vscode-json-languageservice 4.2.0 → 5.1.0

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 (41) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/SECURITY.md +41 -0
  3. package/lib/esm/jsonLanguageService.js +22 -22
  4. package/lib/esm/jsonLanguageTypes.d.ts +3 -1
  5. package/lib/esm/jsonLanguageTypes.js +3 -2
  6. package/lib/esm/jsonSchema.d.ts +21 -2
  7. package/lib/esm/parser/jsonParser.js +488 -488
  8. package/lib/esm/services/configuration.js +9 -9
  9. package/lib/esm/services/jsonCompletion.js +280 -290
  10. package/lib/esm/services/jsonDocumentSymbols.js +88 -99
  11. package/lib/esm/services/jsonFolding.js +38 -39
  12. package/lib/esm/services/jsonHover.js +40 -43
  13. package/lib/esm/services/jsonLinks.js +12 -13
  14. package/lib/esm/services/jsonSchemaService.js +234 -253
  15. package/lib/esm/services/jsonSelectionRanges.js +9 -9
  16. package/lib/esm/services/jsonValidation.js +53 -51
  17. package/lib/esm/utils/colors.js +7 -8
  18. package/lib/esm/utils/glob.js +12 -12
  19. package/lib/esm/utils/json.js +7 -7
  20. package/lib/esm/utils/objects.js +3 -0
  21. package/lib/esm/utils/strings.js +3 -3
  22. package/lib/umd/jsonLanguageService.js +36 -32
  23. package/lib/umd/jsonLanguageTypes.d.ts +3 -1
  24. package/lib/umd/jsonLanguageTypes.js +5 -3
  25. package/lib/umd/jsonSchema.d.ts +21 -2
  26. package/lib/umd/parser/jsonParser.js +492 -482
  27. package/lib/umd/services/configuration.js +9 -9
  28. package/lib/umd/services/jsonCompletion.js +287 -296
  29. package/lib/umd/services/jsonDocumentSymbols.js +92 -102
  30. package/lib/umd/services/jsonFolding.js +40 -41
  31. package/lib/umd/services/jsonHover.js +42 -44
  32. package/lib/umd/services/jsonLinks.js +13 -14
  33. package/lib/umd/services/jsonSchemaService.js +241 -257
  34. package/lib/umd/services/jsonSelectionRanges.js +11 -11
  35. package/lib/umd/services/jsonValidation.js +56 -53
  36. package/lib/umd/utils/colors.js +7 -8
  37. package/lib/umd/utils/glob.js +12 -12
  38. package/lib/umd/utils/json.js +7 -7
  39. package/lib/umd/utils/objects.js +5 -1
  40. package/lib/umd/utils/strings.js +3 -3
  41. package/package.json +12 -12
@@ -8,16 +8,16 @@ import * as Strings from '../utils/strings';
8
8
  import * as Parser from '../parser/jsonParser';
9
9
  import * as nls from 'vscode-nls';
10
10
  import { createRegex } from '../utils/glob';
11
- var localize = nls.loadMessageBundle();
12
- var BANG = '!';
13
- var PATH_SEP = '/';
14
- var FilePatternAssociation = /** @class */ (function () {
15
- function FilePatternAssociation(pattern, uris) {
11
+ import { isObject, isString } from '../utils/objects';
12
+ const localize = nls.loadMessageBundle();
13
+ const BANG = '!';
14
+ const PATH_SEP = '/';
15
+ class FilePatternAssociation {
16
+ constructor(pattern, uris) {
16
17
  this.globWrappers = [];
17
18
  try {
18
- for (var _i = 0, pattern_1 = pattern; _i < pattern_1.length; _i++) {
19
- var patternString = pattern_1[_i];
20
- var include = patternString[0] !== BANG;
19
+ for (let patternString of pattern) {
20
+ const include = patternString[0] !== BANG;
21
21
  if (!include) {
22
22
  patternString = patternString.substring(1);
23
23
  }
@@ -39,23 +39,21 @@ var FilePatternAssociation = /** @class */ (function () {
39
39
  this.uris = [];
40
40
  }
41
41
  }
42
- FilePatternAssociation.prototype.matchesPattern = function (fileName) {
43
- var match = false;
44
- for (var _i = 0, _a = this.globWrappers; _i < _a.length; _i++) {
45
- var _b = _a[_i], regexp = _b.regexp, include = _b.include;
42
+ matchesPattern(fileName) {
43
+ let match = false;
44
+ for (const { regexp, include } of this.globWrappers) {
46
45
  if (regexp.test(fileName)) {
47
46
  match = include;
48
47
  }
49
48
  }
50
49
  return match;
51
- };
52
- FilePatternAssociation.prototype.getURIs = function () {
50
+ }
51
+ getURIs() {
53
52
  return this.uris;
54
- };
55
- return FilePatternAssociation;
56
- }());
57
- var SchemaHandle = /** @class */ (function () {
58
- function SchemaHandle(service, uri, unresolvedSchemaContent) {
53
+ }
54
+ }
55
+ class SchemaHandle {
56
+ constructor(service, uri, unresolvedSchemaContent) {
59
57
  this.service = service;
60
58
  this.uri = uri;
61
59
  this.dependencies = new Set();
@@ -64,66 +62,61 @@ var SchemaHandle = /** @class */ (function () {
64
62
  this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
65
63
  }
66
64
  }
67
- SchemaHandle.prototype.getUnresolvedSchema = function () {
65
+ getUnresolvedSchema() {
68
66
  if (!this.unresolvedSchema) {
69
67
  this.unresolvedSchema = this.service.loadSchema(this.uri);
70
68
  }
71
69
  return this.unresolvedSchema;
72
- };
73
- SchemaHandle.prototype.getResolvedSchema = function () {
74
- var _this = this;
70
+ }
71
+ getResolvedSchema() {
75
72
  if (!this.resolvedSchema) {
76
- this.resolvedSchema = this.getUnresolvedSchema().then(function (unresolved) {
77
- return _this.service.resolveSchemaContent(unresolved, _this);
73
+ this.resolvedSchema = this.getUnresolvedSchema().then(unresolved => {
74
+ return this.service.resolveSchemaContent(unresolved, this);
78
75
  });
79
76
  }
80
77
  return this.resolvedSchema;
81
- };
82
- SchemaHandle.prototype.clearSchema = function () {
83
- var hasChanges = !!this.unresolvedSchema;
78
+ }
79
+ clearSchema() {
80
+ const hasChanges = !!this.unresolvedSchema;
84
81
  this.resolvedSchema = undefined;
85
82
  this.unresolvedSchema = undefined;
86
83
  this.dependencies.clear();
87
84
  this.anchors = undefined;
88
85
  return hasChanges;
89
- };
90
- return SchemaHandle;
91
- }());
92
- var UnresolvedSchema = /** @class */ (function () {
93
- function UnresolvedSchema(schema, errors) {
94
- if (errors === void 0) { errors = []; }
86
+ }
87
+ }
88
+ export class UnresolvedSchema {
89
+ constructor(schema, errors = []) {
95
90
  this.schema = schema;
96
91
  this.errors = errors;
97
92
  }
98
- return UnresolvedSchema;
99
- }());
100
- export { UnresolvedSchema };
101
- var ResolvedSchema = /** @class */ (function () {
102
- function ResolvedSchema(schema, errors) {
103
- if (errors === void 0) { errors = []; }
93
+ }
94
+ export class ResolvedSchema {
95
+ constructor(schema, errors = [], warnings = [], schemaDraft) {
104
96
  this.schema = schema;
105
97
  this.errors = errors;
98
+ this.warnings = warnings;
99
+ this.schemaDraft = schemaDraft;
106
100
  }
107
- ResolvedSchema.prototype.getSection = function (path) {
108
- var schemaRef = this.getSectionRecursive(path, this.schema);
101
+ getSection(path) {
102
+ const schemaRef = this.getSectionRecursive(path, this.schema);
109
103
  if (schemaRef) {
110
104
  return Parser.asSchema(schemaRef);
111
105
  }
112
106
  return undefined;
113
- };
114
- ResolvedSchema.prototype.getSectionRecursive = function (path, schema) {
107
+ }
108
+ getSectionRecursive(path, schema) {
115
109
  if (!schema || typeof schema === 'boolean' || path.length === 0) {
116
110
  return schema;
117
111
  }
118
- var next = path.shift();
112
+ const next = path.shift();
119
113
  if (schema.properties && typeof schema.properties[next]) {
120
114
  return this.getSectionRecursive(path, schema.properties[next]);
121
115
  }
122
116
  else if (schema.patternProperties) {
123
- for (var _i = 0, _a = Object.keys(schema.patternProperties); _i < _a.length; _i++) {
124
- var pattern = _a[_i];
125
- var regex = Strings.extendedRegExp(pattern);
126
- if (regex === null || regex === void 0 ? void 0 : regex.test(next)) {
117
+ for (const pattern of Object.keys(schema.patternProperties)) {
118
+ const regex = Strings.extendedRegExp(pattern);
119
+ if (regex?.test(next)) {
127
120
  return this.getSectionRecursive(path, schema.patternProperties[pattern]);
128
121
  }
129
122
  }
@@ -133,7 +126,7 @@ var ResolvedSchema = /** @class */ (function () {
133
126
  }
134
127
  else if (next.match('[0-9]+')) {
135
128
  if (Array.isArray(schema.items)) {
136
- var index = parseInt(next, 10);
129
+ const index = parseInt(next, 10);
137
130
  if (!isNaN(index) && schema.items[index]) {
138
131
  return this.getSectionRecursive(path, schema.items[index]);
139
132
  }
@@ -143,12 +136,10 @@ var ResolvedSchema = /** @class */ (function () {
143
136
  }
144
137
  }
145
138
  return undefined;
146
- };
147
- return ResolvedSchema;
148
- }());
149
- export { ResolvedSchema };
150
- var JSONSchemaService = /** @class */ (function () {
151
- function JSONSchemaService(requestService, contextService, promiseConstructor) {
139
+ }
140
+ }
141
+ export class JSONSchemaService {
142
+ constructor(requestService, contextService, promiseConstructor) {
152
143
  this.contextService = contextService;
153
144
  this.requestService = requestService;
154
145
  this.promiseConstructor = promiseConstructor || Promise;
@@ -159,36 +150,31 @@ var JSONSchemaService = /** @class */ (function () {
159
150
  this.filePatternAssociations = [];
160
151
  this.registeredSchemasIds = {};
161
152
  }
162
- JSONSchemaService.prototype.getRegisteredSchemaIds = function (filter) {
163
- return Object.keys(this.registeredSchemasIds).filter(function (id) {
164
- var scheme = URI.parse(id).scheme;
153
+ getRegisteredSchemaIds(filter) {
154
+ return Object.keys(this.registeredSchemasIds).filter(id => {
155
+ const scheme = URI.parse(id).scheme;
165
156
  return scheme !== 'schemaservice' && (!filter || filter(scheme));
166
157
  });
167
- };
168
- Object.defineProperty(JSONSchemaService.prototype, "promise", {
169
- get: function () {
170
- return this.promiseConstructor;
171
- },
172
- enumerable: false,
173
- configurable: true
174
- });
175
- JSONSchemaService.prototype.dispose = function () {
158
+ }
159
+ get promise() {
160
+ return this.promiseConstructor;
161
+ }
162
+ dispose() {
176
163
  while (this.callOnDispose.length > 0) {
177
164
  this.callOnDispose.pop()();
178
165
  }
179
- };
180
- JSONSchemaService.prototype.onResourceChange = function (uri) {
181
- var _this = this;
166
+ }
167
+ onResourceChange(uri) {
182
168
  // always clear this local cache when a resource changes
183
169
  this.cachedSchemaForResource = undefined;
184
- var hasChanges = false;
170
+ let hasChanges = false;
185
171
  uri = normalizeId(uri);
186
- var toWalk = [uri];
187
- var all = Object.keys(this.schemasById).map(function (key) { return _this.schemasById[key]; });
172
+ const toWalk = [uri];
173
+ const all = Object.keys(this.schemasById).map(key => this.schemasById[key]);
188
174
  while (toWalk.length) {
189
- var curr = toWalk.pop();
190
- for (var i = 0; i < all.length; i++) {
191
- var handle = all[i];
175
+ const curr = toWalk.pop();
176
+ for (let i = 0; i < all.length; i++) {
177
+ const handle = all[i];
192
178
  if (handle && (handle.uri === curr || handle.dependencies.has(curr))) {
193
179
  if (handle.uri !== curr) {
194
180
  toWalk.push(handle.uri);
@@ -201,87 +187,85 @@ var JSONSchemaService = /** @class */ (function () {
201
187
  }
202
188
  }
203
189
  return hasChanges;
204
- };
205
- JSONSchemaService.prototype.setSchemaContributions = function (schemaContributions) {
190
+ }
191
+ setSchemaContributions(schemaContributions) {
206
192
  if (schemaContributions.schemas) {
207
- var schemas = schemaContributions.schemas;
208
- for (var id in schemas) {
209
- var normalizedId = normalizeId(id);
193
+ const schemas = schemaContributions.schemas;
194
+ for (const id in schemas) {
195
+ const normalizedId = normalizeId(id);
210
196
  this.contributionSchemas[normalizedId] = this.addSchemaHandle(normalizedId, schemas[id]);
211
197
  }
212
198
  }
213
199
  if (Array.isArray(schemaContributions.schemaAssociations)) {
214
- var schemaAssociations = schemaContributions.schemaAssociations;
215
- for (var _i = 0, schemaAssociations_1 = schemaAssociations; _i < schemaAssociations_1.length; _i++) {
216
- var schemaAssociation = schemaAssociations_1[_i];
217
- var uris = schemaAssociation.uris.map(normalizeId);
218
- var association = this.addFilePatternAssociation(schemaAssociation.pattern, uris);
200
+ const schemaAssociations = schemaContributions.schemaAssociations;
201
+ for (let schemaAssociation of schemaAssociations) {
202
+ const uris = schemaAssociation.uris.map(normalizeId);
203
+ const association = this.addFilePatternAssociation(schemaAssociation.pattern, uris);
219
204
  this.contributionAssociations.push(association);
220
205
  }
221
206
  }
222
- };
223
- JSONSchemaService.prototype.addSchemaHandle = function (id, unresolvedSchemaContent) {
224
- var schemaHandle = new SchemaHandle(this, id, unresolvedSchemaContent);
207
+ }
208
+ addSchemaHandle(id, unresolvedSchemaContent) {
209
+ const schemaHandle = new SchemaHandle(this, id, unresolvedSchemaContent);
225
210
  this.schemasById[id] = schemaHandle;
226
211
  return schemaHandle;
227
- };
228
- JSONSchemaService.prototype.getOrAddSchemaHandle = function (id, unresolvedSchemaContent) {
212
+ }
213
+ getOrAddSchemaHandle(id, unresolvedSchemaContent) {
229
214
  return this.schemasById[id] || this.addSchemaHandle(id, unresolvedSchemaContent);
230
- };
231
- JSONSchemaService.prototype.addFilePatternAssociation = function (pattern, uris) {
232
- var fpa = new FilePatternAssociation(pattern, uris);
215
+ }
216
+ addFilePatternAssociation(pattern, uris) {
217
+ const fpa = new FilePatternAssociation(pattern, uris);
233
218
  this.filePatternAssociations.push(fpa);
234
219
  return fpa;
235
- };
236
- JSONSchemaService.prototype.registerExternalSchema = function (uri, filePatterns, unresolvedSchemaContent) {
237
- var id = normalizeId(uri);
220
+ }
221
+ registerExternalSchema(uri, filePatterns, unresolvedSchemaContent) {
222
+ const id = normalizeId(uri);
238
223
  this.registeredSchemasIds[id] = true;
239
224
  this.cachedSchemaForResource = undefined;
240
225
  if (filePatterns) {
241
226
  this.addFilePatternAssociation(filePatterns, [id]);
242
227
  }
243
228
  return unresolvedSchemaContent ? this.addSchemaHandle(id, unresolvedSchemaContent) : this.getOrAddSchemaHandle(id);
244
- };
245
- JSONSchemaService.prototype.clearExternalSchemas = function () {
229
+ }
230
+ clearExternalSchemas() {
246
231
  this.schemasById = {};
247
232
  this.filePatternAssociations = [];
248
233
  this.registeredSchemasIds = {};
249
234
  this.cachedSchemaForResource = undefined;
250
- for (var id in this.contributionSchemas) {
235
+ for (const id in this.contributionSchemas) {
251
236
  this.schemasById[id] = this.contributionSchemas[id];
252
237
  this.registeredSchemasIds[id] = true;
253
238
  }
254
- for (var _i = 0, _a = this.contributionAssociations; _i < _a.length; _i++) {
255
- var contributionAssociation = _a[_i];
239
+ for (const contributionAssociation of this.contributionAssociations) {
256
240
  this.filePatternAssociations.push(contributionAssociation);
257
241
  }
258
- };
259
- JSONSchemaService.prototype.getResolvedSchema = function (schemaId) {
260
- var id = normalizeId(schemaId);
261
- var schemaHandle = this.schemasById[id];
242
+ }
243
+ getResolvedSchema(schemaId) {
244
+ const id = normalizeId(schemaId);
245
+ const schemaHandle = this.schemasById[id];
262
246
  if (schemaHandle) {
263
247
  return schemaHandle.getResolvedSchema();
264
248
  }
265
249
  return this.promise.resolve(undefined);
266
- };
267
- JSONSchemaService.prototype.loadSchema = function (url) {
250
+ }
251
+ loadSchema(url) {
268
252
  if (!this.requestService) {
269
- var errorMessage = localize('json.schema.norequestservice', 'Unable to load schema from \'{0}\'. No schema request service available', toDisplayString(url));
253
+ const errorMessage = localize('json.schema.norequestservice', 'Unable to load schema from \'{0}\'. No schema request service available', toDisplayString(url));
270
254
  return this.promise.resolve(new UnresolvedSchema({}, [errorMessage]));
271
255
  }
272
- return this.requestService(url).then(function (content) {
256
+ return this.requestService(url).then(content => {
273
257
  if (!content) {
274
- var errorMessage = localize('json.schema.nocontent', 'Unable to load schema from \'{0}\': No content.', toDisplayString(url));
258
+ const errorMessage = localize('json.schema.nocontent', 'Unable to load schema from \'{0}\': No content.', toDisplayString(url));
275
259
  return new UnresolvedSchema({}, [errorMessage]);
276
260
  }
277
- var schemaContent = {};
278
- var jsonErrors = [];
261
+ let schemaContent = {};
262
+ const jsonErrors = [];
279
263
  schemaContent = Json.parse(content, jsonErrors);
280
- var errors = jsonErrors.length ? [localize('json.schema.invalidFormat', 'Unable to parse content from \'{0}\': Parse error at offset {1}.', toDisplayString(url), jsonErrors[0].offset)] : [];
264
+ const errors = jsonErrors.length ? [localize('json.schema.invalidFormat', 'Unable to parse content from \'{0}\': Parse error at offset {1}.', toDisplayString(url), jsonErrors[0].offset)] : [];
281
265
  return new UnresolvedSchema(schemaContent, errors);
282
- }, function (error) {
283
- var errorMessage = error.toString();
284
- var errorSplit = error.toString().split('Error: ');
266
+ }, (error) => {
267
+ let errorMessage = error.toString();
268
+ const errorSplit = error.toString().split('Error: ');
285
269
  if (errorSplit.length > 1) {
286
270
  // more concise error message, URL and context are attached by caller anyways
287
271
  errorMessage = errorSplit[1];
@@ -291,52 +275,44 @@ var JSONSchemaService = /** @class */ (function () {
291
275
  }
292
276
  return new UnresolvedSchema({}, [localize('json.schema.nocontent', 'Unable to load schema from \'{0}\': {1}.', toDisplayString(url), errorMessage)]);
293
277
  });
294
- };
295
- JSONSchemaService.prototype.resolveSchemaContent = function (schemaToResolve, handle) {
296
- var _this = this;
297
- var resolveErrors = schemaToResolve.errors.slice(0);
298
- var schema = schemaToResolve.schema;
299
- if (schema.$schema) {
300
- var id = normalizeId(schema.$schema);
301
- if (id === 'http://json-schema.org/draft-03/schema') {
302
- return this.promise.resolve(new ResolvedSchema({}, [localize('json.schema.draft03.notsupported', "Draft-03 schemas are not supported.")]));
303
- }
304
- else if (id === 'https://json-schema.org/draft/2019-09/schema') {
305
- resolveErrors.push(localize('json.schema.draft201909.notsupported', "Draft 2019-09 schemas are not yet fully supported."));
306
- }
307
- else if (id === 'https://json-schema.org/draft/2020-12/schema') {
308
- resolveErrors.push(localize('json.schema.draft202012.notsupported', "Draft 2020-12 schemas are not yet fully supported."));
309
- }
310
- }
311
- var contextService = this.contextService;
312
- var findSectionByJSONPointer = function (schema, path) {
278
+ }
279
+ resolveSchemaContent(schemaToResolve, handle) {
280
+ const resolveErrors = schemaToResolve.errors.slice(0);
281
+ const schema = schemaToResolve.schema;
282
+ let schemaDraft = schema.$schema ? normalizeId(schema.$schema) : undefined;
283
+ if (schemaDraft === 'http://json-schema.org/draft-03/schema') {
284
+ return this.promise.resolve(new ResolvedSchema({}, [localize('json.schema.draft03.notsupported', "Draft-03 schemas are not supported.")], [], schemaDraft));
285
+ }
286
+ let usesUnsupportedFeatures = new Set();
287
+ const contextService = this.contextService;
288
+ const findSectionByJSONPointer = (schema, path) => {
313
289
  path = decodeURIComponent(path);
314
- var current = schema;
290
+ let current = schema;
315
291
  if (path[0] === '/') {
316
292
  path = path.substring(1);
317
293
  }
318
- path.split('/').some(function (part) {
294
+ path.split('/').some((part) => {
319
295
  part = part.replace(/~1/g, '/').replace(/~0/g, '~');
320
296
  current = current[part];
321
297
  return !current;
322
298
  });
323
299
  return current;
324
300
  };
325
- var findSchemaById = function (schema, handle, id) {
301
+ const findSchemaById = (schema, handle, id) => {
326
302
  if (!handle.anchors) {
327
303
  handle.anchors = collectAnchors(schema);
328
304
  }
329
305
  return handle.anchors.get(id);
330
306
  };
331
- var merge = function (target, section) {
332
- for (var key in section) {
307
+ const merge = (target, section) => {
308
+ for (const key in section) {
333
309
  if (section.hasOwnProperty(key) && !target.hasOwnProperty(key) && key !== 'id' && key !== '$id') {
334
310
  target[key] = section[key];
335
311
  }
336
312
  }
337
313
  };
338
- var mergeRef = function (target, sourceRoot, sourceHandle, refSegment) {
339
- var section;
314
+ const mergeRef = (target, sourceRoot, sourceHandle, refSegment) => {
315
+ let section;
340
316
  if (refSegment === undefined || refSegment.length === 0) {
341
317
  section = sourceRoot;
342
318
  }
@@ -355,29 +331,29 @@ var JSONSchemaService = /** @class */ (function () {
355
331
  resolveErrors.push(localize('json.schema.invalidid', '$ref \'{0}\' in \'{1}\' can not be resolved.', refSegment, sourceHandle.uri));
356
332
  }
357
333
  };
358
- var resolveExternalLink = function (node, uri, refSegment, parentHandle) {
334
+ const resolveExternalLink = (node, uri, refSegment, parentHandle) => {
359
335
  if (contextService && !/^[A-Za-z][A-Za-z0-9+\-.+]*:\/\/.*/.test(uri)) {
360
336
  uri = contextService.resolveRelativePath(uri, parentHandle.uri);
361
337
  }
362
338
  uri = normalizeId(uri);
363
- var referencedHandle = _this.getOrAddSchemaHandle(uri);
364
- return referencedHandle.getUnresolvedSchema().then(function (unresolvedSchema) {
339
+ const referencedHandle = this.getOrAddSchemaHandle(uri);
340
+ return referencedHandle.getUnresolvedSchema().then(unresolvedSchema => {
365
341
  parentHandle.dependencies.add(uri);
366
342
  if (unresolvedSchema.errors.length) {
367
- var loc = refSegment ? uri + '#' + refSegment : uri;
343
+ const loc = refSegment ? uri + '#' + refSegment : uri;
368
344
  resolveErrors.push(localize('json.schema.problemloadingref', 'Problems loading reference \'{0}\': {1}', loc, unresolvedSchema.errors[0]));
369
345
  }
370
346
  mergeRef(node, unresolvedSchema.schema, referencedHandle, refSegment);
371
347
  return resolveRefs(node, unresolvedSchema.schema, referencedHandle);
372
348
  });
373
349
  };
374
- var resolveRefs = function (node, parentSchema, parentHandle) {
375
- var openPromises = [];
376
- _this.traverseNodes(node, function (next) {
377
- var seenRefs = new Set();
350
+ const resolveRefs = (node, parentSchema, parentHandle) => {
351
+ const openPromises = [];
352
+ this.traverseNodes(node, next => {
353
+ const seenRefs = new Set();
378
354
  while (next.$ref) {
379
- var ref = next.$ref;
380
- var segments = ref.split('#', 2);
355
+ const ref = next.$ref;
356
+ const segments = ref.split('#', 2);
381
357
  delete next.$ref;
382
358
  if (segments[0].length > 0) {
383
359
  // This is a reference to an external schema
@@ -387,110 +363,119 @@ var JSONSchemaService = /** @class */ (function () {
387
363
  else {
388
364
  // This is a reference inside the current schema
389
365
  if (!seenRefs.has(ref)) {
390
- var id = segments[1];
366
+ const id = segments[1];
391
367
  mergeRef(next, parentSchema, parentHandle, id);
392
368
  seenRefs.add(ref);
393
369
  }
394
370
  }
395
371
  }
372
+ if (next.$recursiveRef) {
373
+ usesUnsupportedFeatures.add('$recursiveRef');
374
+ }
375
+ if (next.$dynamicRef) {
376
+ usesUnsupportedFeatures.add('$dynamicRef');
377
+ }
396
378
  });
397
- return _this.promise.all(openPromises);
379
+ return this.promise.all(openPromises);
398
380
  };
399
- var collectAnchors = function (root) {
400
- var result = new Map();
401
- _this.traverseNodes(root, function (next) {
402
- var id = next.$id || next.id;
403
- if (typeof id === 'string' && id.charAt(0) === '#') {
404
- // delete next.$id;
405
- // delete next.id;
406
- var anchor = id.substring(1);
381
+ const collectAnchors = (root) => {
382
+ const result = new Map();
383
+ this.traverseNodes(root, next => {
384
+ const id = next.$id || next.id;
385
+ const anchor = isString(id) && id.charAt(0) === '#' ? id.substring(1) : next.$anchor;
386
+ if (anchor) {
407
387
  if (result.has(anchor)) {
408
- resolveErrors.push(localize('json.schema.duplicateid', 'Duplicate id declaration: \'{0}\'', id));
388
+ resolveErrors.push(localize('json.schema.duplicateid', 'Duplicate anchor declaration: \'{0}\'', anchor));
409
389
  }
410
390
  else {
411
391
  result.set(anchor, next);
412
392
  }
413
393
  }
394
+ if (next.$recursiveAnchor) {
395
+ usesUnsupportedFeatures.add('$recursiveAnchor');
396
+ }
397
+ if (next.$dynamicAnchor) {
398
+ usesUnsupportedFeatures.add('$dynamicAnchor');
399
+ }
414
400
  });
415
401
  return result;
416
402
  };
417
- return resolveRefs(schema, schema, handle).then(function (_) {
418
- return new ResolvedSchema(schema, resolveErrors);
403
+ return resolveRefs(schema, schema, handle).then(_ => {
404
+ let resolveWarnings = [];
405
+ if (usesUnsupportedFeatures.size) {
406
+ resolveWarnings.push(localize('json.schema.warnings', 'The schema uses meta-schema features ({0}) that are not yet supported by the validator.', Array.from(usesUnsupportedFeatures.keys()).join(', ')));
407
+ }
408
+ return new ResolvedSchema(schema, resolveErrors, resolveWarnings, schemaDraft);
419
409
  });
420
- };
421
- JSONSchemaService.prototype.traverseNodes = function (root, handle) {
410
+ }
411
+ traverseNodes(root, handle) {
422
412
  if (!root || typeof root !== 'object') {
423
413
  return Promise.resolve(null);
424
414
  }
425
- var seen = new Set();
426
- var collectEntries = function () {
427
- var entries = [];
428
- for (var _i = 0; _i < arguments.length; _i++) {
429
- entries[_i] = arguments[_i];
430
- }
431
- for (var _a = 0, entries_1 = entries; _a < entries_1.length; _a++) {
432
- var entry = entries_1[_a];
433
- if (typeof entry === 'object') {
415
+ const seen = new Set();
416
+ const collectEntries = (...entries) => {
417
+ for (const entry of entries) {
418
+ if (isObject(entry)) {
434
419
  toWalk.push(entry);
435
420
  }
436
421
  }
437
422
  };
438
- var collectMapEntries = function () {
439
- var maps = [];
440
- for (var _i = 0; _i < arguments.length; _i++) {
441
- maps[_i] = arguments[_i];
442
- }
443
- for (var _a = 0, maps_1 = maps; _a < maps_1.length; _a++) {
444
- var map = maps_1[_a];
445
- if (typeof map === 'object') {
446
- for (var k in map) {
447
- var key = k;
448
- var entry = map[key];
449
- if (typeof entry === 'object') {
423
+ const collectMapEntries = (...maps) => {
424
+ for (const map of maps) {
425
+ if (isObject(map)) {
426
+ for (const k in map) {
427
+ const key = k;
428
+ const entry = map[key];
429
+ if (isObject(entry)) {
450
430
  toWalk.push(entry);
451
431
  }
452
432
  }
453
433
  }
454
434
  }
455
435
  };
456
- var collectArrayEntries = function () {
457
- var arrays = [];
458
- for (var _i = 0; _i < arguments.length; _i++) {
459
- arrays[_i] = arguments[_i];
460
- }
461
- for (var _a = 0, arrays_1 = arrays; _a < arrays_1.length; _a++) {
462
- var array = arrays_1[_a];
436
+ const collectArrayEntries = (...arrays) => {
437
+ for (const array of arrays) {
463
438
  if (Array.isArray(array)) {
464
- for (var _b = 0, array_1 = array; _b < array_1.length; _b++) {
465
- var entry = array_1[_b];
466
- if (typeof entry === 'object') {
439
+ for (const entry of array) {
440
+ if (isObject(entry)) {
467
441
  toWalk.push(entry);
468
442
  }
469
443
  }
470
444
  }
471
445
  }
472
446
  };
473
- var toWalk = [root];
474
- var next = toWalk.pop();
447
+ const collectEntryOrArrayEntries = (items) => {
448
+ if (Array.isArray(items)) {
449
+ for (const entry of items) {
450
+ if (isObject(entry)) {
451
+ toWalk.push(entry);
452
+ }
453
+ }
454
+ }
455
+ else if (isObject(items)) {
456
+ toWalk.push(items);
457
+ }
458
+ };
459
+ const toWalk = [root];
460
+ let next = toWalk.pop();
475
461
  while (next) {
476
462
  if (!seen.has(next)) {
477
463
  seen.add(next);
478
464
  handle(next);
479
- collectEntries(next.items, next.additionalItems, next.additionalProperties, next.not, next.contains, next.propertyNames, next.if, next.then, next.else);
480
- collectMapEntries(next.definitions, next.properties, next.patternProperties, next.dependencies);
481
- collectArrayEntries(next.anyOf, next.allOf, next.oneOf, next.items);
465
+ collectEntries(next.additionalItems, next.additionalProperties, next.not, next.contains, next.propertyNames, next.if, next.then, next.else, next.unevaluatedItems, next.unevaluatedProperties);
466
+ collectMapEntries(next.definitions, next.$defs, next.properties, next.patternProperties, next.dependencies, next.dependentSchemas);
467
+ collectArrayEntries(next.anyOf, next.allOf, next.oneOf, next.prefixItems);
468
+ collectEntryOrArrayEntries(next.items);
482
469
  }
483
470
  next = toWalk.pop();
484
471
  }
485
- };
472
+ }
486
473
  ;
487
- JSONSchemaService.prototype.getSchemaFromProperty = function (resource, document) {
488
- var _a, _b;
489
- if (((_a = document.root) === null || _a === void 0 ? void 0 : _a.type) === 'object') {
490
- for (var _i = 0, _c = document.root.properties; _i < _c.length; _i++) {
491
- var p = _c[_i];
492
- if (p.keyNode.value === '$schema' && ((_b = p.valueNode) === null || _b === void 0 ? void 0 : _b.type) === 'string') {
493
- var schemaId = p.valueNode.value;
474
+ getSchemaFromProperty(resource, document) {
475
+ if (document.root?.type === 'object') {
476
+ for (const p of document.root.properties) {
477
+ if (p.keyNode.value === '$schema' && p.valueNode?.type === 'string') {
478
+ let schemaId = p.valueNode.value;
494
479
  if (this.contextService && !/^\w[\w\d+.-]*:/.test(schemaId)) { // has scheme
495
480
  schemaId = this.contextService.resolveRelativePath(schemaId, resource);
496
481
  }
@@ -499,16 +484,14 @@ var JSONSchemaService = /** @class */ (function () {
499
484
  }
500
485
  }
501
486
  return undefined;
502
- };
503
- JSONSchemaService.prototype.getAssociatedSchemas = function (resource) {
504
- var seen = Object.create(null);
505
- var schemas = [];
506
- var normalizedResource = normalizeResourceForMatching(resource);
507
- for (var _i = 0, _a = this.filePatternAssociations; _i < _a.length; _i++) {
508
- var entry = _a[_i];
487
+ }
488
+ getAssociatedSchemas(resource) {
489
+ const seen = Object.create(null);
490
+ const schemas = [];
491
+ const normalizedResource = normalizeResourceForMatching(resource);
492
+ for (const entry of this.filePatternAssociations) {
509
493
  if (entry.matchesPattern(normalizedResource)) {
510
- for (var _b = 0, _c = entry.getURIs(); _b < _c.length; _b++) {
511
- var schemaId = _c[_b];
494
+ for (const schemaId of entry.getURIs()) {
512
495
  if (!seen[schemaId]) {
513
496
  schemas.push(schemaId);
514
497
  seen[schemaId] = true;
@@ -517,66 +500,64 @@ var JSONSchemaService = /** @class */ (function () {
517
500
  }
518
501
  }
519
502
  return schemas;
520
- };
521
- JSONSchemaService.prototype.getSchemaURIsForResource = function (resource, document) {
522
- var schemeId = document && this.getSchemaFromProperty(resource, document);
503
+ }
504
+ getSchemaURIsForResource(resource, document) {
505
+ let schemeId = document && this.getSchemaFromProperty(resource, document);
523
506
  if (schemeId) {
524
507
  return [schemeId];
525
508
  }
526
509
  return this.getAssociatedSchemas(resource);
527
- };
528
- JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
510
+ }
511
+ getSchemaForResource(resource, document) {
529
512
  if (document) {
530
513
  // first use $schema if present
531
- var schemeId = this.getSchemaFromProperty(resource, document);
514
+ let schemeId = this.getSchemaFromProperty(resource, document);
532
515
  if (schemeId) {
533
- var id = normalizeId(schemeId);
516
+ const id = normalizeId(schemeId);
534
517
  return this.getOrAddSchemaHandle(id).getResolvedSchema();
535
518
  }
536
519
  }
537
520
  if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
538
521
  return this.cachedSchemaForResource.resolvedSchema;
539
522
  }
540
- var schemas = this.getAssociatedSchemas(resource);
541
- var resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
542
- this.cachedSchemaForResource = { resource: resource, resolvedSchema: resolvedSchema };
523
+ const schemas = this.getAssociatedSchemas(resource);
524
+ const resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
525
+ this.cachedSchemaForResource = { resource, resolvedSchema };
543
526
  return resolvedSchema;
544
- };
545
- JSONSchemaService.prototype.createCombinedSchema = function (resource, schemaIds) {
527
+ }
528
+ createCombinedSchema(resource, schemaIds) {
546
529
  if (schemaIds.length === 1) {
547
530
  return this.getOrAddSchemaHandle(schemaIds[0]);
548
531
  }
549
532
  else {
550
- var combinedSchemaId = 'schemaservice://combinedSchema/' + encodeURIComponent(resource);
551
- var combinedSchema = {
552
- allOf: schemaIds.map(function (schemaId) { return ({ $ref: schemaId }); })
533
+ const combinedSchemaId = 'schemaservice://combinedSchema/' + encodeURIComponent(resource);
534
+ const combinedSchema = {
535
+ allOf: schemaIds.map(schemaId => ({ $ref: schemaId }))
553
536
  };
554
537
  return this.addSchemaHandle(combinedSchemaId, combinedSchema);
555
538
  }
556
- };
557
- JSONSchemaService.prototype.getMatchingSchemas = function (document, jsonDocument, schema) {
539
+ }
540
+ getMatchingSchemas(document, jsonDocument, schema) {
558
541
  if (schema) {
559
- var id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
560
- var handle = this.addSchemaHandle(id, schema);
561
- return handle.getResolvedSchema().then(function (resolvedSchema) {
562
- return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(function (s) { return !s.inverted; });
542
+ const id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
543
+ const handle = this.addSchemaHandle(id, schema);
544
+ return handle.getResolvedSchema().then(resolvedSchema => {
545
+ return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(s => !s.inverted);
563
546
  });
564
547
  }
565
- return this.getSchemaForResource(document.uri, jsonDocument).then(function (schema) {
548
+ return this.getSchemaForResource(document.uri, jsonDocument).then(schema => {
566
549
  if (schema) {
567
- return jsonDocument.getMatchingSchemas(schema.schema).filter(function (s) { return !s.inverted; });
550
+ return jsonDocument.getMatchingSchemas(schema.schema).filter(s => !s.inverted);
568
551
  }
569
552
  return [];
570
553
  });
571
- };
572
- return JSONSchemaService;
573
- }());
574
- export { JSONSchemaService };
575
- var idCounter = 0;
554
+ }
555
+ }
556
+ let idCounter = 0;
576
557
  function normalizeId(id) {
577
558
  // remove trailing '#', normalize drive capitalization
578
559
  try {
579
- return URI.parse(id).toString();
560
+ return URI.parse(id).toString(true);
580
561
  }
581
562
  catch (e) {
582
563
  return id;
@@ -585,7 +566,7 @@ function normalizeId(id) {
585
566
  function normalizeResourceForMatching(resource) {
586
567
  // remove queries and fragments, normalize drive capitalization
587
568
  try {
588
- return URI.parse(resource).with({ fragment: null, query: null }).toString();
569
+ return URI.parse(resource).with({ fragment: null, query: null }).toString(true);
589
570
  }
590
571
  catch (e) {
591
572
  return resource;
@@ -593,7 +574,7 @@ function normalizeResourceForMatching(resource) {
593
574
  }
594
575
  function toDisplayString(url) {
595
576
  try {
596
- var uri = URI.parse(url);
577
+ const uri = URI.parse(url);
597
578
  if (uri.scheme === 'file') {
598
579
  return uri.fsPath;
599
580
  }