jsonValidationExtensionPoint.ts 3.6 KB
Newer Older
M
Martin Aeschlimann 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6
import * as nls from 'vs/nls';
7
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
8
import * as resources from 'vs/base/common/resources';
9
import { isString } from 'vs/base/common/types';
M
Martin Aeschlimann 已提交
10 11

interface IJSONValidationExtensionPoint {
12
	fileMatch: string | string[];
B
Benjamin Pasero 已提交
13
	url: string;
M
Martin Aeschlimann 已提交
14 15
}

16 17
const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IJSONValidationExtensionPoint[]>({
	extensionPoint: 'jsonValidation',
18
	defaultExtensionKind: 'workspace',
19 20 21 22 23 24 25 26 27
	jsonSchema: {
		description: nls.localize('contributes.jsonValidation', 'Contributes json schema configuration.'),
		type: 'array',
		defaultSnippets: [{ body: [{ fileMatch: '${1:file.json}', url: '${2:url}' }] }],
		items: {
			type: 'object',
			defaultSnippets: [{ body: { fileMatch: '${1:file.json}', url: '${2:url}' } }],
			properties: {
				fileMatch: {
28 29 30 31 32
					type: ['string', 'array'],
					description: nls.localize('contributes.jsonValidation.fileMatch', 'The file pattern (or an array of patterns) to match, for example "package.json" or "*.launch". Exclusion patterns start with \'!\''),
					items: {
						type: ['string']
					}
33 34 35 36 37
				},
				url: {
					description: nls.localize('contributes.jsonValidation.url', 'A schema URL (\'http:\', \'https:\') or relative path to the extension folder (\'./\').'),
					type: 'string'
				}
M
Martin Aeschlimann 已提交
38 39 40 41 42 43 44
			}
		}
	}
});

export class JSONValidationExtensionPoint {

45
	constructor() {
M
Martin Aeschlimann 已提交
46
		configurationExtPoint.setHandler((extensions) => {
47 48 49 50
			for (const extension of extensions) {
				const extensionValue = <IJSONValidationExtensionPoint[]>extension.value;
				const collector = extension.collector;
				const extensionLocation = extension.description.extensionLocation;
M
Martin Aeschlimann 已提交
51 52 53 54 55 56

				if (!extensionValue || !Array.isArray(extensionValue)) {
					collector.error(nls.localize('invalid.jsonValidation', "'configuration.jsonValidation' must be a array"));
					return;
				}
				extensionValue.forEach(extension => {
57 58
					if (!isString(extension.fileMatch) && !(Array.isArray(extension.fileMatch) && extension.fileMatch.every(isString))) {
						collector.error(nls.localize('invalid.fileMatch', "'configuration.jsonValidation.fileMatch' must be defined as a string or an array of strings."));
M
Martin Aeschlimann 已提交
59 60
						return;
					}
B
Benjamin Pasero 已提交
61
					let uri = extension.url;
62
					if (!isString(uri)) {
M
Martin Aeschlimann 已提交
63 64 65
						collector.error(nls.localize('invalid.url', "'configuration.jsonValidation.url' must be a URL or relative path"));
						return;
					}
66
					if (uri.startsWith('./')) {
67
						try {
68
							const colorThemeLocation = resources.joinPath(extensionLocation, uri);
69
							if (!resources.isEqualOrParent(colorThemeLocation, extensionLocation)) {
70
								collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.url` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", configurationExtPoint.name, colorThemeLocation.toString(), extensionLocation.path));
71
							}
72
						} catch (e) {
M
Martin Aeschlimann 已提交
73
							collector.error(nls.localize('invalid.url.fileschema', "'configuration.jsonValidation.url' is an invalid relative URL: {0}", e.message));
74
						}
75 76
					} else if (!/^[^:/?#]+:\/\//.test(uri)) {
						collector.error(nls.localize('invalid.url.schema', "'configuration.jsonValidation.url' must be an absolute URL or start with './'  to reference schemas located in the extension."));
M
Martin Aeschlimann 已提交
77 78 79 80 81 82 83 84
						return;
					}
				});
			}
		});
	}

}