5

GitHub - artem-mangilev/jsonmap

 2 years ago
source link: https://github.com/artem-mangilev/jsonmap
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

jsonmap

This is a javascript data mapping library. It allows you to create complex transferable logic and apply it to your data.

The idea was taken from this awesome repo. The initial goal of jsonmap is to create compatibility with JUST.net, but then it could be more adapted for JavaScript world.

How to use?

You should provide some input raw data and transformer data that has jsonmap instructions that will be applied to input.

// your code for fetching json here, this is an example
const inputJson = fs.readFileSync(path.resolve(__dirname, `./input.json`), 'utf-8')
const transformerJson = fs.readFileSync(path.resolve(__dirname, `transformer.json`), 'utf-8')

const transformed = new JsonMap().transform(inputJson, transformerJson)

#valueof

Extracts value by provided path.

Input:

{
    "menu": {
        "popup": {
            "menuitem": {
                "open": "open-text",
                "close": "close-text"
            }
        }
    }
}

Transformer:

{
    "result": {
        "Open": "#valueof($.menu.popup.menuitem.open)",
        "Close": "#valueof($.menu.popup.menuitem.close)"
    }
}

Result:

{
    "result": {
        "Open": "open-text",
        "Close": "close-text"
    }
}

#ifcondition

Executes condition. Format: ifcondition(firstCompareArgument, secondCompareArgument, trueResult, falseResult)

Input:

{
    "menu": {
        "id": "github",
        "repository": "jsonmap"
    }
}

Transformer:

{
    "ifconditiontesttrue": "#ifcondition(#valueof($.menu.id),github,#valueof($.menu.repository),fail)",
    "ifconditiontestfalse": "#ifcondition(#valueof($.menu.id),xml,#valueof($.menu.repository),fail)"
}

Result:

{
    "ifconditiontesttrue": "jsonmap",
    "ifconditiontestfalse": "fail"
}

#loop

Tranverses an array:

Input:

{
    "numbers": [
        1,
        2,
        3,
        4
    ]
}

Transformer:

{
    "iteration": {
        "#loop($.numbers)": {
            "CurrentValue": "#currentvalue()",
            "CurrentIndex": "#currentindex()"
        }
    }
}

Result:

{
    "iteration": [
        {
            "CurrentValue": 1,
            "CurrentIndex": 0
        },
        {
            "CurrentValue": 2,
            "CurrentIndex": 1
        },
        {
            "CurrentValue": 3,
            "CurrentIndex": 2
        },
        {
            "CurrentValue": 4,
            "CurrentIndex": 3
        }
    ]
}

Type utils

String

Input:

{
    "string": "hello world",
    "equalString": "hello world"
}

Transformer:

{
    "length": "#length($.string)",
    "firstindexof": "#firstindexof($.string,world)",
    "lastindexof": "#lastindexof($.string,o)",
    "concat": "#concat($.string,abcd)",
    "equals": "#stringequals($.string,$.equalString)",
    "contains": "#stringcontains($.string,world)"
}

Result:

{
    "length": 11,
    "firstindexof": 6,
    "lastindexof": 7,
    "concat": "hello worldabcd",
    "equals": true,
    "contains": true
}

Input:

{
    "numbers": [
        2,
        4,
        8,
        1.08
    ]
}

Transformer:

{
    "add": "#add($.numbers[0],$.numbers[1],2)",
    "subtract": "#subtract($.numbers[2],$.numbers[1],$.numbers[0],1)",
    "multiply": "#multiply($.numbers[0],$.numbers[1],$.numbers[2])",
    "divide": "#divide($.numbers[2],$.numbers[1],$.numbers[0])",
    "round": "#round($.numbers[3],1)",
    "equals": "#mathequals($.numbers[0],2)",
    "greater": "#mathgreaterthan(5,2)",
    "less": "#mathlessthan(2,4)",
    "greaterOrEqual": "#mathgreaterthanorequalto(4,4)",
    "lessOrEqual": "#mathlessthanorequalto(4,4)"
} 

Result:

{
    "add": 8,
    "subtract": 1,
    "multiply": 64,
    "divide": 1,
    "round": 1.1,
    "equals": true,
    "greater": true,
    "less": true,
    "greaterOrEqual": true,
    "lessOrEqual": true
} 

Array

Input:

{
    "array": [
        1,
        2,
        3
    ],
    "stringArray": [
        "hello",
        " ",
        "world"
    ]
} 

Transformer:

{
    "length": "#length($.array)",
    "concat": "#concatAll($.stringArray)",
    "sum": "#sum(#valueof($.array))",
    "average": "#average($.array)",
    "min": "#min($.array)",
    "max": "#max($.array)"
} 

Result:

{
    "length": 3,
    "concat": "hello world",
    "sum": 6,
    "average": 2,
    "min": 1,
    "max": 3
} 

Type checking

Input:

{
    "integer": 10,
    "string": "",
    "array": [
        100
    ],
    "boolean": false
}

Transformer:

{
    "isNumberTrue": "#isnumber(#valueof($.integer))",
    "isNumberFalse": "#isnumber(#valueof($.string))",
    "isStringTrue": "#isstring(#valueof($.string))",
    "isStringFalse": "#isstring(#valueof($.integer))",
    "isBooleanTrue": "#isboolean(#valueof($.boolean))",
    "isArrayTrue": "#isarray(#valueof($.array))"
} 

Result:

{
    "isNumberTrue": true,
    "isNumberFalse": false,
    "isStringTrue": true,
    "isStringFalse": false,
    "isBooleanTrue": true,
    "isArrayTrue": true
} 

Type conversions

Input:

{
    "booleans": {
        "affirmative_string": "true",
        "negative_string": "false",
        "affirmative_int": 123,
        "negative_int": 0
    },
    "strings": {
        "integer": 123,
        "decimal": 12.34,
        "affirmative_boolean": true,
        "negative_boolean": false
    },
    "integers": {
        "string": "123",
        "decimal": 1.23,
        "affirmative_boolean": true,
        "negative_boolean": false
    },
    "decimals": {
        "integer": 123,
        "string": "1.23"
    }
} 
 24  

Transformer:

{
    "booleans": {
        "affirmative_string": "#toboolean(#valueof($.booleans.affirmative_string))",
        "negative_string": "#toboolean(#valueof($.booleans.negative_string))",
        "affirmative_int": "#toboolean(#valueof($.booleans.affirmative_int))",
        "negative_int": "#toboolean(#valueof($.booleans.negative_int))"
    },
    "strings": {
        "integer": "#tostring(#valueof($.strings.integer))",
        "decimal": "#tostring(#valueof($.strings.decimal))",
        "affirmative_boolean": "#tostring(#valueof($.strings.affirmative_boolean))",
        "negative_boolean": "#tostring(#valueof($.strings.negative_boolean))"
    },
    "integers": {
        "string": "#tointeger(#valueof($.integers.string))",
        "decimal": "#tointeger(#valueof($.integers.decimal))",
        "affirmative_boolean": "#tointeger(#valueof($.integers.affirmative_boolean))",
        "negative_boolean": "#tointeger(#valueof($.integers.negative_boolean))"
    },
    "decimals": {
        "integer": "#todecimal(#valueof($.decimals.integer))",
        "string": "#todecimal(#valueof($.decimals.string))"
    }
} 

Result:

{
    "booleans": {
        "affirmative_string": true,
        "negative_string": false,
        "affirmative_int": true,
        "negative_int": false
    },
    "strings": {
        "integer": "123",
        "decimal": "12.34",
        "affirmative_boolean": "true",
        "negative_boolean": "false"
    },
    "integers": {
        "string": 123,
        "decimal": 1,
        "affirmative_boolean": 1,
        "negative_boolean": 0
    },
    "decimals": {
        "integer": 123.0,
        "string": 1.23
    }
}

Plugins

You could extend library functionality by declaring custom functions. Jsonmap's runtime will evaluate function's argument expressions and call this function.

NOTE: Raw value passed to custom function always parsed as string, in this case you should cast it to type you actualy need (for example, in #date(123) - 123 is a string

Example:

const jsonmap = new JsonMap()

jsonmap.declare('date', (unixtime) =>
    // convert unix time to human readable date string
    new Date(+unixtime * 1000).toDateString()
)

Then use.

Input:

{
    "unixTime": 863222400
}

Transformer:

{
    "humanReadableDate": "#date(#valueof($.unixTime))"
}

Result:

{
    "humanReadableDate": "Sat May 10 1997"
}

Sandbox

https://artem-mangilev.github.io/jsonmap-repl/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK