Package Exports
- @bernierllc/csv-validator
- @bernierllc/csv-validator/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bernierllc/csv-validator) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@bernierllc/csv-validator
Atomic CSV validation utilities with type checking and custom rules.
Features
- Type Validation: Validate data against common types (string, number, email, phone, URL, date, boolean, select)
- Custom Validators: Create custom validation functions for complex business rules
- Business Rules: Define cross-field validation rules with priority
- Error Analysis: Get detailed statistics and suggestions for bulk fixes
- Type Conversion: Convert string values to appropriate types
- Zero Dependencies: Pure TypeScript with no external dependencies
Installation
npm install @bernierllc/csv-validatorQuick Start
import { validateImportData, validators, ValidationField } from '@bernierllc/csv-validator';
// Define your validation fields
const fields: ValidationField[] = [
{
key: 'name',
label: 'Name',
type: 'string',
required: true
},
{
key: 'email',
label: 'Email',
type: 'email',
required: false
},
{
key: 'age',
label: 'Age',
type: 'integer',
required: false,
validation: { min: 0, max: 120 }
}
];
// Validate your data
const rows = [
{ name: 'John Doe', email: 'john@example.com', age: '30' },
{ name: '', email: 'invalid-email', age: '150' }
];
const validatedRows = validateImportData(rows, fields);
console.log(validatedRows[0].isValid); // true
console.log(validatedRows[1].isValid); // false
console.log(validatedRows[1].errors); // Array of validation errorsAPI Reference
Core Functions
validateImportData(rows, fields, customValidators?, businessRules?)
Validates an array of data rows against field definitions.
const validatedRows = validateImportData(
transformedRows,
fields,
customValidators,
businessRules
);validateField(value, type, validation?, rowData?)
Validates a single field value.
const result = validateField('test@example.com', 'email');
// { isValid: true }validateRequired(value)
Checks if a required field has a value.
const result = validateRequired('');
// { isValid: false, error: 'This field is required' }Field Types
string- Text validation with optional length constraintsnumber- Numeric validation with optional min/maxinteger- Whole number validationboolean- Boolean value validation (true/false, yes/no, 1/0)email- Email format validationphone- Phone number validationurl- URL format validationdate- Date validation with optional formatselect- Enum value validationmultiselect- Multiple enum valuescustom- Custom validation function
Validation Rules
const validation = {
min: 1, // Minimum value/length
max: 100, // Maximum value/length
pattern: '^[A-Z]+$', // Regex pattern
enum: ['A', 'B', 'C'], // Allowed values
dateFormat: 'YYYY-MM-DD', // Date format
custom: (value, row) => ({ // Custom validation
isValid: value.length > 0,
error: 'Custom error message'
})
};Custom Validators
const customValidators: CustomValidator[] = [
{
name: 'nameLength',
fields: ['name'],
validate: (data) => ({
isValid: data.name.length >= 3,
error: 'Name must be at least 3 characters'
})
}
];Business Rules
const businessRules: BusinessRule[] = [
{
name: 'adultEmail',
description: 'Adults must have email',
fields: ['age', 'email'],
validate: (data) => ({
isValid: data.age < 18 || data.email,
error: 'Adults must provide an email address'
}),
priority: 1
}
];Error Analysis
getValidationStats(rows)
Get comprehensive validation statistics.
const stats = getValidationStats(validatedRows);
// {
// total: 100,
// valid: 85,
// invalid: 15,
// errorBreakdown: { required: 5, format: 10 },
// commonErrors: [...]
// }groupErrorsByField(rows)
Group errors by field name.
const grouped = groupErrorsByField(validatedRows);
// { name: [...], email: [...], age: [...] }suggestBulkFixes(rows)
Get suggestions for bulk error fixes.
const suggestions = suggestBulkFixes(validatedRows);
// [
// {
// field: 'email',
// error: 'Invalid email format',
// suggestion: 'user@example.com',
// affectedRows: [1, 2, 3],
// confidence: 85
// }
// ]Type Conversion
convertFieldValue(value, type)
Convert string values to appropriate types.
convertFieldValue('123', 'number'); // 123
convertFieldValue('true', 'boolean'); // true
convertFieldValue('a,b,c', 'multiselect'); // ['a', 'b', 'c']Built-in Validators
Email Validator
validators.email('test@example.com'); // { isValid: true }
validators.email('invalid'); // { isValid: false, error: 'Invalid email format', suggestion: 'invalid@example.com' }Phone Validator
validators.phone('1234567890'); // { isValid: true, suggestion: '(123) 456-7890' }
validators.phone('123'); // { isValid: false, error: 'Phone number must be 10 or 11 digits' }URL Validator
validators.url('https://example.com'); // { isValid: true }
validators.url('example.com'); // { isValid: true }
validators.url('not-a-url'); // { isValid: false, error: 'Invalid URL format', suggestion: 'https://not-a-url' }Number Validator
validators.number('123.45'); // { isValid: true }
validators.number('123.45', { min: 100 }); // { isValid: false, error: 'Must be at least 100' }Date Validator
validators.date('2023-01-01'); // { isValid: true }
validators.date('2023-01-01', { dateFormat: 'YYYY-MM-DD' }); // { isValid: true }
validators.date('invalid'); // { isValid: false, error: 'Invalid date format' }Error Types
required- Missing required fieldformat- Invalid format (email, phone, URL, date)type- Invalid data typerange- Value outside allowed rangeenum- Value not in allowed listcustom- Custom validation failedbusiness- Business rule violation
Examples
Basic Validation
import { validateImportData, ValidationField } from '@bernierllc/csv-validator';
const fields: ValidationField[] = [
{ key: 'name', label: 'Name', type: 'string', required: true },
{ key: 'email', label: 'Email', type: 'email', required: false },
{ key: 'age', label: 'Age', type: 'integer', required: false, validation: { min: 0, max: 120 } }
];
const data = [
{ name: 'John', email: 'john@example.com', age: '30' },
{ name: '', email: 'invalid', age: '150' }
];
const results = validateImportData(data, fields);Custom Validation
const customValidators = [
{
name: 'uniqueEmail',
fields: ['email'],
validate: (data) => {
// Check if email is unique in database
const isUnique = checkEmailUnique(data.email);
return {
isValid: isUnique,
error: isUnique ? undefined : 'Email already exists'
};
}
}
];
const results = validateImportData(data, fields, customValidators);Business Rules
const businessRules = [
{
name: 'adultConsent',
description: 'Adults must provide consent',
fields: ['age', 'consent'],
validate: (data) => ({
isValid: data.age < 18 || data.consent === 'yes',
error: 'Adults must provide consent'
}),
priority: 1
}
];
const results = validateImportData(data, fields, undefined, businessRules);Error Analysis
import { getValidationStats, suggestBulkFixes } from '@bernierllc/csv-validator';
const stats = getValidationStats(results);
console.log(`Valid: ${stats.valid}/${stats.total}`);
const suggestions = suggestBulkFixes(results);
suggestions.forEach(suggestion => {
console.log(`Fix ${suggestion.field}: ${suggestion.suggestion} (${suggestion.confidence}% confidence)`);
});License
ISC - See LICENSE file for details.
Contributing
This package is part of the Bernier LLC tools suite. Please refer to the main repository for contribution guidelines.