ngx-airbrush
Version:
Angular client for jsonapi/Graphiti backends
1,770 lines (1,757 loc) • 81.1 kB
JavaScript
import { NgModule } from '@angular/core';
import { __spread, __assign, __read } from 'tslib';
import Jsona from 'jsona';
import { v4 } from 'uuid';
import { map, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { HttpParams } from '@angular/common/http';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var NgxAirbrushModule = /** @class */ (function () {
function NgxAirbrushModule() {
}
NgxAirbrushModule.decorators = [
{ type: 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 || 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 = this;
/** @type {?} */
var keys = this.__wrapper.hasManyKeys({ defined: true });
/** @type {?} */
var touched = false;
keys.forEach((/**
* @param {?} key
* @return {?}
*/
function (key) {
touched = touched || _this[key].map((/**
* @param {?} elt
* @return {?}
*/
function (elt) { return elt.hasBeenTouched; })).reduce((/**
* @param {?} res
* @param {?} bool
* @return {?}
*/
function (res, bool) { return res || bool; }), false);
}));
return touched;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "isRelation", {
get: /**
* @return {?}
*/
function () {
return this.__isRelation;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ResourceBase.prototype, "relationMethod", {
get: /**
* @return {?}
*/
function () {
if (this.__method !== 'untouched') {
return this.__method;
}
if (!this.hasBeenTouched) {
return 'untouched';
}
if (this.id) {
return 'update';
}
return 'create';
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
ResourceBase.prototype.rollbackAttributes = /**
* @return {?}
*/
function () {
/** @type {?} */
var attributesMetadata = this[AttributeMetadata];
for (var propertyName in attributesMetadata) {
if (attributesMetadata.hasOwnProperty(propertyName) && attributesMetadata[propertyName].hasDirtyAttributes) {
this[propertyName] = attributesMetadata[propertyName].oldValue;
}
}
};
/**
* @param {?} data
* @return {?}
*/
ResourceBase.prototype.assign = /**
* @param {?} data
* @return {?}
*/
function (data) {
/** @type {?} */
var clone = this.translateKeys(data);
Object.assign(this, clone);
if (this.__isRelation) {
this.__method = this.relationMethod;
}
};
/**
* @return {?}
*/
ResourceBase.prototype.disassociate = /**
* @return {?}
*/
function () {
this.__method = 'disassociate';
};
/**
* @return {?}
*/
ResourceBase.prototype.destroy = /**
* @return {?}
*/
function () {
if (this.isRelation) {
this.__method = 'destroy';
}
else {
throw new Error('Destroying resource is not supported! Use the service instead.');
}
};
/**
* @return {?}
*/
ResourceBase.prototype.toJsonapi = /**
* @return {?}
*/
function () {
return this.__serializer.toJsonapi();
};
/**
* @return {?}
*/
ResourceBase.prototype.toHash = /**
* @return {?}
*/
function () {
return this.__serializer.toHash();
};
/**
* @return {?}
*/
ResourceBase.prototype.sideload = /**
* @return {?}
*/
function () {
/** @type {?} */
var method = this.relationMethod;
if (method === 'create' || method === 'untouched') {
return;
}
/** @type {?} */
var type = this.modelOptions.type;
return {
id: this.id,
type: type,
__method: method,
};
};
/**
* @return {?}
*/
ResourceBase.prototype.serialize = /**
* @return {?}
*/
function () {
return this.__serializer.serialize();
};
/**
* @private
* @param {?} obj
* @return {?}
*/
ResourceBase.prototype.translateKeys = /**
* @private
* @param {?} obj
* @return {?}
*/
function (obj) {
if (obj.toHash) {
obj = obj.toHash();
}
/** @type {?} */
var filtred = {};
for (var oldkey in obj) {
if (obj.hasOwnProperty(oldkey)) {
/** @type {?} */
var newkey = this.__wrapper.frontendPropName(oldkey.toString());
if (newkey) {
filtred[newkey] = obj[oldkey];
}
}
}
return filtred;
};
return ResourceBase;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?=} options
* @return {?}
*/
function BelongsTo(options) {
if (options === void 0) { options = {}; }
return (/**
* @param {?} target
* @param {?} propertyName
* @return {?}
*/
function (target, propertyName) {
/** @type {?} */
var setupMetadata = (/**
* @return {?}
*/
function () {
/** @type {?} */
var belongsTos = Reflect.getMetadata(BelongsToMetadata, target) || [];
belongsTos.push({
propertyName: propertyName,
backendName: options.backendName || propertyName,
readonly: !!options.readonly,
sidepostable: !!options.sidepostable,
});
Reflect.defineMetadata(BelongsToMetadata, belongsTos, target);
});
/** @type {?} */
var getClass = (/**
* @param {?=} fromVal
* @return {?}
*/
function (fromVal) {
// const klass = options.class();
if (!Array.isArray(options.class)) {
return TypesStore.find(options.class);
}
/** @type {?} */
var klasses = options.class.map((/**
* @param {?} klass
* @return {?}
*/
function (klass) { return TypesStore.find(klass); }));
if (!fromVal) {
return klasses[0];
}
/** @type {?} */
var type = fromVal.type;
if (!type) {
throw new Error('Object should be a subclass of ResourceBase or should have a type attribute!');
}
/** @type {?} */
var prop = klasses.find((/**
* @param {?} k
* @return {?}
*/
function (k) {
/** @type {?} */
var obj = new k();
return obj.type === type;
}));
if (!prop) {
throw new Error('Object should be a subclass of ResourceBase or should have a type attribute!');
}
return prop;
});
/** @type {?} */
var updateSideload = (/**
* @param {?} propClass
* @param {?} oldValue
* @param {?} newValue
* @return {?}
*/
function (propClass, oldValue, newValue) {
/** @type {?} */
var noOldId = !(oldValue && oldValue.id);
/** @type {?} */
var noNewId = !(newValue && newValue.id);
/** @type {?} */
var noIds = noOldId && noNewId;
/** @type {?} */
var eqIds = noOldId || noNewId ? false : oldValue.id === newValue.id;
// no ids: can't create a resource. This is a sideload!
if (noIds) {
return null;
}
// new don't exist: disassociate old from the resource
if (noNewId || newValue.deleteRelation) {
oldValue.disassociate();
return oldValue;
}
// same ids: can't update a resource. This is a sideload!
if (eqIds) {
/** @type {?} */
var type1 = oldValue.type;
/** @type {?} */
var type2 = newValue.type;
if (!type2 || type1 === type2) {
return oldValue;
}
}
// no old or different IDs: create new relationship