Skip to content

Commit

Permalink
add basic support for declaring schema with inline $schema
Browse files Browse the repository at this point in the history
  • Loading branch information
bollwyvl committed May 17, 2024
1 parent dfccc6f commit 7e9164e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
26 changes: 26 additions & 0 deletions src/languageservice/services/dollarUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { SingleYAMLDocument } from '../parser/yamlParser07';
import { JSONDocument } from '../parser/jsonParser07';

/**
* Retrieve schema if declared by `$schema`.
* Public for testing purpose, not part of the API.
* @param doc
*/
export function getDollarSchema(doc: SingleYAMLDocument | JSONDocument): string | undefined {
if (doc instanceof SingleYAMLDocument && doc.root.type === 'object') {
let dollarSchema = doc.root.properties['$schema'];
dollarSchema = typeof dollarSchema === 'string' ? dollarSchema.trim() : undefined;
if (typeof dollarSchema === 'string') {
return dollarSchema.trim();
}
if (dollarSchema) {
console.log('The $schema attribute is not a string, and will be ignored');
}
}
return undefined;
}
58 changes: 38 additions & 20 deletions src/languageservice/services/yamlSchemaService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { SchemaVersions } from '../yamlTypes';

import Ajv, { DefinedError } from 'ajv';
import { getSchemaTitle } from '../utils/schemaUtils';
import { getDollarSchema } from './dollarUitls';

Check failure on line 32 in src/languageservice/services/yamlSchemaService.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Unable to resolve path to module './dollarUitls'

const localize = nls.loadMessageBundle();

Expand Down Expand Up @@ -343,33 +344,46 @@ export class YAMLSchemaService extends JSONSchemaService {
}

public getSchemaForResource(resource: string, doc: JSONDocument): Promise<ResolvedSchema> {
const normalizeSchemaRef = (schemaRef: string): string | undefined => {
if (!schemaRef.startsWith('file:') && !schemaRef.startsWith('http')) {
// If path contains a fragment and it is left intact, "#" will be
// considered part of the filename and converted to "%23" by
// path.resolve() -> take it out and add back after path.resolve
let appendix = '';
if (schemaRef.indexOf('#') > 0) {
const segments = schemaRef.split('#', 2);
schemaRef = segments[0];
appendix = segments[1];
}
if (!path.isAbsolute(schemaRef)) {
const resUri = URI.parse(resource);
schemaRef = URI.file(path.resolve(path.parse(resUri.fsPath).dir, schemaRef)).toString();
} else {
schemaRef = URI.file(schemaRef).toString();
}
if (appendix.length > 0) {
schemaRef += '#' + appendix;
}
}
return schemaRef;
};

const resolveModelineSchema = (): string | undefined => {
let schemaFromModeline = getSchemaFromModeline(doc);
if (schemaFromModeline !== undefined) {
if (!schemaFromModeline.startsWith('file:') && !schemaFromModeline.startsWith('http')) {
// If path contains a fragment and it is left intact, "#" will be
// considered part of the filename and converted to "%23" by
// path.resolve() -> take it out and add back after path.resolve
let appendix = '';
if (schemaFromModeline.indexOf('#') > 0) {
const segments = schemaFromModeline.split('#', 2);
schemaFromModeline = segments[0];
appendix = segments[1];
}
if (!path.isAbsolute(schemaFromModeline)) {
const resUri = URI.parse(resource);
schemaFromModeline = URI.file(path.resolve(path.parse(resUri.fsPath).dir, schemaFromModeline)).toString();
} else {
schemaFromModeline = URI.file(schemaFromModeline).toString();
}
if (appendix.length > 0) {
schemaFromModeline += '#' + appendix;
}
}
schemaFromModeline = normalizeSchemaRef(schemaFromModeline);
return schemaFromModeline;
}
};

const resolveDollarSchema = (): string | undefined => {
let dollarSchema = getDollarSchema(doc);
if (dollarSchema !== undefined) {
dollarSchema = normalizeSchemaRef(dollarSchema);
return dollarSchema;
}
};

const resolveSchemaForResource = (schemas: string[]): Promise<ResolvedSchema> => {
const schemaHandle = super.createCombinedSchema(resource, schemas);
return schemaHandle.getResolvedSchema().then((schema) => {
Expand Down Expand Up @@ -416,6 +430,10 @@ export class YAMLSchemaService extends JSONSchemaService {
if (modelineSchema) {
return resolveSchemaForResource([modelineSchema]);
}
const dollarSchema = resolveDollarSchema();
if (dollarSchema) {
return resolveSchemaForResource([dollarSchema]);
}
if (this.customSchemaProvider) {
return this.customSchemaProvider(resource)
.then((schemaUri) => {
Expand Down

0 comments on commit 7e9164e

Please sign in to comment.