feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
// factories/error_reporter.ts
var ValidationError = class extends Error {
};
var ErrorReporterFactory = class {
create() {
const reporter = {
messages: [],
hasErrors: false,
report(message) {
this.hasErrors = true;
this.messages.push(message);
},
createError() {
const error = new ValidationError("Validation failure");
error.messages = this.messages;
return error;
}
};
return reporter;
}
};
// factories/messages_provider.ts
var MessagesProviderFactory = class {
create() {
const provider = {
getMessage(defaultMessage) {
return defaultMessage;
}
};
return provider;
}
};
export {
ErrorReporterFactory,
MessagesProviderFactory
};

View File

@@ -0,0 +1,2 @@
export { Compiler } from './src/compiler/main.js';
export { refsBuilder } from './src/refs_builder.js';

51
frontend/node_modules/@vinejs/compiler/build/index.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
import {
Compiler
} from "./chunk-K5F7IOJS.js";
// src/refs_builder.ts
function refsBuilder() {
let counter = 0;
const refs = {};
return {
toJSON() {
return refs;
},
/**
* Track a value inside refs
*/
track(value) {
counter++;
const ref = `ref://${counter}`;
refs[ref] = value;
return ref;
},
/**
* Track a validation inside refs
*/
trackValidation(validation) {
return this.track(validation);
},
/**
* Track input value parser inside refs
*/
trackParser(fn) {
return this.track(fn);
},
/**
* Track output value transformer inside refs
*/
trackTransformer(fn) {
return this.track(fn);
},
/**
* Track a conditional inside refs
*/
trackConditional(fn) {
return this.track(fn);
}
};
}
export {
Compiler,
refsBuilder
};

View File

@@ -0,0 +1,26 @@
/**
* Compiler buffer to collect JS fragments in memory
*/
export declare class CompilerBuffer {
#private;
/**
* The character used to create a new line
*/
newLine: string;
/**
* Write statement ot the output
*/
writeStatement(statement: string): void;
/**
* Creates a child buffer
*/
child(): CompilerBuffer;
/**
* Returns the buffer contents as string
*/
toString(): string;
/**
* Flush in-memory string
*/
flush(): void;
}

View File

@@ -0,0 +1,2 @@
import type { CompilerField, CompilerParent } from '../../types.js';
export declare function createArrayField(parent: CompilerParent): CompilerField;

View File

@@ -0,0 +1,2 @@
import type { CompilerField, FieldNode, CompilerParent } from '../../types.js';
export declare function createObjectField(node: Pick<FieldNode, 'fieldName' | 'propertyName'>, variablesCounter: number, parent: CompilerParent): CompilerField;

View File

@@ -0,0 +1,2 @@
import type { CompilerField, CompilerParent } from '../../types.js';
export declare function createRecordField(parent: CompilerParent): CompilerField;

View File

@@ -0,0 +1,2 @@
import type { CompilerField, CompilerParent } from '../../types.js';
export declare function createRootField(parent: CompilerParent): CompilerField;

View File

@@ -0,0 +1,2 @@
import type { CompilerField, FieldNode, CompilerParent } from '../../types.js';
export declare function createTupleField(node: Pick<FieldNode, 'fieldName' | 'propertyName'>, parent: CompilerParent): CompilerField;

View File

@@ -0,0 +1,28 @@
import { CompilerBuffer } from './buffer.js';
import type { Refs, RootNode, CompilerField, CompilerNodes, CompilerParent, CompilerOptions, ErrorReporterContract, MessagesProviderContact } from '../types.js';
/**
* Compiler is used to compile an array of schema nodes into a re-usable
* JavaScript.
*/
export declare class Compiler {
#private;
/**
* Variables counter is used to generate unique variable
* names with a counter suffix.
*/
variablesCounter: number;
constructor(rootNode: RootNode, options?: CompilerOptions);
/**
* Converts a node to a field. Optionally accepts a parent node to create
* a field for a specific parent type.
*/
createFieldFor(node: CompilerNodes, parent: CompilerParent): CompilerField;
/**
* Compiles a given compiler node
*/
compileNode(node: CompilerNodes, buffer: CompilerBuffer, parent: CompilerParent, parentField?: CompilerField): void;
/**
* Compile schema nodes to an async function
*/
compile(): (data: any, meta: Record<string, any>, refs: Refs, messagesProvider: MessagesProviderContact, errorReporter: ErrorReporterContract) => Promise<Record<string, any>>;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerParent, ArrayNode } from '../../types.js';
/**
* Compiles an array schema node to JS string output.
*/
export declare class ArrayNodeCompiler extends BaseNode {
#private;
constructor(node: ArrayNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,9 @@
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerNodes, CompilerParent } from '../../types.js';
export declare abstract class BaseNode {
#private;
protected field: CompilerField;
constructor(node: CompilerNodes, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
protected defineField(buffer: CompilerBuffer): void;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { LiteralNode, CompilerParent, CompilerField } from '../../types.js';
/**
* Compiles a literal schema node to JS string output.
*/
export declare class LiteralNodeCompiler extends BaseNode {
#private;
constructor(node: LiteralNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerParent, ObjectNode } from '../../types.js';
/**
* Compiles an object schema node to JS string output.
*/
export declare class ObjectNodeCompiler extends BaseNode {
#private;
constructor(node: ObjectNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerParent, RecordNode } from '../../types.js';
/**
* Compiles a record schema node to JS string output.
*/
export declare class RecordNodeCompiler extends BaseNode {
#private;
constructor(node: RecordNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerParent, TupleNode } from '../../types.js';
/**
* Compiles a tuple schema node to JS string output.
*/
export declare class TupleNodeCompiler extends BaseNode {
#private;
constructor(node: TupleNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,12 @@
import { BaseNode } from './base.js';
import type { Compiler } from '../main.js';
import type { CompilerBuffer } from '../buffer.js';
import type { CompilerField, CompilerParent, UnionNode } from '../../types.js';
/**
* Compiles a union schema node to JS string output.
*/
export declare class UnionNodeCompiler extends BaseNode {
#private;
constructor(node: UnionNode, buffer: CompilerBuffer, compiler: Compiler, parent: CompilerParent, parentField?: CompilerField);
compile(): void;
}

View File

@@ -0,0 +1,4 @@
/**
* Converts the value to a valid JavaScript variable name
*/
export declare function toVariableName(value: string): string;

View File

@@ -0,0 +1,5 @@
import type { RefsStore } from './types.js';
/**
* Creates a refs store for parsing the schema
*/
export declare function refsBuilder(): RefsStore;

View File

@@ -0,0 +1,9 @@
type ArrayGuardOptions = {
variableName: string;
guardedCodeSnippet: string;
};
/**
* Returns JS fragment to wrap code inside an array conditional
*/
export declare function defineArrayGuard({ variableName, guardedCodeSnippet }: ArrayGuardOptions): string;
export {};

View File

@@ -0,0 +1,13 @@
/**
* Options accepts by the output script
*/
type OutputOptions = {
variableName: string;
outputExpression: string;
outputValueExpression: string;
};
/**
* Returns JS fragment for writing the initial output for an array
*/
export declare function defineArrayInitialOutput({ variableName, outputExpression, outputValueExpression, }: OutputOptions): string;
export {};

View File

@@ -0,0 +1,13 @@
/**
* Options accepts by the loop script
*/
type ArrayLoopOptions = {
variableName: string;
loopCodeSnippet: string;
startingIndex?: number;
};
/**
* Returns JS fragment for wrapping code inside an array loop
*/
export declare function defineArrayLoop({ variableName, loopCodeSnippet, startingIndex, }: ArrayLoopOptions): string;
export {};

View File

@@ -0,0 +1,8 @@
type FieldOptions = {
variableName: string;
};
/**
* Returns JS fragment for defining the array variables
*/
export declare function defineArrayVariables({ variableName }: FieldOptions): string;
export {};

View File

@@ -0,0 +1,11 @@
type ConditionalGuardOptions = {
variableName: string;
conditionalFnRefId: string;
guardedCodeSnippet: string;
conditional: 'if' | 'else if';
};
/**
* Returns JS fragment to wrap code inside a conditional guard
*/
export declare function defineConditionalGuard({ conditional, variableName, conditionalFnRefId, guardedCodeSnippet, }: ConditionalGuardOptions): string;
export {};

View File

@@ -0,0 +1,9 @@
type ConditionalGuardOptions = {
variableName: string;
conditionalFnRefId: string;
};
/**
* Returns JS fragment to invoke a function inside else block
*/
export declare function defineElseCondition({ variableName, conditionalFnRefId }: ConditionalGuardOptions): string;
export {};

View File

@@ -0,0 +1,6 @@
import { CompilerOptions } from '../types.js';
/**
* Returns JS fragment for inline error messages for errors raised
* by the compiler.
*/
export declare function defineInlineErrorMessages(messages: Required<Exclude<CompilerOptions['messages'], undefined>>): string;

View File

@@ -0,0 +1,7 @@
/**
* Returns JS fragment for inline function needed by the
* validation runtime code.
*/
export declare function defineInlineFunctions(options: {
convertEmptyStringsToNull: boolean;
}): string;

View File

@@ -0,0 +1,10 @@
type FieldOptions = {
variableName: string;
isOptional: boolean;
allowNull: boolean;
};
/**
* Returns JS fragment to validate a field's value for existence.
*/
export declare function defineFieldExistenceValidations({ allowNull, isOptional, variableName, }: FieldOptions): string;
export {};

View File

@@ -0,0 +1,10 @@
type ObjectGuardOptions = {
variableName: string;
bail: boolean;
guardedCodeSnippet: string;
};
/**
* Returns JS fragment to wrap code inside a valid guard
*/
export declare function defineIsValidGuard({ variableName, bail, guardedCodeSnippet }: ObjectGuardOptions): string;
export {};

View File

@@ -0,0 +1,16 @@
import { RefIdentifier } from '../../types.js';
/**
* Options accepts by the output script
*/
type OutputOptions = {
outputExpression: string;
variableName: string;
allowNull: boolean;
transformFnRefId?: RefIdentifier;
conditional?: 'if' | 'else if';
};
/**
* Returns JS fragment for writing the null value to the output.
*/
export declare function defineFieldNullOutput({ allowNull, conditional, variableName, outputExpression, transformFnRefId, }: OutputOptions): string;
export {};

View File

@@ -0,0 +1,24 @@
import { ValidationNode } from '../../types.js';
/**
* Options accepts by the validation script
*/
type ValidationOptions = {
bail: boolean;
variableName: string;
validations: ValidationNode[];
/**
* Drop missing conditional check regardless of whether
* rule is implicit or not
*/
dropMissingCheck: boolean;
/**
* The expression to use for performing the existence check.
* Defaults to "item.isDefined"
*/
existenceCheckExpression?: string;
};
/**
* Returns JS fragment for executing validations for a given field.
*/
export declare function defineFieldValidations({ bail, validations, variableName, dropMissingCheck, existenceCheckExpression, }: ValidationOptions): string;
export {};

View File

@@ -0,0 +1,14 @@
import { RefIdentifier } from '../../types.js';
/**
* Options accepts by the output script
*/
type OutputOptions = {
outputExpression: string;
variableName: string;
transformFnRefId?: RefIdentifier;
};
/**
* Returns JS fragment for writing the validated value to the output.
*/
export declare function defineFieldValueOutput({ variableName, outputExpression, transformFnRefId, }: OutputOptions): string;
export {};

View File

@@ -0,0 +1,18 @@
import { RefIdentifier } from '../../types.js';
type FieldOptions = {
parentExpression: string;
variableName: string;
valueExpression: string;
fieldNameExpression: string;
wildCardPath: string;
parentValueExpression: string;
isArrayMember: boolean;
parseFnRefId?: RefIdentifier;
};
/**
* Returns JS fragment for defining the field variables. It includes, the field
* value variable, context variable, and a boolean to know if the field
* exists.
*/
export declare function defineFieldVariables({ parseFnRefId, variableName, wildCardPath, isArrayMember, valueExpression, parentExpression, fieldNameExpression, parentValueExpression, }: FieldOptions): string;
export {};

View File

@@ -0,0 +1,9 @@
type ObjectGuardOptions = {
variableName: string;
guardedCodeSnippet: string;
};
/**
* Returns JS fragment to wrap code inside an object conditional
*/
export declare function defineObjectGuard({ variableName, guardedCodeSnippet }: ObjectGuardOptions): string;
export {};

View File

@@ -0,0 +1,13 @@
/**
* Options accepts by the output script
*/
type OutputOptions = {
variableName: string;
outputExpression: string;
outputValueExpression: string;
};
/**
* Returns JS fragment for writing the initial output for an object
*/
export declare function defineObjectInitialOutput({ variableName, outputExpression, outputValueExpression, }: OutputOptions): string;
export {};

View File

@@ -0,0 +1,14 @@
/**
* Options accepts by the output script
*/
type MovePropertiesOptions = {
variableName: string;
allowUnknownProperties: boolean;
fieldsToIgnore: string[];
};
/**
* Returns JS fragment for moving properties from the source
* to destination
*/
export declare function defineMoveProperties({ variableName, fieldsToIgnore, allowUnknownProperties, }: MovePropertiesOptions): string;
export {};

View File

@@ -0,0 +1,8 @@
type FieldOptions = {
variableName: string;
};
/**
* Returns JS fragment for defining the object variables
*/
export declare function defineObjectVariables({ variableName }: FieldOptions): string;
export {};

View File

@@ -0,0 +1,12 @@
/**
* Options accepts by the loop script
*/
type RecordLoopOptions = {
variableName: string;
loopCodeSnippet: string;
};
/**
* Returns JS fragment for wrapping code inside an record loop
*/
export declare function defineRecordLoop({ variableName, loopCodeSnippet }: RecordLoopOptions): string;
export {};

View File

@@ -0,0 +1,4 @@
/**
* Returns JS fragment to report errors
*/
export declare function reportErrors(): string;

View File

@@ -0,0 +1,11 @@
import type { RefIdentifier } from '../../types.js';
type FieldOptions = {
variableName: string;
parseFnRefId?: RefIdentifier;
};
/**
* Returns JS fragment to call the parse function on the union conditional
* schema.
*/
export declare function callParseFunction({ parseFnRefId, variableName }: FieldOptions): string;
export {};

View File

@@ -0,0 +1,427 @@
/**
* Represenation of a ref id
*/
export type RefIdentifier = `ref://${number}`;
/**
* Allowed values for refs
*/
export type Refs = Record<RefIdentifier, ValidationRule | TransformFn<any, any> | ParseFn | ConditionalFn<any>>;
/**
* Refs store to track runtime values as refs with
* type safety
*/
export type RefsStore = {
toJSON(): Refs;
/**
* Track a value inside refs
*/
track(value: Refs[keyof Refs]): RefIdentifier;
/**
* Track a validation inside refs
*/
trackValidation(validation: ValidationRule): RefIdentifier;
/**
* Track input value parser inside refs
*/
trackParser(fn: ParseFn): RefIdentifier;
/**
* Track output value transformer inside refs
*/
trackTransformer(fn: TransformFn<any, any>): RefIdentifier;
/**
* Track a conditional inside refs
*/
trackConditional(fn: ConditionalFn<any>): RefIdentifier;
};
/**
* The context shared with the entire validation pipeline.
* Each field gets its own context object.
*/
export type FieldContext = {
/**
* Field value
*/
value: unknown;
/**
* The data property is the top-level object under validation.
*/
data: any;
/**
* Shared metadata across the entire validation lifecycle. It can be
* used to pass data between validation rules
*/
meta: Record<string, any>;
/**
* Mutate the value of field under validation.
*/
mutate(newValue: any, field: FieldContext): void;
/**
* Report error to the error reporter
*/
report: ErrorReporterContract['report'];
/**
* Is this field valid. Default: true
*/
isValid: boolean;
/**
* Is this field has value defined.
*/
isDefined: boolean;
/**
* Returns the nested path to the field. The parts
* are joined by a dot notation.
*/
getFieldPath(): string;
/**
* Wildcard path for the field. The value is a nested
* pointer to the field under validation.
*
* In case of arrays, the `*` wildcard is used.
*/
wildCardPath: string;
/**
* The parent property is the parent of the field. It could be an
* array or an object.
*/
parent: any;
/**
* Name of the field under validation. In case of an array, the field
* name will be a number
*/
name: string | number;
/**
* Is this field an array member
*/
isArrayMember: boolean;
};
/**
* The shape of validation rule picked from the
* refs
*/
export type ValidationRule = {
/**
* Performs validation
*/
validator(value: unknown, options: any, field: FieldContext): any;
/**
* Options to pass
*/
options?: any;
};
/**
* The shape of parse function picked from the refs
*/
export type ParseFn = (value: unknown, ctx: Pick<FieldContext, 'data' | 'parent' | 'meta'>) => any;
/**
* The shape of transform function picked from the refs
*/
export type TransformFn<Input, Output> = (value: Input, field: FieldContext) => Output;
/**
* The shape of conditional function used for narrowing down unions.
*/
export type ConditionalFn<Input> = (value: Input, field: FieldContext) => boolean;
/**
* Shape of a validation rule accepted by the compiler
*/
export type ValidationNode = {
/**
* Rule implementation function id.
*/
ruleFnId: RefIdentifier;
/**
* Is this an async rule. This flag helps creating an optimized output
*/
isAsync: boolean;
/**
* The rules are skipped when the value of a field is "null" or "undefined".
* Unless, the "implicit" flag is true
*/
implicit: boolean;
};
/**
* Shape of field inside a schema.
*/
export type FieldNode = {
/**
* Should the validation cycle stop after the first error.
* Defaults to true
*/
bail: boolean;
/**
* Field name refers to the name of the field under the data
* object
*/
fieldName: string;
/**
* Name of the output property. This allows validating a field with a different name, but
* storing its output value with a different name.
*/
propertyName: string;
/**
* Are we expecting this field to be undefined or null
*/
isOptional: boolean;
/**
* Are we expecting this field to be null
*/
allowNull: boolean;
/**
* The reference id for the parse method. Parse method is called to mutate the
* initial value. The function is executed always even when value is undefined
* or null.
*
* @see [[ParseFn]]
*/
parseFnId?: RefIdentifier;
/**
* A set of validations to apply on the field
*/
validations: ValidationNode[];
};
/**
* Shape of a single field accepted by the compiler
*/
export type LiteralNode = FieldNode & {
type: 'literal';
/**
* Transform the output value of a field. The output of this method is the
* final source of truth. The function is executed at the time of writing the
* value to the output.
*/
transformFnId?: RefIdentifier;
};
/**
* Shape of the object node accepted by the compiler
*/
export type ObjectNode = FieldNode & {
type: 'object';
/**
* Whether or not to allow unknown properties. When disabled, the
* output object will have only validated properties.
*
* Default: false
*/
allowUnknownProperties: boolean;
/**
* Object known properties
*/
properties: CompilerNodes[];
/**
* A collection of object groups to merge into the main object.
* Each group is a collection of conditionals with a sub-object
* inside them.
*/
groups: ObjectGroupNode[];
};
/**
* A compiler object group produces a single sub object based upon
* the defined conditions.
*/
export type ObjectGroupNode = {
type: 'group';
/**
* An optional function to call when all of the conditions
* are false.
*/
elseConditionalFnRefId?: RefIdentifier;
/**
* Conditions to evaluate
*/
conditions: {
/**
* The conditional function reference id
*/
conditionalFnRefId: RefIdentifier;
/**
* Schema to use when condition is true
*/
schema: {
type: 'sub_object';
/**
* Object known properties
*/
properties: CompilerNodes[];
/**
* A collection of object groups to merge into the main object.
* Each group is a collection of conditionals with a sub-object
* inside them.
*/
groups: ObjectGroupNode[];
};
}[];
};
/**
* Shape of the tuple node accepted by the compiler
*/
export type TupleNode = FieldNode & {
type: 'tuple';
/**
* Whether or not to allow unknown properties. When disabled, the
* output array will have only validated properties.
*
* Default: false
*/
allowUnknownProperties: boolean;
/**
* Tuple known properties
*/
properties: CompilerNodes[];
};
/**
* Shape of the record node accepted by the compiler
*/
export type RecordNode = FieldNode & {
type: 'record';
/**
* Captures object elements
*/
each: CompilerNodes;
};
/**
* Shape of the array node accepted by the compiler
*/
export type ArrayNode = FieldNode & {
type: 'array';
/**
* Captures array elements
*/
each: CompilerNodes;
};
/**
* Shape of the union node accepted by the compiler. A union is a combination
* of conditionals.
*/
export type UnionNode = {
type: 'union';
/**
* Field name refers to the name of the field under the data
* object
*/
fieldName: string;
/**
* Name of the output property. This allows validating a field with a different name, but
* storing its value with a different name.
*/
propertyName: string;
/**
* An optional function to call when all of the conditions
* are false.
*/
elseConditionalFnRefId?: RefIdentifier;
/**
* Conditions to evaluate
*/
conditions: {
/**
* The conditional function reference id
*/
conditionalFnRefId: RefIdentifier;
/**
* Schema to use when condition is true
*/
schema: CompilerNodes;
}[];
};
/**
* The root of the schema
*/
export type RootNode = {
type: 'root';
/**
* Schema at the root level
*/
schema: CompilerNodes;
};
/**
* Known tree nodes accepted by the compiler
*/
export type CompilerNodes = LiteralNode | ObjectNode | ArrayNode | UnionNode | RecordNode | TupleNode;
/**
* Properties of a parent node as the compiler loops through the
* rules tree and constructs JS code.
*/
export type CompilerParent = {
type: 'array' | 'object' | 'tuple' | 'record' | 'root';
/**
* Wildcard path to the field
*/
wildCardPath: string;
/**
* Name of the variable for the parent property. The variable name
* is used to lookup values from the parent
*/
variableName: string;
/**
* Nested path to the parent field. If the parent is nested inside
* an object or array.
*/
fieldPathExpression: string;
/**
* The expression for the output value.
*/
outputExpression: string;
};
/**
* Compiler field is used to compute the variable and property
* names for the JS output.
*/
export type CompilerField = {
parentExpression: string;
parentValueExpression: string;
fieldNameExpression: string;
fieldPathExpression: string;
variableName: string;
wildCardPath: string;
valueExpression: string;
outputExpression: string;
isArrayMember: boolean;
};
/**
* The error reporter is used for reporting validation
* errors.
*/
export interface ErrorReporterContract {
/**
* A boolean to known if there are one or more
* errors.
*/
hasErrors: boolean;
/**
* Creates an instance of an exception to throw
*/
createError(): Error;
/**
* Report error for a field
*/
report(message: string, rule: string, field: FieldContext, args?: Record<string, any>): any;
}
/**
* Messages provider is used to resolve validation error messages
* during validation.
*/
export interface MessagesProviderContact {
/**
* Returns a validation message for a given field + rule. The args
* may get passed by a validation rule to share additional context.
*/
getMessage(defaultMessage: string, rule: string, field: FieldContext, args?: Record<string, any>): string;
}
/**
* Options accepted by the compiler
*/
export type CompilerOptions = {
/**
* Convert empty string values to null for sake of
* normalization
*/
convertEmptyStringsToNull: boolean;
/**
* Provide messages to use for required, object and
* array validations.
*/
messages?: Partial<{
required: string;
object: string;
array: string;
}>;
};

View File