Skip to content

Csv

Helpers exported by @morevoice/sdk from src/lib/csv.ts.

Exported from @morevoice/sdk (source: packages/sdk-ts/src/lib/csv.ts).

interface

One rejected row. row is the spreadsheet row number (the header is row 1).

interface CsvRowProblem {
row: number;
column: string;
value: string;
reason: "empty" | "unparseable" | "invalid" | "too-short" | "too-long" | "duplicate";
/** For duplicates: the first row with the same number. */
firstRow?: number;
}
interface
interface CsvValidationReport {
/** Data rows read (blank lines excluded). */
rows: number;
/** Rows whose phone is valid and not a duplicate. */
valid: number;
/** The phone column used, and how it was chosen. */
phoneColumn: { name: string; index: number; from: "mapping" | "header" | "data" };
hasHeader: boolean;
delimiter: string;
/** Every problem, up to `maxProblems` (then `truncated`). */
problems: CsvRowProblem[];
truncated: boolean;
}
interface
interface ValidateCsvOptions {
/** Contact field → column header, as for the upload; `mapping.phone` names the phone column. */
mapping?: Record<string, string>;
/** Country for numbers without a country code (default IL). */
default_country?: string;
/** Keep at most this many problems in the report (default 1000). */
maxProblems?: number;
signal?: AbortSignal;
}
type

libphonenumber-js’s parsePhoneNumberFromString, as the check uses it (country codes as plain strings).

type ParsePhone = (text: string, country?: string) => { number: string; isValid(): boolean } | undefined;
type
type PhoneCheck = { e164: string; valid: true } | { e164: string | null; valid: false; reason: Exclude<CsvRowProblem["reason"], "duplicate"> };
function

The server’s normalisation: spaces, dashes, 00 / 972 prefixes, Excel numbers without the leading 0.

function checkPhone(parse: ParsePhone, raw: string, region = "IL"): PhoneCheck;
function

The delimiter that splits the first line into the most fields (outside quotes); “,” when tied or none.

function guessDelimiter(firstLine: string): string;
class

Incremental RFC 4180 parser: text chunks in, complete rows out. State survives chunk boundaries (a "" escape or a CRLF split in two).

class CsvParser {
readonly delimiter: string;
constructor(delimiter: string);
feed(chunk: string): string[][];
/** End of input: the last row, when the file does not end with a newline. */
end(): string[][];
}
function

The rows of a CSV, one at a time.

async function* csvRows(source: AsyncIterable<Uint8Array>, signal?: AbortSignal): AsyncGenerator<{ row: string[]; delimiter: string }>;
function

Check a CSV before upload. Reads source once, streaming. Throws CsvValidationError (with the report) when any row fails; resolves with the report otherwise.

function validateCsv(source: AsyncIterable<Uint8Array>, options: ValidateCsvOptions = {}): Promise<CsvValidationReport>;