Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 1x 1x 1x 1x 1x 1x 1x | import {
bind,
Interceptor,
InvocationContext,
InvocationResult,
Provider,
ValueOrPromise,
} from '@loopback/core';
import { HttpErrors } from '@loopback/rest';
import { compact, isEmpty } from 'lodash';
import { Constants } from '@logchain/configs';
import { MAX_ID_VALUE, MIN_ID_VALUE } from './ensure-id-valid.interceptor';
/**
* This class will be bound to the application as an `Interceptor` during
* `boot`
*/
@bind({ tags: { key: EnsurePagingCorrectInterceptor.BINDING_KEY } })
export class EnsurePagingCorrectInterceptor implements Provider<Interceptor> {
static readonly BINDING_KEY = `interceptors.${EnsurePagingCorrectInterceptor.name}`;
/*
constructor() {}
*/
/**
* This method is used by LoopBack context to produce an interceptor function
* for the binding.
*
* @returns An interceptor function
*/
value() {
return this.intercept.bind(this);
}
/**
* The logic to intercept an invocation
* @param invocationCtx - Invocation context
* @param next - A function to invoke next interceptor or the target method
*/
async intercept(
invocationCtx: InvocationContext,
next: () => ValueOrPromise<InvocationResult>,
) {
const { args } = invocationCtx;
this.setDefaultOffset(args);
this.setDefaultLimit(args);
this.setDefaultOrder(args);
this.processWhereClause(args);
const result = await next();
return result;
}
private setDefaultOffset(args: any[]) {
if (!Number.isSafeInteger(args[0]) || args[0] < 0) {
args[0] = 0;
}
}
private setDefaultLimit(args: any[]) {
if (!Number.isSafeInteger(args[1]) || args[1] > Constants.DefaultLimit) {
args[1] = Constants.DefaultLimit;
}
}
private setDefaultOrder(args: any[]) {
if (!Array.isArray(args[2])) {
args[2] = [args[2]];
}
args[2] = compact(args[2]);
if (args[2].length) {
args[2].forEach((o: string) => {
if (!this.validateOrder(o)) {
throw new HttpErrors.UnprocessableEntity('Invalid order: ' + args[2]);
}
});
} else {
args[2] = ['id DESC'];
}
}
private processWhereClause(args: any[]) {
if (!isEmpty(args[4])) {
delete args[4].additionalProp1;
}
if (isEmpty(args[4])) {
args[4] = {};
} else if ('id' in args[4]) {
const id = Number(args[4].id);
if (isNaN(id) || id < MIN_ID_VALUE || id > MAX_ID_VALUE) {
args[4].id = null;
}
}
}
/**
* Validate order string
* @param order The order
*/
validateOrder(order: string) {
return order.match(/^[^\s]+( (ASC|DESC))?$/);
}
}
|