@axah/koa
Advanced tools
Comparing version 0.0.0-20240606065415 to 0.0.0-20240606073919
@@ -1,2 +0,3 @@ | ||
import type { Context, Next, Middleware } from 'koa'; | ||
import type { Context, Middleware, Next } from 'koa'; | ||
import { StatusCodes } from 'http-status-codes'; | ||
import type { ZodType, ZodTypeDef } from 'zod'; | ||
@@ -12,3 +13,3 @@ import type { Authentication, UserRole } from './auth'; | ||
hashAlgorithm?: string; | ||
useOpenApiErrorFormat?: boolean; | ||
errorFormatter?: (ctx: Context, statusCode: StatusCodes, errorMessage: string, error?: any) => object; | ||
}; | ||
@@ -24,3 +25,3 @@ type ExecutorInput<B, Q, P> = { | ||
type Executor<B, Q, P> = (input: ExecutorInput<B, Q, P>) => Promise<void> | void; | ||
export default function createApiMethod<BodyIn, QueryIn, ParamsIn, BodyOut, QueryOut, ParamsOut>({ allowedRoles, body: bodyValidator, query: queryValidator, params: paramsValidator, files: allowFiles, exposeErrorCause, hashAlgorithm, useOpenApiErrorFormat, }: Input<ZodType<BodyOut, ZodTypeDef, BodyIn>, ZodType<QueryOut, ZodTypeDef, QueryIn>, ZodType<ParamsOut, ZodTypeDef, ParamsIn>>, executor: Executor<BodyOut, QueryOut, ParamsOut>): Middleware; | ||
export default function createApiMethod<BodyIn, QueryIn, ParamsIn, BodyOut, QueryOut, ParamsOut>({ allowedRoles, body: bodyValidator, query: queryValidator, params: paramsValidator, files: allowFiles, exposeErrorCause, hashAlgorithm, errorFormatter, }: Input<ZodType<BodyOut, ZodTypeDef, BodyIn>, ZodType<QueryOut, ZodTypeDef, QueryIn>, ZodType<ParamsOut, ZodTypeDef, ParamsIn>>, executor: Executor<BodyOut, QueryOut, ParamsOut>): Middleware; | ||
export {}; |
@@ -10,15 +10,8 @@ "use strict"; | ||
const clean_up_files_1 = require("./utils/clean-up-files"); | ||
const axa_error_messages_1 = require("./utils/axa-error-messages"); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const enrichResponseWithErrorCause = (ctx, errorCause) => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
ctx.body = { ...ctx.body, errorCause }; | ||
}; | ||
const createOpenApiErrorResponse = (ctx, status, errorCode, errorMessage, errorReasons) => { | ||
ctx.status = status; | ||
ctx.body = { | ||
errorCode, | ||
errorMessage, | ||
errorReasons, | ||
}; | ||
}; | ||
function createApiMethod({ allowedRoles, body: bodyValidator, query: queryValidator, params: paramsValidator, files: allowFiles = false, exposeErrorCause = false, hashAlgorithm, useOpenApiErrorFormat = false, }, executor) { | ||
function createApiMethod({ allowedRoles, body: bodyValidator, query: queryValidator, params: paramsValidator, files: allowFiles = false, exposeErrorCause = false, hashAlgorithm, errorFormatter, }, executor) { | ||
const parseBody = (0, koa_body_1.default)({ | ||
@@ -40,4 +33,4 @@ json: true, | ||
catch (e) { | ||
if (useOpenApiErrorFormat) { | ||
createOpenApiErrorResponse(ctx, http_status_codes_1.StatusCodes.FORBIDDEN, 'ACCESS_DENIED', axa_error_messages_1.AxaErrorMessages.FORBIDDEN, exposeErrorCause ? [{ message: e, code: 'AUTH_ERROR' }] : undefined); | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.FORBIDDEN, http_status_codes_1.ReasonPhrases.FORBIDDEN, e); | ||
} | ||
@@ -47,9 +40,9 @@ else { | ||
ctx.body = { error: http_status_codes_1.ReasonPhrases.FORBIDDEN }; | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'Failed to collect auth information'); | ||
} | ||
} | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'Failed to collect auth information'); | ||
} | ||
return; | ||
@@ -59,4 +52,4 @@ } | ||
ctx.log.error('User %s (%j) tried to access %s %s but does not have one of the required roles %j', auth.userId, auth.userRoles, ctx.method, ctx.path, allowedRoles); | ||
if (useOpenApiErrorFormat) { | ||
createOpenApiErrorResponse(ctx, http_status_codes_1.StatusCodes.FORBIDDEN, 'ACCESS_DENIED', axa_error_messages_1.AxaErrorMessages.FORBIDDEN); | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.FORBIDDEN, http_status_codes_1.ReasonPhrases.FORBIDDEN); | ||
} | ||
@@ -70,2 +63,3 @@ else { | ||
// 2. parse body | ||
// eslint-disable-next-line @typescript-eslint/no-empty-function | ||
await parseBody(ctx, async () => { }); | ||
@@ -81,17 +75,16 @@ // 2b. validate body | ||
catch (e) { | ||
if (useOpenApiErrorFormat) { | ||
createOpenApiErrorResponse(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, 'BAD_REQUEST', axa_error_messages_1.AxaErrorMessages.BAD_REQUEST, exposeErrorCause | ||
? [{ message: e, code: 'BODY_VALIDATION_ERROR' }] | ||
: undefined); | ||
const errorMessage = 'body is invalid'; | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, errorMessage, e); | ||
} | ||
else { | ||
ctx.status = http_status_codes_1.StatusCodes.BAD_REQUEST; | ||
ctx.body = { error: 'body is invalid' }; | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'body is invalid'); | ||
} | ||
ctx.body = { error: errorMessage }; | ||
} | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, errorMessage); | ||
} | ||
await (0, clean_up_files_1.cleanUpFiles)(ctx.request.files); | ||
@@ -105,17 +98,16 @@ return; | ||
catch (e) { | ||
if (useOpenApiErrorFormat) { | ||
createOpenApiErrorResponse(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, 'BAD_REQUEST', axa_error_messages_1.AxaErrorMessages.BAD_REQUEST, exposeErrorCause | ||
? [{ message: e, code: 'PARAMS_VALIDATION_ERROR' }] | ||
: undefined); | ||
const errorMessage = 'params is invalid'; | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, errorMessage, e); | ||
} | ||
else { | ||
ctx.status = http_status_codes_1.StatusCodes.BAD_REQUEST; | ||
ctx.body = { error: 'params is invalid' }; | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'params is invalid'); | ||
} | ||
ctx.body = { error: errorMessage }; | ||
} | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'params is invalid'); | ||
} | ||
await (0, clean_up_files_1.cleanUpFiles)(ctx.request.files); | ||
@@ -129,17 +121,16 @@ return; | ||
catch (e) { | ||
if (useOpenApiErrorFormat) { | ||
createOpenApiErrorResponse(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, 'BAD_REQUEST', axa_error_messages_1.AxaErrorMessages.BAD_REQUEST, exposeErrorCause | ||
? [{ message: e, code: 'QUERY_VALIDATION_ERROR' }] | ||
: undefined); | ||
const errorMessage = 'query is invalid'; | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.BAD_REQUEST, errorMessage, e); | ||
} | ||
else { | ||
ctx.status = http_status_codes_1.StatusCodes.BAD_REQUEST; | ||
ctx.body = { error: 'query is invalid' }; | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, 'query is invalid'); | ||
} | ||
ctx.body = { error: errorMessage }; | ||
} | ||
if (exposeErrorCause) { | ||
enrichResponseWithErrorCause(ctx, e); | ||
} | ||
else { | ||
ctx.log.error(e, errorMessage); | ||
} | ||
await (0, clean_up_files_1.cleanUpFiles)(ctx.request.files); | ||
@@ -146,0 +137,0 @@ return; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const http_status_codes_1 = require("http-status-codes"); | ||
const errorHandler = async (ctx, next) => { | ||
const errorHandler = async (ctx, next, errorFormatter) => { | ||
try { | ||
@@ -14,2 +14,5 @@ await next(); | ||
ctx.log.error(e); | ||
if (errorFormatter) { | ||
errorFormatter(ctx, http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR, http_status_codes_1.ReasonPhrases.INTERNAL_SERVER_ERROR, e); | ||
} | ||
ctx.status = http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; | ||
@@ -16,0 +19,0 @@ ctx.body = { error: http_status_codes_1.ReasonPhrases.INTERNAL_SERVER_ERROR }; |
export { default as errorHandler } from './error-handler'; | ||
export { default as openApiErrorHandler } from './openapi-error-handler'; | ||
export { default as log, getDataFromMdc } from './log'; | ||
@@ -4,0 +3,0 @@ export { dateSchema } from './schemas'; |
@@ -6,7 +6,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.setupGracefulShutdown = exports.healthChecksMiddleware = exports.markServiceAsReady = exports.UserRole = exports.redact = exports.createApiMethod = exports.dateSchema = exports.getDataFromMdc = exports.log = exports.openApiErrorHandler = exports.errorHandler = void 0; | ||
exports.setupGracefulShutdown = exports.healthChecksMiddleware = exports.markServiceAsReady = exports.UserRole = exports.redact = exports.createApiMethod = exports.dateSchema = exports.getDataFromMdc = exports.log = exports.errorHandler = void 0; | ||
var error_handler_1 = require("./error-handler"); | ||
Object.defineProperty(exports, "errorHandler", { enumerable: true, get: function () { return __importDefault(error_handler_1).default; } }); | ||
var openapi_error_handler_1 = require("./openapi-error-handler"); | ||
Object.defineProperty(exports, "openApiErrorHandler", { enumerable: true, get: function () { return __importDefault(openapi_error_handler_1).default; } }); | ||
var log_1 = require("./log"); | ||
@@ -13,0 +11,0 @@ Object.defineProperty(exports, "log", { enumerable: true, get: function () { return __importDefault(log_1).default; } }); |
{ | ||
"name": "@axah/koa", | ||
"version": "0.0.0-20240606065415", | ||
"version": "0.0.0-20240606073919", | ||
"main": "lib/index.js", | ||
@@ -5,0 +5,0 @@ "license": "UNLICENSED", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2
46683
35
692