@theia/plugin-ext 1.75.0-next.21 → 1.75.0-next.28

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 +45 -648
  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 +38 -71
  28. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  29. package/lib/hosted/node/scanners/scanner-theia.js +117 -768
  30. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  31. package/lib/hosted/node/scanners/scanner-theia.spec.js +191 -0
  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 +195 -662
  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 +225 -1
  54. package/src/hosted/node/scanners/scanner-theia.ts +204 -881
  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,600 +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
- 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;
436
167
  }
437
168
  readTerminals(pck) {
438
- if (!pck?.contributes?.terminal?.profiles) {
439
- return undefined;
440
- }
441
- return pck.contributes.terminal.profiles.filter(profile => profile.id && profile.title);
169
+ return (0, normalize_contributions_1.readTerminals)(pck);
442
170
  }
443
171
  readLocalizations(pck) {
444
- if (!pck.contributes || !pck.contributes.localizations) {
445
- return undefined;
446
- }
447
- return pck.contributes.localizations.map(e => this.readLocalization(e, pck.packagePath));
448
- }
449
- readLocalization({ languageId, languageName, localizedLanguageName, translations }, pluginPath) {
450
- const local = {
451
- languageId,
452
- languageName,
453
- localizedLanguageName,
454
- translations: []
455
- };
456
- local.translations = translations.map(e => this.readTranslation(e, pluginPath));
457
- return local;
172
+ return (0, normalize_contributions_1.readLocalizations)(pck, this.contributionCtx(pck));
173
+ }
174
+ readLocalization(entry, pluginPath) {
175
+ return (0, normalize_contributions_1.readLocalization)(entry, pluginPath, {
176
+ readTranslation: (translation, translationPath) => this.readTranslation(translation, translationPath),
177
+ });
458
178
  }
459
179
  readTranslation(packageTranslation, pluginPath) {
460
- const translation = {
461
- id: packageTranslation.id,
462
- path: packageTranslation.path
463
- };
464
- return translation;
180
+ return (0, normalize_contributions_1.readTranslation)(packageTranslation, pluginPath);
465
181
  }
466
- readCommand({ command, title, shortTitle, original, category, icon, enablement }, pck) {
467
- const { themeIcon, iconUrl } = this.transformIconUrl(pck, icon) ?? {};
468
- return { command, title, shortTitle, originalTitle: original, category, iconUrl, themeIcon, enablement };
182
+ readWalkthroughs(pck) {
183
+ return (0, normalize_contributions_1.readWalkthroughs)(pck, this.contributionCtx(pck));
184
+ }
185
+ readCommand(command, pck) {
186
+ return (0, normalize_contributions_1.readCommand)(this.contributionCtx(pck), command, pck);
469
187
  }
470
188
  transformIconUrl(plugin, original) {
471
- if (original) {
472
- if (typeof original === 'string') {
473
- if (original.startsWith('$(')) {
474
- return { themeIcon: original };
475
- }
476
- else {
477
- return { iconUrl: this.toPluginUrl(plugin, original) };
478
- }
479
- }
480
- else {
481
- return {
482
- iconUrl: {
483
- light: this.toPluginUrl(plugin, original.light),
484
- dark: this.toPluginUrl(plugin, original.dark)
485
- }
486
- };
487
- }
488
- }
189
+ return (0, normalize_contributions_1.transformIconUrl)(this.contributionCtx(plugin), plugin, original);
489
190
  }
490
191
  toPluginUrl(pck, relativePath) {
491
- return plugin_protocol_1.PluginPackage.toPluginUrl(pck, relativePath);
192
+ return (0, plugin_model_1.toPluginUrl)(pck, relativePath);
492
193
  }
493
194
  readColors(pck) {
494
- if (!pck.contributes || !pck.contributes.colors) {
495
- return undefined;
496
- }
497
- const result = [];
498
- for (const contribution of pck.contributes.colors) {
499
- if (typeof contribution.id !== 'string' || contribution.id.length === 0) {
500
- this.logger.error("'configuration.colors.id' must be defined and can not be empty");
501
- continue;
502
- }
503
- if (!contribution.id.match(colorIdPattern)) {
504
- this.logger.error("'configuration.colors.id' must follow the word[.word]*");
505
- continue;
506
- }
507
- if (typeof contribution.description !== 'string' || contribution.id.length === 0) {
508
- this.logger.error("'configuration.colors.description' must be defined and can not be empty");
509
- continue;
510
- }
511
- const defaults = contribution.defaults;
512
- if (!defaults || typeof defaults !== 'object' || typeof defaults.light !== 'string' || typeof defaults.dark !== 'string' || typeof defaults.highContrast !== 'string') {
513
- this.logger.error("'configuration.colors.defaults' must be defined and must contain 'light', 'dark' and 'highContrast'");
514
- continue;
515
- }
516
- result.push({
517
- id: contribution.id,
518
- description: contribution.description,
519
- defaults: {
520
- light: defaults.light,
521
- dark: defaults.dark,
522
- hc: defaults.highContrast
523
- }
524
- });
525
- }
526
- return result;
195
+ return (0, normalize_contributions_1.readColors)(this.contributionCtx(pck), pck);
527
196
  }
528
197
  readThemes(pck) {
529
- if (!pck.contributes || !pck.contributes.themes) {
530
- return undefined;
531
- }
532
- const result = [];
533
- for (const contribution of pck.contributes.themes) {
534
- if (contribution.path) {
535
- result.push({
536
- id: contribution.id,
537
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString(),
538
- description: contribution.description,
539
- label: contribution.label,
540
- uiTheme: contribution.uiTheme
541
- });
542
- }
543
- }
544
- return result;
198
+ return (0, normalize_contributions_1.readThemes)(this.contributionCtx(pck), pck);
545
199
  }
546
200
  readIconThemes(pck) {
547
- if (!pck.contributes || !pck.contributes.iconThemes) {
548
- return undefined;
549
- }
550
- const result = [];
551
- for (const contribution of pck.contributes.iconThemes) {
552
- if (typeof contribution.id !== 'string') {
553
- this.logger.error('Expected string in `contributes.iconThemes.id`. Provided value:', contribution.id);
554
- continue;
555
- }
556
- if (typeof contribution.path !== 'string') {
557
- this.logger.error('Expected string in `contributes.iconThemes.path`. Provided value:', contribution.path);
558
- continue;
559
- }
560
- result.push({
561
- id: contribution.id,
562
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString(),
563
- description: contribution.description,
564
- label: contribution.label,
565
- uiTheme: contribution.uiTheme
566
- });
567
- }
568
- return result;
201
+ return (0, normalize_contributions_1.readIconThemes)(this.contributionCtx(pck), pck);
569
202
  }
570
203
  readIcons(pck) {
571
- if (!pck.contributes || !pck.contributes.icons) {
572
- return undefined;
573
- }
574
- const result = [];
575
- const iconEntries = pck.contributes.icons;
576
- for (const id in iconEntries) {
577
- if (pck.contributes.icons.hasOwnProperty(id)) {
578
- if (!id.match(iconIdPattern)) {
579
- this.logger.error("'configuration.icons' keys represent the icon id and can only contain letter, digits and minuses. " +
580
- 'They need to consist of at least two segments in the form `component-iconname`.', 'extension: ', pck.name, 'icon id: ', id);
581
- return;
582
- }
583
- const iconContribution = iconEntries[id];
584
- if (typeof iconContribution.description !== 'string' || iconContribution.description['length'] === 0) {
585
- this.logger.error('configuration.icons.description must be defined and can not be empty, ', 'extension: ', pck.name, 'icon id: ', id);
586
- return;
587
- }
588
- const defaultIcon = iconContribution.default;
589
- if (typeof defaultIcon === 'string') {
590
- result.push({
591
- id,
592
- extensionId: pck.publisher + '.' + pck.name,
593
- description: iconContribution.description,
594
- defaults: { id: defaultIcon }
595
- });
596
- }
597
- else if (typeof defaultIcon === 'object' && typeof defaultIcon.fontPath === 'string' && typeof defaultIcon.fontCharacter === 'string') {
598
- const format = getFileExtension(defaultIcon.fontPath);
599
- if (['woff', 'woff2', 'ttf'].indexOf(format) === -1) {
600
- this.logger.warn("Expected `contributes.icons.default.fontPath` to have file extension 'woff', woff2' or 'ttf', is '{0}'.", format);
601
- return;
602
- }
603
- const iconFontLocation = this.pluginUriFactory.createUri(pck, defaultIcon.fontPath).toString();
604
- result.push({
605
- id,
606
- extensionId: pck.publisher + '.' + pck.name,
607
- description: iconContribution.description,
608
- defaults: {
609
- fontCharacter: defaultIcon.fontCharacter,
610
- location: iconFontLocation
611
- }
612
- });
613
- }
614
- else {
615
- 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`.');
616
- }
617
- }
618
- }
619
- return result;
204
+ return (0, normalize_contributions_1.readIcons)(this.contributionCtx(pck), pck);
620
205
  }
621
206
  readSnippets(pck) {
622
- if (!pck.contributes || !pck.contributes.snippets) {
623
- return undefined;
624
- }
625
- const result = [];
626
- for (const contribution of pck.contributes.snippets) {
627
- if (contribution.path) {
628
- result.push({
629
- language: contribution.language,
630
- source: pck.displayName || pck.name,
631
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString()
632
- });
633
- }
634
- }
635
- return result;
636
- }
637
- async readJson(filePath) {
638
- const content = await this.readFile(filePath);
639
- return content ? jsoncparser.parse(content, undefined, { disallowComments: false }) : undefined;
640
- }
641
- async readFile(filePath) {
642
- try {
643
- const content = await fs_1.promises.readFile(filePath, { encoding: 'utf8' });
644
- return content;
645
- }
646
- catch (e) {
647
- if (!(0, errors_1.isENOENT)(e)) {
648
- this.logger.error(e);
649
- }
650
- return '';
651
- }
207
+ return (0, normalize_contributions_1.readSnippets)(this.contributionCtx(pck), pck);
652
208
  }
653
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
654
209
  readConfiguration(rawConfiguration, pluginPath) {
655
- const { scope, overridable } = TheiaPluginScanner_1.getScope(rawConfiguration.scope);
656
- const schema = {
657
- scope,
658
- defaultOverridable: overridable,
659
- title: rawConfiguration.title,
660
- properties: {}
661
- };
662
- if (rawConfiguration.properties) {
663
- for (const [key, property] of Object.entries(rawConfiguration.properties)) {
664
- const scopeInfo = TheiaPluginScanner_1.getScope(property.scope);
665
- const schemaProperty = {
666
- ...property,
667
- scope: scopeInfo.scope,
668
- overridable: scopeInfo.overridable,
669
- default: property.default !== undefined ? property.default : deriveDefaultForType(property.type)
670
- };
671
- schema.properties[key] = schemaProperty;
672
- }
673
- }
674
- return schema;
210
+ return (0, normalize_contributions_1.readConfiguration)(rawConfiguration, pluginPath);
675
211
  }
676
212
  readKeybinding(rawKeybinding) {
677
- return {
678
- keybinding: rawKeybinding.key,
679
- command: rawKeybinding.command,
680
- when: rawKeybinding.when,
681
- mac: rawKeybinding.mac,
682
- linux: rawKeybinding.linux,
683
- win: rawKeybinding.win,
684
- args: rawKeybinding.args
685
- };
213
+ return (0, normalize_contributions_1.readKeybinding)(rawKeybinding);
686
214
  }
687
215
  readCustomEditors(rawCustomEditors) {
688
216
  return rawCustomEditors.map(rawCustomEditor => this.readCustomEditor(rawCustomEditor));
689
217
  }
690
218
  readCustomEditor(rawCustomEditor) {
691
- return {
692
- viewType: rawCustomEditor.viewType,
693
- displayName: rawCustomEditor.displayName,
694
- selector: rawCustomEditor.selector || [],
695
- priority: rawCustomEditor.priority || plugin_protocol_1.CustomEditorPriority.default
696
- };
219
+ return (0, normalize_contributions_1.readCustomEditor)(rawCustomEditor);
697
220
  }
698
221
  readViewsContainers(rawViewsContainers, pck) {
699
- return rawViewsContainers.map(rawViewContainer => this.readViewContainer(rawViewContainer, pck));
222
+ return rawViewsContainers
223
+ .map(rawViewContainer => this.readViewContainer(rawViewContainer, pck))
224
+ .filter((container) => container !== undefined);
700
225
  }
701
226
  readViewContainer(rawViewContainer, pck) {
702
- const themeIcon = rawViewContainer.icon.startsWith('$(') ? rawViewContainer.icon : undefined;
703
- const iconUrl = this.toPluginUrl(pck, rawViewContainer.icon);
704
- return {
705
- id: rawViewContainer.id,
706
- title: rawViewContainer.title,
707
- iconUrl,
708
- themeIcon,
709
- when: rawViewContainer.when,
710
- };
227
+ return (0, normalize_contributions_1.readViewContainer)(this.contributionCtx(pck), rawViewContainer, pck);
711
228
  }
712
229
  readViews(rawViews) {
713
230
  return rawViews.map(rawView => this.readView(rawView));
714
231
  }
715
232
  readView(rawView) {
716
- const result = {
717
- id: rawView.id,
718
- name: rawView.name,
719
- when: rawView.when,
720
- type: rawView.type
721
- };
722
- return result;
233
+ return (0, normalize_contributions_1.readView)(rawView);
723
234
  }
724
235
  readViewsWelcome(rawViewsWelcome, rowViews) {
725
236
  return rawViewsWelcome.map(rawViewWelcome => this.readViewWelcome(rawViewWelcome, this.extractPluginViewsIds(rowViews)));
726
237
  }
727
238
  readViewWelcome(rawViewWelcome, pluginViewsIds) {
728
- const result = {
729
- view: rawViewWelcome.view,
730
- content: rawViewWelcome.contents,
731
- when: rawViewWelcome.when,
732
- enablement: rawViewWelcome.enablement,
733
- // if the plugin contributes Welcome view to its own view - it will be ordered first
734
- order: pluginViewsIds.findIndex(v => v === rawViewWelcome.view) > -1 ? 0 : 1
735
- };
736
- return result;
239
+ return (0, normalize_contributions_1.readViewWelcome)(rawViewWelcome, pluginViewsIds);
737
240
  }
738
241
  extractPluginViewsIds(views) {
739
- const pluginViewsIds = [];
740
- if (views) {
741
- for (const location of Object.keys(views)) {
742
- const viewsIds = views[location].map(view => view.id);
743
- pluginViewsIds.push(...viewsIds);
744
- }
745
- ;
746
- }
747
- return pluginViewsIds;
242
+ return (0, normalize_contributions_1.extractPluginViewsIds)(views);
748
243
  }
749
244
  readMenus(rawMenus) {
750
245
  return rawMenus.map(rawMenu => this.readMenu(rawMenu));
751
246
  }
752
247
  readMenu(rawMenu) {
753
- const result = {
754
- command: rawMenu.command,
755
- submenu: rawMenu.submenu,
756
- alt: rawMenu.alt,
757
- group: rawMenu.group,
758
- when: rawMenu.when
759
- };
760
- return result;
248
+ return (0, normalize_contributions_1.readMenu)(rawMenu);
761
249
  }
762
250
  async readLanguages(rawLanguages, plugin) {
763
251
  return Promise.all(rawLanguages.map(language => this.readLanguage(language, plugin)));
@@ -766,175 +254,40 @@ let TheiaPluginScanner = TheiaPluginScanner_1 = class TheiaPluginScanner extends
766
254
  return rawSubmenus.map(submenu => this.readSubmenu(submenu, plugin));
767
255
  }
768
256
  readSubmenu(rawSubmenu, plugin) {
769
- const icon = this.transformIconUrl(plugin, rawSubmenu.icon);
770
- return {
771
- icon: icon?.iconUrl ?? icon?.themeIcon,
772
- id: rawSubmenu.id,
773
- label: rawSubmenu.label
774
- };
257
+ return (0, normalize_contributions_1.readSubmenu)(this.contributionCtx(plugin), rawSubmenu, plugin);
775
258
  }
776
259
  async readLanguage(rawLang, plugin) {
777
- // TODO: add validation to all parameters
778
- const icon = this.transformIconUrl(plugin, rawLang.icon);
779
- const result = {
780
- id: rawLang.id,
781
- aliases: rawLang.aliases,
782
- extensions: rawLang.extensions,
783
- filenamePatterns: rawLang.filenamePatterns,
784
- filenames: rawLang.filenames,
785
- firstLine: rawLang.firstLine,
786
- mimetypes: rawLang.mimetypes,
787
- icon: icon?.iconUrl ?? icon?.themeIcon
788
- };
789
- if (rawLang.configuration) {
790
- const rawConfiguration = await this.readJson(path.resolve(plugin.packagePath, rawLang.configuration));
791
- if (rawConfiguration) {
792
- const configuration = {
793
- brackets: rawConfiguration.brackets,
794
- comments: rawConfiguration.comments,
795
- folding: rawConfiguration.folding,
796
- wordPattern: rawConfiguration.wordPattern,
797
- autoClosingPairs: this.extractValidAutoClosingPairs(rawLang.id, rawConfiguration),
798
- indentationRules: rawConfiguration.indentationRules,
799
- surroundingPairs: this.extractValidSurroundingPairs(rawLang.id, rawConfiguration),
800
- onEnterRules: rawConfiguration.onEnterRules,
801
- };
802
- result.configuration = configuration;
803
- }
804
- }
805
- return result;
260
+ return (0, normalize_contributions_1.readLanguage)(this.contributionCtx(plugin), rawLang, plugin);
806
261
  }
807
262
  readDebuggers(rawDebuggers) {
808
- return rawDebuggers.map(rawDebug => this.readDebugger(rawDebug));
263
+ return rawDebuggers.map(rawDebugger => this.readDebugger(rawDebugger));
809
264
  }
810
265
  readDebugger(rawDebugger) {
811
- const result = {
812
- type: rawDebugger.type,
813
- label: rawDebugger.label,
814
- languages: rawDebugger.languages,
815
- enableBreakpointsFor: rawDebugger.enableBreakpointsFor,
816
- variables: rawDebugger.variables,
817
- adapterExecutableCommand: rawDebugger.adapterExecutableCommand,
818
- configurationSnippets: rawDebugger.configurationSnippets,
819
- win: rawDebugger.win,
820
- winx86: rawDebugger.winx86,
821
- windows: rawDebugger.windows,
822
- osx: rawDebugger.osx,
823
- linux: rawDebugger.linux,
824
- program: rawDebugger.program,
825
- args: rawDebugger.args,
826
- runtime: rawDebugger.runtime,
827
- runtimeArgs: rawDebugger.runtimeArgs,
828
- configurationAttributes: rawDebugger.configurationAttributes
829
- };
830
- return result;
266
+ return (0, normalize_contributions_1.readDebugger)(rawDebugger);
831
267
  }
832
268
  readTaskDefinition(pluginName, definitionContribution) {
833
- const propertyKeys = definitionContribution.properties ? Object.keys(definitionContribution.properties) : [];
834
- const schema = this.toSchema(definitionContribution);
835
- return {
836
- taskType: definitionContribution.type,
837
- source: pluginName,
838
- properties: {
839
- required: definitionContribution.required || [],
840
- all: propertyKeys,
841
- schema
842
- }
843
- };
269
+ return (0, normalize_contributions_1.readTaskDefinition)(pluginName, definitionContribution, {
270
+ toSchema: definition => this.toSchema(definition)
271
+ });
844
272
  }
845
273
  toSchema(definition) {
846
- const reconciliation = { ...definition, type: 'object' };
847
- const schema = (0, objects_1.deepClone)(reconciliation);
848
- if (schema.properties === undefined) {
849
- schema.properties = Object.create(null);
850
- }
851
- schema.type = 'object';
852
- schema.properties.type = { type: 'string', const: definition.type };
853
- return schema;
274
+ return (0, normalize_contributions_1.toSchema)(definition);
854
275
  }
855
- extractValidAutoClosingPairs(langId, configuration) {
856
- const source = configuration.autoClosingPairs;
857
- if (typeof source === 'undefined') {
858
- return undefined;
859
- }
860
- if (!Array.isArray(source)) {
861
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs\` to be an array.`);
862
- return undefined;
863
- }
864
- let result = undefined;
865
- for (let i = 0, len = source.length; i < len; i++) {
866
- const pair = source[i];
867
- if (Array.isArray(pair)) {
868
- if (!isCharacterPair(pair)) {
869
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}]\` to be an array of two strings or an object.`);
870
- continue;
871
- }
872
- result = result || [];
873
- result.push({ open: pair[0], close: pair[1] });
874
- }
875
- else {
876
- if (!(0, types_1.isObject)(pair)) {
877
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}]\` to be an array of two strings or an object.`);
878
- continue;
879
- }
880
- if (typeof pair.open !== 'string') {
881
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].open\` to be a string.`);
882
- continue;
883
- }
884
- if (typeof pair.close !== 'string') {
885
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].close\` to be a string.`);
886
- continue;
887
- }
888
- if (typeof pair.notIn !== 'undefined') {
889
- if (!(0, types_1.isStringArray)(pair.notIn)) {
890
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].notIn\` to be a string array.`);
891
- continue;
892
- }
893
- }
894
- result = result || [];
895
- result.push({ open: pair.open, close: pair.close, notIn: pair.notIn });
896
- }
897
- }
898
- return result;
276
+ async readJson(filePath) {
277
+ const content = await this.readFile(filePath);
278
+ return content ? jsoncparser.parse(content, undefined, { disallowComments: false }) : undefined;
899
279
  }
900
- extractValidSurroundingPairs(langId, configuration) {
901
- const source = configuration.surroundingPairs;
902
- if (typeof source === 'undefined') {
903
- return undefined;
904
- }
905
- if (!Array.isArray(source)) {
906
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs\` to be an array.`);
907
- return undefined;
280
+ async readFile(filePath) {
281
+ try {
282
+ const content = await fs_1.promises.readFile(filePath, { encoding: 'utf8' });
283
+ return content;
908
284
  }
909
- let result = undefined;
910
- for (let i = 0, len = source.length; i < len; i++) {
911
- const pair = source[i];
912
- if (Array.isArray(pair)) {
913
- if (!isCharacterPair(pair)) {
914
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}]\` to be an array of two strings or an object.`);
915
- continue;
916
- }
917
- result = result || [];
918
- result.push({ open: pair[0], close: pair[1] });
919
- }
920
- else {
921
- if (!(0, types_1.isObject)(pair)) {
922
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}]\` to be an array of two strings or an object.`);
923
- continue;
924
- }
925
- if (typeof pair.open !== 'string') {
926
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}].open\` to be a string.`);
927
- continue;
928
- }
929
- if (typeof pair.close !== 'string') {
930
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}].close\` to be a string.`);
931
- continue;
932
- }
933
- result = result || [];
934
- result.push({ open: pair.open, close: pair.close });
285
+ catch (e) {
286
+ if (!(0, utils_1.isENOENT)(e)) {
287
+ this.logger.error(e);
935
288
  }
289
+ return '';
936
290
  }
937
- return result;
938
291
  }
939
292
  };
940
293
  exports.TheiaPluginScanner = TheiaPluginScanner;
@@ -943,12 +296,8 @@ tslib_1.__decorate([
943
296
  (0, inversify_1.named)('plugin-ext:TheiaPluginScanner'),
944
297
  tslib_1.__metadata("design:type", Object)
945
298
  ], TheiaPluginScanner.prototype, "logger", void 0);
946
- exports.TheiaPluginScanner = TheiaPluginScanner = TheiaPluginScanner_1 = tslib_1.__decorate([
299
+ exports.TheiaPluginScanner = TheiaPluginScanner = tslib_1.__decorate([
947
300
  (0, inversify_1.injectable)(),
948
301
  tslib_1.__metadata("design:paramtypes", [])
949
302
  ], TheiaPluginScanner);
950
- function isCharacterPair(something) {
951
- return ((0, types_1.isStringArray)(something)
952
- && something.length === 2);
953
- }
954
303
  //# sourceMappingURL=scanner-theia.js.map