import { SimpleErrorReporter, SimpleMessagesProvider, helpers } from "../chunk-YXNUTVGP.js"; import "../chunk-MLKGABMK.js"; // factories/field.ts var FieldFactory = class { create(fieldName, value, messagesProvider, errorReporter) { const reporter = errorReporter || new SimpleErrorReporter(); const provider = messagesProvider || new SimpleMessagesProvider({}, {}); return { value, isArrayMember: false, parent: { [fieldName]: value }, data: { [fieldName]: value }, name: fieldName, wildCardPath: fieldName, getFieldPath() { return fieldName; }, isDefined: helpers.exists(value), isValid: true, meta: {}, mutate(newValue) { this.value = newValue; this.isDefined = helpers.exists(newValue); return this; }, report(message, rule, context, args) { this.isValid = false; reporter.report(provider.getMessage(message, rule, context, args), rule, context, args); } }; } }; // factories/validator.ts import { AssertionError, deepEqual } from "node:assert"; var ValidationResult = class { #outputValue; #reporter; constructor(outputValue, reporter) { this.#outputValue = outputValue; this.#reporter = reporter; } /** * Creates an assertion error instance */ #assertionError(options) { const assertion = new AssertionError(options); Object.defineProperty(assertion, "showDiff", { value: true }); return assertion; } /** * Returns the validation result output */ getOutput() { return this.#outputValue; } /** * Returns an array of errors reported to the * error reporter */ getErrors() { return this.#reporter.errors; } /** * Assert one or more validation errors have occurred */ assertSucceeded() { if (this.#reporter.hasErrors) { const errorsCount = this.#reporter.errors.length; throw this.#assertionError({ message: `Expected validation to pass. Instead failed with "${errorsCount} error(s)"`, operator: "strictEqual", stackStartFn: this.assertSucceeded }); } } /** * Assert the output value of validation. The output value is * same as the input value, unless "mutate" method is called */ assertOutput(expectedOutput) { deepEqual(this.#outputValue, expectedOutput); } /** * Assert one or more validation errors have occurred */ assertFailed() { if (!this.#reporter.hasErrors) { throw this.#assertionError({ message: `Expected validation to report one or more errors`, operator: "strictEqual", stackStartFn: this.assertFailed }); } } /** * Assert the number of errors have occurred */ assertErrorsCount(count) { const errorsCount = this.#reporter.errors.length; if (errorsCount !== count) { throw this.#assertionError({ message: `Expected validation to report "${count}" errors. Received "${errorsCount}"`, expected: count, actual: errorsCount, operator: "strictEqual", stackStartFn: this.assertErrorsCount, showDiff: true }); } } /** * Assert error messages to include a given error message */ assertError(message) { const messages = this.#reporter.errors.map((e) => e.message); if (!messages.includes(message)) { throw this.#assertionError({ message: `Expected validation errors to include "${message}" message`, expected: [message], actual: messages, operator: "includes", stackStartFn: this.assertError, showDiff: true }); } } }; var ValidatorFactory = class _ValidatorFactory { #field; #bail; constructor(field, bail) { this.#field = field; this.#bail = bail; } /** * Creates an instance of the error reporter required * to report errors. */ #getReporter() { return new SimpleErrorReporter(); } /** * Define field context for the validation */ withContext(field) { return new _ValidatorFactory(field, this.#bail); } /** * Toggle bail mode for the validation */ bail(state) { return new _ValidatorFactory(this.#field, state); } /** * Executes a validation against the provided value */ execute(validation, value) { const errorReporter = this.#getReporter(); const bail = this.#bail === false ? false : true; const field = { ...new FieldFactory().create("dummy", value, void 0, errorReporter), ...this.#field }; const validations = Array.isArray(validation) ? validation : [validation]; for (let one of validations) { if (one.rule.isAsync) { throw new Error( `Cannot execute async rule "${one.rule.validator.name}". Use "validator.executeAsync" instead` ); } if ((field.isDefined || one.rule.implicit) && (field.isValid || !bail)) { one.rule.validator(field.value, one.options, field); } } return new ValidationResult(field.value, errorReporter); } /** * Executes an async validation against the provided * value */ async executeAsync(validation, value) { const errorReporter = this.#getReporter(); const bail = this.#bail === false ? false : true; const field = { ...new FieldFactory().create("dummy", value, void 0, errorReporter), ...this.#field }; const validations = Array.isArray(validation) ? validation : [validation]; for (let one of validations) { if ((field.isDefined || one.rule.implicit) && (field.isValid || !bail)) { await one.rule.validator(field.value, one.options, field); } } return new ValidationResult(field.value, errorReporter); } }; // factories/main.ts var validator = new ValidatorFactory(); var fieldContext = new FieldFactory(); export { fieldContext, validator };