jbj

7.1.4 • Public • Published

JBJ : transform Json By Json

A new way to transform JSON object with a JSON stylesheet. It's like XSL/XML but only with JSON.

Try it online !

http://inist-cnrs.github.io/jbj-playground/

Contributors

Installation

With npm do:

$ npm install jbj

Tests

Use mocha to run the tests.

$ npm install
$ npm test

Documentation

API

render(stylesheet : Object, input : Mixed, callback : Function) : None

Render input with stylesheet.

    var JBJ = require('jbj'),
    JBJ.render({ "truncate" : 3 }, "1234", function(err, out) {
            console.log(out);
    });
 
    // Output : 123
 

Variables

Variable can be set using $ plus a dot notation path. The set value can only be a JBJ expression (not a JSON literal).

Input:

{
  "a": {
    "b": {
      "c": 1
    },
    "d": "Second"
  }
}

Stylesheet:

{
    "$x" : {
        "get": "a.b.c"
    },
    "$y.y1.y2" : {
        "get": "a.d"
    }
}

Output:

{
  "a": {
    "b": {
      "c": 1
    },
    "d": "Second"
  },
  "x": 1,
  "y": {
    "y1": {
      "y2": "Second"
    }
  }
}

inject(stylesheet : Object, input : Mixed, callback : Function) : None

Alertative mode to use JBJ actions. You can inject in stylesheet the input. Injections are identified by a prefix and suffix in the key. The prefix and the suffix are the less-than sign <. Prefix inject the result of a JBJ action in the current scope. Suffix inject the result of a JBJ render in the current key.

    var JBJ = require('jbj'),
    JBJ.render({ "<truncate" : 3 }, "1234", function(err, out) {
            console.log(out);
    });
 
    // Output : 123
 

prefix

var input = {
    key : "hello"
}
var stylesheet = {
    "obj" : {
        "<get" : "key",
        upcase: true
    }
};
// output : { obj : "HELLO" }

suffix

var input = {
    key : "hello"
}
var stylesheet = {
    "obj" : {
        "keyword<" : {
            get : "key",
        upcase: true
        }
    }
};
// output : { obj : { keyword : "HELLO" } }

register(protocol : String, callback : Function) : None

Add a function to fetch data for a specific protocol

    JBJ.register('http:', function request(urlObj, callback) {
        var buf = ''
          , req = require('http').get(urlObj, function(res) {
            if (res.statusCode !== 200) {
                return callback(new Error('HTTP Error ' + res.statusCode));
            }
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
              buf += chunk.toString();
            });
            res.on('error', callback);
            res.on('end', function() {
              callback(null, buf);
            });
        });
        req.on('error', callback);
    });

getActions() : Array

List all available actions.

    var JBJ = require('jbj'),
 
    console.log(JBJ.getActions());
 
    // Output : ['get', 'set', 'expect' ...]
 

getFilter(filterName : String) : Function

Get the statement function for an action name.

    var JBJ = require('jbj'),
 
    var func = JBJ.getFilter('append');
 
    func('Hello', 'World' , function(err, output) {
       console.log(output)
    })
 
    // Output : HelloWorld

use(module: Function) : None

Adding filters/actions for external module. see the avaible modules here : https://www.npmjs.com/browse/keyword/jbj

    var JBJ = require('jbj'),
 
    JBJ.use(require('jbj-numerical'));
    JBJ.use(require('jbj-ist'));
    JBJ.use(require('jbj-rdfa'));
 

Warning: the method has change since v4.0

Actions

A stylesheet is a JSON object where each key is an action. The actions are divided into modules (since v4.0):

The modules you can use by defaults are basics and ejs.

To use another module, first install it via npm:

$ npm install jbj-array

then declare its use via:

JBJ.use(require('jbj-array'));

Note: basics and ejs modules are distributed with the jbj package, and used by default: you can use their actions without any further declaration. However, parse, template, and array, which were parts of the pre-3.0 versions of JBJ are now separate packages (simply add jbj- before the modules names to get their matching packages).

set: value

  • module: basics

Set value and ignore input

    var stylesheet1 = {
        "set": "value"
    };
    var stylesheet2 = {
        "set": ["value", "value", "value"]
    };
    var stylesheet3 = {
        "set": {
            "a": 1,
            "b": 2
        }
    };

get: path | [path,path, ...]

  • module: basics
  • aliases : find , path

Get value in input with some paths (with dot notation style)

    var stylesheet1 = {
        "set": {
            "a" : {
                "b" : {
                    "c" : "Yo"
                }
            }
        },
        "get": "a.b.c"
    };
    // output : Yo
    var stylesheet2 = {
        "set" : {
            "a" : {
                "b" : 1,
                "c" : 2,
                "d" : 3
            }
        },
        "get": ["a.b", "a.c", "a.d"]
    };
// output : [1, 2, 3]

default: value

  • module: basics

Fix value if input is not set

    var stylesheet = {
        var stylesheet = {
            "default": "value"
        };
    };

fetch

  • module: basics
  • aliases : fetchURL, $?

Stylesheet can contain a reference to data source. Source can be a file or an URL. By default, only the file: protocol is supported. Add your own protocol with register

    var stylesheet_1 = {
      "fetch" : "https://raw.githubusercontent.com/castorjs/node-jbj/master/package.json",
      "$name" : {
        "upcase": true
      },
      "$main": {
        "upcase": true
      }
    };
    var stylesheet_2 = {
      "$name" : {
        "fetch" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
        "parseJSON" : true,
        "path": "name"
      },
      "$main": {
        "fetch" : "file://" + path.resolve(__dirname, '../dataset/1.json'),
        "parseJSON" : true,
        "path": "main",
      }
    };

add: [key, value]

  • module: basics

Add a key/value pair into the input object.

{
  "input": { },
  "stylesheet": {
    "add": ["tag", "span"]
  },
  "expected": {
    "tag": "span"
  }
}
{
  "input": {
    "content": "not empty"
  },
  "stylesheet": {
    "add": ["tag", "span"]
  },
  "expected": {
    "content": "not empty",
    "tag": "span"
  }
}

expect: object

  • module: basics

Set default key/values for the input object: when a key is not present in the input object, it is set the value given in the argument object.

{
  "input": {
    "a": 3
  },
  "stylesheet": {
    "expect": {
      "a": 1,
      "b": 2
    }
  },
  "expected": {
    "a": 3,
    "b": 2
  }
}
{
  "stylesheet": {
    "expect": {
      "a": 1,
      "b": 2
    }
  },
  "expected": {
    "a": 1,
    "b": 2
  }
}

inject:

  • module: basics

Return a new Object with JBJ.inject.

render:

  • module: basics

Return a new Object with JBJ.render.

compute:

  • module: basics

Compute an expression with all variables of the input. Use the filtrex syntax. Note : this variable contains input

var stylesheet = {
    "set" : {
        "a" : 20,
        "b" : 3,
        "c" : 5,
        "d" : 8
    },
    "$x" : {
        "compute#1": "a / b",
        "compute#2": "round(this)",
        "cast": "number"
    },
    "$y" : {
        "path": "b",
        "cast": "number"
    },
    "$z" : {
        "compute": "x + y",
    }
};
// output : 10

debug: none

  • module: basics

Print input with console.log

    var stylesheet = {
        "set": "value",
        "debug": true
    };
    // output: value

foreach: stylesheet

  • module: basics

Apply stylesheet on all elements of input

    var stylesheet1 = {
        "set": ["value", "value", "value"]
        "foreach" : {
            "upcase" : true
        }
    };
    // output : ["VALUE", "VALUE", "VALUE"]
    var stylesheet2 = {
        "set": [
            { "b" : "x" },
            { "b" : "y" }
        ],
        "foreach" : {
            "get": "b",
            "upcase" : true
        }
    };
    // output : ["X", "Y"]
    var stylesheet3 = {
        "set": [
            { "b" : "x" },
            { "b" : "y" }
        ],
        "foreach" : {
            "$b" : {
                "get": "b",
                "upcase" : true
            }
        }
    };
    // output : [ { "b" : "X" }, { "b" : "Y" } ]

extend: object

  • module: basics
  • aliases : extendWith

Extend input with another object

    var stylesheet = {
        "set": {
            "a" : 1
        },
        "extend" : {
            "b" : 2
        }
    };
    // output : { a: 1, b: 2}

select: path | [path, path, ...]

  • module: basics

Peck element(s) in input with "CSS selector"

    var stylesheet = {
        "set" : {
            "a" : {
                "b" : [
                    { "c" : "1" },
                    { "c" : "2" }
                ]
            }
        },
        "select" : ".a > .b .#c"
    };
    // output : [1, 2]

for syntax see JSONSelect and JSONSelect Expression Tester

Note: select always returns an array (an empty array when nothing was selected).

cast: (number|string|boolean) | [(string|date), pattern]

  • module: basics

Convert input to specific type

    var stylesheet1 = {
        "set" : "1"
        "cast": "number"
    };
    // output : 1
    var stylesheet2 = {
        "set" : 1
        "cast": "string"
    };
    // output: "1"

for syntax see transtype

mask: pattern

  • module: basics

Selecting specific parts of input, hiding the rest, return object

    var stylesheet = {
        "set" : {
            "a" : 1,
            "b" : 2,
            "c" : 3
        },
        "mask": "a,c"
    };
    // output : { a: 1, c: 3}

For syntax see json-mask

omit: pattern

  • module: basics

Unselecting specific parts of input, show the rest, return object

    var stylesheet = {
        "set" : {
            "a" : 1,
            "b" : 2,
            "c" : 3
        },
        "omit": "a,c"
    };
    // output : { b: 2 }

For syntax see object.omit

required: none

  • module: basics

If input is not set, return Error

trim: none

  • module: basics

Trim input, return string

    var stylesheet = {
        "set" : "    xxx    ",
        "trim": true
    };
    // output : "xxx"

assert: expression

  • module: basics

If expression is true, then statements will be continued, otherwise it is stopped and it returns null

Note : this variable contains input

    var stylesheet1 = {
        "set" : {
            "a" : 1
        },
        "$val#1" : {
            "assert": "a == 1",
            "set" : "if val"
        }
    };
    // output : "if val"
    var stylesheet2 = {
        "set" : {
            "a" : 0
        },
        "$val#1" : {
            "assert": "a == 1",
            "set" : "if val"
        },
        "$val#2" : {
            "get" : "val",
            "default": "else val",
          }
    };
    // output : "else val"
 

capitalize:

  • module: ejs

Capitalize the first letter of input

    var stylesheet = {
        "set" : "xyz",
        "capitalize": true
    };
    // output : "Xyz"

downcase:

  • module: ejs

Downcase input

    var stylesheet = {
        "set" : "XYZ",
        "downcase": true
    };
    // output : "xyz"

upcase:

  • module: ejs

Uppercase input

    var stylesheet = {
        "set" : "xyz",
        "upcase": true
    };
    // output : "XYZ"

slug:

  • module: ejs

Convert the input string to something valid in an URI. See https://tools.ietf.org/html/rfc3986

{
  "slug spaces": {
    "input": "with space",
    "stylesheet": {
      "slug": true
    },
    "expected": "with-space"
  },
 
  "slug lowercase": {
    "input": "IN UPPERCASE",
    "stylesheet": {
      "slug": true
    },
    "expected": "in-uppercase"
  },
 
  "slug diacritics": {
    "input": "En français",
    "stylesheet": {
      "slug": true
    },
    "expected": "en-francais"
  },
 
  "slug diacritics #2": {
    "input": "Le Cinquième Élément",
    "stylesheet": {
      "slug": true
    },
    "expected": "le-cinquieme-element"
  },
 
  "slug unicode": {
    "input": "i ♥ unicode",
    "stylesheet": {
      "slug": true
    },
    "expected": "i-unicode"
  }
}

first:

  • module: ejs

Get the first element of input

    var stylesheet = {
        "set" : ["a", "b", "c"],
        "first": true
    };
    // output : "a"

last:

  • module: ejs

Get the last element of input

    var stylesheet = {
        "set" : ["a", "b", "c"],
        "last": true
    };
    // output : "c"

sort:

  • module: ejs

Sort input object or array.

    var stylesheet = {
        "set": ["b", "c", "a"],
        "sort": true
    };
    // output : ["a", "b", "c"]

sortBy: prop | [prop, prop, ...]

  • module: ejs
  • aliases : sort_by

Sort input object the given prop ascending.

    var stylesheet = {
        "set": [
            { "name": "zert" },
            { "name": "abcd" }
        ],
        "sortBy": "name"
    };
    // output : [{ "name": "abcd" }, { "name": "zert" }]

size:

  • module: ejs
  • aliases : length

Get the size or the length of input

    var stylesheet1 = {
        "set" : "12345",
        "size": true
    };
    var stylesheet2 = {
        "set" : [1,2,3,4,5],
        "size": true
    };
    // output : 5

max:

  • module: ejs

Add input and value

    var stylesheet1 = {
        "set" : [2, 4, 1, 7, 9, 3],
        "max" : true
    };
    // output : 9
    var stylesheet2 = {
        "set" : {a: 9, b: 4, c: 3, d: 5},
        "max" : true
    };
    // output : 9

min:

  • module: ejs

Subtract value from input

    var stylesheet1 = {
        "set" : [2, 4, 1, 7, 9, 3],
        "min" : true
    };
    // output : 1
    var stylesheet2 = {
        "set" : {a: 9, b: 4, c: 3, d: 5},
        "min" : true
    };
    // output : 3

plus: value | [value, value, ...]

  • module: ejs

Add input and value

    var stylesheet = {
        "set" : 4,
        "plus": 3
    };
    // output : 7
    var stylesheet = {
        "set" : 4,
        "plus": [1,2,3]
    };
    // output : [5,6,7]

minus: value | [value, value, ...]

  • module: ejs

Subtract value from input

    var stylesheet = {
        "set" : 4,
        "minus": 3
    };
    // output : 1
    var stylesheet = {
        "set" : 4,
        "minus": [1,2,3]
    };
    // output : [3,2,1]

times: value | [value, value, ...]

  • module: ejs

Multiply input by value"

    var stylesheet = {
        "set" : 5,
        "times": 5
    };
    // output : 25
    var stylesheet = {
        "set" : 4,
        "times": [1,2,3]
    };
    // output : [4,8,12]

dividedBy: value | [value, value, ...]

  • module: ejs
  • aliases : divided_by

Divide input by value"

    var stylesheet = {
        "set" : 10,
        "dividedBy": 2
    };
    // output : 5
    var stylesheet = {
        "set" : 4,
        "times": [1,2]
    };
    // output : [4,2]

join: string = ', '

  • module: ejs
  • aliases : glue

Join input with the given string.

    var stylesheet = {
        "set" : ["a","b","c"],
        "join": " | "
    };
    // output : "a | b | c"

shift: n | [n, n, ...]

  • module: ejs

Shift input to the left by n

    var stylesheet = {
        "set" : "The world",
        "shift": 4
    };
    // output : "world"
    var stylesheet = {
        "set" : [1,2,3,4,5],
        "shift": 2
    };
    // output : [3,4,5]
    var stylesheet = {
        "set" : [1,2,3,4,5],
        "shift": [2,3]
    };
    // output : [[3,4,5],[4,5]]

truncate: length | [length, length, ...]

  • module: ejs

Truncate input to length.

    var stylesheet = {
        "set" : "hello world",
        "truncate": 5
    };
    // output : "hello"

truncateWords: n | [n, n, ...]

  • module: ejs
  • aliases : truncate_words

Truncate input to n words (separator: space).

    var stylesheet = {
        "set" : "This is JBJ!",
        "truncateWords": 2
    }
    // output "This is"
    var stylesheet = {
        "set" : "This is JBJ!",
        "truncateWords": [1,2]
    }
    // output ["This","This is"]

replace: [pattern, substitution] | pattern

  • module: ejs

Replace pattern (as a regular expression) with substitution in input.

    var stylesheet = {
        "set" : "XoXoXoX",
        "replace": ["o", "."]
    };
    // output :  X.X.X.X
    var stylesheet = {
        "set" : "XoXoXoX",
        "replace": "o"
    };
    // output :  XXXX

Tip: to escape any character, use \\ instead of just \. Example: use "replace": "\\(trash\\)" removes (trash) from input, whereas "replace": "(trash)" removes only trash.

prepend: something | [something, something, ...]

  • module: ejs

Prepend something to input

    var stylesheet = {
        "set" : "world"
        "prepend": "hello"
    };
    // output : "hello world"
    var stylesheet = {
        "set" : "h"
        "prepend": ["a","e","i","o","u"]
    };
    // output : ["ah","eh","ih","oh","uh"]

append: something | [something, something, ...]

  • module: ejs

Append something to input

    var stylesheet = {
        "set" : "cool",
        "append": "!"
    };
    // output : "cool!"
    var stylesheet = {
        "set" : "cool",
        "append": ["!","?","."]
    };
    // output : ["cool!","cool?","cool."]

reverse:

  • module: ejs

Reverse items order of input

    var stylesheet = {
        "set" : [1,2,3]
    };
    // output : [3,2,1]

flatten:

  • module: ejs

Flatten an array.

    var stylesheet = {
      "set"     : [ ['a', 'b'], ['c', 'd'], 'e'],
      "flatten" : true
    };
    // output : ["a","b","c","d","e"]

deduplicate:

  • module: ejs
  • aliases : dedupe , unique

Deduplicate values in an array.

    var stylesheet = {
      "set"         : [ 1, 2, 3, 1, 2],
      "deduplicate" : true
    };
    // output : [1,2,3]

remove:

  • module: ejs
  • alias : del

Remove one value in an array.

    var stylesheet = {
      "set"    : [ 1, 2, 3],
      "remove" : 2
    };
    // output : [1,3]
    var stylesheet = {
      "set"    : [ "a", "", "b"],
      "remove" : ""
    };
    // output : ["a","b"]
    var stylesheet = {
      "set"    : [ "a", "b", "c"],
      "remove" : "b"
    };
    // output : ["a","c"]

sum:

  • module: ejs
  • alias : total

Return the sum of all the value of an array.

    var stylesheet = {
      "set"    : [ 1, 2, 3],
      "sum" : true
    };
    // output : 6

FAQ

How to chain the same action

just add #

    var stylesheet = {
        "default":  "123456789",
        "truncate#1": 8,
        "truncate#2": 4,
        "truncate#3": 2
    };

How to use input as variable in an expression

just use this

    var stylesheet = {
      "$e" : {
        "compute#1": "a / b",
        "compute#2": "round(this)",
        "cast": "number"
      }
    }
 

How to find more examples

see unit tests : https://github.com/castorjs/node-jbj/tree/master/test

Also

License

MIT

Readme

Keywords

none

Package Sidebar

Install

npm i jbj

Weekly Downloads

4

Version

7.1.4

License

MIT

Last publish

Collaborators

  • touv
  • parmentf