|
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
|
|
|
|
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.