File: index.js

package info (click to toggle)
node-json-localizer 0.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 96 kB
  • ctags: 43
  • sloc: makefile: 4; sh: 2
file content (131 lines) | stat: -rw-r--r-- 3,899 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// API
// var localizer = Localizer(source);
// localizer.where('path.to.prop').then('newvalue');
// localizer.where('path.to.prop').if({key: value}).then({anotherkey: value, andalso: anothervalue});


var L = function (source) {
    this.source = source;
    this.target = [];
    this.leaf = null;
};

L.prototype.where = function (path) {
    var paths = path.split('.'),
        source = this.source,
        step, leaf = paths.length - 1;
    for (var i = 0; i <= leaf; i++) {
        step = source[paths[i]];
        this.leaf = paths[i];
        if (typeof step !== 'undefined') {
            if (i === leaf) {
                if (L.isObject(step) || L.isObjectsArray(step)) source = step;
                else continue;  // Keep parent as reference.
            } else if (step instanceof Object) {
                source = step; // Continue.
            } else {
                // We have hit somethings that is not an object,
                // and we are not at the leaf of the path, that's
                // and invalid path.
                source = null;
                break;
            }
        } else return this;
    }
    if (source) this.target = Array.isArray(source) ? source : [source];
    return this;
};

L.prototype.if = function (rules) {
    if (!(rules instanceof Object) || Array.isArray(rules)) {
        var tmp = rules;
        rules = {};
        rules[this.leaf] = tmp;
    }
    var target = [];
    main: for (var i = 0; i < this.target.length; i++) {
        for (var path in rules) {
            if (!L.hasValue(this.target[i], path, rules[path])) continue main;
        }
        target.push(this.target[i]);
    }
    this.target = target;
    return this;
};

L.prototype.then = function (rules) {
    var toapply = rules;
    for (var i = 0; i < this.target.length; i++) {
        if (typeof rules === 'function') toapply = rules(this.target[i]);
        if (!(toapply instanceof Object) || Array.isArray(toapply)) {
            var tmp = toapply;
            toapply = {};
            toapply[this.leaf] = tmp;
        }
        for (var path in toapply) {
            L.setValue(this.target[i], path, toapply[path]);
        }
    }
    return this;
};

L.prototype.fromString = function (rules) {
    rules = typeof rules === 'string' ? JSON.parse(rules) : rules;
    if (!Array.isArray(rules)) rules = [rules];
    for (var i = 0, rule; i < rules.length; i++) {
        rule = rules[i];
        if (rule.where) this.where(rule.where);
        else continue;
        if (rule.if) this.if(rule.if);
        if (rule.then) this.then(rule.then);
    }
    return this;
};

/*
* Turns {"Datasource": {"id": "xxx"}} into {"Datasource.id": "xxx"}
*/
L.flaten = function (obj) {
    var output = {};
    var flaten = function (els, prefix) {
        prefix = prefix && prefix + '.' || '';
        var key, value;
        for (var el in els) {
            key = prefix + el;
            value = els[el];
            if (value instanceof Object) {
                flaten(value, key);
            } else {
                output[key] = value;
            }
        }
    };
    flaten(obj);
    return output;
};

L.hasValue = function (obj, path, expected) {
    var flat = L.flaten(obj),
        current = flat[path];
    return expected instanceof Array && expected.indexOf(current) !== -1 || current === expected;
};

L.setValue = function(obj, path, value) {
    var path_elements = path.split('.'),
        field = obj;
    for (var el in path_elements) {
        if (typeof field === 'undefined') break;
        if (L.isObject(field[path_elements[el]])) field = field[path_elements[el]];
        else field[path_elements[el]] = value;
    }
};

L.isObject = function (what) {
    return what && what.constructor === Object;
};

L.isObjectsArray = function (what) {
    return Array.isArray(what) && what.every(L.isObject);
};

exports.Localizer = L;