{"_id":"@amida-tech/jsonapter","_rev":"2-888eac1ee2f27377593bffd978495ad3","name":"@amida-tech/jsonapter","dist-tags":{"latest":"2.0.10"},"versions":{"2.0.8":{"name":"@amida-tech/jsonapter","version":"2.0.8","description":"Template based JSON to JSON transformer","main":"./index.js","directories":{"lib":"lib"},"scripts":{"test":"grunt test","verify":"grunt"},"author":{"name":"Afsin Ustundag","email":"afsin@amida.com"},"contributors":[{"name":"Gautam Dev","email":"gdind2003@gmail.com"}],"license":"Apache-2.0","engines":{"node":">= 14.19.1"},"dependencies":{"lodash":"^4.17.21"},"devDependencies":{"@amida-tech/jsonave":"1.0.1","grunt":"^1.5.2","grunt-contrib-jshint":"^3.2.0","grunt-contrib-watch":"^1.1.0","grunt-jsbeautifier":"^0.2.13","grunt-mocha-test":"^0.13.3","grunt-run":"^0.8.1","jest":"^27.5.1"},"repository":{"type":"git","url":"git+https://github.com/amida-tech/jsonapter.git"},"keywords":["json to json","json2json","json transformer","json transform"],"bugs":{"url":"https://github.com/amida-tech/jsonapter/issues"},"homepage":"https://github.com/amida-tech/jsonapter","gitHead":"2419f2125e6a85c9a35e8e10c49f29af9a42be26","_id":"@amida-tech/jsonapter@2.0.8","_nodeVersion":"16.14.2","_npmVersion":"8.8.0","dist":{"integrity":"sha512-ZrVhZc9XqKT9FbyKDLGRtT7QOSiK4Dz0Cu3eFEWzkwG7P+nle1kqwQHHwsWMirAaHdZ45R182dBI529UoNYJrw==","shasum":"93dc8e0f08f791743d369eccf157a2685f7e53a6","tarball":"https://registry.npmjs.org/@amida-tech/jsonapter/-/jsonapter-2.0.8.tgz","fileCount":67,"unpackedSize":179893,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAuzPtUsppeAfDcgdqrF+N89kNk2yc+usoy5R7pvsFIgIhAK9LoO5OBwcK3c21hLo6cvaIjA980icfM19/sLwz2LeT"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJic964ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6fQ//Zo9gHIWC9qib4hTI5DjRo2kt3PR9undGCuKIeJKN3hoWZFjp\r\nsiuKgGQdB0R1VnycSzeeJ65LkcxnkTssJWWPdxGqyikYZ6QzrhWVpB+X1mx4\r\nhQeo4ZoY12qqP84ZTe32t3ULroV4Re7ap/D+dAMzz8HekA309DnA5nwRWV6g\r\nT+JoDJfJeXHNBBb1sK369qwjVNxAJ6drvpLWlCrZ82H61c1v1QtH4tfFXto4\r\nJraU9qo8k1Jn9pkMhfXZFhpg4tV0YfQ45Gj2xIH0rL/Q3OfcEo9aUK6EHJXj\r\nO9tnOSWBnO2zVB68jmxKN7omoQJwDRtStsX60lD/1ZrJf4ArJHXGVkdAfEp9\r\nDVFwDVu1RckUbsBO2YSw8AbzZfWTYkgTRuQK/El1cBJVj95xKyc2QTRbtJQ4\r\nog7ydINvH7ABw68pUJOzE1Kx0Kx4s56PuO5tN3fuOsAPen0K1waLvXAWDwvE\r\nba0/s0N3PRvii0JWY/DyOoTAo62/iU1SrlPbO5VVdcVe8JrI1cjIeKKbPJ4M\r\ndP8UdZH30v6CK2gD8wTEPOQVZXwCYWK1ruxGmSxLnbeqxVf0+/Fm+jDXNlpH\r\n+oPN1r7MGmslb75mfnaMTaftQ11c1ZelUpFJZlFuTkw8vjza8xw+a1GdEIVu\r\niq1sIO0O/r9/4UsnWlPphRmwrsRCvRWwQpY=\r\n=WRwG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"manhydra","email":"marc.sylvestre@manhydra.com"},"maintainers":[{"name":"manhydra","email":"marc.sylvestre@manhydra.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/jsonapter_2.0.8_1651760824000_0.3456870045056606"},"_hasShrinkwrap":false},"2.0.9":{"name":"@amida-tech/jsonapter","version":"2.0.9","description":"Template based JSON to JSON transformer","main":"./index.js","directories":{"lib":"lib"},"scripts":{"test":"grunt test","verify":"grunt"},"author":{"name":"Afsin Ustundag","email":"afsin@amida.com"},"contributors":[{"name":"Gautam Dev","email":"gdind2003@gmail.com"}],"license":"Apache-2.0","engines":{"node":">= 14.19.3"},"dependencies":{"lodash":"^4.17.21"},"devDependencies":{"@amida-tech/jsonave":"^1.0.2","grunt":"^1.5.3","grunt-contrib-jshint":"^3.2.0","grunt-contrib-watch":"^1.1.0","grunt-jsbeautifier":"^0.2.13","grunt-mocha-test":"^0.13.3","grunt-run":"^0.8.1","jest":"^27.5.1"},"repository":{"type":"git","url":"git+https://github.com/amida-tech/jsonapter.git"},"keywords":["json to json","json2json","json transformer","json transform"],"bugs":{"url":"https://github.com/amida-tech/jsonapter/issues"},"homepage":"https://github.com/amida-tech/jsonapter","gitHead":"c69045d99877e864ddeb9990864548b213581993","_id":"@amida-tech/jsonapter@2.0.9","_nodeVersion":"16.14.2","_npmVersion":"8.10.0","dist":{"integrity":"sha512-Vk4IKnmN0TG5TKmRAH8TTBWxH5exknh+woXEs3ASF3AEkLXIgVNjtbctGpQ9SbjPQfq6OPv3wSuWxnkswiR2gw==","shasum":"23ab0767f1b821bc4c7da136f6b70ed8b99ff4c5","tarball":"https://registry.npmjs.org/@amida-tech/jsonapter/-/jsonapter-2.0.9.tgz","fileCount":67,"unpackedSize":179997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWFDc7AH2n59UhfZ6uACBHmWy+Uz01FaZMT8zdK06iaQIhALryGzaBTyQVxazJ38oVKnBrLxqCDg9DXhYHMB8oSvEa"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiloDyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqTSA//STe0ZT9LjRPd82AE7T0J/K7mQPhcvWVIXI8ro0E6yH8AN5CE\r\ndpdXFB6XCgyBr4/hsALiUgjx+qc1BX/jQMH5fx8gHyGNDOOKnjUelCEbh5ZW\r\nsoYK3gFeVRIrB4iGbQIIrl9OLnk7V86P6WO2gTA1jpjN9lU6OpS7Gce3q8om\r\nOB3+3rEWAsGLeWL8uWt+4T1bnXIJFQaVwJAmgZPufMv09/CQn+3eDNNJpqLY\r\nHaTCB0rP6Ir1QTzFQied5XupEkX42JVwgblEo3DIyLW1TSvuG/vrf4l9yuqo\r\nO2mO/1VyJcxO6JyAIgug0v4duZEIZbSrcb0wv9SbOg61pL5HJzCK5TSCg72l\r\nSnXSxL6YHkqZ3MaIHgk3I3yxauZAiwR3rus/vgZHiT+Lf9bSIk5OOVXvWB9z\r\noKuXHB7puaX4h/q2Gdyuw+l6YcDSLokrMd8J6F9I3EWVzE7J6mfqnuekBRoE\r\nWoE2WHg1jJxNtLp7fnW/Jov1WVbOFiS8O2u9L0ONRprZzUwniPzSwtWjjPoW\r\nDqWtYfqfKqRpca7LkWN/eq3FCuzI7ph6qgNZh63JL6oJ5ELsKMWU1OeBHrU4\r\nIyAhKlHsfMTKT4RFTbSIr+fmOVNPxnY8Eip3E9XMXRK2yQ2DmzBspkLVEsQr\r\nyg0VxRiX3vY0Nin87DcN4wi/Jftc05pCdHU=\r\n=gR9B\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"manhydra","email":"marc.sylvestre@manhydra.com"},"maintainers":[{"name":"manhydra","email":"marc.sylvestre@manhydra.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/jsonapter_2.0.9_1654030577975_0.5446669338625876"},"_hasShrinkwrap":false},"2.0.10":{"name":"@amida-tech/jsonapter","version":"2.0.10","description":"Template based JSON to JSON transformer","main":"./index.js","directories":{"lib":"lib"},"scripts":{"test":"grunt test","verify":"grunt"},"author":{"name":"Afsin Ustundag","email":"afsin@amida.com"},"contributors":[{"name":"Gautam Dev","email":"gdind2003@gmail.com"}],"license":"Apache-2.0","engines":{"node":">= 14.19.3"},"dependencies":{"lodash":"^4.17.21"},"devDependencies":{"@amida-tech/jsonave":"^1.0.3","grunt":"^1.5.3","grunt-contrib-jshint":"^3.2.0","grunt-contrib-watch":"^1.1.0","grunt-jsbeautifier":"^0.2.13","grunt-mocha-test":"^0.13.3","grunt-run":"^0.8.1","jest":"^27.5.1"},"repository":{"type":"git","url":"git+https://github.com/amida-tech/jsonapter.git"},"keywords":["json to json","json2json","json transformer","json transform"],"bugs":{"url":"https://github.com/amida-tech/jsonapter/issues"},"homepage":"https://github.com/amida-tech/jsonapter","gitHead":"061b206c9a27df17d88bd8b04248d06132aa0133","_id":"@amida-tech/jsonapter@2.0.10","_nodeVersion":"16.14.2","_npmVersion":"8.12.1","dist":{"integrity":"sha512-RHQk5AE5qG46wyFkxP4brtJI0eP8mAsqY1Hcf++8vd97I0ECLquEARwKHN+O6C7zP3hFOlTaRceqnXEmY51IwA==","shasum":"9d642923919040b1518e3247d1b9a95489ec60c3","tarball":"https://registry.npmjs.org/@amida-tech/jsonapter/-/jsonapter-2.0.10.tgz","fileCount":67,"unpackedSize":179998,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpth6+ssAvHyciOogrrNREoActJJhjU2yKXN8dhM2bzwIhAPdwmwkmuaQ8NYyl0rZYHNiWsDGtNMp20xJzmkWTeRjB"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6ZQzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmptaw//fxn3Bd7P9cM5VOL4Vx5jQyAausKxXMBjF/ODrIJysm4ZYp7D\r\nEL8AcCJfQNMdhytVYIB7Zdu+4soGZE254EevjBhzux3teEnqvli+R52X/vE4\r\n6g5qkaC83NLCjO19wL4mxgT+Tk20+TQUlXBxehXayp57FT9AuWHJV84qIf3D\r\nyja0HqWTPSvbO3hv7fBZnYSVdM/5SLSZnwhvYra4ps1GWHmQ+23jM2mkKGBL\r\nWLpUUxD+mtkpiEXPXmuFfrHdRGbiEBlm4lcwj07DyT+O3z+F7VW5NDnDoPNu\r\nTQfePnFStG/ACmIkgd1SIstutt8JcTg/B9jK+7tDjYP9tm1zjCqyY2qU7VyP\r\nt00Uvk3QJVimCwtUuKp7xN4l97aOiaNXXvCqxgNWNeCnQ/GP5XXI1khkjdX9\r\nJVtNPDnXIvZdJ/ZQ2zArJc7yoMFUmkIN2YjyPpXnIEomAe5geaIMgJOkrlJe\r\nPmdCCDocQf232V2exEuaHocNaqz2uVqi38lMgIDSg2uagLK5AxuCv4wPM2Ws\r\nrQ9ia0SDvlyMcEtXFZM1i0vF7z2Tx6/MojVjC/Wsknggf+CxOtCMSM31FYET\r\nVelf05TI8UjQ3oEerD+/kMuJwvYuP/NKEVkzxEvGbaELPr3q0KZepYfZfnCb\r\nbZ4cUlxKAUEri659VU+a0TFgDeNL1rBaYPQ=\r\n=U2bx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"manhydra","email":"marc.sylvestre@manhydra.com"},"maintainers":[{"name":"manhydra","email":"marc.sylvestre@manhydra.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/jsonapter_2.0.10_1659474995685_0.1383013729268725"},"_hasShrinkwrap":false}},"time":{"created":"2022-05-05T14:27:03.930Z","2.0.8":"2022-05-05T14:27:04.189Z","modified":"2022-08-02T21:16:35.937Z","2.0.9":"2022-05-31T20:56:18.197Z","2.0.10":"2022-08-02T21:16:35.857Z"},"maintainers":[{"name":"manhydra","email":"marc.sylvestre@manhydra.com"}],"description":"Template based JSON to JSON transformer","homepage":"https://github.com/amida-tech/jsonapter","keywords":["json to json","json2json","json transformer","json transform"],"repository":{"type":"git","url":"git+https://github.com/amida-tech/jsonapter.git"},"contributors":[{"name":"Gautam Dev","email":"gdind2003@gmail.com"}],"author":{"name":"Afsin Ustundag","email":"afsin@amida.com"},"bugs":{"url":"https://github.com/amida-tech/jsonapter/issues"},"license":"Apache-2.0","readme":"jsonapter\n=====================\n\nTemplate Rules based JSON Transformer\n\n[![NPM](https://nodei.co/npm/@amida-tech/jsonapter.png)](https://nodei.co/npm/@amida-tech/jsonapter/)\n\n[![Build Status](https://travis-ci.org/amida-tech/jsonapter.svg)](https://travis-ci.org/amida-tech/jsonapter)\n[![Coverage Status](https://coveralls.io/repos/amida-tech/jsonapter/badge.png)](https://coveralls.io/r/amida-tech/jsonapter)\n\nThis library provides a template rules based formalism to describe JSON to JSON transformations declaratively.  This formalism is primarily designed for health data translation between various formats such as FHIR and CCDA.\n\n## Usage\n\nIn its most basic form JSON to JSON transformations are described by a template object where [`content`](#content) properties recursively describe destination keys, [`dataKey`](#dataKey) properties describe source keys, and [`value`](#value) properties describe formatting\n```js\nvar upper = function(input) {\n\treturn input ? input.toUpperCase() : null;\n};\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a.c'\n        },\n        dest_b: {\n            content: {\n                dest_b0: {\n                    value: upper,\n                    dataKey: 'b.c'\n                },\n                dest_b1: {\n                    value: upper,\n                    dataKey: 'd'\n                }\n            },\n            dataKey: 'a'\n        }\n    }\n};\n```\nAn engine instance is available from jsonapter and can be used to transform an `input` as described by the template\n```js\nvar bbj2j = require('jsonapter');\nvar j2j = bbj2j.instance();\n\nvar input = {\n    a: {\n        b: {\n            c: 'value_0'\n        },\n        c: 'value_2',\n        d: 'value_1'\n    }\n};\n\nvar r = j2j.run(template, input);\nconsole.log(r); // {dest_a: 'value_2', dest_b: {dest_b0: 'VALUE_0', dest_b1: 'VALUE_1'}}\n```\n\n## Standard Template Rules\n\nThe following are the list of all keys that have special meaning in template objects\n- [`dataKey`](#dataKey)\n- [`value`](#value)\n- [`content`](#content)\n- [`arrayContent`](#arrayContent)\n- [`constant`](#constant)\n- [`existsWhen`](#existsWhen)\n- [`existsEither`](#existsEither)\n- [`existsUnless`](#existsUnless)\n- [`dataTransform`](#dataTransform)\n- [`default`](#default)\n- [`multiple`](#multiple)\n- [`single`](#single)\n- [`firstOf`](#firstOf)\n- [`assign`](#assign)\n- [`ignoreDeep`](#ignoreDeep)\n- [`paramKey`](#paramKey)\n- [`arrayIndex`](#arrayIndex)\n- [`size`](#size)\n- [`timeStamp`](#timeStamp)\n- [`template`](#template)\n- [`skip`](#skip)\n- [`output`](#output)\n- [`pick`](#pick)\n- [`omit`](#omit)\n\n### <a id=\"dataKey\"></a>`dataKey` rule ###\n\nThis rule selects a particular property of input. It can a `string`, `array` or `function`.\n```js\nvar template = {\n    dataKey: 'a'\n};\n\nvar r0 = j2j.run(template, {\n    a: 1,\n    b: 2\n});\nconsole.log(r0); // 1\n\nvar r1 = j2j.run(template, {\n    b: 2\n});\nconsole.log(r1); // null\n\n\nvar r2 = j2j.run(template, {\n    a: {\n        b: 2\n    }\n});\nconsole.log(r2); // {b: 2}\n```\n\nThe properties can be deep\n```js\nvar template = {\n    dataKey: 'a.b.c'\n};\n\nvar r0 = j2j.run(template, {\n    a: {\n        b: {\n            c: 'value'\n        }\n    }\n});\nconsole.log(r0); // 'value'\n\nvar r1 = j2j.run(template, {\n    a: 2\n});\nconsole.log(r1); // null\n```\n\nIf the property or any of the properties on the deep property is an array `dataKey` you can use jsonave\n```js\nvar jsonave = require('@amida-tech/jsonave').instance;\n\nvar template = {\n    dataKey: jsonave('a.b[*].c')\n};\n\nvar r = j2j.run(template, {\n    a: {\n        b: [{\n            c: 'value_0'\n        }, {\n            d: 'value_1'\n        }, {\n            c: 'value_2'\n        }]\n    }\n});\nconsole.log(r); // ['value_0', 'value_2']\n```\nCurrently only one array on a deep property is supported.  Multiple arrays will result in array of arrays.\n\n`0` on a deep property is treated as a special case and selects the first element of the array\n```js\nvar template = {\n    dataKey: 'a.b.0.c'\n};\n\nvar r = j2j.run(template, {\n    a: {\n        b: [{\n            c: 'value_0'\n        }, {\n            d: 'value_1'\n        }, {\n            c: 'value_2'\n        }]\n    }\n});\nconsole.log(r); // 'value_0'\n```\n\n`dataKey` can be a function.  In particular JSONPath expressions are particularly useful and available from [jsonave](https://github.com/amida-tech/jsonave)\n```js\nvar jsonave = require('@amida-tech/jsonave').instance;\nvar template = {\n    dataKey: jsonave('book[1:].price')\n};\n\nvar r = j2j.run(template, {\n    book: [{\n        price: 10\n    }, {\n        price: 20\n    }, {\n        price: 30\n    }]\n});\n\nconsole.log(r); // [20, 30]\n```\nOne can pass a `source` parameter which can have value `parent`. It will lookup from the parent object.\n\nThe `template` below will \n\n```js\n\nvar template = {\n    dataKey: \"data\",\n    template: {\n        dataKey: \"address\",\n        content: {\n            company: {dataKey: \"company\", source: \"parent\"},\n            street: {dataKey: \"street\"},\n            city: {dataKey: \"city\"},\n            state: {dataKey: \"state\"},\n            zip: {dataKey: \"zip\"}\n        }\n    }\n};\n\nvar input = {\n    data: {\n        company: \"Google\",\n        address: {\n            street: \"1600 Amphitheatre Parkway\",\n            city: \"Mountain View\",\n            state: \"CA\",\n            zip: 94043\n        }\n    }\n};\n\n```\nThis will produce the following output :\n\n```js\n\n{\n    company: \"Google\",\n    street: \"1600 Amphitheatre Parkway\",\n    city: \"Mountain View\",\n    state: \"CA\",\n    zip: 94043\n};\n\n```\n\n\nA second [`context`](#context) parameter is also passed to `dataKey` functions.  By default this parameter is an empty object but that can be [overridden](#context).  This is useful to further customize JSONPath function.\n\n`dataKey` can be an array.  In that case the first deep property that evaluates to a value that is not `null` is selected\n```js\nvar template = {\n    dataKey: ['a.b', 'a.c']\n};\n\nvar r0 = j2j.run(template, {\n    a: {\n        b: 1,\n        c: 2\n    }\n});\nconsole.log(r0); // 1\n\nvar r1 = j2j.run(template, {\n    a: {\n        c: 3\n    }\n});\nconsole.log(r1); // 3\n\nvar r2 = j2j.run(template, {\n    a: {\n        d: 4\n    }\n});\nconsole.log(r2); // null\n```\n\n### <a id=\"paramKey\"></a>`paramKey` rule ###\n\nThis rule selects a particular property of params, which can be passed as a optional third parameter to the run function as shown below :\n```js\nvar template = {\n    paramKey: 'a'\n};\n\nvar r0 = j2j.run(template, {}, {\n    a: 1\n});\nconsole.log(r0); // 1\n```\n\nThe `paramKey` value can be an object\n\n```js\n\nvar template = {\n    paramKey: 'paramObject'\n};\n\nvar r0 = j2j.run(template, {}, {\n    paramObject: {\n        a : {\n            b: \"test\"\n        }\n    }\n});\nconsole.log(r0);\n\n{\n   a : {\n          b: \"test\"\n   }\n}\n```\n\n### <a id=\"arrayIndex\"></a>`arrayIndex` rule ###\nThis rule is primarily used to get the index of the array. Optionally `start` can be given.\nWithout `start` it will be zero based as usual.\n\n```js\n      var template = {\n          content: {\n              cost: {dataKey: 'price'},\n              num: {arrayIndex: {}}\n          }\n      };\n\n      var r = j2j.run(template,\n          [{\n              price: 20\n          }, {\n              price: 30\n          }]);\n\nconsole.log(r); // // [{cost: 20, num: 0}, {cost: 30, num: 1}]\n```\n\nWith `start` :\n\n```js\n\n      var template = {\n          content: {\n              cost: {dataKey: 'price'},\n              num: {arrayIndex: {start: 1}}\n          }\n      };\n\n      var r = j2j.run(template,\n          [{\n              price: 20\n          }, {\n              price: 30\n          }]);\n\nconsole.log(r); // // [{cost: 20, num: 1}, {cost: 30, num: 2}]\n```\n\n### <a id=\"timeStamp\"></a>`timeStamp` rule ###\n\nThis rule is  used to get timeStamp as `{occurred: {timeStamp: {serialize: true}}`. \nIt will produce an output `occurred: \"2017-06-12T22:54:39.502Z\"`. \nThe `serialize` option is `true` by default. If it is `false` it will keep it a `Date` object.\nThe `serialize` option can be a `function` as well which one can use to formar the `Date` object.\nIf the timeStamp tag is invoked multiple times in the same template the output will be same. \n\nThis rule is primarily used to get the length of an array. It is also valid for length of string and object.\nIf it is in the context of an array the `size` will print the length of the array. If not it will check if it is in the same template with the `dataKey`.\n\n```js\n      var template = {\n          content: {\n              cost: {dataKey: 'price'},\n              num: {arrayIndex: {}},\n              total: {size: {}}\n          }\n      };\n\n      var r = j2j.run(template,\n          [{\n              price: 20\n          }, {\n              price: 30\n          }]);\n\nconsole.log(r); // // [{cost: 20, total:2, num: 0}, {cost: 30, total:2, num: 1}]\n```\n\n```js\n        var template = {dataKey: 'name', size: {}};\n        var r = j2j.run(template, {\n            name: 'USA'\n        });\n        //console.log(r); // 3\n        expect(r).to.deep.equal(3);\n```\n### <a id=\"template\"></a>`template` rule ###\n\nThis rule is primarily used to apply a nested template.\n```js\nvar nestedTemplate = {\n    value: function(input) {\n        return input.toUpperCase();\n    },\n    dataKey: 'b'\n};\n\nvar template = {\n    template: nestedTemplate,\n    dataKey: 'a'\n};\n\nvar r = j2j.run(template, {\n    a: {\n        b: 'value'\n    }\n});\nconsole.log(r); // 'VALUE'\n```\n\n### <a id=\"value\"></a> `value` rule ###\n\nThis rule is primarily used to format `input` or `input` property that is selected by `dataKey`.  In this case it is a function\n```js\nvar template = {\n    value: function (input) {\n        return input.toUpperCase();\n    },\n    dataKey: 'name'\n};\n\nvar r = j2j.run(template, {\n    name: 'joe'\n});\nconsole.log(r); // JOE\n```\n```js\nvar template = {\n    value: function (input) {\n        return input.toUpperCase();\n    }\n};\n\n\nvar r = j2j.run(template, 'joe');\nconsole.log(r); // JOE\n```\nOne can also use the parent inside the value function.\n\n```js\nvar template = {\n    value: function (input, parent) {\n        return parent.title.toUpperCase() + ' ' + input.toUpperCase();\n    },\n    dataKey: 'name'\n};\n\nvar r = j2j.run(template, {\n    name: 'joe',\n    title: 'mr'\n});\nconsole.log(r); // MR JOE\n```\n\n\nOne can also use the params to the value function.\n```js\nvar template = {\n    dataKey: 'name',\n    value: function (input, parent, params) {\n        return params.title[input.gender] + ' ' + input;\n    }\n};\n\nvar params = {title: { M: 'Mr', F: 'Ms'}};\n\nvar input = {name: 'Joe', gender: 'M'};\n\nvar r = j2j.run(template, input, params);\nconsole.log(r); // Mr Joe\n\nvar input1 = {name: 'Jane', gender: 'F'};\n\nvar r1 = j2j.run(template, input1, params);\nconsole.log(r1); // Ms Jane\n\n```\n\n\nThis rule can be used to return a primary data type\n```js\nvar template = {\n    value: 'names are classified',\n    dataKey: 'name'\n};\n\nvar r = j2j.run(template, {\n    name: 'joe'\n});\nconsole.log(r); // 'names are classified'\n```\n\nThis rule can be used to as lookup. When it is an object without `dataKey` we take it as literally.\nThe `value` can not be used as a nested template. If `dataKey` is provided one can use it for lookup as shown below:\n\n```js\nvar template = {\n    content: {\n         title: {\n            dataKey: \"gender\",\n            value: {\n                M: 'Mr',\n                F: 'Ms'\n             }\n            },\n         name : { dataKey: \"name\" }\n    }\n};\n\nvar input = {name: 'Joe', gender: 'M'};\n\nvar r = j2j.run(template, input);\n\nconsole.log(r); // { title: \"Mr\", name : \"Joe\" }\n\n\n```\n\nOne can also pass extra parameter to the `value` function. For this to work one has to pass `params` in the template:\nThe `value` function needs to written with `extraParams` as the last parameter.\n\n```js\n\nvar template = {\n    value: function (input, parent, params, extraParams) {\n        return (input > extraParams) ? input - extraParams: null;\n    },\n    params: 50\n};\n\nvar input = [50, 51, 52];\n\nvar r = j2j.run(template, input);\n\nconsole.log(r); // [1, 2]\n\n```\n\n### <a id=\"content\"></a> `content` rule ###\n\nThis rule is used to describe a new object based on `input`.  The property keys of the `content` becomes the properties in the destination object.  The property values of `content` are primarily other templates.\nThis is an object and cannot be empty.\n\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    }\n};\n\nvar template = {\n    content: {\n        name: nameTemplate,\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE',\n    birthYear: 1980\n});\nconsole.log(r); // {name: {last: 'DOE', first: 'JOE'}, age: 35}\n```\n\nThe `content` property values can also be formatting functions or primary data types which shortcuts the need to use `value` rule for those cases\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    }\n};\n\nvar template = {\n    content: {\n        type: 'Report',\n        title: function (input) {\n            return input.gender === 'M' ? 'Mr.' : 'Ms.';\n        },\n        name: nameTemplate,\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE',\n    gender: 'M',\n    birthYear: 1980\n});\nconsole.log(r); // {type: 'Report', title: 'Mr.', name: {last: 'DOE', first: 'JOE'}, age: 35}\n```\n\nThe `content` property keys can be deep\n```js\nvar template = {\n    content: {\n        'name.last': {\n            dataKey: 'familyName'\n        },\n        'name.first': {\n            dataKey: 'givenName'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r); // {name: {last: 'DOE', first: 'JOE'}}\n```\n\n### <a id=\"arrayContent\"></a> `arrayContent` rule ###\n\nThis rule is similar to `content` but is used to describe an `array` instead of an `object` based on `input`.  The array elements of the `arrayContent` becomes the array elements in the destination object.  Otherwise the array elements of the `arrayContent` work identically to properties of the `content`\nThis is an array and cannot be empty.\n\n```js\nvar nameTemplate = {\n    arrayContent: [{\n        dataKey: 'familyName'\n    }, {\n        dataKey: 'givenName'\n    }]\n};\n\nvar template = {\n    content: {\n        name: nameTemplate,\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE',\n    birthYear: 1980\n});\nconsole.log(r); // {name: ['DOE', 'JOE'], age: 35}\n```\n\n### <a id=\"constant\"></a> `constant` rule ###\n\nWhen values in `value` rule and property values in `content` rule are objects, they are assumed to be nested templates.  `constant` rule makes it possible to define a constant object within template\n```js\nvar template = {\n    content: {\n        codes: {\n            constant: {\n                'Y': 'yellow',\n                'R': 'red'\n            }\n        },\n        'color.back': {\n            dataKey: 'backgroundColor'\n        },\n        'color.fore': {\n            dataKey: 'foreGroundColor'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    backgroundColor: 'Y',\n    foreGroundColor: 'R'\n});\nconsole.log(r); // {codes: {Y: 'yellow', R: 'red'}, color: {back: 'Y', fore: 'R'}}\n```\n\nYou can also use primary data types in `constant` rule as alternatives to directly specifying them with `content` and `value` rules\n```js\nvar template = {\n    constant: 'CONST'\n};\n\nvar r = j2j.run(template, {\n    any: 'any'\n});\nconsole.log(r); // 'CONST'\n```\n\n### <a name=\"existsWhen\"></a> `existsWhen` rule ###\n\nThis rule must be a predicate or array of predicates. If the predicate evaluates to false, the template is ignored.  This rule is evaluated before any other rule on the same level.\nThe predicate can be a `function`, an `object` or a simple `property`. If it is an object or a simple property it works just like [iteratee](https://lodash.com/docs/4.16.3#iteratee) in lodash.\nThe property can be in the input or in the params.  It is to be noted that this feature is little different from the value function which is supplied with params as well as input.\nFor the value function the input and the params are available at the same time to the `function`.\n\n```js\nvar _ = require('lodash');\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a'\n        },\n        dest_b: {\n            dataKey: 'b',\n            existsWhen: _.partialRight(_.has, 'c')\n        }\n    },\n    existsWhen: 'public'\n};\n\nvar r0 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    public: true\n});\nconsole.log(r0.dest_a); // 'value_a'\nconsole.log(r0.dest_b); // undefined\n\nvar r1 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 0,\n    public: true\n});\nconsole.log(r1.dest_a); // 'value_a'\nconsole.log(r1.dest_b); // 'value_b'\n\nvar r2 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 0\n});\nconsole.log(r2); // null because public is not present\n\n\nvar r3 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b'\n},\n{\n    public: true,\n    c: 0\n}\n);\n\n//console.log(r3.dest_a); // 'value_a'\n//console.log(r3.dest_b); // 'value_b'\n\n```\n\nIf this rule is an array, each predicate in the array must evaluate to true\n\n```js\nvar _ = require('lodash');\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a'\n        },\n        dest_b: {\n            dataKey: 'b'\n        }\n    },\n    existsWhen: [_.partialRight(_.has, 'c'), _.partialRight(_.has, 'd')]\n};\n\nvar r0 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 'available'\n});\nconsole.log(r0); // null\n\nvar r1 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    d: 'available'\n});\nconsole.log(r1); // null\n\nvar r2 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 'available',\n    d: 'available'\n});\nconsole.log(r2.dest_a); // 'value_a'\nconsole.log(r2.dest_b); // 'value_b'\n```\n\n### <a id=\"existsEither\"></a> `existsEither` rule ###\n\nThis rule must be an array of predicates. If all the predicates evaluates to false, the template is ignored.  This rule is evaluated before any other rule on the same level.\nThe predicate can be a function, an object or a simple property. If it is an object or a simple property it works just like [iteratee](https://lodash.com/docs/4.16.3#iteratee) in lodash.\n\n```js\nvar _ = require('lodash');\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a'\n        },\n        dest_b: {\n            dataKey: 'b'\n        }\n    },\n    existsEither: [_.partialRight(_.has, 'c'), _.partialRight(_.has, 'd')]\n};\n\nvar r0 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 'available'\n});\nconsole.log(r0.dest_a); // 'value_a'\nconsole.log(r0.dest_b); // 'value_b'\n\n```\n\n### <a id=\"existsUnless\"></a> `existsUnless` rule ###\n\n This rule must be a predicate or array of predicates. If the predicate evaluates to true, the template is ignored.  This rule is evaluated before any other rule but existsWhen.\n\n```js\nvar _ = require('lodash');\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a'\n        },\n        dest_b: {\n            dataKey: 'b',\n            existsUnless: _.partialRight(_.has, 'c')\n        }\n    },\n    existsUnless: function (input) {\n        return input && input.private;\n    }\n};\n\nvar r0 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 0,\n    private: false\n});\nconsole.log(r0.dest_a); // 'value_a'\nconsole.log(r0.dest_b); // undefined\n\nvar r1 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b'\n});\nconsole.log(r1.dest_a); // 'value_a'\nconsole.log(r1.dest_b); // 'value_b'\n\nvar r2 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    private: true\n});\nconsole.log(r2); // null\n```\n\nIf this rule is an array, each predicate in the array must evaluate to true for the template to evaluate to `null`.\n\n```js\nvar _ = require('lodash');\n\nvar template = {\n    content: {\n        dest_a: {\n            dataKey: 'a'\n        },\n        dest_b: {\n            dataKey: 'b'\n        }\n    },\n    existsUnless: [_.partialRight(_.has, 'c'), _.partialRight(_.has, 'd')]\n};\n\nvar r0 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 'available'\n});\nconsole.log(r0.dest_a); // 'value_a'\nconsole.log(r0.dest_b); // 'value_b'\n\nvar r1 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    d: 'available'\n});\nconsole.log(r1.dest_a); // 'value_a'\nconsole.log(r1.dest_b); // 'value_b'\n\nvar r2 = j2j.run(template, {\n    a: 'value_a',\n    b: 'value_b',\n    c: 'available',\n    d: 'available'\n});\nconsole.log(r2); // null\n```\n\n### <a id=\"dataTransform\"></a> `dataTransform` rule ###\n\nThis rule transforms `input` so that existing templates can be reused. It can be a string, or an `object` (another jsonapter template) as well as a `function`.\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    }\n};\n\nvar template = {\n    content: {\n        name: {\n        \ttemplate: nameTemplate,\n\t\t\t    dataTransform: function(input) {\n\t\t\t\t    return {\n\t\t\t\t\t    familyName: input.lastName,\n\t\t\t\t\t    givenName: input.firstName\n\t\t\t\t    };\n\t\t\t  }\n\t\t},\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    lastName: 'DOE',\n    firstName: 'JOE',\n    birthYear: 1980\n});\nconsole.log(r); // {name: {last: 'DOE', first: 'JOE'}, age: 35}\n```\n\nIn the above example `dataTransform` can be a jsonapter template as shown below :\n```js\n\n    dataTransform: {\n        content: {\n           familyName: { dataKey: \"lastName\" }\n           givenName: { dataKey: \"firstName\" }\n       }\n    }\n```\n\n### <a id=\"default\"></a> `default` rule ###\n\nThis rule can be used to assign default values after templates are evaluated to be `null`\nThe `default` can be a `function` as well. If `function` one can use the `input`, `parent`, and `params` just like `value` as `function`.\n\n```js\nvar template = {\n    content: {\n        last: {\n            dataKey: 'familyName',\n            default: 'unknown'\n        },\n        first: {\n            dataKey: 'givenName',\n            default: function() {return 'unknown';}\n        },\n        title: {\n            dataKey: 'title',\n            default: function getTitle(input, parent, params) {\n                if (parent.gender === 'M') {\n                    return \"MR\";\n                } else if (parent.gender === 'F') {\n                    return \"MS\";\n                } else {\n                    return null;\n                }\n            }\n        }\n    }\n};\n\nvar r0 = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r0); // {last: 'DOE', first: 'JOE', title: null}\n\nvar r1 = j2j.run(template, {\n    familyName: 'DOE'\n});\nconsole.log(r1); // {last: 'DOE', first: 'unknown', title: null}\n\nvar r2 = j2j.run(template, {\n    givenName: 'JOE'\n});\nconsole.log(r2); // {last: 'unknown', first: 'JOE', title: null}\n\nvar r3 = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE',\n    gender: 'M'\n});\nconsole.log(r3); // {last: 'unknown', first: 'JOE', title: 'MR'}\n\n```\n\n### <a name=\"multiple\"></a> `multiple` rule ###\n\nThis rule can be used to change a template evaluted value into a one element array\n```js\nvar template = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        given: {\n            dataKey: 'givenName',\n            multiple: true\n        }\n    }\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r); // {last: 'DOE', given: ['JOE']}\n```\n<a name=\"single\" />\n#### `single` rule\n\nThis rule can be used to select the first value of a template evaluated array.  This is especially useful for conditional JSONPath expression\n```js\nvar jsonave = require('@amida-tech/jsonave').instance;\nvar template = {\n    dataKey: jsonave('book[?(@.id===\"AF20\")].price'),\n    single: true\n};\n\nvar r = j2j.run(template, {\n    book: [{\n        id: \"AA10\",\n        price: 10\n    }, {\n        id: \"AF20\",\n        price: 20\n    }, {\n        id: \"AB15\",\n        price: 30\n    }]\n});\n\nconsole.log(r); // 20\n```\n\n### <a id=\"firstOf\"></a> `firstOf` rule ###\n\nThis rule must be assigned to an array of other templates and selects the first one that does not evaluate to `null`\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    },\n    existsWhen: function (input) {\n        return input && input.familyName && input.givenName;\n    }\n};\n\nvar template = {\n    firstOf: [nameTemplate, {\n        dataKey: 'familyName'\n    }]\n};\n\nvar r0 = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r0); // {last: 'DOE', first: 'JOE'}\n\nvar r1 = j2j.run(template, {\n    familyName: 'DOE'\n});\nconsole.log(r1); // 'DOE'\n\nvar r2 = j2j.run(template, {\n    givenName: 'JOE'\n});\nconsole.log(r2); // null\n```\n\nYou can also include a primary data type as the last element to simulate a default\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    },\n    existsWhen: function (input) {\n        return input && input.familyName && input.givenName;\n    }\n};\n\nvar template = {\n    firstOf: [nameTemplate, 'UNKNOWN']\n};\n\nvar r0 = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r0); // {last: 'DOE', first: 'JOE'}\n\nvar r1 = j2j.run(template, {\n    familyName: 'DOE'\n});\nconsole.log(r1); // 'UNKNOWN'\n```\n\n### <a id=\"assign\"></a> `assign` rule ###\n\nThis rule accepts an array of other templates that generate object results and works similar to [lodash assign method](https://lodash.com/docs#assign).  `assign` rule is primarily used to reuse existing templates to obtain a new one.\nThis is an array and cannot be empty.\n```js\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'familyName'\n        },\n        first: {\n            dataKey: 'givenName'\n        }\n    }\n};\n\nvar template = {\n    assign: [{\n        content: {\n            id: function (input) {\n                return input.givenName[0] + input.familyName;\n            }\n        }\n    }, nameTemplate]\n};\n\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r); // {id: 'JDOE', last: 'DOE', first: 'JOE'}\n```\n\n### <a id=\"ignoreDeep\"></a> `ignoreDeep` rule ###\n\nThis rule can be used when dots in [content](#content) keys are part of the key rather than describing a path\n```js\nvar template = {\n    content: {\n        'name.last': {\n            dataKey: 'familyName'\n        },\n        'name.first': {\n            dataKey: 'givenName'\n        }\n    },\n    ignoreDeep: true\n};\n\nvar r = j2j.run(template, {\n    familyName: 'DOE',\n    givenName: 'JOE'\n});\nconsole.log(r); // {'name.last': 'DOE', 'name.first': 'JOE'}\n```\n\n## Prune Values\n\nFrom the instance we can pass a third object parameter, as options, with an array named as `pruneValues`, to drop all the keys from the final output which have any of the values represented by the strings present in `pruneValues` array. This can always be override by using [`default`](#default) rule.\nArray pruneValues can take a min of 1 to a max of 3 string based rule. Comes in handy if we need to enforce dirty check on the templates.\n\nAs of now values which can be pruned are:\n\n- `emptyString`\n- `emptyArray`\n- `NaN`\n\n```js\n\nvar bbj2j = require('jsonapter');\n\nvar options =   {pruneValues: ['emptyString', 'emptyArray', 'NaN']};\n\nvar j2j = bbj2j.instance(null,null,options);\n\n\nvar sampleInput = {\n    firstName: 'TIM',\n    lastName:'DOE',\n    middleName:'JOE',\n    familyName:'',\n    address:'',\n    age:NaN,\n    numbers:[],\n    friends:[],\n    groups:[1,2]\n};\n\nvar sampleTemplate = {\n    content: {\n        firstName: {\n            dataKey: 'firstName'\n        },\n        middleName: {\n            dataKey: 'middleName'\n        },\n        lastName: {\n            dataKey: 'lastName'\n        },\n        familyName: {\n            dataKey: 'familyName'\n        },\n        address: {\n            dataKey: 'address', default: \"\"\n        },\n        age: {\n            dataKey: 'age'\n        },\n        numbers:{\n            dataKey:'numbers', default:[]\n        },\n        friends:{\n            dataKey:'friends'\n        },\n        groups:{\n            dataKey:'groups'\n        }\n    }\n};\n\nvar r = j2j.run(sampleTemplate, sampleInput);\n\nconsole.log(r); // {\"firstName\": \"TIM\", \"middleName\": \"JOE\", \"lastName\": \"DOE\", \"address\": \"\", \"numbers\": [], \"groups\": [1,2]}\n```\n\n### <a id=\"skip\"></a> `skip` rule ###\n\nThis rule is used to skip a template.\n\n```js\nvar nestedTemplate = {\n    dataKey: 'b',\n    skip: true\n};\n\nvar template = {\n    template: nestedTemplate,\n    dataKey: 'a'\n};\n\nvar r = j2j.run(template, {\n    a: {\n        b: 'value'\n    }\n});\nconsole.log(r); // null\n```\n\n\n### <a id=\"output\"></a> `output` rule ###\n\nThe `output` tag is there to modify final result. It can be either `string`, `boolean`, `number`, `object` or `function`.\nWhen it is a function it's first argument is the `result` of the template as shown below :\n\n```js\n\nvar template = {\n            dataKey: 'name',\n            output: function(result, input, parent, params) {\n                // return some other result\n            }\n     }\n```\n\nIt is almost similar to the `value` as `function` but unlike `value` it is not an action key.\nThe `value` tag cannot be present along with other actionKeys e.g `content`, `arrayContent` etc.\nThe `output` tag can be specified by simply including `{output: string}` or `output: {type: string}`.\nWith the second option more features are available e.g. `substring`,  `upperCase`, etc.\n\nIf the result of the template is a string then the output tag can be omitted and the string options can be used. \nSimilarly if result of the template is boolean then boolean option can be used without using the output tag.\n\nIf output is string then these options are available e.g `split`, `substring`, `prefix`, `upperCase`, `lowerCase`, etc.\nHere is the complete list of all available options for all types. \n\n| Type      |   options    |   Format\n----------- |:------------:|:------------------------------\n| string    |   split      |  `split`: {`separator`(optional): \"-\"}, if no separator it will be white space\n| string    |   trim       |  `trim`: true\n| string    |   substring  |  `substring`: {start(optional): 1, end(optional): 5}\n| string    |   upperCase  |  `upperCase`: true\n| string    |   lowerCase  |  `lowerCase`: true\n| string    |   prefix     |  `prefix`: \"a\"\n| string    |   suffix     |  `suffix`: \"b\"\n| array     |   join       |  `join`: {`separator`(optional): \"-\"}, if no separator it will be ,(comma)\n| array     |   flatten    |  `flatten`: {`deep`(optional): true}, default is false\n| array     |   compact    |  `compact`: true\n| boolean   |   reverse    |  `reverse`: true\n| number    |   floor      |  `floor`: true\n| number    |   ceiling    |  `ceiling`: true\n| number    |   round      |  `round`: true\n\n### <a id=\"pick\"></a> `pick` rule ###\n\nThis rule is used to add a list of properties as is.\n\n```js\nvar template = {\n    content: {\n        fullName: {\n            value: function (input) {\n                return input.firstName + ' ' + input.lastName;\n            },\n            existsWhen: ['firstName', 'lastName']\n        },\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    },\n    pick: ['eyeColor', 'hairColor']\n};\n\nvar input = {\n    lastName: 'Doe',\n    firstName: 'Joe',\n    birthYear: 2000,\n    eyeColor: 'blue',\n    hairColor: 'brown'\n};\n\nvar r = j2j.run(template, input);\nconsole.log(r); // { fullName: 'Joe Doe', age: 15, eyeColor: 'blue', hairColor: 'brown' }\n}\n```\n\n### <a id=\"omit\"></a> `omit` rule ###\n\nThis rule is used to add all the properties as is except the specified.\n\n```js\nvar template = {\n    content: {\n        fullName: {\n            value: function (input) {\n                return input.firstName + ' ' + input.lastName;\n            },\n            existsWhen: ['firstName', 'lastName']\n        },\n        age: {\n            value: function (input) {\n                return 2015 - input;\n            },\n            dataKey: 'birthYear'\n        }\n    },\n    omit: ['eyeColor', 'lastName', 'firstName', 'birthYear']\n};\n\nvar input = {\n    lastName: 'Doe',\n    firstName: 'Joe',\n    birthYear: 2000,\n    eyeColor: 'blue',\n    hairColor: 'brown',\n    weight: 242,\n};\n\nvar r = j2j.run(template, input);\nconsole.log(r); // { fullName: 'Joe Doe', age: 15, hairColor: 'brown', weight: 242 }\n```\n\n## Errors\n\nThis library will throw `Error` in some cases, e.g. if [`content`](#content) is provided but it is an array or it is empty.\nThis can be avoided by creating a `jsonapter` `instance` with `options` as `instance (null, null, {mode: null})`.\nBy default, `mode` is `strict`.\n\n\n## Overrides\n\nEach engine instance `j2j` contains all the implementation details as functions in the following keys:\n- `run`\n- `content`\n- `assign`\n- `firstOf`\n- `constant`\n- `arrayIndex`\n- `template`\n- `size`\n- `value`\n- `runForArray`\n- `evaluateDataKey`\n- `evaluateValue`\n- `actionKeys`\n- `dataKeyToInput`\n- `dataKeyArrayToInput`\n- `context`\n\n`run` is the entry point. `content`, `arrayContent`, `value`, `size`, `template`, `arrayIndex`, `constant`, `firstOf` and `assign` are called action keys and listed in `actionKeys` array.\nOnly one of `actionKeys` can appear on a template on the same level. None of these keys are designed to be overridden except `context`.  However you can add additional functionality by adding new data and action keys.\n\n### Overrides To Existing Keys\n\nAlthough in principle any of the implementation keys can be overridden, only `context` is designed as such.\n\n### <a id=\"context\"></a> `context` Override ###\n\nWhen `dataKey` is a function this parameter is passed as the second parameter.  By default `context` is an empty object.  You can specify any property to be used by the `dataKey` function.  In particular [jsonave](https://github.com/amida-tech/jsonave) library allows functions in JSONPath expressions which can be specified with this key\n\n```js\nvar override = {\n    context: {\n        round: function(obj) {\n            return Math.round(obj);\n        }\n    }\n};\n\nvar j2j_dkfno = bbj2j.instance(override, override);\n\n\nvar jsonave = require('@amida-tech/jsonave').instance;\nvar template = {\n    dataKey: jsonave('book[:].price.round()')\n};\n\nvar r = j2j_dkfno.run(template, {\n    book: [{\n        price: 10.3\n    }, {\n        price: 22.2\n    }, {\n        price: 31.9\n    }]\n});\n\nconsole.log(r); // [10, 22, 32]\n```\n\n### Additional Action Keys\n\nThe functionality of templates can be customized by adding additional action keys\n```js\nvar meds = {\n    'aspirin': {\n        id: 1\n    }\n};\n\nvar override = {\n    meds: meds,\n    external: function (template, input) {\n        var te = template.external;\n        if (!input) {\n            return null;\n        }\n        var external = this.meds[input];\n        if (external) {\n            return external.id;\n        } else {\n            var newId = Object.keys(meds).length + 1;\n            meds[input] = {\n                id: newId\n            };\n            return newId;\n        }\n    }\n};\n\nvar j2j_od_e = bbj2j.instance(override, ['external']);\n\nvar nameTemplate = {\n    content: {\n        last: {\n            dataKey: 'lastName'\n        },\n        first: {\n            dataKey: 'firstName'\n        }\n    }\n};\n\nvar template = {\n    content: {\n        name: nameTemplate,\n        meds: {\n            external: {},\n            dataKey: 'meds'\n        }\n    }\n};\n\nvar r = j2j_od_e.run(template, {\n    lastName: 'Doe',\n    firstName: 'Joe',\n    meds: ['claritin', 'aspirin', 'albuterol']\n});\nconsole.log(r); // {name: {last: 'Doe', first: 'Joe'}, meds: [2, 1, 3]}\n\nconsole.log(meds); // {aspirin: {id: 1}, claritin: {id: 2}, albuterol: {id: 3}}\n```\nHere we added `external` to `actionKeys`.  Note that for this simple example, `external` is assigned to an empty object but in general it can be anything including other templates.  You can `run` the templates by `this.run(te, input)` where `te` is the value of `external` as demontrated above.\n\n## License\n\nLicensed under [Apache 2.0](./LICENSE).\n\n","readmeFilename":"README.md"}