@pebula/metap
Version:
meta-programming tools
1,289 lines (1,251 loc) • 58 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pebula/metap/internal'), require('@pebula/utils')) :
typeof define === 'function' && define.amd ? define('@pebula/metap', ['exports', '@pebula/metap/internal', '@pebula/utils'], factory) :
(global = global || self, factory((global.pebula = global.pebula || {}, global.pebula.metap = {}), global.pebula.metap.internal, global.pebula.utils));
}(this, function (exports, internal, utils) { 'use strict';
/*! *****************************************************************************
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.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
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 __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
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;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result.default = mod;
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
We need to do some funky stuff for angular compiler...
If we wont, the output d.ts files will be messed up
For example:
export const Prop = MetaClass.decorator(PropMetadata, true);
WILL BECOME IN "d.ts"
export declare const Prop: (def?: import("../../../../../dist/@pebula/metap/internal/pebula-metap-internal").PropMetadataArgs) => (target: any, propertyKey?: string | number | symbol, descOrIndex?: number | PropertyDescriptor) => any;
This will happen because ngc doesn't know how properly get the symbol declaration so it fallbacks to the import style....
*/
/**
* \@propertyDecorator instance
* \@param def
* @type {?}
*/
var Prop = internal.MetaClass.decorator(internal.PropMetadata, true);
/**
* \@propertyDecorator instance
* \@param def
* @type {?}
*/
var Exclude = internal.MetaClass.decorator(internal.ExcludeMetadata, true);
/**
* \@propertyDecorator instance
* \@param def
* @type {?}
*/
var Relation = internal.MetaClass.decorator(internal.RelationMetadata, true);
/**
* \@propertyDecorator instance
* \@param def
* @type {?}
*/
var Type = internal.MetaClass.decorator(internal.TypeMetadata);
/**
* \@propertyDecorator instance
* @return {?}
*/
function Identity() {
return (/**
* @param {?} target
* @param {?} key
* @return {?}
*/
function (target, key) {
internal.targetStore.getTargetMeta((/** @type {?} */ (target.constructor))).model().identity = key;
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* \@propertyDecorator static
* @param {?=} metaArgs
* @return {?}
*/
function Model(metaArgs) {
return (/**
* @param {?} target
* @return {?}
*/
function (target) {
/** @type {?} */
var metaClass = internal.MetaClass.create(internal.ModelMetadata, metaArgs, target);
processModel(target, metaClass, metaClass.skip !== true);
});
}
/**
* Takes a model and process it.
* The first step is to extend the target, if it inherits.
* The second step is calling the build() method on the metadata class which will
* start the event life-cycle.
* @param {?} target
* @param {?} metaClass
* @param {?=} build
* @return {?}
*/
function processModel(target, metaClass, build) {
var e_1, _a;
try {
for (var _b = __values(utils.getProtoChain(target)), _c = _b.next(); !_c.done; _c = _b.next()) {
var proto = _c.value;
if (target !== proto && internal.targetStore.hasTarget(proto)) {
internal.targetStore.extend(proto, target);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
if (build) {
metaClass.build();
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @record
*/
function CompiledTransformation() { }
if (false) {
/**
* Excluded members that doesn't have a \@Prop decorator.
* All \@Exclude instructions on members with \@Prop instructions are add to the PoClassPropertyMap
* @type {?}
*/
CompiledTransformation.prototype.excluded;
/** @type {?} */
CompiledTransformation.prototype.instructions;
}
/**
* @param {?} value
* @param {?} prop
* @return {?}
*/
function transformValueOut(value, prop) {
if (prop && prop.transform && prop.transform.outgoing) {
return prop.transform.outgoing(value);
}
return value;
}
/**
* @param {?} value
* @param {?} prop
* @return {?}
*/
function transformValueIn(value, prop) {
if (prop && prop.transform && prop.transform.incoming) {
return prop.transform.incoming(value);
}
return value;
}
/**
* @param {?} e
* @return {?}
*/
function excludedPredicate(e) {
return e.name === this;
}
var InclusivePropertyContainer = /** @class */ (function () {
function InclusivePropertyContainer(target, compiled, predicate, renamer) {
this.target = target;
this.compiled = compiled;
this.predicate = predicate;
this.renamer = renamer;
}
/**
* @param {?} keys
* @param {?} cb
* @return {?}
*/
InclusivePropertyContainer.prototype.forEach = /**
* @param {?} keys
* @param {?} cb
* @return {?}
*/
function (keys, cb) {
/** @type {?} */
var len = keys.length;
/** @type {?} */
var instructions = this.compiled.instructions.slice();
/** @type {?} */
var excluded = this.compiled.excluded.slice();
for (var i = 0; i < len; i++) {
/** @type {?} */
var prop = internal.array.findRemove(instructions, this.predicate, keys[i]) || {
cls: keys[i],
obj: keys[i],
exclude: internal.array.findRemove(excluded, excludedPredicate, keys[i])
};
if (!prop.exclude) {
// we only transform names for ad-hoc properties. registered @Prop's are transformed
// when the prop is compiled.
if (!prop.prop && this.renamer) {
this.renamer(prop);
}
cb(prop);
}
}
};
/**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param keys
* @param cb
*/
/**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param {?} keys
* @param {?} cb
* @return {?}
*/
InclusivePropertyContainer.prototype.forEachRaw = /**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param {?} keys
* @param {?} cb
* @return {?}
*/
function (keys, cb) {
/** @type {?} */
var len = keys.length;
/** @type {?} */
var instructions = this.compiled.instructions.slice();
/** @type {?} */
var excluded = this.compiled.excluded.slice();
for (var i = 0; i < len; i++) {
/** @type {?} */
var prop = internal.array.findRemove(instructions, this.predicate, keys[i]) || {
cls: keys[i],
obj: keys[i],
exclude: internal.array.findRemove(excluded, excludedPredicate, keys[i])
};
// we only transform names for ad-hoc properties. registered @Prop's are transformed
// when the prop is compiled.
if (!prop.prop && this.renamer) {
this.renamer(prop);
}
cb(prop);
}
len = instructions.length;
for (var i = 0; i < len; i++) {
/** @type {?} */
var prop = instructions[i];
// we only transform names for ad-hoc properties. registered @Prop's are transformed
// when the prop is compiled.
if (!prop.prop && this.renamer) {
this.renamer(prop);
}
cb(prop);
}
};
return InclusivePropertyContainer;
}());
if (false) {
/** @type {?} */
InclusivePropertyContainer.prototype.target;
/**
* @type {?}
* @private
*/
InclusivePropertyContainer.prototype.compiled;
/**
* @type {?}
* @private
*/
InclusivePropertyContainer.prototype.predicate;
/**
* @type {?}
* @private
*/
InclusivePropertyContainer.prototype.renamer;
}
var ExclusivePropertyContainer = /** @class */ (function () {
function ExclusivePropertyContainer(target, compiled) {
this.target = target;
this.compiled = compiled;
}
/**
* @param {?} keys
* @param {?} cb
* @return {?}
*/
ExclusivePropertyContainer.prototype.forEach = /**
* @param {?} keys
* @param {?} cb
* @return {?}
*/
function (keys, cb) {
/** @type {?} */
var instructions = this.compiled.instructions;
// No need to apply transformNameStrategy, it is cached in the instructions.
for (var i = 0, len = instructions.length; i < len; i++) {
!instructions[i].exclude && cb(instructions[i]);
}
};
/**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param keys
* @param cb
*/
/**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param {?} keys
* @param {?} cb
* @return {?}
*/
ExclusivePropertyContainer.prototype.forEachRaw = /**
* A forEach loop on all instructions including excluded instructions and properties not in "keys" but in metadata.
* It is recommended to use "forEach" unless the mapper implementation has different transformation strategies.
* @param {?} keys
* @param {?} cb
* @return {?}
*/
function (keys, cb) {
/** @type {?} */
var instructions = this.compiled.instructions;
for (var i = 0, len = instructions.length; i < len; i++) {
cb(instructions[i]);
}
};
return ExclusivePropertyContainer;
}());
if (false) {
/** @type {?} */
ExclusivePropertyContainer.prototype.target;
/**
* @type {?}
* @private
*/
ExclusivePropertyContainer.prototype.compiled;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var TransformationError = /** @class */ (function (_super) {
__extends(TransformationError, _super);
function TransformationError(message) {
return _super.call(this, message) || this;
}
/**
* @param {?} expectedCol
* @return {?}
*/
TransformationError.coll_obj = /**
* @param {?} expectedCol
* @return {?}
*/
function (expectedCol) {
return new TransformationError(expectedCol
? "Expected a collection but got an object"
: "Expected an object but got a collection");
};
return TransformationError;
}(Error));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Returns an array of 2 property names, first is the name of the transformed output
* second is the name of the property name to transform.
* Used for applying NamingStrategyConfig based on the TransformDir
* @param {?} dir
* @param {?} transformNameStrategy
* @return {?}
*/
function namingStrategyMap(dir, transformNameStrategy) {
return transformNameStrategy && utils.isFunction(transformNameStrategy[dir]);
}
/**
* \@internal
* @template T, Z
* @param {?} meta
* @param {?} dir
* @return {?}
*/
function getInstructions(meta, dir) {
// all excluded instructions for this type
// this array will be filtered to hold only @Exclude without @Prop
/** @type {?} */
var excluded = meta
.getValues(internal.ExcludeMetadata)
.filter((/**
* @param {?} e
* @return {?}
*/
function (e) { return !e.from || e.from === dir; }));
/** @type {?} */
var model = meta.model();
// in exclusive mode there is no point in have 2 transformation strategies.
// incoming is never there since incoming keys are not calculated, only defined Props.
if (model.transformStrategy === 'exclusive') {
dir = 'outgoing';
}
// only apply naming strategy on outgoing, incoming has no effect here
/** @type {?} */
var naming = namingStrategyMap(dir, model.transformNameStrategy);
/** @type {?} */
var fkMap = new Map();
// TODO: move to for loop
/** @type {?} */
var instructions = meta.getValues(internal.PropMetadata).map((/**
* @param {?} prop
* @return {?}
*/
function (prop) {
/** @type {?} */
var obj = {
cls: prop.name,
obj: prop.alias[dir],
exclude: internal.array.findRemove(excluded, (/**
* @param {?} e
* @return {?}
*/
function (e) { return e.name === prop.name; })),
prop: prop
};
// apply naming strategy when DONT HAVE ALIAS!
if (!obj.exclude && naming && obj.cls === obj.obj) {
obj.obj = model.transformNameStrategy[dir](obj.cls);
}
// store the PoClassPropertyMap of a belongsTo PropMetadata relation
// and the PoClassPropertyMap of all foreign key PropMetadata.
// These arr actually matching pairs of a belongTo relation and it's fk
// (not all belongsTo has fk, only different property name is a fk)
//
// At the end, go through the stored PropMetadata and see if matching pairs found (2 values in array)
// for all of them, swap the prop names so:
// belongsTo PoClassPropertyMap will output (deserialize) to the original fk property name
// foreignKey PoClassPropertyMap wil input (serialize) to the belongsTo property name
// this swap make the deserialize/serialize process transparent to fk mismatch defined on the model.
// De/Serialize implementations are only responsible to return the right object
// (e.g. detect when a key is incoming, return obj instead)
if (prop.relation) {
/** @type {?} */
var arr = fkMap.get(prop) || [];
arr[0] = obj;
fkMap.set(prop, arr);
}
else if (prop.foreignKeyOf) {
/** @type {?} */
var arr = fkMap.get(prop.foreignKeyOf) || [];
arr[1] = obj;
fkMap.set(prop.foreignKeyOf, arr);
}
return obj;
}));
Array.from(fkMap.entries()).forEach((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var _b = __read(_a, 2), k = _b[0], v = _b[1];
if (v.length === 2) {
// this is a swap
v[0].obj = (/** @type {?} */ (v[1].cls));
v[1].cls = (/** @type {?} */ (k.name)); // v[0].cls === k.name
}
}));
return { excluded: excluded, instructions: instructions };
}
/**
* @param {?} p
* @return {?}
*/
function serializePredicate(p) {
return p.cls === this;
}
/**
* @param {?} p
* @return {?}
*/
function deserializePredicate(p) {
return p.obj === this;
}
var ɵ0 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var idKey = this.meta.getIdentityKey();
if (idKey) {
return (this.hasOwnProperty('incoming')
? this.incoming
: this.outgoing).instructions.find((/**
* @param {?} p
* @return {?}
*/
function (p) { return p.prop.name === idKey; }));
}
}, ɵ1 = /**
* @this {?}
* @return {?}
*/
function () {
return getInstructions(this.meta, 'incoming');
}, ɵ2 = /**
* @this {?}
* @return {?}
*/
function () {
return getInstructions(this.meta, 'outgoing');
}, ɵ3 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var model = this.meta.model();
if (model.transformStrategy === 'exclusive') {
return new ExclusivePropertyContainer(this.meta.target, this.incoming);
}
else {
/** @type {?} */
var rename = namingStrategyMap('incoming', model.transformNameStrategy)
? (/**
* @param {?} prop
* @return {?}
*/
function (prop) { return (prop.cls = model.transformNameStrategy.incoming(prop.obj)); })
: undefined;
return new InclusivePropertyContainer(this.meta.target, this.incoming, deserializePredicate, rename);
}
}, ɵ4 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var model = this.meta.model();
if (model.transformStrategy === 'exclusive') {
return new ExclusivePropertyContainer(this.meta.target, this.outgoing);
}
else {
/** @type {?} */
var rename = namingStrategyMap('outgoing', model.transformNameStrategy)
? (/**
* @param {?} prop
* @return {?}
*/
function (prop) { return (prop.obj = model.transformNameStrategy.outgoing(prop.cls)); })
: undefined;
return new InclusivePropertyContainer(this.meta.target, this.outgoing, serializePredicate, rename);
}
};
// @dynamic
/**
* A TargetSerializationContext is the running context of a mapper for a specific target class that
* can serialize and deserialize instances of the target class.
* It will run the mapper, provide input and parse results
* @template T, Z
*/
var TargetSerializationContext = /** @class */ (function () {
function TargetSerializationContext(meta) {
this.meta = meta;
}
/**
* @param {?} mapper
* @return {?}
*/
TargetSerializationContext.prototype.serialize = /**
* @param {?} mapper
* @return {?}
*/
function (mapper) {
return mapper.serialize(this.outgoingContainer);
};
/**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param mapper
* @param target
*/
/**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param {?} mapper
* @param {?} target
* @return {?}
*/
TargetSerializationContext.prototype.deserialize = /**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param {?} mapper
* @param {?} target
* @return {?}
*/
function (mapper, target) {
/** @type {?} */
var cb = (/**
* @param {?} prop
* @return {?}
*/
function (prop) {
/** @type {?} */
var propMeta = (prop.prop && prop.prop.foreignKeyOf) || prop.prop;
target[prop.cls] = transformValueIn(mapper.getValue(prop.obj, propMeta), propMeta);
});
if (utils.isFunction(mapper.setRef)) {
mapper.setRef(target);
}
if (mapper.raw === true) {
this.incomingContainer.forEachRaw(mapper.getKeys(), cb);
}
else {
this.incomingContainer.forEach(mapper.getKeys(), cb);
}
if (utils.isFunction(mapper.getIdentity)) {
if (this.identity) {
/** @type {?} */
var ident = transformValueIn(mapper.getIdentity(), this.identity.prop);
if (ident) {
target[this.identity.cls] = ident;
}
}
}
};
__decorate([
internal.LazyInit((ɵ0)),
__metadata("design:type", Object)
], TargetSerializationContext.prototype, "identity", void 0);
__decorate([
internal.LazyInit((ɵ1)),
__metadata("design:type", Object)
], TargetSerializationContext.prototype, "incoming", void 0);
__decorate([
internal.LazyInit((ɵ2)),
__metadata("design:type", Object)
], TargetSerializationContext.prototype, "outgoing", void 0);
__decorate([
internal.LazyInit((ɵ3)),
__metadata("design:type", Object)
], TargetSerializationContext.prototype, "incomingContainer", void 0);
__decorate([
internal.LazyInit((ɵ4)),
__metadata("design:type", Object)
], TargetSerializationContext.prototype, "outgoingContainer", void 0);
return TargetSerializationContext;
}());
if (false) {
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.identity;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.incoming;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.outgoing;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.incomingContainer;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.outgoingContainer;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.meta;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var targetSerializationContextStore = new Map();
/**
* @param {?} targetMeta
* @return {?}
*/
function getTargetSerializationContext(targetMeta) {
/** @type {?} */
var ctx = targetSerializationContextStore.get(targetMeta);
if (!ctx) {
ctx = new TargetSerializationContext(targetMeta);
targetSerializationContextStore.set(targetMeta, ctx);
}
return ctx;
}
/**
* @template TMeta
* @param {?} targetMeta
* @param {?} mapper
* @return {?}
*/
function serializeTargetMeta(targetMeta, mapper) {
return getTargetSerializationContext(targetMeta).serialize(mapper);
}
/**
* @template TMeta
* @param {?} targetMeta
* @param {?} mapper
* @param {?} target
* @param {?=} plain
* @return {?}
*/
function deserializeTargetMeta(targetMeta, mapper, target, plain) {
if (plain === void 0) { plain = false; }
if (mapper.isCollection) {
if (!Array.isArray(target)) {
throw TransformationError.coll_obj(true);
}
/** @type {?} */
var refItems = target.splice(0, target.length);
/** @type {?} */
var identKey_1 = internal.targetStore.getIdentityKey(targetMeta.target, 'incoming');
var _loop_1 = function () {
/** @type {?} */
var t = void 0;
// compare current item to map with a list of items that if we, if we got.
// if match use that instance.
// TODO: Move compare to the global store, so logic can change without bugs.
if (refItems.length > 0 && utils.isFunction(mapper.getIdentity)) {
/** @type {?} */
var incomingIdent_1 = mapper.getIdentity();
t = internal.array.findRemove(refItems, (/**
* @param {?} item
* @return {?}
*/
function (item) { return item[identKey_1] === incomingIdent_1; }));
}
if (!t) {
t = plain ? {} : targetMeta.model().factory(false);
}
getTargetSerializationContext(targetMeta).deserialize(mapper, t);
target.push(t);
};
while (mapper.next()) {
_loop_1();
}
}
else {
if (Array.isArray(target)) {
throw TransformationError.coll_obj(false);
}
getTargetSerializationContext(targetMeta).deserialize(mapper, target);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var PlainObject = /** @class */ (function () {
function PlainObject() {
}
PlainObject = __decorate([
Model({ resName: 'InternalPlainObject' })
], PlainObject);
return PlainObject;
}());
/**
* @param {?} mapper
* @param {?} instanceOrTarget
* @param {?=} target
* @return {?}
*/
function serialize(mapper, instanceOrTarget, target) {
if (mapper instanceof internal.BaseSerializer) {
/** @type {?} */
var meta = internal.targetStore.getTargetMeta(instanceOrTarget);
if (meta) {
return serializeTargetMeta(meta, mapper);
}
}
else {
/** @type {?} */
var meta = internal.targetStore.getTargetMeta(target || instanceOrTarget.constructor);
if (meta) {
return serializeTargetMeta(meta, mapper.serializer(instanceOrTarget));
}
}
}
/**
* Automatically serialize an instance.
* This method will serialize an instance by first trying to locate the target using the `constructor` function.
* If a target is found and if it's a model target (i.e. ModelMetadata) it will try to get the mapper assign for that
* model.
*
* If no target, model or mapper was found it will use the fallbackMapper mapper provided, or `directMapper`
* if no fallback is provided provided.
*
* Note that when provided a fallback mapper, make sure it is able to serialize unknown targets. (plain objects)
* @param {?} instance
* @param {?=} fallbackMapper
* @return {?}
*/
function autoSerialize(instance, fallbackMapper) {
/** @type {?} */
var tMeta = internal.targetStore.getTargetMeta((/** @type {?} */ (instance.constructor)));
/** @type {?} */
var mapper = (tMeta && tMeta.hasModel && tMeta.model().mapper) || fallbackMapper || directMapper;
return serialize(mapper, instance);
}
/**
* @param {?} mapper
* @param {?=} plainObject
* @param {?=} type
* @param {?=} instance
* @return {?}
*/
function deserialize(mapper, plainObject, type, instance) {
/** @type {?} */
var deserializer;
if (mapper instanceof internal.BaseDeserializer) {
instance = plainObject;
deserializer = mapper;
}
else {
deserializer = mapper.deserializer(plainObject, type);
}
if (internal.targetStore.hasTarget(deserializer.sourceType)) {
/** @type {?} */
var meta = internal.targetStore.getTargetMeta(deserializer.sourceType);
/** @type {?} */
var result = instance || meta.model().factory(deserializer.isCollection);
deserializeTargetMeta(meta, deserializer, result);
return result;
}
else {
/** @type {?} */
var meta = internal.targetStore.getTargetMeta(PlainObject);
/** @type {?} */
var result = instance || deserializer.isCollection ? [] : {};
deserializeTargetMeta(meta, deserializer, result, true);
return result;
}
}
/**
* Automatically de-serialize an object to/into an instance.
* This method will de-serialize an object by first trying to locate a model (i.e. ModelMetadata) for the target.
* If a model is found it will try to get the mapper assign for that model.
*
* If no model or mapper was found it will use the fallbackMapper mapper provided, or `directMapper`
* if no fallback is provided provided.
*
* @template T, Z
* @param {?} plainObject
* @param {?} type
* @param {?=} instance
* @param {?=} fallbackMapper
* @return {?}
*/
function autoDeserialize(plainObject, type, instance, fallbackMapper) {
if (instance === void 0) { instance = null; }
/** @type {?} */
var tMeta = internal.targetStore.getTargetMeta(type);
/** @type {?} */
var mapper = (tMeta && tMeta.hasModel && tMeta.model().mapper) || fallbackMapper || directMapper;
return deserialize(mapper, plainObject, type, instance);
}
/**
* Performs a deep clone to the resource using serialization and deserialization, which means that all rules apply (i.e \@Exclude)
*
* @template T
* @param {?} resource the resource (instance) to clone
* @param {?=} serializationFactory Optional, The [[SerializationFactory]] to use, defaults to [[directMapper]].
* @return {?}
*/
function clone(resource, serializationFactory) {
return autoDeserialize(autoSerialize(resource, serializationFactory), (/** @type {?} */ (resource.constructor)), null, serializationFactory);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* A mapper that has no mapping effect.
* Maps every property on the source to the same property on the target.
* This mapper does not support non primitive id's
* @template T, Z
*/
var /**
* A mapper that has no mapping effect.
* Maps every property on the source to the same property on the target.
* This mapper does not support non primitive id's
* @template T, Z
*/
DirectDeserializeMapper = /** @class */ (function (_super) {
__extends(DirectDeserializeMapper, _super);
function DirectDeserializeMapper(source, sourceType, plainMapper) {
var _this = _super.call(this, source, sourceType, plainMapper) || this;
_this.idx = -1;
if (!(_this instanceof DirectChildDeserializeMapper)) {
_this.existing = new internal.DualKeyMap();
}
_this.identity = internal.targetStore.getIdentityKey(_this.sourceType, 'outgoing');
_this.isCollection = Array.isArray(source);
if (!_this.isCollection) {
_this.current = _this.source;
}
return _this;
}
/**
* @param {?} value
* @return {?}
*/
DirectDeserializeMapper.prototype.setRef = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (this.current) {
this.existing.set(this.sourceType, this.getIdentity(), value);
}
};
Object.defineProperty(DirectDeserializeMapper.prototype, "ref", {
get: /**
* @protected
* @return {?}
*/
function () {
if (this.current) {
return this.existing.get(this.sourceType, this.getIdentity());
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
DirectDeserializeMapper.prototype.getIdentity = /**
* @return {?}
*/
function () {
// TODO: Move to the global store, so logic can change without bugs.
return this.current[this.identity];
};
/**
* @return {?}
*/
DirectDeserializeMapper.prototype.next = /**
* @return {?}
*/
function () {
if (this.isCollection) {
this.current = this.source[++this.idx];
return !!this.current;
}
else {
return false;
}
};
/**
* @return {?}
*/
DirectDeserializeMapper.prototype.getKeys = /**
* @return {?}
*/
function () {
return Object.keys(this.current);
};
/**
* @param {?} key
* @param {?=} prop
* @return {?}
*/
DirectDeserializeMapper.prototype.getValue = /**
* @param {?} key
* @param {?=} prop
* @return {?}
*/
function (key, prop) {
/** @type {?} */
var value = this.current[key];
if (prop) {
// The adapter has the responsibility to manage relationships.
// It doesn't care about key matching (e.g. key in property customer_id but property is customer)
// it get's a value and the property to assign to, the adapter should check if the value it got
// was an id or an object.
// this relationship handling logic makes this whole adapter support only primitive ID properties.
// if we have primitives we treat them as id's and create an object.
// later we wil check if this value is in cache, if not create it.
// if its not a primitive, it will process as a full object included in the payload.
/** @type {?} */
var rel = this.getRelationQuery(prop, value);
if (rel) {
value = rel;
}
if (internal.targetStore.hasTarget(prop.type.ref)) {
return (this.getCache(prop.type.ref, value) || this.deserialize(value, prop));
}
}
return typeof value === 'object'
? this.plainMapper.deserialize(value)
: value;
};
/**
* @protected
* @param {?} value
* @param {?} prop
* @return {?}
*/
DirectDeserializeMapper.prototype.deserialize = /**
* @protected
* @param {?} value
* @param {?} prop
* @return {?}
*/
function (value, prop) {
/** @type {?} */
var deserializer = this.ref
? new DirectChildDeserializeMapper(value, prop.type.ref, this.existing, this.plainMapper)
: directMapper.deserializer(value, prop.type.ref, this.plainMapper);
return deserialize(deserializer);
};
/**
* Returns a relationship object with the identity property set.
* This object can then be used by the cache to identify if a value is cached or not (using the type & identity comb)
*/
/**
* Returns a relationship object with the identity property set.
* This object can then be used by the cache to identify if a value is cached or not (using the type & identity comb)
* @protected
* @param {?} prop
* @param {?} value
* @return {?}
*/
DirectDeserializeMapper.prototype.getRelationQuery = /**
* Returns a relationship object with the identity property set.
* This object can then be used by the cache to identify if a value is cached or not (using the type & identity comb)
* @protected
* @param {?} prop
* @param {?} value
* @return {?}
*/
function (prop, value) {
var _a;
if (prop.relation && utils.isPrimitive(value)) {
return _a = {},
_a[internal.targetStore.getIdentityKey((/** @type {?} */ (prop.type.ref)), 'outgoing')] = value,
_a;
}
};
/**
* @protected
* @param {?} type
* @param {?} value
* @return {?}
*/
DirectDeserializeMapper.prototype.getCache = /**
* @protected
* @param {?} type
* @param {?} value
* @return {?}
*/
function (type, value) {
/** @type {?} */
var idKey = internal.targetStore.getIdentityKey(type, 'outgoing');
/** @type {?} */
var idVal = idKey && value[idKey];
if (idVal) {
return this.existing.get(type, idVal);
}
};
return DirectDeserializeMapper;
}(internal.BaseDeserializer));
if (false) {