Skip to content

Commit 3d82d61

Browse files
authored
Load schema content contributed by other extensions (#451)
* Load schema content contributed by other extensions Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com> * Fix review comments Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com> * update readme with way to disable code lens Signed-off-by: Yevhen Vydolob <yvydolob@redhat.com>
1 parent c011045 commit 3d82d61

File tree

5 files changed

+84
-8
lines changed

5 files changed

+84
-8
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ The following settings are supported:
4545
- `yaml.schemas`: Helps you associate schemas with files in a glob pattern
4646
- `yaml.schemaStore.enable`: When set to true the YAML language server will pull in all available schemas from [JSON Schema Store](http://schemastore.org/json/)
4747
- `yaml.customTags`: Array of custom tags that the parser will validate against. It has two ways to be used. Either an item in the array is a custom tag such as "!Ref" and it will automatically map !Ref to scalar or you can specify the type of the object !Ref should be e.g. "!Ref sequence". The type of object can be either scalar (for strings and booleans), sequence (for arrays), mapping (for objects).
48-
- `[yaml]`: VSCode-YAML adds default configuration for all yaml files. More specifically it converts tabs to spaces to ensure valid yaml, sets the tab size, and allows live typing autocompletion and formatting. These settings can be modified via the corresponding settings inside the `[yaml]` section in the settings:
48+
- `[yaml]`: VSCode-YAML adds default configuration for all yaml files. More specifically it converts tabs to spaces to ensure valid yaml, sets the tab size, and allows live typing autocompletion and formatting, also allows code lens. These settings can be modified via the corresponding settings inside the `[yaml]` section in the settings:
4949
- `editor.insertSpaces`
5050
- `editor.tabSize`
5151
- `editor.quickSuggestions`
5252
- `editor.formatOnType`
53+
- `editor.codeLens`
5354

5455
##### Adding custom tags
5556

src/extension.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ export function activate(context: ExtensionContext): SchemaExtensionAPI {
102102
// client can be deactivated on extension deactivation
103103
context.subscriptions.push(disposable);
104104
context.subscriptions.push(
105-
workspace.registerTextDocumentContentProvider('json-schema', new JSONSchemaDocumentContentProvider(schemaCache))
105+
workspace.registerTextDocumentContentProvider(
106+
'json-schema',
107+
new JSONSchemaDocumentContentProvider(schemaCache, schemaExtensionAPI)
108+
)
106109
);
107110

108111
findConflicts();

src/json-schema-content-provider.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,38 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { TextDocumentContentProvider, Uri, ProviderResult, workspace } from 'vscode';
6+
import { TextDocumentContentProvider, Uri, workspace, window } from 'vscode';
77
import { xhr, configure as configureHttpRequests, getErrorStatusDescription, XHRResponse } from 'request-light';
88
import { JSONSchemaCache } from './json-schema-cache';
9+
import { SchemaExtensionAPI } from './schema-extension-api';
910

1011
export class JSONSchemaDocumentContentProvider implements TextDocumentContentProvider {
11-
constructor(private readonly schemaCache: JSONSchemaCache) {}
12-
provideTextDocumentContent(uri: Uri): ProviderResult<string> {
13-
return getJsonSchemaContent(uri.toString().replace('json-schema://', 'https://'), this.schemaCache);
12+
constructor(private readonly schemaCache: JSONSchemaCache, private readonly schemaApi: SchemaExtensionAPI) {}
13+
async provideTextDocumentContent(uri: Uri): Promise<string> {
14+
if (uri.fragment) {
15+
const origUri = uri.fragment;
16+
const schemaUri = Uri.parse(origUri);
17+
// handle both 'http' and 'https'
18+
if (origUri.startsWith('http')) {
19+
return getJsonSchemaContent(origUri, this.schemaCache);
20+
} else if (this.schemaApi.hasProvider(schemaUri.scheme)) {
21+
let content = this.schemaApi.requestCustomSchemaContent(origUri);
22+
23+
content = await Promise.resolve(content);
24+
// prettify JSON
25+
if (content.indexOf('\n') === -1) {
26+
content = JSON.stringify(JSON.parse(content), null, 2);
27+
}
28+
29+
return content;
30+
} else {
31+
window.showErrorMessage(`Cannot Load content for: ${origUri}. Unknown schema: '${schemaUri.scheme}'`);
32+
return null;
33+
}
34+
} else {
35+
window.showErrorMessage(`Cannot Load content for: '${uri.toString()}' `);
36+
return null;
37+
}
1438
}
1539
}
1640

src/schema-extension-api.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { logToExtensionOutputChannel } from './extension';
55

66
interface SchemaContributorProvider {
77
readonly requestSchema: (resource: string) => string;
8-
readonly requestSchemaContent: (uri: string) => string;
8+
readonly requestSchemaContent: (uri: string) => Promise<string> | string;
99
readonly label?: string;
1010
}
1111

@@ -137,7 +137,7 @@ class SchemaExtensionAPI implements ExtensionAPI {
137137
* @param {string} uri the schema uri returned from requestSchema.
138138
* @returns {string} the schema content
139139
*/
140-
public requestCustomSchemaContent(uri: string): string {
140+
public requestCustomSchemaContent(uri: string): Promise<string> | string {
141141
if (uri) {
142142
const _uri = URI.parse(uri);
143143

@@ -154,6 +154,10 @@ class SchemaExtensionAPI implements ExtensionAPI {
154154
public async modifySchemaContent(schemaModifications: SchemaAdditions | SchemaDeletions): Promise<void> {
155155
return this._yamlClient.sendRequest(SchemaModificationNotification.type, schemaModifications);
156156
}
157+
158+
public hasProvider(schema: string): boolean {
159+
return this._customSchemaContributors[schema] !== undefined;
160+
}
157161
}
158162

159163
// constants
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Red Hat, Inc. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import * as vscode from 'vscode';
6+
import { getDocUri, activate } from './helper';
7+
import * as assert from 'assert';
8+
9+
describe('Tests for JSON Schema content provider', () => {
10+
const SCHEMA = 'myschema';
11+
const schemaJSON = JSON.stringify({
12+
type: 'object',
13+
properties: {
14+
version: {
15+
type: 'string',
16+
description: 'A stringy string string',
17+
enum: ['test'],
18+
},
19+
},
20+
});
21+
22+
function onRequestSchema1URI(resource: string): string | undefined {
23+
if (resource.endsWith('completion.yaml') || resource.endsWith('basic.yaml')) {
24+
return `${SCHEMA}://schema/porter`;
25+
}
26+
return undefined;
27+
}
28+
29+
function onRequestSchema1Content(): string | undefined {
30+
return schemaJSON;
31+
}
32+
33+
it('should handle "json-schema" url', async () => {
34+
const docUri = getDocUri('completion/completion.yaml');
35+
const client = await activate(docUri);
36+
client._customSchemaContributors = {};
37+
client.registerContributor(SCHEMA, onRequestSchema1URI, onRequestSchema1Content);
38+
const customUri = vscode.Uri.parse(`json-schema://some/url/schema.json#${SCHEMA}://some/path/schema.json`);
39+
const doc = await vscode.workspace.openTextDocument(customUri);
40+
const editor = await vscode.window.showTextDocument(doc);
41+
assert.strictEqual(editor.document.getText(), JSON.stringify(JSON.parse(schemaJSON), null, 2));
42+
client._customSchemaContributors = {};
43+
});
44+
});

0 commit comments

Comments
 (0)