{"version":3,"file":"odata_error_middleware-BQ2zELv3.cjs","sources":["../src/private/odata_macro/utils/http.ts","../src/private/odata_macro/middlewares/odata_error_middleware.ts"],"sourcesContent":["import type { HttpContext } from '@adonisjs/core/http'\n\nexport const ODataResponseFormat = ['xml' as 'xml', 'json' as 'json']\nexport type ODataResponseFormat = (typeof ODataResponseFormat)[number]\n\nexport const negotiateContent = (\n  ctx: HttpContext,\n  fallback: ODataResponseFormat = 'json'\n): ODataResponseFormat => {\n  for (const acceptable of ODataResponseFormat) {\n    const query = ctx.request.qs()\n    if ('string' === typeof query['$format'] && query['$format'].includes(acceptable)) {\n      return acceptable\n    }\n    if (ctx.request.header('accept')?.includes(acceptable)) {\n      return acceptable\n    }\n  }\n  return fallback\n}\n\nexport const ODataMetadataLevel = ['full' as 'full', 'minimal' as 'minimal', 'none' as 'none']\nexport type ODataMetadataLevel = (typeof ODataMetadataLevel)[number]\n\nexport const negotiateMetadata = (\n  ctx: HttpContext,\n  fallback: ODataMetadataLevel = 'minimal'\n): ODataMetadataLevel => {\n  for (const acceptable of ODataMetadataLevel) {\n    const query = ctx.request.qs()\n    if (\n      'string' === typeof query['$format'] &&\n      query['$format'].includes(`metadata=${acceptable}`)\n    ) {\n      return acceptable\n    }\n    if (ctx.request.header('accept')?.includes(`metadata=${acceptable}`)) {\n      return acceptable\n    }\n  }\n  return fallback\n}\n\nexport const ODataPreference = ['representation' as 'representation', 'minimal' as 'minimal']\nexport type ODataPreference = (typeof ODataPreference)[number]\n\nexport const negotiatePreference = (\n  ctx: HttpContext,\n  fallback: ODataPreference = 'representation'\n): ODataPreference => {\n  const prefer = ctx.request.header('prefer')\n  if (prefer) {\n    for (const acceptable of ODataPreference) {\n      if (prefer.includes(acceptable)) {\n        return acceptable\n      }\n    }\n  }\n  return fallback\n}\n\nconst IEEE754_COMPATIBLE_TRUE = /ieee754compatible\\s*=\\s*true/i\nconst IEEE754_COMPATIBLE_FALSE = /ieee754compatible\\s*=\\s*false/i\n\n/**\n * Negotiates the OData JSON `IEEE754Compatible` format parameter for a request.\n *\n * Per OData JSON §3.2, when `IEEE754Compatible=true` is negotiated, `Edm.Int64`\n * and `Edm.Decimal` values MUST be serialized as JSON strings (to preserve\n * precision in JavaScript / Power BI / Excel); when `false`, they are\n * serialized as JSON numbers. The server MUST NOT advertise a parameter it\n * does not actually conform to — mismatching the advertised parameter and the\n * actual payload is what triggers the Power BI\n * `DataSource.Error: Cannot convert a value to target type 'Edm.Int64' because\n * of conflict between input format string/number and parameter\n * 'IEEE754Compatible' false/true`.\n *\n * The fallback defaults to `false` (the OData spec default when the client\n * omits the parameter). Power BI and other OData clients that do not\n * explicitly request `IEEE754Compatible=true` reject unsolicited `=true`\n * responses — they expect JSON numbers for `Edm.Int64` / `Edm.Decimal` and\n * choke on strings they did not ask for. The controller's reverse-coercion\n * helper (`coerceIeee754NumericValues`) converts node-postgres `bigint` /\n * `numeric` string values back to JSON numbers when `=false`, so the wire\n * format stays consistent with the advertised parameter. Clients that\n * explicitly request `=true` via `Accept` / `$format` still get string\n * serialization.\n */\nexport const negotiateIeee754Compatible = (\n  ctx: HttpContext,\n  fallback: boolean = false\n): boolean => {\n  const query = ctx.request.qs()\n  const format = typeof query['$format'] === 'string' ? query['$format'] : ''\n  if (IEEE754_COMPATIBLE_TRUE.test(format)) return true\n  if (IEEE754_COMPATIBLE_FALSE.test(format)) return false\n  const accept = ctx.request.header('accept') || ''\n  if (IEEE754_COMPATIBLE_TRUE.test(accept)) return true\n  if (IEEE754_COMPATIBLE_FALSE.test(accept)) return false\n  return fallback\n}\n","/*\n|--------------------------------------------------------------------------\n| Resourceful Error Middleware\n|--------------------------------------------------------------------------\n|\n| Intercepts errors thrown during http requests and formats the responses\n| in a consistent manner meant to be easily consumed by clients.\n|\n| While designed specifically to work with Lucid Resourceful, there is no\n| reason it cannot be applied to non-resourceful routes as well.\n*/\nimport { js2xml } from 'xml-js'\nimport { errors } from '@vinejs/vine'\nimport { Exception } from '@poppinss/utils'\nimport { negotiateContent } from '../utils/http'\nimport { default as string } from '@poppinss/string'\nimport { TypedEventEmitter } from '@nhtio/tiny-typed-emitter'\nimport { isObject, stripUndefinedValuesFromObject } from '../../utils'\nimport { ValidationError as JoiValidationError } from '@nhtio/lucid-resourceful/joi'\nimport {\n  isError,\n  isException,\n  isJoiValidationError,\n  isVineValidationError,\n  isNotImplementedError,\n} from '../../router_macro/utils/errors'\nimport type { JsonObject } from 'type-fest'\nimport type { ElementCompact } from 'xml-js'\nimport type { HttpContext } from '@adonisjs/core/http'\nimport type { NextFn } from '@adonisjs/core/types/http'\nimport type { EventMap } from '@nhtio/tiny-typed-emitter'\n/**\n * Type alias for Vine validation errors thrown by the VineJS validation library.\n *\n * @example\n * ```typescript\n * try {\n *   await vine.validate(schema, data)\n * } catch (error) {\n *   if (isVineValidationError(error)) {\n *     // Handle Vine validation error\n *   }\n * }\n * ```\n */\nexport type VineValidationError = InstanceType<typeof errors.E_VALIDATION_ERROR>\n\n/**\n * Event map defining the types of errors that can be emitted by the ODataErrorMiddleware.\n * Each event type maps to the specific error instance that will be passed to event handlers.\n *\n * @example\n * ```typescript\n * const middleware = new ODataErrorMiddleware({\n *   onVineValidationError: (error) => logger.warn('Validation failed', error),\n *   onException: (error) => monitoring.captureException(error),\n *   onAny: (error) => analytics.trackError(error)\n * })\n * ```\n */\nexport type ODataErrorMiddlewareEvents = EventMap<{\n  vineValidationError: [VineValidationError]\n  joiValidationError: [JoiValidationError]\n  exception: [Exception]\n  error: [Error]\n  unknown: [unknown]\n  any: [unknown]\n}>\n\nclass ODataErrorMiddlewareEmitter extends TypedEventEmitter<ODataErrorMiddlewareEvents> {}\n\n/**\n * Configuration object for custom HTTP headers to be included in error responses.\n * Allows for CORS headers, security headers, API versioning, or any custom headers\n * that should be consistently applied to all error responses.\n *\n * @example\n * ```typescript\n * const headers: ODataErrorMiddlewareHeaders = {\n *   'X-API-Version': '1.0',\n *   'Access-Control-Allow-Origin': '*',\n *   'X-RateLimit-Remaining': '100'\n * }\n * ```\n */\nexport interface ODataErrorMiddlewareHeaders {\n  [key: string]: string\n}\n\n/**\n * Configuration options for the ODataErrorMiddleware class.\n * Defines event handlers for different error types and response formatting options.\n *\n * @example\n * ```typescript\n * const options: ODataErrorMiddlewareOptions = {\n *   onVineValidationError: (error) => logger.warn('Validation failed', error),\n *   onException: (error) => monitoring.captureException(error),\n *   onAny: (error) => analytics.trackError(error),\n *   asYaml: true,\n *   headers: {\n *     'X-API-Version': '1.0',\n *     'Access-Control-Allow-Origin': '*'\n *   }\n * }\n * ```\n */\nexport interface ODataErrorMiddlewareOptions {\n  /** Event handler called when a Vine validation error is encountered */\n  onVineValidationError?: (error: VineValidationError) => void\n  /** Event handler called when a Joi validation error is encountered */\n  onJoiValidationError?: (error: JoiValidationError) => void\n  /** Event handler called when a framework Exception is encountered */\n  onException?: (error: Exception) => void\n  /** Event handler called when a generic Error is encountered */\n  onError?: (error: Error) => void\n  /** Event handler called when an unknown error type is encountered */\n  onUnknown?: (error: unknown) => void\n  /** Event handler called for any error that occurs, regardless of type */\n  onAny?: (error: unknown) => void\n  /** Whether to support YAML response format. Defaults to true */\n  asYaml?: boolean\n  /** Custom headers to include in all error responses */\n  headers?: ODataErrorMiddlewareHeaders\n}\n\n/**\n * Individual error detail within a formatted error response.\n * Provides field-level information for validation errors or error chain details.\n *\n * @example\n * ```typescript\n * const detail: ResourcefulFormattedErrorDetails = {\n *   code: 'E_REQUIRED',\n *   message: 'The email field is required',\n *   target: 'email',\n *   context: { field: 'email', value: null }\n * }\n * ```\n */\nexport interface ResourcefulFormattedErrorDetails {\n  /** Machine-readable error code (e.g., 'E_REQUIRED', 'E_INVALID_FORMAT') */\n  code: string\n  /** Human-readable error message */\n  message: string\n  /** The field or property that caused the error (for validation errors) */\n  target?: string\n  /** Additional context information about the error */\n  context?: JsonObject\n}\n\n/**\n * Standardized error response format used by the ODataErrorMiddleware.\n * Provides consistent structure for all API error responses with support for\n * field-level validation details and error chaining.\n *\n * @example\n * ```typescript\n * const formattedError: ResourcefulFormattedError = {\n *   status: 422,\n *   code: 'E_VALIDATION_ERROR',\n *   message: 'Validation failed',\n *   help: 'Check the provided field values',\n *   details: [\n *     {\n *       code: 'E_REQUIRED',\n *       message: 'The email field is required',\n *       target: 'email'\n *     }\n *   ]\n * }\n * ```\n */\nexport interface ResourcefulFormattedError {\n  /** HTTP status code for the error response */\n  status: number\n  /** Machine-readable error code */\n  code: string\n  /** Human-readable error message */\n  message: string\n  /** Optional help text providing guidance on how to resolve the error */\n  help?: string\n  /** Array of detailed error information, typically for validation errors */\n  details?: ResourcefulFormattedErrorDetails[]\n}\n\n/**\n * AdonisJS middleware that intercepts errors thrown during HTTP requests and formats\n * the responses in a consistent, client-friendly manner. Supports multiple error types\n * including Vine validation errors, Joi validation errors, framework exceptions, and\n * generic errors.\n *\n * The middleware provides:\n * - Consistent error response formatting across all error types\n * - Event-driven error handling for monitoring and logging\n * - Content negotiation supporting JSON and YAML responses\n * - Recursive error cause handling to preserve error chains\n * - Configurable headers for CORS, security, and custom requirements\n *\n * @example\n * ```typescript\n * // Basic usage with default configuration\n * const middleware = new ODataErrorMiddleware({})\n * router.use(middleware.handle)\n *\n * // Advanced usage with event handlers and custom headers\n * const middleware = new ODataErrorMiddleware({\n *   onVineValidationError: (error) => logger.warn('Validation failed', error),\n *   onException: (error) => monitoring.captureException(error),\n *   onAny: (error) => analytics.trackError(error),\n *   headers: {\n *     'X-API-Version': '1.0',\n *     'Access-Control-Allow-Origin': '*'\n *   }\n * })\n * router.use(middleware.handle)\n * ```\n *\n * @example\n * ```typescript\n * // Standalone usage outside of resourceful routes\n * import ODataErrorMiddleware from '@nhtio/lucid-resourceful/middlewares/resourceful_error'\n *\n * const errorHandler = new ODataErrorMiddleware({\n *   onException: (error) => logger.error(error),\n *   headers: { 'X-Error-Handler': 'resourceful' }\n * })\n *\n * router.use(errorHandler.handle)\n * ```\n */\nexport class ODataErrorMiddleware {\n  /**\n   * Creates a usable middleware function that can be applied directly to AdonisJS routes.\n   * @param opts - Configuration options for the middleware\n   * @returns A middleware function that can be used in AdonisJS routes\n   */\n  public static usable(opts: ODataErrorMiddlewareOptions = {}) {\n    const instance = new ODataErrorMiddleware(opts)\n    return (ctx: HttpContext, next: NextFn) => instance.handle(ctx, next)\n  }\n\n  /**\n   * Handles errors thrown during request processing. This method is meant to be integrated with the AdonisJS HttpExceptionHandler\n   * @param error - The error that was thrown\n   * @param ctx - The HTTP context object\n   * @param opts - Configuration options for the middleware\n   * @returns A Promise that resolves to the error response\n   */\n  public static handle(error: unknown, ctx: HttpContext, opts: ODataErrorMiddlewareOptions = {}) {\n    const instance = new ODataErrorMiddleware(opts)\n    return instance.onError(ctx, error)\n  }\n\n  /**\n   * Determines if the middleware should handle the request based on the desired response format.\n   * If the desired format is HTML, it returns false to allow other handlers to process the request.\n   * Otherwise, it returns true to indicate that this middleware should handle the error response.\n   *\n   * @param ctx - The HTTP context object containing request and response information\n   * @returns A boolean indicating whether this middleware should handle the request\n   */\n  public static shouldHandle(_ctx: HttpContext): boolean {\n    return true\n  }\n\n  readonly #emitter: ODataErrorMiddlewareEmitter\n  readonly #asYaml: boolean\n  readonly #headers: ODataErrorMiddlewareHeaders\n\n  /**\n   * Creates a new instance of ODataErrorMiddleware with the specified configuration.\n   *\n   * @param opts - Configuration options for the middleware\n   *\n   * @example\n   * ```typescript\n   * const middleware = new ODataErrorMiddleware({\n   *   onVineValidationError: (error) => console.error('Validation:', error),\n   *   onException: (error) => monitoring.captureException(error),\n   *   asYaml: true,\n   *   headers: { 'X-API-Version': '1.0' }\n   * })\n   * ```\n   */\n  constructor(opts: ODataErrorMiddlewareOptions) {\n    this.#emitter = new ODataErrorMiddlewareEmitter()\n    // asYaml defaults to `true`\n    this.#asYaml = false !== opts.asYaml\n    // headers defaults to an empty object\n    this.#headers = isObject(opts.headers) ? opts.headers : {}\n    if ('function' === typeof opts.onVineValidationError) {\n      this.#emitter.once('vineValidationError', opts.onVineValidationError)\n    }\n    if ('function' === typeof opts.onJoiValidationError) {\n      this.#emitter.once('joiValidationError', opts.onJoiValidationError)\n    }\n    if ('function' === typeof opts.onException) {\n      this.#emitter.once('exception', opts.onException)\n    }\n    if ('function' === typeof opts.onError) {\n      this.#emitter.once('error', opts.onError)\n    }\n    if ('function' === typeof opts.onUnknown) {\n      this.#emitter.once('unknown', opts.onUnknown)\n    }\n    if ('function' === typeof opts.onAny) {\n      this.#emitter.once('any', opts.onAny)\n    }\n  }\n\n  /**\n   * AdonisJS middleware handler that intercepts and processes errors during request execution.\n   * This method should be used as middleware in your route definitions.\n   *\n   * @param ctx - The HTTP context object containing request and response information\n   * @param next - The next function to call in the middleware chain\n   *\n   * @example\n   * ```typescript\n   * const middleware = new ODataErrorMiddleware({})\n   * router.use(middleware.handle)\n   *\n   * // Or bind it to specific routes\n   * router.get('/api/users', UserController.index).use([middleware.handle])\n   * ```\n   */\n  async handle(ctx: HttpContext, next: NextFn) {\n    try {\n      await next()\n    } catch (error) {\n      return this.onError(ctx, error)\n    }\n  }\n\n  /**\n   * Processes a caught error, emits appropriate events, and sends a formatted response.\n   * This method handles error classification, event emission, content negotiation,\n   * and response formatting.\n   *\n   * @param ctx - The HTTP context object\n   * @param error - The error that was caught during request processing\n   *\n   * @example\n   * ```typescript\n   * // Typically called automatically by the handle method, but can be used directly\n   * try {\n   *   // Some operation that might throw\n   * } catch (error) {\n   *   middleware.onError(ctx, error)\n   * }\n   * ```\n   */\n  onError(ctx: HttpContext, error: unknown) {\n    this.#emitter.emit('any', error)\n    switch (true) {\n      case isVineValidationError(error):\n        this.#emitter.emit('vineValidationError', error)\n        break\n\n      case isJoiValidationError(error):\n        this.#emitter.emit('joiValidationError', error)\n        break\n\n      case isException(error):\n        this.#emitter.emit('exception', error)\n        break\n\n      case isError(error):\n        this.#emitter.emit('error', error)\n        break\n\n      default:\n        this.#emitter.emit('unknown', error)\n        break\n    }\n    const format = negotiateContent(ctx)\n    // if the desired format is HTML, break early since that needs to be handled elsewhere\n    const formattedError = this.#getFormattedError(error)\n    ctx.response.status(formattedError.status)\n    Object.entries(this.#headers).forEach(([key, value]) => {\n      ctx.response.header(key, value)\n    })\n    switch (true) {\n      case 'xml' === format && this.#asYaml:\n        return this.#sendAsXml(ctx, formattedError)\n\n      default:\n        return this.#sendAsJson(ctx, formattedError)\n    }\n  }\n\n  #sendAsJson(ctx: HttpContext, formattedError: ResourcefulFormattedError) {\n    ctx.response.header('Content-Type', 'application/json')\n    ctx.response.send(\n      JSON.stringify({\n        error: stripUndefinedValuesFromObject({\n          ...formattedError,\n          status: undefined,\n        }),\n      })\n    )\n  }\n\n  #sendAsXml(ctx: HttpContext, formattedError: ResourcefulFormattedError) {\n    const payload: ElementCompact = {\n      '_declaration': { _attributes: { version: '1.0', encoding: 'UTF-8' } },\n      'm:error': {\n        '_attributes': {\n          'xmlns:m': 'http://docs.oasis-open.org/odata/ns/metadata',\n        },\n        'm:code': { _text: formattedError.code },\n        'm:message': { _text: formattedError.message },\n        ...(formattedError.details &&\n          formattedError.details.length > 0 && {\n            'm:details': formattedError.details.map((detail) => ({\n              'm:detail': {\n                'm:code': { _text: detail.code },\n                'm:message': { _text: detail.message },\n                ...(detail.target && { 'm:target': { _text: detail.target } }),\n              },\n            })),\n          }),\n      },\n    }\n\n    ctx.response.header('Content-Type', 'application/xml')\n    ctx.response.header('OData-Version', '4.0')\n    ctx.response.send(js2xml(payload, { compact: true, spaces: 2 }))\n  }\n\n  #getFormattedError(error: unknown): ResourcefulFormattedError {\n    switch (true) {\n      case isVineValidationError(error):\n        return this.#formatVineValidationError(error)\n\n      case isJoiValidationError(error):\n        return this.#formatJoiValidationError(error)\n\n      case isException(error):\n        return this.#formatException(error)\n\n      case isError(error):\n        return this.#formatError(error)\n\n      default:\n        return this.#formatUnknown(error)\n    }\n  }\n\n  #formatVineValidationError(error: VineValidationError): ResourcefulFormattedError {\n    const status: number = error.status || 422\n    const code: string = error.code || 'E_VALIDATION_ERROR'\n    const message: string = error.messages || 'Validation failed'\n    const help: string | undefined =\n      'help' in error && 'string' === typeof error.help ? error.help : undefined\n    let details: ResourcefulFormattedErrorDetails[] | undefined = Array.isArray(error.messages)\n      ? error.messages.map((m) => {\n          return stripUndefinedValuesFromObject({\n            code: m.rule ? string.snakeCase(m.rule).toUpperCase() : 'E_VALIDATION_ERROR',\n            message: m.message || 'Validation error',\n            target: m.field,\n          })\n        })\n      : undefined\n    if (error.cause) {\n      if (!details) {\n        details = []\n      }\n      const formattedCause = this.#getFormattedError(error.cause)\n      details.push({\n        code: formattedCause.code,\n        message: formattedCause.message,\n      })\n    }\n    return stripUndefinedValuesFromObject({\n      status,\n      code,\n      message,\n      help,\n      details,\n    })\n  }\n\n  #formatJoiValidationError(error: JoiValidationError): ResourcefulFormattedError {\n    const status: number = 422\n    const code: string = 'E_VALIDATION_ERROR'\n    const message: string = error.message || 'Validation failed'\n    const help: string | undefined =\n      'help' in error && 'string' === typeof error.help ? error.help : undefined\n    let details: ResourcefulFormattedErrorDetails[] | undefined = Array.isArray(error.details)\n      ? error.details.map((d) => {\n          return stripUndefinedValuesFromObject({\n            code: string.snakeCase(d.type).toUpperCase(),\n            message: d.message || 'Validation error',\n            target: d.path.length > 0 ? d.path.join('.') : undefined,\n            context: d.context || undefined,\n          })\n        })\n      : undefined\n    if (error.cause) {\n      if (!details) {\n        details = []\n      }\n      const formattedCause = this.#getFormattedError(error.cause)\n      details.push({\n        code: formattedCause.code,\n        message: formattedCause.message,\n      })\n    }\n    return stripUndefinedValuesFromObject({\n      status,\n      code,\n      message,\n      help,\n      details,\n    })\n  }\n\n  #formatException(error: Exception): ResourcefulFormattedError {\n    const status: number = error.status || 500\n    const code: string = error.code || 'E_EXCEPTION'\n    const message: string = error.message || 'An exception occurred'\n    const help: string | undefined =\n      'help' in error && 'string' === typeof error.help ? error.help : undefined\n    const formattedCause = error.cause ? this.#getFormattedError(error.cause) : undefined\n    const details: ResourcefulFormattedErrorDetails[] | undefined = formattedCause\n      ? [\n          stripUndefinedValuesFromObject({\n            code: formattedCause.code,\n            message: formattedCause.message,\n          }),\n        ]\n      : undefined\n    return stripUndefinedValuesFromObject({\n      status,\n      code,\n      message,\n      help,\n      details,\n    })\n  }\n\n  #formatError(error: Error): ResourcefulFormattedError {\n    const status: number = isNotImplementedError(error) ? 501 : 500\n    const code: string = 'E_ERROR'\n    const message: string = error.message || 'An error occurred'\n    const help: string | undefined =\n      'help' in error && 'string' === typeof error.help ? error.help : undefined\n    const formattedCause = error.cause ? this.#getFormattedError(error.cause) : undefined\n    const details: ResourcefulFormattedErrorDetails[] | undefined = formattedCause\n      ? [\n          stripUndefinedValuesFromObject({\n            code: formattedCause.code,\n            message: formattedCause.message,\n          }),\n        ]\n      : undefined\n    return stripUndefinedValuesFromObject({\n      status,\n      code,\n      message,\n      help,\n      details,\n    })\n  }\n\n  #formatUnknown(error: unknown): ResourcefulFormattedError {\n    const status: number = 500\n    const code: string = 'E_UNKNOWN_ERROR'\n    const message: string = 'An unknown error occurred'\n    const help: string | undefined =\n      isObject(error) && 'help' in error && 'string' === typeof error.help ? error.help : undefined\n    const formattedCause =\n      isObject(error) && error.cause ? this.#getFormattedError(error.cause) : undefined\n    const details: ResourcefulFormattedErrorDetails[] | undefined = formattedCause\n      ? [\n          stripUndefinedValuesFromObject({\n            code: formattedCause.code,\n            message: formattedCause.message,\n          }),\n        ]\n      : undefined\n    return stripUndefinedValuesFromObject({\n      status,\n      code,\n      message,\n      help,\n      details,\n    })\n  }\n}\n"],"names":["TypedEventEmitter","isObject","isVineValidationError","isJoiValidationError","isException","isError","stripUndefinedValuesFromObject","js2xml","isNotImplementedError"],"mappings":"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"}