2.0.0 • Published 5 years ago

untold-json-enhancer v2.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
5 years ago

Untold JSON Enhancer

The JSON Enhancer was created to add calculated fields into an existing JSON object.

Installing

Install with npm

npm install untold-json-enhancer --save

Usage

For the purpose of this example we will write queries for the Character JSON object.

Setting up the enhancer

First, import the json enhancer library.

For the web:

import JSONEnhancer from 'untold-json-enhancer';

In node:

const JSONEnhancer = require('untold-json-enhancer');

Next, you should create a new instance from the JSON Enhancer:

const enhancer = new JSONEnhancer();

Creating a schema

A schema represents a group of enhancements which will be applied at once on an object.

In the following example we create a new schema for our character object and use it to enhance its properties.

enhancer.setSchema('Character');

// TODO: add your own rules

enhancer.enhance(character, 'Character');

If we execute this code we will realize that it does nothing because our schema is empty.

Creating a static rule

Rules can be added with the addRuleToSchema method. It expects 3 parameters:

  • The name of the schema
  • An Untold JSON Pointer query to specify the target or targets.
  • The new value

The Untold JSON Pointer is query library designed to help us target properties in an object. The only difference you have to notice that it always starts with the . character. You can read more about it on its own GitHub page.

In the following example we create a rule which points to the name of the weapon and renames it from sword to stick.

console.log(character.weapon.name); // "sword"

enhancer.setSchema('Character');
enhancer.addRuleToSchema('Character', '.weapon.name', '"stick"');
enhancer.addRuleToSchema('Character', '.weapon.price', '2 * 8');

enhancer.enhance(character, 'Character');

console.log(character.weapon.name); // "stick"
console.log(character.weapon.price); // 16

Using rule scoped variables to calculate value based on context

There are 3 variables available for you in the value expression.

item

The item points to the original object. It is useful when you want to use absolute path to navigate.

console.log(character.name); // "Conan"
console.log(character.weapon.name); // "sword"

enhancer.setSchema('Character');
enhancer.addRuleToSchema('Character', '.weapon.name', 'item.name');

enhancer.enhance(character, 'Character');

console.log(character.name); // "Conan"
console.log(character.weapon.name); // "Conan"

target

The target points to property what we are planning to update.

console.log(character.weapon.name); // "sword"

enhancer.setSchema('Character');
enhancer.addRuleToSchema('Character', '.weapon.name', 'target.name + "2"');

enhancer.enhance(character, 'Character');

console.log(character.weapon.name); // "sword2"

parent

The parent object has 2 properties:

  • value - which is the reference to the parent
  • parent - which goes up on the chain.

So you can get the reference of the grandparent by using the parent.parent.value.

console.log(character.name); // "Conan"
console.log(character.weapon.name); // "sword"

enhancer.setSchema('Character');
enhancer.addRuleToSchema('Character', '.weapon.name', 'parent.parent.value.name');

enhancer.enhance(character, 'Character');

console.log(character.name); // "Conan"
console.log(character.weapon.name); // "Conan"

Adding your own context variables

You can add context variables globaly or only into the schema.

console.log(character.name); // "Conan"

enhancer.setGlobalScope({ globalTitle: 'Global' });

enhancer.setSchema('Character');
enhancer.setSchemaScope('Character', { schemaTitle: 'Schema' });
enhancer.addRuleToSchema('Character', '.name', 'globalTitle + " " + schemaTitle');

enhancer.enhance(characterCopy, 'Character');

console.log(character.name); // "Global Schema"

Please keep in mind that in case of duplicate variable names, the more specific always wins.

Adding helper methods and using pipes

You can inject anything into the scope and use them.

enhancer.setGlobalScope({ Math: Math };

enhancer.setSchema('Character');
enhancer.addRuleToSchema('Character', '.weapon.price', 'Math.floor(2.4)');

console.log(character.weapon.price); // 2

Also if the function only takes one parameter you can use the pipe shorthand.

enhancer.addRuleToSchema('Character', '.weapon.price', '2.4 | Math.floor');

Nested schema

You can also create schemas for common parts in other schemas to avoid redundancy.

Here, the character has an item array and we would like to add a new property to each item which is calculated based on that properties of that item.

enhancer.setSchema('Character');

enhancer.setSchema('Item');
enhancer.addRuleToSchema('Item', '.sumWeight', 'parent.value.weight * parent.value.quantity');

enhancer.addSchemaToSchema('Character', '.items', 'Item');

enhancer.enhance(characterCopy, 'Character');

console.log(characterCopy.items[0].sumWeight)); // 1
console.log(characterCopy.items[1].sumWeight)); // 3
console.log(characterCopy.items[2].sumWeight)); // 2
console.log(characterCopy.items[3].sumWeight)); // 0.5

It is important to notice that we applied our nested schema to an array and that's why the enhancer applied the schema to every single element.

Built With

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate.

Building the application:

npm run build

Generating types for TypeScript:

npm run build:types

Executing tests in chrome:

npm run test

Authors

License

MIT

2.0.0

5 years ago

1.4.0

5 years ago

1.3.0

5 years ago

1.2.0

5 years ago

1.1.0

5 years ago

1.0.0

5 years ago