All files / resources/api/v2 _base.ts

98% Statements 49/50
88.88% Branches 8/9
100% Functions 1/1
98% Lines 49/50

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          1x   1x         1x   1x                         33x 33x                       33x 33x 33x 33x 33x   32x 32x 32x 32x 32x     32x 32x 32x 32x 32x 32x     32x 32x 17x 12x 32x 12x 12x     32x 32x 32x 32x 32x   32x 32x 32x 32x 27x 27x 27x 27x 32x 16x 16x   32x 32x   1x 1x  
import {
  APIGatewayProxyEvent, APIGatewayProxyResult
} from 'aws-lambda';
import { Api } from 'ts-oas';
 
import { getCurrentUser } from './_utils';
 
import { api403Response } from '@/types/api/_shared';
import {
  FrontendUserObject
} from '@/types/api/users';
import { UserPermissions } from '@/types/backend/user';
import { getLogger } from '@/utils/common/logger';
 
const logger = getLogger('api/v2/_base');
 
export type LambdaApiFunction<T extends Api> = (
  event: APIGatewayProxyEvent,
  user: Readonly<FrontendUserObject | null>,
  userPerms: Readonly<UserPermissions>,
) => Promise<[
  keyof T['responses'],
  T['responses'][keyof T['responses']],
  (APIGatewayProxyResult['multiValueHeaders'] | null)?,
  string?
]>;
 
export async function handleResourceApi(
  handlers: {
    [key in Api['method']]?: (
      event: APIGatewayProxyEvent,
      user: Readonly<FrontendUserObject | null>,
      userPerms: Readonly<UserPermissions>,
    ) => Promise<[
      number,
      unknown,
      (APIGatewayProxyResult['multiValueHeaders'] | null)?,
      string?
    ]>;
  },
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> {
  logger.trace('handleResourceApi', ...arguments);
  const method = event.httpMethod as Api['method'];
  if (typeof handlers[method] !== 'undefined') {
    // Get user information
    const [
      user,
      userPerms,
      userHeaders,
    ] = await getCurrentUser(event);
 
    // Run the function
    const [
      statusCode,
      responseBody,
      responseHeaders,
      contentType = 'application/json',
    ] = await handlers[method](event, user, userPerms);
 
    // Log details for any errors
    if (
      statusCode !== 200 &&
      statusCode !== 204 &&
      statusCode !== 205
    ) {
      logger.error(`${method} Error - ${statusCode}`, responseBody, event);
    }
 
    // Build the response
    const response: APIGatewayProxyResult = {
      statusCode,
      body: JSON.stringify(responseBody),
    };
    if (responseHeaders) {
      response.multiValueHeaders = responseHeaders;
    } else {
      response.multiValueHeaders = userHeaders;
    }
    if (statusCode !== 204) {
      response.headers = {
        'Content-Type': contentType,
      };
    }
    if (typeof responseBody === 'string') {
      response.body = responseBody;
    }
 
    return response;
  }
 
  return api403Response;
}