Skip to content

Commit

Permalink
[feat] add reach-like functionality to object
Browse files Browse the repository at this point in the history
In elastic#36804 we need to validate a `Partial<HttpConfig>` object which may
or may not have all the required keys attached to it.  This is the type
of use-case for `Joi.reach`, so we should expose a reach-like method on
the object validation class so that you can return the validator for a
specific key on an object.
  • Loading branch information
toddself committed May 24, 2019
1 parent b7b7aa5 commit 9e0c42f
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
16 changes: 16 additions & 0 deletions packages/kbn-config-schema/src/types/object_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,19 @@ test('includes namespace in failure when wrong value type', () => {

expect(() => type.validate(value, {}, 'foo-namespace')).toThrowErrorMatchingSnapshot();
});

test('reach returns a valid schema component', () => {
const type = schema.object({
foo: schema.boolean(),
});

const fooSchema = type.reach('foo');
const value = false;
expect(() => fooSchema.validate(value)).toBeTruthy();

try {
type.reach('bar');
} catch (err) {
expect(err.message).toBe('bar is not a valid part of this schema');
}
});
8 changes: 8 additions & 0 deletions packages/kbn-config-schema/src/types/object_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export type TypeOf<RT extends Type<any>> = RT['type'];
export type ObjectResultType<P extends Props> = Readonly<{ [K in keyof P]: TypeOf<P[K]> }>;

export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>> {
private props: Record<string, AnySchema>;

constructor(props: P, options: TypeOptions<{ [K in keyof P]: TypeOf<P[K]> }> = {}) {
const schemaKeys = {} as Record<string, AnySchema>;
for (const [key, value] of Object.entries(props)) {
Expand All @@ -44,6 +46,7 @@ export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>>
.default();

super(schema, options);
this.props = schemaKeys;
}

protected handleError(type: string, { reason, value }: Record<string, any>) {
Expand All @@ -57,4 +60,9 @@ export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>>
return reason[0];
}
}

reach(key: string) {
if (!this.props[key]) throw new Error(`${key} is not a valid part of this schema`);
return this.props[key];
}
}

0 comments on commit 9e0c42f

Please sign in to comment.