awesome-json2json
TypeScript icon, indicating that this package has built-in type declarations

0.6.0 • Public • Published

Awesome json2json

Actions Status npm package npm downloads

An awesome json to json mapper

Installation

npm install awesome-json2json --save

Usage

import json2json from 'awesome-json2json';
// const { default: json2json } = require('awesome-json2json');

let sourceJson = { foo: { bar: { baz: 1 } } };

let template = {
  new_foo: 'foo.bar.baz',
};

json2json(sourceJson, template);
// { new_foo: 1 }

Template

Template is the structure of output json, and the rule of how to map one json data to another. The syntax should look like this:

// Input:
// {
//   foo: {
//     bar: {
//       baz: 1
//     }
//   },
//   foo_array: [
//     { bar: 1 },
//     { bar: 2 },
//     { bar: 3 }
//   ]
// }
//
// Template example:
{
  new_foo1: 'foo.bar.baz',
  new_foo2: 'foo.not_exist_key?.bar.baz',
  new_foo3: (root) => { return root.foo.bar.baz; },
  new_foo4: {
    $path: 'foo',
    $formatting: (foo) => { return foo.bar.baz; }
  },
  new_foo5: {
    $path: 'foo',
    new_bar1: 'bar.baz',
    new_bar2: '$root.foo.bar.baz',
    new_bar3: {
      $formatting: (foo) => { return foo.bar.baz; }
    },
    new_bar4: {
      $disable: (foo) => { return foo.bar.baz === 1; }
      new_baz: 'foo.bar.baz'
    },
  },
  new_foo_array1: 'foo_array[].bar',
  new_foo_array2: {
    $path: 'foo_array[]',
    $formatting: (foo_item) => { return foo_item.bar; }
  }
  new_foo_array3: {
    $path: 'foo_array[]',
    new_bar: {
      $path: 'bar',
      $formatting: (barValue, { $item: fooItem }) => barValue + fooItem.bar
    }
  }
}
// Output:
// {
//   new_foo1: 1,
//   new_foo2: undefined,
//   new_foo3: 1,
//   new_foo4: 1,
//   new_foo5: {
//     new_bar1: 1,
//     new_bar2: 1,
//     new_bar3: 1
//   },
//   new_foo_array1: [1, 2, 3],
//   new_foo_array2: [1, 2, 3],
//   new_foo_array3: [
//     { new_bar: 2 },
//     { new_bar: 4 },
//     { new_bar: 6 }
//   ]
// }

Features

Optional chaining

Optional chaining is a stage-1 ECMAScript feature, by adding a ? to the end of one pathItem, it will return undefined if the value is undefined. As a comparison, it will throw an error without optional chaining question mark.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: 'foo.not_exist_key?.bar.baz',
  },
);
// { new_foo: undefined }

Function template

By passing a function to the template, the field value will be the return value of the funtion. The first argument of the function is the root of current input json.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: (root) => {
      return root.foo.bar.baz + '_formatted';
    },
  },
);
// { new_foo: '1_formatted' }

Template with $path and $formatting

We can combine the above two type of templates into one template item by passing an object to it, with key $path and $formatting, in this case, the first argument of $formatting is the json result which gets from $path.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: {
      $path: 'foo.bar',
      $formatting: (bar) => {
        return bar.baz + '_formatted';
      },
    },
  },
);
// { new_foo: '1_formatted' }

Nested template

If we pass some keys that are not starts with $, then it will return the new structure that contains the keys we pass.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: {
      $path: 'foo',
      new_bar: 'bar.baz',
    },
  },
);
// { new_foo: { new_bar: 1 }}

Nested template with $path and $formatting

$path, $formatting and nested template can work togather!

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: {
      $path: 'foo',
      $formatting: (foo) => {
        return {
          baz2: foo.bar.baz + '_formatted',
        };
      },
      new_bar: 'baz2',
    },
  },
);
// { new_foo: { new_bar: '1_formatted' }}

Nested template with $disable

With $disable keyword, we can disable a field when $disable returns true.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: {
      $path: 'foo',
      new_bar1: {
        $disable: (foo) => {
          return foo.bar.baz === 1;
        },
        new_baz: 'bar.baz',
      },
      new_bar2: 'bar.baz',
    },
  },
);
// {
//   new_foo: {
//     new_bar2: 1
//   }
// }

Nested template with $default

With $default keyword, we can provide a default value when a field returns undefined.

json2json(
  { foo: { bar: 1 } },
  {
    new_foo: {
      $path: 'foo',
      new_bar: { $path: 'bar', $default: 11 },
      new_baz: { $path: 'baz', $default: 9 },
      new_qux: { $path: 'qux', $default: () => 88 },
    },
  },
);
// {
//   new_foo: {
//     new_bar: 1
//     new_baz: 9,
//     new_qux: 88,
//   }
// }

Template with $root

When we reaches the very bottom, it possible to use $root to go back to the root of input json.

json2json(
  { foo: { bar: { baz: 1 } } },
  {
    new_foo: {
      $path: 'foo',
      new_bar: {
        $path: 'bar',
        new_baz1: 'baz',
        new_baz2: '$root.foo',
      },
    },
  },
);
// new_foo: {
//   new_bar: {
//     new_baz1: 1,
//     new_baz2: {
//       bar: {
//         baz: 1
//       }
//     }
//   }
// }

Array template

Map an array is so easy.

json2json(
  {
    foo: [{ bar: 1 }, { bar: 2 }, { bar: 3 }],
  },
  {
    new_foo: 'foo[].bar',
  },
);
// { new_foo: [1, 2, 3] }

Array template with $formatting

json2json(
  {
    foo: [{ bar: 1 }, { bar: 2 }, { bar: 3 }],
  },
  {
    new_foo: {
      $path: 'foo[].bar',
      $formatting: (barValue) => barValue + '_formatted',
    },
  },
);
// {
//   new_foo: [
//     '1_formatted',
//     '2_formatted',
//     '3_formatted'
//   ]
// }

Nested array template

json2json(
  {
    foo: [{ bar: 1 }, { bar: 2 }, { bar: 3 }],
  },
  {
    new_foo: {
      $path: 'foo[]',
      new_bar: {
        $formatting: (fooItem) => {
          return fooItem.bar;
        },
      },
    },
  },
);
// {
//   new_foo: [
//     { new_bar: 1 },
//     { new_bar: 2 },
//     { new_bar: 3 }
//   ]
// }

$item and $root inside $formatting

The second parameter of $formatting is the context of current mapping status, including $item and $root.

json2json(
  {
    foo: [{ bar: 1 }, { bar: 2 }, { bar: 3 }],
  },
  {
    new_foo: {
      $path: 'foo[]',
      new_bar1: {
        $path: 'bar',
        $formatting: (barValue, { $item: fooItem }) => {
          return barValue + '_formatted_' + fooItem.bar;
        },
      },
      new_bar2: (fooItem, { $root }) => {
        return fooItem.bar + '_formatted_' + $root.foo.length;
      },
    },
  },
);
// {
//   new_foo: [
//     {
//       new_bar1: '1_formatted_1',
//       new_bar2: '1_formatted_3'
//     },
//     {
//       new_bar1: '2_formatted_2',
//       new_bar2: '2_formatted_3'
//     },
//     {
//       new_bar1: '3_formatted_3',
//       new_bar2: '3_formatted_3'
//     }
//   ]
// }

Template with $item

item represents the current array item.

json2json(
  {
    foo: [
      { bar: { baz1: 1, baz2: 2, baz3: 3 } },
      { bar: { baz1: 1, baz2: 2, baz3: 3 } },
      { bar: { baz1: 1, baz2: 2, baz3: 3 } },
    ],
  },
  {
    new_foo: {
      $path: 'foo[]',
      new_bar: {
        $path: 'bar',
        new_baz: '$item.bar.baz1',
      },
    },
  },
);
// {
//   new_foo: [
//     { new_bar: { new_baz: 1 } },
//     { new_bar: { new_baz: 1 } },
//     { new_bar: { new_baz: 1 } },
//   ]
// }

Using only the head of an Array

If you need to work with just a the first element of an array you can use $head in the path to access it.

json2json({ foo: [{ bar: 1 }, { bar: 2 }] }, { first_bar: 'foo.$head.bar' });
// { first_bar: 1 }

Clear all empty data

Passing clearEmpty: true to the third parameter of json2json will clear all empty data including undefined, null, empty object {}, empty array [], and combination of empty object and empty array such as [{}, {}, {}]

json2json(
  {
    foo: [{ bar: 1 }, { bar: 2 }, { bar: 3 }],
  },
  {
    new_foo: {
      new_bar1: 'foo[].bar',
      new_bar2: {
        $path: 'foo[]',
        new_baz1: 'baz',
        new_baz2: {
          new_qux: 'baz',
        },
      },
    },
  },
  {
    clearEmpty: true,
  },
);
// {
//   new_foo: {
//     new_bar1: [1, 2, 3]
//   }
// }

Package Sidebar

Install

npm i awesome-json2json

Weekly Downloads

177

Version

0.6.0

License

MIT

Unpacked Size

60.9 kB

Total Files

19

Last publish

Collaborators

  • xcatliu