/** * Pre-save operations type definitions * * Pre-save operations are transformations applied to data before it's written * to the database. They support encryption, hashing, masking, validation, * sanitization, and custom transformations. */ /** * Types of pre-save operations available */ export declare enum PreSaveOperationType { /** Encrypt field value using AES-256 */ ENCRYPT = "encrypt", /** Hash field value (one-way, e.g., for passwords) */ HASH = "hash", /** Mask sensitive data (e.g., credit card: **** **** **** 1234) */ MASK = "mask", /** Trim whitespace from string */ TRIM = "trim", /** Convert to lowercase */ LOWERCASE = "lowercase", /** Convert to uppercase */ UPPERCASE = "uppercase", /** Sanitize HTML/script tags */ SANITIZE = "sanitize", /** Validate and throw if invalid */ VALIDATE = "validate", /** Transform with custom function */ TRANSFORM = "transform", /** Generate UUID */ UUID = "uuid", /** Generate slug from another field */ SLUG = "slug", /** Set to current timestamp */ TIMESTAMP = "timestamp", /** Round number to specified decimals */ ROUND = "round", /** Clamp number to min/max range */ CLAMP = "clamp", /** Truncate string to max length */ TRUNCATE = "truncate", /** Default value if null/undefined */ DEFAULT = "default", /** Normalize phone number */ NORMALIZE_PHONE = "normalizePhone", /** Normalize email (lowercase, trim) */ NORMALIZE_EMAIL = "normalizeEmail", /** Parse JSON string to object */ PARSE_JSON = "parseJson", /** Stringify object to JSON */ STRINGIFY_JSON = "stringifyJson", /** Compute derived field from other fields */ COMPUTE = "compute" } /** * Base options for all pre-save operations */ export interface IPreSaveBaseOptions { /** Field name to apply operation to */ field: string; /** Operation type */ type: PreSaveOperationType; /** Skip operation if field is null/undefined */ skipIfNull?: boolean; /** Skip operation if field is empty string */ skipIfEmpty?: boolean; /** Condition function - only apply if returns true */ condition?: (data: Record) => boolean; } /** * Encryption options */ export interface IPreSaveEncryptOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.ENCRYPT; /** Encryption algorithm (default: aes-256-gcm) */ algorithm?: 'aes-256-gcm' | 'aes-256-cbc' | 'aes-128-gcm'; /** Encryption key (or use default from config) */ key?: string; /** Store IV alongside encrypted data (required for decryption) */ storeIV?: boolean; /** Field to store IV in (default: `${field}_iv`) */ ivField?: string; } /** * Hash options (for passwords, etc.) */ export interface IPreSaveHashOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.HASH; /** Hash algorithm */ algorithm?: 'bcrypt' | 'argon2' | 'sha256' | 'sha512' | 'md5'; /** Salt rounds for bcrypt (default: 10) */ saltRounds?: number; /** Custom salt (if not using bcrypt) */ salt?: string; } /** * Mask options */ export interface IPreSaveMaskOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.MASK; /** Mask pattern: 'credit-card', 'ssn', 'phone', 'email', or custom */ pattern?: 'credit-card' | 'ssn' | 'phone' | 'email' | 'custom'; /** For custom pattern: character to mask with (default: '*') */ maskChar?: string; /** For custom pattern: number of characters to show at start */ showFirst?: number; /** For custom pattern: number of characters to show at end */ showLast?: number; /** Store original value in separate field */ storeOriginalIn?: string; } /** * Validation options */ export interface IPreSaveValidateOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.VALIDATE; /** Validation rules */ rules: IValidationRule[]; /** Custom error message */ errorMessage?: string; /** Throw on validation failure (default: true) */ throwOnFail?: boolean; /** Field to store validation result if not throwing */ resultField?: string; } /** * Validation rule */ export interface IValidationRule { /** Rule type */ type: 'required' | 'email' | 'url' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'enum' | 'custom' | 'type' | 'integer' | 'positive' | 'negative'; /** Value for the rule (min, max, pattern, enum values, etc.) */ value?: any; /** Custom validation function */ validator?: (value: any, data: Record) => boolean; /** Error message for this rule */ message?: string; } /** * Transform options (custom function) */ export interface IPreSaveTransformOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.TRANSFORM; /** Transformation function */ transformer: (value: any, data: Record) => any; } /** * Slug options */ export interface IPreSaveSlugOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.SLUG; /** Source field to generate slug from */ sourceField: string; /** Separator character (default: '-') */ separator?: string; /** Convert to lowercase (default: true) */ lowercase?: boolean; /** Remove special characters (default: true) */ removeSpecialChars?: boolean; /** Max length of slug */ maxLength?: number; } /** * Truncate options */ export interface IPreSaveTruncateOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.TRUNCATE; /** Maximum length */ maxLength: number; /** Suffix to add if truncated (default: '...') */ suffix?: string; /** Truncate at word boundary */ wordBoundary?: boolean; } /** * Round options */ export interface IPreSaveRoundOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.ROUND; /** Number of decimal places (default: 2) */ decimals?: number; /** Rounding mode */ mode?: 'round' | 'floor' | 'ceil'; } /** * Clamp options */ export interface IPreSaveClampOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.CLAMP; /** Minimum value */ min?: number; /** Maximum value */ max?: number; } /** * Default value options */ export interface IPreSaveDefaultOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.DEFAULT; /** Default value to use */ value: any; /** Use function to generate default */ generator?: (data: Record) => any; } /** * Compute options (derived field) */ export interface IPreSaveComputeOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.COMPUTE; /** Computation function */ compute: (data: Record) => any; /** Source fields this computation depends on */ dependsOn?: string[]; } /** * Simple operation options (no additional config needed) */ export interface IPreSaveSimpleOptions extends IPreSaveBaseOptions { type: PreSaveOperationType.TRIM | PreSaveOperationType.LOWERCASE | PreSaveOperationType.UPPERCASE | PreSaveOperationType.SANITIZE | PreSaveOperationType.UUID | PreSaveOperationType.TIMESTAMP | PreSaveOperationType.NORMALIZE_PHONE | PreSaveOperationType.NORMALIZE_EMAIL | PreSaveOperationType.PARSE_JSON | PreSaveOperationType.STRINGIFY_JSON; } /** * Union type of all pre-save operation options */ export type IPreSaveOperation = IPreSaveEncryptOptions | IPreSaveHashOptions | IPreSaveMaskOptions | IPreSaveValidateOptions | IPreSaveTransformOptions | IPreSaveSlugOptions | IPreSaveTruncateOptions | IPreSaveRoundOptions | IPreSaveClampOptions | IPreSaveDefaultOptions | IPreSaveComputeOptions | IPreSaveSimpleOptions; /** * Pre-save processor configuration */ export interface IPreSaveConfig { /** Default encryption key (can be overridden per operation) */ encryptionKey?: string; /** Default hash algorithm */ defaultHashAlgorithm?: 'bcrypt' | 'argon2' | 'sha256' | 'sha512'; /** Default bcrypt salt rounds */ defaultSaltRounds?: number; /** Whether to throw on validation errors (default: true) */ throwOnValidationError?: boolean; /** Custom sanitizer function */ sanitizer?: (value: string) => string; } /** * Pre-save processing result */ export interface IPreSaveResult { /** Processed data */ data: Record | Record[]; /** Operations that were applied */ appliedOperations: IAppliedOperation[]; /** Validation errors (if any and not throwing) */ validationErrors?: IValidationError[]; /** Whether processing was successful */ success: boolean; } /** * Applied operation record */ export interface IAppliedOperation { /** Field name */ field: string; /** Operation type */ operation: PreSaveOperationType; /** Whether operation was applied */ applied: boolean; /** Reason if skipped */ skippedReason?: string; } /** * Validation error */ export interface IValidationError { /** Field name */ field: string; /** Error message */ message: string; /** Failed rule type */ rule: string; /** Actual value */ value?: any; } /** * Pre-save operations defined at schema level * Can be stored in _ductape_schema for automatic application */ export interface ISchemaPreSaveConfig { /** Collection/table name */ collection: string; /** Operations to apply */ operations: IPreSaveOperation[]; /** Whether these operations are enabled */ enabled: boolean; /** Order of operations (lower numbers run first) */ order?: number; }