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