Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
A small and fast CSV parser with support for nested JSON.
json2csv
.header
, delimiter
, eol
.fields
, with custom value getters and setters and the ability to ignore fields.formatValue
and parseValue
.Note that the parser has no streaming support.
Well, you have to write a CSV parser at least once in you life, right? ;)
The csv42
library was developed specifically for https://jsoneditoronline.org, for use in the browser. Besides being small and fast, one important feature is supporting nested JSON objects. So, why the name csv42
? Just because 42 is a beautiful number and to remind us that there is a whole universe of beautiful CSV libraries out there.
npm install csv42
Install the library once:
import { json2csv } from 'csv42'
const users = [
{ id: 1, name: 'Joe', address: { city: 'New York', street: '1st Ave' } },
{ id: 2, name: 'Sarah', address: { city: 'Manhattan', street: 'Spring street' } }
]
// By default, nested JSON properties are flattened
const csv = json2csv(users)
console.log(csv)
// id,name,address.city,address.street
// 1,Joe,New York,1st Ave
// 2,Sarah,Manhattan,Spring street
// You can turn off flattening using the option `flatten`
const csvFlat = json2csv(users, { flatten: false })
console.log(csvFlat)
// id,name,address
// 1,Joe,"{""city"":""New York"",""street"":""1st Ave""}"
// 2,Sarah,"{""city"":""Manhattan"",""street"":""Spring street""}"
// The CSV output can be fully customized and transformed using `fields`:
const csvCustom = json2csv(users, {
fields: [
{ name: 'name', getValue: (item) => item.name },
{ name: 'address', getValue: (item) => item.address.city + ' - ' + object.address.street }
]
})
console.log(csvCustom)
// name,address
// Joe,New York - 1st Ave
// Sarah,Manhattan - Spring street
import { csv2json } from 'csv42'
const csv = `id,name,address.city,address.street
1,Joe,New York,1st Ave
2,Sarah,Manhattan,Spring street`
// By default, fields containing a dot will be parsed inty nested JSON objects
const users = csv2json(csv)
console.log(users)
// [
// { id: 1, name: 'Joe', address: { city: 'New York', street: '1st Ave' } },
// { id: 2, name: 'Sarah', address: { city: 'Manhattan', street: 'Spring street' } }
// ]
// Creating nested objects can be turned off using the option `nested`
const usersFlat = csv2json(csv, { nested: false })
console.log(usersFlat)
// [
// { id: 1, name: 'Joe', 'address.city': 'New York', 'address.street': '1st Ave' },
// { id: 2, name: 'Sarah', 'address.city': 'Manhattan', 'address.street': 'Spring street' }
// ]
// The JSON output can be customized using `fields`
const usersCustom = csv2json(csv, {
fields: [
{ name: 'name', setValue: (item, value) => (item.name = value) },
{ name: 'address.city', setValue: (item, value) => (item.city = value) }
]
})
console.log(usersCustom)
// [
// { name: 'Joe', city: 'New York' },
// { name: 'Sarah', city: 'Manhattan' }
// ]
json2csv<T>(json: T[], options?: CsvOptions<T>) : string
Where options
is an object with the following properties:
Option | Type | Description |
---|---|---|
header | boolean | If true, a header will be created as first line of the CSV. |
delimiter | string | Default delimiter is , . A delimiter must be a single character. |
eol | \r\n or \n | End of line, can be \r\n (default) or \n . |
flatten | boolean or (value: unknown) => boolean | If true (default), plain, nested objects will be flattened in multiple CSV columns, and arrays and classes will be serialized in a single field. When false , nested objects will be serialized as JSON in a single CSV field. This behavior can be customized by providing your own callback function for flatten . For example, to flatten objects and arrays, you can use json2csv(json, { flatten: isObjectOrArray }) , and to flatten a specific class, you can use json2csv(json, { flatten: value => isObject(value) || isCustomClass(value) }) . The option flatten is not applicable whenfields is defined. |
fields | CsvField<T>[] or CsvFieldsParser<T> | A list with fields to be put into the CSV file. This allows specifying the order of the fields and which fields to include/excluded. |
formatValue | ValueFormatter | Function used to change any type of value into a serialized string for the CSV. The build in formatter will only enclose values in quotes when necessary, and will stringify nested JSON objects. |
A simple example of a ValueFormatter
is the following. This formatter will enclose every value in quotes:
function formatValue(value: unknown): string {
return '"' + String(value) + '"'
}
csv2json<T>(csv: string, options?: JsonOptions) : T[]
Where options
is an object with the following properties:
Option | Type | Description |
---|---|---|
header | boolean | Should be set true when the first line of the CSV file contains a header |
delimiter | string | Default delimiter is , . A delimiter must be a single character. |
nested | boolean | If true (default), field names containing a dot will be parsed into nested JSON objects. The option nested is not applicable when fields is defined. |
fields | JsonField[] or JsonFieldsParser | A list with fields to be extracted from the CSV file into JSON. This allows specifying which fields are include/excluded, and how they will be put into the JSON object. A field can be specified either by name, like { name, setValue } , or by the index of the columns in the CSV file, like { index, setValue } . |
parseValue | ValueParser | Used to parse a stringified value into a value again (number, boolean, string, ...). The build in parser will parse numbers and booleans, and will parse stringified JSON objects. |
A simple value parser can look as follows. This will keep all values as string:
function parseValue(value: string): unknown {
return value.startsWith('"') ? value.substring(1, value.length - 1).replaceAll('""', '"') : value
}
The library exports a number of utility functions:
Function | Description |
---|---|
createFormatValue(delimiter: string): (value: unknown) => string | Create a function that can format (stringify) a value into a valid CSV value, escaping the value when needed. This function is used as default for the option formatValue . |
parseValue(value: string): unknown | Parse a string into a value, parse numbers into a number, etc. This is the function used by default for the option parseValue . |
unescapeValue(value: string) : string | Unescape an escaped value like "hello ""Joe""" into the string hello "Joe" . |
collectNestedPaths(records: NestedObject[], recurse: boolean): Path[] | Loop over the data and collect all nested paths. This can be used to generate a list with fields. |
parsePath(pathStr: string): Path | Parse a path like 'items[3].name' |
stringifyPath(path: Path): string | Stringify a path into a string like 'items[3].name' |
getIn(object: NestedObject, path: Path): unknown | Get a nested property from an object |
setIn(object: NestedObject, path: Path, value: unknown): NestedObject | Set a nested property in an object |
isObject(value: unknown): boolean | Returns true when value is a plain JavaScript object, and returns false for primitive values, arrays, and classes. Can be used as callback function for the option flatten . |
isObjectOrArray(value: unknown): boolean | Returns true when value is a plain JavaScript object or array, and returns false for primitive values and classes. Can be used as callback function for the option flatten . |
To release a new version:
$ npm run release
This will:
To try the build and see the change list without actually publishing:
$ npm run release-dry-run
csv42
is released as open source under the permissive the ISC license.
If you are using csv42
commercially, there is a social (but no legal) expectation that you help fund its maintenance. Start here.
4.0.0 (2023-06-02)
json2csv<User>(...)
and
csv2json<User>(...)
. The typings of the value getters and setters (getValue
and
setValue
) is changed, and the type of NestedObject
is changed.FAQs
A small and fast CSV parser with support for nested JSON
The npm package csv42 receives a total of 2,434 weekly downloads. As such, csv42 popularity was classified as popular.
We found that csv42 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.