Adds config-schema nullable composite type (#41728)
The `nullable` type is very similar to the `maybe` type, except that it validates nulls and undefined values to null, instead of undefined. Eg, maybe(T): T | undefined nullable(T): T | null
This commit is contained in:
parent
9f6188f314
commit
25026381ec
|
@ -36,6 +36,7 @@ import {
|
||||||
MapOfOptions,
|
MapOfOptions,
|
||||||
MapOfType,
|
MapOfType,
|
||||||
MaybeType,
|
MaybeType,
|
||||||
|
NullableType,
|
||||||
NeverType,
|
NeverType,
|
||||||
NumberOptions,
|
NumberOptions,
|
||||||
NumberType,
|
NumberType,
|
||||||
|
@ -100,6 +101,10 @@ function maybe<V>(type: Type<V>): Type<V | undefined> {
|
||||||
return new MaybeType(type);
|
return new MaybeType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nullable<V>(type: Type<V>): Type<V | null> {
|
||||||
|
return new NullableType(type);
|
||||||
|
}
|
||||||
|
|
||||||
function object<P extends Props>(props: P, options?: ObjectTypeOptions<P>): ObjectType<P> {
|
function object<P extends Props>(props: P, options?: ObjectTypeOptions<P>): ObjectType<P> {
|
||||||
return new ObjectType(props, options);
|
return new ObjectType(props, options);
|
||||||
}
|
}
|
||||||
|
@ -191,6 +196,7 @@ export const schema = {
|
||||||
literal,
|
literal,
|
||||||
mapOf,
|
mapOf,
|
||||||
maybe,
|
maybe,
|
||||||
|
nullable,
|
||||||
never,
|
never,
|
||||||
number,
|
number,
|
||||||
object,
|
object,
|
||||||
|
|
|
@ -4,4 +4,6 @@ exports[`fails if null 1`] = `"expected value of type [string] but got [null]"`;
|
||||||
|
|
||||||
exports[`includes namespace in failure 1`] = `"[foo-namespace]: expected value of type [string] but got [null]"`;
|
exports[`includes namespace in failure 1`] = `"[foo-namespace]: expected value of type [string] but got [null]"`;
|
||||||
|
|
||||||
|
exports[`validates basic type 1`] = `"expected value of type [string] but got [number]"`;
|
||||||
|
|
||||||
exports[`validates contained type 1`] = `"value is [foo] but it must have a maximum length of [1]."`;
|
exports[`validates contained type 1`] = `"value is [foo] but it must have a maximum length of [1]."`;
|
||||||
|
|
7
packages/kbn-config-schema/src/types/__snapshots__/nullable_type.test.ts.snap
generated
Normal file
7
packages/kbn-config-schema/src/types/__snapshots__/nullable_type.test.ts.snap
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`includes namespace in failure 1`] = `"[foo-namespace]: value is [foo] but it must have a maximum length of [1]."`;
|
||||||
|
|
||||||
|
exports[`validates basic type 1`] = `"expected value of type [string] but got [number]"`;
|
||||||
|
|
||||||
|
exports[`validates contained type 1`] = `"value is [foo] but it must have a maximum length of [1]."`;
|
|
@ -26,6 +26,7 @@ export { ConditionalType, ConditionalTypeValue } from './conditional_type';
|
||||||
export { DurationOptions, DurationType } from './duration_type';
|
export { DurationOptions, DurationType } from './duration_type';
|
||||||
export { LiteralType } from './literal_type';
|
export { LiteralType } from './literal_type';
|
||||||
export { MaybeType } from './maybe_type';
|
export { MaybeType } from './maybe_type';
|
||||||
|
export { NullableType } from './nullable_type';
|
||||||
export { MapOfOptions, MapOfType } from './map_type';
|
export { MapOfOptions, MapOfType } from './map_type';
|
||||||
export { NumberOptions, NumberType } from './number_type';
|
export { NumberOptions, NumberType } from './number_type';
|
||||||
export { ObjectType, ObjectTypeOptions, Props, TypeOf } from './object_type';
|
export { ObjectType, ObjectTypeOptions, Props, TypeOf } from './object_type';
|
||||||
|
|
|
@ -45,6 +45,12 @@ test('validates contained type', () => {
|
||||||
expect(() => type.validate('foo')).toThrowErrorMatchingSnapshot();
|
expect(() => type.validate('foo')).toThrowErrorMatchingSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('validates basic type', () => {
|
||||||
|
const type = schema.maybe(schema.string());
|
||||||
|
|
||||||
|
expect(() => type.validate(666)).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
test('fails if null', () => {
|
test('fails if null', () => {
|
||||||
const type = schema.maybe(schema.string());
|
const type = schema.maybe(schema.string());
|
||||||
expect(() => type.validate(null)).toThrowErrorMatchingSnapshot();
|
expect(() => type.validate(null)).toThrowErrorMatchingSnapshot();
|
||||||
|
|
63
packages/kbn-config-schema/src/types/nullable_type.test.ts
Normal file
63
packages/kbn-config-schema/src/types/nullable_type.test.ts
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { schema } from '..';
|
||||||
|
|
||||||
|
test('returns value if specified', () => {
|
||||||
|
const type = schema.nullable(schema.string());
|
||||||
|
expect(type.validate('test')).toEqual('test');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns null if null', () => {
|
||||||
|
const type = schema.nullable(schema.string());
|
||||||
|
expect(type.validate(null)).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns null if undefined', () => {
|
||||||
|
const type = schema.nullable(schema.string());
|
||||||
|
expect(type.validate(undefined)).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns null even if contained type has a default value', () => {
|
||||||
|
const type = schema.nullable(
|
||||||
|
schema.string({
|
||||||
|
defaultValue: 'abc',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(type.validate(undefined)).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('validates contained type', () => {
|
||||||
|
const type = schema.nullable(schema.string({ maxLength: 1 }));
|
||||||
|
|
||||||
|
expect(() => type.validate('foo')).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('validates basic type', () => {
|
||||||
|
const type = schema.nullable(schema.string());
|
||||||
|
|
||||||
|
expect(() => type.validate(666)).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('includes namespace in failure', () => {
|
||||||
|
const type = schema.nullable(schema.string({ maxLength: 1 }));
|
||||||
|
|
||||||
|
expect(() => type.validate('foo', {}, 'foo-namespace')).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
32
packages/kbn-config-schema/src/types/nullable_type.ts
Normal file
32
packages/kbn-config-schema/src/types/nullable_type.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Type } from './type';
|
||||||
|
|
||||||
|
export class NullableType<V> extends Type<V | null> {
|
||||||
|
constructor(type: Type<V>) {
|
||||||
|
super(
|
||||||
|
type
|
||||||
|
.getSchema()
|
||||||
|
.optional()
|
||||||
|
.allow(null)
|
||||||
|
.default(null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue