@@ -16,6 +16,27 @@ const localize = nls.loadMessageBundle();
1616
1717export declare type CustomSchemaProvider = ( uri : string ) => Thenable < string > ;
1818
19+ export enum MODIFICATION_ACTIONS {
20+ 'delete' ,
21+ 'add'
22+ }
23+
24+ export interface SchemaAdditions {
25+ schema : string ,
26+ action : MODIFICATION_ACTIONS . add ,
27+ path : string ,
28+ key : string ,
29+ // tslint:disable-next-line: no-any
30+ content : any
31+ }
32+
33+ export interface SchemaDeletions {
34+ schema : string ,
35+ action : MODIFICATION_ACTIONS . delete ,
36+ path : string ,
37+ key : string
38+ }
39+
1940export class FilePatternAssociation {
2041
2142 private schemas : string [ ] ;
@@ -45,6 +66,9 @@ export class FilePatternAssociation {
4566}
4667
4768export class YAMLSchemaService extends JSONSchemaService {
69+ // To allow to use schemasById from super.
70+ // tslint:disable-next-line: no-any
71+ [ x : string ] : any ;
4872
4973 private customSchemaProvider : CustomSchemaProvider | undefined ;
5074 private filePatternAssociations : FilePatternAssociation [ ] ;
@@ -236,6 +260,89 @@ export class YAMLSchemaService extends JSONSchemaService {
236260 }
237261 }
238262
263+ /**
264+ * Save a schema with schema ID and schema content.
265+ * Overrides previous schemas set for that schema ID.
266+ */
267+ public async saveSchema ( schemaId : string , schemaContent : JSONSchema ) : Promise < void > {
268+ const id = this . normalizeId ( schemaId ) ;
269+ this . getOrAddSchemaHandle ( id , schemaContent ) ;
270+ return Promise . resolve ( undefined ) ;
271+ }
272+
273+ /**
274+ * Delete a schema with schema ID.
275+ */
276+ public async deleteSchema ( schemaId : string ) : Promise < void > {
277+ const id = this . normalizeId ( schemaId ) ;
278+ if ( this . schemasById [ id ] ) {
279+ delete this . schemasById [ id ] ;
280+ }
281+ return Promise . resolve ( undefined ) ;
282+ }
283+
284+ /**
285+ * Add content to a specified schema at a specified path
286+ */
287+ public async addContent ( additions : SchemaAdditions ) {
288+ const schema = await this . getResolvedSchema ( additions . schema ) ;
289+ if ( schema ) {
290+ const resolvedSchemaLocation = this . resolveJSONSchemaToSection ( schema . schema , additions . path ) ;
291+
292+ if ( typeof resolvedSchemaLocation === 'object' ) {
293+ resolvedSchemaLocation [ additions . key ] = additions . content ;
294+ }
295+ await this . saveSchema ( additions . schema , schema . schema ) ;
296+ }
297+ }
298+
299+ /**
300+ * Delete content in a specified schema at a specified path
301+ */
302+ public async deleteContent ( deletions : SchemaDeletions ) {
303+ const schema = await this . getResolvedSchema ( deletions . schema ) ;
304+ if ( schema ) {
305+ const resolvedSchemaLocation = this . resolveJSONSchemaToSection ( schema . schema , deletions . path ) ;
306+
307+ if ( typeof resolvedSchemaLocation === 'object' ) {
308+ delete resolvedSchemaLocation [ deletions . key ] ;
309+ }
310+ await this . saveSchema ( deletions . schema , schema . schema ) ;
311+ }
312+ }
313+
314+ /**
315+ * Take a JSON Schema and the path that you would like to get to
316+ * @returns the JSON Schema resolved at that specific path
317+ */
318+ private resolveJSONSchemaToSection ( schema : JSONSchema , paths : string ) : JSONSchema {
319+ const splitPathway = paths . split ( '/' ) ;
320+ let resolvedSchemaLocation = schema ;
321+ for ( const path of splitPathway ) {
322+ if ( path === '' ) {
323+ continue ;
324+ }
325+ this . resolveNext ( resolvedSchemaLocation , path ) ;
326+ resolvedSchemaLocation = resolvedSchemaLocation [ path ] ;
327+ }
328+ return resolvedSchemaLocation ;
329+ }
330+
331+ /**
332+ * Resolve the next Object if they have compatible types
333+ * @param object a location in the JSON Schema
334+ * @param token the next token that you want to search for
335+ */
336+ // tslint:disable-next-line: no-any
337+ private resolveNext ( object : any , token : any ) {
338+ // tslint:disable-next-line: no-any
339+ if ( Array . isArray ( object ) && isNaN ( token ) ) {
340+ throw new Error ( 'Expected a number after the array object' ) ;
341+ } else if ( typeof object === 'object' && typeof token !== 'string' ) {
342+ throw new Error ( 'Expected a string after the object' ) ;
343+ }
344+ }
345+
239346 /**
240347 * Everything below here is needed because we're importing from vscode-json-languageservice umd and we need
241348 * to provide a wrapper around the javascript methods we are calling since they have no type
0 commit comments