UNPKG

csv-rxjs-kit

Version:

A kit of RxJS operators to handle CSV formatted (RFC 4180, MIME Type 'text/csv') data.

180 lines (179 loc) 8.54 kB
import { OperatorFunction, MonoTypeOperatorFunction } from 'rxjs'; /** Basic CSV-record. * * `csvRecord` datatype represents single MIME Type 'text/csv' [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt) data record. * Any first record of a CSV-record stream might be header record. * * Every CSV-record just an array of string. Every empty field is an empty string. Empty records are empty arrays. */ export declare type csvRecord = string[]; /** CSV data converter function type. * @typeParam T - source data type * @typeParam R - result data type * @param src - source data object * @param names - field names form header record */ export declare type csvDataConverter<T, R> = (src: T, names?: string[]) => R; /** * CSV-record validator function type. * @param csvRecord - CSV-record to validate * @param isHeader - CSV-record type * @returns validated CSV-record * @throws any validation errors */ export declare type csvRecordValidator = (rec: csvRecord, isHeader: boolean) => csvRecord; /** Object builder function type. */ export declare type csvBuilder<T> = csvDataConverter<csvRecord, T>; /** CSV-record extractor function type. */ export declare type csvExtractor<T> = csvDataConverter<T, csvRecord>; /** * CSV formatter RxJS operator. * * Returns an Observable that converts to text every `csvRecord` emitted by source Observable. * Output text data is formatted as MIME Type 'text/csv' [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt). * * Parameter `opt.delimiter` sets line breaks type, default is `CRLF`. * * Parameter `opt.last_break` adds optional line delimiter after the last record. * * Parameter `opt.force_quote` adds quotation to every item. * * @param opt - options */ export declare function csvStringify(opt?: { delimiter?: '\r\n' | '\n'; last_break?: boolean; force_quote?: boolean; }): OperatorFunction<csvRecord, string>; /** * CSV parser RxJS operator. * * Returns an Obsrevable that parses text emitted by source Observable and converts it to `csvRecord`s. * Input text should be MIME Type 'text/csv' as described is [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt). * * All parse errors are reported as `SyntaxError` using an Observer's `error()` method. */ export declare function csvParse(): OperatorFunction<string, csvRecord>; /** * Removes empty records. * * Returns an Observable that removes all empty records emitted by source Observable. */ export declare function csvDropEmpty(): MonoTypeOperatorFunction<csvRecord>; /** * Removes header record. * * Returns an Observable that removes header `csvRecord` (the first data item) emitted by source Observable. * There is no dedicated tagging for header `csvRecord` so one must be sure the source Observable emits header. * * @typeParam T - the main data type, might be csvRecord or any arbitrary data type */ export declare function csvDropHeader<T>(): OperatorFunction<T | csvRecord, T>; /** * Injects a header record. * * Returns an Observable that emits header record and then mirrors source Observable. * Inserted `csvRecord` will be interpreted as a header `csvRecord` by other operators if they are instructed to. * * @typeParam T - the main stream type * @param header - header record value */ export declare function csvInjectHeader<T>(header: csvRecord): OperatorFunction<T, T | csvRecord>; /** * Validates a record. * * Returns an Observable that uses `validator` to check/modify every `csvRecord` emitted by source Observable. * * To remove invalid records one can use `validator` to convert them to empty records and then use `csvDropEmpty` operator. * * @param hdr - does source Obsrvable emit header 'csvRecord'? * @param validator - function to validate a 'csvRecord' * @throws everything that `validator` throws */ export declare function csvValidateRecord(hdr: boolean, validator: csvRecordValidator): MonoTypeOperatorFunction<csvRecord>; /** * Creates `csvRecord` for data array. * * Returns an Observable that converts every array item emitted by source Observable to `csvRecord`. * The operator calls `String(...)` for every defined item in the input data array, undefined items are replaced by `''`. * * It doesn't matter if source Observable emits header record. The operator's conversion procedure doesn't affect a header record. * * If you need different behavior and/or have different input data type use `csvConvert()` and custom `csvExtractor<T>`. */ export declare function csvFromArray(): OperatorFunction<unknown[], csvRecord>; /** * Converts an item using provided data converter function, uses header record to extract names. * * Returns an Observable that uses `prj` function to convert items emitted by source Observable. * * If `hdr === true` the operator interprets first item emitted by source Observable as a header record * and uses the record's data as names in subsequent `prj` calls. * The header records is reemitted, don't forget to remove it to clean up the data item stream. * * If `hdr === false` no names available to `prj` function and every record emitted by source Observable is converted. * * @typeParam T - input object type * @typeParam R - output object type * @param hdr - does source Observable emit header 'csvRecord'? * @param prj - function to convert object * @throws `RangeError` if `prj` argument is invalid */ export declare function csvConvert<T, R>(hdr: false, prj: csvDataConverter<T, R>): OperatorFunction<T, R>; export declare function csvConvert<T, R>(hdr: true, prj: csvDataConverter<T, R>): OperatorFunction<csvRecord | T, csvRecord | R>; /** * Justifies record length, can be is used with `csvValidateRecord()`. * * Returns `csvRecordValidator` that justifies record length according to header length. * According to RFC 4180 'each line should contain the same number of fields throughout the file' * hence any changes to bad sized records violate the RFC. * * Parameter `opt.length` sets default length of a record. A header record length (if available) * overrides `opt.length` value. If `opt.length` is not set and header record hasn't been available, * no records are altered. * * Parameter `opt.skip_empty` instructs to skip empty records, **violates RFC 4180** * * Parameter `opt.repair` instructs to repair bad sized records, **violates RFC 4180** * * Parameter `opt.filler` sets repair mode. If `opt.filler` is defined bad sized record is filled up * or cut to the header length. If `opt.filler` is undefined invalid record is replaced with an empty record. * * @param opt - validation options */ export declare function csvJustifier(opt?: { length?: number; skip_empty?: boolean; repair?: boolean; filler?: string; }): csvRecordValidator; /** * Creates an object upon `csvRecord`. * * Returns `csvBuilder<Record<string, string>>` that creates an object using properties names array and `rec` data as values. * Every data item in `csvRecords` is added to created object. Data item index is used to select property name in `names` array. * If no such name exists then argument `extra` is used to generate property name for index `i`. * * If `extra` is function, then propery name is `<extra>(<i>)`. * If `extra` is string, then property name is `<extra><i>`. * If `extra` is undefined, then property name is `_<i>`. * * Can be used in `csvConvert()` to create simple objects. * * @see csvConvert() * * @param extra - property name generator for unlisted properties */ export declare function csvAssembler(extra?: string | ((index: number) => string)): csvBuilder<Record<string, string>>; /** Returns an array of alphabetically sorted enumerable properties of an object. */ export declare function csvPropNames(obj: Record<string, unknown>): csvRecord; /** * Creates an CSV record upon object. * * Returns `csvExtractor<Record<string, unknown>>` that creates an CSV record using properties names array and `obj` as values. * Every listed on `names` property's value is received from `obj` and stored in the record. Undefined values replaced by `''`. * If `extra === true` all non listed object properties values are added to the record in alphabetical order after the listed ones. * * @param extra - add non listed properties values */ export declare function csvPropValues(extra?: boolean): csvExtractor<Record<string, unknown>>;