GithubHelp home page GithubHelp logo

json-mapper-json's Introduction

json-mapper-json

Simple library to convert a json object into a new json object formatted by a template.

Installation

Install via npm:

$ npm install json-mapper-json

Documentation

Usage

const jsonMapper = require('json-mapper-json');

jsonMapper(json<Object>, template<Object>) => Promise

Template Syntax Explanations

{
  newFieldName1: {
    path: <String>, // required
    required: <Boolean> // not required, default `true`
    formatting: <Function> // optional (ex: function(value) {return value + '_formatted';})
    defaultValue: <AnyType> // optional
    type: <NativeType> // optional (ex: String, Number, Boolean, ...) (not supported yet)
    nested: { <Object> // optional
      newNestedFieldName: <String>,
      required: <Boolean> // not required, default `true`
      formatting: <Function> // optional
      defaultValue: <AnyType> // optional
      type: <NativeType> // optional (ex: String, Number, Boolean, ...) (not supported yet)
      nested: { <Object> // optional
        ...
      },
    },
  },
  newFieldName2: <String> // (it's the path, syntactic sugar for {path: ''})
  ...
}

Path Key Words

  • $root: give possibility to access the root given object in a nested path.
  • $item: give possibility to access of the all item of an array in a nested path.
  • $empty: give possibility to create skip path, to create empty object to be able to merge paths (see example).

Example

Basic

jsonMapper({
  field: 'value',
}, {
  'new_field': {
    path: 'field',
  },
}).then((result) => {
  /*
  result === {
    'new_field': 'value',
  }
  */
});

Basic with required

jsonMapper({
  field1: 'value1',
}, {
  'new_field1': {
    path: 'field1',
  },
  'new_field2': {
    path: 'field2',
    required: false,
  },
}).then((result) => {
  /*
  result === {
    'new_field1': 'value1',
  }
  */
});

Basic with defaultValue

jsonMapper({
  field1: 'value1',
}, {
  'new_field1': {
    path: 'field1',
  },
  'new_field2': {
    path: 'field2',
    defaultValue: 'default_value',
  },
}).then((result) => {
  /*
  result === {
    'new_field1': 'value1',
    'new_field2': 'default_value',
  }
  */
});
jsonMapper({
  field1: 'value1',
  nested: {
    field3: 'value3',  
  },
}, {
  'new_field1': {
    path: 'field1',
  },
  'new_field2': {
    path: 'field2',
  },
}).then((result) => {
  /*
  throw Error: Invalid path nested.field2 (field2)
  */
});

Basic with nested

jsonMapper({
  field1: {
    field2: {
      field3: 'value',
      field4: 'value4',
    },
  },
}, {
  'new_field': {
    path: 'field1.field2',
    nested: {
      'nested_field1': {
        path: 'field3',
      },
      'nested_field2': {
        path: 'field4',
      },
    },
  },
}).then((result) => {
  /*
  result === {
    'new_field': {
      'nested_field1': 'value',
      'nested_field2': 'value4',
    }
  }
  */
});

Basic with formatting

jsonMapper({
  field1: {
    field2: {
      field3: 'value',
    },
  },
}, {
  'new_field': {
    path: 'field1.field2.field3',
    formatting: (value) => {return value + '_formatted';},
  },
}).then((result) => {
  /*
  result === {
    'new_field': 'value_formatted',
  }
  */
});

Array

jsonMapper([{
  field: 'value1',
}, {
  field: 'value2',
}, {
  field: 'value3',
},
], {
  'new_field': {
    path: 'field',
  },
}).then((result) => {
  /*
  result === [
    {'new_field': 'value1'},
    {'new_field': 'value2'},
    {'new_field': 'value3'},
  ]
  */
});

Array with formatting

jsonMapper([{
  field: 'value1',
}, {
  field: 'value2',
}, {
  field: 'value3',
},
], {
  'new_field': {
    path: 'field',
    formatting: (value, index) => (`${value}_formatted_${index}`),
  },
}).then((result) => {
  /*
  result === [
    {'new_field': 'value1_formatted_0'},
    {'new_field': 'value2_formatted_1'},
    {'new_field': 'value3_formatted_2'},
  ]
  */
});

Usage of the syntactic sugar for path

jsonMapper({
  field: 'value',
}, {
  'new_field': 'field',
}).then((result) => {
  /*
  result === {
    'new_field': 'value',
  }
  */
});

Array with nested and path syntactic sugar

jsonMapper([{
  field: {'nested_field': 'value1'},
}, {
  field: {'nested_field': 'value2'},
}, {
  field: {'nested_field': 'value3'},
},
], {
  'new_field': {
    path: 'field',
    nested: {
      'new_nested_field': 'nested_field',
    },
  },
}).then((result) => {
  /*
  result === [
    {'new_field': {'new_nested_field': 'value1'}},
    {'new_field': {'new_nested_field': 'value2'}},
    {'new_field': {'new_nested_field': 'value3'}},
  ]
  */
});

Usage of the key word $root for path

jsonMapper({
  'content': {
    'result': [
      {
        'courseStatisticsDto': {
          'times': 3,
          'persons': 1,
          'courseCode': '',
        },
        'courseAddressDto': {},
        'endDate': 1460590552000,
        'startDate': 1460590552000,
        'name': 'Example Course',
      },
    ],
    'type': 'offline',
  },
}, {
  data: {
    path: 'content.result',
    nested: {
      name: 'name',
      code: 'courseStatisticsDto.courseCode',
      type: '$root.content.type',
    },
  },
}).then((result) => {
/*
  result === {
    'data': [{
      'name': 'Example Course',
      'code': '',
      'type': 'offline',
    }],
  }
*/
});

Usage of the key word $item for path

jsonMapper({
	hits: {
		total: 1,
		hits: [{
			_index: 'some_index',
			_type: 'some_type',
			_id: '123456',
			_score: 1,
			_source: {
				id: 123456
			},
		}],
	},
}, {
	hits: {
		path: 'hits.hits',
		nested: {
			id: '_source.id',
			type: {
				path: '$item',
				formatting: (value, index) => (`${value._index}/${value._type}/${index}`),
			},
		},
	},
}).then((result) => {
/*
  result === {
    'hits': [{
      'id': 123456,
      'type': 'some_index/some_type/0',
    }],
  }
*/
});

Usage of the key word $empty for path

jsonMapper({
  field1: {
    field2: {
      field3: 0
    },
    field4: {
      field5: ['value1', 'value2'],
    },
  },
}, {
  'new_field1': {
    path: 'field1',
    nested: {
      'new_field2': {
        path: '$empty',
        nested: {
          new_field3: {
            path: 'field2.field3'
          },
          new_field4: {
            path: 'field4.field5',
          },
        },
      },
    },
  },
}).then((result) => {
  /*
  {
    new_field1: {
      new_field2: {
        new_field3: 0,
        new_field4: ['value1', 'value2'],
      },
    },
  }
  */
});

## Note

this library is very usefull when you have well design models and have to communicate with horrible webservices.

## TODO

* manage `type` property

## Contributing

This project is a work in progress and subject to API changes, please feel free to contribute

json-mapper-json's People

Contributors

marchah avatar slamuu avatar xcatliu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

json-mapper-json's Issues

[Question]: Array from single item

Hey,

Is there a way to output an array of one item from a single object?

Input Object:
{ email: "[email protected]" }

Required output:
{ emails: [ { email: "[email protected]" }] }

I have tried the below but its not quite what I need.

{
  "emails": {
    "path": "$empty",
    "nested": {
      "email": {
        "path": "email"
      }
    }
  }
}

Also this is invalid:

{
  "emails": [{
    "path": "$empty",
    "nested": {
      "email": {
        "path": "email"
      }
    }
  }]
}

[Bug] Throw wrong error with formatting and key word `$root` and undefined value

jsonMapper.then({
  field1: {
    field2: {
      field3: 'value',
    },
  },
}, {
  'new_field1': {
    path: '$root.field1',
    formatting: (field1) => {
      return field1.field2.field4;
    }
  },
}).catch((e) => {
  console.error(e);
});

Should throw error

TypeError: Cannot read property 'field4' of undefined

But got

TypeError: Cannot read property 'field2' of undefined

[Feature request] Support defaultValue

Hi, this is an awesome tool to transform data. Thanks for your awesome work!
I am thinking if it's possible to add an option to pass defaultValue to a field. Return the defaultValue rather than throw an error Invalid path xxx

Any keywords to get array item root properties in the formatting?

Hello, I'm using this lib and I like it. But today I faced an interesting situation.

I have a json from Elasticsearch:

{  
  "hits": {
    "total": 1,
    "hits": [
      {
        "_index": "some_index",
        "_type": "some_type",
        "_id": "123456",
        "_score": 1,
        "_source": {
          "id": 123456
        }
      }
    ]
  }
}

And I need to map it into json like this:

{
   "type": "some_index/some_type"
   "id": "123456"
}

My mapping template:

{	
	"hits": {
		path: "hits.hits",
		nested: {
			"id": {
				path: "_source.id"
			},
			"type": {
				path: "_type",
				formatting: (value) => { return value; }
			}
		}
	}
}

So the problem is that I can't get both values from _index and _type at the same time because they are root properties of an array item.

Not the best solution is to wrap each array item like this. And I won't use it

"hits":[
   {
       "item": {
          "_index": "some_index",
          "_type": "some_type",
          "_id": "123456",
          "_score": 1,
          "_source": {
          "id": 123456
        }
    }
]

Is it possible to implement a new keyword like "$item" and it will be a whole array item, so it will be possible to grab any number of root properties at the same time.

Hope it's clear :)
Thanks in advance.

$root keyword problem

Hello, I'm having an issue with using the $root keyword. Here is my code:
var source = { "data": { "items": [ {"item": "one"}, {"item": "two"} ] } }

var template = { "query": { path: "data.items", nested: { "item": { path: "$item" } } } }

As a mapping result I will get this:
{ "query": [{ "term":{"item":"one} }, { "term":{"item":"two"} }] }

But when I change in the template 'path: "data.items"' to 'path: "$root.data.items"', I will get this:
{ "query": { "term": [ {"term":{"item":"one}}, {"term":{"item":"two"}} ] } }

So there is a strange behavior of the $root keyword.

mongoos dependency

./lib/constants.js
const mongoose = require('mongoose');

However mongoose is declared as a devDependency. Kindly look into this which will cause a build error.

Create key word to skip path

ex:

main: {
	path: '$EMPTY',
	nested: {
		nested_1: '...',
		nested_2: '...',
	}
}

result:

main: {
	nested_1: '...',
	nested_2: '...',
}

Big number of nested fields

Hello.
Sometimes there is a need to get a JSON with a mass of nested fields as a result of mapping like this:
"query": { "constant_score" : { "filter" : { "bool" : { "must" : [ { "term" : {"name" : "foo"}}, { "term" : {"id": 1}} ] } } } }

A source is:
var source = { "data": { "terms": [ {"item": "one"}, {"item": "two"} ] } }

Is there a way to avoid templates like this:
"query": { path: "$root.data", nested: { "constant_score": { path: "$root.data", nested: { "filter" : { path: "$root.data", nested: { "bool": { path: "$root.data", nested: { "must": { path: "$root.data.terms" } } } } } } } } }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.