├── .gitignore
├── index.js
├── foobar.json
├── collaborators.md
├── package.json
├── cli.js
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // var through = require('through2')
2 | var merge = require('merge-object-streams')
3 |
4 | module.exports = function(streams) {
5 | return new merge(streams)
6 | }
7 |
--------------------------------------------------------------------------------
/foobar.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": [
3 | {
4 | "a": {
5 | "all": "lowercase"
6 | },
7 | "b": {
8 | "ALL": "CAPS"
9 | },
10 | "c": {
11 | "All": "Propercase"
12 | }
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/collaborators.md:
--------------------------------------------------------------------------------
1 | ## Collaborators
2 |
3 | json-merge is only possible due to the excellent work of the following collaborators:
4 |
5 |
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json-merge",
3 | "version": "1.2.0",
4 | "bin": {
5 | "json-merge": "cli.js"
6 | },
7 | "description": "given two streams of newline delimited JSON data perform a merge/extend on each object in the stream",
8 | "keywords": [
9 | "stream",
10 | "ldjson",
11 | "ndjson",
12 | "newline",
13 | "parsing",
14 | "cli",
15 | "command-line"
16 | ],
17 | "main": "index.js",
18 | "scripts": {
19 | "test": "npm run pipe-test && npm run parse-test",
20 | "pipe-test": "cat foobar.json | json-merge \"data.*.a\" \"data.*.b\" \"data.*.c\"",
21 | "parse-test": "json-merge foobar.json --parse=\"data.*.a\" foobar.json --parse=\"data.*.b\""
22 | },
23 | "author": "max ogden",
24 | "license": "BSD",
25 | "dependencies": {
26 | "JSONStream": "^0.8.4",
27 | "ldjson-stream": "^1.1.0",
28 | "merge-object-streams": "0.0.3",
29 | "request": "^2.36.0"
30 | },
31 | "devDependencies": {},
32 | "repository": {
33 | "type": "git",
34 | "url": "https://github.com/maxogden/json-merge.git"
35 | },
36 | "bugs": {
37 | "url": "https://github.com/maxogden/json-merge/issues"
38 | },
39 | "homepage": "https://github.com/maxogden/json-merge"
40 | }
41 |
--------------------------------------------------------------------------------
/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var merge = require('./')
4 | var fs = require('fs')
5 | var request = require('request')
6 | var ldj = require('ldjson-stream')
7 | var JSONStream = require('JSONStream')
8 |
9 | run()
10 |
11 | function run() {
12 | if (!process.argv[2] || !process.argv[3]) {
13 | var usage = 'Usage: json-merge [options] [options] [...]'
14 | usage += '\n\nOptions'
15 | usage += '\n--parse=\t Parse the precedent source with '
16 | console.error(usage)
17 | }
18 |
19 | var args = process.argv.splice(2).reduce(function (sources, current, cb) {
20 | if(current.match(/^--parse=/)) {
21 | sources.push({uri: sources.pop().uri, parse: current.substring(8)})
22 | } else {
23 | sources.push({uri: current})
24 | }
25 | return sources
26 | }, [])
27 |
28 | var streams = args.map(getStream);
29 | var merger = merge(streams)
30 | merger.pipe(ldj.serialize()).pipe(process.stdout)
31 | }
32 |
33 | function getStream(source) {
34 | var sourceStream
35 | var uri = source.uri
36 |
37 | if (uri.match(/^http\:\/\//)) {
38 | sourceStream = request(uri)
39 | } else if (fs.existsSync(uri)) {
40 | sourceStream = fs.createReadStream(uri)
41 | } else {
42 | return process.stdin.pipe(JSONStream.parse(uri))
43 | }
44 |
45 | if(source.parse) {
46 | return sourceStream.pipe(JSONStream.parse(source.parse))
47 | } else {
48 | return sourceStream.pipe(ldj.parse())
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # json-merge
2 |
3 | given multiple streams of newline delimited JSON data perform a merge/extend on each object in the stream
4 |
5 | [](https://nodei.co/npm/json-merge/)
6 | 
7 |
8 | ## usage
9 |
10 | ```
11 | npm install json-merge -g
12 | Usage: json-merge [options] [options] [...]
13 |
14 | Options
15 | --parse= Parse the precedent source with
16 | ```
17 |
18 | sources can be one of 3 things:
19 |
20 | - paths to newline-delimited json data files
21 | - HTTP uris that return newline-delimited json data
22 | - JSONStream selector syntax to be used to parse stdin into a stream of JS objects
23 |
24 | ## examples
25 |
26 | ### newline delimited json files
27 |
28 | e.g. given a file `a.json`:
29 |
30 | ```
31 | {"foo": "bar"}
32 | ```
33 |
34 | and a file `b.json`:
35 |
36 | ```
37 | {"taco": "pizza"}
38 | ```
39 |
40 | then running:
41 |
42 | ```
43 | json-merge a.json b.json
44 | ```
45 |
46 | would output:
47 |
48 | ```
49 | {"foo": "bar", "taco": "pizza"}
50 | ```
51 |
52 | ### JSONStream parsing
53 |
54 | you can also specify [JSONStream](http://npmjs.org/JSONStream) query syntax and `json-merge` will parse stdin
55 |
56 | e.g. if `foobar.json` is:
57 |
58 | ```
59 | {
60 | "data": [
61 | {
62 | "a": {
63 | "all": "lowercase"
64 | },
65 | "b": {
66 | "ALL": "CAPS"
67 | }
68 | }
69 | ]
70 | }
71 | ```
72 |
73 | then running:
74 |
75 | ```
76 | cat foobar.json | json-merge "data.*.a" "data.*.b"
77 | ```
78 |
79 | would output:
80 |
81 | ```
82 | {"all":"lowercase","ALL":"CAPS"}
83 | ```
84 |
85 | ### Parsing different sources
86 |
87 | A given a file `food1.json`:
88 |
89 | ```
90 | {
91 | "salty":
92 | {
93 | "tacos": "muybien",
94 | "pretzel": "jawohl"
95 | }
96 | }
97 |
98 | ```
99 |
100 | and a file `food2.json`:
101 |
102 | ```
103 | {
104 | "sweet":
105 | {
106 | "waffle": "delicious",
107 | "pancake": "yummy"
108 | }
109 | }
110 | ```
111 |
112 | then running:
113 |
114 | ```
115 | json-merge food1.json --parse="salty" food2.json --parse="sweet"
116 | ```
117 |
118 | would output:
119 |
120 | ```
121 | {"tacos":"muybien","pretzel":"jawohl","waffle":"delicious","pancake":"yummy"}
122 |
--------------------------------------------------------------------------------