Clowning
Clowning

Reputation: 179

How to get parameters name within decorators

I'm trying to develop a decorator to know if some params are valid.

Here is my method,

getUsers(offset, limit, orderBy, sort){
....
}

I need to check if orderBy is 'createdAt' or 'updatedAt' if not, a http response will be send.

Same thing for sort, it need to be 'ASC' or 'DESC'.

So, i don't know how can I use decorator to help me to remove some line in my code, it's a small block but it's cleaner I think. Currently here is my block to check

if (!includes(this.orderByFields, orderBy)) {
  return Utils.HttpError.badRequest(`You are allowed to order by [ ${this.orderByFields.join(', ')} ] only.`);
}

Maybe is not possible to do it, thanks by advance :-)

Upvotes: 0

Views: 3074

Answers (1)

Gustorn
Gustorn

Reputation: 455

You should be able to do something like this:

type ApiFunction = (offset: number, limit: number, orderBy: string, sort: string) => any;

const orderByFields = ["createdAt", "updatedAt"];
function validateRequest() {
  return function(_target: any, _propertyName: string, descriptor: TypedPropertyDescriptor<ApiFunction>) {
    const originalMethod = descriptor.value!;
    descriptor.value = function(offset, limit, orderBy, sort) {
      if (!orderByFields.includes(orderBy)) {
        return "Bad Request";
      }
      return originalMethod.bind(this)(offset, limit, orderBy, sort);
    };
  };
}

This also makes sure that you can only apply the decorator to methods with a matching signature.

Usage example:

class Foo {
  @validateRequest()
  getUsers(offset: number, limit: number, orderBy: string, sort: string): string {
    return "Result";
  }
}

Apart from this you might want to try and enforce the orderBy and sort parameters on the type-level (and if you're the only consumer of this API then you might not even need the decorators):

function getUsers(offset: number, limit: number, orderBy: "createdAt" | "updatedAt", sort: "ASC" | "DESC") {}

Upvotes: 1

Related Questions