feat(medusa): Parsing CSV files (#1572)

* add: csv parser

* fix: tests

* fix: linting + comment

* add: missing dependency

* fix: generic transformers

* fix: address comments

* fix: make parser options generic

* add: support regex columns + fix missing columns bug

* improve test case

* add: support for reducer + tests

* fix: add comments to csv parser
This commit is contained in:
Zakaria El Asri
2022-06-19 16:10:15 +01:00
committed by GitHub
parent 46a6e1a4d3
commit 9e686a8e47
6 changed files with 730 additions and 4 deletions
@@ -0,0 +1,73 @@
import { AwilixContainer } from "awilix"
/**
* Generic validation interface used to run validation logic on every line or record.
* All different validation objects should implement this interface
*/
export interface ICsvValidator<TCsvLine, TBuiltLine> {
/**
*
* @param value value of column or property
* @param context includes contextual information such as line number, line, etc.
*/
validate: (
value: TBuiltLine,
context: CsvParserContext<TCsvLine>
) => Promise<boolean | never>
}
export type CsvParserContext<TLine> = LineContext<TLine> & {
column: string
}
export type LineContext<TLine> = {
lineNumber: number
line: TLine
}
/**
* Abstract class implementation of the IValidator interface.
* All validation objects part of the schema should extend this class.
*/
export abstract class AbstractCsvValidator<TCsvLine, TBuiltLine>
implements ICsvValidator<TCsvLine, TBuiltLine>
{
constructor(protected readonly container: AwilixContainer) {}
abstract validate(
builtLine: TBuiltLine,
context: CsvParserContext<TCsvLine>
): Promise<boolean | never>
}
export type CsvSchemaColumn<TCsvLine, TBuiltLine> = {
name: string
required?: boolean
validator?: AbstractCsvValidator<TCsvLine, TBuiltLine>
} & (
| {
mapTo?: string
transform?: ColumnTransformer<TCsvLine>
}
| {
match?: RegExp
reducer?: ColumnReducer<TCsvLine, TBuiltLine>
transform?: ColumnTransformer<TCsvLine>
}
)
export type ColumnTransformer<TCsvLine> = (
value: string,
context: CsvParserContext<TCsvLine>
) => unknown
export type ColumnReducer<TCsvLine = unknown, TBuiltLine = unknown> = (
builtLine: TBuiltLine,
key: string,
value: string,
context: CsvParserContext<TCsvLine>
) => TBuiltLine
export type CsvSchema<TCsvLine = unknown, TBuiltLine = unknown> = {
columns: CsvSchemaColumn<TCsvLine, TBuiltLine>[]
}