UNPKG

@inaiat/fastify-papr

Version:
1 lines 6.9 kB
{"version":3,"sources":["../src/mongo-validation-error.ts"],"sourcesContent":["import { MongoServerError } from 'mongodb'\n\n/**\n * Represents details about a property that failed validation\n */\nexport type ValidationDetail = {\n /** The validation operator that failed (e.g., 'maxLength', 'minimum') */\n operatorName?: string\n /** The specification that was violated */\n specifiedAs?: Record<string, unknown>\n /** Human-readable reason for the validation failure */\n reason?: string\n /** The actual value that was rejected */\n consideredValue?: unknown\n /** The type of the value that was rejected */\n consideredType?: unknown\n}\n\n/**\n * Represents a property that failed MongoDB validation\n */\nexport type ValidationProperty = {\n /** Name of the property that failed validation */\n propertyName: string\n /** Details about why validation failed */\n details: ValidationDetail[]\n}\n\n/**\n * MongoDB validation error structure as returned by the server\n */\nexport type DocumentValidationError = {\n /** ID of the document that failed validation */\n failingDocumentId?: string\n /** Error details from MongoDB */\n details?: {\n /** The validation operator (usually '$jsonSchema') */\n operatorName?: string\n /** Rules that weren't satisfied by the document */\n schemaRulesNotSatisfied?: [\n {\n /** The specific rule operator that failed */\n operatorName: string\n /** Properties that didn't satisfy the validation rules */\n propertiesNotSatisfied: ValidationProperty[]\n },\n ]\n }\n}\n\n/**\n * A simplified representation of MongoDB validation errors\n * Maps operator names to property details for easier client-side handling\n */\nexport type ValidationErrors = Record<string, Record<string, ValidationDetail[]>[]>[] | undefined\n\n/**\n * Checks if an error is a MongoDB server error\n * @param error The error to check\n * @returns True if the error is a MongoDB server error\n */\nexport function isMongoServerError(error: unknown): error is MongoServerError {\n if (error instanceof MongoServerError) {\n return true\n }\n\n const errorWithCode = error as { code?: number }\n return error instanceof Error && typeof errorWithCode.code === 'number'\n}\n\n/**\n * Transforms validation error properties into a more readable format\n * @param properties The properties that failed validation\n * @returns A mapped array of property errors with details\n * @internal\n */\nconst formatValidationProperties = (properties: readonly ValidationProperty[]) =>\n properties?.map(prop => ({ [prop.propertyName]: prop.details }))\n\n/**\n * Attempts to extract validation error details from a MongoDB server error\n * @param error The MongoDB server error to process\n * @returns A simplified representation of validation errors or undefined if not a validation error\n */\nexport function extractValidationErrors(\n error: Readonly<MongoServerError>,\n): ValidationErrors | undefined {\n // Check if this is actually a MongoDB validation error\n if (!isMongoServerError(error) || error.code !== 121) {\n return undefined\n }\n\n // Safely extract schema rules not satisfied\n const errInfo = error.errInfo as DocumentValidationError | undefined\n if (!errInfo?.details?.schemaRulesNotSatisfied?.length) {\n return undefined\n }\n\n const schemaRulesNotSatisfied = errInfo.details.schemaRulesNotSatisfied\n\n // Transform the schema rules into a more user-friendly format\n const result: ValidationErrors = schemaRulesNotSatisfied.map(rule => ({\n [rule.operatorName]: formatValidationProperties(rule.propertiesNotSatisfied || []),\n }))\n\n return result.length > 0 ? result : undefined\n}\n\n/**\n * Error class that simplifies handling of MongoDB validation errors\n * Extracts and provides easy access to validation details\n */\nexport class MongoValidationError extends Error {\n /** The extracted validation rules that weren't satisfied */\n validationErrors?: ValidationErrors\n\n /** Flag indicating whether this is a document validation error */\n hasValidationFailures: boolean\n\n /**\n * Creates an instance from a MongoDB server error\n * @param mongoError The original MongoDB error\n */\n constructor(mongoError: Readonly<MongoServerError>) {\n super(mongoError.message, { cause: mongoError })\n this.validationErrors = extractValidationErrors(mongoError)\n this.hasValidationFailures = this.validationErrors !== undefined\n }\n\n /**\n * Returns the validation errors as a JSON string\n * @returns A JSON string of the validation errors or undefined if not a validation error\n */\n getValidationErrorsAsString(): string | undefined {\n return this.hasValidationFailures ? JSON.stringify(this.validationErrors) : undefined\n }\n\n /**\n * Finds validation errors for a specific field\n * @param fieldName The field name to find errors for\n * @returns Array of validation details for the field or undefined if none found\n */\n getFieldErrors(fieldName: string): ValidationDetail[] | undefined {\n if (!this.hasValidationFailures || !this.validationErrors?.length) {\n return undefined\n }\n\n for (const ruleSet of this.validationErrors) {\n for (const [, properties] of Object.entries(ruleSet)) {\n for (const property of properties) {\n const field = Object.keys(property).find(key => key === fieldName)\n if (field) {\n return property[field]\n }\n }\n }\n }\n\n return undefined\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAiC;AA6D1B,SAAS,mBAAmB,OAA2C;AAC5E,MAAI,iBAAiB,iCAAkB;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB;AACtB,SAAO,iBAAiB,SAAS,OAAO,cAAc,SAAS;AACjE;AAQA,IAAM,6BAA6B,CAAC,eAClC,YAAY,IAAI,WAAS,EAAE,CAAC,KAAK,YAAY,GAAG,KAAK,QAAQ,EAAE;AAO1D,SAAS,wBACd,OAC8B;AAE9B,MAAI,CAAC,mBAAmB,KAAK,KAAK,MAAM,SAAS,KAAK;AACpD,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,MAAM;AACtB,MAAI,CAAC,SAAS,SAAS,yBAAyB,QAAQ;AACtD,WAAO;AAAA,EACT;AAEA,QAAM,0BAA0B,QAAQ,QAAQ;AAGhD,QAAM,SAA2B,wBAAwB,IAAI,WAAS;AAAA,IACpE,CAAC,KAAK,YAAY,GAAG,2BAA2B,KAAK,0BAA0B,CAAC,CAAC;AAAA,EACnF,EAAE;AAEF,SAAO,OAAO,SAAS,IAAI,SAAS;AACtC;AAMO,IAAM,uBAAN,cAAmC,MAAM;AAAA;AAAA,EAE9C;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,YAAwC;AAClD,UAAM,WAAW,SAAS,EAAE,OAAO,WAAW,CAAC;AAC/C,SAAK,mBAAmB,wBAAwB,UAAU;AAC1D,SAAK,wBAAwB,KAAK,qBAAqB;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,8BAAkD;AAChD,WAAO,KAAK,wBAAwB,KAAK,UAAU,KAAK,gBAAgB,IAAI;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,WAAmD;AAChE,QAAI,CAAC,KAAK,yBAAyB,CAAC,KAAK,kBAAkB,QAAQ;AACjE,aAAO;AAAA,IACT;AAEA,eAAW,WAAW,KAAK,kBAAkB;AAC3C,iBAAW,CAAC,EAAE,UAAU,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,mBAAW,YAAY,YAAY;AACjC,gBAAM,QAAQ,OAAO,KAAK,QAAQ,EAAE,KAAK,SAAO,QAAQ,SAAS;AACjE,cAAI,OAAO;AACT,mBAAO,SAAS,KAAK;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}