Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

serializr

Package Overview
Dependencies
Maintainers
2
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serializr - npm Package Compare versions

Comparing version 1.3.0 to 1.4.1

14

CHANGELOG.md

@@ -0,5 +1,15 @@

# 1.4.0
* Introduced beforeDeserialize and afterDeserialize lifecycle methods to support e.g. better error handling during deserialization by @evoye
* Introduced cancelDeserialize to stop async requests that get stuck, e.g. in case of unresolved waiting references by @evoye
* Added capability to deserialize arrays with empty entries by @evoye
* Fixed mapAsArray to always push elements to the serialized array by @evoye
# 1.3.0
* Introduced async ability into `custom` (de)serializer, to support asynchronous custom deserialization by @evoye
* Fixed missed typescript export of `raw` type by @VChastinet
* Documentation updates by @maslade and @razetdinov
# 1.2.1
* Introduced `raw` type, to allow for complex dynamic types to be deserialized
* Introduced `customAsync`, to support asynchronous custom deserialization
# 1.1.12

@@ -6,0 +16,0 @@

499

lib/es/serializr.js

@@ -33,3 +33,3 @@ /**

var fired = false;
return function() {
return function () {
if (!fired) {

@@ -49,9 +49,9 @@ fired = true;

function parallel(ar, processor, cb) {
// TODO: limit parallelization?
// TODO: limit parallelization?
if (ar.length === 0)
return void cb(null, [])
var left = ar.length;
var left = ar.filter(function(){ return true }).length; // only count items processed by forEach
var resultArray = [];
var failed = false;
var processorCb = function(idx, err, result) {
var processorCb = function (idx, err, result) {
if (err) {

@@ -69,3 +69,3 @@ if (!failed) {

ar.forEach(function (value, idx) {
processor(value, processorCb.bind(null, idx));
processor(value, processorCb.bind(null, idx), idx);
});

@@ -93,3 +93,3 @@ }

function isIdentifierPropSchema(propSchema) {
return typeof propSchema === "object" && propSchema.identifier === true
return typeof propSchema === "object" && propSchema.identifier === true
}

@@ -122,2 +122,15 @@

function processAdditionalPropArgs(propSchema, additionalArgs) {
if (additionalArgs) {
invariant(isPropSchema(propSchema), "expected a propSchema");
var argNames = ["beforeDeserialize", "afterDeserialize"];
argNames.forEach(function(argName) {
if (typeof additionalArgs[argName] === "function") {
propSchema[argName] = additionalArgs[argName];
}
});
}
return propSchema
}
/**

@@ -212,6 +225,7 @@ * Returns the standard model schema associated with a class / constructor function

*
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {ModelSchema}
*/
function primitive() {
return {
function primitive(additionalArgs) {
var result = {
serializer: function (value) {

@@ -226,3 +240,5 @@ invariant(isPrimitive(value), "this value is not primitive: " + value);

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -444,2 +460,4 @@

var rootContextCache = new Map();
function Context(parentContext, modelSchema, json, onReadyCb, customArgs) {

@@ -452,3 +470,3 @@ this.parentContext = parentContext;

this.json = json;
this.target = null;
this.target = null; // always set this property using setTarget
this.hasError = false;

@@ -470,3 +488,3 @@ this.modelSchema = modelSchema;

// once: defend against user-land calling 'done' twice
return once(function(err, value) {
return once(function (err, value) {
if (err) {

@@ -476,2 +494,3 @@ if (!this.hasError) {

this.onReadyCb(err);
rootContextCache.delete(this);
}

@@ -481,13 +500,16 @@ } else if (!this.hasError) {

if (--this.pendingCallbacks === this.pendingRefsCount) {
if (this.pendingRefsCount > 0)
// all pending callbacks are pending reference resolvers. not good.
if (this.pendingRefsCount > 0) {
// all pending callbacks are pending reference resolvers. not good.
this.onReadyCb(new Error(
"Unresolvable references in json: \"" +
Object.keys(this.pendingRefs).filter(function (uuid) {
return this.pendingRefs[uuid].length > 0
}, this).join("\", \"") +
"\""
));
else
this.onReadyCb(null, this.target);
"Unresolvable references in json: \"" +
Object.keys(this.pendingRefs).filter(function (uuid) {
return this.pendingRefs[uuid].length > 0
}, this).join("\", \"") +
"\""
));
rootContextCache.delete(this);
} else {
this.onReadyCb(null, this.target);
rootContextCache.delete(this);
}
}

@@ -520,3 +542,3 @@ }

// given a model schema, uuid and value, resolve all references that where looking for this object
Context.prototype.resolve = function(modelSchema, uuid, value) {
Context.prototype.resolve = function (modelSchema, uuid, value) {
invariant(this.isRoot);

@@ -540,5 +562,47 @@ if (!this.resolvedRefs[uuid])

// set target and update root context cache
Context.prototype.setTarget = function (target) {
if (this.isRoot && this.target) {
rootContextCache.delete(this.target);
}
this.target = target;
rootContextCache.set(this.target, this);
};
// call all remaining reference lookup callbacks indicating an error during ref resolution
Context.prototype.cancelAwaits = function () {
invariant(this.isRoot);
var self = this;
Object.keys(this.pendingRefs).forEach(function (uuid) {
self.pendingRefs[uuid].forEach(function (refOpts) {
self.pendingRefsCount--;
refOpts.callback(new Error("Reference resolution canceled for " + uuid));
});
});
this.pendingRefs = {};
this.pendingRefsCount = 0;
};
function getTargetContext(target) {
return rootContextCache.get(target)
}
/*
* Deserialization
*/
/**
* Cancels an asynchronous deserialization or update operation for the specified target object.
* @param instance object that was previously returned from deserialize or update method
*/
function cancelDeserialize(instance) {
invariant(typeof instance === "object" && instance && !Array.isArray(instance), "cancelDeserialize needs an object");
var context = getTargetContext(instance);
if (context) {
context.cancelAwaits();
}
}
/*
* Deserialization
*/
function schemaHasAlias(schema, name) {

@@ -554,4 +618,7 @@ for (var key in schema.props)

var value = json[key];
// when deserializing we don't want to silently ignore 'unparseable data' to avoid confusing bugs
invariant(isPrimitive(value), "encountered non primitive value while deserializing '*' properties in property '" + key + "': " + value);
// when deserializing we don't want to silently ignore 'unparseable data' to avoid
// confusing bugs
invariant(isPrimitive(value),
"encountered non primitive value while deserializing '*' properties in property '" +
key + "': " + value);
obj[key] = value;

@@ -562,3 +629,4 @@ }

/**
* Deserializes a json structor into an object graph.
* Deserializes a json structure into an object graph.
*
* This process might be asynchronous (for example if there are references with an asynchronous

@@ -570,5 +638,8 @@ * lookup function). The function returns an object (or array of objects), but the returned object

* @param {json} json data to deserialize
* @param {function} callback node style callback that is invoked once the deserializaiton has finished.
* First argument is the optional error, second argument is the deserialized object (same as the return value)
* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
* @param {function} callback node style callback that is invoked once the deserialization has
* finished. First argument is the optional error, second argument is the deserialized object
* (same as the return value)
* @param {*} customArgs custom arguments that are available as `context.args` during the
* deserialization process. This can be used as dependency injection mechanism to pass in, for
* example, stores.
* @returns {object|array} deserialized object, possibly incomplete.

@@ -593,16 +664,18 @@ */

} else
return deserializeObjectWithSchema(null, schema, json, callback, customArgs)
return deserializeObjectWithSchema(null, schema, json, callback, customArgs)
}
function deserializeObjectWithSchema(parentContext, schema, json, callback, customArgs) {
if (json === null || json === undefined)
function deserializeObjectWithSchema(parentContext, modelSchema, json, callback, customArgs) {
if (json === null || json === undefined || typeof json !== "object")
return void callback(null, null)
var context = new Context(parentContext, schema, json, callback, customArgs);
var target = schema.factory(context);
var context = new Context(parentContext, modelSchema, json, callback, customArgs);
var target = modelSchema.factory(context);
// todo async invariant
invariant(!!target, "No object returned from factory");
// TODO: make invariant? invariant(schema.extends || !target.constructor.prototype.constructor.serializeInfo, "object has a serializable supertype, but modelschema did not provide extends clause")
context.target = target;
// TODO: make invariant? invariant(schema.extends ||
// !target.constructor.prototype.constructor.serializeInfo, "object has a serializable
// supertype, but modelschema did not provide extends clause")
context.setTarget(target);
var lock = context.createCallback(GUARDED_NOOP);
deserializePropsWithSchema(context, schema, json, target);
deserializePropsWithSchema(context, modelSchema, json, target);
lock();

@@ -612,10 +685,59 @@ return target

function deserializePropsWithSchema(context, schema, json, target) {
if (schema.extends)
deserializePropsWithSchema(context, schema.extends, json, target);
Object.keys(schema.props).forEach(function (propName) {
var propDef = schema.props[propName];
function deserializePropsWithSchema(context, modelSchema, json, target) {
if (modelSchema.extends)
deserializePropsWithSchema(context, modelSchema.extends, json, target);
function deserializeProp(propDef, jsonValue, propName) {
function setValue(value) {
if (value !== SKIP) {
target[propName] = value;
}
}
function preProcess(resultCallback) {
return function (err, newValue) {
function finalCallback(errPreliminary, finalOrRetryValue) {
if (errPreliminary && finalOrRetryValue !== undefined &&
typeof propDef.afterDeserialize === "function") {
propDef.deserializer(
finalOrRetryValue,
preProcess(resultCallback),
context,
target[propName]
);
} else {
resultCallback(errPreliminary, finalOrRetryValue);
}
}
onAfterDeserialize(finalCallback, err, newValue, jsonValue, json,
propName, context, propDef);
}
}
propDef.deserializer(
jsonValue,
// for individual props, use root context based callbacks
// this allows props to complete after completing the object itself
// enabling reference resolving and such
preProcess(context.rootContext.createCallback(setValue)),
context,
target[propName] // initial value
);
}
Object.keys(modelSchema.props).forEach(function (propName) {
var propDef = modelSchema.props[propName];
function callbackDeserialize(err, jsonValue) {
if (!err && jsonValue !== undefined) {
deserializeProp(propDef, jsonValue, propName);
}
}
if (propName === "*") {
invariant(propDef === true, "prop schema '*' can onle be used with 'true'");
deserializeStarProps(schema, target, json);
invariant(propDef === true, "prop schema '*' can only be used with 'true'");
deserializeStarProps(modelSchema, target, json);
return

@@ -628,20 +750,30 @@ }

var jsonAttr = propDef.jsonname || propName;
if (!(jsonAttr in json))
return
propDef.deserializer(
json[jsonAttr],
// for individual props, use root context based callbacks
// this allows props to complete after completing the object itself
// enabling reference resolving and such
context.rootContext.createCallback(function (value) {
if (value !== SKIP){
target[propName] = value;
}
}),
context,
target[propName] // initial value
);
var jsonValue = json[jsonAttr];
onBeforeDeserialize(callbackDeserialize, jsonValue, json, jsonAttr, context, propDef);
});
}
function onBeforeDeserialize(
callback, jsonValue, jsonParentValue, propNameOrIndex, context, propDef) {
if (propDef && typeof propDef.beforeDeserialize === "function") {
propDef.beforeDeserialize(callback, jsonValue, jsonParentValue, propNameOrIndex, context,
propDef);
} else {
callback(null, jsonValue);
}
}
function onAfterDeserialize(
callback, err, newValue, jsonValue, jsonParentValue, propNameOrIndex, context, propDef) {
if (propDef && typeof propDef.afterDeserialize === "function") {
propDef.afterDeserialize(callback, err, newValue, jsonValue, jsonParentValue,
propNameOrIndex, context, propDef);
} else {
callback(err, newValue);
}
}
/*

@@ -661,2 +793,3 @@ * Update

* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
* @returns {object|array} deserialized object, possibly incomplete.
*/

@@ -680,6 +813,7 @@ function update(modelSchema, target, json, callback, customArgs) {

var context = new Context(null, modelSchema, json, callback, customArgs);
context.target = target;
context.setTarget(target);
var lock = context.createCallback(GUARDED_NOOP);
deserializePropsWithSchema(context, modelSchema, json, target);
var result = deserializePropsWithSchema(context, modelSchema, json, target);
lock();
return result
}

@@ -704,3 +838,3 @@

* var todos = {};
*
*
* var s = _.createSimpleSchema({

@@ -710,3 +844,3 @@ * id: _.identifier((id, object) => (todos[id] = object)),

* });
*
*
* _.deserialize(s, {

@@ -717,3 +851,3 @@ * id: 1,

* _.deserialize(s, [{ id: 2, title: 'test2' }, { id: 1, title: 'test1' }]);
*
*
* t.deepEqual(todos, {

@@ -724,9 +858,17 @@ * 1: { id: 1, title: 'test1' },

*
* @param {RegisterFunction} registerFn optional function to register this object during creation.
* @param { RegisterFunction | AdditionalPropArgs } arg1 optional registerFn: function to register this object during creation.
* @param {AdditionalPropArgs} arg2 optional object that contains beforeDeserialize and/or afterDeserialize handlers
*
* @returns {PropSchema}
*/
function identifier(registerFn) {
invariant(!registerFn || typeof registerFn === "function", "First argument should be omitted or function");
return {
function identifier(arg1, arg2) {
var registerFn, additionalArgs;
if (typeof arg1 === "function") {
registerFn = arg1;
additionalArgs = arg2;
} else {
additionalArgs = arg1;
}
invariant(!additionalArgs || typeof additionalArgs === "object", "Additional property arguments should be an object, register function should be omitted or a funtion");
var result = {
identifier: true,

@@ -742,3 +884,5 @@ serializer: _defaultPrimitiveProp.serializer,

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -749,7 +893,8 @@

*
* @returns
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function date() {
function date(additionalArgs) {
// TODO: add format option?
return {
var result = {
serializer: function(value) {

@@ -766,3 +911,5 @@ if (value === null || value === undefined)

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -795,3 +942,5 @@

deserializer: propSchema.deserializer,
identifier: isIdentifierPropSchema(propSchema)
identifier: isIdentifierPropSchema(propSchema),
beforeDeserialize: propSchema.beforeDeserialize,
afterDeserialize: propSchema.afterDeserialize
}

@@ -854,17 +1003,20 @@ }

* @param {function} deserializer function that takes a json value and turns it into a model value. It also takes context argument, which can allow you to deserialize based on the context of other parameters.
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function custom(serializer, deserializer) {
function custom(serializer, deserializer, additionalArgs) {
invariant(typeof serializer === "function", "first argument should be function");
invariant((typeof deserializer === "function"), "second argument should be a function or promise");
return {
var result = {
serializer: serializer,
deserializer: function (jsonValue, done, context, oldValue) {
if (deserializer.length === 4) {
deserializer(jsonValue, context, oldValue, done);
deserializer(jsonValue, context, oldValue, done, additionalArgs);
} else {
done(null, deserializer(jsonValue, context, oldValue));
done(null, deserializer(jsonValue, context, oldValue, null, additionalArgs));
}
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -898,7 +1050,8 @@

* @param {ModelSchema} modelSchema to be used to (de)serialize the object
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function object(modelSchema) {
function object(modelSchema, additionalArgs) {
invariant(typeof modelSchema === "object" || typeof modelSchema === "function", "No modelschema provided. If you are importing it from another file be aware of circular dependencies.");
return {
var result = {
serializer: function (item) {

@@ -916,5 +1069,7 @@ modelSchema = getDefaultModelSchema(modelSchema);

return void done(null, childJson)
return void deserializeObjectWithSchema(context, modelSchema, childJson, done)
return void deserializeObjectWithSchema(context, modelSchema, childJson, done, additionalArgs)
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -980,13 +1135,18 @@

* @param target: ModelSchema or string
* @param {RefLookupFunction} lookupFn function
* @param {RefLookupFunction | AdditionalPropArgs} lookupFn optional function or additionalArgs object
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function reference(target, lookupFn) {
function reference(target, lookupFn, additionalArgs) {
invariant(!!target, "No modelschema provided. If you are importing it from another file be aware of circular dependencies.");
var initialized = false;
var childIdentifierAttribute;
if (typeof lookupFn === "object" && additionalArgs === undefined) {
additionalArgs = lookupFn;
lookupFn = undefined;
}
function initialize() {
initialized = true;
invariant(typeof target !== "string" || lookupFn, "if the reference target is specified by attribute name, a lookup function is required");
invariant(!lookupFn || typeof lookupFn === "function", "second argument should be a lookup function");
invariant(typeof target !== "string" || lookupFn && typeof lookupFn === "function", "if the reference target is specified by attribute name, a lookup function is required");
invariant(!lookupFn || typeof lookupFn === "function", "second argument should be a lookup function or additional arguments object");
if (typeof target === "string")

@@ -1002,3 +1162,3 @@ childIdentifierAttribute = target;

}
return {
var result = {
serializer: function (item) {

@@ -1017,3 +1177,5 @@ if (!initialized)

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1048,9 +1210,11 @@

* @param {PropSchema} propSchema to be used to (de)serialize the contents of the array
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function list(propSchema) {
function list(propSchema, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!isAliasedPropSchema(propSchema), "provided prop is aliased, please put aliases first");
return {
invariant(!isAliasedPropSchema(propSchema),
"provided prop is aliased, please put aliases first");
var result = {
serializer: function (ar) {

@@ -1060,14 +1224,51 @@ invariant(ar && "length" in ar && "map" in ar, "expected array (like) object");

},
deserializer: function(jsonArray, done, context) {
deserializer: function (jsonArray, done, context) {
if (!Array.isArray(jsonArray))
return void done("[serializr] expected JSON array")
function processItem(jsonValue, onItemDone, itemIndex) {
function callbackBefore(err, value) {
if (!err) {
propSchema.deserializer(value, deserializeDone, context);
} else {
onItemDone(err);
}
}
function deserializeDone(err, value) {
if (typeof propSchema.afterDeserialize === "function") {
onAfterDeserialize(callbackAfter, err, value, jsonValue, itemIndex, context,
propSchema);
} else {
onItemDone(err, value);
}
}
function callbackAfter(errPreliminary, finalOrRetryValue) {
if (errPreliminary && finalOrRetryValue !== undefined &&
typeof propSchema.afterDeserialize === "function") {
propSchema.deserializer(
finalOrRetryValue,
deserializeDone,
context
);
} else {
onItemDone(errPreliminary, finalOrRetryValue);
}
}
onBeforeDeserialize(callbackBefore, jsonValue, jsonArray, itemIndex, context,
propSchema);
}
parallel(
jsonArray,
function (item, itemDone) {
return propSchema.deserializer(item, itemDone, context)
},
processItem,
done
);
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1081,9 +1282,10 @@

* @param {*} propSchema
* @returns
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function map(propSchema) {
function map(propSchema, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!isAliasedPropSchema(propSchema), "provided prop is aliased, please put aliases first");
return {
var res = {
serializer: function (m) {

@@ -1105,3 +1307,3 @@ invariant(m && typeof m === "object", "expected object or Map");

var keys = Object.keys(jsonObject);
list(propSchema).deserializer(
list(propSchema, additionalArgs).deserializer(
keys.map(function (key) {

@@ -1133,52 +1335,68 @@ return jsonObject[key]

}
}
};
res = processAdditionalPropArgs(res, additionalArgs);
return res
}
/**
* Similar to map, mapAsArray can be used to serialize a map-like collection where the key is contained in the 'value object'.
* Example: consider Map<id: number, customer: Customer> where the Customer object has the id stored on itself.
* mapAsArray stores all values from the map into an array which is serialized.
* Deserialization returns a ES6 Map or plain object object where the `keyPropertyName` of each object is used for keys.
* For ES6 maps this has the benefit of being allowed to have non-string keys in the map. The serialized json also may be slightly more compact.
* Similar to map, mapAsArray can be used to serialize a map-like collection where the key is
* contained in the 'value object'. Example: consider Map<id: number, customer: Customer> where the
* Customer object has the id stored on itself. mapAsArray stores all values from the map into an
* array which is serialized. Deserialization returns a ES6 Map or plain object object where the
* `keyPropertyName` of each object is used for keys. For ES6 maps this has the benefit of being
* allowed to have non-string keys in the map. The serialized json also may be slightly more
* compact.
*
* @param {any} propSchema, {string} keyPropertyName - the property of stored objects used as key in the map
* @returns
* @param {any} propSchema
* @param {string} keyPropertyName - the property of stored objects used as key in the map
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function mapAsArray(propSchema, keyPropertyName) {
function mapAsArray(propSchema, keyPropertyName, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!!keyPropertyName, "expected key property name as second argument");
return {
var res = {
serializer: function (m) {
invariant(m && typeof m === "object", "expected object or Map");
var isMap = isMapLike(m);
var result = [];
// eslint-disable-next-line no-unused-vars
m.forEach(function (value, key) {
result.push(propSchema.serializer(value));
});
if (isMap) {
m.forEach(function (value) {
result.push(propSchema.serializer(value));
});
} else for (var key in m) {
result.push(propSchema.serializer(m[key]));
// result[key] = propSchema.serializer(m[key])
}
return result
},
deserializer: function (jsonArray, done, context, oldValue) {
list(propSchema).deserializer(
jsonArray,
function (err, values) {
if (err)
return void done(err)
var isMap = isMapLike(oldValue);
var newValue;
if (isMap) {
oldValue.clear();
newValue = oldValue;
} else
newValue = {};
for (var i = 0, l = jsonArray.length; i < l; i++)
if (isMap)
newValue.set(values[i][keyPropertyName], values[i]);
else
newValue[values[i][keyPropertyName].toString()] = values[i];
done(null, newValue);
},
context
);
list(propSchema, additionalArgs).deserializer(
jsonArray,
function (err, values) {
if (err)
return void done(err)
var isMap = isMapLike(oldValue);
var newValue;
if (isMap) {
oldValue.clear();
newValue = oldValue;
} else {
newValue = {};
}
for (var i = 0, l = jsonArray.length; i < l; i++)
if (isMap)
newValue.set(values[i][keyPropertyName], values[i]);
else
newValue[values[i][keyPropertyName].toString()] = values[i];
done(null, newValue);
},
context
);
}
}
};
res = processAdditionalPropArgs(res, additionalArgs);
return res
}

@@ -1198,6 +1416,7 @@

*
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {ModelSchema}
*/
function raw() {
return {
function raw(additionalArgs) {
var result = {
serializer: function (value) {

@@ -1209,3 +1428,5 @@ return value

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1267,2 +1488,2 @@

export { createSimpleSchema, createModelSchema, getDefaultModelSchema, setDefaultModelSchema, serializable, serialize, serializeAll, deserialize, update, primitive, identifier, date, alias, custom, object, reference, list, map, mapAsArray, raw, SKIP, object as child, reference as ref };
export { createSimpleSchema, createModelSchema, getDefaultModelSchema, setDefaultModelSchema, serializable, serialize, serializeAll, cancelDeserialize, deserialize, update, primitive, identifier, date, alias, custom, object, reference, list, map, mapAsArray, raw, SKIP, object as child, reference as ref };

@@ -40,3 +40,3 @@ /** serializr - (c) Michel Weststrate 2016 - MIT Licensed */

var fired = false;
return function() {
return function () {
if (!fired) {

@@ -56,9 +56,9 @@ fired = true;

function parallel(ar, processor, cb) {
// TODO: limit parallelization?
// TODO: limit parallelization?
if (ar.length === 0)
return void cb(null, [])
var left = ar.length;
var left = ar.filter(function(){ return true }).length; // only count items processed by forEach
var resultArray = [];
var failed = false;
var processorCb = function(idx, err, result) {
var processorCb = function (idx, err, result) {
if (err) {

@@ -76,3 +76,3 @@ if (!failed) {

ar.forEach(function (value, idx) {
processor(value, processorCb.bind(null, idx));
processor(value, processorCb.bind(null, idx), idx);
});

@@ -100,3 +100,3 @@ }

function isIdentifierPropSchema(propSchema) {
return typeof propSchema === "object" && propSchema.identifier === true
return typeof propSchema === "object" && propSchema.identifier === true
}

@@ -129,2 +129,15 @@

function processAdditionalPropArgs(propSchema, additionalArgs) {
if (additionalArgs) {
invariant(isPropSchema(propSchema), "expected a propSchema");
var argNames = ["beforeDeserialize", "afterDeserialize"];
argNames.forEach(function(argName) {
if (typeof additionalArgs[argName] === "function") {
propSchema[argName] = additionalArgs[argName];
}
});
}
return propSchema
}
/**

@@ -219,6 +232,7 @@ * Returns the standard model schema associated with a class / constructor function

*
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {ModelSchema}
*/
function primitive() {
return {
function primitive(additionalArgs) {
var result = {
serializer: function (value) {

@@ -233,3 +247,5 @@ invariant(isPrimitive(value), "this value is not primitive: " + value);

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -451,2 +467,4 @@

var rootContextCache = new Map();
function Context(parentContext, modelSchema, json, onReadyCb, customArgs) {

@@ -459,3 +477,3 @@ this.parentContext = parentContext;

this.json = json;
this.target = null;
this.target = null; // always set this property using setTarget
this.hasError = false;

@@ -477,3 +495,3 @@ this.modelSchema = modelSchema;

// once: defend against user-land calling 'done' twice
return once(function(err, value) {
return once(function (err, value) {
if (err) {

@@ -483,2 +501,3 @@ if (!this.hasError) {

this.onReadyCb(err);
rootContextCache.delete(this);
}

@@ -488,13 +507,16 @@ } else if (!this.hasError) {

if (--this.pendingCallbacks === this.pendingRefsCount) {
if (this.pendingRefsCount > 0)
// all pending callbacks are pending reference resolvers. not good.
if (this.pendingRefsCount > 0) {
// all pending callbacks are pending reference resolvers. not good.
this.onReadyCb(new Error(
"Unresolvable references in json: \"" +
Object.keys(this.pendingRefs).filter(function (uuid) {
return this.pendingRefs[uuid].length > 0
}, this).join("\", \"") +
"\""
));
else
this.onReadyCb(null, this.target);
"Unresolvable references in json: \"" +
Object.keys(this.pendingRefs).filter(function (uuid) {
return this.pendingRefs[uuid].length > 0
}, this).join("\", \"") +
"\""
));
rootContextCache.delete(this);
} else {
this.onReadyCb(null, this.target);
rootContextCache.delete(this);
}
}

@@ -527,3 +549,3 @@ }

// given a model schema, uuid and value, resolve all references that where looking for this object
Context.prototype.resolve = function(modelSchema, uuid, value) {
Context.prototype.resolve = function (modelSchema, uuid, value) {
invariant(this.isRoot);

@@ -547,5 +569,47 @@ if (!this.resolvedRefs[uuid])

// set target and update root context cache
Context.prototype.setTarget = function (target) {
if (this.isRoot && this.target) {
rootContextCache.delete(this.target);
}
this.target = target;
rootContextCache.set(this.target, this);
};
// call all remaining reference lookup callbacks indicating an error during ref resolution
Context.prototype.cancelAwaits = function () {
invariant(this.isRoot);
var self = this;
Object.keys(this.pendingRefs).forEach(function (uuid) {
self.pendingRefs[uuid].forEach(function (refOpts) {
self.pendingRefsCount--;
refOpts.callback(new Error("Reference resolution canceled for " + uuid));
});
});
this.pendingRefs = {};
this.pendingRefsCount = 0;
};
function getTargetContext(target) {
return rootContextCache.get(target)
}
/*
* Deserialization
*/
/**
* Cancels an asynchronous deserialization or update operation for the specified target object.
* @param instance object that was previously returned from deserialize or update method
*/
function cancelDeserialize(instance) {
invariant(typeof instance === "object" && instance && !Array.isArray(instance), "cancelDeserialize needs an object");
var context = getTargetContext(instance);
if (context) {
context.cancelAwaits();
}
}
/*
* Deserialization
*/
function schemaHasAlias(schema, name) {

@@ -561,4 +625,7 @@ for (var key in schema.props)

var value = json[key];
// when deserializing we don't want to silently ignore 'unparseable data' to avoid confusing bugs
invariant(isPrimitive(value), "encountered non primitive value while deserializing '*' properties in property '" + key + "': " + value);
// when deserializing we don't want to silently ignore 'unparseable data' to avoid
// confusing bugs
invariant(isPrimitive(value),
"encountered non primitive value while deserializing '*' properties in property '" +
key + "': " + value);
obj[key] = value;

@@ -569,3 +636,4 @@ }

/**
* Deserializes a json structor into an object graph.
* Deserializes a json structure into an object graph.
*
* This process might be asynchronous (for example if there are references with an asynchronous

@@ -577,5 +645,8 @@ * lookup function). The function returns an object (or array of objects), but the returned object

* @param {json} json data to deserialize
* @param {function} callback node style callback that is invoked once the deserializaiton has finished.
* First argument is the optional error, second argument is the deserialized object (same as the return value)
* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
* @param {function} callback node style callback that is invoked once the deserialization has
* finished. First argument is the optional error, second argument is the deserialized object
* (same as the return value)
* @param {*} customArgs custom arguments that are available as `context.args` during the
* deserialization process. This can be used as dependency injection mechanism to pass in, for
* example, stores.
* @returns {object|array} deserialized object, possibly incomplete.

@@ -600,16 +671,18 @@ */

} else
return deserializeObjectWithSchema(null, schema, json, callback, customArgs)
return deserializeObjectWithSchema(null, schema, json, callback, customArgs)
}
function deserializeObjectWithSchema(parentContext, schema, json, callback, customArgs) {
if (json === null || json === undefined)
function deserializeObjectWithSchema(parentContext, modelSchema, json, callback, customArgs) {
if (json === null || json === undefined || typeof json !== "object")
return void callback(null, null)
var context = new Context(parentContext, schema, json, callback, customArgs);
var target = schema.factory(context);
var context = new Context(parentContext, modelSchema, json, callback, customArgs);
var target = modelSchema.factory(context);
// todo async invariant
invariant(!!target, "No object returned from factory");
// TODO: make invariant? invariant(schema.extends || !target.constructor.prototype.constructor.serializeInfo, "object has a serializable supertype, but modelschema did not provide extends clause")
context.target = target;
// TODO: make invariant? invariant(schema.extends ||
// !target.constructor.prototype.constructor.serializeInfo, "object has a serializable
// supertype, but modelschema did not provide extends clause")
context.setTarget(target);
var lock = context.createCallback(GUARDED_NOOP);
deserializePropsWithSchema(context, schema, json, target);
deserializePropsWithSchema(context, modelSchema, json, target);
lock();

@@ -619,10 +692,59 @@ return target

function deserializePropsWithSchema(context, schema, json, target) {
if (schema.extends)
deserializePropsWithSchema(context, schema.extends, json, target);
Object.keys(schema.props).forEach(function (propName) {
var propDef = schema.props[propName];
function deserializePropsWithSchema(context, modelSchema, json, target) {
if (modelSchema.extends)
deserializePropsWithSchema(context, modelSchema.extends, json, target);
function deserializeProp(propDef, jsonValue, propName) {
function setValue(value) {
if (value !== SKIP) {
target[propName] = value;
}
}
function preProcess(resultCallback) {
return function (err, newValue) {
function finalCallback(errPreliminary, finalOrRetryValue) {
if (errPreliminary && finalOrRetryValue !== undefined &&
typeof propDef.afterDeserialize === "function") {
propDef.deserializer(
finalOrRetryValue,
preProcess(resultCallback),
context,
target[propName]
);
} else {
resultCallback(errPreliminary, finalOrRetryValue);
}
}
onAfterDeserialize(finalCallback, err, newValue, jsonValue, json,
propName, context, propDef);
}
}
propDef.deserializer(
jsonValue,
// for individual props, use root context based callbacks
// this allows props to complete after completing the object itself
// enabling reference resolving and such
preProcess(context.rootContext.createCallback(setValue)),
context,
target[propName] // initial value
);
}
Object.keys(modelSchema.props).forEach(function (propName) {
var propDef = modelSchema.props[propName];
function callbackDeserialize(err, jsonValue) {
if (!err && jsonValue !== undefined) {
deserializeProp(propDef, jsonValue, propName);
}
}
if (propName === "*") {
invariant(propDef === true, "prop schema '*' can onle be used with 'true'");
deserializeStarProps(schema, target, json);
invariant(propDef === true, "prop schema '*' can only be used with 'true'");
deserializeStarProps(modelSchema, target, json);
return

@@ -635,20 +757,30 @@ }

var jsonAttr = propDef.jsonname || propName;
if (!(jsonAttr in json))
return
propDef.deserializer(
json[jsonAttr],
// for individual props, use root context based callbacks
// this allows props to complete after completing the object itself
// enabling reference resolving and such
context.rootContext.createCallback(function (value) {
if (value !== SKIP){
target[propName] = value;
}
}),
context,
target[propName] // initial value
);
var jsonValue = json[jsonAttr];
onBeforeDeserialize(callbackDeserialize, jsonValue, json, jsonAttr, context, propDef);
});
}
function onBeforeDeserialize(
callback, jsonValue, jsonParentValue, propNameOrIndex, context, propDef) {
if (propDef && typeof propDef.beforeDeserialize === "function") {
propDef.beforeDeserialize(callback, jsonValue, jsonParentValue, propNameOrIndex, context,
propDef);
} else {
callback(null, jsonValue);
}
}
function onAfterDeserialize(
callback, err, newValue, jsonValue, jsonParentValue, propNameOrIndex, context, propDef) {
if (propDef && typeof propDef.afterDeserialize === "function") {
propDef.afterDeserialize(callback, err, newValue, jsonValue, jsonParentValue,
propNameOrIndex, context, propDef);
} else {
callback(err, newValue);
}
}
/*

@@ -668,2 +800,3 @@ * Update

* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
* @returns {object|array} deserialized object, possibly incomplete.
*/

@@ -687,6 +820,7 @@ function update(modelSchema, target, json, callback, customArgs) {

var context = new Context(null, modelSchema, json, callback, customArgs);
context.target = target;
context.setTarget(target);
var lock = context.createCallback(GUARDED_NOOP);
deserializePropsWithSchema(context, modelSchema, json, target);
var result = deserializePropsWithSchema(context, modelSchema, json, target);
lock();
return result
}

@@ -711,3 +845,3 @@

* var todos = {};
*
*
* var s = _.createSimpleSchema({

@@ -717,3 +851,3 @@ * id: _.identifier((id, object) => (todos[id] = object)),

* });
*
*
* _.deserialize(s, {

@@ -724,3 +858,3 @@ * id: 1,

* _.deserialize(s, [{ id: 2, title: 'test2' }, { id: 1, title: 'test1' }]);
*
*
* t.deepEqual(todos, {

@@ -731,9 +865,17 @@ * 1: { id: 1, title: 'test1' },

*
* @param {RegisterFunction} registerFn optional function to register this object during creation.
* @param { RegisterFunction | AdditionalPropArgs } arg1 optional registerFn: function to register this object during creation.
* @param {AdditionalPropArgs} arg2 optional object that contains beforeDeserialize and/or afterDeserialize handlers
*
* @returns {PropSchema}
*/
function identifier(registerFn) {
invariant(!registerFn || typeof registerFn === "function", "First argument should be omitted or function");
return {
function identifier(arg1, arg2) {
var registerFn, additionalArgs;
if (typeof arg1 === "function") {
registerFn = arg1;
additionalArgs = arg2;
} else {
additionalArgs = arg1;
}
invariant(!additionalArgs || typeof additionalArgs === "object", "Additional property arguments should be an object, register function should be omitted or a funtion");
var result = {
identifier: true,

@@ -749,3 +891,5 @@ serializer: _defaultPrimitiveProp.serializer,

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -756,7 +900,8 @@

*
* @returns
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function date() {
function date(additionalArgs) {
// TODO: add format option?
return {
var result = {
serializer: function(value) {

@@ -773,3 +918,5 @@ if (value === null || value === undefined)

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -802,3 +949,5 @@

deserializer: propSchema.deserializer,
identifier: isIdentifierPropSchema(propSchema)
identifier: isIdentifierPropSchema(propSchema),
beforeDeserialize: propSchema.beforeDeserialize,
afterDeserialize: propSchema.afterDeserialize
}

@@ -861,17 +1010,20 @@ }

* @param {function} deserializer function that takes a json value and turns it into a model value. It also takes context argument, which can allow you to deserialize based on the context of other parameters.
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function custom(serializer, deserializer) {
function custom(serializer, deserializer, additionalArgs) {
invariant(typeof serializer === "function", "first argument should be function");
invariant((typeof deserializer === "function"), "second argument should be a function or promise");
return {
var result = {
serializer: serializer,
deserializer: function (jsonValue, done, context, oldValue) {
if (deserializer.length === 4) {
deserializer(jsonValue, context, oldValue, done);
deserializer(jsonValue, context, oldValue, done, additionalArgs);
} else {
done(null, deserializer(jsonValue, context, oldValue));
done(null, deserializer(jsonValue, context, oldValue, null, additionalArgs));
}
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -905,7 +1057,8 @@

* @param {ModelSchema} modelSchema to be used to (de)serialize the object
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function object(modelSchema) {
function object(modelSchema, additionalArgs) {
invariant(typeof modelSchema === "object" || typeof modelSchema === "function", "No modelschema provided. If you are importing it from another file be aware of circular dependencies.");
return {
var result = {
serializer: function (item) {

@@ -923,5 +1076,7 @@ modelSchema = getDefaultModelSchema(modelSchema);

return void done(null, childJson)
return void deserializeObjectWithSchema(context, modelSchema, childJson, done)
return void deserializeObjectWithSchema(context, modelSchema, childJson, done, additionalArgs)
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -987,13 +1142,18 @@

* @param target: ModelSchema or string
* @param {RefLookupFunction} lookupFn function
* @param {RefLookupFunction | AdditionalPropArgs} lookupFn optional function or additionalArgs object
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function reference(target, lookupFn) {
function reference(target, lookupFn, additionalArgs) {
invariant(!!target, "No modelschema provided. If you are importing it from another file be aware of circular dependencies.");
var initialized = false;
var childIdentifierAttribute;
if (typeof lookupFn === "object" && additionalArgs === undefined) {
additionalArgs = lookupFn;
lookupFn = undefined;
}
function initialize() {
initialized = true;
invariant(typeof target !== "string" || lookupFn, "if the reference target is specified by attribute name, a lookup function is required");
invariant(!lookupFn || typeof lookupFn === "function", "second argument should be a lookup function");
invariant(typeof target !== "string" || lookupFn && typeof lookupFn === "function", "if the reference target is specified by attribute name, a lookup function is required");
invariant(!lookupFn || typeof lookupFn === "function", "second argument should be a lookup function or additional arguments object");
if (typeof target === "string")

@@ -1009,3 +1169,3 @@ childIdentifierAttribute = target;

}
return {
var result = {
serializer: function (item) {

@@ -1024,3 +1184,5 @@ if (!initialized)

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1055,9 +1217,11 @@

* @param {PropSchema} propSchema to be used to (de)serialize the contents of the array
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function list(propSchema) {
function list(propSchema, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!isAliasedPropSchema(propSchema), "provided prop is aliased, please put aliases first");
return {
invariant(!isAliasedPropSchema(propSchema),
"provided prop is aliased, please put aliases first");
var result = {
serializer: function (ar) {

@@ -1067,14 +1231,51 @@ invariant(ar && "length" in ar && "map" in ar, "expected array (like) object");

},
deserializer: function(jsonArray, done, context) {
deserializer: function (jsonArray, done, context) {
if (!Array.isArray(jsonArray))
return void done("[serializr] expected JSON array")
function processItem(jsonValue, onItemDone, itemIndex) {
function callbackBefore(err, value) {
if (!err) {
propSchema.deserializer(value, deserializeDone, context);
} else {
onItemDone(err);
}
}
function deserializeDone(err, value) {
if (typeof propSchema.afterDeserialize === "function") {
onAfterDeserialize(callbackAfter, err, value, jsonValue, itemIndex, context,
propSchema);
} else {
onItemDone(err, value);
}
}
function callbackAfter(errPreliminary, finalOrRetryValue) {
if (errPreliminary && finalOrRetryValue !== undefined &&
typeof propSchema.afterDeserialize === "function") {
propSchema.deserializer(
finalOrRetryValue,
deserializeDone,
context
);
} else {
onItemDone(errPreliminary, finalOrRetryValue);
}
}
onBeforeDeserialize(callbackBefore, jsonValue, jsonArray, itemIndex, context,
propSchema);
}
parallel(
jsonArray,
function (item, itemDone) {
return propSchema.deserializer(item, itemDone, context)
},
processItem,
done
);
}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1088,9 +1289,10 @@

* @param {*} propSchema
* @returns
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function map(propSchema) {
function map(propSchema, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!isAliasedPropSchema(propSchema), "provided prop is aliased, please put aliases first");
return {
var res = {
serializer: function (m) {

@@ -1112,3 +1314,3 @@ invariant(m && typeof m === "object", "expected object or Map");

var keys = Object.keys(jsonObject);
list(propSchema).deserializer(
list(propSchema, additionalArgs).deserializer(
keys.map(function (key) {

@@ -1140,52 +1342,68 @@ return jsonObject[key]

}
}
};
res = processAdditionalPropArgs(res, additionalArgs);
return res
}
/**
* Similar to map, mapAsArray can be used to serialize a map-like collection where the key is contained in the 'value object'.
* Example: consider Map<id: number, customer: Customer> where the Customer object has the id stored on itself.
* mapAsArray stores all values from the map into an array which is serialized.
* Deserialization returns a ES6 Map or plain object object where the `keyPropertyName` of each object is used for keys.
* For ES6 maps this has the benefit of being allowed to have non-string keys in the map. The serialized json also may be slightly more compact.
* Similar to map, mapAsArray can be used to serialize a map-like collection where the key is
* contained in the 'value object'. Example: consider Map<id: number, customer: Customer> where the
* Customer object has the id stored on itself. mapAsArray stores all values from the map into an
* array which is serialized. Deserialization returns a ES6 Map or plain object object where the
* `keyPropertyName` of each object is used for keys. For ES6 maps this has the benefit of being
* allowed to have non-string keys in the map. The serialized json also may be slightly more
* compact.
*
* @param {any} propSchema, {string} keyPropertyName - the property of stored objects used as key in the map
* @returns
* @param {any} propSchema
* @param {string} keyPropertyName - the property of stored objects used as key in the map
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {PropSchema}
*/
function mapAsArray(propSchema, keyPropertyName) {
function mapAsArray(propSchema, keyPropertyName, additionalArgs) {
propSchema = propSchema || _defaultPrimitiveProp;
invariant(isPropSchema(propSchema), "expected prop schema as first argument");
invariant(!!keyPropertyName, "expected key property name as second argument");
return {
var res = {
serializer: function (m) {
invariant(m && typeof m === "object", "expected object or Map");
var isMap = isMapLike(m);
var result = [];
// eslint-disable-next-line no-unused-vars
m.forEach(function (value, key) {
result.push(propSchema.serializer(value));
});
if (isMap) {
m.forEach(function (value) {
result.push(propSchema.serializer(value));
});
} else for (var key in m) {
result.push(propSchema.serializer(m[key]));
// result[key] = propSchema.serializer(m[key])
}
return result
},
deserializer: function (jsonArray, done, context, oldValue) {
list(propSchema).deserializer(
jsonArray,
function (err, values) {
if (err)
return void done(err)
var isMap = isMapLike(oldValue);
var newValue;
if (isMap) {
oldValue.clear();
newValue = oldValue;
} else
newValue = {};
for (var i = 0, l = jsonArray.length; i < l; i++)
if (isMap)
newValue.set(values[i][keyPropertyName], values[i]);
else
newValue[values[i][keyPropertyName].toString()] = values[i];
done(null, newValue);
},
context
);
list(propSchema, additionalArgs).deserializer(
jsonArray,
function (err, values) {
if (err)
return void done(err)
var isMap = isMapLike(oldValue);
var newValue;
if (isMap) {
oldValue.clear();
newValue = oldValue;
} else {
newValue = {};
}
for (var i = 0, l = jsonArray.length; i < l; i++)
if (isMap)
newValue.set(values[i][keyPropertyName], values[i]);
else
newValue[values[i][keyPropertyName].toString()] = values[i];
done(null, newValue);
},
context
);
}
}
};
res = processAdditionalPropArgs(res, additionalArgs);
return res
}

@@ -1205,6 +1423,7 @@

*
* @param {AdditionalPropArgs} additionalArgs optional object that contains beforeDeserialize and/or afterDeserialize handlers
* @returns {ModelSchema}
*/
function raw() {
return {
function raw(additionalArgs) {
var result = {
serializer: function (value) {

@@ -1216,3 +1435,5 @@ return value

}
}
};
result = processAdditionalPropArgs(result, additionalArgs);
return result
}

@@ -1281,2 +1502,3 @@

exports.serializeAll = serializeAll;
exports.cancelDeserialize = cancelDeserialize;
exports.deserialize = deserialize;

@@ -1283,0 +1505,0 @@ exports.update = update;

/** serializr - (c) Michel Weststrate 2016 - MIT Licensed */
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define("serializr",["exports"],r):r(e.serializr={})}(this,function(e){"use strict";function r(e){if(e)throw new Error(e)}function n(e,r){if(!e)throw new Error("[serializr] "+(r||"Illegal State"))}function t(e,r,n){if(0!==e.length){var t=e.length,i=[],o=!1;e.forEach(function(e,a){r(e,function(e,r,a){r?o||(o=!0,n(r)):(i[e]=a,0==--t&&n(null,i))}.bind(null,a))})}else n(null,[])}function i(e){return null===e||"object"!=typeof e&&"function"!=typeof e}function o(e){return e&&e.factory&&e.props}function a(e){return e&&e.serializer&&e.deserializer}function s(e){return"object"==typeof e&&!!e.jsonname}function u(e,r){for(;e;){if(e===r)return!0;e=e["extends"]}return!1}function l(e){return e&&"function"==typeof e.keys&&"function"==typeof e.clear}function c(e){return e?o(e)?e:o(e.serializeInfo)?e.serializeInfo:e.constructor&&e.constructor.serializeInfo?e.constructor.serializeInfo:void 0:null}function f(e,r){return n(o(r)),e.serializeInfo=r}function p(e,r,t){n(e!==Object,"one cannot simply put define a model schema for Object"),n("function"==typeof e,"expected constructor function");var i={targetClass:e,factory:t||function(){return new e},props:r};if(e.prototype.constructor!==Object){var o=c(e.prototype.constructor);o&&o.targetClass!==e&&(i["extends"]=o)}return f(e,i),i}function d(){return{serializer:function(e){return n(i(e),"this value is not primitive: "+e),e},deserializer:function(e,r){i(e)?r(null,e):r("[serializr] this value is not primitive: "+e)}}}var h="undefined"!=typeof Symbol?Symbol("SKIP"):{SKIP:!0},m=d(),y=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,g=/([^\s,]+)/g;function v(e,r,t,i){var o,s,u;if(n(arguments.length>=2,"too few arguments. Please use @serializable as property decorator"),t===undefined&&"function"==typeof r&&r.prototype&&i!==undefined&&"number"==typeof i){n(a(e),"Constructor params must use alias(name)"),n(e.jsonname,"Constructor params must use alias(name)");var l=(s=r.toString().replace(y,""),null===(u=s.slice(s.indexOf("(")+1,s.indexOf(")")).match(g))&&(u=[]),u);l.length>=i&&(t=l[i],e.paramNumber=i,i=undefined,r=r.prototype,o=function(e){for(var n=[],t=0;t<r.constructor.length;t++)Object.keys(e.modelSchema.props).forEach(function(r){var i=e.modelSchema.props[r];i.paramNumber===t&&(n[t]=e.json[i.jsonname])});return new(Function.prototype.bind.apply(r.constructor,[null].concat(n)))})}n("string"==typeof t,"incorrect usage of @serializable decorator");var f=c(r);return f&&r.constructor.hasOwnProperty("serializeInfo")||(f=p(r.constructor,{},o)),f&&f.targetClass!==r.constructor&&(f=p(r.constructor,{},o)),f.props[t]=e,!i||i.get||i.set||(i.writable=!0),i}function b(e,r){n(1===arguments.length||2===arguments.length,"serialize expects one or 2 arguments");var t=1===arguments.length?e:r,i=1===arguments.length?null:e;if(Array.isArray(t)){if(0===t.length)return[];i||(i=c(t[0]))}else i||(i=c(t));return n(!!i,"Failed to find default schema for "+e),Array.isArray(t)?t.map(function(e){return z(i,e)}):z(i,t)}function z(e,r){var t;return n(e&&"object"==typeof e,"Expected schema"),n(r&&"object"==typeof r,"Expected object"),t=e["extends"]?z(e["extends"],r):{},Object.keys(e.props).forEach(function(o){var a=e.props[o];if("*"===o)return n(!0===a,"prop schema '*' can onle be used with 'true'"),void function(e,r,n){for(var t in r)if(r.hasOwnProperty(t)&&!(t in e.props)){var o=r[t];i(o)&&(n[t]=o)}}(e,r,t);if(!0===a&&(a=m),!1!==a){var s=a.serializer(r[o],o,r);s!==h&&(t[a.jsonname||o]=s)}}),t}function j(e,n,t,i,o){this.parentContext=e,this.isRoot=!e,this.pendingCallbacks=0,this.pendingRefsCount=0,this.onReadyCb=i||r,this.json=t,this.target=null,this.hasError=!1,this.modelSchema=n,this.isRoot?(this.rootContext=this,this.args=o,this.pendingRefs={},this.resolvedRefs={}):(this.rootContext=e.rootContext,this.args=e.args)}function x(e,r){for(var n in e.props)if("object"==typeof e.props[n]&&e.props[n].jsonname===r)return!0;return!1}function R(e,t,i,o,a){if(null!==i&&i!==undefined){var s=new j(e,t,i,o,a),u=t.factory(s);n(!!u,"No object returned from factory"),s.target=u;var l=s.createCallback(r);return C(s,t,i,u),l(),u}o(null,null)}function C(e,r,t,o){r["extends"]&&C(e,r["extends"],t,o),Object.keys(r.props).forEach(function(a){var s=r.props[a];if("*"===a)return n(!0===s,"prop schema '*' can onle be used with 'true'"),void function(e,r,t){for(var o in t)if(!(o in e.props||x(e,o))){var a=t[o];n(i(a),"encountered non primitive value while deserializing '*' properties in property '"+o+"': "+a),r[o]=a}}(r,o,t);if(!0===s&&(s=m),!1!==s){var u=s.jsonname||a;u in t&&s.deserializer(t[u],e.rootContext.createCallback(function(e){e!==h&&(o[a]=e)}),e,o[a])}})}function S(e){return n("object"==typeof e||"function"==typeof e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies."),{serializer:function(r){return n(o(e=c(e)),"expected modelSchema, got "+e),null===r||r===undefined?r:b(e,r)},deserializer:function(r,t,i){n(o(e=c(e)),"expected modelSchema, got "+e),null!==r&&r!==undefined?R(i,e,r,t):t(null,r)}}}function w(e,r){n(!!e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies.");var t,i=!1;function a(){if(i=!0,n("string"!=typeof e||r,"if the reference target is specified by attribute name, a lookup function is required"),n(!r||"function"==typeof r,"second argument should be a lookup function"),"string"==typeof e)t=e;else{var a=c(e);n(o(a),"expected model schema or string as first argument for 'ref', got "+a),r=r||(s=a,function(e,r,n){n.rootContext.await(s,e,r)}),n(!!(t=function(e){for(n(o(e));e;){for(var r in e.props)if("object"==typeof e.props[r]&&!0===e.props[r].identifier)return r;e=e["extends"]}return null}(a)),"provided model schema doesn't define an identifier() property and cannot be used by 'ref'.")}var s}return{serializer:function(e){return i||a(),e?e[t]:null},deserializer:function(e,n,t){i||a(),null===e||e===undefined?n(null,e):r(e,n,t)}}}function k(e){return n(a(e=e||m),"expected prop schema as first argument"),n(!s(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){return n(r&&"length"in r&&"map"in r,"expected array (like) object"),r.map(e.serializer)},deserializer:function(r,n,i){Array.isArray(r)?t(r,function(r,n){return e.deserializer(r,n,i)},n):n("[serializr] expected JSON array")}}}j.prototype.createCallback=function(e){return this.pendingCallbacks++,r=function(r,n){r?this.hasError||(this.hasError=!0,this.onReadyCb(r)):this.hasError||(e(n),--this.pendingCallbacks===this.pendingRefsCount&&(this.pendingRefsCount>0?this.onReadyCb(new Error('Unresolvable references in json: "'+Object.keys(this.pendingRefs).filter(function(e){return this.pendingRefs[e].length>0},this).join('", "')+'"')):this.onReadyCb(null,this.target)))}.bind(this),t=!1,function(){if(!t)return t=!0,r.apply(null,arguments);n(!1,"callback was invoked twice")};var r,t},j.prototype.await=function(e,r,t){if(n(this.isRoot),r in this.resolvedRefs){var i=this.resolvedRefs[r].filter(function(r){return u(r.modelSchema,e)})[0];if(i)return void t(null,i.value)}this.pendingRefsCount++,this.pendingRefs[r]||(this.pendingRefs[r]=[]),this.pendingRefs[r].push({modelSchema:e,uuid:r,callback:t})},j.prototype.resolve=function(e,r,t){if(n(this.isRoot),this.resolvedRefs[r]||(this.resolvedRefs[r]=[]),this.resolvedRefs[r].push({modelSchema:e,value:t}),r in this.pendingRefs)for(var i=this.pendingRefs[r].length-1;i>=0;i--){var o=this.pendingRefs[r][i];u(e,o.modelSchema)&&(this.pendingRefs[r].splice(i,1),this.pendingRefsCount--,o.callback(null,t))}},e.createSimpleSchema=function(e){return{factory:function(){return{}},props:e}},e.createModelSchema=p,e.getDefaultModelSchema=c,e.setDefaultModelSchema=f,e.serializable=function(e,r,t){if(1===arguments.length){var i=!0===e?m:e;return n(a(i),"@serializable expects prop schema"),v.bind(null,i)}return v(d(),e,r,t)},e.serialize=b,e.serializeAll=function(e){n(1===arguments.length&&"function"==typeof e,"@serializeAll can only be used as class decorator");var r=c(e);return r&&e.hasOwnProperty("serializeInfo")||f(e,r=p(e,{})),c(e).props["*"]=!0,e},e.deserialize=function(e,i,a,s){if(n(arguments.length>=2,"deserialize expects at least 2 arguments"),n(o(e=c(e)),"first argument should be model schema"),Array.isArray(i)){var u=[];return t(i,function(r,n){var t=R(null,e,r,n,s);u.push(t)},a||r),u}return R(null,e,i,a,s)},e.update=function(e,t,i,a,s){2===arguments.length||"function"==typeof arguments[2]?(e=c(t=arguments[0]),i=arguments[1],a=arguments[2],s=arguments[3]):e=c(e),n(o(e),"update failed to determine schema"),n("object"==typeof t&&t&&!Array.isArray(t),"update needs an object");var u=new j(null,e,i,a,s);u.target=t;var l=u.createCallback(r);C(u,e,i,t),l()},e.primitive=d,e.identifier=function(e){return n(!e||"function"==typeof e,"First argument should be omitted or function"),{identifier:!0,serializer:m.serializer,deserializer:function(r,n,t){m.deserializer(r,function(r,i){var o,a;o=i,t.target,(a=t).rootContext.resolve(a.modelSchema,o,a.target),e&&e(i,t.target,t),n(r,i)})}}},e.date=function(){return{serializer:function(e){return null===e||e===undefined?e:(n(e instanceof Date,"Expected Date object"),e.getTime())},deserializer:function(e,r){null!==e&&e!==undefined?r(null,new Date(e)):r(null,e)}}},e.alias=function(e,r){return n(e&&"string"==typeof e,"expected prop name as first argument"),n(a(r=r&&!0!==r?r:m),"expected prop schema as second argument"),n(!s(r),"provided prop is already aliased"),{jsonname:e,serializer:r.serializer,deserializer:r.deserializer,identifier:(t=r,"object"==typeof t&&!0===t.identifier)};var t},e.custom=function(e,r){return n("function"==typeof e,"first argument should be function"),n("function"==typeof r,"second argument should be a function or promise"),{serializer:e,deserializer:function(e,n,t,i){4===r.length?r(e,t,i,n):n(null,r(e,t,i))}}},e.object=S,e.reference=w,e.list=k,e.map=function(e){return n(a(e=e||m),"expected prop schema as first argument"),n(!s(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){n(r&&"object"==typeof r,"expected object or Map");var t=l(r),i={};if(t)r.forEach(function(r,n){i[n]=e.serializer(r)});else for(var o in r)i[o]=e.serializer(r[o]);return i},deserializer:function(r,n,t,i){if(r&&"object"==typeof r){var o=Object.keys(r);k(e).deserializer(o.map(function(e){return r[e]}),function(e,r){if(e)n(e);else{var t,a=l(i);a?(i.clear(),t=i):t={};for(var s=0,u=o.length;s<u;s++)a?t.set(o[s],r[s]):t[o[s]]=r[s];n(null,t)}},t)}else n("[serializr] expected JSON object")}}},e.mapAsArray=function(e,r){return n(a(e=e||m),"expected prop schema as first argument"),n(!!r,"expected key property name as second argument"),{serializer:function(r){var n=[];return r.forEach(function(r,t){n.push(e.serializer(r))}),n},deserializer:function(n,t,i,o){k(e).deserializer(n,function(e,i){if(e)t(e);else{var a,s=l(o);s?(o.clear(),a=o):a={};for(var u=0,c=n.length;u<c;u++)s?a.set(i[u][r],i[u]):a[i[u][r].toString()]=i[u];t(null,a)}},i)}}},e.raw=function(){return{serializer:function(e){return e},deserializer:function(e,r){r(null,e)}}},e.SKIP=h,e.child=S,e.ref=w,Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define("serializr",["exports"],n):n(e.serializr={})}(this,function(e){"use strict";function f(e){if(e)throw new Error(e)}function l(e,n){if(!e)throw new Error("[serializr] "+(n||"Illegal State"))}function t(e,t,r){if(0!==e.length){var i=e.filter(function(){return!0}).length,o=[],a=!1;e.forEach(function(e,n){t(e,function(e,n,t){n?a||(a=!0,r(n)):(o[e]=t,0==--i&&r(null,o))}.bind(null,n),n)})}else r(null,[])}function s(e){return null===e||"object"!=typeof e&&"function"!=typeof e}function u(e){return e&&e.factory&&e.props}function p(e){return e&&e.serializer&&e.deserializer}function r(e){return"object"==typeof e&&!!e.jsonname}function o(e,n){for(;e;){if(e===n)return!0;e=e["extends"]}return!1}function c(e){return e&&"function"==typeof e.keys&&"function"==typeof e.clear}function d(n,t){if(t){l(p(n),"expected a propSchema");["beforeDeserialize","afterDeserialize"].forEach(function(e){"function"==typeof t[e]&&(n[e]=t[e])})}return n}function h(e){return e?u(e)?e:u(e.serializeInfo)?e.serializeInfo:e.constructor&&e.constructor.serializeInfo?e.constructor.serializeInfo:void 0:null}function a(e,n){return l(u(n)),e.serializeInfo=n}function m(e,n,t){l(e!==Object,"one cannot simply put define a model schema for Object"),l("function"==typeof e,"expected constructor function");var r={targetClass:e,factory:t||function(){return new e},props:n};if(e.prototype.constructor!==Object){var i=h(e.prototype.constructor);i&&i.targetClass!==e&&(r["extends"]=i)}return a(e,r),r}function i(e){var n={serializer:function(e){return l(s(e),"this value is not primitive: "+e),e},deserializer:function(e,n){s(e)?n(null,e):n("[serializr] this value is not primitive: "+e)}};return n=d(n,e)}var y="undefined"!=typeof Symbol?Symbol("SKIP"):{SKIP:!0},g=i(),b=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,v=/([^\s,]+)/g;function z(e,n,t,r){var i;if(l(2<=arguments.length,"too few arguments. Please use @serializable as property decorator"),t===undefined&&"function"==typeof n&&n.prototype&&r!==undefined&&"number"==typeof r){l(p(e),"Constructor params must use alias(name)"),l(e.jsonname,"Constructor params must use alias(name)");var o=function s(e){var n=e.toString().replace(b,""),t=n.slice(n.indexOf("(")+1,n.indexOf(")")).match(v);return null===t&&(t=[]),t}(n);o.length>=r&&(t=o[r],e.paramNumber=r,r=undefined,n=n.prototype,i=function(t){for(var r=[],i=0;i<n.constructor.length;i++)Object.keys(t.modelSchema.props).forEach(function(e){var n=t.modelSchema.props[e];n.paramNumber===i&&(r[i]=t.json[n.jsonname])});return new(Function.prototype.bind.apply(n.constructor,[null].concat(r)))})}l("string"==typeof t,"incorrect usage of @serializable decorator");var a=h(n);return a&&n.constructor.hasOwnProperty("serializeInfo")||(a=m(n.constructor,{},i)),a&&a.targetClass!==n.constructor&&(a=m(n.constructor,{},i)),a.props[t]=e,!r||r.get||r.set||(r.writable=!0),r}function n(e,n){l(1===arguments.length||2===arguments.length,"serialize expects one or 2 arguments");var t=1===arguments.length?e:n,r=1===arguments.length?null:e;if(Array.isArray(t)){if(0===t.length)return[];r||(r=h(t[0]))}else r||(r=h(t));return l(!!r,"Failed to find default schema for "+e),Array.isArray(t)?t.map(function(e){return j(r,e)}):j(r,t)}function j(r,i){var a;return l(r&&"object"==typeof r,"Expected schema"),l(i&&"object"==typeof i,"Expected object"),a=r["extends"]?j(r["extends"],i):{},Object.keys(r.props).forEach(function(e){var n=r.props[e];if("*"===e)return l(!0===n,"prop schema '*' can onle be used with 'true'"),void function o(e,n,t){for(var r in n)if(n.hasOwnProperty(r)&&!(r in e.props)){var i=n[r];s(i)&&(t[r]=i)}}(r,i,a);if(!0===n&&(n=g),!1!==n){var t=n.serializer(i[e],e,i);t!==y&&(a[n.jsonname||e]=t)}}),a}var x=new Map;function R(e,n,t,r,i){this.parentContext=e,this.isRoot=!e,this.pendingCallbacks=0,this.pendingRefsCount=0,this.onReadyCb=r||f,this.json=t,this.target=null,this.hasError=!1,this.modelSchema=n,this.isRoot?((this.rootContext=this).args=i,this.pendingRefs={},this.resolvedRefs={}):(this.rootContext=e.rootContext,this.args=e.args)}function C(e,n){for(var t in e.props)if("object"==typeof e.props[t]&&e.props[t].jsonname===n)return!0;return!1}function w(e,n,t,r,i){if(null!==t&&t!==undefined&&"object"==typeof t){var o=new R(e,n,t,r,i),a=n.factory(o);l(!!a,"No object returned from factory"),o.setTarget(a);var s=o.createCallback(f);return S(o,n,t,a),s(),a}r(null,null)}function S(f,n,u,c){n["extends"]&&S(f,n["extends"],u,c),Object.keys(n.props).forEach(function(r){var i=n.props[r];if("*"===r)return l(!0===i,"prop schema '*' can only be used with 'true'"),void function o(e,n,t){for(var r in t)if(!(r in e.props||C(e,r))){var i=t[r];l(s(i),"encountered non primitive value while deserializing '*' properties in property '"+r+"': "+i),n[r]=i}}(n,c,u);if(!0===i&&(i=g),!1!==i){var e=i.jsonname||r;k(function a(e,n){e||n===undefined||function t(i,o,a){i.deserializer(o,function s(r){return function(e,n){D(function t(e,n){e&&n!==undefined&&"function"==typeof i.afterDeserialize?i.deserializer(n,s(r),f,c[a]):r(e,n)},e,n,o,u,a,f,i)}}(f.rootContext.createCallback(function n(e){e!==y&&(c[a]=e)})),f,c[a])}(i,n,r)},u[e],u,e,f,i)}})}function k(e,n,t,r,i,o){o&&"function"==typeof o.beforeDeserialize?o.beforeDeserialize(e,n,t,r,i,o):e(null,n)}function D(e,n,t,r,i,o,a,s){s&&"function"==typeof s.afterDeserialize?s.afterDeserialize(e,n,t,r,i,o,a,s):e(n,t)}function E(r,i){l("object"==typeof r||"function"==typeof r,"No modelschema provided. If you are importing it from another file be aware of circular dependencies.");var e={serializer:function(e){return l(u(r=h(r)),"expected modelSchema, got "+r),null===e||e===undefined?e:n(r,e)},deserializer:function(e,n,t){l(u(r=h(r)),"expected modelSchema, got "+r),null!==e&&e!==undefined?w(t,r,e,n,i):n(null,e)}};return e=d(e,i)}function A(r,i,e){l(!!r,"No modelschema provided. If you are importing it from another file be aware of circular dependencies.");var o,a=!1;function s(){if(a=!0,l("string"!=typeof r||i&&"function"==typeof i,"if the reference target is specified by attribute name, a lookup function is required"),l(!i||"function"==typeof i,"second argument should be a lookup function or additional arguments object"),"string"==typeof r)o=r;else{var e=h(r);l(u(e),"expected model schema or string as first argument for 'ref', got "+e),i=i||function n(r){return function(e,n,t){t.rootContext.await(r,e,n)}}(e),l(!!(o=function t(e){for(l(u(e));e;){for(var n in e.props)if("object"==typeof e.props[n]&&!0===e.props[n].identifier)return n;e=e["extends"]}return null}(e)),"provided model schema doesn't define an identifier() property and cannot be used by 'ref'.")}}"object"==typeof i&&e===undefined&&(e=i,i=undefined);var n={serializer:function(e){return a||s(),e?e[o]:null},deserializer:function(e,n,t){a||s(),null===e||e===undefined?n(null,e):i(e,n,t)}};return n=d(n,e)}function O(c,e){l(p(c=c||g),"expected prop schema as first argument"),l(!r(c),"provided prop is aliased, please put aliases first");var n={serializer:function(e){return l(e&&"length"in e&&"map"in e,"expected array (like) object"),e.map(c.serializer)},deserializer:function(e,n,f){Array.isArray(e)?t(e,function u(t,r,i){function o(e,n){"function"==typeof c.afterDeserialize?D(a,e,n,t,i,f,c):r(e,n)}function a(e,n){e&&n!==undefined&&"function"==typeof c.afterDeserialize?c.deserializer(n,o,f):r(e,n)}k(function s(e,n){e?r(e):c.deserializer(n,o,f)},t,e,i,f,c)},n):n("[serializr] expected JSON array")}};return n=d(n,e)}R.prototype.createCallback=function(t){return this.pendingCallbacks++,function r(e){var n=!1;return function(){if(!n)return n=!0,e.apply(null,arguments);l(!1,"callback was invoked twice")}}(function(e,n){e?this.hasError||(this.hasError=!0,this.onReadyCb(e),x["delete"](this)):this.hasError||(t(n),--this.pendingCallbacks===this.pendingRefsCount&&(0<this.pendingRefsCount?this.onReadyCb(new Error('Unresolvable references in json: "'+Object.keys(this.pendingRefs).filter(function(e){return 0<this.pendingRefs[e].length},this).join('", "')+'"')):this.onReadyCb(null,this.target),x["delete"](this)))}.bind(this))},R.prototype.await=function(n,e,t){if(l(this.isRoot),e in this.resolvedRefs){var r=this.resolvedRefs[e].filter(function(e){return o(e.modelSchema,n)})[0];if(r)return void t(null,r.value)}this.pendingRefsCount++,this.pendingRefs[e]||(this.pendingRefs[e]=[]),this.pendingRefs[e].push({modelSchema:n,uuid:e,callback:t})},R.prototype.resolve=function(e,n,t){if(l(this.isRoot),this.resolvedRefs[n]||(this.resolvedRefs[n]=[]),this.resolvedRefs[n].push({modelSchema:e,value:t}),n in this.pendingRefs)for(var r=this.pendingRefs[n].length-1;0<=r;r--){var i=this.pendingRefs[n][r];o(e,i.modelSchema)&&(this.pendingRefs[n].splice(r,1),this.pendingRefsCount--,i.callback(null,t))}},R.prototype.setTarget=function(e){this.isRoot&&this.target&&x["delete"](this.target),this.target=e,x.set(this.target,this)},R.prototype.cancelAwaits=function(){l(this.isRoot);var t=this;Object.keys(this.pendingRefs).forEach(function(n){t.pendingRefs[n].forEach(function(e){t.pendingRefsCount--,e.callback(new Error("Reference resolution canceled for "+n))})}),this.pendingRefs={},this.pendingRefsCount=0},e.createSimpleSchema=function I(e){return{factory:function(){return{}},props:e}},e.createModelSchema=m,e.getDefaultModelSchema=h,e.setDefaultModelSchema=a,e.serializable=function P(e,n,t){if(1!==arguments.length)return z(i(),e,n,t);var r=!0===e?g:e;return l(p(r),"@serializable expects prop schema"),z.bind(null,r)},e.serialize=n,e.serializeAll=function M(e){l(1===arguments.length&&"function"==typeof e,"@serializeAll can only be used as class decorator");var n=h(e);return n&&e.hasOwnProperty("serializeInfo")||a(e,n=m(e,{})),h(e).props["*"]=!0,e},e.cancelDeserialize=function N(e){l("object"==typeof e&&e&&!Array.isArray(e),"cancelDeserialize needs an object");var n=function t(e){return x.get(e)}(e);n&&n.cancelAwaits()},e.deserialize=function T(r,e,n,i){if(l(2<=arguments.length,"deserialize expects at least 2 arguments"),l(u(r=h(r)),"first argument should be model schema"),Array.isArray(e)){var o=[];return t(e,function(e,n){var t=w(null,r,e,n,i);o.push(t)},n||f),o}return w(null,r,e,n,i)},e.update=function K(e,n,t,r,i){2===arguments.length||"function"==typeof arguments[2]?(e=h(n=arguments[0]),t=arguments[1],r=arguments[2],i=arguments[3]):e=h(e),l(u(e),"update failed to determine schema"),l("object"==typeof n&&n&&!Array.isArray(n),"update needs an object");var o=new R(null,e,t,r,i);o.setTarget(n);var a=o.createCallback(f),s=S(o,e,t,n);return a(),s},e.primitive=i,e.identifier=function F(e,n){var o,t;l(!(t="function"==typeof e?(o=e,n):e)||"object"==typeof t,"Additional property arguments should be an object, register function should be omitted or a funtion");var r={identifier:!0,serializer:g.serializer,deserializer:function(e,t,i){g.deserializer(e,function(e,n){!function r(e,n,t){t.rootContext.resolve(t.modelSchema,e,t.target)}(n,i.target,i),o&&o(n,i.target,i),t(e,n)})}};return r=d(r,t)},e.date=function J(e){var n={serializer:function(e){return null===e||e===undefined?e:(l(e instanceof Date,"Expected Date object"),e.getTime())},deserializer:function(e,n){null!==e&&e!==undefined?n(null,new Date(e)):n(null,e)}};return n=d(n,e)},e.alias=function _(e,n){return l(e&&"string"==typeof e,"expected prop name as first argument"),l(p(n=n&&!0!==n?n:g),"expected prop schema as second argument"),l(!r(n),"provided prop is already aliased"),{jsonname:e,serializer:n.serializer,deserializer:n.deserializer,identifier:function t(e){return"object"==typeof e&&!0===e.identifier}(n),beforeDeserialize:n.beforeDeserialize,afterDeserialize:n.afterDeserialize}},e.custom=function q(e,i,o){l("function"==typeof e,"first argument should be function"),l("function"==typeof i,"second argument should be a function or promise");var n={serializer:e,deserializer:function(e,n,t,r){4===i.length?i(e,t,r,n,o):n(null,i(e,t,r,null,o))}};return n=d(n,o)},e.object=E,e.reference=A,e.list=O,e.map=function U(i,t){l(p(i=i||g),"expected prop schema as first argument"),l(!r(i),"provided prop is aliased, please put aliases first");var e={serializer:function(e){l(e&&"object"==typeof e,"expected object or Map");var n=c(e),t={};if(n)e.forEach(function(e,n){t[n]=i.serializer(e)});else for(var r in e)t[r]=i.serializer(e[r]);return t},deserializer:function(n,a,e,s){if(n&&"object"==typeof n){var f=Object.keys(n);O(i,t).deserializer(f.map(function(e){return n[e]}),function(e,n){if(e)a(e);else{var t,r=c(s);t=r?(s.clear(),s):{};for(var i=0,o=f.length;i<o;i++)r?t.set(f[i],n[i]):t[f[i]]=n[i];a(null,t)}},e)}else a("[serializr] expected JSON object")}};return e=d(e,t)},e.mapAsArray=function $(i,u,n){l(p(i=i||g),"expected prop schema as first argument"),l(!!u,"expected key property name as second argument");var e={serializer:function(e){l(e&&"object"==typeof e,"expected object or Map");var n=c(e),t=[];if(n)e.forEach(function(e){t.push(i.serializer(e))});else for(var r in e)t.push(i.serializer(e[r]));return t},deserializer:function(a,s,e,f){O(i,n).deserializer(a,function(e,n){if(e)s(e);else{var t,r=c(f);t=r?(f.clear(),f):{};for(var i=0,o=a.length;i<o;i++)r?t.set(n[i][u],n[i]):t[n[i][u].toString()]=n[i];s(null,t)}},e)}};return e=d(e,n)},e.raw=function B(e){var n={serializer:function(e){return e},deserializer:function(e,n){n(null,e)}};return n=d(n,e)},e.SKIP=y,e.child=E,e.ref=A,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=serializr.min.js.map
{
"name": "serializr",
"version": "1.3.0",
"version": "1.4.1",
"description": "Serialize and deserialize complex object graphs to JSON",

@@ -5,0 +5,0 @@ "main": "lib/serializr.js",

@@ -260,2 +260,3 @@ # Serializr

- `map(propSchema)`: Serializes an Map or string key based collection
- `mapAsArray(propSchema, keyPropertyName)`: Serializes a map to an array of elements
- `object(modelSchema)`: Serializes an child model element

@@ -293,2 +294,42 @@ - `reference(modelSchema, lookupFunction?)`: Serializes a reference to another model element

## AdditionalPropArgs
A PropSchema can be further parameterized using AdditionalPropArgs. Currently, they can be used to specify lifecycle functions. During deserialization they can be useful, e.g. in case you want to
- react to errors in the deserialization on a value level and retry with corrected value,
- remove invalid items e.g. in arrays or maps,
- react to changes in field names, e.g. due to schema migration (i.e. only one-directional changes that cannot be dealt with by alias operators).
It is possible to define those functions by passing them as additional property arguments to the propSchema during its creation.
```javascript
const myHandler = {
beforeDeserialize: function (callback, jsonValue, jsonParentValue, propNameOrIndex, context, propDef) {
if (typeof jsonValue === 'string') {
callback(null, jsonValue)
} else if (typeof jsonValue === 'number') {
callback(null, jsonValue.toString())
} else {
callback(new Error('something went wrong before deserialization'))
}
},
afterDeserialize: function (callback, error, newValue, jsonValue, jsonParentValue, propNameOrIndex, context,
propDef, numRetry) {
if (!error && newValue !== 'needs change') {
callback(null, newValue)
} else if (!error && newValue === 'needs change') {
callback(new Error(), 'changed value')
} else {
callback(error)
}
}
}
class MyData {
@serializable(primitive(myHandler)) mySimpleField
}
```
A more detailed example can be found in [test/typescript/ts.ts](test/typescript/ts.ts).
# API

@@ -300,3 +341,3 @@

[src/serializr.js:52-52](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/serializr.js#L52-L52 "Source code on GitHub")
[src/serializr.js:52-52](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/serializr.js#L52-L52 "Source code on GitHub")

@@ -310,7 +351,7 @@ JSDOC type defintions for usage w/o typescript.

- `value` **any**
- `writeable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `get` **([Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))**
- `set` **([Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))**
- `configurable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `enumerable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `writeable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `get` **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))**
- `set` **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))**
- `configurable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `enumerable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `sourcePropertyValue` **any**

@@ -326,3 +367,3 @@ - `jsonValue` **any**

- `error` **any**
- `id` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `callback` **cpsCallback**

@@ -337,3 +378,3 @@ - `factory`

- `deserializer` **deserializerFunction**
- `identifier` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
- `identifier` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

@@ -350,3 +391,3 @@ Returns **any** any - serialized object

[src/api/createSimpleSchema.js:17-24](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/api/createSimpleSchema.js#L17-L24 "Source code on GitHub")
[src/api/createSimpleSchema.js:17-24](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/api/createSimpleSchema.js#L17-L24 "Source code on GitHub")

@@ -376,3 +417,3 @@ Creates a model schema that (de)serializes from / to plain javascript objects.

[src/api/createModelSchema.js:29-47](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/api/createModelSchema.js#L29-L47 "Source code on GitHub")
[src/api/createModelSchema.js:29-47](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/api/createModelSchema.js#L29-L47 "Source code on GitHub")

@@ -385,5 +426,5 @@ Creates a model schema that (de)serializes an object created by a constructor function (class).

- `clazz` **([constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function
- `clazz` **([constructor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function
- `props` **[object](#object)** property mapping
- `factory` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** optional custom factory. Receives context as first arg
- `factory` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** optional custom factory. Receives context as first arg

@@ -411,3 +452,3 @@ **Examples**

[src/api/getDefaultModelSchema.js:9-18](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/api/getDefaultModelSchema.js#L9-L18 "Source code on GitHub")
[src/api/getDefaultModelSchema.js:9-18](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/api/getDefaultModelSchema.js#L9-L18 "Source code on GitHub")

@@ -424,3 +465,3 @@ Returns the standard model schema associated with a class / constructor function

[src/api/setDefaultModelSchema.js:15-18](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/api/setDefaultModelSchema.js#L15-L18 "Source code on GitHub")
[src/api/setDefaultModelSchema.js:15-18](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/api/setDefaultModelSchema.js#L15-L18 "Source code on GitHub")

@@ -436,3 +477,3 @@ Sets the default model schema for class / constructor function.

- `clazz` **([constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function
- `clazz` **([constructor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function
- `modelSchema` **[ModelSchema](#modelschema)** a model schema

@@ -444,3 +485,3 @@

[src/api/serializable.js:93-103](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/api/serializable.js#L93-L103 "Source code on GitHub")
[src/api/serializable.js:93-103](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/api/serializable.js#L93-L103 "Source code on GitHub")

@@ -469,3 +510,3 @@ Decorator that defines a new property mapping on the default model schema for the class

[src/core/serialize.js:16-34](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/core/serialize.js#L16-L34 "Source code on GitHub")
[src/core/serialize.js:16-34](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/core/serialize.js#L16-L34 "Source code on GitHub")

@@ -485,3 +526,3 @@ Serializes an object (graph) into json using the provided model schema.

[src/core/serialize.js:89-100](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/core/serialize.js#L89-L100 "Source code on GitHub")
[src/core/serialize.js:89-100](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/core/serialize.js#L89-L100 "Source code on GitHub")

@@ -494,7 +535,18 @@ The `serializeAll` decorator can be used on a class to signal that all primitive properties should be serialized automatically.

## cancelDeserialize
[src/core/cancelDeserialize.js:12-18](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/core/cancelDeserialize.js#L12-L18 "Source code on GitHub")
Cancels an asynchronous deserialization or update operation for the specified target object.
**Parameters**
- `instance` object that was previously returned from deserialize or update method
## deserialize
[src/core/deserialize.js:38-56](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/core/deserialize.js#L38-L56 "Source code on GitHub")
[src/core/deserialize.js:45-63](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/core/deserialize.js#L45-L63 "Source code on GitHub")
Deserializes a json structor into an object graph.
Deserializes a json structure into an object graph.
This process might be asynchronous (for example if there are references with an asynchronous

@@ -506,13 +558,16 @@ lookup function). The function returns an object (or array of objects), but the returned object

- `schema` **([object](#object) \| [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** to use for deserialization
- `json` **[json](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)** data to deserialize
- `callback` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** node style callback that is invoked once the deserializaiton has finished.
First argument is the optional error, second argument is the deserialized object (same as the return value)
- `customArgs` **any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
- `schema` **([object](#object) \| [array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** to use for deserialization
- `json` **[json](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON)** data to deserialize
- `callback` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** node style callback that is invoked once the deserialization has
finished. First argument is the optional error, second argument is the deserialized object
(same as the return value)
- `customArgs` **any** custom arguments that are available as `context.args` during the
deserialization process. This can be used as dependency injection mechanism to pass in, for
example, stores.
Returns **([object](#object) \| [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** deserialized object, possibly incomplete.
Returns **([object](#object) \| [array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** deserialized object, possibly incomplete.
## update
[src/core/update.js:21-42](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/core/update.js#L21-L42 "Source code on GitHub")
[src/core/update.js:22-44](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/core/update.js#L22-L44 "Source code on GitHub")

@@ -528,11 +583,17 @@ Similar to deserialize, but updates an existing object instance.

- `json` **[object](#object)** the json to deserialize
- `callback` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** the callback to invoke once deserialization has completed.
- `callback` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** the callback to invoke once deserialization has completed.
- `customArgs` **any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores.
Returns **([object](#object) \| [array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** deserialized object, possibly incomplete.
## primitive
[src/types/primitive.js:17-29](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/primitive.js#L17-L29 "Source code on GitHub")
[src/types/primitive.js:18-32](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/primitive.js#L18-L32 "Source code on GitHub")
Indicates that this field contains a primitive value (or Date) which should be serialized literally to json.
**Parameters**
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers
**Examples**

@@ -553,3 +614,3 @@

[src/types/identifier.js:42-56](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/identifier.js#L42-L56 "Source code on GitHub")
[src/types/identifier.js:43-66](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/identifier.js#L43-L66 "Source code on GitHub")

@@ -566,3 +627,4 @@ Similar to primitive, but this field will be marked as the identifier for the given Model type.

- `registerFn` **RegisterFunction** optional function to register this object during creation.
- `arg1` **(RegisterFunction | AdditionalPropArgs)** optional registerFn: function to register this object during creation.
- `arg2` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers

@@ -595,9 +657,15 @@ **Examples**

[src/types/date.js:8-23](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/date.js#L8-L23 "Source code on GitHub")
[src/types/date.js:9-26](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/date.js#L9-L26 "Source code on GitHub")
Similar to primitive, serializes instances of Date objects
**Parameters**
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers
Returns **PropSchema**
## alias
[src/types/alias.js:20-31](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/alias.js#L20-L31 "Source code on GitHub")
[src/types/alias.js:20-33](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/alias.js#L20-L33 "Source code on GitHub")

@@ -609,3 +677,3 @@ Alias indicates that this model property should be named differently in the generated json.

- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** name of the json field to be used for this property
- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** name of the json field to be used for this property
- `propSchema` **PropSchema** propSchema to (de)serialize the contents of this field

@@ -628,3 +696,3 @@

[src/types/custom.js:59-72](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/custom.js#L59-L72 "Source code on GitHub")
[src/types/custom.js:60-75](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/custom.js#L60-L75 "Source code on GitHub")

@@ -650,4 +718,5 @@ Can be used to create simple custom propSchema. Multiple things can be done inside of a custom propSchema, like deserializing and serializing other (polymorphic) objects, skipping the serialization of something or checking the context of the obj being (de)serialized.

- `serializer` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function that takes a model value and turns it into a json value
- `deserializer` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function that takes a json value and turns it into a model value. It also takes context argument, which can allow you to deserialize based on the context of other parameters.
- `serializer` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** function that takes a model value and turns it into a json value
- `deserializer` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** function that takes a json value and turns it into a model value. It also takes context argument, which can allow you to deserialize based on the context of other parameters.
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers

@@ -694,3 +763,3 @@ **Examples**

[src/types/object.js:34-52](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/object.js#L34-L52 "Source code on GitHub")
[src/types/object.js:35-55](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/object.js#L35-L55 "Source code on GitHub")

@@ -705,2 +774,3 @@ `object` indicates that this property contains an object that needs to be (de)serialized

- `modelSchema` **[ModelSchema](#modelschema)** to be used to (de)serialize the object
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers

@@ -733,3 +803,3 @@ **Examples**

[src/types/reference.js:65-98](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/reference.js#L65-L98 "Source code on GitHub")
[src/types/reference.js:66-105](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/reference.js#L66-L105 "Source code on GitHub")

@@ -756,3 +826,4 @@ `reference` can be used to (de)serialize references that point to other models.

- `target` : ModelSchema or string
- `lookupFn` **RefLookupFunction** function
- `lookupFn` **(RefLookupFunction | AdditionalPropArgs)** optional function or additionalArgs object
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers

@@ -799,3 +870,3 @@ **Examples**

[src/types/list.js:33-54](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/list.js#L33-L54 "Source code on GitHub")
[src/types/list.js:42-104](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/list.js#L42-L104 "Source code on GitHub")

@@ -808,2 +879,3 @@ List indicates that this property contains a list of things.

- `propSchema` **PropSchema** to be used to (de)serialize the contents of the array
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers

@@ -839,3 +911,3 @@ **Examples**

[src/types/map.js:13-62](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/map.js#L13-L62 "Source code on GitHub")
[src/types/map.js:14-65](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/map.js#L14-L65 "Source code on GitHub")

@@ -849,21 +921,29 @@ Similar to list, but map represents a string keyed dynamic collection.

- `propSchema` **any**
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers
Returns **PropSchema**
## mapAsArray
[src/types/mapAsArray.js:15-52](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/mapAsArray.js#L15-L52 "Source code on GitHub")
[src/types/mapAsArray.js:19-66](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/mapAsArray.js#L19-L66 "Source code on GitHub")
Similar to map, mapAsArray can be used to serialize a map-like collection where the key is contained in the 'value object'.
Example: consider Map&lt;id: number, customer: Customer> where the Customer object has the id stored on itself.
mapAsArray stores all values from the map into an array which is serialized.
Deserialization returns a ES6 Map or plain object object where the `keyPropertyName` of each object is used for keys.
For ES6 maps this has the benefit of being allowed to have non-string keys in the map. The serialized json also may be slightly more compact.
Similar to map, mapAsArray can be used to serialize a map-like collection where the key is
contained in the 'value object'. Example: consider Map&lt;id: number, customer: Customer> where the
Customer object has the id stored on itself. mapAsArray stores all values from the map into an
array which is serialized. Deserialization returns a ES6 Map or plain object object where the
`keyPropertyName` of each object is used for keys. For ES6 maps this has the benefit of being
allowed to have non-string keys in the map. The serialized json also may be slightly more
compact.
**Parameters**
- `propSchema` **any** , {string} keyPropertyName - the property of stored objects used as key in the map
- `keyPropertyName`
- `propSchema` **any**
- `keyPropertyName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the property of stored objects used as key in the map
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers
Returns **PropSchema**
## raw
[src/types/raw.js:15-24](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/types/raw.js#L15-L24 "Source code on GitHub")
[src/types/raw.js:18-29](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/types/raw.js#L18-L29 "Source code on GitHub")

@@ -873,2 +953,6 @@ Indicates that this field is only need to putted in the serialized json or

**Parameters**
- `additionalArgs` **AdditionalPropArgs** optional object that contains beforeDeserialize and/or afterDeserialize handlers
**Examples**

@@ -889,3 +973,3 @@

[src/constants.js:20-20](https://github.com/mobxjs/serializr/blob/b34674d96cb101c30739a497287d3c24ede31010/src/constants.js#L20-L20 "Source code on GitHub")
[src/constants.js:20-20](https://github.com/:mobxjs/serializr/blob/e46f7980d4a3db201ce7f75c9f3b235acdc7c61f/src/constants.js#L20-L20 "Source code on GitHub")

@@ -892,0 +976,0 @@ In the event that a property needs to be deserialized, but not serialized, you can use the SKIP symbol to omit the property. This has to be used with the custom serializer.

@@ -8,2 +8,4 @@ // TODO: put this in the source files, and extract it, to preserve comments

args: any;
await(modelschema: ClazzOrModelSchema<any>,id:string,callback?: (err: any, result: any) => void):any;
rootContext:Context;
}

@@ -13,5 +15,13 @@

export interface AdditionalPropArgs {
beforeDeserialize?: BeforeDeserializeFunc;
afterDeserialize?: AfterDeserializeFunc;
}
export interface PropSchema {
serializer(sourcePropertyValue: any): any;
deserializer(jsonValue: any, callback: (err: any, targetPropertyValue: any) => void, context: Context, currentPropertyValue: any): void;
beforeDeserialize: BeforeDeserializeFunc;
afterDeserialize: AfterDeserializeFunc;
}

@@ -31,2 +41,6 @@

export type AfterDeserializeFunc = (callback: (err: any, value: any) => void, err: any, newValue: any, jsonValue: any, jsonParentValue: any, propNameOrIndex: string | number, context: Context, propDef: PropSchema, numRetry: number) => void;
export type BeforeDeserializeFunc = (callback: (err: any, value: any) => void, jsonValue: any, jsonParentValue: any, propNameOrIndex: string | number, context: Context, propDef: PropSchema) => void;
export function createSimpleSchema<T extends Object>(props: Props): ModelSchema<T>;

@@ -46,2 +60,4 @@

export function cancelDeserialize<T>(instance: T): void;
export function deserialize<T>(modelschema: ClazzOrModelSchema<T>, jsonArray: any[], callback?: (err: any, result: T[]) => void, customArgs?: any): T[];

@@ -53,29 +69,32 @@ export function deserialize<T>(modelschema: ClazzOrModelSchema<T>, json: any, callback?: (err: any, result: T) => void, customArgs?: any): T;

export function primitive(): PropSchema;
export function primitive(additionalArgs?: AdditionalPropArgs): PropSchema;
export function identifier(registerFn?: (id: any, value: any, context: Context) => void): PropSchema;
export function identifier(registerFn?: (id: any, value: any, context: Context) => void, additionalArgs?: AdditionalPropArgs): PropSchema;
export function identifier(additionalArgs: AdditionalPropArgs): PropSchema;
export function date(): PropSchema;
export function date(additionalArgs?: AdditionalPropArgs): PropSchema;
export function alias(jsonName: string, propSchema?: PropSchema | boolean): PropSchema;
export function child(modelschema: ClazzOrModelSchema<any>): PropSchema;
export function object(modelschema: ClazzOrModelSchema<any>): PropSchema;
export function child(modelschema: ClazzOrModelSchema<any>, additionalArgs?: AdditionalPropArgs): PropSchema;
export function object(modelschema: ClazzOrModelSchema<any>, additionalArgs?: AdditionalPropArgs): PropSchema;
export type RefLookupFunction = (id: string, callback: (err: any, result: any) => void) => void;
export type RefLookupFunction = (id: string, callback: (err: any, result: any) => void,context:Context) => void;
export type RegisterFunction = (id: any, object: any, context: Context) => void;
export function ref(modelschema: ClazzOrModelSchema<any>, lookupFn?: RefLookupFunction): PropSchema;
export function ref(identifierAttr: string, lookupFn: RefLookupFunction): PropSchema;
export function reference(modelschema: ClazzOrModelSchema<any>, lookupFn?: RefLookupFunction): PropSchema;
export function reference(identifierAttr: string, lookupFn: RefLookupFunction): PropSchema;
export function ref(modelschema: ClazzOrModelSchema<any>, lookupFn?: RefLookupFunction, additionalArgs?: AdditionalPropArgs): PropSchema;
export function ref(modelschema: ClazzOrModelSchema<any>, additionalArgs?: AdditionalPropArgs): PropSchema;
export function ref(identifierAttr: string, lookupFn: RefLookupFunction, additionalArgs?: AdditionalPropArgs): PropSchema;
export function reference(modelschema: ClazzOrModelSchema<any>, lookupFn?: RefLookupFunction, additionalArgs?: AdditionalPropArgs): PropSchema;
export function reference(modelschema: ClazzOrModelSchema<any>, additionalArgs?: AdditionalPropArgs): PropSchema;
export function reference(identifierAttr: string, lookupFn: RefLookupFunction, additionalArgs?: AdditionalPropArgs): PropSchema;
export function list(propSchema: PropSchema): PropSchema;
export function list(propSchema: PropSchema, additionalArgs?: AdditionalPropArgs): PropSchema;
export function map(propSchema: PropSchema): PropSchema;
export function map(propSchema: PropSchema, additionalArgs?: AdditionalPropArgs): PropSchema;
export function mapAsArray(propSchema: PropSchema, keyPropertyName: string): PropSchema;
export function mapAsArray(propSchema: PropSchema, keyPropertyName: string, additionalArgs?: AdditionalPropArgs): PropSchema;
export function custom(serializer: (value: any) => any, deserializer: (jsonValue: any, context?: any, oldValue?: any) => any): PropSchema;
export function custom(serializer: (value: any) => any, deserializer: (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => any): PropSchema;
export function custom(serializer: (value: any) => any, deserializer: (jsonValue: any, context?: any, oldValue?: any) => any, additionalArgs?: AdditionalPropArgs): PropSchema;
export function custom(serializer: (value: any) => any, deserializer: (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => any, additionalArgs?: AdditionalPropArgs): PropSchema;

@@ -82,0 +101,0 @@ export function serializeAll<T extends Function>(clazz: T): T

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc