{"version":3,"file":"better-ajv-errors.cjs.production.min.js","sources":["../src/constants.ts","../src/lib/suggestions.ts","../src/lib/utils.ts","../src/index.ts","../src/lib/filter.ts"],"sourcesContent":["import { DefinedError } from 'ajv';\n\nexport const AJV_ERROR_KEYWORD_WEIGHT_MAP: Partial> = {\n enum: 1,\n type: 0,\n};\n\nexport const QUOTES_REGEX = /\"/g;\nexport const NOT_REGEX = /NOT/g;\nexport const SLASH_REGEX = /\\//g;\n","import leven from 'leven';\n\nexport const getSuggestion = ({\n value,\n suggestions,\n format = (suggestion) => `Did you mean '${suggestion}'?`,\n}: {\n value: string | null;\n suggestions: string[];\n format?: (suggestion: string) => string;\n}): string => {\n if (!value) return '';\n const bestSuggestion = suggestions.reduce(\n (best, current) => {\n const distance = leven(value, current);\n if (best.distance > distance) {\n return { value: current, distance };\n }\n\n return best;\n },\n {\n distance: Infinity,\n value: '',\n }\n );\n\n return bestSuggestion.distance < value.length ? format(bestSuggestion.value) : '';\n};\n","import { NOT_REGEX, QUOTES_REGEX, SLASH_REGEX } from '../constants';\nimport pointer from 'jsonpointer';\n\nexport const pointerToDotNotation = (pointer: string): string => {\n return pointer.replace(SLASH_REGEX, '.');\n};\n\nexport const cleanAjvMessage = (message: string): string => {\n return message.replace(QUOTES_REGEX, \"'\").replace(NOT_REGEX, 'not');\n};\n\nexport const getLastSegment = (path: string): string => {\n const segments = path.split('/');\n return segments.pop() as string;\n};\n\nexport const safeJsonPointer = ({ object, pnter, fallback }: { object: any; pnter: string; fallback: T }): T => {\n try {\n return pointer.get(object, pnter);\n } catch (err) {\n return fallback;\n }\n};\n","import { DefinedError, ErrorObject } from 'ajv';\nimport type { JSONSchema6 } from 'json-schema';\nimport { ValidationError } from './types/ValidationError';\nimport { filterSingleErrorPerProperty } from './lib/filter';\nimport { getSuggestion } from './lib/suggestions';\nimport { cleanAjvMessage, getLastSegment, pointerToDotNotation, safeJsonPointer } from './lib/utils';\n\nexport interface BetterAjvErrorsOptions {\n errors: ErrorObject[] | null | undefined;\n data: any;\n schema: JSONSchema6;\n basePath?: string;\n}\n\nexport const betterAjvErrors = ({\n errors,\n data,\n schema,\n basePath = '{base}',\n}: BetterAjvErrorsOptions): ValidationError[] => {\n if (!Array.isArray(errors) || errors.length === 0) {\n return [];\n }\n\n const definedErrors = filterSingleErrorPerProperty(errors as DefinedError[]);\n\n return definedErrors.map((error) => {\n const path = pointerToDotNotation(basePath + error.instancePath);\n const prop = getLastSegment(error.instancePath);\n const defaultContext = {\n errorType: error.keyword,\n };\n const defaultMessage = `${prop ? `property '${prop}'` : path} ${cleanAjvMessage(error.message as string)}`;\n\n let validationError: ValidationError;\n\n switch (error.keyword) {\n case 'additionalProperties': {\n const additionalProp = error.params.additionalProperty;\n const suggestionPointer = error.schemaPath.replace('#', '').replace('/additionalProperties', '');\n const { properties } = safeJsonPointer({\n object: schema,\n pnter: suggestionPointer,\n fallback: { properties: {} },\n });\n validationError = {\n message: `'${additionalProp}' property is not expected to be here`,\n suggestion: getSuggestion({\n value: additionalProp,\n suggestions: Object.keys(properties ?? {}),\n format: (suggestion) => `Did you mean property '${suggestion}'?`,\n }),\n path,\n context: defaultContext,\n };\n break;\n }\n case 'enum': {\n const suggestions = error.params.allowedValues.map((value) => value.toString());\n const prop = getLastSegment(error.instancePath);\n const value = safeJsonPointer({ object: data, pnter: error.instancePath, fallback: '' });\n validationError = {\n message: `'${prop}' property must be equal to one of the allowed values`,\n suggestion: getSuggestion({\n value,\n suggestions,\n }),\n path,\n context: {\n ...defaultContext,\n allowedValues: error.params.allowedValues,\n },\n };\n break;\n }\n case 'type': {\n const prop = getLastSegment(error.instancePath);\n const type = error.params.type;\n validationError = {\n message: `'${prop}' property type must be ${type}`,\n path,\n context: defaultContext,\n };\n break;\n }\n case 'required': {\n validationError = {\n message: `${path} must have required property '${error.params.missingProperty}'`,\n path,\n context: defaultContext,\n };\n break;\n }\n case 'const': {\n return {\n message: `'${prop}' property must be equal to the allowed value`,\n path,\n context: {\n ...defaultContext,\n allowedValue: error.params.allowedValue,\n },\n };\n }\n\n default:\n return { message: defaultMessage, path, context: defaultContext };\n }\n\n // Remove empty properties\n const errorEntries = Object.entries(validationError);\n for (const [key, value] of errorEntries as [keyof ValidationError, unknown][]) {\n if (value === null || value === undefined || value === '') {\n delete validationError[key];\n }\n }\n\n return validationError;\n });\n};\n\nexport { ValidationError };\n","import { DefinedError } from 'ajv';\nimport { AJV_ERROR_KEYWORD_WEIGHT_MAP } from '../constants';\n\nexport const filterSingleErrorPerProperty = (errors: DefinedError[]): DefinedError[] => {\n const errorsPerProperty = errors.reduce>((acc, error) => {\n const prop =\n error.instancePath + ((error.params as any)?.additionalProperty ?? (error.params as any)?.missingProperty ?? '');\n const existingError = acc[prop];\n if (!existingError) {\n acc[prop] = error;\n return acc;\n }\n const weight = AJV_ERROR_KEYWORD_WEIGHT_MAP[error.keyword] ?? 0;\n const existingWeight = AJV_ERROR_KEYWORD_WEIGHT_MAP[existingError.keyword] ?? 0;\n\n if (weight > existingWeight) {\n acc[prop] = error;\n }\n return acc;\n }, {});\n\n return Object.values(errorsPerProperty);\n};\n"],"names":["AJV_ERROR_KEYWORD_WEIGHT_MAP","enum","type","QUOTES_REGEX","NOT_REGEX","SLASH_REGEX","getSuggestion","value","format","suggestion","bestSuggestion","suggestions","reduce","best","current","distance","leven","Infinity","length","getLastSegment","path","split","pop","safeJsonPointer","object","pnter","fallback","pointer","get","err","errors","data","schema","basePath","Array","isArray","errorsPerProperty","acc","error","prop","instancePath","params","_error$params","additionalProperty","_error$params2","missingProperty","existingError","keyword","Object","values","filterSingleErrorPerProperty","map","validationError","replace","pointerToDotNotation","defaultContext","errorType","defaultMessage","message","additionalProp","suggestionPointer","schemaPath","properties","keys","context","allowedValues","toString","allowedValue","entries"],"mappings":"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"}