All files process.ts

100% Statements 46/46
100% Branches 51/51
100% Functions 5/5
100% Lines 46/46

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 471x 1x 1x 1x 13x 13x 13x 1x 17x 17x 1x 1x 1x 1x 22x 22x 23x 23x 23x 23x 5x 2x 2x 3x 5x 2x 2x 2x 2x 2x 2x 2x 2x 5x 19x 19x 19x 23x 23x 13x 13x 13x 13x 13x 13x 23x  
import { wrapHandleWithValidation } from './contractValidation.js'
import { HttpMethods, AuthInput, ContractType, Implementation, HandleErrorResponse, HandleResult } from './globalTypes.js'
import { map } from 'microtil'
 
function isPrimitive (test:any):boolean {
  return (test !== Object(test))
};
export const errorStructure =
(status:number, errorType:string, errors: string, data:any):
HandleErrorResponse => ({ status, errorType, data, errors: [errors] })
 
export type HandleType <OUT> =(body?: any, id?: string, user?: AuthInput) => Promise<HandleResult<OUT>>
 
export const processHandle = <METHOD extends HttpMethods, IMPL extends Implementation, IN, OUT> (contract: ContractType<METHOD, IMPL, IN, OUT>):
  HandleType<OUT> =>
    async (body?:any, id?:string, user?:AuthInput):
      Promise<HandleResult<OUT>> => {
      const { authentication, manageFields } = contract
 
      if (authentication) {
        if (!user?.sub) {
          return errorStructure(401, 'unauthorized', 'Only logged in users can do this', { id })
        }
 
        if (Array.isArray(authentication)) {
          const perm: string[] = user.permissions || []
 
          const hasPerm = perm.some(y => authentication.some(z => z === y))
          const canUserAccess = manageFields.createdBy
          if (!hasPerm && !canUserAccess) {
            return errorStructure(403, 'forbidden', "You don't have permission to do this", { id })
          }
        }
      }
 
      try {
        const result: HandleResult<OUT> = await wrapHandleWithValidation(contract)(body, { ...user }, id)
        return { ...result, status: result.status || (contract.type === 'POST' ? 201 : 200) }
      } catch (e) {
        const normalizeErrorCode = (input:number) => input >= 400 && input < 600 ? input : 500
        const getIfNumber = (input:any) :number | false => typeof input === 'number' && normalizeErrorCode(input)
        const data = (isPrimitive(e) || !e) ? e : map(e, y => y)
        const code = getIfNumber(e?.status) || getIfNumber(e?.statusCode) || getIfNumber(e?.code) || 500
        return errorStructure(code, e?.name || 'exception', e?.message || e?.toString() || 'unknown', data)
      }
    }