Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add rollup-plugin-dsv #22

Merged
merged 2 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions packages/dsv/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# rollup-plugin-dsv changelog

## 1.2.0

* Pass `id` to `processRow`

## 1.1.2

* Return a `name`

## 1.1.1

* Add missing dependencies

## 1.1.0

* Support `options.processRow`

## 1.0.1

* Include correct files in package

## 1.0.0

* First release
100 changes: 100 additions & 0 deletions packages/dsv/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
[cover]: https://codecov.io/gh/rollup/plugins/replace/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/rollup/plugins
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-dsv
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-dsv
[tests]: https://img.shields.io/circleci/project/github/rollup/plugins.svg
[tests-url]: https://circleci.com/gh/rollup/plugins

[![tests][tests]][tests-url]
[![cover][cover]][cover-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)

# @rollup/plugin-dsv

🍣 A Rollup plugin which converts `.csv` and `.tsv` files into JavaScript modules with [d3-dsv](https://github.com/d3/d3-dsv).

WebAssembly Modules are imported asynchronous as base64 strings. Small modules [can be imported synchronously](#synchronous-modules).

## Requirements

This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v8.0.0+) and Rollup v1.20.0+.

## Install

Using npm:

```console
npm install @rollup/plugin-dsv --save-dev
```

## Usage

Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:

```js
import dsv from '@rollup/plugin-dsv';

export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [dsv()]
};
```

Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).

## Practical Example

Suppose that you have a CSV (or TSV!) file which contains some information on delicious fruits:

```csv
type,count
apples,7
pears,4
bananas,5
```

And suppose you'd like to import that CSV as an `Array` within some part of your code. After adding the plugin (as shown above), you may `import` (or `require`) the CSV file directly. The import will provide an `Array` of `Objects` representing rows from the CSV file:

```js
import fruit from './fruit.csv';

console.log(fruit);
// [
// { type: 'apples', count: '7' },
// { type: 'pears', count: '4' },
// { type: 'bananas', count: '5' }
// ]
```

## Options

### `processRow`

Type: `Function`<br>
Default: `null`

Specifies a function which processes each row in the parsed array. The function can either manipulate the passed `row`, or return an entirely new row object.

This option could be used for converting numeric `string` values into `Number` values. – for example turning numeric values into numbers, e.g.

```js
dsv({
processRow: (row, id) => {
Object.keys(row).forEach(key => {
var value = row[key];
row[key] = isNaN(+value) ? value : +value;
});
}
});
```

## Meta

[CONTRIBUTING](./.github/CONTRIBUTING.md)

[LICENSE (MIT)](./LICENSE)
53 changes: 53 additions & 0 deletions packages/dsv/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@rollup/plugin-dsv",
"version": "2.0.0",
"description": "Convert .csv and .tsv files into JavaScript modules with d3-dsv",
"license": "MIT",
"repository": "rollup/plugins",
"author": "Rich Harris",
"homepage": "https://github.com/rollup/plugins",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "dist/index.js",
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm run test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:coverage:submit": "curl -s https://codecov.io/bash | bash -s - -F dsv",
"ci:lint": "pnpm run build && pnpm run lint && pnpm run security",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm run test -- --verbose",
"lint": "pnpm run lint:js && pnpm run lint:docs && pnpm run lint:package",
"lint:docs": "prettier --single-quote --write README.md",
"lint:js": "eslint --fix --cache src test",
"lint:package": "prettier --write package.json --plugin=prettier-plugin-package",
"prebuild": "del-cli dist",
"prepare": "npm run build",
"prepublishOnly": "npm run lint",
"pretest": "npm run build",
"security": "echo 'pnpm needs `npm audit` support'",
"test": "ava"
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"dependencies": {
"d3-dsv": "^0.1.14",
"rollup-pluginutils": "^2.8.2",
"tosource": "^1.0.0"
},
"devDependencies": {
"del-cli": "^3.0.0",
"rollup": "^1.20.0"
},
"ava": {
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"jsnext:main": "dist/index.es.js",
"module": "dist/index.es.js"
}
6 changes: 6 additions & 0 deletions packages/dsv/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pkg from './package.json';

export default {
input: 'src/index.js',
output: [{ file: pkg.main, format: 'cjs' }, { file: pkg.module, format: 'es' }]
};
33 changes: 33 additions & 0 deletions packages/dsv/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { extname } from 'path';

import { csv, tsv } from 'd3-dsv';
import toSource from 'tosource';
import { createFilter } from 'rollup-pluginutils';

const parsers = { '.csv': csv, '.tsv': tsv };

export default function dsv(options = {}) {
const filter = createFilter(options.include, options.exclude);

return {
name: 'dsv',

transform(code, id) {
if (!filter(id)) return null;

const ext = extname(id);
if (!(ext in parsers)) return null;

let rows = parsers[ext].parse(code);

if (options.processRow) {
rows = rows.map((row) => options.processRow(row, id) || row);
}

return {
code: `export default ${toSource(rows)};`,
map: { mappings: '' }
};
}
};
}
5 changes: 5 additions & 0 deletions packages/dsv/test/fixtures/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"globals": {
"t": "readonly"
}
}
4 changes: 4 additions & 0 deletions packages/dsv/test/fixtures/basic-csv/fruit.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type,count
apples,7
pears,4
bananas,5
7 changes: 7 additions & 0 deletions packages/dsv/test/fixtures/basic-csv/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import fruit from './fruit.csv';

t.deepEqual(fruit, [
{ type: 'apples', count: '7' },
{ type: 'pears', count: '4' },
{ type: 'bananas', count: '5' }
]);
4 changes: 4 additions & 0 deletions packages/dsv/test/fixtures/basic-tsv/fruit.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type count
apples 7
pears 4
bananas 5
7 changes: 7 additions & 0 deletions packages/dsv/test/fixtures/basic-tsv/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import fruit from './fruit.tsv';

t.deepEqual(fruit, [
{ type: 'apples', count: '7' },
{ type: 'pears', count: '4' },
{ type: 'bananas', count: '5' }
]);
4 changes: 4 additions & 0 deletions packages/dsv/test/fixtures/process-id/lower.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type,count
Apples,7
Pears,4
Bananas,5
14 changes: 14 additions & 0 deletions packages/dsv/test/fixtures/process-id/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import lower from './lower.csv';
import upper from './upper.csv';

t.deepEqual(lower, [
{ type: 'apples', count: 7 },
{ type: 'pears', count: 4 },
{ type: 'bananas', count: 5 }
]);

t.deepEqual(upper, [
{ type: 'APPLES', count: 7 },
{ type: 'PEARS', count: 4 },
{ type: 'BANANAS', count: 5 }
]);
4 changes: 4 additions & 0 deletions packages/dsv/test/fixtures/process-id/upper.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type,count
Apples,7
Pears,4
Bananas,5
4 changes: 4 additions & 0 deletions packages/dsv/test/fixtures/process/fruit.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type,count
apples,7
pears,4
bananas,5
7 changes: 7 additions & 0 deletions packages/dsv/test/fixtures/process/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import fruit from './fruit.csv';

t.deepEqual(fruit, [
{ type: 'apples', count: 7 },
{ type: 'pears', count: 4 },
{ type: 'bananas', count: 5 }
]);
69 changes: 69 additions & 0 deletions packages/dsv/test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const test = require('ava');
const { rollup } = require('rollup');

const dsv = require('..');

process.chdir(__dirname);

const testBundle = async (t, bundle) => {
const { output } = await bundle.generate({ format: 'cjs' });
const [{ code }] = output;
const func = new Function('t', code); // eslint-disable-line no-new-func

return func(t);
};

test('converts a csv file', async (t) => {
const bundle = await rollup({
input: 'fixtures/basic-csv/main.js',
plugins: [dsv()]
});
t.plan(1);
return testBundle(t, bundle);
});

test('converts a tsv file', async (t) => {
const bundle = await rollup({
input: 'fixtures/basic-tsv/main.js',
plugins: [dsv()]
});
t.plan(1);
return testBundle(t, bundle);
});

test('uses a custom processor', async (t) => {
const parse = (value) => (isNaN(+value) ? value : +value);

const bundle = await rollup({
input: 'fixtures/process/main.js',
plugins: [
dsv({
processRow(row) {
Object.keys(row).forEach((key) => {
row[key] = parse(row[key]); // eslint-disable-line no-param-reassign
});
}
})
]
});
t.plan(1);
return testBundle(t, bundle);
});

test('uses a custom processor with id', async (t) => {
const bundle = await rollup({
input: 'fixtures/process-id/main.js',
plugins: [
dsv({
processRow(row, id) {
return {
type: row.type[/lower/.test(id) ? 'toLowerCase' : 'toUpperCase'](),
count: +row.count
};
}
})
]
});
t.plan(2);
return testBundle(t, bundle);
});
Loading