simple-jas
Version:
A simple, smart, minimum configuration JSONAPI serializer.
219 lines (180 loc) • 7.05 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.howLongUntilLunch = factory());
}(this, (function () { 'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var index = {
serialize: function serialize(dataObject) {
var other = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return Object.assign({}, { data: this.serializeData(dataObject) }, other);
},
serializeData: function serializeData(object) {
var _this = this;
var data = {
type: object.type,
attributes: {},
relationships: {}
};
if (object.id) {
data.id = object.id;
}
Object.keys(object).forEach(function (key) {
var value = object[key];
// Ignore type attribute
if (key === 'type') {
return;
}
// Match relationship base on key
if (_this._endsWith(key, 'Id')) {
var relationshipKey = key.slice(0, -2);
var type = relationshipKey;
data.relationships[relationshipKey] = { data: { id: value, type: type } };
return;
}
// Match relationship base on key & value
if (_this._endsWith(key, 'Ids') && Array.isArray(value)) {
var _relationshipKey = key.slice(0, -3);
var _type = _relationshipKey;
var rioArray = [];
value.forEach(function (item) {
// If item is an object we assume there is an id attribute
if (_this._isObject(item)) {
var resourceIdentifierObject = { id: item.id, type: item.type };
resourceIdentifierObject.type = resourceIdentifierObject.type || _type;
rioArray.push(resourceIdentifierObject);
// If item is not an object we assume it is an id
} else {
rioArray.push({ id: item, type: _type });
}
});
data.relationships[_relationshipKey] = { data: rioArray };
return;
}
// Match relationship base on value
if (Array.isArray(value) && _this._isObject(value[0])) {
var _type2 = key;
var _rioArray = [];
value.forEach(function (item) {
var resourceIdentifierObject = { id: item.id, type: item.type };
resourceIdentifierObject.type = resourceIdentifierObject.type || _type2;
_rioArray.push(resourceIdentifierObject);
});
data.relationships[key] = { data: _rioArray };
return;
}
// Match relationship base on value
if (_this._isObject(value) && value.id) {
var _type3 = key;
var rio = { id: value.id, type: value.type };
rio.type = rio.type || _type3;
data.relationships[key] = { data: rio };
return;
}
// Match attributes
data.attributes[key] = value;
});
return data;
},
deserialize: function deserialize(payload) {
var deserializedData = this.deserializeData(payload.data, payload.included || []);
if (!payload.meta) {
return { data: deserializedData };
}
return { data: deserializedData, meta: payload.meta };
},
deserializeData: function deserializeData(data) {
var included = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (Array.isArray(data)) {
return this._deserializeArrayData(data, included);
}
return this._deserializeResourceData(data, included);
},
deserializeErrors: function deserializeErrors(errors) {
var errorObjects = {};
errors.forEach(function (item) {
var pointerArray = item.source.pointer.split('/');
var index = 3;
if (pointerArray.length === 3) {
index = 2;
}
errorObjects[pointerArray[index]] = errorObjects[pointerArray[index]] || [];
errorObjects[pointerArray[index]].push(item);
});
return errorObjects;
},
_deserializeArrayData: function _deserializeArrayData(data) {
var _this2 = this;
var included = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var objectArray = [];
data.forEach(function (resourceObject) {
var object = _this2._deserializeResourceData(resourceObject, included);
objectArray.push(object);
});
return objectArray;
},
_deserializeResourceData: function _deserializeResourceData(data) {
var _this3 = this;
var included = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var deserializationTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var object = {};
object.id = data.id;
object.type = data.type;
var newTree = deserializationTree.concat([{ type: data.type, id: object.id }]);
if (data.attributes) {
Object.keys(data.attributes).forEach(function (name) {
object[name] = data.attributes[name];
});
}
if (data.relationships) {
Object.keys(data.relationships).forEach(function (name) {
var value = data.relationships[name];
if (Array.isArray(value.data)) {
object[name] = [];
value.data.forEach(function (rio) {
var relationshipData = _this3._find(included, { type: rio.type, id: rio.id });
if (relationshipData) {
var relationshipObject = _this3._deserializeResourceData(relationshipData, included, newTree);
object[name].push(relationshipObject);
}
});
}
if (_this3._isObject(value.data)) {
if (_this3._find(deserializationTree, { type: value.data.type, id: value.data.id })) {
object[name] = value.data;
} else {
var rio = value.data;
var relationshipData = _this3._find(included, { type: rio.type, id: rio.id });
if (relationshipData) {
object[name] = _this3._deserializeResourceData(relationshipData, included, newTree);
} else {
object[name] = rio;
}
}
}
if (value.data === null) {
object[name] = null;
}
});
}
return object;
},
_find: function _find(collection, target) {
for (var i = 0; i < collection.length; i++) {
if (collection[i].id === target.id && collection[i].type === target.type) {
return collection[i];
}
}
},
_isObject: function _isObject(target) {
return target && !Array.isArray(target) && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object';
},
_endsWith: function _endsWith(str, search) {
if (!String.prototype.endsWith) {
return str.substring(str.length - search.length, str.length) === search;
}
return str.endsWith(search);
}
};
return index;
})));