Passed
Pull Request — master (#3)
by Alberto
02:16 queued 28s
created

lib/CompoundDocument.js   A

Complexity

Total Complexity 28
Complexity/F 2

Size

Lines of Code 117
Function Count 14

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 28
eloc 77
mnd 14
bc 14
fnc 14
dl 0
loc 117
bpm 1
cpm 2
noi 11
c 0
b 0
f 0
rs 10
1
"use strict";
2
var __assign = (this && this.__assign) || function () {
3
    __assign = Object.assign || function(t) {
4
        for (var s, i = 1, n = arguments.length; i < n; i++) {
5
            s = arguments[i];
6
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
                t[p] = s[p];
8
        }
9
        return t;
10
    };
11
    return __assign.apply(this, arguments);
12
};
13
var __importStar = (this && this.__importStar) || function (mod) {
14
    if (mod && mod.__esModule) return mod;
15
    var result = {};
16
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
17
    result["default"] = mod;
18
    return result;
19
};
20
Object.defineProperty(exports, "__esModule", { value: true });
21
var Array_1 = require("fp-ts/lib/Array");
22
var function_1 = require("fp-ts/lib/function");
23
var pipeable_1 = require("fp-ts/lib/pipeable");
24
var Writer_1 = require("fp-ts/lib/Writer");
25
var t = __importStar(require("io-ts"));
26
var ArrayC_1 = require("./io/ArrayC");
27
var EntityC_1 = require("./io/EntityC");
28
var NonEmptyArrayC_1 = require("./io/NonEmptyArrayC");
29
var ResourceIdentifierC_1 = require("./io/ResourceIdentifierC");
30
var JsonApiData_1 = require("./JsonApiData");
31
var RelationshipsCache_1 = require("./RelationshipsCache");
32
var m = Writer_1.getMonad(RelationshipsCache_1.RelationshipsCache.monoid.self);
33
var M = pipeable_1.pipeable(m);
34
var fromUnknown = function (u) {
35
    return m.of(u);
36
};
37
var fromArray = function (u) {
38
    return Array_1.array.traverse(m)(u, fromJson);
39
};
40
var fromRecord = function (u) {
41
    return Object.keys(u)
42
        .reduce(function (writer, key) {
43
        return pipeable_1.pipe(writer, M.chain(
44
        // The accumulator (bag of relationships) has to be modified depending on returned data (the actual JSON).
45
        function (attributes) { return Writer_1.pass(pipeable_1.pipe(fromJson(u[key]), M.map(function (data) {
46
            var _a, _b;
47
            return !t.UnknownRecord.is(data)
48
                /**
49
                 * No transformation needed with a scalar, just map the value in the result (as an [attribute][1]).
50
                 *
51
                 * [1]: https://jsonapi.org/format/#document-resource-object-attributes
52
                 */
53
                ? [
54
                    __assign(__assign({}, attributes), (_a = {}, _a[key] = data, _a)),
55
                    function_1.identity
56
                ]
57
                // Beware: *non-empty* array.
58
                : ResourceIdentifierC_1.ResourceIdentifierC.is(data) || NonEmptyArrayC_1.NonEmptyArrayC(ResourceIdentifierC_1.ResourceIdentifierC).is(data)
59
                    /**
60
                     * Child resources must be added to the bag of [relationships][1] (the accumulator). Leave the
61
                     * attributes alone.
62
                     *
63
                     * [1]: https://jsonapi.org/format/#document-resource-object-relationships
64
                     */
65
                    ? [
66
                        attributes,
67
                        function (relationships) {
68
                            var _a;
69
                            return RelationshipsCache_1.RelationshipsCache.monoid.self
70
                                .concat(relationships, (_a = {}, _a[key] = data, _a));
71
                        }
72
                    ]
73
                    /**
74
                     * A nested non-resource object must be added to the attributes just like a scalar, while current
75
                     * relationships have to mirror the nesting.
76
                     */
77
                    : [
78
                        __assign(__assign({}, attributes), (_b = {}, _b[key] = data, _b)),
79
                        function (relationships) { return RelationshipsCache_1.RelationshipsCache.nestLocal(relationships, key); }
80
                    ];
81
        }))); }));
82
    }, fromUnknown({}));
83
};
84
var fromJson = function (u, primaryData) {
85
    if (primaryData === void 0) { primaryData = false; }
86
    return !t.UnknownRecord.is(u)
87
        ? fromUnknown(u)
88
        : Writer_1.pass(// pass() allows both Writer elements to be modified at once.
89
        pipeable_1.pipe(Writer_1.listen(// Expose Writer accumulator.
90
        (ArrayC_1.ArrayC().is(u)
91
            ? fromArray(u)
92
            : fromRecord(u))), M.map(function (_a) {
93
            var data = _a[0], relationships = _a[1];
94
            var cache = RelationshipsCache_1.RelationshipsCache.fromRelationships(relationships);
95
            var locals = RelationshipsCache_1.RelationshipsCache.lens.local.get(cache);
96
            /**
97
             * If resulting data is an entity - or if we're parsing [primary data][1] -, convert it to JSON:API format and
98
             * flush local relationships.
99
             * Otherwise, just forward everything to the upper level.
100
             *
101
             * [1]: https://jsonapi.org/format/#document-top-level
102
             */
103
            return primaryData &&
104
                !NonEmptyArrayC_1.NonEmptyArrayC(ResourceIdentifierC_1.ResourceIdentifierC).is(data) || // Prevent repeating the conversion.
105
                EntityC_1.EntityC.is(data)
106
                ? [
107
                    ArrayC_1.ArrayC().is(data)
108
                        ? data.map(function (record) { return JsonApiData_1.JsonApiData.fromJson(record, locals); })
109
                        : JsonApiData_1.JsonApiData.fromJson(data, locals),
110
                    RelationshipsCache_1.RelationshipsCache.emptyLocal
111
                ]
112
                : [data, function_1.identity];
113
        })));
114
};
115
exports.CompoundDocument = {
116
    fromJson: fromJson
117
};
118