Thank you; on a blank project with no existing schemas I tried Joi Schemas with joi-extract-type (suggested by hexsprite above), and it works great with ValidatedMethod.
My methods look like this:
import DeclareJoiValidatedMethod from '../core/joi-method'
import * as Joi from '@hapi/joi';
import 'joi-extract-type';
const MyFirstMethodSchema = Joi.object({
userId: Joi.string().required(),
roles: Joi.array().items(Joi.string()).required(),
});
DeclareJoiValidatedMethod({
name: 'myMethod',
schema: MyFirstMethodSchema,
run({userId, roles}: Joi.extractType<typeof MyFirstMethodSchema>): boolean {
...
return true
}
});
with the helper function DeclareJoiValidatedMethod inspired from this post:
export interface JoiValidatedMethodOptions<T> {
name: string,
schema: Joi.ObjectSchema,
validate?(obj: Object): void,
run(obj: Object): T;
}
export function joiValidate<T>(vmOptions: JoiValidatedMethodOptions<T>) {
vmOptions.validate = (obj: Object) => {
const result = Joi.validate(obj, vmOptions.schema, { stripUnknown: true });
if (result.error) {
const err = new ValidationError(result.error.details.map(err => {
// map joi error to ValidationError
return {
name: err.path,
type: err.type,
message: err.message
};
}));
throw err;
}
// call validatedMethod.run with the validated/cleaned values!
const runFunc = vmOptions.run;
vmOptions.run = function () {
return runFunc.bind(this)(result.value);
}
}
return vmOptions as ValidatedMethodOptionsWithMixins<string, typeof vmOptions.run>;
}
function DeclareJoiValidatedMethod<T>(optionObj: JoiValidatedMethodOptions<T>) {
return new ValidatedMethod(joiValidate(optionObj));
}