ngx-airbrush
Version:
Angular client for jsonapi/Graphiti backends
1,527 lines (1,509 loc) • 95.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('jsona'), require('uuid'), require('rxjs/operators'), require('rxjs'), require('@angular/common/http')) :
typeof define === 'function' && define.amd ? define('ngx-airbrush', ['exports', '@angular/core', 'jsona', 'uuid', 'rxjs/operators', 'rxjs', '@angular/common/http'], factory) :
(global = global || self, factory(global['ngx-airbrush'] = {}, global.ng.core, global.Jsona, global.uuid, global.rxjs.operators, global.rxjs, global.ng.common.http));
}(this, function (exports, core, Jsona, uuid, operators, rxjs, http) { 'use strict';
Jsona = Jsona && Jsona.hasOwnProperty('default') ? Jsona['default'] : Jsona;
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var NgxAirbrushModule = /** @class */ (function () {
function NgxAirbrushModule() {
}
NgxAirbrushModule.decorators = [
{ type: core.NgModule }
];
return NgxAirbrushModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var ServiceMetadata = (/** @type {?} */ (Symbol('ServiceMetadata')));
/** @type {?} */
var ModelMetadata = (/** @type {?} */ (Symbol('ModelMetadata')));
/** @type {?} */
var AttributeMetadata = (/** @type {?} */ (Symbol('AttributeMetadata')));
/** @type {?} */
var BelongsToMetadata = (/** @type {?} */ (Symbol('BelongsToMetadata')));
/** @type {?} */
var HasManyMetadata = (/** @type {?} */ (Symbol('HasManyMetadata')));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} options
* @return {?}
*/
function ServiceDecorator(options) {
return (/**
* @param {?} target
* @return {?}
*/
function (target) {
Reflect.defineMetadata(ServiceMetadata, options, target);
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var TypesStore = /** @class */ (function () {
function TypesStore() {
// tslint:disable-next-line: variable-name
this._types = {};
}
/**
* @return {?}
*/
TypesStore.getInstance = /**
* @return {?}
*/
function () {
if (!TypesStore.instance) {
TypesStore.instance = new TypesStore();
}
return TypesStore.instance;
};
/**
* @param {?} key
* @param {?} obj
* @return {?}
*/
TypesStore.add = /**
* @param {?} key
* @param {?} obj
* @return {?}
*/
function (key, obj) {
TypesStore.getInstance().add(key, obj);
};
/**
* @param {?} key
* @return {?}
*/
TypesStore.find = /**
* @param {?} key
* @return {?}
*/
function (key) {
return TypesStore.getInstance().find(key);
};
/**
* @return {?}
*/
TypesStore.all = /**
* @return {?}
*/
function () {
return TypesStore.getInstance().all;
};
/**
* @param {?} key
* @param {?} obj
* @return {?}
*/
TypesStore.prototype.add = /**
* @param {?} key
* @param {?} obj
* @return {?}
*/
function (key, obj) {
this._types[key] = obj;
};
/**
* @param {?} key
* @return {?}
*/
TypesStore.prototype.find = /**
* @param {?} key
* @return {?}
*/
function (key) {
return this.all[key];
};
Object.defineProperty(TypesStore.prototype, "all", {
get: /**
* @return {?}
*/
function () { return this._types; },
enumerable: true,
configurable: true
});
TypesStore.instance = null;
return TypesStore;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} options
* @return {?}
*/
function Model(options) {
return (/**
* @param {?} target
* @return {?}
*/
function (target) {
Reflect.defineMetadata(ModelMetadata, options, target);
TypesStore.add(options.type, target);
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var DateConverter = /** @class */ (function () {
function DateConverter() {
}
/**
* @param {?} value
* @return {?}
*/
DateConverter.prototype.deserialize = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (!value) {
return null;
}
return new Date(value);
};
/**
* @param {?} value
* @return {?}
*/
DateConverter.prototype.serialize = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (!value) {
return null;
}
return value.toJSON();
};
return DateConverter;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?=} options
* @return {?}
*/
function Attribute(options) {
if (options === void 0) { options = {}; }
return (/**
* @param {?} target
* @param {?} propertyName
* @return {?}
*/
function (target, propertyName) {
/** @type {?} */
var converter = (/**
* @param {?} propType
* @return {?}
*/
function (propType) {
/** @type {?} */
var attrConverter;
if (options.converter) {
attrConverter = options.converter;
}
else if (propType === Date) {
attrConverter = new DateConverter();
}
else {
/** @type {?} */
var datatype = new propType();
if (datatype.serialize && datatype.deserialize) {
attrConverter = datatype;
}
}
return attrConverter;
});
/** @type {?} */
var convert = (/**
* @param {?} propType
* @param {?} value
* @param {?=} serialize
* @return {?}
*/
function (propType, value, serialize) {
if (serialize === void 0) { serialize = false; }
/** @type {?} */
var attrConverter = converter(propType);
if (attrConverter) {
if (serialize) {
return attrConverter.serialize(value);
}
return attrConverter.deserialize(value);
} // else
return value;
});
/** @type {?} */
var areEquals = (/**
* @param {?} propType
* @param {?} oldValue
* @param {?} newValue
* @return {?}
*/
function (propType, oldValue, newValue) {
/** @type {?} */
var attrConverter = converter(propType);
if (attrConverter) {
if (attrConverter.areEquals) {
return attrConverter.areEquals(oldValue, newValue);
}
// else
/** @type {?} */
var newVal = attrConverter.serialize(newValue);
/** @type {?} */
var oldVal = attrConverter.serialize(oldValue);
return newVal === oldVal;
} // else
return oldValue === newValue;
});
/** @type {?} */
var setupMetadata = (/**
* @return {?}
*/
function () {
/** @type {?} */
var attributes = Reflect.getMetadata(AttributeMetadata, target) || [];
attributes.push({
propertyName: propertyName,
backendName: options.backendName || propertyName,
readonly: !!options.readonly,
converter: options.converter,
});
Reflect.defineMetadata(AttributeMetadata, attributes, target);
});
/** @type {?} */
var setMetadata = (/**
* @param {?} instance
* @param {?} oldValue
* @param {?} newValue
* @return {?}
*/
function (instance, oldValue, newValue) {
/** @type {?} */
var propType = Reflect.getMetadata('design:type', target, propertyName);
instance[AttributeMetadata] = instance[AttributeMetadata] || {};
instance[AttributeMetadata][propertyName] = {
newValue: newValue,
oldValue: oldValue,
backendName: options.backendName || propertyName,
hasDirtyAttributes: !areEquals(propType, oldValue, newValue),
serializedValue: convert(propType, newValue, true),
};
});
/** @type {?} */
var getter = (/**
* @return {?}
*/
function () {
return this["_" + propertyName];
});
/** @type {?} */
var setter = (/**
* @param {?} newVal
* @return {?}
*/
function (newVal) {
/** @type {?} */
var propType = Reflect.getMetadata('design:type', target, propertyName);
/** @type {?} */
var serialized = convert(propType, newVal);
/** @type {?} */
var oldValue = null;
if (this.isModelInitialization() && this.id) {
oldValue = serialized;
}
else {
if (this[AttributeMetadata] && this[AttributeMetadata][propertyName]) {
oldValue = this[AttributeMetadata][propertyName].oldValue;
}
}
this["_" + propertyName] = serialized;
setMetadata(this, oldValue, serialized);
});
if (delete target[propertyName]) {
setupMetadata();
Object.defineProperty(target, propertyName, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var JsonapiConverter = /** @class */ (function () {
function JsonapiConverter() {
this.jsona = new Jsona();
}
/**
* @param {?} data
* @return {?}
*/
JsonapiConverter.prototype.deserialize = /**
* @param {?} data
* @return {?}
*/
function (data) {
return this.jsona.deserialize(data);
};
/**
* @param {?} data
* @param {?=} includedKeys
* @return {?}
*/
JsonapiConverter.prototype.serialize = /**
* @param {?} data
* @param {?=} includedKeys
* @return {?}
*/
function (data, includedKeys) {
if (!data) {
return;
}
// data preparation
this.defineTempIds(data);
/** @type {?} */
var body = (/** @type {?} */ (this.jsona.serialize({ stuff: data, includeNames: includedKeys })));
if (!body) {
return;
}
// Fix relationships and includes
if (!body.data.id) {
delete body.data.id;
}
this.addMethodsInRelations(data, body);
this.deleteMethodsInIncludes(body);
this.renameTempIdKeys(body);
return (/** @type {?} */ (body));
};
/**
* @private
* @param {?} data
* @return {?}
*/
JsonapiConverter.prototype.defineTempIds = /**
* @private
* @param {?} data
* @return {?}
*/
function (data) {
var _this = this;
this.getRelationsKeys(data).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
/** @type {?} */
var resources = data[key];
_this.execOnElementOrArray(resources, (/**
* @param {?} elt
* @return {?}
*/
function (elt) {
if (elt.__method === 'create') {
elt.id = elt.id || uuid.v4();
}
_this.defineTempIds(elt);
}));
}));
};
/**
* @private
* @param {?} data
* @param {?} body
* @return {?}
*/
JsonapiConverter.prototype.addMethodsInRelations = /**
* @private
* @param {?} data
* @param {?} body
* @return {?}
*/
function (data, body) {
var _this = this;
this.updateMethods(data, body.data);
this.getRelationsKeys(data).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return data[key]; })).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
_this.execOnElementOrArray(data[key], (/**
* @param {?} elt
* @return {?}
*/
function (elt) { return _this.updateMethodsInculdes(elt, body.included); }));
}));
};
/**
* @private
* @param {?} data
* @param {?} includes
* @return {?}
*/
JsonapiConverter.prototype.updateMethodsInculdes = /**
* @private
* @param {?} data
* @param {?} includes
* @return {?}
*/
function (data, includes) {
var _this = this;
/** @type {?} */
var found = includes && includes.find((/**
* @param {?} incl
* @return {?}
*/
function (incl) { return (incl.id === data.id && incl.type === data.type); }));
if (!found) {
return;
}
this.updateMethods(data, found);
this.getRelationsKeys(data).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return data[key]; })).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
_this.updateMethodsInculdes(data[key], includes);
}));
};
/**
* @private
* @param {?} data
* @param {?} resource
* @return {?}
*/
JsonapiConverter.prototype.updateMethods = /**
* @private
* @param {?} data
* @param {?} resource
* @return {?}
*/
function (data, resource) {
var _this = this;
/** @type {?} */
var relations = resource.relationships;
if (!relations) {
return;
}
this.getRelationsKeys(data).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return relations[key]; })).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
_this.execOnElementOrArray(relations[key].data, (/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.method = data[key].__method; }), (/**
* @param {?} elt
* @return {?}
*/
function (elt) {
/** @type {?} */
var method = data[key].find((/**
* @param {?} itm
* @return {?}
*/
function (itm) { return itm.id === elt.id; })).__method;
elt.method = method;
}));
}));
};
/**
* @private
* @param {?} body
* @return {?}
*/
JsonapiConverter.prototype.deleteMethodsInIncludes = /**
* @private
* @param {?} body
* @return {?}
*/
function (body) {
/** @type {?} */
var includes = body.included || [];
includes.forEach((/**
* @param {?} incl
* @return {?}
*/
function (incl) {
delete incl.attributes.__method;
}));
};
/**
* @private
* @param {?} body
* @return {?}
*/
JsonapiConverter.prototype.renameTempIdKeys = /**
* @private
* @param {?} body
* @return {?}
*/
function (body) {
var _this = this;
/** @type {?} */
var includes = body.included;
if (!includes) {
return;
}
this.setTempId(body.data, includes);
includes.forEach((/**
* @param {?} elt
* @return {?}
*/
function (elt) {
_this.setTempId(elt, includes);
}));
};
/**
* @private
* @param {?} resource
* @param {?} includes
* @return {?}
*/
JsonapiConverter.prototype.setTempId = /**
* @private
* @param {?} resource
* @param {?} includes
* @return {?}
*/
function (resource, includes) {
var _this = this;
/** @type {?} */
var relations = resource.relationships;
if (!relations) {
return;
}
/** @type {?} */
var keys = Object.keys(relations).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return (relations.hasOwnProperty(key) && relations[key]); }));
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
_this.execOnElementOrArray(relations[key].data, (/**
* @param {?} elt
* @return {?}
*/
function (elt) {
if (elt.method === 'create') {
/** @type {?} */
var included = includes.find((/**
* @param {?} itm
* @return {?}
*/
function (itm) { return itm.id === elt.id && itm.type === elt.type; }));
included['temp-id'] = included.id;
elt['temp-id'] = elt.id;
delete included.id;
delete elt.id;
}
}));
}));
};
/**
* @private
* @param {?} resource
* @return {?}
*/
JsonapiConverter.prototype.getRelationsKeys = /**
* @private
* @param {?} resource
* @return {?}
*/
function (resource) {
return resource.relationshipNames || [];
};
/**
* @private
* @param {?} elements
* @param {?} callback
* @param {?=} callBackArray
* @return {?}
*/
JsonapiConverter.prototype.execOnElementOrArray = /**
* @private
* @param {?} elements
* @param {?} callback
* @param {?=} callBackArray
* @return {?}
*/
function (elements, callback, callBackArray) {
callBackArray = callBackArray || callback;
if (Array.isArray(elements)) {
elements.forEach((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return callBackArray(elt); }));
}
else {
callback(elements);
}
};
return JsonapiConverter;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var getIncludedKeys;
var ResourceMetadataWrapper = /** @class */ (function () {
function ResourceMetadataWrapper(model) {
this.model = model;
}
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.allKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
return __spread(this.attributesKeys(options), this.relationshipKeys(options));
};
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.relationshipKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
return __spread(this.belongsToKeys(options), this.hasManyKeys(options));
};
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.attributesKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
var _this = this;
/** @type {?} */
var keys = this.retrieveKeys(AttributeMetadata);
if (options && options.defined) {
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.model[key] !== undefined; }));
// FIXME: quick fix to delete null values when it's a create
if (!this.model.id) {
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.model[key] !== null; }));
}
}
return keys;
};
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.belongsToKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
return this.retrieveKeys(BelongsToMetadata, options);
};
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.hasManyKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
return this.retrieveKeys(HasManyMetadata, options);
};
/**
* @return {?}
*/
ResourceMetadataWrapper.prototype.allMetadata = /**
* @return {?}
*/
function () {
return __spread(this.attributesMetadata(), this.relationshipMetadata());
};
/**
* @return {?}
*/
ResourceMetadataWrapper.prototype.relationshipMetadata = /**
* @return {?}
*/
function () {
return __spread(this.belongsToMetadata(), this.hasManyMetadata());
};
/**
* @return {?}
*/
ResourceMetadataWrapper.prototype.attributesMetadata = /**
* @return {?}
*/
function () {
return this.retrieveMetadata(AttributeMetadata);
};
/**
* @return {?}
*/
ResourceMetadataWrapper.prototype.belongsToMetadata = /**
* @return {?}
*/
function () {
return this.retrieveMetadata(BelongsToMetadata);
};
/**
* @return {?}
*/
ResourceMetadataWrapper.prototype.hasManyMetadata = /**
* @return {?}
*/
function () {
return this.retrieveMetadata(HasManyMetadata);
};
/**
* @param {?} propertyName
* @return {?}
*/
ResourceMetadataWrapper.prototype.isSidepostable = /**
* @param {?} propertyName
* @return {?}
*/
function (propertyName) {
/** @type {?} */
var metadata = Reflect.getMetadata(BelongsToMetadata, this.model);
/** @type {?} */
var found = metadata && metadata.find((/**
* @param {?} rel
* @return {?}
*/
function (rel) { return rel.propertyName === propertyName; }));
if (found) {
return found.sidepostable;
}
metadata = Reflect.getMetadata(HasManyMetadata, this.model);
found = metadata && metadata.find((/**
* @param {?} rel
* @return {?}
*/
function (rel) { return rel.propertyName === propertyName; }));
if (found) {
return found.sidepostable;
}
};
/**
* @param {?} propertyName
* @return {?}
*/
ResourceMetadataWrapper.prototype.isWritable = /**
* @param {?} propertyName
* @return {?}
*/
function (propertyName) {
/** @type {?} */
var allMetadata = this.allMetadata();
/** @type {?} */
var found = allMetadata.find((/**
* @param {?} pname
* @return {?}
*/
function (pname) { return pname.propertyName === propertyName; }));
if (found) {
return !found.readonly;
}
};
/**
* @param {?} propertyName
* @return {?}
*/
ResourceMetadataWrapper.prototype.backendPropName = /**
* @param {?} propertyName
* @return {?}
*/
function (propertyName) {
/** @type {?} */
var allMetadata = this.allMetadata();
/** @type {?} */
var found = allMetadata.find((/**
* @param {?} pname
* @return {?}
*/
function (pname) { return pname.propertyName === propertyName; }));
if (found) {
return found.backendName;
}
};
/**
* @param {?} propertyName
* @return {?}
*/
ResourceMetadataWrapper.prototype.frontendPropName = /**
* @param {?} propertyName
* @return {?}
*/
function (propertyName) {
/** @type {?} */
var allMetadata = this.allMetadata();
// search in backend
/** @type {?} */
var found = allMetadata.find((/**
* @param {?} pname
* @return {?}
*/
function (pname) { return pname.backendName === propertyName; }));
if (found) {
return found.propertyName;
}
// search in frontend
found = allMetadata.find((/**
* @param {?} pname
* @return {?}
*/
function (pname) { return pname.propertyName === propertyName; }));
if (found) {
return propertyName;
}
};
/**
* @private
* @param {?} symbol
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.retrieveKeys = /**
* @private
* @param {?} symbol
* @param {?=} options
* @return {?}
*/
function (symbol, options) {
var _this = this;
this.model.modelSerialization = true;
/** @type {?} */
var metadata = this.retrieveMetadata(symbol);
/** @type {?} */
var keys = metadata.map((/**
* @param {?} btm
* @return {?}
*/
function (btm) { return btm.propertyName; }));
if (options && options.defined) {
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.model[key]; }));
}
this.model.modelSerialization = false;
return keys;
};
/**
* @private
* @param {?} symbol
* @return {?}
*/
ResourceMetadataWrapper.prototype.retrieveMetadata = /**
* @private
* @param {?} symbol
* @return {?}
*/
function (symbol) {
return Reflect.getMetadata(symbol, this.model) || [];
};
/**
* @param {?=} options
* @return {?}
*/
ResourceMetadataWrapper.prototype.getIncludedKeys = /**
* @param {?=} options
* @return {?}
*/
function (options) {
options = (options || {}) && __assign({ forBackend: true }, options);
return getIncludedKeys(this.model, this, options);
};
return ResourceMetadataWrapper;
}());
getIncludedKeys = (/**
* @param {?} model
* @param {?} wrapper
* @param {?=} options
* @return {?}
*/
function (model, wrapper, options) {
/** @type {?} */
var keyTranslator = options.forBackend ? 'backendPropName' : 'frontendPropName';
/** @type {?} */
var localKeys = wrapper.relationshipKeys({ defined: true }).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return wrapper.isSidepostable(key); }));
/** @type {?} */
var childKeys = [];
localKeys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
/** @type {?} */
var resource = model[key];
/** @type {?} */
var cKeys = [];
if (Array.isArray(resource)) {
resource.forEach((/**
* @param {?} elt
* @return {?}
*/
function (elt) {
/** @type {?} */
var wrap = new ResourceMetadataWrapper(elt);
/** @type {?} */
var keys = getIncludedKeys(elt, wrap, options);
cKeys.push.apply(cKeys, __spread(keys));
}));
}
else {
/** @type {?} */
var wrap = new ResourceMetadataWrapper(resource);
/** @type {?} */
var keys = getIncludedKeys(resource, wrap, options);
cKeys.push.apply(cKeys, __spread(keys));
}
cKeys = cKeys.map((/**
* @param {?} ckey
* @return {?}
*/
function (ckey) { return wrapper[keyTranslator](key) + "." + ckey; }));
// remove duplicates
cKeys = cKeys.filter((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
function (item, index) { return cKeys.indexOf(item) >= index; }));
childKeys.push.apply(childKeys, __spread(cKeys));
}));
localKeys = localKeys.map((/**
* @param {?} lkey
* @return {?}
*/
function (lkey) { return wrapper[keyTranslator](lkey); }));
return __spread(localKeys, childKeys);
});
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var ResourceSerializer = /** @class */ (function () {
function ResourceSerializer(model) {
this.model = model;
this.mdwrapper = new ResourceMetadataWrapper(model);
}
/**
* @return {?}
*/
ResourceSerializer.prototype.toJsonapi = /**
* @return {?}
*/
function () {
/** @type {?} */
var result = this.serialize();
/** @type {?} */
var includeKeys = this.mdwrapper.getIncludedKeys();
/** @type {?} */
var body = new JsonapiConverter().serialize(result, includeKeys);
return body;
};
/**
* @return {?}
*/
ResourceSerializer.prototype.serialize = /**
* @return {?}
*/
function () {
/** @type {?} */
var type = this.model.type;
var _a = __read(this.serializeAll(), 3), attributes = _a[0], belongstos = _a[1], hasManys = _a[2];
/** @type {?} */
var relationshipNames = [];
relationshipNames.push.apply(relationshipNames, __spread(Object.keys(belongstos).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return belongstos.hasOwnProperty(key); }))));
relationshipNames.push.apply(relationshipNames, __spread(Object.keys(hasManys).filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return hasManys.hasOwnProperty(key); }))));
/** @type {?} */
var result = __assign({ id: this.model.id, type: type }, attributes, belongstos, hasManys, { relationshipNames: relationshipNames });
if (this.model.isRelation) {
result.__method = this.model.relationMethod;
}
return result;
};
/**
* @return {?}
*/
ResourceSerializer.prototype.toHash = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var res = { id: this.model.id, type: this.model.type };
this.mdwrapper.attributesKeys({ defined: true }).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) { return res[key] = _this.model[key]; }));
this.mdwrapper.belongsToKeys({ defined: true }).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) { return res[key] = _this.model[key].toHash(); }));
this.mdwrapper.hasManyKeys({ defined: true }).forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
_this.model[key].forEach((/**
* @param {?} elt
* @return {?}
*/
function (elt) {
res[key] = res[key] || []; // no need to init res[key] if array has no elements.
res[key].push(elt.toHash());
}));
}));
return res;
};
/**
* @private
* @return {?}
*/
ResourceSerializer.prototype.serializeAll = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var attributes = this.serializeAttributes();
/** @type {?} */
var belongstos = this.serializeBelongsTo();
/** @type {?} */
var hasManys = this.serializeHasMany();
return [attributes, belongstos, hasManys];
};
/**
* @private
* @return {?}
*/
ResourceSerializer.prototype.serializeAttributes = /**
* @private
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var keys = this.mdwrapper.attributesKeys({ defined: true });
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.mdwrapper.isWritable(key); }));
/** @type {?} */
var attributes = this.model[AttributeMetadata];
keys = this.model.id ? keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return attributes[key].hasDirtyAttributes; })) : keys;
/** @type {?} */
var result = {};
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
/** @type {?} */
var beKey = _this.mdwrapper.backendPropName(key);
result[beKey] = attributes[key].serializedValue;
}));
return result;
};
/**
* @private
* @return {?}
*/
ResourceSerializer.prototype.serializeBelongsTo = /**
* @private
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var keys = this.mdwrapper.belongsToKeys({ defined: true });
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.mdwrapper.isWritable(key); }));
// Ignore untouched relationships
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.model[key].hasBeenTouched; }));
/** @type {?} */
var belongstos = {};
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
/** @type {?} */
var sidepostable = _this.mdwrapper.isSidepostable(key);
/** @type {?} */
var beKey = _this.mdwrapper.backendPropName(key);
belongstos[beKey] = sidepostable ? _this.model[key].serialize() : _this.model[key].sideload();
if (!belongstos[beKey]) {
delete belongstos[beKey];
}
}));
return belongstos;
};
/**
* @private
* @return {?}
*/
ResourceSerializer.prototype.serializeHasMany = /**
* @private
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var keys = this.mdwrapper.hasManyKeys({ defined: true });
keys = keys.filter((/**
* @param {?} key
* @return {?}
*/
function (key) { return _this.mdwrapper.isWritable(key); }));
/** @type {?} */
var hasManys = {};
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
/** @type {?} */
var sidepostable = _this.mdwrapper.isSidepostable(key);
/** @type {?} */
var beKey = _this.mdwrapper.backendPropName(key);
hasManys[beKey] = sidepostable ?
_this.model[key].filter((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.hasBeenTouched; })).map((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.serialize(); })) :
_this.model[key].filter((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.hasBeenTouched; })).map((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.sideload(); }));
if (hasManys[beKey].length === 0) {
delete hasManys[beKey];
}
}));
return hasManys;
};
return ResourceSerializer;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @abstract
*/
var /**
* @abstract
*/
ResourceBase = /** @class */ (function () {
function ResourceBase(data) {
this.modelInitialization = false;
this.modelSerialization = false;
this.__isRelation = false;
if (!data) {
return;
}
this.modelInitialization = true;
this.id = data.id;
this.assign(data);
this.modelInitialization = false;
}
Object.defineProperty(ResourceBase.prototype, "__wrapper", {
get: /**
* @private
* @return {?}
*/
function () {
if (!this.__mdwrapper) {
this.__mdwrapper = new ResourceMetadataWrapper(this);
}
return this.__mdwrapper;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "__serializer", {
get: /**
* @private
* @return {?}
*/
function () {
if (!this.__resSerializer) {
this.__resSerializer = new ResourceSerializer(this);
}
return this.__resSerializer;
},
enumerable: true,
configurable: true
});
/**
* @template T
* @param {?} constructor
* @param {?=} data
* @return {?}
*/
ResourceBase.getModel = /**
* @template T
* @param {?} constructor
* @param {?=} data
* @return {?}
*/
function (constructor, data) {
/** @type {?} */
var ret = new JsonapiConverter().deserialize(data);
return new constructor(ret);
};
/**
* @template T
* @param {?} constructor
* @param {?} data
* @param {?=} options
* @return {?}
*/
ResourceBase.getAsRelationship = /**
* @template T
* @param {?} constructor
* @param {?} data
* @param {?=} options
* @return {?}
*/
function (constructor, data, options) {
if (!data) {
return null;
}
options = __assign({ method: 'untouched', modelInit: false }, options);
/** @type {?} */
var model;
if (options.modelInit) {
model = new constructor(data);
}
else {
model = new constructor();
model.id = data.id;
model.assign(data);
}
model.__isRelation = true;
model.__method = options.method;
return model;
};
/**
* @return {?}
*/
ResourceBase.prototype.isModelInitialization = /**
* @return {?}
*/
function () {
return this.modelInitialization;
};
Object.defineProperty(ResourceBase.prototype, "modelOptions", {
get: /**
* @return {?}
*/
function () {
return Reflect.getMetadata(ModelMetadata, this.constructor);
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "type", {
get: /**
* @return {?}
*/
function () {
return this.modelOptions.type;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "hasBeenTouched", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var touched = this.__isRelation && this.__method !== 'untouched';
return this.hasDirtyAttributes || this.hasDirtyBelongsTos || this.hasDirtyHasManys || touched;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "hasDirtyAttributes", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var attributesMetadata = this[AttributeMetadata];
for (var propertyName in attributesMetadata) {
if (attributesMetadata.hasOwnProperty(propertyName) && attributesMetadata[propertyName].hasDirtyAttributes) {
return true;
}
}
return false;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "hasDirtyBelongsTos", {
get: /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var keys = this.__wrapper.belongsToKeys({ defined: true });
/** @type {?} */
var touched = false;
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
touched = touched || _this[key].hasBeenTouched;
}));
return touched;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "hasDirtyHasManys", {
get: /**
* @return {?}
*/
function () {
var _this = t