type-graphql#createMethodDecorator TypeScript Examples
The following examples show how to use
type-graphql#createMethodDecorator.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: authorizations.ts From backend with MIT License | 6 votes |
/* Inside mutations, determining Ownership is hard because the actual value is retrieved by it's primary key during
mutation execution. Thus with AuthorizedDeferred one can move the access check into the mutation, and call
hasAccess once the value is ready, like:
@AuthorizedDeferred(Role.OWNER)
courseCancel(@Ctx() context, @Arg() courseId: number) {
const course = await getCourse(courseId);
await hasAccess(context, "Course", course);
// ...
}
Note that this leaks the information whether an entity exists, though as we use artificial primary keys this should not reveal
anything of value
*/
export function AuthorizedDeferred(...requiredRoles: Role[]) {
assert(requiredRoles.length, "Roles must be passed to AUTHORIZED");
return createMethodDecorator<GraphQLContext>(({ args, root, info, context }, next) => {
context.deferredRequiredRoles = requiredRoles;
return next();
});
}
Example #2
Source File: cache.ts From backend with MIT License | 6 votes |
/* If a Query is annotated with @PublicCache AND all the entities involved in the query are marked with "cacheAllFields" in the enhancement map below,
then further requests with exactly the same query are served from cache for (duration) seconds */
export function PublicCache(duration: number = 60 /*s*/) {
return createMethodDecorator<GraphQLContext>(({ info }, next) => {
info.cacheControl.setCacheHint({
maxAge: duration,
scope: CacheScope.Public
});
return next();
});
}
Example #3
Source File: complexity.ts From backend with MIT License | 6 votes |
export function LimitedQuery(limit = 100) {
return createMethodDecorator<LimitedQueryContext>(({ args, root, info, context }, next) => {
// mutations are always fine, we only worry about queries
if (info.operation.operation === "mutation") {
return next();
}
const numberLimited = !!args.take;
const numberLimitedLow = args.take <= limit;
const isIDQuery = !!args.where?.id;
if (numberLimited && !numberLimitedLow) {
throw new ValidationError(`Overcomplex Query: Please reduce the TAKE arg to less than ${limit} entries`);
}
if (!isIDQuery && !numberLimitedLow) {
throw new ValidationError(`Overcomplex Query: Please implement pagination with TAKE and SKIP`);
}
const cardinality = isIDQuery ? 1 : args.take;
enforceAccumulatedLimit(info, context, cardinality);
return next();
});
}
Example #4
Source File: rate-limit.ts From backend with MIT License | 6 votes |
export function RateLimit(name: string, max: number, interval: number /* in ms */) {
const countPerIP = new Map<string, number>();
setInterval(() => {
countPerIP.clear();
log.info(`Cleared Rate Limit ${name} counters`);
}, interval);
return createMethodDecorator<GraphQLContext>(({ args, root, info, context }, next) => {
// Trusted users are generally power-users and perform a lot of API requests,
// for those we do not enforce rate limits (as we trust them)
if ((context as GraphQLContext).user?.roles.includes(Role.ADMIN) ||
(context as GraphQLContext).user?.roles.includes(Role.SCREENER)) {
return next();
}
if (!countPerIP.has(context.ip)) {
log.debug(`First request from ${context.ip}`);
countPerIP.set(context.ip, 1);
return next();
}
const count = countPerIP.get(context.ip);
countPerIP.set(context.ip, count + 1);
if (count > max) {
log.warn(`Blocked ${context.ip} from accessing ${name} as maximum of ${max} was reached`);
throw new Error(`RateLimit Enforcement`);
}
log.debug(`${context.ip} requested ${name} for the ${count}th time`);
return next();
});
}
Example #5
Source File: complexity.ts From backend with MIT License | 5 votes |
/* For nested field resolvers one can still give a brief estimation about the entries expected */
export function LimitEstimated(cardinality: number) {
return createMethodDecorator(({ info, context }, next) => {
enforceAccumulatedLimit(info, context, cardinality);
return next();
});
}