Skip to content

Instantly share code, notes, and snippets.

@marcus-sa
Last active May 16, 2025 16:53
Show Gist options
  • Save marcus-sa/05c54e665b9c83c24c8f9e08491d9ddd to your computer and use it in GitHub Desktop.
Save marcus-sa/05c54e665b9c83c24c8f9e08491d9ddd to your computer and use it in GitHub Desktop.
custom deepkit http decorator
import {http as _http, HttpAction, httpAction, HttpActionDecorator, httpClass} from "@deepkit/http";
import {
createPropertyDecoratorContext,
DualDecorator,
mergeDecorator,
PropertyDecoratorFn,
ReceiveType
} from "@deepkit/type";
import {ClassType,UnionToIntersection} from "@deepkit/core";
export enum Role {
ADMIN = 'admin',
USER = 'user',
}
class HttpAuthActionDecorator extends HttpActionDecorator {
t = new HttpAction();
roles(...roles: Role[]) {
this.t.data.set('roles', roles);
}
}
export const httpAuthAction = createPropertyDecoratorContext(HttpAuthActionDecorator);
//this workaround is necessary since generic functions are lost during a mapped type and changed ReturnType
type HttpMerge<U> = { [K in keyof U]: K extends 'response' ? <T2>(statusCode: number, description?: string, type?: ReceiveType<T2>) => PropertyDecoratorFn & U : U[K] extends ((...a: infer A) => infer R) ? R extends DualDecorator ? (...a: A) => PropertyDecoratorFn & R & U : (...a: A) => R : never };
type MergedHttp<T extends any[]> = HttpMerge<Omit<UnionToIntersection<T[number]>, '_fetch' | 't'>>
export const http = mergeDecorator(httpClass, httpAuthAction) as any as MergedHttp<[typeof httpClass, typeof httpAuthAction]>;
@http.controller('/test')
class TestController {
@(http.POST('test')).roles(Role.ADMIN)
test() {
}
}
console.log(httpClass._fetch(TestController));
@marcus-sa
Copy link
Author

It logs

HttpController {
  baseUrl: "/test",
  actions: Set(1) {
    HttpAuthAction {
      name: "",
      description: "",
      category: "",
      path: "test",
      httpMethods: [ "POST" ],
      methodName: "test",
      groups: [],
      middlewares: [],
      resolverForToken: Map {},
      resolverForParameterName: Map {},
      data: Map(1) {
        "roles": [ "admin" ],
      },
      responses: [],
    },
  },
  groups: [],
  middlewares: [],
  resolverForToken: Map {},
  resolverForParameterName: Map {},
  actionsProcessed: Set {},
  getUrl: [Function: getUrl],
  addAction: [Function: addAction],
  getActions: [Function: getActions],
  removeAction: [Function: removeAction],
  getAction: [Function: getAction],
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment