UNPKG

@elsikora/nestjs-crud-automator

Version:

A library for automating the creation of CRUD operations in NestJS.

162 lines (158 loc) 8.22 kB
'use strict'; var tslib_es6 = require('../external/tslib/tslib.es6.js'); var mustMatchOneOfSchemasErrorType_enum = require('../enum/validator/must-match-one-of-schemas-error-type.enum.js'); var exception_utility = require('../utility/error/exception.utility.js'); var classValidator = require('class-validator'); // eslint-disable-next-line @elsikora/typescript/naming-convention exports.MustMatchOneOfSchemasConstraint = class MustMatchOneOfSchemasConstraint { allowedValues = []; discriminatorField = null; discriminatorValue = null; errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.UNKNOWN; /** * Provides a custom error message based on the type of validation failure * @param {ValidationArguments} _arguments - Validation arguments containing property information * @returns {string} A descriptive error message explaining why validation failed */ defaultMessage(_arguments) { const propertyName = _arguments.property; switch (this.errorType) { case mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.INVALID_DISCRIMINATOR: { const schemasList = this.allowedValues .map((value) => { return `'${value}'`; }) .join(", "); return `${propertyName} has invalid discriminator value '${String(this.discriminatorValue)}' for field '${String(this.discriminatorField)}'. must be one of: ${schemasList}`; } case mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.MISSING_DISCRIMINATOR: { return `${propertyName} is missing required discriminator field '${String(this.discriminatorField)}'`; } case mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.SCHEMA_MISMATCH: { const schemasList = this.allowedValues .map((value) => { return `'${value}'`; }) .join(", "); return `${propertyName} must match one of the schemas: ${schemasList}`; } case mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.UNKNOWN: { return `${propertyName} must match one of the valid schemas`; } default: { return `${propertyName} must match one of the valid schemas`; } } } /** * Validates whether an object matches one of the allowed schemas based on its discriminator field * @param {unknown} value - The value being validated * @param {ValidationArguments} _arguments - Validation arguments containing constraints * @returns {boolean} True if the value matches a valid schema, false otherwise */ validate(value, _arguments) { if (!value || typeof value !== "object" || Array.isArray(value)) { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.SCHEMA_MISMATCH; this.prepareAllowedSchemas(_arguments); return false; } const valueAsRecord = value; if (Object.keys(valueAsRecord).length === 0) { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.SCHEMA_MISMATCH; this.prepareAllowedSchemas(_arguments); return false; } const constraints = _arguments.constraints; if (!constraints?.[0]?.discriminator) { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.UNKNOWN; return false; } try { const discriminator = constraints[0].discriminator; if (!discriminator.propertyName || typeof discriminator.propertyName !== "string") { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.UNKNOWN; return false; } this.discriminatorField = discriminator.propertyName; if (!(discriminator.propertyName in valueAsRecord)) { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.MISSING_DISCRIMINATOR; return false; } const discriminatorValue = valueAsRecord[discriminator.propertyName]; if (typeof discriminatorValue !== "string" || discriminatorValue === "") { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.INVALID_DISCRIMINATOR; this.discriminatorValue = String(discriminatorValue); this.prepareAllowedSchemas(_arguments); return false; } this.discriminatorValue = discriminatorValue; if (!discriminator.mapping || typeof discriminator.mapping !== "object") { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.SCHEMA_MISMATCH; this.prepareAllowedSchemas(_arguments); return false; } this.prepareAllowedSchemas(_arguments); if (!this.allowedValues.includes(discriminatorValue)) { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.INVALID_DISCRIMINATOR; return false; } return true; } catch { this.errorType = mustMatchOneOfSchemasErrorType_enum.EMastMatchOneOfSchemasValidationErrorType.SCHEMA_MISMATCH; this.prepareAllowedSchemas(_arguments); return false; } } /** * Prepares the list of allowed discriminator values based on validation constraints * @param {ValidationArguments} _arguments - Validation arguments containing constraints * @returns {void} * @private */ prepareAllowedSchemas(_arguments) { this.allowedValues = []; const constraints = _arguments.constraints; if (!constraints?.[0]) { return; } const { discriminator } = constraints[0]; if (!discriminator?.mapping) { return; } this.allowedValues = Object.keys(discriminator.mapping); } }; exports.MustMatchOneOfSchemasConstraint = tslib_es6.__decorate([ classValidator.ValidatorConstraint({ async: false, name: "must-match-one-of-schemas" }) ], exports.MustMatchOneOfSchemasConstraint); /** * Decorator that checks if the object matches one of the schemas based on the discriminator field * @param {IMustMatchOneOfSchemasDiscriminatorConfig} discriminatorConfig - Configuration for the discriminator * @param {ValidationOptions} [validationOptions] - Validation options * @returns {PropertyDecorator} - Decorator */ function MustMatchOneOfSchemasValidator(discriminatorConfig, validationOptions) { return function (target, propertyKey) { if (typeof propertyKey !== "string") { throw exception_utility.ErrorException("MatchesOneOfSchemas decorator can only be applied to string properties"); } if (!discriminatorConfig?.discriminator) { throw exception_utility.ErrorException("discriminatorConfig must contain a discriminator property"); } const discriminator = discriminatorConfig.discriminator; if (!discriminator.propertyName || !discriminator.mapping) { throw exception_utility.ErrorException("discriminator must contain propertyName and mapping properties"); } classValidator.registerDecorator({ constraints: [discriminatorConfig], name: "must-match-one-of-schemas", options: validationOptions, propertyName: propertyKey, target: target.constructor, validator: exports.MustMatchOneOfSchemasConstraint, }); }; } exports.MustMatchOneOfSchemasValidator = MustMatchOneOfSchemasValidator; //# sourceMappingURL=must-match-one-of-schemas.validator.js.map