mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 10:38:31 -05:00
Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2
This commit is contained in:
committed by
Anthony Dresser
parent
3603f55d97
commit
7f1d8fc32f
@@ -24,6 +24,7 @@ import { EditorModel } from 'vs/workbench/common/editor';
|
||||
import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { withNullAsUndefined, isArray } from 'vs/base/common/types';
|
||||
import { FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { createValidator } from 'vs/workbench/services/preferences/common/preferencesValidation';
|
||||
|
||||
export const nullRange: IRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 };
|
||||
export function isNullRange(range: IRange): boolean { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; }
|
||||
@@ -1028,180 +1029,6 @@ class SettingsContentBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
export function createValidator(prop: IConfigurationPropertySchema): (value: any) => (string | null) {
|
||||
// Only for array of string
|
||||
if (prop.type === 'array' && prop.items && !isArray(prop.items) && prop.items.type === 'string') {
|
||||
const propItems = prop.items;
|
||||
if (propItems && !isArray(propItems) && propItems.type === 'string') {
|
||||
const withQuotes = (s: string) => `'` + s + `'`;
|
||||
|
||||
return value => {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let message = '';
|
||||
|
||||
const stringArrayValue = value as string[];
|
||||
|
||||
if (prop.uniqueItems) {
|
||||
if (new Set(stringArrayValue).size < stringArrayValue.length) {
|
||||
message += nls.localize('validations.stringArrayUniqueItems', 'Array has duplicate items');
|
||||
message += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.minItems && stringArrayValue.length < prop.minItems) {
|
||||
message += nls.localize('validations.stringArrayMinItem', 'Array must have at least {0} items', prop.minItems);
|
||||
message += '\n';
|
||||
}
|
||||
|
||||
if (prop.maxItems && stringArrayValue.length > prop.maxItems) {
|
||||
message += nls.localize('validations.stringArrayMaxItem', 'Array must have at most {0} items', prop.maxItems);
|
||||
message += '\n';
|
||||
}
|
||||
|
||||
if (typeof propItems.pattern === 'string') {
|
||||
const patternRegex = new RegExp(propItems.pattern);
|
||||
stringArrayValue.forEach(v => {
|
||||
if (!patternRegex.test(v)) {
|
||||
message +=
|
||||
propItems.patternErrorMessage ||
|
||||
nls.localize(
|
||||
'validations.stringArrayItemPattern',
|
||||
'Value {0} must match regex {1}.',
|
||||
withQuotes(v),
|
||||
withQuotes(propItems.pattern!)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const propItemsEnum = propItems.enum;
|
||||
if (propItemsEnum) {
|
||||
stringArrayValue.forEach(v => {
|
||||
if (propItemsEnum.indexOf(v) === -1) {
|
||||
message += nls.localize(
|
||||
'validations.stringArrayItemEnum',
|
||||
'Value {0} is not one of {1}',
|
||||
withQuotes(v),
|
||||
'[' + propItemsEnum.map(withQuotes).join(', ') + ']'
|
||||
);
|
||||
message += '\n';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return value => {
|
||||
let exclusiveMax: number | undefined;
|
||||
let exclusiveMin: number | undefined;
|
||||
|
||||
if (typeof prop.exclusiveMaximum === 'boolean') {
|
||||
exclusiveMax = prop.exclusiveMaximum ? prop.maximum : undefined;
|
||||
} else {
|
||||
exclusiveMax = prop.exclusiveMaximum;
|
||||
}
|
||||
|
||||
if (typeof prop.exclusiveMinimum === 'boolean') {
|
||||
exclusiveMin = prop.exclusiveMinimum ? prop.minimum : undefined;
|
||||
} else {
|
||||
exclusiveMin = prop.exclusiveMinimum;
|
||||
}
|
||||
|
||||
let patternRegex: RegExp | undefined;
|
||||
if (typeof prop.pattern === 'string') {
|
||||
patternRegex = new RegExp(prop.pattern);
|
||||
}
|
||||
|
||||
const type: (string | undefined)[] = Array.isArray(prop.type) ? prop.type : [prop.type];
|
||||
const canBeType = (t: string) => type.indexOf(t) > -1;
|
||||
|
||||
const isNullable = canBeType('null');
|
||||
const isNumeric = (canBeType('number') || canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable);
|
||||
const isIntegral = (canBeType('integer')) && (type.length === 1 || type.length === 2 && isNullable);
|
||||
|
||||
type Validator<T> = { enabled: boolean, isValid: (value: T) => boolean; message: string };
|
||||
|
||||
const numericValidations: Validator<number>[] = isNumeric ? [
|
||||
{
|
||||
enabled: exclusiveMax !== undefined && (prop.maximum === undefined || exclusiveMax <= prop.maximum),
|
||||
isValid: ((value: number) => value < exclusiveMax!),
|
||||
message: nls.localize('validations.exclusiveMax', "Value must be strictly less than {0}.", exclusiveMax)
|
||||
},
|
||||
{
|
||||
enabled: exclusiveMin !== undefined && (prop.minimum === undefined || exclusiveMin >= prop.minimum),
|
||||
isValid: ((value: number) => value > exclusiveMin!),
|
||||
message: nls.localize('validations.exclusiveMin', "Value must be strictly greater than {0}.", exclusiveMin)
|
||||
},
|
||||
|
||||
{
|
||||
enabled: prop.maximum !== undefined && (exclusiveMax === undefined || exclusiveMax > prop.maximum),
|
||||
isValid: ((value: number) => value <= prop.maximum!),
|
||||
message: nls.localize('validations.max', "Value must be less than or equal to {0}.", prop.maximum)
|
||||
},
|
||||
{
|
||||
enabled: prop.minimum !== undefined && (exclusiveMin === undefined || exclusiveMin < prop.minimum),
|
||||
isValid: ((value: number) => value >= prop.minimum!),
|
||||
message: nls.localize('validations.min', "Value must be greater than or equal to {0}.", prop.minimum)
|
||||
},
|
||||
{
|
||||
enabled: prop.multipleOf !== undefined,
|
||||
isValid: ((value: number) => value % prop.multipleOf! === 0),
|
||||
message: nls.localize('validations.multipleOf', "Value must be a multiple of {0}.", prop.multipleOf)
|
||||
},
|
||||
{
|
||||
enabled: isIntegral,
|
||||
isValid: ((value: number) => value % 1 === 0),
|
||||
message: nls.localize('validations.expectedInteger', "Value must be an integer.")
|
||||
},
|
||||
].filter(validation => validation.enabled) : [];
|
||||
|
||||
const stringValidations: Validator<string>[] = [
|
||||
{
|
||||
enabled: prop.maxLength !== undefined,
|
||||
isValid: ((value: { length: number; }) => value.length <= prop.maxLength!),
|
||||
message: nls.localize('validations.maxLength', "Value must be {0} or fewer characters long.", prop.maxLength)
|
||||
},
|
||||
{
|
||||
enabled: prop.minLength !== undefined,
|
||||
isValid: ((value: { length: number; }) => value.length >= prop.minLength!),
|
||||
message: nls.localize('validations.minLength', "Value must be {0} or more characters long.", prop.minLength)
|
||||
},
|
||||
{
|
||||
enabled: patternRegex !== undefined,
|
||||
isValid: ((value: string) => patternRegex!.test(value)),
|
||||
message: prop.patternErrorMessage || nls.localize('validations.regex', "Value must match regex `{0}`.", prop.pattern)
|
||||
},
|
||||
].filter(validation => validation.enabled);
|
||||
|
||||
if (prop.type === 'string' && stringValidations.length === 0) { return null; }
|
||||
if (isNullable && value === '') { return ''; }
|
||||
|
||||
const errors: string[] = [];
|
||||
|
||||
if (isNumeric) {
|
||||
if (value === '' || isNaN(+value)) {
|
||||
errors.push(nls.localize('validations.expectedNumeric', "Value must be a number."));
|
||||
} else {
|
||||
errors.push(...numericValidations.filter(validator => !validator.isValid(+value)).map(validator => validator.message));
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.type === 'string') {
|
||||
errors.push(...stringValidations.filter(validator => !validator.isValid('' + value)).map(validator => validator.message));
|
||||
}
|
||||
if (errors.length) {
|
||||
return prop.errorMessage ? [prop.errorMessage, ...errors].join(' ') : errors.join(' ');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
}
|
||||
|
||||
class RawSettingsContentBuilder extends SettingsContentBuilder {
|
||||
|
||||
constructor(private indent: string = '\t') {
|
||||
|
||||
Reference in New Issue
Block a user