Atomic CSV parsing utilities with encoding support
npm install @bernierllc/csv-parserAtomic CSV parsing utilities with robust quote and encoding handling.
- Pure CSV Parsing: Focused on parsing CSV content without validation or business logic
- Robust Quote Handling: Properly handles quoted fields, escaped quotes, and unclosed quotes
- Flexible Formatting: Convert data back to CSV format with customizable options
- Type Safety: Full TypeScript support with strict typing
- Zero Dependencies: No external dependencies, pure Node.js/TypeScript
- Comprehensive Testing: 90%+ test coverage with extensive edge case testing
``bash`
npm install @bernierllc/csv-parser
`typescript
import { parseCSV, formatCSV } from '@bernierllc/csv-parser';
// Parse CSV content
const csv = name,age,city
"John Doe",30,"New York"
"Jane Smith",25,"Los Angeles";
const result = parseCSV(csv);
console.log(result.headers); // ['name', 'age', 'city']
console.log(result.rows); // [['John Doe', '30', 'New York'], ['Jane Smith', '25', 'Los Angeles']]
// Format data back to CSV
const data = [
['name', 'age', 'city'],
['John Doe', 30, 'New York'],
['Jane Smith', 25, 'Los Angeles']
];
const formatted = formatCSV(data);
console.log(formatted);
// name,age,city
// John Doe,30,New York
// Jane Smith,25,Los Angeles
`
#### parseCSV(csvContent, options?)
Parse CSV content into headers and rows.
`typescript`
function parseCSV(
csvContent: string,
options?: CSVParserOptions
): CSVParsedResult
Parameters:
- csvContent: The CSV content as a stringoptions
- : Optional parsing configuration
Returns:
- headers: Array of column headersrows
- : 2D array of data rowstotalRows
- : Total number of rows (including header)dataRows
- : Number of data rows (excluding header)
Example:
`typescriptname,age,city
const csv =
John Doe,30,New York
Jane Smith,25,Los Angeles;
const result = parseCSV(csv);
// result.headers = ['name', 'age', 'city']
// result.rows = [['John Doe', '30', 'New York'], ['Jane Smith', '25', 'Los Angeles']]
`
#### parseCSVLine(line, options?)
Parse a single CSV line.
`typescript`
function parseCSVLine(
line: string,
options?: CSVParserOptions
): CSVLineResult
Returns:
- fields: Array of parsed fieldsisQuoted
- : Whether the line has unclosed quotesoriginalLength
- : Original line length
Example:
`typescript`
const line = '"John Doe",30,"New York"';
const result = parseCSVLine(line);
// result.fields = ['John Doe', '30', 'New York']
// result.isQuoted = false
#### validateCSV(csvContent, options?)
Validate CSV content for common issues.
`typescript`
function validateCSV(
csvContent: string,
options?: CSVParserOptions
): CSVValidationResult
Returns:
- isValid: Whether the CSV is validerror
- : Error message if invaliderrorLine
- : Line number where error occurrederrorColumn
- : Column number where error occurrederrorType
- : Type of error
Example:
`typescriptname,age,city
const csv =
John Doe,30,New York;
const result = validateCSV(csv);
// result.isValid = true
`
#### getColumnCount(line, options?)
Get the number of columns in a CSV line.
`typescript`
function getColumnCount(
line: string,
options?: CSVParserOptions
): number
Example:
`typescript`
const count = getColumnCount('John Doe,30,New York'); // 3
#### isLineQuoted(line, options?)
Check if a CSV line is properly quoted.
`typescript`
function isLineQuoted(
line: string,
options?: CSVParserOptions
): boolean
Example:
`typescript`
const quoted = isLineQuoted('"John Doe,30,"New York"'); // true
#### formatCSVValue(value, options?)
Format a single value for CSV output.
`typescript`
function formatCSVValue(
value: any,
options?: CSVFormatOptions
): string
Example:
`typescript`
formatCSVValue('John, Doe'); // '"John, Doe"'
formatCSVValue('He said "Hello"'); // '"He said ""Hello"""'
#### formatCSVRow(values, options?)
Format an array of values as a CSV row.
`typescript`
function formatCSVRow(
values: any[],
options?: CSVFormatOptions
): string
Example:
`typescript`
const row = formatCSVRow(['John Doe', 30, 'New York']);
// 'John Doe,30,New York'
#### formatCSV(data, options?)
Format a 2D array of data as CSV content.
`typescript`
function formatCSV(
data: any[][],
options?: CSVFormatOptions
): string
Example:
`typescript
const data = [
['name', 'age', 'city'],
['John Doe', 30, 'New York'],
['Jane Smith', 25, 'Los Angeles']
];
const csv = formatCSV(data);
// name,age,city
// John Doe,30,New York
// Jane Smith,25,Los Angeles
`
#### formatCSVWithHeaders(headers, rows, options?)
Format data with headers as CSV content.
`typescript`
function formatCSVWithHeaders(
headers: string[],
rows: any[][],
options?: CSVFormatOptions
): string
Example:
`typescript
const headers = ['name', 'age', 'city'];
const rows = [
['John Doe', 30, 'New York'],
['Jane Smith', 25, 'Los Angeles']
];
const csv = formatCSVWithHeaders(headers, rows);
// name,age,city
// John Doe,30,New York
// Jane Smith,25,Los Angeles
`
#### formatCSVFromObjects(objects, options?)
Format an array of objects as CSV content.
`typescript`
function formatCSVFromObjects(
objects: Record
options?: CSVFormatOptions
): string
Example:
`typescript
const objects = [
{ name: 'John Doe', age: 30, city: 'New York' },
{ name: 'Jane Smith', age: 25, city: 'Los Angeles' }
];
const csv = formatCSVFromObjects(objects);
// name,age,city
// John Doe,30,New York
// Jane Smith,25,Los Angeles
`
#### createCSVTemplate(headers, sampleRows?, options?)
Create a CSV template with headers and optional sample data.
`typescript`
function createCSVTemplate(
headers: string[],
sampleRows?: any[][],
options?: CSVFormatOptions
): string
Example:
`typescript
const headers = ['name', 'age', 'city'];
const sampleRows = [
['John Doe', 30, 'New York'],
['Jane Smith', 25, 'Los Angeles']
];
const template = createCSVTemplate(headers, sampleRows);
// name,age,city
// John Doe,30,New York
// Jane Smith,25,Los Angeles
`
#### escapeCSVString(str, quoteChar?)
Escape a string for CSV output.
`typescript`
function escapeCSVString(
str: string,
quoteChar?: string
): string
Example:
`typescript`
escapeCSVString('Hello "World"'); // 'Hello ""World""'
#### unescapeCSVString(str, quoteChar?)
Unescape a CSV string.
`typescript`
function unescapeCSVString(
str: string,
quoteChar?: string
): string
Example:
`typescript`
unescapeCSVString('Hello ""World""'); // 'Hello "World"'
`typescript`
interface CSVParserOptions {
/* Character used to separate fields (default: ',') /
delimiter?: string;
/* Whether to trim whitespace from values (default: true) /
trim?: boolean;
/* Whether to skip empty rows (default: true) /
skipEmptyRows?: boolean;
/* Whether to preserve quotes in output (default: false) /
preserveQuotes?: boolean;
/* Character encoding of the input (default: 'utf-8') /
encoding?: string;
}
`typescript`
interface CSVFormatOptions {
/* Character used to separate fields (default: ',') /
delimiter?: string;
/* Whether to quote all fields (default: false) /
quoteAll?: boolean;
/* Whether to quote fields containing delimiter (default: true) /
quoteDelimiter?: boolean;
/* Whether to quote fields containing quotes (default: true) /
quoteQuotes?: boolean;
/* Whether to quote fields containing newlines (default: true) /
quoteNewlines?: boolean;
/* Quote character to use (default: '"') /
quoteChar?: string;
/* Line ending to use (default: '\n') /
lineEnding?: string;
}
`typescript
import { parseCSV, formatCSV } from '@bernierllc/csv-parser';
// Parse semicolon-separated values
const ssv = name;age;city
John Doe;30;New York
Jane Smith;25;Los Angeles;
const result = parseCSV(ssv, { delimiter: ';' });
// Format with custom delimiter
const formatted = formatCSV(result.rows, { delimiter: ';' });
`
`typescript
import { parseCSV, formatCSVFromObjects } from '@bernierllc/csv-parser';
// Parse complex CSV with quoted fields
const csv = name,description,address
"John ""The Rock"" Doe","Software Engineer, Senior","123 Main St, Apt 4B, New York, NY"
"Jane Smith","Product Manager","456 Oak Ave, Los Angeles, CA";
const result = parseCSV(csv);
// Convert to objects and back
const objects = result.rows.map(row => ({
name: row[0],
description: row[1],
address: row[2]
}));
const formatted = formatCSVFromObjects(objects);
`
`typescript
import { parseCSV, validateCSV } from '@bernierllc/csv-parser';
const csv = name,age,city
John Doe,30,New York
Jane Smith,25,Los Angeles,extra;
// Validate before parsing
const validation = validateCSV(csv);
if (!validation.isValid) {
console.error(CSV Error: ${validation.error});Line: ${validation.errorLine}, Column: ${validation.errorColumn}
console.error();
return;
}
// Safe to parse
const result = parseCSV(csv);
`
`typescript
import { createCSVTemplate } from '@bernierllc/csv-parser';
// Create a template for user data import
const headers = ['first_name', 'last_name', 'email', 'phone', 'department'];
const sampleRows = [
['John', 'Doe', 'john.doe@example.com', '(555) 123-4567', 'Engineering'],
['Jane', 'Smith', 'jane.smith@example.com', '(555) 987-6543', 'Marketing']
];
const template = createCSVTemplate(headers, sampleRows);
console.log(template);
// first_name,last_name,email,phone,department
// John,Doe,john.doe@example.com,(555) 123-4567,Engineering
// Jane,Smith,jane.smith@example.com,(555) 987-6543,Marketing
`
The parser provides detailed error information for common CSV issues:
- Empty files: CSV content is emptyUnclosed quote in line X
- Unclosed quotes: CSV must have at least a header row and one data row
- Missing data: Row X has Y columns, expected Z
- Mismatched columns:
The parser is optimized for performance with:
- Minimal memory allocation
- Efficient string processing
- No external dependencies
- Streaming-friendly design
Run the test suite:
`bash``
npm test
npm run test:coverage
This package follows the Bernier LLC coding standards:
- TypeScript strict mode
- Comprehensive test coverage
- Clear documentation
- Atomic, focused functionality
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license.
The client may use and modify this code only within the scope of the project it was delivered for.
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.