vscode-json-languageservice 5.6.2 → 5.6.4

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.
@@ -0,0 +1,295 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ // This file is generated - do not edit directly!
6
+ // Derived from https://json-schema.org/draft/2020-12
7
+ export default {
8
+ $id: 'https://json-schema.org/draft/2020-12/schema',
9
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
10
+ title: '(Flattened static) Core and Validation specifications meta-schema',
11
+ type: [
12
+ 'object',
13
+ 'boolean',
14
+ ],
15
+ properties: {
16
+ definitions: {
17
+ $comment: 'While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.',
18
+ type: 'object',
19
+ additionalProperties: {
20
+ $ref: '#',
21
+ },
22
+ default: {},
23
+ },
24
+ dependencies: {
25
+ $comment: '"dependencies" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to "dependentSchemas" and "dependentRequired"',
26
+ type: 'object',
27
+ additionalProperties: {
28
+ anyOf: [
29
+ {
30
+ $ref: '#',
31
+ },
32
+ {
33
+ $ref: '#/$defs/stringArray',
34
+ },
35
+ ],
36
+ },
37
+ },
38
+ $id: {
39
+ type: 'string',
40
+ format: 'uri-reference',
41
+ $comment: 'Non-empty fragments not allowed.',
42
+ pattern: '^[^#]*#?$',
43
+ },
44
+ $schema: {
45
+ type: 'string',
46
+ format: 'uri',
47
+ },
48
+ $anchor: {
49
+ type: 'string',
50
+ pattern: '^[A-Za-z_][-A-Za-z0-9._]*$',
51
+ },
52
+ $ref: {
53
+ type: 'string',
54
+ format: 'uri-reference',
55
+ },
56
+ $dynamicRef: {
57
+ type: 'string',
58
+ format: 'uri-reference',
59
+ },
60
+ $vocabulary: {
61
+ type: 'object',
62
+ propertyNames: {
63
+ type: 'string',
64
+ format: 'uri',
65
+ },
66
+ additionalProperties: {
67
+ type: 'boolean',
68
+ },
69
+ },
70
+ $comment: {
71
+ type: 'string',
72
+ },
73
+ $defs: {
74
+ type: 'object',
75
+ additionalProperties: {
76
+ $ref: '#',
77
+ },
78
+ default: {},
79
+ },
80
+ prefixItems: {
81
+ $ref: '#/$defs/schemaArray',
82
+ },
83
+ items: {
84
+ $ref: '#',
85
+ },
86
+ contains: {
87
+ $ref: '#',
88
+ },
89
+ additionalProperties: {
90
+ $ref: '#',
91
+ },
92
+ properties: {
93
+ type: 'object',
94
+ additionalProperties: {
95
+ $ref: '#',
96
+ },
97
+ default: {},
98
+ },
99
+ patternProperties: {
100
+ type: 'object',
101
+ additionalProperties: {
102
+ $ref: '#',
103
+ },
104
+ propertyNames: {
105
+ format: 'regex',
106
+ },
107
+ default: {},
108
+ },
109
+ dependentSchemas: {
110
+ type: 'object',
111
+ additionalProperties: {
112
+ $ref: '#',
113
+ },
114
+ },
115
+ propertyNames: {
116
+ $ref: '#',
117
+ },
118
+ if: {
119
+ $ref: '#',
120
+ },
121
+ then: {
122
+ $ref: '#',
123
+ },
124
+ else: {
125
+ $ref: '#',
126
+ },
127
+ allOf: {
128
+ $ref: '#/$defs/schemaArray',
129
+ },
130
+ anyOf: {
131
+ $ref: '#/$defs/schemaArray',
132
+ },
133
+ oneOf: {
134
+ $ref: '#/$defs/schemaArray',
135
+ },
136
+ not: {
137
+ $ref: '#',
138
+ },
139
+ unevaluatedItems: {
140
+ $ref: '#',
141
+ },
142
+ unevaluatedProperties: {
143
+ $ref: '#',
144
+ },
145
+ multipleOf: {
146
+ type: 'number',
147
+ exclusiveMinimum: 0,
148
+ },
149
+ maximum: {
150
+ type: 'number',
151
+ },
152
+ exclusiveMaximum: {
153
+ type: 'number',
154
+ },
155
+ minimum: {
156
+ type: 'number',
157
+ },
158
+ exclusiveMinimum: {
159
+ type: 'number',
160
+ },
161
+ maxLength: {
162
+ $ref: '#/$defs/nonNegativeInteger',
163
+ },
164
+ minLength: {
165
+ $ref: '#/$defs/nonNegativeIntegerDefault0',
166
+ },
167
+ pattern: {
168
+ type: 'string',
169
+ format: 'regex',
170
+ },
171
+ maxItems: {
172
+ $ref: '#/$defs/nonNegativeInteger',
173
+ },
174
+ minItems: {
175
+ $ref: '#/$defs/nonNegativeIntegerDefault0',
176
+ },
177
+ uniqueItems: {
178
+ type: 'boolean',
179
+ default: false,
180
+ },
181
+ maxContains: {
182
+ $ref: '#/$defs/nonNegativeInteger',
183
+ },
184
+ minContains: {
185
+ $ref: '#/$defs/nonNegativeInteger',
186
+ default: 1,
187
+ },
188
+ maxProperties: {
189
+ $ref: '#/$defs/nonNegativeInteger',
190
+ },
191
+ minProperties: {
192
+ $ref: '#/$defs/nonNegativeIntegerDefault0',
193
+ },
194
+ required: {
195
+ $ref: '#/$defs/stringArray',
196
+ },
197
+ dependentRequired: {
198
+ type: 'object',
199
+ additionalProperties: {
200
+ $ref: '#/$defs/stringArray',
201
+ },
202
+ },
203
+ const: true,
204
+ enum: {
205
+ type: 'array',
206
+ items: true,
207
+ },
208
+ type: {
209
+ anyOf: [
210
+ {
211
+ $ref: '#/$defs/simpleTypes',
212
+ },
213
+ {
214
+ type: 'array',
215
+ items: {
216
+ $ref: '#/$defs/simpleTypes',
217
+ },
218
+ minItems: 1,
219
+ uniqueItems: true,
220
+ },
221
+ ],
222
+ },
223
+ title: {
224
+ type: 'string',
225
+ },
226
+ description: {
227
+ type: 'string',
228
+ },
229
+ default: true,
230
+ deprecated: {
231
+ type: 'boolean',
232
+ default: false,
233
+ },
234
+ readOnly: {
235
+ type: 'boolean',
236
+ default: false,
237
+ },
238
+ writeOnly: {
239
+ type: 'boolean',
240
+ default: false,
241
+ },
242
+ examples: {
243
+ type: 'array',
244
+ items: true,
245
+ },
246
+ format: {
247
+ type: 'string',
248
+ },
249
+ contentMediaType: {
250
+ type: 'string',
251
+ },
252
+ contentEncoding: {
253
+ type: 'string',
254
+ },
255
+ contentSchema: {
256
+ $ref: '#',
257
+ },
258
+ },
259
+ $defs: {
260
+ schemaArray: {
261
+ type: 'array',
262
+ minItems: 1,
263
+ items: {
264
+ $ref: '#',
265
+ },
266
+ },
267
+ nonNegativeInteger: {
268
+ type: 'integer',
269
+ minimum: 0,
270
+ },
271
+ nonNegativeIntegerDefault0: {
272
+ $ref: '#/$defs/nonNegativeInteger',
273
+ default: 0,
274
+ },
275
+ simpleTypes: {
276
+ enum: [
277
+ 'array',
278
+ 'boolean',
279
+ 'integer',
280
+ 'null',
281
+ 'number',
282
+ 'object',
283
+ 'string',
284
+ ],
285
+ },
286
+ stringArray: {
287
+ type: 'array',
288
+ items: {
289
+ type: 'string',
290
+ },
291
+ uniqueItems: true,
292
+ default: [],
293
+ },
294
+ },
295
+ };
@@ -394,9 +394,10 @@
394
394
  }
395
395
  const testAlternatives = (alternatives, maxOneMatch) => {
396
396
  const matches = [];
397
+ const alternativesToTest = _tryDiscriminatorOptimization(alternatives) ?? alternatives;
397
398
  // remember the best match that is used for error messages
398
399
  let bestMatch = undefined;
399
- for (const subSchemaRef of alternatives) {
400
+ for (const subSchemaRef of alternativesToTest) {
400
401
  const subSchema = asSchema(subSchemaRef);
401
402
  const subValidationResult = new ValidationResult();
402
403
  const subMatchingSchemas = matchingSchemas.newSub();
@@ -521,6 +522,70 @@
521
522
  });
522
523
  }
523
524
  }
525
+ function _tryDiscriminatorOptimization(alternatives) {
526
+ if (alternatives.length < 2) {
527
+ return undefined;
528
+ }
529
+ const buildConstMap = (getSchemas) => {
530
+ const constMap = new Map();
531
+ for (let i = 0; i < alternatives.length; i++) {
532
+ const schemas = getSchemas(asSchema(alternatives[i]), i);
533
+ if (!schemas) {
534
+ return undefined; // Early exit if any alternative can't be processed
535
+ }
536
+ schemas.forEach(([key, schema]) => {
537
+ if (schema.const !== undefined) {
538
+ if (!constMap.has(key)) {
539
+ constMap.set(key, new Map());
540
+ }
541
+ const valueMap = constMap.get(key);
542
+ if (!valueMap.has(schema.const)) {
543
+ valueMap.set(schema.const, []);
544
+ }
545
+ valueMap.get(schema.const).push(i);
546
+ }
547
+ });
548
+ }
549
+ return constMap;
550
+ };
551
+ const findDiscriminator = (constMap, getValue) => {
552
+ for (const [key, valueMap] of constMap) {
553
+ const coveredAlts = new Set();
554
+ valueMap.forEach(indices => indices.forEach(idx => coveredAlts.add(idx)));
555
+ if (coveredAlts.size === alternatives.length) {
556
+ const discriminatorValue = getValue(key);
557
+ const matchingIndices = valueMap.get(discriminatorValue);
558
+ if (matchingIndices?.length) {
559
+ return matchingIndices.map(idx => alternatives[idx]);
560
+ }
561
+ break; // Found valid discriminator but no match
562
+ }
563
+ }
564
+ return undefined;
565
+ };
566
+ if (node.type === 'object' && node.properties?.length) {
567
+ const constMap = buildConstMap((schema) => schema.properties ? Object.entries(schema.properties).map(([k, v]) => [k, asSchema(v)]) : undefined);
568
+ if (constMap) {
569
+ return findDiscriminator(constMap, (propName) => {
570
+ const prop = node.properties.find(p => p.keyNode.value === propName);
571
+ return prop?.valueNode?.type === 'string' ? prop.valueNode.value : undefined;
572
+ });
573
+ }
574
+ }
575
+ else if (node.type === 'array' && node.items?.length) {
576
+ const constMap = buildConstMap((schema) => {
577
+ const itemSchemas = schema.prefixItems || (Array.isArray(schema.items) ? schema.items : undefined);
578
+ return itemSchemas ? itemSchemas.map((item, idx) => [idx, asSchema(item)]) : undefined;
579
+ });
580
+ if (constMap) {
581
+ return findDiscriminator(constMap, (itemIndex) => {
582
+ const item = node.items[itemIndex];
583
+ return item?.type === 'string' ? item.value : undefined;
584
+ });
585
+ }
586
+ }
587
+ return undefined;
588
+ }
524
589
  function _validateNumberNode(node) {
525
590
  const val = node.value;
526
591
  function normalizeFloats(float) {
@@ -982,7 +1047,7 @@
982
1047
  for (const f of node.properties) {
983
1048
  const key = f.keyNode;
984
1049
  if (key) {
985
- validate(key, propertyNames, validationResult, NoOpSchemaCollector.instance, context);
1050
+ validate(key, propertyNames, validationResult, matchingSchemas, context);
986
1051
  }
987
1052
  }
988
1053
  }
@@ -8,12 +8,14 @@
8
8
  if (v !== undefined) module.exports = v;
9
9
  }
10
10
  else if (typeof define === "function" && define.amd) {
11
- define(["require", "exports", "@vscode/l10n"], factory);
11
+ define(["require", "exports", "./schemas/draft-2019-09-flat", "./schemas/draft-2020-12-flat", "@vscode/l10n"], factory);
12
12
  }
13
13
  })(function (require, exports) {
14
14
  "use strict";
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.schemaContributions = void 0;
17
+ const draft_2019_09_flat_1 = require("./schemas/draft-2019-09-flat");
18
+ const draft_2020_12_flat_1 = require("./schemas/draft-2020-12-flat");
17
19
  const l10n = require("@vscode/l10n");
18
20
  exports.schemaContributions = {
19
21
  schemaAssociations: [],
@@ -465,7 +467,9 @@
465
467
  'not': { '$ref': '#' }
466
468
  },
467
469
  'default': true
468
- }
470
+ },
471
+ 'https://json-schema.org/draft/2020-12/schema': draft_2020_12_flat_1.default,
472
+ 'https://json-schema.org/draft/2019-09/schema': draft_2019_09_flat_1.default
469
473
  }
470
474
  };
471
475
  const descriptions = {
@@ -56,60 +56,60 @@
56
56
  }
57
57
  }
58
58
  return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
59
- if (schema && node) {
60
- const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset);
61
- let title = undefined;
62
- let markdownDescription = undefined;
63
- let markdownEnumValueDescription = undefined, enumValue = undefined;
64
- matchingSchemas.every((s) => {
65
- if (s.node === node && !s.inverted && s.schema) {
66
- title = title || s.schema.title;
67
- markdownDescription = markdownDescription || s.schema.markdownDescription || toMarkdown(s.schema.description);
68
- if (s.schema.enum) {
69
- const idx = s.schema.enum.indexOf(Parser.getNodeValue(node));
70
- if (s.schema.markdownEnumDescriptions) {
71
- markdownEnumValueDescription = s.schema.markdownEnumDescriptions[idx];
72
- }
73
- else if (s.schema.enumDescriptions) {
74
- markdownEnumValueDescription = toMarkdown(s.schema.enumDescriptions[idx]);
75
- }
76
- if (markdownEnumValueDescription) {
77
- enumValue = s.schema.enum[idx];
78
- if (typeof enumValue !== 'string') {
79
- enumValue = JSON.stringify(enumValue);
80
- }
81
- }
59
+ if (!schema) {
60
+ return null;
61
+ }
62
+ let title = undefined;
63
+ let markdownDescription = undefined;
64
+ let markdownEnumValueDescription = undefined, enumValue = undefined;
65
+ const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset).filter((s) => s.node === node && !s.inverted).map((s) => s.schema);
66
+ for (const schema of matchingSchemas) {
67
+ title = title || schema.title;
68
+ markdownDescription = markdownDescription || schema.markdownDescription || toMarkdown(schema.description);
69
+ if (schema.enum) {
70
+ const idx = schema.enum.indexOf(Parser.getNodeValue(node));
71
+ if (schema.markdownEnumDescriptions) {
72
+ markdownEnumValueDescription = schema.markdownEnumDescriptions[idx];
73
+ }
74
+ else if (schema.enumDescriptions) {
75
+ markdownEnumValueDescription = toMarkdown(schema.enumDescriptions[idx]);
76
+ }
77
+ if (markdownEnumValueDescription) {
78
+ enumValue = schema.enum[idx];
79
+ if (typeof enumValue !== 'string') {
80
+ enumValue = JSON.stringify(enumValue);
82
81
  }
83
82
  }
84
- return true;
85
- });
86
- let result = '';
87
- if (title) {
88
- result = toMarkdown(title);
89
83
  }
90
- if (markdownDescription) {
91
- if (result.length > 0) {
92
- result += "\n\n";
93
- }
94
- result += markdownDescription;
84
+ }
85
+ let result = '';
86
+ if (title) {
87
+ result = toMarkdown(title);
88
+ }
89
+ if (markdownDescription) {
90
+ if (result.length > 0) {
91
+ result += "\n\n";
95
92
  }
96
- if (markdownEnumValueDescription) {
97
- if (result.length > 0) {
98
- result += "\n\n";
99
- }
100
- result += `\`${toMarkdownCodeBlock(enumValue)}\`: ${markdownEnumValueDescription}`;
93
+ result += markdownDescription;
94
+ }
95
+ if (markdownEnumValueDescription) {
96
+ if (result.length > 0) {
97
+ result += "\n\n";
101
98
  }
102
- return createHover([result]);
99
+ result += `\`${toMarkdownCodeBlock(enumValue)}\`: ${markdownEnumValueDescription}`;
103
100
  }
104
- return null;
101
+ return createHover([result]);
105
102
  });
106
103
  }
107
104
  }
108
105
  exports.JSONHover = JSONHover;
109
106
  function toMarkdown(plain) {
110
107
  if (plain) {
111
- const res = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph)
112
- return res.replace(/[\\`*_{}[\]()#+\-.!]/g, "\\$&"); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
108
+ return plain
109
+ .trim()
110
+ .replace(/[\\`*_{}[\]()<>#+\-.!]/g, '\\$&') // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
111
+ .replace(/([ \t]+)/g, (_match, g1) => '&nbsp;'.repeat(g1.length)) // escape spaces tabs
112
+ .replace(/\n/g, '\\\n'); // escape new lines
113
113
  }
114
114
  return undefined;
115
115
  }