-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
3,782 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/dist | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/jest.config.json | ||
**/*.test.ts | ||
/.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Incremental CSV Parser | ||
|
||
A fast & lightweight CSV parser with an incremental parsing api. No | ||
dependencies; browser compatible. Includes ESM and CJS builds. All column | ||
values are strings (numbers and dates will **not** automatically be parsed). | ||
|
||
Fully compatible with [rfc4180](https://www.ietf.org/rfc/rfc4180.txt). | ||
|
||
|
||
## Basic parsing | ||
|
||
```js | ||
import { parse } from 'incremental-csv-parser'; | ||
|
||
|
||
const results = await parse(`a,b,c,d | ||
1,2,3,4 | ||
5,6,7,8 | ||
`); | ||
|
||
console.log(results); | ||
// [ | ||
// { a: '1', b: '2', c: '3', d: '4' }, | ||
// { a: '5', b: '6', c: '7', d: '8' }, | ||
// ] | ||
``` | ||
|
||
## Incremental parsing | ||
|
||
```js | ||
import { CSVParser } from 'incremental-csv-parser'; | ||
|
||
const results = []; | ||
|
||
const parser = new CSVParser((row) => { | ||
results.push(row); | ||
}); | ||
|
||
parser.process('a,b,c,d\n'); | ||
parser.process('1,2,3,4\n'); | ||
console.log(results.shift()); // { a: '1', b: '2', c: '3', d: '4' } | ||
parser.process('5,6,7,8'); | ||
parser.flush(); | ||
console.log(results.shift()); // { a: '5', b: '6', c: '7', d: '8' } | ||
``` | ||
|
||
## Typescript support | ||
|
||
If column names are known ahead of time, they can be passed in via generics. | ||
|
||
```ts | ||
import { CSVParser } from 'incremental-csv-parser'; | ||
|
||
type ColumnName = 'a' | 'b' | 'c' | 'd'; | ||
const results: Record<ColumnName, string> = []; | ||
|
||
const parser = new CSVParser<ColumName>((row) => { | ||
results.push(row); | ||
}); | ||
``` | ||
|
||
## CSV files without pre-defined headers | ||
|
||
Both the `parse` function and `CSVParser` class have an optional second argument | ||
for explicitly providing column names for a csv. | ||
|
||
```ts | ||
import { CSVParser } from 'incremental-csv-parser'; | ||
|
||
const columns = ['a', 'b', 'c', 'd']; | ||
|
||
const results = parse(`1,2,3,4 | ||
5,6,7,8`, columns); | ||
|
||
console.log(results); | ||
// [ | ||
// { a: '1', b: '2', c: '3', d: '4' }, | ||
// { a: '5', b: '6', c: '7', d: '8' }, | ||
// ] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"transform": { | ||
"^.+\\.ts$": ["esbuild-jest", { "sourcemap": true }] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "incremental-csv-parser", | ||
"version": "1.0.0", | ||
"description": "A simple, browser compatible, incremental CSV parser.", | ||
"main": "dist/esm/index.js", | ||
"repository": "https://github.com/AllAwesome497/incremental-csv-parser", | ||
"author": "Wade Bourne <[email protected]>", | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "yarn build:types && yarn build:esm && yarn build:cjs", | ||
"build:types": "tsc", | ||
"build:esm": "esbuild src/*.ts --outdir=dist/esm --format=esm --out-extension:.js=.mjs --sourcemap", | ||
"build:cjs": "esbuild src/*.ts --outdir=dist/cjs --format=cjs --sourcemap", | ||
"test": "jest", | ||
"prepack": "yarn test && yarn build" | ||
}, | ||
"exports": { | ||
".": { | ||
"import": "./dist/esm/index.mjs", | ||
"require": "./dist/cjs/index.js", | ||
"types": "./dist/types/index.d.ts" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"devDependencies": { | ||
"@babel/preset-typescript": "^7.18.6", | ||
"@jest/globals": "^29.3.1", | ||
"esbuild": "^0.15.15", | ||
"esbuild-jest": "^0.5.0", | ||
"jest": "^29.3.1", | ||
"ts-jest": "^29.0.3", | ||
"typescript": "^4.9.3", | ||
"prettier": "^2.7.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* eslint-env jest */ | ||
import { expect, describe, it } from '@jest/globals'; | ||
import { CSVParser } from '../index'; | ||
|
||
interface CSVParserTest { | ||
name: string; | ||
headers?: Array<string>; | ||
chunks: Array<string>; | ||
expected: Array<Record<string, string>>; | ||
} | ||
|
||
describe('SimpleCSVParser', () => { | ||
it.each<CSVParserTest>([ | ||
{ | ||
name: 'basic', | ||
chunks: [ | ||
`a,b,c,d | ||
1,2,3,4 | ||
5,6,7,8 | ||
`, | ||
], | ||
expected: [ | ||
{ a: '1', b: '2', c: '3', d: '4' }, | ||
{ a: '5', b: '6', c: '7', d: '8' }, | ||
], | ||
}, | ||
{ | ||
name: 'mixed quotes', | ||
chunks: [ | ||
`a,b,c,"d" | ||
"1",2,"3","4" | ||
5,6,7,8 | ||
`, | ||
], | ||
expected: [ | ||
{ a: '1', b: '2', c: '3', d: '4' }, | ||
{ a: '5', b: '6', c: '7', d: '8' }, | ||
], | ||
}, | ||
{ | ||
name: 'quoted newlines', | ||
chunks: [ | ||
`a,b,c,d | ||
"1 | ||
2",3,4,5 | ||
`, | ||
], | ||
expected: [{ a: '1\n2', b: '3', c: '4', d: '5' }], | ||
}, | ||
{ | ||
name: 'empty values', | ||
chunks: [ | ||
`a,b,c,d | ||
,,,`, | ||
], | ||
expected: [{ a: '', b: '', c: '', d: '' }], | ||
}, | ||
{ | ||
name: 'carriage returns + newlines', | ||
chunks: [ | ||
`a,b,c,d\r | ||
1,2,3,4\r | ||
5,6,7,8 | ||
`, | ||
], | ||
expected: [ | ||
{ a: '1', b: '2', c: '3', d: '4' }, | ||
{ a: '5', b: '6', c: '7', d: '8' }, | ||
], | ||
}, | ||
{ | ||
name: 'commas in quoted text', | ||
chunks: [ | ||
`a,b,c,d | ||
"1,2",3,4,5 | ||
`, | ||
], | ||
expected: [{ a: '1,2', b: '3', c: '4', d: '5' }], | ||
}, | ||
{ | ||
name: 'basic chunks', | ||
chunks: ['a,b,c,d\n', '1,', '2,', '3,', '4\n'], | ||
|
||
expected: [{ a: '1', b: '2', c: '3', d: '4' }], | ||
}, | ||
{ | ||
name: 'chunks with newlines', | ||
chunks: ['a,b,c\n', '"1\n', '\n', '\n', '"', ',2,3\n'], | ||
expected: [{ a: '1\n\n\n', b: '2', c: '3' }], | ||
}, | ||
{ | ||
name: 'chunks with commas and quotes', | ||
chunks: ['a,b,c\n', ',', '",,,', '",'], | ||
expected: [{ a: '', b: ',,,', c: '' }], | ||
}, | ||
{ | ||
name: 'manually set headers', | ||
chunks: [ | ||
`1,2,3,4 | ||
5,6,7,8`, | ||
], | ||
headers: ['a', 'b', 'c', 'd'], | ||
expected: [ | ||
{ a: '1', b: '2', c: '3', d: '4' }, | ||
{ a: '5', b: '6', c: '7', d: '8' }, | ||
], | ||
}, | ||
])('$name', ({ chunks, expected, headers }) => { | ||
const results: Array<Record<string, string>> = []; | ||
|
||
const parser = new CSVParser((data) => results.push(data), headers); | ||
|
||
for (const chunk of chunks) { | ||
parser.process(chunk); | ||
} | ||
|
||
parser.flush(); | ||
|
||
expect(results).toEqual(expected); | ||
}); | ||
}); |
Oops, something went wrong.