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.
- package/CHANGELOG.md +1 -1
- package/lib/esm/parser/jsonParser.js +67 -2
- package/lib/esm/services/configuration.js +5 -1
- package/lib/esm/services/jsonHover.js +42 -42
- package/lib/esm/services/schemas/draft-2019-09-flat.d.ts +278 -0
- package/lib/esm/services/schemas/draft-2019-09-flat.js +302 -0
- package/lib/esm/services/schemas/draft-2020-12-flat.d.ts +276 -0
- package/lib/esm/services/schemas/draft-2020-12-flat.js +295 -0
- package/lib/umd/parser/jsonParser.js +67 -2
- package/lib/umd/services/configuration.js +6 -2
- package/lib/umd/services/jsonHover.js +42 -42
- package/lib/umd/services/schemas/draft-2019-09-flat.d.ts +278 -0
- package/lib/umd/services/schemas/draft-2019-09-flat.js +314 -0
- package/lib/umd/services/schemas/draft-2020-12-flat.d.ts +276 -0
- package/lib/umd/services/schemas/draft-2020-12-flat.js +307 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
5.6.0 / 2025-05-28
|
|
2
2
|
================
|
|
3
|
-
* added `Schema.enumSortTexts`and
|
|
3
|
+
* added `Schema.enumSortTexts` and `Schema.enumDetails` to control the sort order and presentation of suggestions for enums
|
|
4
4
|
|
|
5
5
|
5.5.0 / 2025-03-25
|
|
6
6
|
================
|
|
@@ -364,9 +364,10 @@ function validate(n, schema, validationResult, matchingSchemas, context) {
|
|
|
364
364
|
}
|
|
365
365
|
const testAlternatives = (alternatives, maxOneMatch) => {
|
|
366
366
|
const matches = [];
|
|
367
|
+
const alternativesToTest = _tryDiscriminatorOptimization(alternatives) ?? alternatives;
|
|
367
368
|
// remember the best match that is used for error messages
|
|
368
369
|
let bestMatch = undefined;
|
|
369
|
-
for (const subSchemaRef of
|
|
370
|
+
for (const subSchemaRef of alternativesToTest) {
|
|
370
371
|
const subSchema = asSchema(subSchemaRef);
|
|
371
372
|
const subValidationResult = new ValidationResult();
|
|
372
373
|
const subMatchingSchemas = matchingSchemas.newSub();
|
|
@@ -491,6 +492,70 @@ function validate(n, schema, validationResult, matchingSchemas, context) {
|
|
|
491
492
|
});
|
|
492
493
|
}
|
|
493
494
|
}
|
|
495
|
+
function _tryDiscriminatorOptimization(alternatives) {
|
|
496
|
+
if (alternatives.length < 2) {
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
const buildConstMap = (getSchemas) => {
|
|
500
|
+
const constMap = new Map();
|
|
501
|
+
for (let i = 0; i < alternatives.length; i++) {
|
|
502
|
+
const schemas = getSchemas(asSchema(alternatives[i]), i);
|
|
503
|
+
if (!schemas) {
|
|
504
|
+
return undefined; // Early exit if any alternative can't be processed
|
|
505
|
+
}
|
|
506
|
+
schemas.forEach(([key, schema]) => {
|
|
507
|
+
if (schema.const !== undefined) {
|
|
508
|
+
if (!constMap.has(key)) {
|
|
509
|
+
constMap.set(key, new Map());
|
|
510
|
+
}
|
|
511
|
+
const valueMap = constMap.get(key);
|
|
512
|
+
if (!valueMap.has(schema.const)) {
|
|
513
|
+
valueMap.set(schema.const, []);
|
|
514
|
+
}
|
|
515
|
+
valueMap.get(schema.const).push(i);
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
return constMap;
|
|
520
|
+
};
|
|
521
|
+
const findDiscriminator = (constMap, getValue) => {
|
|
522
|
+
for (const [key, valueMap] of constMap) {
|
|
523
|
+
const coveredAlts = new Set();
|
|
524
|
+
valueMap.forEach(indices => indices.forEach(idx => coveredAlts.add(idx)));
|
|
525
|
+
if (coveredAlts.size === alternatives.length) {
|
|
526
|
+
const discriminatorValue = getValue(key);
|
|
527
|
+
const matchingIndices = valueMap.get(discriminatorValue);
|
|
528
|
+
if (matchingIndices?.length) {
|
|
529
|
+
return matchingIndices.map(idx => alternatives[idx]);
|
|
530
|
+
}
|
|
531
|
+
break; // Found valid discriminator but no match
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return undefined;
|
|
535
|
+
};
|
|
536
|
+
if (node.type === 'object' && node.properties?.length) {
|
|
537
|
+
const constMap = buildConstMap((schema) => schema.properties ? Object.entries(schema.properties).map(([k, v]) => [k, asSchema(v)]) : undefined);
|
|
538
|
+
if (constMap) {
|
|
539
|
+
return findDiscriminator(constMap, (propName) => {
|
|
540
|
+
const prop = node.properties.find(p => p.keyNode.value === propName);
|
|
541
|
+
return prop?.valueNode?.type === 'string' ? prop.valueNode.value : undefined;
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else if (node.type === 'array' && node.items?.length) {
|
|
546
|
+
const constMap = buildConstMap((schema) => {
|
|
547
|
+
const itemSchemas = schema.prefixItems || (Array.isArray(schema.items) ? schema.items : undefined);
|
|
548
|
+
return itemSchemas ? itemSchemas.map((item, idx) => [idx, asSchema(item)]) : undefined;
|
|
549
|
+
});
|
|
550
|
+
if (constMap) {
|
|
551
|
+
return findDiscriminator(constMap, (itemIndex) => {
|
|
552
|
+
const item = node.items[itemIndex];
|
|
553
|
+
return item?.type === 'string' ? item.value : undefined;
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return undefined;
|
|
558
|
+
}
|
|
494
559
|
function _validateNumberNode(node) {
|
|
495
560
|
const val = node.value;
|
|
496
561
|
function normalizeFloats(float) {
|
|
@@ -952,7 +1017,7 @@ function validate(n, schema, validationResult, matchingSchemas, context) {
|
|
|
952
1017
|
for (const f of node.properties) {
|
|
953
1018
|
const key = f.keyNode;
|
|
954
1019
|
if (key) {
|
|
955
|
-
validate(key, propertyNames, validationResult,
|
|
1020
|
+
validate(key, propertyNames, validationResult, matchingSchemas, context);
|
|
956
1021
|
}
|
|
957
1022
|
}
|
|
958
1023
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import draft201909Flat from './schemas/draft-2019-09-flat';
|
|
6
|
+
import draft202012Flat from './schemas/draft-2020-12-flat';
|
|
5
7
|
import * as l10n from '@vscode/l10n';
|
|
6
8
|
export const schemaContributions = {
|
|
7
9
|
schemaAssociations: [],
|
|
@@ -453,7 +455,9 @@ export const schemaContributions = {
|
|
|
453
455
|
'not': { '$ref': '#' }
|
|
454
456
|
},
|
|
455
457
|
'default': true
|
|
456
|
-
}
|
|
458
|
+
},
|
|
459
|
+
'https://json-schema.org/draft/2020-12/schema': draft202012Flat,
|
|
460
|
+
'https://json-schema.org/draft/2019-09/schema': draft201909Flat
|
|
457
461
|
}
|
|
458
462
|
};
|
|
459
463
|
const descriptions = {
|
|
@@ -44,59 +44,59 @@ export class JSONHover {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
|
|
47
|
-
if (schema
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
47
|
+
if (!schema) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
let title = undefined;
|
|
51
|
+
let markdownDescription = undefined;
|
|
52
|
+
let markdownEnumValueDescription = undefined, enumValue = undefined;
|
|
53
|
+
const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset).filter((s) => s.node === node && !s.inverted).map((s) => s.schema);
|
|
54
|
+
for (const schema of matchingSchemas) {
|
|
55
|
+
title = title || schema.title;
|
|
56
|
+
markdownDescription = markdownDescription || schema.markdownDescription || toMarkdown(schema.description);
|
|
57
|
+
if (schema.enum) {
|
|
58
|
+
const idx = schema.enum.indexOf(Parser.getNodeValue(node));
|
|
59
|
+
if (schema.markdownEnumDescriptions) {
|
|
60
|
+
markdownEnumValueDescription = schema.markdownEnumDescriptions[idx];
|
|
61
|
+
}
|
|
62
|
+
else if (schema.enumDescriptions) {
|
|
63
|
+
markdownEnumValueDescription = toMarkdown(schema.enumDescriptions[idx]);
|
|
64
|
+
}
|
|
65
|
+
if (markdownEnumValueDescription) {
|
|
66
|
+
enumValue = schema.enum[idx];
|
|
67
|
+
if (typeof enumValue !== 'string') {
|
|
68
|
+
enumValue = JSON.stringify(enumValue);
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
|
-
return true;
|
|
73
|
-
});
|
|
74
|
-
let result = '';
|
|
75
|
-
if (title) {
|
|
76
|
-
result = toMarkdown(title);
|
|
77
71
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
}
|
|
73
|
+
let result = '';
|
|
74
|
+
if (title) {
|
|
75
|
+
result = toMarkdown(title);
|
|
76
|
+
}
|
|
77
|
+
if (markdownDescription) {
|
|
78
|
+
if (result.length > 0) {
|
|
79
|
+
result += "\n\n";
|
|
83
80
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
result +=
|
|
81
|
+
result += markdownDescription;
|
|
82
|
+
}
|
|
83
|
+
if (markdownEnumValueDescription) {
|
|
84
|
+
if (result.length > 0) {
|
|
85
|
+
result += "\n\n";
|
|
89
86
|
}
|
|
90
|
-
|
|
87
|
+
result += `\`${toMarkdownCodeBlock(enumValue)}\`: ${markdownEnumValueDescription}`;
|
|
91
88
|
}
|
|
92
|
-
return
|
|
89
|
+
return createHover([result]);
|
|
93
90
|
});
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
93
|
function toMarkdown(plain) {
|
|
97
94
|
if (plain) {
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
return plain
|
|
96
|
+
.trim()
|
|
97
|
+
.replace(/[\\`*_{}[\]()<>#+\-.!]/g, '\\$&') // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
|
98
|
+
.replace(/([ \t]+)/g, (_match, g1) => ' '.repeat(g1.length)) // escape spaces tabs
|
|
99
|
+
.replace(/\n/g, '\\\n'); // escape new lines
|
|
100
100
|
}
|
|
101
101
|
return undefined;
|
|
102
102
|
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
$id: string;
|
|
3
|
+
$schema: string;
|
|
4
|
+
title: string;
|
|
5
|
+
type: string[];
|
|
6
|
+
properties: {
|
|
7
|
+
definitions: {
|
|
8
|
+
$comment: string;
|
|
9
|
+
type: string;
|
|
10
|
+
additionalProperties: {
|
|
11
|
+
$ref: string;
|
|
12
|
+
};
|
|
13
|
+
default: {};
|
|
14
|
+
};
|
|
15
|
+
dependencies: {
|
|
16
|
+
$comment: string;
|
|
17
|
+
type: string;
|
|
18
|
+
additionalProperties: {
|
|
19
|
+
anyOf: {
|
|
20
|
+
$ref: string;
|
|
21
|
+
}[];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
$id: {
|
|
25
|
+
type: string;
|
|
26
|
+
format: string;
|
|
27
|
+
$comment: string;
|
|
28
|
+
pattern: string;
|
|
29
|
+
};
|
|
30
|
+
$schema: {
|
|
31
|
+
type: string;
|
|
32
|
+
format: string;
|
|
33
|
+
};
|
|
34
|
+
$anchor: {
|
|
35
|
+
type: string;
|
|
36
|
+
pattern: string;
|
|
37
|
+
};
|
|
38
|
+
$ref: {
|
|
39
|
+
type: string;
|
|
40
|
+
format: string;
|
|
41
|
+
};
|
|
42
|
+
$recursiveAnchor: {
|
|
43
|
+
type: string;
|
|
44
|
+
default: boolean;
|
|
45
|
+
};
|
|
46
|
+
$vocabulary: {
|
|
47
|
+
type: string;
|
|
48
|
+
propertyNames: {
|
|
49
|
+
type: string;
|
|
50
|
+
format: string;
|
|
51
|
+
};
|
|
52
|
+
additionalProperties: {
|
|
53
|
+
type: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
$comment: {
|
|
57
|
+
type: string;
|
|
58
|
+
};
|
|
59
|
+
$defs: {
|
|
60
|
+
type: string;
|
|
61
|
+
additionalProperties: {
|
|
62
|
+
$ref: string;
|
|
63
|
+
};
|
|
64
|
+
default: {};
|
|
65
|
+
};
|
|
66
|
+
additionalItems: {
|
|
67
|
+
$ref: string;
|
|
68
|
+
};
|
|
69
|
+
unevaluatedItems: {
|
|
70
|
+
$ref: string;
|
|
71
|
+
};
|
|
72
|
+
items: {
|
|
73
|
+
anyOf: {
|
|
74
|
+
$ref: string;
|
|
75
|
+
}[];
|
|
76
|
+
};
|
|
77
|
+
contains: {
|
|
78
|
+
$ref: string;
|
|
79
|
+
};
|
|
80
|
+
additionalProperties: {
|
|
81
|
+
$ref: string;
|
|
82
|
+
};
|
|
83
|
+
unevaluatedProperties: {
|
|
84
|
+
$ref: string;
|
|
85
|
+
};
|
|
86
|
+
properties: {
|
|
87
|
+
type: string;
|
|
88
|
+
additionalProperties: {
|
|
89
|
+
$ref: string;
|
|
90
|
+
};
|
|
91
|
+
default: {};
|
|
92
|
+
};
|
|
93
|
+
patternProperties: {
|
|
94
|
+
type: string;
|
|
95
|
+
additionalProperties: {
|
|
96
|
+
$ref: string;
|
|
97
|
+
};
|
|
98
|
+
propertyNames: {
|
|
99
|
+
format: string;
|
|
100
|
+
};
|
|
101
|
+
default: {};
|
|
102
|
+
};
|
|
103
|
+
dependentSchemas: {
|
|
104
|
+
type: string;
|
|
105
|
+
additionalProperties: {
|
|
106
|
+
$ref: string;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
propertyNames: {
|
|
110
|
+
$ref: string;
|
|
111
|
+
};
|
|
112
|
+
if: {
|
|
113
|
+
$ref: string;
|
|
114
|
+
};
|
|
115
|
+
then: {
|
|
116
|
+
$ref: string;
|
|
117
|
+
};
|
|
118
|
+
else: {
|
|
119
|
+
$ref: string;
|
|
120
|
+
};
|
|
121
|
+
allOf: {
|
|
122
|
+
$ref: string;
|
|
123
|
+
};
|
|
124
|
+
anyOf: {
|
|
125
|
+
$ref: string;
|
|
126
|
+
};
|
|
127
|
+
oneOf: {
|
|
128
|
+
$ref: string;
|
|
129
|
+
};
|
|
130
|
+
not: {
|
|
131
|
+
$ref: string;
|
|
132
|
+
};
|
|
133
|
+
multipleOf: {
|
|
134
|
+
type: string;
|
|
135
|
+
exclusiveMinimum: number;
|
|
136
|
+
};
|
|
137
|
+
maximum: {
|
|
138
|
+
type: string;
|
|
139
|
+
};
|
|
140
|
+
exclusiveMaximum: {
|
|
141
|
+
type: string;
|
|
142
|
+
};
|
|
143
|
+
minimum: {
|
|
144
|
+
type: string;
|
|
145
|
+
};
|
|
146
|
+
exclusiveMinimum: {
|
|
147
|
+
type: string;
|
|
148
|
+
};
|
|
149
|
+
maxLength: {
|
|
150
|
+
$ref: string;
|
|
151
|
+
};
|
|
152
|
+
minLength: {
|
|
153
|
+
$ref: string;
|
|
154
|
+
};
|
|
155
|
+
pattern: {
|
|
156
|
+
type: string;
|
|
157
|
+
format: string;
|
|
158
|
+
};
|
|
159
|
+
maxItems: {
|
|
160
|
+
$ref: string;
|
|
161
|
+
};
|
|
162
|
+
minItems: {
|
|
163
|
+
$ref: string;
|
|
164
|
+
};
|
|
165
|
+
uniqueItems: {
|
|
166
|
+
type: string;
|
|
167
|
+
default: boolean;
|
|
168
|
+
};
|
|
169
|
+
maxContains: {
|
|
170
|
+
$ref: string;
|
|
171
|
+
};
|
|
172
|
+
minContains: {
|
|
173
|
+
$ref: string;
|
|
174
|
+
default: number;
|
|
175
|
+
};
|
|
176
|
+
maxProperties: {
|
|
177
|
+
$ref: string;
|
|
178
|
+
};
|
|
179
|
+
minProperties: {
|
|
180
|
+
$ref: string;
|
|
181
|
+
};
|
|
182
|
+
required: {
|
|
183
|
+
$ref: string;
|
|
184
|
+
};
|
|
185
|
+
dependentRequired: {
|
|
186
|
+
type: string;
|
|
187
|
+
additionalProperties: {
|
|
188
|
+
$ref: string;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
const: boolean;
|
|
192
|
+
enum: {
|
|
193
|
+
type: string;
|
|
194
|
+
items: boolean;
|
|
195
|
+
};
|
|
196
|
+
type: {
|
|
197
|
+
anyOf: ({
|
|
198
|
+
$ref: string;
|
|
199
|
+
type?: undefined;
|
|
200
|
+
items?: undefined;
|
|
201
|
+
minItems?: undefined;
|
|
202
|
+
uniqueItems?: undefined;
|
|
203
|
+
} | {
|
|
204
|
+
type: string;
|
|
205
|
+
items: {
|
|
206
|
+
$ref: string;
|
|
207
|
+
};
|
|
208
|
+
minItems: number;
|
|
209
|
+
uniqueItems: boolean;
|
|
210
|
+
$ref?: undefined;
|
|
211
|
+
})[];
|
|
212
|
+
};
|
|
213
|
+
title: {
|
|
214
|
+
type: string;
|
|
215
|
+
};
|
|
216
|
+
description: {
|
|
217
|
+
type: string;
|
|
218
|
+
};
|
|
219
|
+
default: boolean;
|
|
220
|
+
deprecated: {
|
|
221
|
+
type: string;
|
|
222
|
+
default: boolean;
|
|
223
|
+
};
|
|
224
|
+
readOnly: {
|
|
225
|
+
type: string;
|
|
226
|
+
default: boolean;
|
|
227
|
+
};
|
|
228
|
+
writeOnly: {
|
|
229
|
+
type: string;
|
|
230
|
+
default: boolean;
|
|
231
|
+
};
|
|
232
|
+
examples: {
|
|
233
|
+
type: string;
|
|
234
|
+
items: boolean;
|
|
235
|
+
};
|
|
236
|
+
format: {
|
|
237
|
+
type: string;
|
|
238
|
+
};
|
|
239
|
+
contentMediaType: {
|
|
240
|
+
type: string;
|
|
241
|
+
};
|
|
242
|
+
contentEncoding: {
|
|
243
|
+
type: string;
|
|
244
|
+
};
|
|
245
|
+
contentSchema: {
|
|
246
|
+
$ref: string;
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
$defs: {
|
|
250
|
+
schemaArray: {
|
|
251
|
+
type: string;
|
|
252
|
+
minItems: number;
|
|
253
|
+
items: {
|
|
254
|
+
$ref: string;
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
nonNegativeInteger: {
|
|
258
|
+
type: string;
|
|
259
|
+
minimum: number;
|
|
260
|
+
};
|
|
261
|
+
nonNegativeIntegerDefault0: {
|
|
262
|
+
$ref: string;
|
|
263
|
+
default: number;
|
|
264
|
+
};
|
|
265
|
+
simpleTypes: {
|
|
266
|
+
enum: string[];
|
|
267
|
+
};
|
|
268
|
+
stringArray: {
|
|
269
|
+
type: string;
|
|
270
|
+
items: {
|
|
271
|
+
type: string;
|
|
272
|
+
};
|
|
273
|
+
uniqueItems: boolean;
|
|
274
|
+
default: any[];
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
export default _default;
|