├── .commitlintrc.json ├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── test.yml ├── .gitignore ├── .huskyrc ├── .npmrc ├── .nvmrc ├── .prettierrc ├── .run ├── Run Examples.run.xml ├── Serve Docs.run.xml └── jest.config.js.run.xml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── contributing.md ├── documentation ├── .gitignore ├── CHANGELOG.md ├── README.md ├── blog │ └── 2020-03-11-new-docs.md ├── docs │ ├── formatting │ │ ├── examples.mdx │ │ ├── getting-started.mdx │ │ ├── methods.mdx │ │ ├── options.md │ │ └── row-types.md │ ├── introduction │ │ ├── example.mdx │ │ ├── getting-started.md │ │ └── install.md │ ├── migration-guides │ │ └── v2.x-to-v3.x.md │ └── parsing │ │ ├── benchmark.md │ │ ├── events.md │ │ ├── examples.mdx │ │ ├── getting-started.mdx │ │ ├── methods.mdx │ │ └── options.md ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ └── styles.module.css └── static │ └── img │ ├── favicon.ico │ ├── format_parse.svg │ ├── logo.svg │ ├── nodejs_icon.svg │ └── ts_logo.png ├── examples ├── benchmark │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── assets │ │ ├── 1000.nonquoted.csv │ │ ├── 1000.quoted.csv │ │ ├── 10000.nonquoted.csv │ │ ├── 10000.quoted.csv │ │ ├── 100000.nonquoted.csv │ │ ├── 100000.quoted.csv │ │ ├── 20000.nonquoted.csv │ │ ├── 20000.quoted.csv │ │ ├── 50000.nonquoted.csv │ │ └── 50000.quoted.csv │ ├── createData.js │ ├── index.js │ └── package.json ├── example-runner │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── bin │ │ └── run-examples │ └── package.json ├── fast-csv-js │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── examples │ │ ├── assets │ │ │ ├── parse.csv │ │ │ └── snake_case_users.csv │ │ ├── format.example.js │ │ ├── models │ │ │ └── user.js │ │ ├── parse.example.js │ │ └── parse_and_format_transform_async.example.js │ └── package.json ├── fast-csv-ts │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── assets │ │ ├── parse.csv │ │ └── snake_case_users.csv │ ├── examples │ │ ├── format.example.ts │ │ ├── models │ │ │ └── user.ts │ │ ├── parse.example.ts │ │ └── parse_and_format_transform_async.example.ts │ ├── package.json │ └── tsconfig.json ├── formatting-js │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── examples │ │ ├── append.example.js │ │ ├── delimiter_option.example.js │ │ ├── escape_option.example.js │ │ ├── format.example.js │ │ ├── hash_array.example.js │ │ ├── headers_auto_discovery_hash_array.example.js │ │ ├── headers_auto_discovery_object.example.js │ │ ├── headers_provided_array.example.js │ │ ├── headers_provided_hash_array.example.js │ │ ├── headers_provided_object.example.js │ │ ├── headers_provided_object_remove_column.example.js │ │ ├── quote_all_columns.example.js │ │ ├── quote_all_headers.example.js │ │ ├── quote_columns_array.example.js │ │ ├── quote_columns_not_headers.example.js │ │ ├── quote_columns_object.example.js │ │ ├── quote_headers_array.example.js │ │ ├── quote_headers_object.example.js │ │ ├── quote_option.example.js │ │ ├── quote_some_columns_and_headers.example.js │ │ ├── row_delimiter_option.example.js │ │ ├── transform.example.js │ │ ├── transform_async.example.js │ │ ├── transform_option.example.js │ │ ├── write.example.js │ │ ├── write_headers_auto_discover.example.js │ │ ├── write_headers_provided_headers.example.js │ │ ├── write_to_buffer.example.js │ │ ├── write_to_path.example.js │ │ ├── write_to_stream.example.js │ │ ├── write_to_string.example.js │ │ ├── write_to_string_no_headers.example.js │ │ └── write_to_string_transform.example.js │ └── package.json ├── formatting-ts │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── examples │ │ ├── append.example.ts │ │ ├── delimiter_option.example.ts │ │ ├── escape_option.example.ts │ │ ├── format.example.ts │ │ ├── hash_array.example.ts │ │ ├── headers_auto_discovery_hash_array.example.ts │ │ ├── headers_auto_discovery_object.example.ts │ │ ├── headers_provided_array.example.ts │ │ ├── headers_provided_hash_array.example.ts │ │ ├── headers_provided_object.example.ts │ │ ├── headers_provided_object_remove_column.example.ts │ │ ├── quote_all_columns.example.ts │ │ ├── quote_all_headers.example.ts │ │ ├── quote_columns_array.example.ts │ │ ├── quote_columns_not_headers.example.ts │ │ ├── quote_columns_object.example.ts │ │ ├── quote_headers_array.example.ts │ │ ├── quote_headers_object.example.ts │ │ ├── quote_option.example.ts │ │ ├── quote_some_columns_and_headers.example.ts │ │ ├── row_delimiter_option.example.ts │ │ ├── transform.example.ts │ │ ├── transform_async.example.ts │ │ ├── transform_option.example.ts │ │ ├── write.example.ts │ │ ├── write_headers_auto_discover.example.ts │ │ ├── write_headers_provided_headers.example.ts │ │ ├── write_to_buffer.example.ts │ │ ├── write_to_path.example.ts │ │ ├── write_to_stream.example.ts │ │ ├── write_to_string.example.ts │ │ ├── write_to_string_no_headers.example.ts │ │ └── write_to_string_transform.example.ts │ ├── package.json │ └── tsconfig.json ├── js.eslintrc.js ├── parsing-js │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── assets │ │ └── snake_case_users.csv │ ├── examples │ │ ├── alternate_delimiter.example.js │ │ ├── custom_headers.example.js │ │ ├── first_row_as_headers.example.js │ │ ├── ignore_empty_rows.example.js │ │ ├── manual_write.example.js │ │ ├── max_rows.example.js │ │ ├── parse_string.example.js │ │ ├── pipe.example.js │ │ ├── rename_headers.example.js │ │ ├── skip_lines.example.js │ │ ├── skip_rows.example.js │ │ ├── skipping_columns.example.js │ │ ├── transform.example.js │ │ ├── transform_async.example.js │ │ ├── transform_headers.example.js │ │ ├── validate.example.js │ │ ├── validate_async.example.js │ │ └── validate_with_reason.example.js │ └── package.json └── parsing-ts │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── assets │ └── snake_case_users.csv │ ├── examples │ ├── alternate_delimiter.example.ts │ ├── custom_headers.example.ts │ ├── first_row_as_headers.example.ts │ ├── ignore_empty_rows.example.ts │ ├── manual_write.example.ts │ ├── max_rows.example.ts │ ├── parse_string.example.ts │ ├── pipe.example.ts │ ├── rename_headers.example.ts │ ├── skip_lines.example.ts │ ├── skip_rows.example.ts │ ├── skipping_columns.example.ts │ ├── transform.example.ts │ ├── transform_async.example.ts │ ├── transform_headers.example.ts │ ├── validate.example.ts │ ├── validate_async.example.ts │ └── validate_with_reason.example.ts │ ├── package.json │ └── tsconfig.json ├── jest.config.js ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── fast-csv │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ │ └── fast-csv.spec.ts │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── format │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ │ ├── CsvFormatterStream.spec.ts │ │ ├── FormatterOptions.spec.ts │ │ ├── __fixtures__ │ │ │ ├── .gitkeep │ │ │ ├── RecordingStream.ts │ │ │ └── index.ts │ │ ├── format.spec.ts │ │ ├── formatter │ │ │ ├── FieldFormatter.spec.ts │ │ │ └── RowFormatter.spec.ts │ │ └── issues │ │ │ ├── __fixtures__ │ │ │ └── .gitkeep │ │ │ ├── issue158.spec.ts │ │ │ ├── issue252.spec.ts │ │ │ ├── issue446.spec.ts │ │ │ ├── issue503.spec.ts │ │ │ ├── issue77.spec.ts │ │ │ └── issue97.spec.ts │ ├── package.json │ ├── src │ │ ├── CsvFormatterStream.ts │ │ ├── FormatterOptions.ts │ │ ├── formatter │ │ │ ├── FieldFormatter.ts │ │ │ ├── RowFormatter.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ └── types.ts │ └── tsconfig.json └── parse │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ ├── CsvParsingStream.spec.ts │ ├── ParserOptions.spec.ts │ ├── __fixtures__ │ │ ├── RecordingStream.ts │ │ ├── alternateEncoding.ts │ │ ├── duplicateHeaders.ts │ │ ├── emptyRows.ts │ │ ├── headerColumnMismatch.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── malformed.ts │ │ ├── noHeadersAndQuotes.ts │ │ ├── skipLines.ts │ │ ├── tmp │ │ │ ├── malformed.csv │ │ │ └── with_headers.csv │ │ ├── trailingComma.ts │ │ ├── withHeaders.ts │ │ ├── withHeadersAlternateDelimiter.ts │ │ ├── withHeadersAndAlternateQuote.ts │ │ ├── withHeadersAndMissingColumns.ts │ │ ├── withHeadersAndQuotes.ts │ │ └── withHeadersAndSkippedLines.ts │ ├── issues │ │ ├── __fixtures__ │ │ │ ├── issue102.csv │ │ │ ├── issue68-invalid.tsv │ │ │ ├── issue68.tsv │ │ │ └── issue87.csv │ │ ├── issue102.spec.ts │ │ ├── issue111.spec.ts │ │ ├── issue131.spec.ts │ │ ├── issue150.spec.ts │ │ ├── issue174.spec.ts │ │ ├── issue214.spec.ts │ │ ├── issue223.spec.ts │ │ ├── issue317.spec.ts │ │ ├── issue340.spec.ts │ │ ├── issue356.spec.ts │ │ ├── issue540.spec.ts │ │ ├── issue68.spec.ts │ │ ├── issue87.spec.ts │ │ └── issue93.spec.ts │ ├── parse.spec.ts │ ├── parser │ │ ├── Parser.spec.ts │ │ ├── RowParser.spec.ts │ │ ├── Scanner.spec.ts │ │ └── column │ │ │ ├── ColumnParser.spec.ts │ │ │ ├── NonQuotedColumnParser.spec.ts │ │ │ └── QuotedColumnParser.spec.ts │ └── transforms │ │ ├── HeaderTransformer.spec.ts │ │ └── RowTransformerValidator.spec.ts │ ├── package.json │ ├── src │ ├── CsvParserStream.ts │ ├── ParserOptions.ts │ ├── index.ts │ ├── parser │ │ ├── Parser.ts │ │ ├── RowParser.ts │ │ ├── Scanner.ts │ │ ├── Token.ts │ │ ├── column │ │ │ ├── ColumnFormatter.ts │ │ │ ├── ColumnParser.ts │ │ │ ├── NonQuotedColumnParser.ts │ │ │ ├── QuotedColumnParser.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── transforms │ │ ├── HeaderTransformer.ts │ │ ├── RowTransformerValidator.ts │ │ └── index.ts │ └── types.ts │ └── tsconfig.json ├── renovate.json ├── tsconfig.build.json └── tsconfig.json /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-angular"], 3 | "rules": { 4 | "subject-case": [ 5 | 2, 6 | "always", 7 | ["sentence-case", "start-case", "pascal-case", "upper-case", "lower-case"] 8 | ], 9 | "type-enum": [ 10 | 2, 11 | "always", 12 | [ 13 | "build", 14 | "chore", 15 | "ci", 16 | "docs", 17 | "feat", 18 | "fix", 19 | "perf", 20 | "refactor", 21 | "revert", 22 | "style", 23 | "test", 24 | "example" 25 | ] 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/build 2 | **/node_modules 3 | documentation 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: doug-martin, dustinsmith1024 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Parsing or Formatting?** 14 | 15 | - [ ] Formatting 16 | - [ ] Parsing 17 | 18 | **To Reproduce** 19 | Steps to reproduce the behavior: 20 | 1. Example file contents if applicable 21 | 2. Example code to reproduce the issue. 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. MacOS] 31 | - OS Version [e.g. Mojave] 32 | - Node Version [e.g. 10.16.0] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: doug-martin, dustinsmith1024 7 | 8 | --- 9 | 10 | **Parsing or Formatting?** 11 | 12 | - [ ] Formatting 13 | - [ ] Parsing 14 | 15 | **Is your feature request related to a problem? Please describe.** 16 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 17 | 18 | **Describe the solution you'd like** 19 | A clear and concise description of what you want to happen. 20 | 21 | **Describe alternatives you've considered** 22 | A clear and concise description of any alternative solutions or features you've considered. 23 | 24 | **Additional context** 25 | Add any other context or screenshots about the feature request here. -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### All Submissions: 2 | 3 | * [ ] Have you followed the guidelines in our Contributing document? 4 | * [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/c2fo/fast-csv/pulls) for the same update/change? 5 | 6 | 7 | 8 | ### New Feature Submissions: 9 | 10 | 1. [ ] Have you added tests for the new feature 11 | 2. [ ] Does your submission pass tests? 12 | 3. [ ] Have you lint your code locally prior to submission? 13 | 4. [ ] Have you updated the docs? 14 | * [ ] If you added new parsing or formatting options have you added them to the docs? 15 | * [ ] If applicable have you added an example to the parsing or formatting docs? 16 | 17 | ### Changes to Core Features: 18 | 19 | * [ ] Have you added an explanation of what your changes do and why you'd like us to include them? 20 | * [ ] Have you written new tests for your core changes, as applicable? 21 | * [ ] Have you successfully ran tests with your changes locally? -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: # Array of patterns that match refs/heads 6 | - main # Push events on main branch 7 | pull_request: # Specify a second event with pattern matching 8 | env: 9 | CI: true 10 | jobs: 11 | unit: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | node-version: [18.x, 20.x, 21.x] 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Use Node.js ${{ matrix.node-version }} 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | - name: Restore Dependencies 23 | uses: actions/cache@v4 24 | with: 25 | path: ~/.npm 26 | key: ${{ runner.os }}-node-${{matrix.node-version}}-${{ hashFiles('**/package-lock.json') }} 27 | restore-keys: | 28 | ${{ runner.os }}-node-${{matrix.node-version}}- 29 | - run: npm ci 30 | - run: npm run build 31 | - run: npm run lint 32 | - run: npm run jest 33 | - run: npm run examples 34 | - run: npm run benchmarks 35 | - name: Coveralls GitHub Action 36 | # Per Actions best practices, SHA is the safest for third party actions 37 | # https://github.com/coverallsapp/github-action/releases/tag/v2.3.4 38 | uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 39 | with: 40 | github-token: ${{ secrets.GITHUB_TOKEN }} 41 | flag-name: run-unit-${{ matrix.node-version }} 42 | parallel: true 43 | 44 | finish: 45 | needs: unit 46 | runs-on: ubuntu-latest 47 | steps: 48 | - name: Coveralls Finished 49 | # Per Actions best practices, SHA is the safest for third party actions 50 | # https://github.com/coverallsapp/github-action/releases/tag/v2.3.4 51 | uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 52 | with: 53 | github-token: ${{ secrets.github_token }} 54 | parallel-finished: true 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .DS_Store 4 | .idea 5 | benchmark/results 6 | .nyc_output 7 | build 8 | coverage 9 | **/*.tmp.csv 10 | **/*.tsbuildinfo 11 | lerna-debug.log 12 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "skipCI": false, 3 | "hooks": { 4 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", 5 | "pre-commit": "npm test" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | if-present=true 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.18.0 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 120, 4 | "trailingComma": "all", 5 | "tabWidth": 4 6 | } 7 | -------------------------------------------------------------------------------- /.run/Run Examples.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |