arkos 2.0.0-next.29 → 2.0.0-next.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/esm/app.js +2 -0
  2. package/dist/esm/app.js.map +1 -1
  3. package/dist/esm/components/arkos-gateway/arkos-gateway.js +22 -5
  4. package/dist/esm/components/arkos-gateway/arkos-gateway.js.map +1 -1
  5. package/dist/esm/components/arkos-gateway/types.js.map +1 -1
  6. package/dist/esm/components/arkos-route-hook/index.js +9 -3
  7. package/dist/esm/components/arkos-route-hook/index.js.map +1 -1
  8. package/dist/esm/components/arkos-route-hook/reader.js.map +1 -1
  9. package/dist/esm/components/arkos-route-hook/types.js.map +1 -1
  10. package/dist/esm/exports/file-upload.js +2 -0
  11. package/dist/esm/exports/file-upload.js.map +1 -0
  12. package/dist/esm/exports/index.js.map +1 -1
  13. package/dist/esm/exports/websockets.js.map +1 -1
  14. package/dist/esm/generated.js.map +1 -1
  15. package/dist/esm/modules/auth/auth.controller.js +84 -141
  16. package/dist/esm/modules/auth/auth.controller.js.map +1 -1
  17. package/dist/esm/modules/auth/auth.router.js +1 -1
  18. package/dist/esm/modules/auth/auth.router.js.map +1 -1
  19. package/dist/esm/modules/auth/auth.service.js +93 -15
  20. package/dist/esm/modules/auth/auth.service.js.map +1 -1
  21. package/dist/esm/modules/auth/auth.types.js +2 -0
  22. package/dist/esm/modules/auth/auth.types.js.map +1 -0
  23. package/dist/esm/modules/auth/utils/helpers/auth.controller.helpers.js +1 -0
  24. package/dist/esm/modules/auth/utils/helpers/auth.controller.helpers.js.map +1 -1
  25. package/dist/esm/modules/auth/utils/token-extraction.js +57 -0
  26. package/dist/esm/modules/auth/utils/token-extraction.js.map +1 -0
  27. package/dist/esm/modules/base/base.controller.js +5 -0
  28. package/dist/esm/modules/base/base.controller.js.map +1 -1
  29. package/dist/esm/modules/base/base.middlewares.js +4 -4
  30. package/dist/esm/modules/base/base.middlewares.js.map +1 -1
  31. package/dist/esm/modules/base/utils/error-prettifier.js +64 -0
  32. package/dist/esm/modules/base/utils/error-prettifier.js.map +1 -1
  33. package/dist/esm/modules/error-handler/utils/error-handler.helpers.js +52 -8
  34. package/dist/esm/modules/error-handler/utils/error-handler.helpers.js.map +1 -1
  35. package/dist/esm/modules/error-handler/utils/get-handled-error.js +5 -0
  36. package/dist/esm/modules/error-handler/utils/get-handled-error.js.map +1 -1
  37. package/dist/esm/modules/file-upload/file-upload.controller.js +25 -7
  38. package/dist/esm/modules/file-upload/file-upload.controller.js.map +1 -1
  39. package/dist/esm/modules/file-upload/file-upload.router.js +21 -5
  40. package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
  41. package/dist/esm/modules/file-upload/file-upload.service.js +28 -18
  42. package/dist/esm/modules/file-upload/file-upload.service.js.map +1 -1
  43. package/dist/esm/modules/file-upload/utils/file-upload-json-schema-generator.js +37 -12
  44. package/dist/esm/modules/file-upload/utils/file-upload-json-schema-generator.js.map +1 -1
  45. package/dist/esm/modules/file-upload/utils/helpers/file-upload.helpers.js +73 -35
  46. package/dist/esm/modules/file-upload/utils/helpers/file-upload.helpers.js.map +1 -1
  47. package/dist/esm/modules/file-upload/utils/helpers/serve-upload-dir.js +206 -0
  48. package/dist/esm/modules/file-upload/utils/helpers/serve-upload-dir.js.map +1 -0
  49. package/dist/esm/modules/file-upload/utils/helpers/upload-path.helper.js +103 -0
  50. package/dist/esm/modules/file-upload/utils/helpers/upload-path.helper.js.map +1 -0
  51. package/dist/esm/modules/file-upload/utils/helpers/upload-serving-validation.js +212 -0
  52. package/dist/esm/modules/file-upload/utils/helpers/upload-serving-validation.js.map +1 -0
  53. package/dist/esm/modules/file-upload/utils/helpers/upload-serving.registry.js +30 -0
  54. package/dist/esm/modules/file-upload/utils/helpers/upload-serving.registry.js.map +1 -0
  55. package/dist/esm/modules/swagger/utils/helpers/get-swagger-default-configs.js +1 -1
  56. package/dist/esm/modules/swagger/utils/helpers/get-swagger-default-configs.js.map +1 -1
  57. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js +7 -8
  58. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
  59. package/dist/esm/types/index.js.map +1 -1
  60. package/dist/esm/types/internal.js +2 -0
  61. package/dist/esm/types/internal.js.map +1 -0
  62. package/dist/esm/types/new-arkos-config.js.map +1 -1
  63. package/dist/esm/types/upload.js.map +1 -1
  64. package/dist/esm/types/validation/validation-manager.js +18 -10
  65. package/dist/esm/types/validation/validation-manager.js.map +1 -1
  66. package/dist/esm/types/validation/validator.js.map +1 -1
  67. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  68. package/dist/esm/utils/arkos-router/index.js +2 -11
  69. package/dist/esm/utils/arkos-router/index.js.map +1 -1
  70. package/dist/esm/utils/arkos-router/route-config-validator.js +11 -10
  71. package/dist/esm/utils/arkos-router/route-config-validator.js.map +1 -1
  72. package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
  73. package/dist/esm/utils/arkos-router/types/upload-config.js.map +1 -1
  74. package/dist/esm/utils/arkos-router/utils/helpers/index.js +1 -0
  75. package/dist/esm/utils/arkos-router/utils/helpers/index.js.map +1 -1
  76. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js +326 -37
  77. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  78. package/dist/esm/utils/cli/dev.js +15 -2
  79. package/dist/esm/utils/cli/dev.js.map +1 -1
  80. package/dist/esm/utils/cli/generate.js +8 -3
  81. package/dist/esm/utils/cli/generate.js.map +1 -1
  82. package/dist/esm/utils/cli/index.js +21 -20
  83. package/dist/esm/utils/cli/index.js.map +1 -1
  84. package/dist/esm/utils/cli/prisma-generate.js +24 -5
  85. package/dist/esm/utils/cli/prisma-generate.js.map +1 -1
  86. package/dist/esm/utils/cli/start.js +2 -0
  87. package/dist/esm/utils/cli/start.js.map +1 -1
  88. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  89. package/dist/esm/utils/cli/utils/dependency-version-check.js +39 -0
  90. package/dist/esm/utils/cli/utils/dependency-version-check.js.map +1 -0
  91. package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
  92. package/dist/esm/utils/define-config.js +1 -0
  93. package/dist/esm/utils/define-config.js.map +1 -1
  94. package/dist/esm/utils/initialize-app.js +2 -0
  95. package/dist/esm/utils/initialize-app.js.map +1 -1
  96. package/dist/types/app.d.ts +5 -2
  97. package/dist/types/components/arkos-gateway/arkos-gateway.d.ts +19 -7
  98. package/dist/types/components/arkos-gateway/types.d.ts +19 -2
  99. package/dist/types/components/arkos-route-hook/index.d.ts +4 -3
  100. package/dist/types/components/arkos-route-hook/reader.d.ts +1 -1
  101. package/dist/types/components/arkos-route-hook/types.d.ts +4 -1
  102. package/dist/types/exports/file-upload.d.ts +1 -0
  103. package/dist/types/exports/index.d.ts +1 -2
  104. package/dist/types/exports/websockets.d.ts +1 -1
  105. package/dist/types/modules/auth/auth.controller.d.ts +10 -3
  106. package/dist/types/modules/auth/auth.service.d.ts +90 -0
  107. package/dist/types/modules/auth/auth.types.d.ts +72 -0
  108. package/dist/types/modules/auth/utils/helpers/auth.controller.helpers.d.ts +1 -0
  109. package/dist/types/modules/auth/utils/token-extraction.d.ts +53 -0
  110. package/dist/types/modules/base/base.controller.d.ts +1 -0
  111. package/dist/types/modules/base/utils/error-prettifier.d.ts +8 -0
  112. package/dist/types/modules/error-handler/utils/error-handler.helpers.d.ts +1 -0
  113. package/dist/types/modules/file-upload/file-upload.service.d.ts +2 -6
  114. package/dist/types/modules/file-upload/utils/helpers/file-upload.helpers.d.ts +21 -1
  115. package/dist/types/modules/file-upload/utils/helpers/serve-upload-dir.d.ts +43 -0
  116. package/dist/types/modules/file-upload/utils/helpers/upload-path.helper.d.ts +14 -0
  117. package/dist/types/modules/file-upload/utils/helpers/upload-serving-validation.d.ts +5 -0
  118. package/dist/types/modules/file-upload/utils/helpers/upload-serving.registry.d.ts +31 -0
  119. package/dist/types/modules/swagger/utils/helpers/openapi-schema-converter.d.ts +1 -1
  120. package/dist/types/types/index.d.ts +5 -0
  121. package/dist/types/types/internal.d.ts +25 -0
  122. package/dist/types/types/new-arkos-config.d.ts +24 -2
  123. package/dist/types/types/upload.d.ts +35 -0
  124. package/dist/types/types/validation/validation-manager.d.ts +6 -8
  125. package/dist/types/types/validation/validator.d.ts +2 -2
  126. package/dist/types/utils/arkos-router/types/index.d.ts +3 -2
  127. package/dist/types/utils/arkos-router/types/upload-config.d.ts +102 -11
  128. package/dist/types/utils/arkos-router/utils/helpers/upload-manager.d.ts +20 -0
  129. package/dist/types/utils/cli/utils/dependency-version-check.d.ts +15 -0
  130. package/dist/types/utils/define-config.d.ts +56 -2
  131. package/dist/types/utils/helpers/prisma.helpers.d.ts +1 -1
  132. package/package.json +15 -38
@@ -1 +1 @@
1
- {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from 'express';\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosResponse,\n AuthPrismaQueryOptions,\n} from '../../types';\nimport { getArkosConfig } from '../../server';\nimport deepmerge from '../../utils/helpers/deepmerge.helper';\nimport {\n AppError,\n BadRequestError,\n catchAsync,\n} from '../../exports/error-handler';\nimport { resolvePrismaQueryOptions } from './utils/helpers/base.middlewares.helpers';\nimport { ArkosRouteConfig } from '../../utils/arkos-router/types';\nimport { capitalize } from '../../utils/helpers/text.helpers';\nimport errorPrettifier from './utils/error-prettifier';\nimport { lenientDecode } from '../../utils/helpers/url-helpers';\nimport { pascalCase } from '../../exports/utils';\nimport validationManager from '../../types/validation/validation-manager';\n\n/**\n * Deep comparison helper for objects\n */\nfunction deepEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return a === b;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(a[key], b[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Sends response with backward compatibility support\n * Compares current values against original values to detect middleware changes\n * If values were modified by subsequent middleware, use the modified version\n */\nexport function sendResponse(req: ArkosRequest, res: ArkosResponse) {\n let responseData;\n let responseStatus;\n\n const originalData = (res as any).originalData;\n const originalStatus = (res as any).originalStatus;\n\n const currentReqData = req.responseData;\n const currentReqStatus = req.responseStatus;\n const currentLocalsData = res.locals?.data;\n const currentLocalsStatus = res.locals?.status;\n\n if (\n currentReqData !== undefined &&\n !deepEqual(currentReqData, originalData)\n ) {\n responseData = currentReqData;\n } else if (\n currentLocalsData !== undefined &&\n !deepEqual(currentLocalsData, originalData)\n ) {\n responseData = currentLocalsData;\n } else if (originalData !== undefined) {\n responseData = originalData;\n } else {\n responseData = currentReqData ?? currentLocalsData;\n }\n\n if (currentReqStatus !== undefined && currentReqStatus !== originalStatus) {\n responseStatus = currentReqStatus;\n } else if (\n currentLocalsStatus !== undefined &&\n currentLocalsStatus !== originalStatus\n ) {\n responseStatus = currentLocalsStatus;\n } else if (originalStatus !== undefined) {\n responseStatus = originalStatus;\n } else {\n responseStatus = currentReqStatus ?? currentLocalsStatus;\n }\n\n // Send response\n\n if (Number(responseStatus) === 204) {\n res.status(Number(responseStatus)).send();\n } else if (\n (responseData !== undefined || responseData !== null) &&\n responseStatus\n ) {\n res.status(Number(responseStatus)).json(responseData);\n } else if (\n Number(responseStatus) &&\n (responseData === undefined || responseData === null)\n ) {\n res.status(Number(responseStatus)).send();\n } else {\n res.status(500).json({\n message: 'No status or data attached to the response',\n });\n }\n}\n\n/**\n * Type representing all possible actions that can be performed on a controller\n * Combines both standard CRUD operations and auth-specific operations\n */\nexport type ControllerActions =\n | keyof PrismaQueryOptions<any>\n | keyof Omit<AuthPrismaQueryOptions<any>, keyof PrismaQueryOptions<any>>;\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T> | AuthPrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequest<T extends Record<string, any>>(\n prismaQueryOptions: PrismaQueryOptions<T> | AuthPrismaQueryOptions<T>,\n action: ControllerActions,\n) {\n return (req: ArkosRequest, _: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const resolvedOptions = resolvePrismaQueryOptions(\n prismaQueryOptions,\n action,\n );\n\n const requestQueryOptions = configs?.request?.parameters\n ?.allowDangerousPrismaQueryOptions\n ? JSON.parse((req.query?.prismaQueryOptions as string) || '{}')\n : {};\n\n req.prismaQueryOptions = deepmerge(resolvedOptions, requestQueryOptions);\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction,\n) {\n const startTime = Date.now();\n\n const methodColors = {\n GET: '\\x1b[36m', // Cyan\n POST: '\\x1b[32m', // Green\n PUT: '\\x1b[33m', // Orange/Yellow\n PATCH: '\\x1b[33m', // Orange/Yellow\n DELETE: '\\x1b[31m', // Red\n HEAD: '\\x1b[34m', // Blue\n OPTIONS: '\\x1b[34m', // Blue\n };\n\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return '\\x1b[32m';\n if (statusCode >= 300 && statusCode < 400) return '\\x1b[33m';\n if (statusCode >= 400 && statusCode < 500) return '\\x1b[33m';\n if (statusCode >= 500) return '\\x1b[31m';\n return '\\x1b[0m';\n };\n\n res.on('finish', () => {\n const isProduction = process.env.ARKOS_BUILD == 'true';\n const duration = Date.now() - startTime;\n\n const now = new Date();\n\n const date = now.toISOString().split('T')[0];\n const time = now.toTimeString().split(' ')[0];\n\n const timestamp = isProduction ? `${date} ${time}` : time;\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || '\\x1b[0m';\n const statusColor = getStatusColor(res.statusCode);\n\n console.info(\n `[\\x1b[36mInfo\\x1b[0m] \\x1b[90m${timestamp}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${lenientDecode(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`,\n );\n });\n\n next();\n}\n\nexport function validateRequestInputs(routeConfig: ArkosRouteConfig) {\n const arkosConfig = getArkosConfig();\n const validationConfig = arkosConfig.validation;\n const validators = routeConfig?.validation;\n const openapi = routeConfig?.experimental?.openapi;\n\n const validationToParameterMapping = {\n query: 'query',\n params: 'path',\n headers: 'header',\n cookies: 'cookie',\n };\n\n if (\n !validationConfig?.resolver &&\n Object.keys(routeConfig.validation || {}).length > 0\n )\n throw Error(\n `Trying to pass validators into route \\\"${routeConfig.path}\\\" config validation option without choosing a validation resolver under arkos config { validation: {} }.`,\n );\n\n if ((validators as any) === true)\n throw Error(\n `Invalid value ${validators} passed to validation option, it can only receive false or object of { query, body, params }.`,\n );\n\n const validatorsKey: ('body' | 'query' | 'params')[] = [\n 'body',\n 'query',\n 'params',\n ];\n\n const { validationFn, validatorNameType, validatorName } = validationManager;\n\n if (typeof validators === 'object')\n validatorsKey.forEach((key) => {\n if (\n openapi &&\n typeof openapi === 'object' &&\n key != 'body' &&\n openapi.parameters?.some(\n (parameter: any) =>\n parameter.in === validationToParameterMapping[key],\n ) &&\n validators?.[key]\n ) {\n throw Error(\n `Error in ${routeConfig.path}: when usign validation.${key} you must not define parameters under openapi.parameters as documentation of req.${key} because the ${validatorName} you passed under validation.${key} will be added as jsonSchema into the api documenation, if you wish to define documenation by yourself do not define validation.${key}.\n\nRead more about strict validation at https://www.arkosjs.com/docs/guides/validation/setup#strict-mode.\n`,\n );\n }\n\n if (\n openapi &&\n typeof openapi === 'object' &&\n openapi.requestBody &&\n validators?.[key] &&\n key === 'body'\n ) {\n throw Error(\n `When usign validation.${key} you must not define json-schema under openapi.requestBody as documentation for req.${key}, because the ${validatorName} you passed under validation.${key} will be added as json-schema into the api documenation, if you wish to define documenation by yourself do not define validation.${key}.`,\n );\n }\n\n if (\n validators?.[key] &&\n !validationManager.isValidator(validators?.[key])\n )\n throw Error(\n `Your validation resolver is set to ${arkosConfig?.validation?.resolver}, please provide a valid ${validatorName} in order to use in { validation: { ${key}: ${validatorNameType} } } under route ${routeConfig.path}. Received ${validators?.[key]}`,\n );\n });\n\n return catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n for (const key of validatorsKey) {\n const validator = (validators as any)?.[key];\n const NotAllowedInputError = new BadRequestError(\n `Request ${key} is not allowed on this route`,\n `Request${capitalize(key)}NotAllowed`,\n { [key]: req[key] },\n );\n\n const shouldValidate = validationManager.shouldValidate(\n validator,\n req?.[key],\n );\n\n if (shouldValidate === 'prohibit') throw NotAllowedInputError;\n else if (shouldValidate === 'passthrough') continue;\n\n if (validator)\n try {\n Object.defineProperty(req, key, {\n value: await (validationFn as any)(\n validator,\n req[key],\n arkosConfig.validation?.validationOptions,\n ),\n writable: false,\n configurable: true,\n enumerable: true,\n });\n } catch (err: any) {\n const resolver = validationConfig?.resolver;\n const isZod = validationConfig?.resolver === 'zod';\n\n const prettifiedError = errorPrettifier.prettify(\n resolver as any,\n err,\n );\n const error = prettifiedError[0];\n throw new AppError(\n error.message,\n 400,\n `InvalidRequest${pascalCase(key)}`,\n isZod ? err.format() : err,\n );\n }\n }\n\n next();\n },\n );\n}\n\n"]}
1
+ {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from 'express';\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosResponse,\n AuthPrismaQueryOptions,\n} from '../../types';\nimport { getArkosConfig } from '../../server';\nimport { isZodSchema } from '../../utils/dynamic-loader';\nimport deepmerge from '../../utils/helpers/deepmerge.helper';\nimport {\n AppError,\n BadRequestError,\n catchAsync,\n} from '../../exports/error-handler';\nimport { resolvePrismaQueryOptions } from './utils/helpers/base.middlewares.helpers';\nimport { ArkosRouteConfig } from '../../utils/arkos-router/types';\nimport { capitalize } from '../../utils/helpers/text.helpers';\nimport errorPrettifier from './utils/error-prettifier';\nimport { lenientDecode } from '../../utils/helpers/url-helpers';\nimport { pascalCase } from '../../exports/utils';\nimport validationManager from '../../types/validation/validation-manager';\n\n/**\n * Deep comparison helper for objects\n */\nfunction deepEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return a === b;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(a[key], b[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Sends response with backward compatibility support\n * Compares current values against original values to detect middleware changes\n * If values were modified by subsequent middleware, use the modified version\n */\nexport function sendResponse(req: ArkosRequest, res: ArkosResponse) {\n let responseData;\n let responseStatus;\n\n const originalData = (res as any).originalData;\n const originalStatus = (res as any).originalStatus;\n\n const currentReqData = req.responseData;\n const currentReqStatus = req.responseStatus;\n const currentLocalsData = res.locals?.data;\n const currentLocalsStatus = res.locals?.status;\n\n if (\n currentReqData !== undefined &&\n !deepEqual(currentReqData, originalData)\n ) {\n responseData = currentReqData;\n } else if (\n currentLocalsData !== undefined &&\n !deepEqual(currentLocalsData, originalData)\n ) {\n responseData = currentLocalsData;\n } else if (originalData !== undefined) {\n responseData = originalData;\n } else {\n responseData = currentReqData ?? currentLocalsData;\n }\n\n if (currentReqStatus !== undefined && currentReqStatus !== originalStatus) {\n responseStatus = currentReqStatus;\n } else if (\n currentLocalsStatus !== undefined &&\n currentLocalsStatus !== originalStatus\n ) {\n responseStatus = currentLocalsStatus;\n } else if (originalStatus !== undefined) {\n responseStatus = originalStatus;\n } else {\n responseStatus = currentReqStatus ?? currentLocalsStatus;\n }\n\n // Send response\n\n if (Number(responseStatus) === 204) {\n res.status(Number(responseStatus)).send();\n } else if (\n (responseData !== undefined || responseData !== null) &&\n responseStatus\n ) {\n res.status(Number(responseStatus)).json(responseData);\n } else if (\n Number(responseStatus) &&\n (responseData === undefined || responseData === null)\n ) {\n res.status(Number(responseStatus)).send();\n } else {\n res.status(500).json({\n message: 'No status or data attached to the response',\n });\n }\n}\n\n/**\n * Type representing all possible actions that can be performed on a controller\n * Combines both standard CRUD operations and auth-specific operations\n */\nexport type ControllerActions =\n | keyof PrismaQueryOptions<any>\n | keyof Omit<AuthPrismaQueryOptions<any>, keyof PrismaQueryOptions<any>>;\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T> | AuthPrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequest<T extends Record<string, any>>(\n prismaQueryOptions: PrismaQueryOptions<T> | AuthPrismaQueryOptions<T>,\n action: ControllerActions,\n) {\n return (req: ArkosRequest, _: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const resolvedOptions = resolvePrismaQueryOptions(\n prismaQueryOptions,\n action,\n );\n\n const requestQueryOptions = configs?.request?.parameters\n ?.allowDangerousPrismaQueryOptions\n ? JSON.parse((req.query?.prismaQueryOptions as string) || '{}')\n : {};\n\n req.prismaQueryOptions = deepmerge(resolvedOptions, requestQueryOptions);\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction,\n) {\n const startTime = Date.now();\n\n const methodColors = {\n GET: '\\x1b[36m', // Cyan\n POST: '\\x1b[32m', // Green\n PUT: '\\x1b[33m', // Orange/Yellow\n PATCH: '\\x1b[33m', // Orange/Yellow\n DELETE: '\\x1b[31m', // Red\n HEAD: '\\x1b[34m', // Blue\n OPTIONS: '\\x1b[34m', // Blue\n };\n\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return '\\x1b[32m';\n if (statusCode >= 300 && statusCode < 400) return '\\x1b[33m';\n if (statusCode >= 400 && statusCode < 500) return '\\x1b[33m';\n if (statusCode >= 500) return '\\x1b[31m';\n return '\\x1b[0m';\n };\n\n res.on('finish', () => {\n const isProduction = process.env.ARKOS_BUILD == 'true';\n const duration = Date.now() - startTime;\n\n const now = new Date();\n\n const date = now.toISOString().split('T')[0];\n const time = now.toTimeString().split(' ')[0];\n\n const timestamp = isProduction ? `${date} ${time}` : time;\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || '\\x1b[0m';\n const statusColor = getStatusColor(res.statusCode);\n\n console.info(\n `[\\x1b[36mInfo\\x1b[0m] \\x1b[90m${timestamp}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${lenientDecode(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`,\n );\n });\n\n next();\n}\n\nexport function validateRequestInputs(routeConfig: ArkosRouteConfig) {\n const arkosConfig = getArkosConfig();\n const validationConfig = arkosConfig.validation;\n const validators = routeConfig?.validation;\n const openapi = routeConfig?.experimental?.openapi;\n\n const validationToParameterMapping = {\n query: 'query',\n params: 'path',\n headers: 'header',\n cookies: 'cookie',\n };\n\n if (\n !validationConfig?.resolver &&\n Object.keys(routeConfig.validation || {}).length > 0\n )\n throw Error(\n `Trying to pass validators into route \\\"${routeConfig.path}\\\" config validation option without choosing a validation resolver under arkos config { validation: {} }.`,\n );\n\n if ((validators as any) === true)\n throw Error(\n `Invalid value ${validators} passed to validation option, it can only receive false or object of { query, body, params }.`,\n );\n\n const validatorsKey: ('body' | 'query' | 'params')[] = [\n 'body',\n 'query',\n 'params',\n ];\n\n const { validationFn, validatorNameType, validatorName } = validationManager;\n\n if (typeof validators === 'object')\n validatorsKey.forEach((key) => {\n if (\n openapi &&\n typeof openapi === 'object' &&\n key != 'body' &&\n openapi.parameters?.some(\n (parameter: any) =>\n parameter.in === validationToParameterMapping[key],\n ) &&\n validators?.[key]\n ) {\n throw Error(\n `Error in ${routeConfig.path}: when usign validation.${key} you must not define parameters under openapi.parameters as documentation of req.${key} because the ${validatorName} you passed under validation.${key} will be added as jsonSchema into the api documenation, if you wish to define documenation by yourself do not define validation.${key}.\n\nRead more about strict validation at https://www.arkosjs.com/docs/guides/validation/setup#strict-mode.\n`,\n );\n }\n\n if (\n openapi &&\n typeof openapi === 'object' &&\n openapi.requestBody &&\n validators?.[key] &&\n key === 'body'\n ) {\n throw Error(\n `When usign validation.${key} you must not define json-schema under openapi.requestBody as documentation for req.${key}, because the ${validatorName} you passed under validation.${key} will be added as json-schema into the api documenation, if you wish to define documenation by yourself do not define validation.${key}.`,\n );\n }\n\n if (\n validators?.[key] &&\n !validationManager.isValidator(validators?.[key])\n )\n throw Error(\n `Your validation resolver is set to ${arkosConfig?.validation?.resolver}, please provide a valid ${validatorName} in order to use in { validation: { ${key}: ${validatorNameType} } } under route ${routeConfig.path}. Received ${validators?.[key]}`,\n );\n });\n\n return catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n for (const key of validatorsKey) {\n const validator = (validators as any)?.[key];\n const NotAllowedInputError = new BadRequestError(\n `Request ${key} is not allowed on this route`,\n `Request${capitalize(key)}NotAllowed`,\n { [key]: req[key] },\n );\n\n const shouldValidate = validationManager.shouldValidate(\n validator,\n req?.[key],\n );\n\n if (shouldValidate === 'prohibit') throw NotAllowedInputError;\n else if (shouldValidate === 'passthrough') continue;\n\n if (validator)\n try {\n Object.defineProperty(req, key, {\n value: await (validationFn as any)(\n validator,\n req[key],\n arkosConfig.validation?.validationOptions,\n ),\n writable: false,\n configurable: true,\n enumerable: true,\n });\n } catch (err: any) {\n const isZod = isZodSchema(validator);\n\n const prettifiedError = errorPrettifier.prettify(\n isZod ? 'zod' : ('class-validator' as any),\n err,\n );\n\n const error = prettifiedError[0];\n throw new AppError(\n error?.message || err?.message || `Request ${key} is invalid`,\n 400,\n `InvalidRequest${pascalCase(key)}`,\n isZod && typeof err?.format === 'function' ? err.format() : err,\n );\n }\n }\n\n next();\n },\n );\n}\n\n"]}
@@ -106,6 +106,8 @@ export class ErrorPrettifier {
106
106
  return "ArrayMaxSizeConstraint";
107
107
  }
108
108
  return "TooBigConstraint";
109
+ case "invalid_format":
110
+ return this.mapZodFormatToConstraintName(issue.format);
109
111
  case "invalid_value":
110
112
  if (issue.values.length > 1) {
111
113
  return "IsEnumConstraint";
@@ -123,6 +125,60 @@ export class ErrorPrettifier {
123
125
  return "ValidationConstraint";
124
126
  }
125
127
  }
128
+ mapZodFormatToConstraintName(format) {
129
+ switch (format) {
130
+ case "email":
131
+ return "IsEmailConstraint";
132
+ case "uuid":
133
+ case "guid":
134
+ return "IsUuidConstraint";
135
+ case "url":
136
+ return "IsUrlConstraint";
137
+ case "emoji":
138
+ return "IsEmojiConstraint";
139
+ case "datetime":
140
+ case "date":
141
+ case "time":
142
+ case "duration":
143
+ return "IsDateStringConstraint";
144
+ case "ipv4":
145
+ case "ipv6":
146
+ case "cidrv4":
147
+ case "cidrv6":
148
+ return "IsIPConstraint";
149
+ case "base64":
150
+ case "base64url":
151
+ return "IsBase64Constraint";
152
+ case "json_string":
153
+ return "IsJSONConstraint";
154
+ case "e164":
155
+ return "IsPhoneNumberConstraint";
156
+ case "jwt":
157
+ return "IsJWTConstraint";
158
+ case "regex":
159
+ return "MatchesConstraint";
160
+ case "starts_with":
161
+ return "StartsWithConstraint";
162
+ case "ends_with":
163
+ return "EndsWithConstraint";
164
+ case "includes":
165
+ return "ContainsConstraint";
166
+ case "lowercase":
167
+ return "IsLowercaseConstraint";
168
+ case "uppercase":
169
+ return "IsUppercaseConstraint";
170
+ case "nanoid":
171
+ case "cuid":
172
+ case "cuid2":
173
+ case "ulid":
174
+ case "xid":
175
+ case "ksuid":
176
+ case "template_literal":
177
+ return "IsStringConstraint";
178
+ default:
179
+ return "InvalidFormatConstraint";
180
+ }
181
+ }
126
182
  prettifyZod(error) {
127
183
  const result = [];
128
184
  for (const issue of error.issues) {
@@ -166,6 +222,14 @@ export class ErrorPrettifier {
166
222
  if (message.startsWith("Expected")) {
167
223
  return `'${fieldPath}' must be valid: ${message}`;
168
224
  }
225
+ if (message.startsWith("Invalid input:")) {
226
+ const detail = message.replace(/^Invalid input:\s*/, "");
227
+ return `'${fieldPath}' must be valid: ${detail}`;
228
+ }
229
+ if (message.startsWith("Too small:") || message.startsWith("Too big:")) {
230
+ const detail = message.charAt(0).toLowerCase() + message.slice(1);
231
+ return `'${fieldPath}' ${detail}`;
232
+ }
169
233
  if (message.startsWith("Invalid ")) {
170
234
  const type = message.replace("Invalid ", "");
171
235
  return `'${fieldPath}' must be a valid ${type}`;
@@ -1 +1 @@
1
- {"version":3,"file":"error-prettifier.js","sourceRoot":"","sources":["../../../../../src/modules/base/utils/error-prettifier.ts"],"names":[],"mappings":"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","sourcesContent":["import { ValidationError } from \"class-validator\";\nimport z, { ZodError } from \"zod\";\nimport { pascalCase } from \"../../../utils/helpers/change-case.helpers\";\n\n/**\n * Prettified error result with consistent format\n */\nexport interface PrettifiedError {\n /** Human-readable error message */\n message: string;\n /** Field name + constraint type code (e.g., 'NameIsStringConstraint') */\n code: string;\n}\n\n/**\n * Supported validation library types\n */\nexport type ValidationLibrary = \"class-validator\" | \"zod\";\n\n/**\n * ErrorPrettifier class for normalizing validation errors from class-validator and Zod\n * into a consistent format with field name + constraint code pattern.\n *\n * @example\n * ```typescript\n * const prettifier = new ErrorPrettifier();\n *\n * // Class-validator example\n * const classValidatorErrors = await validate(userDto);\n * const prettified = prettifier.prettify('class-validator', classValidatorErrors);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n *\n * // Zod example\n * try {\n * schema.parse(data);\n * } catch (error) {\n * const prettified = prettifier.prettify('zod', error);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n * }\n *\n * // Nested errors\n * // [{ message: 'user.address.street must be a string', code: 'UserAddressStreetIsStringConstraint' }]\n * ```\n */\nexport class ErrorPrettifier {\n /**\n * Prettifies validation errors from class-validator or Zod into a consistent format.\n *\n * @param library - The validation library type ('class-validator' or 'zod')\n * @param error - The validation error(s) from the library\n * @returns Array of prettified errors with consistent message and code format\n */\n prettify(\n library: \"class-validator\",\n error: ValidationError[]\n ): PrettifiedError[];\n prettify(library: \"zod\", error: ZodError): PrettifiedError[];\n prettify(\n library: ValidationLibrary,\n error: ValidationError[] | ZodError\n ): PrettifiedError[] {\n if (library === \"class-validator\") {\n return this.prettifyClassValidator(error as ValidationError[]);\n } else {\n return this.prettifyZod(error as ZodError);\n }\n }\n\n /**\n * Converts a field path to PascalCase for code generation.\n *\n * @example\n * ```typescript\n * toPascalCase('user.address.street') // 'UserAddressStreet'\n * toPascalCase('email') // 'Email'\n * ```\n *\n * @param path - Dot-separated field path\n * @returns PascalCase version of the path\n */\n private toPascalCase(path: string): string {\n return path\n .split(\".\")\n .map((part) => pascalCase(part))\n .join(\"\");\n }\n\n /**\n * Replaces the field name in the validation message with the full path.\n * Handles array indices like tags[0] and nested paths like user.address.street.\n *\n * @example\n * ```typescript\n * replaceFieldInMessage('id must be a UUID', 'id', 'user.id')\n * // Returns: ''user.id' must be a UUID'\n *\n * replaceFieldInMessage('name must be a string', 'name', 'tags[0].name')\n * // Returns: ''tags[0].name' must be a string'\n * ```\n *\n * @param message - Original validation message\n * @param fieldName - Original field name\n * @param fullPath - Full path including parent properties\n * @returns Message with field name replaced by full path\n */\n private replaceFieldInMessage(\n message: string,\n fieldName: string,\n fullPath: string\n ): string {\n // If it's a top-level field (no dots or brackets), return original message\n if (!fullPath.includes(\".\") && !fullPath.includes(\"[\")) {\n return message;\n }\n\n // Replace the field name at the start of the message with the full path\n // Handle cases like \"id must be a UUID\" -> \"'user.id' must be a UUID\"\n const regex = new RegExp(`^${fieldName}\\\\b`, \"i\");\n if (regex.test(message)) {\n return message.replace(regex, `'${fullPath}'`);\n }\n\n // If field name is not at the start, try to find it and replace\n // This handles cases like \"must be a valid id\" or other formats\n const wordBoundaryRegex = new RegExp(`\\\\b${fieldName}\\\\b`, \"gi\");\n if (wordBoundaryRegex.test(message)) {\n return message.replace(wordBoundaryRegex, `'${fullPath}'`);\n }\n\n // If we can't find the field name in the message, prepend the path\n return `'${fullPath}' ${message}`;\n }\n\n /**\n * Prettifies class-validator ValidationError array.\n * Handles nested validation errors recursively.\n *\n * @param errors - Array of ValidationError from class-validator\n * @param parentPath - Parent path for nested errors (used internally)\n * @returns Array of prettified errors\n */\n private prettifyClassValidator(\n errors: ValidationError[],\n parentPath: string = \"\"\n ): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const error of errors) {\n const currentPath = parentPath\n ? `${parentPath}.${error.property}`\n : error.property;\n\n if (error.children && error.children.length > 0) {\n result.push(\n ...this.prettifyClassValidator(error.children, currentPath)\n );\n continue;\n }\n\n if (error.constraints) {\n const fieldPascal = this.toPascalCase(currentPath);\n\n for (const [constraintKey, originalMessage] of Object.entries(\n error.constraints\n )) {\n const constraintName =\n constraintKey.charAt(0).toUpperCase() + constraintKey.slice(1);\n\n const message = this.replaceFieldInMessage(\n originalMessage,\n error.property,\n currentPath\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}Constraint`,\n });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Maps Zod error codes and validation info to class-validator style constraint names.\n *\n * @param issue - Zod validation issue\n * @returns Class-validator style constraint name\n */\n private mapZodToConstraintName(issue: z.core.$ZodIssue): string {\n switch (issue.code) {\n case \"invalid_type\":\n const expected = issue.expected;\n switch (expected) {\n case \"string\":\n return \"IsStringConstraint\";\n case \"email\":\n return \"IsEmailConstraint\";\n case \"uuid\":\n return \"IsUuidConstraint\";\n case \"url\":\n return \"IsUrlConstraint\";\n case \"number\":\n return \"IsNumberConstraint\";\n case \"boolean\":\n return \"IsBooleanConstraint\";\n case \"array\":\n return \"IsArrayConstraint\";\n case \"object\":\n return \"IsObjectConstraint\";\n case \"date\":\n return \"IsDateConstraint\";\n default:\n if (typeof expected === \"object\" && \"includes\" in expected)\n return \"ContainsConstraint\";\n if (typeof expected === \"object\" && \"startsWith\" in expected)\n return \"StartsWithConstraint\";\n if (typeof expected === \"object\" && \"endsWith\" in expected)\n return \"EndsWithConstraint\";\n return \"InvalidTypeConstraint\";\n }\n\n case \"too_small\":\n if (issue.origin === \"string\") {\n return \"MinLengthConstraint\";\n } else if (issue.origin === \"number\") {\n return \"MinConstraint\";\n } else if (issue.origin === \"array\") {\n return \"ArrayMinSizeConstraint\";\n }\n return \"TooSmallConstraint\";\n\n case \"too_big\":\n if (issue.origin === \"string\") {\n return \"MaxLengthConstraint\";\n } else if (issue.origin === \"number\") {\n return \"MaxConstraint\";\n } else if (issue.origin === \"array\") {\n return \"ArrayMaxSizeConstraint\";\n }\n return \"TooBigConstraint\";\n\n // case \"invalid_string\":\n // if (\"expected\" in issue) {\n // const validation = issue.expected;\n // if (validation === \"email\") return \"IsEmailConstraint\";\n // if (validation === \"uuid\") return \"IsUuidConstraint\";\n // if (validation === \"url\") return \"IsUrlConstraint\";\n // if (typeof validation === \"object\" && \"includes\" in validation)\n // return \"ContainsConstraint\";\n // if (typeof validation === \"object\" && \"startsWith\" in validation)\n // return \"StartsWithConstraint\";\n // if (typeof validation === \"object\" && \"endsWith\" in validation)\n // return \"EndsWithConstraint\";\n // }\n // return \"InvalidStringConstraint\";\n //\n case \"invalid_value\":\n if (issue.values.length > 1) {\n return \"IsEnumConstraint\";\n } else {\n return \"EqualsConstraint\";\n }\n\n // case \"invalid_enum_value\":\n // return \"IsEnumConstraint\";\n\n // case \"invalid_literal\":\n // return \"EqualsConstraint\";\n\n case \"unrecognized_keys\":\n return \"UnrecognizedKeysConstraint\";\n\n case \"invalid_union\":\n return \"InvalidUnionConstraint\";\n\n case \"custom\":\n return \"CustomConstraint\";\n\n default:\n return \"ValidationConstraint\";\n }\n }\n\n /**\n * Prettifies Zod ZodError.\n * Handles nested paths and multiple issues per field.\n *\n * @param error - ZodError from Zod validation\n * @returns Array of prettified errors\n */\n private prettifyZod(error: ZodError): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const issue of error.issues) {\n // Build the field path from the issue path\n const fieldPath = issue.path\n .map((segment, index) => {\n // Handle array indices: convert to bracket notation\n if (typeof segment === \"number\") {\n return `[${segment}]`;\n }\n // First segment doesn't need a dot prefix\n return index === 0 ? segment : `.${String(segment)}`;\n })\n .join(\"\")\n .replace(/\\.\\[/g, \"[\"); // Clean up .[ to just [\n\n const fieldPascal = fieldPath\n ? this.toPascalCase(fieldPath.replace(/\\[\\d+\\]/g, \"\"))\n : \"\";\n\n // Map Zod error code to constraint name\n const constraintName = this.mapZodToConstraintName(issue);\n\n // Inject the field path into the message naturally\n const message = this.injectFieldPathInZodMessage(\n issue.message,\n fieldPath,\n issue\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}`,\n });\n }\n\n return result;\n }\n\n /**\n * Injects the field path into Zod error messages naturally.\n *\n * @example\n * ```typescript\n * injectFieldPathInZodMessage('String must contain at least 100 character(s)', 'user.id', issue)\n * // Returns: ''user.id' must contain at least 100 character(s)'\n *\n * injectFieldPathInZodMessage('Required', 'email', issue)\n * // Returns: ''email' is required'\n * ```\n *\n * @param message - Original Zod error message\n * @param fieldPath - Full field path (e.g., 'user.id', 'tags[0].name')\n * @param issue - Zod issue for context\n * @returns Message with field path injected naturally\n */\n private injectFieldPathInZodMessage(\n message: string,\n fieldPath: string,\n _: z.core.$ZodIssue\n ): string {\n if (!fieldPath) {\n return message;\n }\n\n // \"Required\" -> \"'fieldPath' is required\"\n if (message === \"Required\") {\n return `'${fieldPath}' is required`;\n }\n\n // \"String must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"String must\")) {\n return message.replace(/^String must/, `'${fieldPath}' must`);\n }\n\n // \"Number must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Number must\")) {\n return message.replace(/^Number must/, `'${fieldPath}' must`);\n }\n\n // \"Array must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Array must\")) {\n return message.replace(/^Array must/, `'${fieldPath}' must`);\n }\n\n // \"Expected string, received number\" -> \"'fieldPath': Expected string, received number\"\n if (message.startsWith(\"Expected\")) {\n return `'${fieldPath}' must be valid: ${message}`;\n }\n\n // \"Invalid email\" -> \"'fieldPath' must be a valid email\"\n if (message.startsWith(\"Invalid \")) {\n const type = message.replace(\"Invalid \", \"\");\n return `'${fieldPath}' must be a valid ${type}`;\n }\n\n // For any other message, return the message\n if (!message.toLowerCase().includes(fieldPath))\n return `'${fieldPath}' ${message}`;\n return message;\n }\n}\n\nconst errorPrettifier = new ErrorPrettifier();\n\nexport default errorPrettifier;\n\n"]}
1
+ {"version":3,"file":"error-prettifier.js","sourceRoot":"","sources":["../../../../../src/modules/base/utils/error-prettifier.ts"],"names":[],"mappings":"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","sourcesContent":["import { ValidationError } from \"class-validator\";\nimport z, { ZodError } from \"zod\";\nimport { pascalCase } from \"../../../utils/helpers/change-case.helpers\";\n\n/**\n * Prettified error result with consistent format\n */\nexport interface PrettifiedError {\n /** Human-readable error message */\n message: string;\n /** Field name + constraint type code (e.g., 'NameIsStringConstraint') */\n code: string;\n}\n\n/**\n * Supported validation library types\n */\nexport type ValidationLibrary = \"class-validator\" | \"zod\";\n\n/**\n * ErrorPrettifier class for normalizing validation errors from class-validator and Zod\n * into a consistent format with field name + constraint code pattern.\n *\n * @example\n * ```typescript\n * const prettifier = new ErrorPrettifier();\n *\n * // Class-validator example\n * const classValidatorErrors = await validate(userDto);\n * const prettified = prettifier.prettify('class-validator', classValidatorErrors);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n *\n * // Zod example\n * try {\n * schema.parse(data);\n * } catch (error) {\n * const prettified = prettifier.prettify('zod', error);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n * }\n *\n * // Nested errors\n * // [{ message: 'user.address.street must be a string', code: 'UserAddressStreetIsStringConstraint' }]\n * ```\n */\nexport class ErrorPrettifier {\n /**\n * Prettifies validation errors from class-validator or Zod into a consistent format.\n *\n * @param library - The validation library type ('class-validator' or 'zod')\n * @param error - The validation error(s) from the library\n * @returns Array of prettified errors with consistent message and code format\n */\n prettify(\n library: \"class-validator\",\n error: ValidationError[]\n ): PrettifiedError[];\n prettify(library: \"zod\", error: ZodError): PrettifiedError[];\n prettify(\n library: ValidationLibrary,\n error: ValidationError[] | ZodError\n ): PrettifiedError[] {\n if (library === \"class-validator\") {\n return this.prettifyClassValidator(error as ValidationError[]);\n } else {\n return this.prettifyZod(error as ZodError);\n }\n }\n\n /**\n * Converts a field path to PascalCase for code generation.\n *\n * @example\n * ```typescript\n * toPascalCase('user.address.street') // 'UserAddressStreet'\n * toPascalCase('email') // 'Email'\n * ```\n *\n * @param path - Dot-separated field path\n * @returns PascalCase version of the path\n */\n private toPascalCase(path: string): string {\n return path\n .split(\".\")\n .map((part) => pascalCase(part))\n .join(\"\");\n }\n\n /**\n * Replaces the field name in the validation message with the full path.\n * Handles array indices like tags[0] and nested paths like user.address.street.\n *\n * @example\n * ```typescript\n * replaceFieldInMessage('id must be a UUID', 'id', 'user.id')\n * // Returns: ''user.id' must be a UUID'\n *\n * replaceFieldInMessage('name must be a string', 'name', 'tags[0].name')\n * // Returns: ''tags[0].name' must be a string'\n * ```\n *\n * @param message - Original validation message\n * @param fieldName - Original field name\n * @param fullPath - Full path including parent properties\n * @returns Message with field name replaced by full path\n */\n private replaceFieldInMessage(\n message: string,\n fieldName: string,\n fullPath: string\n ): string {\n // If it's a top-level field (no dots or brackets), return original message\n if (!fullPath.includes(\".\") && !fullPath.includes(\"[\")) {\n return message;\n }\n\n // Replace the field name at the start of the message with the full path\n // Handle cases like \"id must be a UUID\" -> \"'user.id' must be a UUID\"\n const regex = new RegExp(`^${fieldName}\\\\b`, \"i\");\n if (regex.test(message)) {\n return message.replace(regex, `'${fullPath}'`);\n }\n\n // If field name is not at the start, try to find it and replace\n // This handles cases like \"must be a valid id\" or other formats\n const wordBoundaryRegex = new RegExp(`\\\\b${fieldName}\\\\b`, \"gi\");\n if (wordBoundaryRegex.test(message)) {\n return message.replace(wordBoundaryRegex, `'${fullPath}'`);\n }\n\n // If we can't find the field name in the message, prepend the path\n return `'${fullPath}' ${message}`;\n }\n\n /**\n * Prettifies class-validator ValidationError array.\n * Handles nested validation errors recursively.\n *\n * @param errors - Array of ValidationError from class-validator\n * @param parentPath - Parent path for nested errors (used internally)\n * @returns Array of prettified errors\n */\n private prettifyClassValidator(\n errors: ValidationError[],\n parentPath: string = \"\"\n ): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const error of errors) {\n const currentPath = parentPath\n ? `${parentPath}.${error.property}`\n : error.property;\n\n if (error.children && error.children.length > 0) {\n result.push(\n ...this.prettifyClassValidator(error.children, currentPath)\n );\n continue;\n }\n\n if (error.constraints) {\n const fieldPascal = this.toPascalCase(currentPath);\n\n for (const [constraintKey, originalMessage] of Object.entries(\n error.constraints\n )) {\n const constraintName =\n constraintKey.charAt(0).toUpperCase() + constraintKey.slice(1);\n\n const message = this.replaceFieldInMessage(\n originalMessage,\n error.property,\n currentPath\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}Constraint`,\n });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Maps Zod error codes and validation info to class-validator style constraint names.\n *\n * @param issue - Zod validation issue\n * @returns Class-validator style constraint name\n */\n private mapZodToConstraintName(issue: z.core.$ZodIssue): string {\n switch (issue.code) {\n case \"invalid_type\":\n const expected = issue.expected;\n switch (expected) {\n case \"string\":\n return \"IsStringConstraint\";\n case \"email\":\n return \"IsEmailConstraint\";\n case \"uuid\":\n return \"IsUuidConstraint\";\n case \"url\":\n return \"IsUrlConstraint\";\n case \"number\":\n return \"IsNumberConstraint\";\n case \"boolean\":\n return \"IsBooleanConstraint\";\n case \"array\":\n return \"IsArrayConstraint\";\n case \"object\":\n return \"IsObjectConstraint\";\n case \"date\":\n return \"IsDateConstraint\";\n default:\n if (typeof expected === \"object\" && \"includes\" in expected)\n return \"ContainsConstraint\";\n if (typeof expected === \"object\" && \"startsWith\" in expected)\n return \"StartsWithConstraint\";\n if (typeof expected === \"object\" && \"endsWith\" in expected)\n return \"EndsWithConstraint\";\n return \"InvalidTypeConstraint\";\n }\n\n case \"too_small\":\n if (issue.origin === \"string\") {\n return \"MinLengthConstraint\";\n } else if (issue.origin === \"number\") {\n return \"MinConstraint\";\n } else if (issue.origin === \"array\") {\n return \"ArrayMinSizeConstraint\";\n }\n return \"TooSmallConstraint\";\n\n case \"too_big\":\n if (issue.origin === \"string\") {\n return \"MaxLengthConstraint\";\n } else if (issue.origin === \"number\") {\n return \"MaxConstraint\";\n } else if (issue.origin === \"array\") {\n return \"ArrayMaxSizeConstraint\";\n }\n return \"TooBigConstraint\";\n\n case \"invalid_format\":\n return this.mapZodFormatToConstraintName((issue as any).format);\n\n case \"invalid_value\":\n if (issue.values.length > 1) {\n return \"IsEnumConstraint\";\n } else {\n return \"EqualsConstraint\";\n }\n\n // case \"invalid_enum_value\":\n // return \"IsEnumConstraint\";\n\n // case \"invalid_literal\":\n // return \"EqualsConstraint\";\n\n case \"unrecognized_keys\":\n return \"UnrecognizedKeysConstraint\";\n\n case \"invalid_union\":\n return \"InvalidUnionConstraint\";\n\n case \"custom\":\n return \"CustomConstraint\";\n\n default:\n return \"ValidationConstraint\";\n }\n }\n\n /**\n * Maps a Zod `invalid_format` format (e.g. \"email\", \"uuid\", \"regex\") to a\n * class-validator style constraint name.\n *\n * @param format - The format reported by Zod\n * @returns Class-validator style constraint name\n */\n private mapZodFormatToConstraintName(format?: string): string {\n switch (format) {\n case \"email\":\n return \"IsEmailConstraint\";\n case \"uuid\":\n case \"guid\":\n return \"IsUuidConstraint\";\n case \"url\":\n return \"IsUrlConstraint\";\n case \"emoji\":\n return \"IsEmojiConstraint\";\n case \"datetime\":\n case \"date\":\n case \"time\":\n case \"duration\":\n return \"IsDateStringConstraint\";\n case \"ipv4\":\n case \"ipv6\":\n case \"cidrv4\":\n case \"cidrv6\":\n return \"IsIPConstraint\";\n case \"base64\":\n case \"base64url\":\n return \"IsBase64Constraint\";\n case \"json_string\":\n return \"IsJSONConstraint\";\n case \"e164\":\n return \"IsPhoneNumberConstraint\";\n case \"jwt\":\n return \"IsJWTConstraint\";\n case \"regex\":\n return \"MatchesConstraint\";\n case \"starts_with\":\n return \"StartsWithConstraint\";\n case \"ends_with\":\n return \"EndsWithConstraint\";\n case \"includes\":\n return \"ContainsConstraint\";\n case \"lowercase\":\n return \"IsLowercaseConstraint\";\n case \"uppercase\":\n return \"IsUppercaseConstraint\";\n case \"nanoid\":\n case \"cuid\":\n case \"cuid2\":\n case \"ulid\":\n case \"xid\":\n case \"ksuid\":\n case \"template_literal\":\n return \"IsStringConstraint\";\n default:\n return \"InvalidFormatConstraint\";\n }\n }\n\n /**\n * Prettifies Zod ZodError.\n * Handles nested paths and multiple issues per field.\n *\n * @param error - ZodError from Zod validation\n * @returns Array of prettified errors\n */\n private prettifyZod(error: ZodError): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const issue of error.issues) {\n // Build the field path from the issue path\n const fieldPath = issue.path\n .map((segment, index) => {\n // Handle array indices: convert to bracket notation\n if (typeof segment === \"number\") {\n return `[${segment}]`;\n }\n // First segment doesn't need a dot prefix\n return index === 0 ? segment : `.${String(segment)}`;\n })\n .join(\"\")\n .replace(/\\.\\[/g, \"[\"); // Clean up .[ to just [\n\n const fieldPascal = fieldPath\n ? this.toPascalCase(fieldPath.replace(/\\[\\d+\\]/g, \"\"))\n : \"\";\n\n // Map Zod error code to constraint name\n const constraintName = this.mapZodToConstraintName(issue);\n\n // Inject the field path into the message naturally\n const message = this.injectFieldPathInZodMessage(\n issue.message,\n fieldPath,\n issue\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}`,\n });\n }\n\n return result;\n }\n\n /**\n * Injects the field path into Zod error messages naturally.\n *\n * @example\n * ```typescript\n * injectFieldPathInZodMessage('String must contain at least 100 character(s)', 'user.id', issue)\n * // Returns: ''user.id' must contain at least 100 character(s)'\n *\n * injectFieldPathInZodMessage('Required', 'email', issue)\n * // Returns: ''email' is required'\n * ```\n *\n * @param message - Original Zod error message\n * @param fieldPath - Full field path (e.g., 'user.id', 'tags[0].name')\n * @param issue - Zod issue for context\n * @returns Message with field path injected naturally\n */\n private injectFieldPathInZodMessage(\n message: string,\n fieldPath: string,\n _: z.core.$ZodIssue\n ): string {\n if (!fieldPath) {\n return message;\n }\n\n // \"Required\" -> \"'fieldPath' is required\"\n if (message === \"Required\") {\n return `'${fieldPath}' is required`;\n }\n\n // \"String must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"String must\")) {\n return message.replace(/^String must/, `'${fieldPath}' must`);\n }\n\n // \"Number must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Number must\")) {\n return message.replace(/^Number must/, `'${fieldPath}' must`);\n }\n\n // \"Array must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Array must\")) {\n return message.replace(/^Array must/, `'${fieldPath}' must`);\n }\n\n // \"Expected string, received number\" -> \"'fieldPath': Expected string, received number\"\n if (message.startsWith(\"Expected\")) {\n return `'${fieldPath}' must be valid: ${message}`;\n }\n\n if (message.startsWith(\"Invalid input:\")) {\n const detail = message.replace(/^Invalid input:\\s*/, \"\");\n return `'${fieldPath}' must be valid: ${detail}`;\n }\n\n if (message.startsWith(\"Too small:\") || message.startsWith(\"Too big:\")) {\n const detail = message.charAt(0).toLowerCase() + message.slice(1);\n return `'${fieldPath}' ${detail}`;\n }\n\n // \"Invalid email\" -> \"'fieldPath' must be a valid email\"\n if (message.startsWith(\"Invalid \")) {\n const type = message.replace(\"Invalid \", \"\");\n return `'${fieldPath}' must be a valid ${type}`;\n }\n\n // For any other message, return the message\n if (!message.toLowerCase().includes(fieldPath))\n return `'${fieldPath}' ${message}`;\n return message;\n }\n}\n\nconst errorPrettifier = new ErrorPrettifier();\n\nexport default errorPrettifier;\n\n"]}
@@ -1,5 +1,16 @@
1
1
  import { pascalCase } from "../../../utils/helpers/change-case.helpers.js";
2
2
  import AppError from "./app-error.js";
3
+ function getDriverAdapterCause(err) {
4
+ if (err?.name === "DriverAdapterError")
5
+ return err?.cause ?? null;
6
+ return err?.meta?.driverAdapterError?.cause ?? null;
7
+ }
8
+ function resolveConstraint(err) {
9
+ const constraint = getDriverAdapterCause(err)?.constraint;
10
+ if (!constraint)
11
+ return undefined;
12
+ return constraint.fields ?? constraint.index;
13
+ }
3
14
  export function handleJWTError() {
4
15
  return new AppError("Invalid token. Please log in again!", 401);
5
16
  }
@@ -28,7 +39,11 @@ export function handleDatabaseNotFoundError(_) {
28
39
  return new AppError(message, 404);
29
40
  }
30
41
  export function handleFieldValueTooLargeError(err) {
31
- const message = `The value for the field "${err?.meta?.field_name}" is too large. Please provide a smaller value.`;
42
+ const fieldName = err?.meta?.field_name;
43
+ const field = fieldName !== undefined
44
+ ? fieldName
45
+ : getDriverAdapterCause(err)?.column;
46
+ const message = `The value for the field "${field}" is too large. Please provide a smaller value.`;
32
47
  return new AppError(message, 400);
33
48
  }
34
49
  export function handleRecordNotFoundError(_) {
@@ -36,7 +51,7 @@ export function handleRecordNotFoundError(_) {
36
51
  return new AppError(message, 404);
37
52
  }
38
53
  export function handleUniqueConstraintError(err) {
39
- const field = err?.meta?.target || "unknown";
54
+ const field = err?.meta?.target || resolveConstraint(err) || "unknown";
40
55
  const message = `Duplicate unique field(s) ${Array.isArray(field) ? field.map((f) => `'${f}'`).join(", ") : `'${field}'`}`;
41
56
  return new AppError(message, 409, "DuplicateRecords");
42
57
  }
@@ -45,7 +60,7 @@ export function handleForeignKeyConstraintError(_) {
45
60
  return new AppError(message, 409, "ForeignKeyViolation");
46
61
  }
47
62
  export function handleConstraintFailedError(err) {
48
- const constraint = err?.meta?.constraint || "unknown constraint";
63
+ const constraint = err?.meta?.constraint || resolveConstraint(err) || "unknown constraint";
49
64
  const message = `A database constraint "${constraint}" failed. Please review your input data.`;
50
65
  return new AppError(message, 400);
51
66
  }
@@ -68,13 +83,42 @@ export function handleVersionMismatchError(_) {
68
83
  return new AppError(message, 400);
69
84
  }
70
85
  export function handleNonExistingRecord(err) {
71
- const message = err?.meta?.cause ||
72
- `Operation could not be completed as some required record was not found`;
73
- const model = err?.meta?.cause
74
- ? err?.meta?.cause?.split("No '")?.[1]?.split?.("'")?.[0]
75
- : "";
86
+ const cause = err?.meta?.cause;
87
+ const model = (cause ? cause.split("No '")?.[1]?.split?.("'")?.[0] : "") ||
88
+ err?.meta?.model ||
89
+ "";
90
+ const message = cause ||
91
+ (model
92
+ ? `No '${model}' record was found for the requested operation`
93
+ : `Operation could not be completed as some required record was not found`);
76
94
  return new AppError(message, model ? 400 : 404, `${model ? "Inline" : ""}${pascalCase(model || "")}RecordNotFound`);
77
95
  }
96
+ export function handleDriverAdapterError(err) {
97
+ const kind = getDriverAdapterCause(err)?.kind;
98
+ switch (kind) {
99
+ case "UniqueConstraintViolation":
100
+ return handleUniqueConstraintError(err);
101
+ case "ForeignKeyConstraintViolation":
102
+ case "RestrictViolation":
103
+ return handleForeignKeyConstraintError(err);
104
+ case "NullConstraintViolation":
105
+ return handleConstraintFailedError(err);
106
+ case "LengthMismatch":
107
+ return handleFieldValueTooLargeError(err);
108
+ case "AuthenticationFailed":
109
+ return handleAuthenticationError(err);
110
+ case "DatabaseNotReachable":
111
+ return handleServerNotReachableError(err);
112
+ case "DatabaseDoesNotExist":
113
+ return handleDatabaseNotFoundError(err);
114
+ case "SocketTimeout":
115
+ return handleConnectionTimeoutError(err);
116
+ case "TransactionWriteConflict":
117
+ return new AppError("The transaction failed due to a write conflict or a deadlock. Please retry.", 409);
118
+ default:
119
+ return null;
120
+ }
121
+ }
78
122
  export function handlePrismaClientInitializationError(_) {
79
123
  return new AppError("Service temporarily unavailable", 503, "ServiceUnavailable", {});
80
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.helpers.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/error-handler.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { pascalCase } from \"../../../utils/helpers/change-case.helpers\";\nimport AppError from \"./app-error\";\n\nexport function handleJWTError() {\n return new AppError(\"Invalid token. Please log in again!\", 401);\n}\n\nexport function handleJWTExpired() {\n return new AppError(\"Your token has expired, Please log again!\", 401);\n}\n\nexport function handlePrismaClientValidationError(err: AppError) {\n const message =\n err?.message?.split(\"\\n\")[err?.message?.split(\"\\n\").length - 1] ||\n \"Invalid query arguments\";\n return new AppError(\n message.split(\". Did you\")[0],\n 400,\n \"InvalidQueryArgument\"\n );\n}\n\nexport function handleAuthenticationError(_: AppError) {\n const message =\n \"Authentication failed against the database server. Please check your credentials.\";\n return new AppError(message, 401);\n}\n\nexport function handleServerNotReachableError(_: AppError) {\n const message =\n \"The database server is not reachable. Verify your connection string or ensure the server is online.\";\n return new AppError(message, 503);\n}\n\nexport function handleConnectionTimeoutError(_: AppError) {\n const message =\n \"Connection to the database timed out. Please check server performance or network connectivity.\";\n return new AppError(message, 504);\n}\n\nexport function handleDatabaseNotFoundError(_: AppError) {\n const message = \"The specified database does not exist on the server.\";\n return new AppError(message, 404);\n}\n\nexport function handleFieldValueTooLargeError(err: AppError) {\n const message = `The value for the field \"${err?.meta?.field_name}\" is too large. Please provide a smaller value.`;\n return new AppError(message, 400);\n}\n\nexport function handleRecordNotFoundError(_: AppError) {\n const message =\n \"No record found for the given query. Ensure the query parameters are correct.\";\n return new AppError(message, 404);\n}\n\nexport function handleUniqueConstraintError(err: any) {\n const field = err?.meta?.target || \"unknown\";\n const message = `Duplicate unique field(s) ${Array.isArray(field) ? field.map((f) => `'${f}'`).join(\", \") : `'${field}'`}`;\n return new AppError(message, 409, \"DuplicateRecords\");\n}\n\nexport function handleForeignKeyConstraintError(_: AppError) {\n const message =\n \"Foreign key constraint violation. Ensure that the referenced record exists.\";\n return new AppError(message, 409, \"ForeignKeyViolation\");\n}\n\nexport function handleConstraintFailedError(err: AppError) {\n const constraint = err?.meta?.constraint || \"unknown constraint\";\n const message = `A database constraint \"${constraint}\" failed. Please review your input data.`;\n return new AppError(message, 400);\n}\n\nexport function handleSchemaCreationFailedError(_: AppError) {\n const message =\n \"Failed to create the database schema. Verify the schema definition and try again.\";\n return new AppError(message, 500);\n}\n\nexport function handleMigrationAlreadyAppliedError(err: AppError) {\n const migrationName = err?.meta?.migration || \"unknown migration\";\n const message = `The migration \"${migrationName}\" has already been applied to the database.`;\n return new AppError(message, 409);\n}\n\nexport function handleMigrationScriptFailedError(err: AppError) {\n const migrationName = err?.meta?.migration || \"unknown migration\";\n const message = `The migration script \"${migrationName}\" failed. Review the script and resolve any issues.`;\n return new AppError(message, 500);\n}\n\nexport function handleVersionMismatchError(_: AppError) {\n const message = `Version mismatch: The database schema and migration versions are inconsistent. Please check and resolve this issue.`;\n return new AppError(message, 400);\n}\n\nexport function handleNonExistingRecord(err: {\n meta?: Record<string, any>;\n [x: string]: any;\n}) {\n const message =\n err?.meta?.cause ||\n `Operation could not be completed as some required record was not found`;\n\n const model = err?.meta?.cause\n ? err?.meta?.cause?.split(\"No '\")?.[1]?.split?.(\"'\")?.[0]\n : \"\";\n\n return new AppError(\n message,\n model ? 400 : 404,\n `${model ? \"Inline\" : \"\"}${pascalCase(model || \"\")}RecordNotFound`\n );\n}\n\nexport function handlePrismaClientInitializationError(_: any) {\n return new AppError(\n \"Service temporarily unavailable\",\n 503,\n \"ServiceUnavailable\",\n {}\n );\n}\n"]}
1
+ {"version":3,"file":"error-handler.helpers.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/error-handler.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { pascalCase } from \"../../../utils/helpers/change-case.helpers\";\nimport AppError from \"./app-error\";\n\nfunction getDriverAdapterCause(err: any): Record<string, any> | null {\n if (err?.name === \"DriverAdapterError\") return err?.cause ?? null;\n return err?.meta?.driverAdapterError?.cause ?? null;\n}\n\nfunction resolveConstraint(err: any): string | string[] | undefined {\n const constraint = getDriverAdapterCause(err)?.constraint;\n\n if (!constraint) return undefined;\n\n return constraint.fields ?? constraint.index;\n}\n\nexport function handleJWTError() {\n return new AppError(\"Invalid token. Please log in again!\", 401);\n}\n\nexport function handleJWTExpired() {\n return new AppError(\"Your token has expired, Please log again!\", 401);\n}\n\nexport function handlePrismaClientValidationError(err: AppError) {\n const message =\n err?.message?.split(\"\\n\")[err?.message?.split(\"\\n\").length - 1] ||\n \"Invalid query arguments\";\n return new AppError(\n message.split(\". Did you\")[0],\n 400,\n \"InvalidQueryArgument\"\n );\n}\n\nexport function handleAuthenticationError(_: AppError) {\n const message =\n \"Authentication failed against the database server. Please check your credentials.\";\n return new AppError(message, 401);\n}\n\nexport function handleServerNotReachableError(_: AppError) {\n const message =\n \"The database server is not reachable. Verify your connection string or ensure the server is online.\";\n return new AppError(message, 503);\n}\n\nexport function handleConnectionTimeoutError(_: AppError) {\n const message =\n \"Connection to the database timed out. Please check server performance or network connectivity.\";\n return new AppError(message, 504);\n}\n\nexport function handleDatabaseNotFoundError(_: AppError) {\n const message = \"The specified database does not exist on the server.\";\n return new AppError(message, 404);\n}\n\nexport function handleFieldValueTooLargeError(err: AppError) {\n const fieldName = (err?.meta as any)?.field_name;\n const field =\n fieldName !== undefined\n ? fieldName\n : getDriverAdapterCause(err)?.column;\n const message = `The value for the field \"${field}\" is too large. Please provide a smaller value.`;\n return new AppError(message, 400);\n}\n\nexport function handleRecordNotFoundError(_: AppError) {\n const message =\n \"No record found for the given query. Ensure the query parameters are correct.\";\n return new AppError(message, 404);\n}\n\nexport function handleUniqueConstraintError(err: any) {\n const field =\n err?.meta?.target || resolveConstraint(err) || \"unknown\";\n const message = `Duplicate unique field(s) ${Array.isArray(field) ? field.map((f) => `'${f}'`).join(\", \") : `'${field}'`}`;\n return new AppError(message, 409, \"DuplicateRecords\");\n}\n\nexport function handleForeignKeyConstraintError(_: AppError) {\n const message =\n \"Foreign key constraint violation. Ensure that the referenced record exists.\";\n return new AppError(message, 409, \"ForeignKeyViolation\");\n}\n\nexport function handleConstraintFailedError(err: AppError) {\n const constraint =\n err?.meta?.constraint || resolveConstraint(err) || \"unknown constraint\";\n const message = `A database constraint \"${constraint}\" failed. Please review your input data.`;\n return new AppError(message, 400);\n}\n\nexport function handleSchemaCreationFailedError(_: AppError) {\n const message =\n \"Failed to create the database schema. Verify the schema definition and try again.\";\n return new AppError(message, 500);\n}\n\nexport function handleMigrationAlreadyAppliedError(err: AppError) {\n const migrationName = err?.meta?.migration || \"unknown migration\";\n const message = `The migration \"${migrationName}\" has already been applied to the database.`;\n return new AppError(message, 409);\n}\n\nexport function handleMigrationScriptFailedError(err: AppError) {\n const migrationName = err?.meta?.migration || \"unknown migration\";\n const message = `The migration script \"${migrationName}\" failed. Review the script and resolve any issues.`;\n return new AppError(message, 500);\n}\n\nexport function handleVersionMismatchError(_: AppError) {\n const message = `Version mismatch: The database schema and migration versions are inconsistent. Please check and resolve this issue.`;\n return new AppError(message, 400);\n}\n\nexport function handleNonExistingRecord(err: {\n meta?: Record<string, any>;\n [x: string]: any;\n}) {\n const cause = err?.meta?.cause;\n\n const model =\n (cause ? cause.split(\"No '\")?.[1]?.split?.(\"'\")?.[0] : \"\") ||\n err?.meta?.model ||\n \"\";\n\n const message =\n cause ||\n (model\n ? `No '${model}' record was found for the requested operation`\n : `Operation could not be completed as some required record was not found`);\n\n return new AppError(\n message,\n model ? 400 : 404,\n `${model ? \"Inline\" : \"\"}${pascalCase(model || \"\")}RecordNotFound`\n );\n}\n\nexport function handleDriverAdapterError(err: any): AppError | null {\n const kind = getDriverAdapterCause(err)?.kind;\n\n switch (kind) {\n case \"UniqueConstraintViolation\":\n return handleUniqueConstraintError(err);\n case \"ForeignKeyConstraintViolation\":\n case \"RestrictViolation\":\n return handleForeignKeyConstraintError(err);\n case \"NullConstraintViolation\":\n return handleConstraintFailedError(err);\n case \"LengthMismatch\":\n return handleFieldValueTooLargeError(err);\n case \"AuthenticationFailed\":\n return handleAuthenticationError(err);\n case \"DatabaseNotReachable\":\n return handleServerNotReachableError(err);\n case \"DatabaseDoesNotExist\":\n return handleDatabaseNotFoundError(err);\n case \"SocketTimeout\":\n return handleConnectionTimeoutError(err);\n case \"TransactionWriteConflict\":\n return new AppError(\n \"The transaction failed due to a write conflict or a deadlock. Please retry.\",\n 409\n );\n default:\n return null;\n }\n}\n\nexport function handlePrismaClientInitializationError(_: any) {\n return new AppError(\n \"Service temporarily unavailable\",\n 503,\n \"ServiceUnavailable\",\n {}\n );\n}\n"]}
@@ -63,6 +63,11 @@ export function getHandledError(err) {
63
63
  error = errorControllerHelper.handleVersionMismatchError(err);
64
64
  break;
65
65
  }
66
+ if (error === err) {
67
+ const adapterError = errorControllerHelper.handleDriverAdapterError(err);
68
+ if (adapterError)
69
+ error = adapterError;
70
+ }
66
71
  return error;
67
72
  }
68
73
  //# sourceMappingURL=get-handled-error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-handled-error.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/get-handled-error.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AAExE,MAAM,UAAU,eAAe,CAAC,GAAQ;IACtC,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,mBAAmB;YACtB,KAAK,GAAG,qBAAqB,CAAC,cAAc,EAAE,CAAC;YAC/C,MAAM;QACR,KAAK,mBAAmB;YACtB,KAAK,GAAG,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;YACjD,MAAM;QACR,KAAK,6BAA6B;YAChC,KAAK,GAAG,qBAAqB,CAAC,iCAAiC,CAAC,GAAG,CAAC,CAAC;YACrE,MAAM;QACR,KAAK,iCAAiC;YACpC,KAAK,GAAG,qBAAqB,CAAC,qCAAqC,CAAC,GAAG,CAAC,CAAC;YACzE,MAAM;QACR,KAAK,aAAa;YAChB,KAAK,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAA6B,CAAC,CAAC;YACjE,MAAM;IACV,CAAC;IAED,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;YAC3D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,kCAAkC,CAAC,GAAG,CAAC,CAAC;YACtE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,gCAAgC,CAAC,GAAG,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAC9D,MAAM;IACV,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { MulterError } from \"multer\";\nimport multerErrorHandler from \"../utils/multer-error-handler\";\nimport * as errorControllerHelper from \"../utils/error-handler.helpers\";\n\nexport function getHandledError(err: any): any {\n let error = err;\n\n switch (err.name) {\n case \"JsonWebTokenError\":\n error = errorControllerHelper.handleJWTError();\n break;\n case \"TokenExpiredError\":\n error = errorControllerHelper.handleJWTExpired();\n break;\n case \"PrismaClientValidationError\":\n error = errorControllerHelper.handlePrismaClientValidationError(err);\n break;\n case \"PrismaClientInitializationError\":\n error = errorControllerHelper.handlePrismaClientInitializationError(err);\n break;\n case \"MulterError\":\n error = multerErrorHandler.handle(err as unknown as MulterError);\n break;\n }\n\n switch (err.code) {\n case \"P1000\":\n error = errorControllerHelper.handleAuthenticationError(err);\n break;\n case \"P1001\":\n error = errorControllerHelper.handleServerNotReachableError(err);\n break;\n case \"P1002\":\n error = errorControllerHelper.handleConnectionTimeoutError(err);\n break;\n case \"P1003\":\n error = errorControllerHelper.handleDatabaseNotFoundError(err);\n break;\n case \"P2000\":\n error = errorControllerHelper.handleFieldValueTooLargeError(err);\n break;\n case \"P2001\":\n error = errorControllerHelper.handleRecordNotFoundError(err);\n break;\n case \"P2002\":\n error = errorControllerHelper.handleUniqueConstraintError(err);\n break;\n case \"P2003\":\n error = errorControllerHelper.handleForeignKeyConstraintError(err);\n break;\n case \"P2004\":\n error = errorControllerHelper.handleConstraintFailedError(err);\n break;\n case \"P2025\":\n error = errorControllerHelper.handleNonExistingRecord(err);\n break;\n case \"P3000\":\n error = errorControllerHelper.handleSchemaCreationFailedError(err);\n break;\n case \"P3001\":\n error = errorControllerHelper.handleMigrationAlreadyAppliedError(err);\n break;\n case \"P3002\":\n error = errorControllerHelper.handleMigrationScriptFailedError(err);\n break;\n case \"P3003\":\n error = errorControllerHelper.handleVersionMismatchError(err);\n break;\n }\n\n return error;\n}\n"]}
1
+ {"version":3,"file":"get-handled-error.js","sourceRoot":"","sources":["../../../../../src/modules/error-handler/utils/get-handled-error.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AAExE,MAAM,UAAU,eAAe,CAAC,GAAQ;IACtC,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,mBAAmB;YACtB,KAAK,GAAG,qBAAqB,CAAC,cAAc,EAAE,CAAC;YAC/C,MAAM;QACR,KAAK,mBAAmB;YACtB,KAAK,GAAG,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;YACjD,MAAM;QACR,KAAK,6BAA6B;YAChC,KAAK,GAAG,qBAAqB,CAAC,iCAAiC,CAAC,GAAG,CAAC,CAAC;YACrE,MAAM;QACR,KAAK,iCAAiC;YACpC,KAAK,GAAG,qBAAqB,CAAC,qCAAqC,CAAC,GAAG,CAAC,CAAC;YACzE,MAAM;QACR,KAAK,aAAa;YAChB,KAAK,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAA6B,CAAC,CAAC;YACjE,MAAM;IACV,CAAC;IAED,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;YAC3D,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,kCAAkC,CAAC,GAAG,CAAC,CAAC;YACtE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,gCAAgC,CAAC,GAAG,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,GAAG,qBAAqB,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;YAC9D,MAAM;IACV,CAAC;IAED,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAClB,MAAM,YAAY,GAAG,qBAAqB,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACzE,IAAI,YAAY;YAAE,KAAK,GAAG,YAAY,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { MulterError } from \"multer\";\nimport multerErrorHandler from \"../utils/multer-error-handler\";\nimport * as errorControllerHelper from \"../utils/error-handler.helpers\";\n\nexport function getHandledError(err: any): any {\n let error = err;\n\n switch (err.name) {\n case \"JsonWebTokenError\":\n error = errorControllerHelper.handleJWTError();\n break;\n case \"TokenExpiredError\":\n error = errorControllerHelper.handleJWTExpired();\n break;\n case \"PrismaClientValidationError\":\n error = errorControllerHelper.handlePrismaClientValidationError(err);\n break;\n case \"PrismaClientInitializationError\":\n error = errorControllerHelper.handlePrismaClientInitializationError(err);\n break;\n case \"MulterError\":\n error = multerErrorHandler.handle(err as unknown as MulterError);\n break;\n }\n\n switch (err.code) {\n case \"P1000\":\n error = errorControllerHelper.handleAuthenticationError(err);\n break;\n case \"P1001\":\n error = errorControllerHelper.handleServerNotReachableError(err);\n break;\n case \"P1002\":\n error = errorControllerHelper.handleConnectionTimeoutError(err);\n break;\n case \"P1003\":\n error = errorControllerHelper.handleDatabaseNotFoundError(err);\n break;\n case \"P2000\":\n error = errorControllerHelper.handleFieldValueTooLargeError(err);\n break;\n case \"P2001\":\n error = errorControllerHelper.handleRecordNotFoundError(err);\n break;\n case \"P2002\":\n error = errorControllerHelper.handleUniqueConstraintError(err);\n break;\n case \"P2003\":\n error = errorControllerHelper.handleForeignKeyConstraintError(err);\n break;\n case \"P2004\":\n error = errorControllerHelper.handleConstraintFailedError(err);\n break;\n case \"P2025\":\n error = errorControllerHelper.handleNonExistingRecord(err);\n break;\n case \"P3000\":\n error = errorControllerHelper.handleSchemaCreationFailedError(err);\n break;\n case \"P3001\":\n error = errorControllerHelper.handleMigrationAlreadyAppliedError(err);\n break;\n case \"P3002\":\n error = errorControllerHelper.handleMigrationScriptFailedError(err);\n break;\n case \"P3003\":\n error = errorControllerHelper.handleVersionMismatchError(err);\n break;\n }\n\n if (error === err) {\n const adapterError = errorControllerHelper.handleDriverAdapterError(err);\n if (adapterError) error = adapterError;\n }\n\n return error;\n}\n"]}
@@ -4,7 +4,7 @@ import path from "path";
4
4
  import fs from "fs";
5
5
  import catchAsync from "../error-handler/utils/catch-async.js";
6
6
  import { getArkosConfig } from "../../server.js";
7
- import { processFile, processImage } from "./utils/helpers/file-upload.helpers.js";
7
+ import { processFile, processImage, } from "./utils/helpers/file-upload.helpers.js";
8
8
  import loadableRegistry from "../../components/arkos-loadable-registry/index.js";
9
9
  import { routeHookReader } from "../../components/arkos-route-hook/reader.js";
10
10
  function matchesUploadUrl(originalUrl, baseUploadRoute, fileType, fileName) {
@@ -24,8 +24,14 @@ export class FileUploadController {
24
24
  }
25
25
  uploadFile = catchAsync(async (req, res, next) => {
26
26
  const { fileType } = req.params;
27
- const { format, width, height, resizeTo } = req.query;
28
- const options = { format, width, height, resizeTo };
27
+ const { format, width, height, resizeTo, quality } = req.query;
28
+ const options = {
29
+ format,
30
+ width,
31
+ height,
32
+ resizeTo,
33
+ quality,
34
+ };
29
35
  const { documentUploadService, fileUploadService, imageUploadService, videoUploadService, } = getFileUploadServices();
30
36
  const { fileUpload } = getArkosConfig();
31
37
  const baseUploadDir = fileUpload?.baseUploadDir || "/uploads";
@@ -98,7 +104,10 @@ export class FileUploadController {
98
104
  });
99
105
  });
100
106
  deleteFile = catchAsync(async (req, res, next) => {
101
- const { fileType, fileName } = req.params;
107
+ const { fileType } = req.params;
108
+ const fileName = Array.isArray(req.params.fileName)
109
+ ? req.params.fileName.join("/")
110
+ : req.params.fileName;
102
111
  const { documentUploadService, fileUploadService, imageUploadService, videoUploadService, } = getFileUploadServices();
103
112
  let uploader;
104
113
  switch (fileType) {
@@ -144,9 +153,18 @@ export class FileUploadController {
144
153
  }
145
154
  });
146
155
  updateFile = catchAsync(async (req, res, next) => {
147
- const { fileType, fileName } = req.params;
148
- const { format, width, height, resizeTo } = req.query;
149
- const options = { format, width, height, resizeTo };
156
+ const { fileType } = req.params;
157
+ const fileName = Array.isArray(req.params.fileName)
158
+ ? req.params.fileName.join("/")
159
+ : req.params.fileName;
160
+ const { format, width, height, resizeTo, quality } = req.query;
161
+ const options = {
162
+ format,
163
+ width,
164
+ height,
165
+ resizeTo,
166
+ quality,
167
+ };
150
168
  const { documentUploadService, fileUploadService, imageUploadService, videoUploadService, } = getFileUploadServices();
151
169
  const { fileUpload } = getArkosConfig();
152
170
  const baseUploadDir = fileUpload?.baseUploadDir || "/uploads";