fctorial
fctorial

Reputation: 915

Joi: Automatic validation of function arguments

I saw a codebase which was using joi library like this:

function f(a, b) {
  // ...
}

f.schema = {
  a: Joi.string().uuid().required(),
  b: Joi.number()
}

And then the f.schema property wasn't referenced anywhere else. Is there some framework which performs automatic validation of function arguments using the schema property? Googling this didn't bring up anything.

Upvotes: 2

Views: 823

Answers (2)

Vladimir Kotov
Vladimir Kotov

Reputation: 1

You can use @pro-script/as-is for that

import { Checker } from '@pro-script/as-is';
const { is, as, Interface } = new Checker();

Interface({
    IArguments: {
        a: as.number,
        b: as.number,
    }
});

function add(a, b) {
    as.IArguments = { a, b };
    return as.number = a + b;
}

function add(a, b, _ = as.IArguments = { a, b }) {
    return as.number = a + b;
}

Upvotes: 0

Oursin
Oursin

Reputation: 141

I don't think it is possible to do exactly what you are showing here, since overloading of function call is impossible in Javascript, but there is a way to do something pretty similar using Proxies.

Here is what I've managed to do. We create a validated proxy object, that overrides the apply behavior, which corresponds to standard function calls, as well as apply and call methods.

The proxy checks for the presence of a schema property on the function, then validates each argument using the elements of the schema array.

const Joi = require('joi');

const validated = function(f) {
    return new Proxy(f, {
        apply: function(target, thisArg, arguments) {
            if (target.schema) {
                for (let i = 0; i < target.length; i++) {
                    const res = target.schema[i].validate(arguments[i]);
                    if (res.error) {
                        throw res.error;
                    }
                }
            }
            target.apply(thisArg, arguments)
        }
    })
}

const myFunc = validated((a, b) => {
    console.log(a, b)
});

myFunc.schema = [
    Joi.string().required(),
    Joi.number(),
];

myFunc('a', 2);

Upvotes: 1

Related Questions