From 9592b136a0acd99f72bc93be91316c288ec81d86 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:03:37 -0800 Subject: [PATCH 01/67] Allows an object to receive deserializedSelf every time it is deserialized as the root of a serilization --- core/serialization/deserializer/montage-reviver.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index 969d05e16b..db7343bf92 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -502,7 +502,14 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont object = value && "prototype" in value ? Object.create(module.montageObject) : module.montageObject; context.setObjectLabel(object, label); - return this.instantiateMJSONObject(value, object, objectName, context, label); + + if(label === "root") { + return this.instantiateMontageObject(value, object, objectName, context, label); + } + else { + return this.instantiateMJSONObject(value, object, objectName, context, label); + } + } else { object = this.getMontageObject(value, module, objectName, context, label); context.setObjectLabel(object, label); From 63ccacf9a5c7a5ea2b9e24b3dd0dfc53c5946c53 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:04:59 -0800 Subject: [PATCH 02/67] Creates a new root class for converters dedicated to be used in expression data mappings --- .../expression-data-mapping-converter.js | 373 ++++++++++++++++++ .../raw-property-value-to-object-converter.js | 313 +-------------- 2 files changed, 386 insertions(+), 300 deletions(-) create mode 100644 data/converter/expression-data-mapping-converter.js diff --git a/data/converter/expression-data-mapping-converter.js b/data/converter/expression-data-mapping-converter.js new file mode 100644 index 0000000000..7b1ae24f0b --- /dev/null +++ b/data/converter/expression-data-mapping-converter.js @@ -0,0 +1,373 @@ +var Converter = require("core/converter/converter").Converter, + Criteria = require("core/criteria").Criteria, + DataQuery = require("data/model/data-query").DataQuery, + ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, + Promise = require("core/promise").Promise, + Scope = require("frb/scope"), + parse = require("frb/parse"), + compile = require("frb/compile-evaluator"); + +/** + * @class ExpressionDataMappingConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends Converter + */ +exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends ExpressionDataMappingConverter# */ { + +/* + converter.expression = converter.expression || rule.expression; + converter.foreignDescriptor = converter.foreignDescriptor || propertyDescriptor.valueDescriptor; + converter.objectDescriptor = this.objectDescriptor; + converter.serviceIdentifier = rule.serviceIdentifier; + +*/ + + + /********************************************************************* + * Serialization + */ + + serializeSelf: { + value: function (serializer) { + + serializer.setProperty("convertExpression", this.convertExpression); + + serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); + + serializer.setProperty("revertExpression", this.revertExpression); + + serializer.setProperty("root", this.owner); + + serializer.setProperty("serviceIdentifier", this.serviceIdentifier); + serializer.setProperty("service", this.service); + + } + }, + + deserializeSelf: { + value: function (deserializer) { + var value = deserializer.getProperty("convertExpression"); + if (value) { + this.convertExpression = value; + } + + value = deserializer.getProperty("revertExpression"); + if (value) { + this.revertExpression = value; + } + + value = deserializer.getProperty("foreignDescriptor"); + if (value instanceof ObjectDescriptorReference) { + this._foreignDescriptorReference = value; + } else if (value) { + this.foreignDescriptor = value; + } + + value = deserializer.getProperty("service"); + if (value) { + this.service = value; + } + + value = deserializer.getObjectByLabel("root"); + if (value) { + this.owner = value; + } + + value = deserializer.getProperty("serviceIdentifier"); + if (value) { + this.serviceIdentifier = value; + } + + deserializer.deserializeUnit("bindings"); + } + }, + + /********************************************************************* + * Initialization + */ + + /** + * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. + * @return itself + */ + initWithConvertExpression: { + value: function (convertExpression) { + this.convertExpression = convertExpression; + return this; + } + }, + + /********************************************************************* + * Properties + */ + + + _convertExpression: { + value: null + }, + + /** + * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. + * @type {string} + * */ + convertExpression: { + get: function() { + return this._convertExpression; + }, + set: function(value) { + if(value !== this._convertExpression) { + this._convertExpression = value; + this._convertSyntax = undefined; + } + } + }, + + _convertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .convertExpression using frb/grammar.js that will + * be used to initialize the convert query criteria + * @type {Object} + * */ + + convertSyntax: { + get: function() { + return this._convertSyntax || (this._convertSyntax === undefined + ? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null + : null); + } + }, + + _revertExpression: { + value: null + }, + + /** + * The expression used to revert the modeled value into a raw one. For example, + * reverting an object into it's primary key. + * @type {string} + * */ + revertExpression: { + get: function() { + return this._revertExpression; + }, + set: function(value) { + if(value !== this._revertExpression) { + this._revertExpression = value; + this._revertSyntax = undefined; + } + } + }, + + _revertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .revertExpression using frb/grammar.js that will + * be used to revert the modeled value into a raw one + * @type {Object} + * */ + revertSyntax: { + get: function() { + return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); + } + }, + + _compiledRevertSyntax: { + value: undefined + }, + + compiledRevertSyntax: { + get: function () { + return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); + } + }, + + + /** + * The descriptor of the destination object. If one is not provided, + * .objectDescriptor will be used. If .objectDescriptor is not provided, + * the value descriptor of the property descriptor that defines the + * relationship will be used. + * @type {?ObjectDescriptorReference} + * */ + foreignDescriptor: { + serializable: false, + get: function () { + var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; + return isReference ? this._foreignDescriptor : + this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : + this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); + }, + set: function (descriptor) { + this._foreignDescriptor = descriptor; + } + }, + + /** + * The descriptor of the source object. It will be used only if it is provided and + * .foreignDescriptor is not provided. + * @type {?ObjectDescriptorReference} + **/ + objectDescriptor: { + get: function () { + return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : + this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : + this._isAsync(this.owner) ? this._objectDescriptorReference : + undefined; + }, + set: function (value) { + this._objectDescriptor = value; + } + }, + + _objectDescriptorReference: { + get: function () { + var self = this; + return this.owner.then(function (object) { + var objectDescriptor = object.objectDescriptor; + self.objectDescriptor = objectDescriptor; + return objectDescriptor; + }); + } + }, + + _isAsync: { + value: function (object) { + return object && object.then && typeof object.then === "function"; + } + }, + + + /** + * The descriptor for which to perform the fetch. + * This returns foreignDescriptor, if it exists, and otherwise + * returns objectDescriptor. + * @type {?ObjectDescriptorReference} + **/ + _descriptorToFetch: { + get: function () { + if (!this.__descriptorToFetch) { + if (this.foreignDescriptor && this.foreignDescriptor.promise) { + this.__descriptorToFetch = this.foreignDescriptor.promise(require); + } else if (this.foreignDescriptor) { + this.__descriptorToFetch = this.foreignDescriptor; + } else { + this.__descriptorToFetch = this.objectDescriptor; + } + } + return this.__descriptorToFetch; + + // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { + // return descriptor || self.objectDescriptor; + // }) : Promise.resolve(this.objectDescriptor); + // return this.foreignDescriptor || this.objectDescriptor; + } + }, + + owner: { + get: function () { + return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; + }, + set: function (value) { + this._owner = value; + } + }, + + __scope: { + value: null + }, + + /** + * Scope with which convert and revert expressions are evaluated. + * @type {?Scope} + **/ + scope: { + get: function() { + return this.__scope || (this.__scope = new Scope(this)); + } + }, + + /** + * The service to use to make requests. + */ + service: { + get: function () { + return this._service ? this._service : + this.owner ? this.owner.then(function (object) { return object.service; }) : + undefined; + }, + set: function (value) { + this._service = !value || value.then ? value : Promise.resolve(value); + } + }, + + /** + * Identifier of the child of .service that the query should be routed to + */ + serviceIdentifier: { + value: undefined + }, + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + criteria = new Criteria().initWithSyntax(self.convertSyntax, v), + query; + + return this._descriptorToFetch.then(function (typeToFetch) { + var type = [typeToFetch.module.id, typeToFetch.name].join("/"); + + if (self.serviceIdentifier) { + criteria.parameters.serviceIdentifier = self.serviceIdentifier; + } + + query = DataQuery.withTypeAndCriteria(type, criteria); + + return self.service ? self.service.then(function (service) { + return service.rootService.fetchData(query); + }) : null; + }); + } + }, + + + + /** + * Reverts the relationship back to raw data. + * @function + * @param {Scope} v The value to revert. + * @returns {string} v + */ + revert: { + value: function (v) { + if (v) { + if (!this.compiledRevertSyntax) { + return Promise.resolve(v); + } else { + var scope = this.scope; + //Parameter is what is accessed as $ in expressions + scope.value = v; + return Promise.resolve(this.compiledRevertSyntax(scope)); + } + + } + return Promise.resolve(undefined); + } + } + +}); diff --git a/data/converter/raw-property-value-to-object-converter.js b/data/converter/raw-property-value-to-object-converter.js index 69ecc3f352..e6fa40252c 100644 --- a/data/converter/raw-property-value-to-object-converter.js +++ b/data/converter/raw-property-value-to-object-converter.js @@ -1,4 +1,4 @@ -var Converter = require("core/converter/converter").Converter, +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, Criteria = require("core/criteria").Criteria, DataQuery = require("data/model/data-query").DataQuery, ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, @@ -10,302 +10,15 @@ var Converter = require("core/converter/converter").Converter, /** * @class RawPropertyValueToObjectConverter * @classdesc Converts a property value of raw data to the referenced object. - * @extends Converter + * @extends ExpressionDataMappingConverter */ -exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - - - /********************************************************************* - * Serialization - */ - - serializeSelf: { - value: function (serializer) { - - serializer.setProperty("convertExpression", this.convertExpression); - - serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); - - serializer.setProperty("revertExpression", this.revertExpression); - - serializer.setProperty("root", this.owner); - - serializer.setProperty("serviceIdentifier", this.serviceIdentifier); - serializer.setProperty("service", this.service); - - } - }, - - deserializeSelf: { - value: function (deserializer) { - var value = deserializer.getProperty("convertExpression"); - if (value) { - this.convertExpression = value; - } - - value = deserializer.getProperty("revertExpression"); - if (value) { - this.revertExpression = value; - } - - value = deserializer.getProperty("foreignDescriptor"); - if (value instanceof ObjectDescriptorReference) { - this._foreignDescriptorReference = value; - } else if (value) { - this.foreignDescriptor = value; - } - - value = deserializer.getProperty("service"); - if (value) { - this.service = value; - } - - value = deserializer.getObjectByLabel("root"); - if (value) { - this.owner = value; - } - - value = deserializer.getProperty("serviceIdentifier"); - if (value) { - this.serviceIdentifier = value; - } - - deserializer.deserializeUnit("bindings"); - } - }, - - /********************************************************************* - * Initialization - */ - - /** - * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. - * @return itself - */ - initWithConvertExpression: { - value: function (convertExpression) { - this.convertExpression = convertExpression; - return this; - } - }, - - /********************************************************************* - * Properties - */ - - - _convertExpression: { - value: null - }, - - /** - * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. - * @type {string} - * */ - convertExpression: { - get: function() { - return this._convertExpression; - }, - set: function(value) { - if(value !== this._convertExpression) { - this._convertExpression = value; - this._convertSyntax = undefined; - } - } - }, - - _convertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .convertExpression using frb/grammar.js that will - * be used to initialize the convert query criteria - * @type {Object} - * */ - - convertSyntax: { - get: function() { - return this._convertSyntax || (this._convertSyntax = parse(this.convertExpression)); - } - }, - - _revertExpression: { - value: null - }, - - /** - * The expression used to revert the modeled value into a raw one. For example, - * reverting an object into it's primary key. - * @type {string} - * */ - revertExpression: { - get: function() { - return this._revertExpression; - }, - set: function(value) { - if(value !== this._revertExpression) { - this._revertExpression = value; - this._revertSyntax = undefined; - } - } - }, - - _revertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .revertExpression using frb/grammar.js that will - * be used to revert the modeled value into a raw one - * @type {Object} - * */ - revertSyntax: { - get: function() { - return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); - } - }, - - _compiledRevertSyntax: { - value: undefined - }, - - compiledRevertSyntax: { - get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); - } - }, +exports.RawPropertyValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - /** - * The descriptor of the destination object. If one is not provided, - * .objectDescriptor will be used. If .objectDescriptor is not provided, - * the value descriptor of the property descriptor that defines the - * relationship will be used. - * @type {?ObjectDescriptorReference} - * */ - foreignDescriptor: { - serializable: false, - get: function () { - var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; - return isReference ? this._foreignDescriptor : - this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : - this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); - }, - set: function (descriptor) { - this._foreignDescriptor = descriptor; - } - }, - - /** - * The descriptor of the source object. It will be used only if it is provided and - * .foreignDescriptor is not provided. - * @type {?ObjectDescriptorReference} - **/ - objectDescriptor: { - get: function () { - return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : - this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : - this._isAsync(this.owner) ? this._objectDescriptorReference : - undefined; - }, - set: function (value) { - this._objectDescriptor = value; - } - }, - - _objectDescriptorReference: { - get: function () { - var self = this; - return this.owner.then(function (object) { - var objectDescriptor = object.objectDescriptor; - self.objectDescriptor = objectDescriptor; - return objectDescriptor; - }); - } - }, - - _isAsync: { - value: function (object) { - return object && object.then && typeof object.then === "function"; - } - }, - - - /** - * The descriptor for which to perform the fetch. - * This returns foreignDescriptor, if it exists, and otherwise - * returns objectDescriptor. - * @type {?ObjectDescriptorReference} - **/ - _descriptorToFetch: { - get: function () { - if (!this.__descriptorToFetch) { - if (this.foreignDescriptor && this.foreignDescriptor.promise) { - this.__descriptorToFetch = this.foreignDescriptor.promise(require); - } else if (this.foreignDescriptor) { - this.__descriptorToFetch = this.foreignDescriptor; - } else { - this.__descriptorToFetch = this.objectDescriptor; - } - } - return this.__descriptorToFetch; - - // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { - // return descriptor || self.objectDescriptor; - // }) : Promise.resolve(this.objectDescriptor); - // return this.foreignDescriptor || this.objectDescriptor; - } - }, - - owner: { - get: function () { - return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; - }, - set: function (value) { - this._owner = value; - } - }, - - __scope: { - value: null - }, - - /** - * Scope with which convert and revert expressions are evaluated. - * @type {?Scope} - **/ - scope: { - get: function() { - return this.__scope || (this.__scope = new Scope(this)); - } - }, - - /** - * The service to use to make requests. - */ - service: { - get: function () { - return this._service ? this._service : - this.owner ? this.owner.then(function (object) { return object.service; }) : - undefined; - }, - set: function (value) { - this._service = !value || value.then ? value : Promise.resolve(value); - } - }, - - /** - * Identifier of the child of .service that the query should be routed to - */ - serviceIdentifier: { - value: undefined - }, - /********************************************************************* * Public API */ - + /** * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. * @function @@ -318,25 +31,25 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw var self = this, criteria = new Criteria().initWithSyntax(self.convertSyntax, v), query; - + return this._descriptorToFetch.then(function (typeToFetch) { var type = [typeToFetch.module.id, typeToFetch.name].join("/"); - + if (self.serviceIdentifier) { criteria.parameters.serviceIdentifier = self.serviceIdentifier; } - + query = DataQuery.withTypeAndCriteria(type, criteria); - + return self.service ? self.service.then(function (service) { return service.rootService.fetchData(query); }) : null; }); } }, - - - + + + /** * Reverts the relationship back to raw data. * @function @@ -354,10 +67,10 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw scope.value = v; return Promise.resolve(this.compiledRevertSyntax(scope)); } - + } return Promise.resolve(undefined); } } - + }); From 8a2bd2428b7cd3f1bf24f64992ff34afbb182f45 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:08:55 -0800 Subject: [PATCH 03/67] - _addChildService can be called several times without side effects - adds a future-proof way to get a type's prototype & constructor --- data/service/data-service.js | 45 +++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index c645b2fa35..623eda18aa 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -91,7 +91,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (value !== undefined) { this.isUniquing = value; } - + return result; } }, @@ -272,16 +272,21 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { _addChildService: { value: function (child, types) { var children, type, i, n, nIfEmpty = 1; - types = types || child.model && child.model.objectDescriptors || child.types; + types = types || child.model && child.model.objectDescriptors || child.types, + isNotParentService = (child._parentService !== this); // If the new child service already has a parent, remove it from // that parent. - if (child._parentService) { + // Adding more test to allow a service to register types in multiple + // calls, which can happen if the service is deserilized multiple times + if (child._parentService && isNotParentService) { child._parentService.removeChildService(child); } // Add the new child to this service's children set. - this.childServices.add(child); - this._childServicesByIdentifier.set(child.identifier, child); + if(isNotParentService) { + this.childServices.add(child); + this._childServicesByIdentifier.set(child.identifier, child); + } // Add the new child service to the services array of each of its // types or to the "all types" service array identified by the // `null` type, and add each of the new child's types to the array @@ -290,12 +295,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { for (i = 0, n = types && types.length || nIfEmpty; i < n; i += 1) { type = types && types.length && types[i] || null; children = this._childServicesByType.get(type) || []; - children.push(child); - if (children.length === 1) { - this._childServicesByType.set(type, children); - if (type) { - this._childServiceTypes.push(type); + + //Checking in case this is called multiple times + if(children.indexOf(child) === -1 ) { + children.push(child); + if (children.length === 1) { + this._childServicesByType.set(type, children); + if (type) { + this._childServiceTypes.push(type); + } } + } } // Set the new child service's parent. @@ -963,12 +973,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { */ _getPrototypeForType: { value: function (type) { - var info, triggers, prototype; + var info, triggers, prototypeToExtend, prototype; type = this._objectDescriptorForType(type); prototype = this._dataObjectPrototypes.get(type); if (type && !prototype) { - prototype = Object.create(type.objectPrototype || Montage.prototype); - prototype.constuctor = type.objectPrototype.constructor; + //type.objectPrototype is legacy and should be depreated over time + prototypeToExtend = type.objectPrototype || Object.getPrototypeOf(type.module) || Montage.prototype; + prototype = Object.create(prototypeToExtend); + prototype.constuctor = type.objectPrototype + ? type.objectPrototype.constructor + : type.module; + if(prototype.constuctor.name === "constructor" ) { Object.defineProperty(prototype.constuctor, "name", { value: type.typeName }); } @@ -1324,6 +1339,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (mapping) { + //Why aren't we passing this.snapshotForObject(object) instead of copying everying in a new empty object? Object.assign(data, this.snapshotForObject(object)); result = mapping.mapObjectToCriteriaSourceForProperty(object, data, propertyName); if (this._isAsync(result)) { @@ -1332,6 +1348,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return mapping.mapRawDataToObjectProperty(data, object, propertyName); }); } else { + //This was already done a few lines up. Why are we re-doing this? Object.assign(data, self.snapshotForObject(object)); result = mapping.mapRawDataToObjectProperty(data, object, propertyName); if (!this._isAsync(result)) { @@ -1938,7 +1955,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return promise; } }, - + /** * Save changes made to a data object. * From 6191519d04c6ddc178d5dd50c843478d8bcda89b Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:09:33 -0800 Subject: [PATCH 04/67] Adds a new converter to create embedded full objects of the right type --- .../raw-embedded-value-to-object-converter.js | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 data/converter/raw-embedded-value-to-object-converter.js diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js new file mode 100644 index 0000000000..0d6ccc9f67 --- /dev/null +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -0,0 +1,121 @@ +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, +Criteria = require("core/criteria").Criteria, +DataQuery = require("data/model/data-query").DataQuery, +ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, +Promise = require("core/promise").Promise, +Scope = require("frb/scope"), +parse = require("frb/parse"), +compile = require("frb/compile-evaluator"); + +/** + * @class RawEmbeddedRelationshipValueToObjectConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends ExpressionDataMappingConverter + */ +exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { + + /********************************************************************* + * Properties + */ + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + convertedValue, + result, + criteria = this.convertSyntax + ? new Criteria().initWithSyntax(self.convertSyntax, v) + : null, + query; + + + + return Promise.all([this._descriptorToFetch, this.service]).then(function (values) { + var typeToFetch = values[0], + service = values[1]; + + if(Array.isArray(v)) { + if(v.length) { + convertedValue = []; + for(var i=0, countI=v.length, promises;(i Date: Sun, 10 Feb 2019 18:03:37 -0800 Subject: [PATCH 05/67] Allows an object to receive deserializedSelf every time it is deserialized as the root of a serilization --- core/serialization/deserializer/montage-reviver.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index 969d05e16b..db7343bf92 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -502,7 +502,14 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont object = value && "prototype" in value ? Object.create(module.montageObject) : module.montageObject; context.setObjectLabel(object, label); - return this.instantiateMJSONObject(value, object, objectName, context, label); + + if(label === "root") { + return this.instantiateMontageObject(value, object, objectName, context, label); + } + else { + return this.instantiateMJSONObject(value, object, objectName, context, label); + } + } else { object = this.getMontageObject(value, module, objectName, context, label); context.setObjectLabel(object, label); From de359b45cf74869069f4f818c30750ed368d4634 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:04:59 -0800 Subject: [PATCH 06/67] Creates a new root class for converters dedicated to be used in expression data mappings --- .../expression-data-mapping-converter.js | 373 ++++++++++++++++++ .../raw-property-value-to-object-converter.js | 313 +-------------- 2 files changed, 386 insertions(+), 300 deletions(-) create mode 100644 data/converter/expression-data-mapping-converter.js diff --git a/data/converter/expression-data-mapping-converter.js b/data/converter/expression-data-mapping-converter.js new file mode 100644 index 0000000000..7b1ae24f0b --- /dev/null +++ b/data/converter/expression-data-mapping-converter.js @@ -0,0 +1,373 @@ +var Converter = require("core/converter/converter").Converter, + Criteria = require("core/criteria").Criteria, + DataQuery = require("data/model/data-query").DataQuery, + ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, + Promise = require("core/promise").Promise, + Scope = require("frb/scope"), + parse = require("frb/parse"), + compile = require("frb/compile-evaluator"); + +/** + * @class ExpressionDataMappingConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends Converter + */ +exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends ExpressionDataMappingConverter# */ { + +/* + converter.expression = converter.expression || rule.expression; + converter.foreignDescriptor = converter.foreignDescriptor || propertyDescriptor.valueDescriptor; + converter.objectDescriptor = this.objectDescriptor; + converter.serviceIdentifier = rule.serviceIdentifier; + +*/ + + + /********************************************************************* + * Serialization + */ + + serializeSelf: { + value: function (serializer) { + + serializer.setProperty("convertExpression", this.convertExpression); + + serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); + + serializer.setProperty("revertExpression", this.revertExpression); + + serializer.setProperty("root", this.owner); + + serializer.setProperty("serviceIdentifier", this.serviceIdentifier); + serializer.setProperty("service", this.service); + + } + }, + + deserializeSelf: { + value: function (deserializer) { + var value = deserializer.getProperty("convertExpression"); + if (value) { + this.convertExpression = value; + } + + value = deserializer.getProperty("revertExpression"); + if (value) { + this.revertExpression = value; + } + + value = deserializer.getProperty("foreignDescriptor"); + if (value instanceof ObjectDescriptorReference) { + this._foreignDescriptorReference = value; + } else if (value) { + this.foreignDescriptor = value; + } + + value = deserializer.getProperty("service"); + if (value) { + this.service = value; + } + + value = deserializer.getObjectByLabel("root"); + if (value) { + this.owner = value; + } + + value = deserializer.getProperty("serviceIdentifier"); + if (value) { + this.serviceIdentifier = value; + } + + deserializer.deserializeUnit("bindings"); + } + }, + + /********************************************************************* + * Initialization + */ + + /** + * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. + * @return itself + */ + initWithConvertExpression: { + value: function (convertExpression) { + this.convertExpression = convertExpression; + return this; + } + }, + + /********************************************************************* + * Properties + */ + + + _convertExpression: { + value: null + }, + + /** + * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. + * @type {string} + * */ + convertExpression: { + get: function() { + return this._convertExpression; + }, + set: function(value) { + if(value !== this._convertExpression) { + this._convertExpression = value; + this._convertSyntax = undefined; + } + } + }, + + _convertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .convertExpression using frb/grammar.js that will + * be used to initialize the convert query criteria + * @type {Object} + * */ + + convertSyntax: { + get: function() { + return this._convertSyntax || (this._convertSyntax === undefined + ? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null + : null); + } + }, + + _revertExpression: { + value: null + }, + + /** + * The expression used to revert the modeled value into a raw one. For example, + * reverting an object into it's primary key. + * @type {string} + * */ + revertExpression: { + get: function() { + return this._revertExpression; + }, + set: function(value) { + if(value !== this._revertExpression) { + this._revertExpression = value; + this._revertSyntax = undefined; + } + } + }, + + _revertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .revertExpression using frb/grammar.js that will + * be used to revert the modeled value into a raw one + * @type {Object} + * */ + revertSyntax: { + get: function() { + return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); + } + }, + + _compiledRevertSyntax: { + value: undefined + }, + + compiledRevertSyntax: { + get: function () { + return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); + } + }, + + + /** + * The descriptor of the destination object. If one is not provided, + * .objectDescriptor will be used. If .objectDescriptor is not provided, + * the value descriptor of the property descriptor that defines the + * relationship will be used. + * @type {?ObjectDescriptorReference} + * */ + foreignDescriptor: { + serializable: false, + get: function () { + var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; + return isReference ? this._foreignDescriptor : + this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : + this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); + }, + set: function (descriptor) { + this._foreignDescriptor = descriptor; + } + }, + + /** + * The descriptor of the source object. It will be used only if it is provided and + * .foreignDescriptor is not provided. + * @type {?ObjectDescriptorReference} + **/ + objectDescriptor: { + get: function () { + return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : + this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : + this._isAsync(this.owner) ? this._objectDescriptorReference : + undefined; + }, + set: function (value) { + this._objectDescriptor = value; + } + }, + + _objectDescriptorReference: { + get: function () { + var self = this; + return this.owner.then(function (object) { + var objectDescriptor = object.objectDescriptor; + self.objectDescriptor = objectDescriptor; + return objectDescriptor; + }); + } + }, + + _isAsync: { + value: function (object) { + return object && object.then && typeof object.then === "function"; + } + }, + + + /** + * The descriptor for which to perform the fetch. + * This returns foreignDescriptor, if it exists, and otherwise + * returns objectDescriptor. + * @type {?ObjectDescriptorReference} + **/ + _descriptorToFetch: { + get: function () { + if (!this.__descriptorToFetch) { + if (this.foreignDescriptor && this.foreignDescriptor.promise) { + this.__descriptorToFetch = this.foreignDescriptor.promise(require); + } else if (this.foreignDescriptor) { + this.__descriptorToFetch = this.foreignDescriptor; + } else { + this.__descriptorToFetch = this.objectDescriptor; + } + } + return this.__descriptorToFetch; + + // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { + // return descriptor || self.objectDescriptor; + // }) : Promise.resolve(this.objectDescriptor); + // return this.foreignDescriptor || this.objectDescriptor; + } + }, + + owner: { + get: function () { + return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; + }, + set: function (value) { + this._owner = value; + } + }, + + __scope: { + value: null + }, + + /** + * Scope with which convert and revert expressions are evaluated. + * @type {?Scope} + **/ + scope: { + get: function() { + return this.__scope || (this.__scope = new Scope(this)); + } + }, + + /** + * The service to use to make requests. + */ + service: { + get: function () { + return this._service ? this._service : + this.owner ? this.owner.then(function (object) { return object.service; }) : + undefined; + }, + set: function (value) { + this._service = !value || value.then ? value : Promise.resolve(value); + } + }, + + /** + * Identifier of the child of .service that the query should be routed to + */ + serviceIdentifier: { + value: undefined + }, + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + criteria = new Criteria().initWithSyntax(self.convertSyntax, v), + query; + + return this._descriptorToFetch.then(function (typeToFetch) { + var type = [typeToFetch.module.id, typeToFetch.name].join("/"); + + if (self.serviceIdentifier) { + criteria.parameters.serviceIdentifier = self.serviceIdentifier; + } + + query = DataQuery.withTypeAndCriteria(type, criteria); + + return self.service ? self.service.then(function (service) { + return service.rootService.fetchData(query); + }) : null; + }); + } + }, + + + + /** + * Reverts the relationship back to raw data. + * @function + * @param {Scope} v The value to revert. + * @returns {string} v + */ + revert: { + value: function (v) { + if (v) { + if (!this.compiledRevertSyntax) { + return Promise.resolve(v); + } else { + var scope = this.scope; + //Parameter is what is accessed as $ in expressions + scope.value = v; + return Promise.resolve(this.compiledRevertSyntax(scope)); + } + + } + return Promise.resolve(undefined); + } + } + +}); diff --git a/data/converter/raw-property-value-to-object-converter.js b/data/converter/raw-property-value-to-object-converter.js index 69ecc3f352..e6fa40252c 100644 --- a/data/converter/raw-property-value-to-object-converter.js +++ b/data/converter/raw-property-value-to-object-converter.js @@ -1,4 +1,4 @@ -var Converter = require("core/converter/converter").Converter, +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, Criteria = require("core/criteria").Criteria, DataQuery = require("data/model/data-query").DataQuery, ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, @@ -10,302 +10,15 @@ var Converter = require("core/converter/converter").Converter, /** * @class RawPropertyValueToObjectConverter * @classdesc Converts a property value of raw data to the referenced object. - * @extends Converter + * @extends ExpressionDataMappingConverter */ -exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - - - /********************************************************************* - * Serialization - */ - - serializeSelf: { - value: function (serializer) { - - serializer.setProperty("convertExpression", this.convertExpression); - - serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); - - serializer.setProperty("revertExpression", this.revertExpression); - - serializer.setProperty("root", this.owner); - - serializer.setProperty("serviceIdentifier", this.serviceIdentifier); - serializer.setProperty("service", this.service); - - } - }, - - deserializeSelf: { - value: function (deserializer) { - var value = deserializer.getProperty("convertExpression"); - if (value) { - this.convertExpression = value; - } - - value = deserializer.getProperty("revertExpression"); - if (value) { - this.revertExpression = value; - } - - value = deserializer.getProperty("foreignDescriptor"); - if (value instanceof ObjectDescriptorReference) { - this._foreignDescriptorReference = value; - } else if (value) { - this.foreignDescriptor = value; - } - - value = deserializer.getProperty("service"); - if (value) { - this.service = value; - } - - value = deserializer.getObjectByLabel("root"); - if (value) { - this.owner = value; - } - - value = deserializer.getProperty("serviceIdentifier"); - if (value) { - this.serviceIdentifier = value; - } - - deserializer.deserializeUnit("bindings"); - } - }, - - /********************************************************************* - * Initialization - */ - - /** - * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. - * @return itself - */ - initWithConvertExpression: { - value: function (convertExpression) { - this.convertExpression = convertExpression; - return this; - } - }, - - /********************************************************************* - * Properties - */ - - - _convertExpression: { - value: null - }, - - /** - * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. - * @type {string} - * */ - convertExpression: { - get: function() { - return this._convertExpression; - }, - set: function(value) { - if(value !== this._convertExpression) { - this._convertExpression = value; - this._convertSyntax = undefined; - } - } - }, - - _convertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .convertExpression using frb/grammar.js that will - * be used to initialize the convert query criteria - * @type {Object} - * */ - - convertSyntax: { - get: function() { - return this._convertSyntax || (this._convertSyntax = parse(this.convertExpression)); - } - }, - - _revertExpression: { - value: null - }, - - /** - * The expression used to revert the modeled value into a raw one. For example, - * reverting an object into it's primary key. - * @type {string} - * */ - revertExpression: { - get: function() { - return this._revertExpression; - }, - set: function(value) { - if(value !== this._revertExpression) { - this._revertExpression = value; - this._revertSyntax = undefined; - } - } - }, - - _revertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .revertExpression using frb/grammar.js that will - * be used to revert the modeled value into a raw one - * @type {Object} - * */ - revertSyntax: { - get: function() { - return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); - } - }, - - _compiledRevertSyntax: { - value: undefined - }, - - compiledRevertSyntax: { - get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); - } - }, +exports.RawPropertyValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - /** - * The descriptor of the destination object. If one is not provided, - * .objectDescriptor will be used. If .objectDescriptor is not provided, - * the value descriptor of the property descriptor that defines the - * relationship will be used. - * @type {?ObjectDescriptorReference} - * */ - foreignDescriptor: { - serializable: false, - get: function () { - var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; - return isReference ? this._foreignDescriptor : - this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : - this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); - }, - set: function (descriptor) { - this._foreignDescriptor = descriptor; - } - }, - - /** - * The descriptor of the source object. It will be used only if it is provided and - * .foreignDescriptor is not provided. - * @type {?ObjectDescriptorReference} - **/ - objectDescriptor: { - get: function () { - return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : - this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : - this._isAsync(this.owner) ? this._objectDescriptorReference : - undefined; - }, - set: function (value) { - this._objectDescriptor = value; - } - }, - - _objectDescriptorReference: { - get: function () { - var self = this; - return this.owner.then(function (object) { - var objectDescriptor = object.objectDescriptor; - self.objectDescriptor = objectDescriptor; - return objectDescriptor; - }); - } - }, - - _isAsync: { - value: function (object) { - return object && object.then && typeof object.then === "function"; - } - }, - - - /** - * The descriptor for which to perform the fetch. - * This returns foreignDescriptor, if it exists, and otherwise - * returns objectDescriptor. - * @type {?ObjectDescriptorReference} - **/ - _descriptorToFetch: { - get: function () { - if (!this.__descriptorToFetch) { - if (this.foreignDescriptor && this.foreignDescriptor.promise) { - this.__descriptorToFetch = this.foreignDescriptor.promise(require); - } else if (this.foreignDescriptor) { - this.__descriptorToFetch = this.foreignDescriptor; - } else { - this.__descriptorToFetch = this.objectDescriptor; - } - } - return this.__descriptorToFetch; - - // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { - // return descriptor || self.objectDescriptor; - // }) : Promise.resolve(this.objectDescriptor); - // return this.foreignDescriptor || this.objectDescriptor; - } - }, - - owner: { - get: function () { - return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; - }, - set: function (value) { - this._owner = value; - } - }, - - __scope: { - value: null - }, - - /** - * Scope with which convert and revert expressions are evaluated. - * @type {?Scope} - **/ - scope: { - get: function() { - return this.__scope || (this.__scope = new Scope(this)); - } - }, - - /** - * The service to use to make requests. - */ - service: { - get: function () { - return this._service ? this._service : - this.owner ? this.owner.then(function (object) { return object.service; }) : - undefined; - }, - set: function (value) { - this._service = !value || value.then ? value : Promise.resolve(value); - } - }, - - /** - * Identifier of the child of .service that the query should be routed to - */ - serviceIdentifier: { - value: undefined - }, - /********************************************************************* * Public API */ - + /** * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. * @function @@ -318,25 +31,25 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw var self = this, criteria = new Criteria().initWithSyntax(self.convertSyntax, v), query; - + return this._descriptorToFetch.then(function (typeToFetch) { var type = [typeToFetch.module.id, typeToFetch.name].join("/"); - + if (self.serviceIdentifier) { criteria.parameters.serviceIdentifier = self.serviceIdentifier; } - + query = DataQuery.withTypeAndCriteria(type, criteria); - + return self.service ? self.service.then(function (service) { return service.rootService.fetchData(query); }) : null; }); } }, - - - + + + /** * Reverts the relationship back to raw data. * @function @@ -354,10 +67,10 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw scope.value = v; return Promise.resolve(this.compiledRevertSyntax(scope)); } - + } return Promise.resolve(undefined); } } - + }); From bafd719428a8b50baa2709a2f8333cc2a081bbbf Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:08:55 -0800 Subject: [PATCH 07/67] - _addChildService can be called several times without side effects - adds a future-proof way to get a type's prototype & constructor --- data/service/data-service.js | 45 +++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index c645b2fa35..623eda18aa 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -91,7 +91,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (value !== undefined) { this.isUniquing = value; } - + return result; } }, @@ -272,16 +272,21 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { _addChildService: { value: function (child, types) { var children, type, i, n, nIfEmpty = 1; - types = types || child.model && child.model.objectDescriptors || child.types; + types = types || child.model && child.model.objectDescriptors || child.types, + isNotParentService = (child._parentService !== this); // If the new child service already has a parent, remove it from // that parent. - if (child._parentService) { + // Adding more test to allow a service to register types in multiple + // calls, which can happen if the service is deserilized multiple times + if (child._parentService && isNotParentService) { child._parentService.removeChildService(child); } // Add the new child to this service's children set. - this.childServices.add(child); - this._childServicesByIdentifier.set(child.identifier, child); + if(isNotParentService) { + this.childServices.add(child); + this._childServicesByIdentifier.set(child.identifier, child); + } // Add the new child service to the services array of each of its // types or to the "all types" service array identified by the // `null` type, and add each of the new child's types to the array @@ -290,12 +295,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { for (i = 0, n = types && types.length || nIfEmpty; i < n; i += 1) { type = types && types.length && types[i] || null; children = this._childServicesByType.get(type) || []; - children.push(child); - if (children.length === 1) { - this._childServicesByType.set(type, children); - if (type) { - this._childServiceTypes.push(type); + + //Checking in case this is called multiple times + if(children.indexOf(child) === -1 ) { + children.push(child); + if (children.length === 1) { + this._childServicesByType.set(type, children); + if (type) { + this._childServiceTypes.push(type); + } } + } } // Set the new child service's parent. @@ -963,12 +973,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { */ _getPrototypeForType: { value: function (type) { - var info, triggers, prototype; + var info, triggers, prototypeToExtend, prototype; type = this._objectDescriptorForType(type); prototype = this._dataObjectPrototypes.get(type); if (type && !prototype) { - prototype = Object.create(type.objectPrototype || Montage.prototype); - prototype.constuctor = type.objectPrototype.constructor; + //type.objectPrototype is legacy and should be depreated over time + prototypeToExtend = type.objectPrototype || Object.getPrototypeOf(type.module) || Montage.prototype; + prototype = Object.create(prototypeToExtend); + prototype.constuctor = type.objectPrototype + ? type.objectPrototype.constructor + : type.module; + if(prototype.constuctor.name === "constructor" ) { Object.defineProperty(prototype.constuctor, "name", { value: type.typeName }); } @@ -1324,6 +1339,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (mapping) { + //Why aren't we passing this.snapshotForObject(object) instead of copying everying in a new empty object? Object.assign(data, this.snapshotForObject(object)); result = mapping.mapObjectToCriteriaSourceForProperty(object, data, propertyName); if (this._isAsync(result)) { @@ -1332,6 +1348,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return mapping.mapRawDataToObjectProperty(data, object, propertyName); }); } else { + //This was already done a few lines up. Why are we re-doing this? Object.assign(data, self.snapshotForObject(object)); result = mapping.mapRawDataToObjectProperty(data, object, propertyName); if (!this._isAsync(result)) { @@ -1938,7 +1955,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return promise; } }, - + /** * Save changes made to a data object. * From 63fe0253caacf7fe84e071f452afbd0c04d39588 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:09:33 -0800 Subject: [PATCH 08/67] Adds a new converter to create embedded full objects of the right type --- .../raw-embedded-value-to-object-converter.js | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 data/converter/raw-embedded-value-to-object-converter.js diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js new file mode 100644 index 0000000000..0d6ccc9f67 --- /dev/null +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -0,0 +1,121 @@ +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, +Criteria = require("core/criteria").Criteria, +DataQuery = require("data/model/data-query").DataQuery, +ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, +Promise = require("core/promise").Promise, +Scope = require("frb/scope"), +parse = require("frb/parse"), +compile = require("frb/compile-evaluator"); + +/** + * @class RawEmbeddedRelationshipValueToObjectConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends ExpressionDataMappingConverter + */ +exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { + + /********************************************************************* + * Properties + */ + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + convertedValue, + result, + criteria = this.convertSyntax + ? new Criteria().initWithSyntax(self.convertSyntax, v) + : null, + query; + + + + return Promise.all([this._descriptorToFetch, this.service]).then(function (values) { + var typeToFetch = values[0], + service = values[1]; + + if(Array.isArray(v)) { + if(v.length) { + convertedValue = []; + for(var i=0, countI=v.length, promises;(i Date: Mon, 11 Feb 2019 23:36:45 -0800 Subject: [PATCH 09/67] - Makes revertSyntax, compiledRevertSyntax more robust to undefimed revertExpression --- data/converter/expression-data-mapping-converter.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/data/converter/expression-data-mapping-converter.js b/data/converter/expression-data-mapping-converter.js index 7b1ae24f0b..dc39ff424d 100644 --- a/data/converter/expression-data-mapping-converter.js +++ b/data/converter/expression-data-mapping-converter.js @@ -172,7 +172,9 @@ exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends Expres * */ revertSyntax: { get: function() { - return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); + return this._revertSyntax || (this._revertSyntax === undefined + ? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) : null + : null); } }, @@ -182,7 +184,10 @@ exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends Expres compiledRevertSyntax: { get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); + + return this._compiledRevertSyntax || (this._compiledRevertSyntax === undefined + ? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) : null + : null); } }, From 57c776605417ef5abaee0cdab16ef4a0a1216794 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 11 Feb 2019 23:47:51 -0800 Subject: [PATCH 10/67] adds resolveObjectForTypeRawData method to asynchronously retrieve a fully mapped object --- data/service/raw-data-service.js | 53 +++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/data/service/raw-data-service.js b/data/service/raw-data-service.js index 696549f3c1..ef9a4e285d 100644 --- a/data/service/raw-data-service.js +++ b/data/service/raw-data-service.js @@ -435,6 +435,12 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot } this._addMapDataPromiseForStream(result, stream); + + //TO-DO: #warning + //This method should evolve to use resolveObjectForTypeRawData instead, + //however resolveObjectForTypeRawData's promises resolves to object + //only after it's been mapped, so this delegate call should only be called then + //and not too early as it is now. Not sure if that may create a backward compatibility issue if (object) { this.callDelegateMethod("rawDataServiceDidAddOneRawData", this, stream, rawData, object); } @@ -461,10 +467,55 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot } }, + /** + * Called by [addRawData()]{@link RawDataService#addRawData} to add an object + * for the passed record to the stream. This method both takes care of doing + * mapRawDataToObject and add the object to the stream. + * + * @method + * @argument {ObjectDescriptor} type + * - The type of the data object matching rawData. + * @argument {Object} rawData - An anonymnous object whose properties' + * values hold the raw data. + * @argument {?} context - An arbitrary value that will be passed to + * [getDataObject()]{@link RawDataService#getDataObject} + * and + * [mapRawDataToObject()]{@link RawDataService#mapRawDataToObject} + * if it is provided. + * + * @returns {Promise} - A promise resolving to the mapped object. + * + */ + + resolveObjectForTypeRawData: { + value:function(type, rawData, context) { + var dataIdentifier = this.dataIdentifierForTypeRawData(type,rawData), + //Retrieves an existing object is responsible data service is uniquing, or creates one + object, result; + + //Record snapshot before we may create an object + this.recordSnapshot(dataIdentifier, rawData); + + //Retrieves an existing object is responsible data service is uniquing, or creates one + object = this.getDataObject(type, rawData, context, dataIdentifier), + + result = this._mapRawDataToObject(rawData, object, context); + + if (Promise.is(result)) { + return result.then(function () { + return object; + }); + } else { + return Promise.resolve(object); + } + } + }, + + objectForTypeRawData: { value:function(type, rawData, context) { var dataIdentifier = this.dataIdentifierForTypeRawData(type,rawData); - //Record snapshot before we may create an object + //Record snapshot before we may create an object this.recordSnapshot(dataIdentifier, rawData); //iDataIdentifier argument should be all we need later on return this.getDataObject(type, rawData, context, dataIdentifier); From 62563b012fd779acafd465febbc8a40bf81d6636 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 11 Feb 2019 23:53:32 -0800 Subject: [PATCH 11/67] - fixes bugs --- data/converter/raw-embedded-value-to-object-converter.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js index 0d6ccc9f67..21d3cdb411 100644 --- a/data/converter/raw-embedded-value-to-object-converter.js +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -73,13 +73,10 @@ exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.speci _convertOneValue: { value: function (v, typeToFetch, service, valueArray, index) { - var dataIdentifier = service.dataIdentifierForTypeRawData(typeToFetch, v), - dataServiceForType = service.rootService.childServiceForType(typeToFetch); - dataObject = service.rootService.getDataObject(typeToFetch, v, /* context */ undefined, dataIdentifier), - result = dataServiceForType.mapRawDataToObject(v,dataObject); + var result = service.resolveObjectForTypeRawData(typeToFetch, v); if (result) { - result = result.then(function () { + result = result.then(function (dataObject) { if(valueArray) { //Wondering if we need to do this in a property-change compatible way, //[] direct modification of an Array doesn't send property-changes @@ -89,7 +86,7 @@ exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.speci }); } else { - result = dataObject; + result = Promise.resolve(undefined); } return result; } From b3b1f4bb66e2fce0972a534f40defcf1fcd207f6 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 17:47:18 -0800 Subject: [PATCH 12/67] Bootstrap scripts from main app package If they can't be loaded from the app package, they will be retried under mr (npm 2 / legacy bundling support). --- montage.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/montage.js b/montage.js index a3dc057a98..ef1866c63a 100644 --- a/montage.js +++ b/montage.js @@ -91,12 +91,19 @@ } }, - load: function (location,loadCallback) { + load: function (location, callback) { var script = document.createElement("script"); script.src = location; script.onload = function () { - if(loadCallback) { - loadCallback(script); + if (callback) { + callback(null, script); + } + // remove clutter + script.parentNode.removeChild(script); + }; + script.onerror = function () { + if (callback) { + callback(new Error("Can't load script " + JSON.stringify(location)), script); } // remove clutter script.parentNode.removeChild(script); @@ -253,13 +260,28 @@ allModulesLoaded(); }; + var montageLocation; + function loadModuleScript(path, callback) { + montageLocation = montageLocation || resolve(global.location, params.montageLocation); + // try loading script relative to app first (npm 3+) + browser.load(resolve(global.location, path), function (err, script) { + if (err) { + // if that fails, the app may have been installed with + // npm 2 or with --legacy-bundling, in which case the + // script will be under montage's node_modules + browser.load(resolve(montageLocation, path), callback); + } else if (callback) { + callback(null, script); + } + }); + } + // load in parallel, but only if we're not using a preloaded cache. // otherwise, these scripts will be inlined after already if (typeof global.BUNDLE === "undefined") { - var montageLocation = resolve(global.location, params.montageLocation); - //Special Case bluebird for now: - browser.load(resolve(montageLocation, pending.promise), function() { + // Special Case bluebird for now: + loadModuleScript(pending.promise, function () { delete pending.promise; //global.bootstrap cleans itself from global once all known are loaded. "bluebird" is not known, so needs to do it first @@ -272,7 +294,7 @@ for (var module in pending) { if (pending.hasOwnProperty(module)) { - browser.load(resolve(montageLocation, pending[module])); + loadModuleScript(pending[module]); } } }); From 620b8116d52d889a0da8260c5415a019a888edc7 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 17:54:14 -0800 Subject: [PATCH 13/67] Use mr#feature/npm3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df66264f8f..1ece62516f 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "frb": "~4.0.x", "htmlparser2": "~3.0.5", "q-io": "^1.13.3", - "mr": "^17.0.11", + "mr": "montagejs/mr#feature/npm3", "weak-map": "^1.0.5", "lodash.kebabcase": "^4.1.1", "lodash.camelcase": "^4.3.0", From 10c74d5f915cb9c4d682c41d653a2dcc3c58cddc Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 18:17:20 -0800 Subject: [PATCH 14/67] Fix bad mainPackageLocation in getMontageDeserializer --- node.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/node.js b/node.js index ad6c0cec6c..1b93bc16dd 100644 --- a/node.js +++ b/node.js @@ -72,12 +72,11 @@ function getMontageMontageDeserializer() { return getMontageMontageDeserializer._promise; } - return (getMontageMontageDeserializer._promise = MontageBoot.loadPackage( - PATH.join(__dirname, "."), {mainPackageLocation: PATH.join(__dirname, "../")}) + return (getMontageMontageDeserializer._promise = MontageBoot.loadPackage(PATH.join(__dirname, ".")) .then(function (mr) { return mr.async("./core/serialization/deserializer/montage-deserializer") .then(function (MontageDeserializerModule) { - return (MontageBoot.MontageDeserializer = + return (MontageBoot.MontageDeserializer = MontageDeserializerModule.MontageDeserializer ); }); From 75be71f5a0e658b2cd9f5a83b8e124a560230839 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 18:19:14 -0800 Subject: [PATCH 15/67] Enable node 6, 8, 10 in travis --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a235b44877..ecb8610af1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: node_js node_js: - - "4" + - 4 + - 6 + - 8 + - 10 script: npm run $COMMAND env: - COMMAND=test From f8dd5df7cc89ede9af57242f4ff43beebbfffd63 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 21:29:45 -0800 Subject: [PATCH 16/67] Remove legacy bundling option from travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ecb8610af1..3d66f41028 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ env: #- COMMAND=integration MONTAGE_VERSION=. MOP_VERSION=latest - COMMAND=integration MONTAGE_VERSION=. MOP_VERSION="#master" before_install: - - "npm set legacy-bundling=true" - export CHROME_BIN=chromium-browser - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start From c2323d9f02513f3802a394bb372f0036449afd08 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Wed, 30 Jan 2019 21:30:18 -0800 Subject: [PATCH 17/67] Run integration with mop#feature/npm3 --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d66f41028..01a610b3e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,7 @@ script: npm run $COMMAND env: - COMMAND=test - COMMAND=test:karma-travis - #- COMMAND=integration MONTAGE_VERSION=. MOP_VERSION=latest - - COMMAND=integration MONTAGE_VERSION=. MOP_VERSION="#master" + - COMMAND=integration MONTAGE_VERSION=. MOP_VERSION="#feature/npm3" before_install: - export CHROME_BIN=chromium-browser - export DISPLAY=:99.0 From 13305c99dee5fe3cfe031ce77774d870ae78eda8 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Thu, 31 Jan 2019 14:03:57 -0800 Subject: [PATCH 18/67] Remove useless bluebird injection code I suspect this code only exists for historical reasons, but it seems totally unnecessary, as bluebird will already be cached in the registry and will not be loaded twice. The hardcoded bluebird path causes an extra 404 when loading the app with npm 3+. --- montage.js | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/montage.js b/montage.js index ef1866c63a..1f2cf7a5a9 100644 --- a/montage.js +++ b/montage.js @@ -799,34 +799,8 @@ hash: params.montageHash }) .then(function (montageRequire) { - // load the promise package so we can inject the bootstrapped - // promise library back into it - var promiseLocation; - if (params.promiseLocation) { - promiseLocation = URL.resolve(Require.getLocation(), params.promiseLocation); - } else { - //promiseLocation = URL.resolve(montageLocation, "packages/mr/packages/q"); - //node tools/build --features="core timers call_get" --browser - promiseLocation = URL.resolve(montageLocation, "node_modules/bluebird"); - } - - var result = [ - montageRequire, - montageRequire.loadPackage({ - location: promiseLocation, - hash: params.promiseHash - }) - ]; - - return result; - }) - .spread(function (montageRequire, promiseRequire) { montageRequire.inject("core/mini-url", URL); montageRequire.inject("core/promise", {Promise: Promise}); - promiseRequire.inject("bluebird", Promise); - - // This prevents bluebird to be loaded twice by mousse's code - promiseRequire.inject("js/browser/bluebird", Promise); // install the linter, which loads on the first error config.lint = function (module) { From 099766bcc3c31155df9dc093783d09ee7f816b03 Mon Sep 17 00:00:00 2001 From: Corentin Debost Date: Thu, 7 Feb 2019 08:35:54 -0800 Subject: [PATCH 19/67] Bump version to 18.0.0-rc1 --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1ece62516f..b4a579469f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "montage", - "version": "17.2.1", + "version": "18.0.0-rc1", "description": "Build your next application with a browser based platform that really gets the web.", "license": "BSD-3-Clause", "repository": { @@ -9,8 +9,8 @@ }, "main": "montage", "engines": { - "node": "<=4.9.1", - "npm": "<=2.15.11" + "node": ">=4", + "npm": ">=2" }, "overlay": { "browser": { @@ -53,7 +53,7 @@ "frb": "~4.0.x", "htmlparser2": "~3.0.5", "q-io": "^1.13.3", - "mr": "montagejs/mr#feature/npm3", + "mr": "18.0.0-rc1", "weak-map": "^1.0.5", "lodash.kebabcase": "^4.1.1", "lodash.camelcase": "^4.3.0", From 19d947cb57c73d5948fdb3cc6e49d9b277875c1e Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:03:37 -0800 Subject: [PATCH 20/67] Allows an object to receive deserializedSelf every time it is deserialized as the root of a serilization --- core/serialization/deserializer/montage-reviver.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index 969d05e16b..db7343bf92 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -502,7 +502,14 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont object = value && "prototype" in value ? Object.create(module.montageObject) : module.montageObject; context.setObjectLabel(object, label); - return this.instantiateMJSONObject(value, object, objectName, context, label); + + if(label === "root") { + return this.instantiateMontageObject(value, object, objectName, context, label); + } + else { + return this.instantiateMJSONObject(value, object, objectName, context, label); + } + } else { object = this.getMontageObject(value, module, objectName, context, label); context.setObjectLabel(object, label); From e582eace1e7b78fa870a3b40d9ce046f51e5f47a Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:04:59 -0800 Subject: [PATCH 21/67] Creates a new root class for converters dedicated to be used in expression data mappings --- .../expression-data-mapping-converter.js | 373 ++++++++++++++++++ .../raw-property-value-to-object-converter.js | 313 +-------------- 2 files changed, 386 insertions(+), 300 deletions(-) create mode 100644 data/converter/expression-data-mapping-converter.js diff --git a/data/converter/expression-data-mapping-converter.js b/data/converter/expression-data-mapping-converter.js new file mode 100644 index 0000000000..7b1ae24f0b --- /dev/null +++ b/data/converter/expression-data-mapping-converter.js @@ -0,0 +1,373 @@ +var Converter = require("core/converter/converter").Converter, + Criteria = require("core/criteria").Criteria, + DataQuery = require("data/model/data-query").DataQuery, + ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, + Promise = require("core/promise").Promise, + Scope = require("frb/scope"), + parse = require("frb/parse"), + compile = require("frb/compile-evaluator"); + +/** + * @class ExpressionDataMappingConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends Converter + */ +exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends ExpressionDataMappingConverter# */ { + +/* + converter.expression = converter.expression || rule.expression; + converter.foreignDescriptor = converter.foreignDescriptor || propertyDescriptor.valueDescriptor; + converter.objectDescriptor = this.objectDescriptor; + converter.serviceIdentifier = rule.serviceIdentifier; + +*/ + + + /********************************************************************* + * Serialization + */ + + serializeSelf: { + value: function (serializer) { + + serializer.setProperty("convertExpression", this.convertExpression); + + serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); + + serializer.setProperty("revertExpression", this.revertExpression); + + serializer.setProperty("root", this.owner); + + serializer.setProperty("serviceIdentifier", this.serviceIdentifier); + serializer.setProperty("service", this.service); + + } + }, + + deserializeSelf: { + value: function (deserializer) { + var value = deserializer.getProperty("convertExpression"); + if (value) { + this.convertExpression = value; + } + + value = deserializer.getProperty("revertExpression"); + if (value) { + this.revertExpression = value; + } + + value = deserializer.getProperty("foreignDescriptor"); + if (value instanceof ObjectDescriptorReference) { + this._foreignDescriptorReference = value; + } else if (value) { + this.foreignDescriptor = value; + } + + value = deserializer.getProperty("service"); + if (value) { + this.service = value; + } + + value = deserializer.getObjectByLabel("root"); + if (value) { + this.owner = value; + } + + value = deserializer.getProperty("serviceIdentifier"); + if (value) { + this.serviceIdentifier = value; + } + + deserializer.deserializeUnit("bindings"); + } + }, + + /********************************************************************* + * Initialization + */ + + /** + * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. + * @return itself + */ + initWithConvertExpression: { + value: function (convertExpression) { + this.convertExpression = convertExpression; + return this; + } + }, + + /********************************************************************* + * Properties + */ + + + _convertExpression: { + value: null + }, + + /** + * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. + * @type {string} + * */ + convertExpression: { + get: function() { + return this._convertExpression; + }, + set: function(value) { + if(value !== this._convertExpression) { + this._convertExpression = value; + this._convertSyntax = undefined; + } + } + }, + + _convertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .convertExpression using frb/grammar.js that will + * be used to initialize the convert query criteria + * @type {Object} + * */ + + convertSyntax: { + get: function() { + return this._convertSyntax || (this._convertSyntax === undefined + ? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null + : null); + } + }, + + _revertExpression: { + value: null + }, + + /** + * The expression used to revert the modeled value into a raw one. For example, + * reverting an object into it's primary key. + * @type {string} + * */ + revertExpression: { + get: function() { + return this._revertExpression; + }, + set: function(value) { + if(value !== this._revertExpression) { + this._revertExpression = value; + this._revertSyntax = undefined; + } + } + }, + + _revertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .revertExpression using frb/grammar.js that will + * be used to revert the modeled value into a raw one + * @type {Object} + * */ + revertSyntax: { + get: function() { + return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); + } + }, + + _compiledRevertSyntax: { + value: undefined + }, + + compiledRevertSyntax: { + get: function () { + return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); + } + }, + + + /** + * The descriptor of the destination object. If one is not provided, + * .objectDescriptor will be used. If .objectDescriptor is not provided, + * the value descriptor of the property descriptor that defines the + * relationship will be used. + * @type {?ObjectDescriptorReference} + * */ + foreignDescriptor: { + serializable: false, + get: function () { + var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; + return isReference ? this._foreignDescriptor : + this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : + this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); + }, + set: function (descriptor) { + this._foreignDescriptor = descriptor; + } + }, + + /** + * The descriptor of the source object. It will be used only if it is provided and + * .foreignDescriptor is not provided. + * @type {?ObjectDescriptorReference} + **/ + objectDescriptor: { + get: function () { + return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : + this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : + this._isAsync(this.owner) ? this._objectDescriptorReference : + undefined; + }, + set: function (value) { + this._objectDescriptor = value; + } + }, + + _objectDescriptorReference: { + get: function () { + var self = this; + return this.owner.then(function (object) { + var objectDescriptor = object.objectDescriptor; + self.objectDescriptor = objectDescriptor; + return objectDescriptor; + }); + } + }, + + _isAsync: { + value: function (object) { + return object && object.then && typeof object.then === "function"; + } + }, + + + /** + * The descriptor for which to perform the fetch. + * This returns foreignDescriptor, if it exists, and otherwise + * returns objectDescriptor. + * @type {?ObjectDescriptorReference} + **/ + _descriptorToFetch: { + get: function () { + if (!this.__descriptorToFetch) { + if (this.foreignDescriptor && this.foreignDescriptor.promise) { + this.__descriptorToFetch = this.foreignDescriptor.promise(require); + } else if (this.foreignDescriptor) { + this.__descriptorToFetch = this.foreignDescriptor; + } else { + this.__descriptorToFetch = this.objectDescriptor; + } + } + return this.__descriptorToFetch; + + // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { + // return descriptor || self.objectDescriptor; + // }) : Promise.resolve(this.objectDescriptor); + // return this.foreignDescriptor || this.objectDescriptor; + } + }, + + owner: { + get: function () { + return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; + }, + set: function (value) { + this._owner = value; + } + }, + + __scope: { + value: null + }, + + /** + * Scope with which convert and revert expressions are evaluated. + * @type {?Scope} + **/ + scope: { + get: function() { + return this.__scope || (this.__scope = new Scope(this)); + } + }, + + /** + * The service to use to make requests. + */ + service: { + get: function () { + return this._service ? this._service : + this.owner ? this.owner.then(function (object) { return object.service; }) : + undefined; + }, + set: function (value) { + this._service = !value || value.then ? value : Promise.resolve(value); + } + }, + + /** + * Identifier of the child of .service that the query should be routed to + */ + serviceIdentifier: { + value: undefined + }, + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + criteria = new Criteria().initWithSyntax(self.convertSyntax, v), + query; + + return this._descriptorToFetch.then(function (typeToFetch) { + var type = [typeToFetch.module.id, typeToFetch.name].join("/"); + + if (self.serviceIdentifier) { + criteria.parameters.serviceIdentifier = self.serviceIdentifier; + } + + query = DataQuery.withTypeAndCriteria(type, criteria); + + return self.service ? self.service.then(function (service) { + return service.rootService.fetchData(query); + }) : null; + }); + } + }, + + + + /** + * Reverts the relationship back to raw data. + * @function + * @param {Scope} v The value to revert. + * @returns {string} v + */ + revert: { + value: function (v) { + if (v) { + if (!this.compiledRevertSyntax) { + return Promise.resolve(v); + } else { + var scope = this.scope; + //Parameter is what is accessed as $ in expressions + scope.value = v; + return Promise.resolve(this.compiledRevertSyntax(scope)); + } + + } + return Promise.resolve(undefined); + } + } + +}); diff --git a/data/converter/raw-property-value-to-object-converter.js b/data/converter/raw-property-value-to-object-converter.js index 69ecc3f352..e6fa40252c 100644 --- a/data/converter/raw-property-value-to-object-converter.js +++ b/data/converter/raw-property-value-to-object-converter.js @@ -1,4 +1,4 @@ -var Converter = require("core/converter/converter").Converter, +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, Criteria = require("core/criteria").Criteria, DataQuery = require("data/model/data-query").DataQuery, ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, @@ -10,302 +10,15 @@ var Converter = require("core/converter/converter").Converter, /** * @class RawPropertyValueToObjectConverter * @classdesc Converts a property value of raw data to the referenced object. - * @extends Converter + * @extends ExpressionDataMappingConverter */ -exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - - - /********************************************************************* - * Serialization - */ - - serializeSelf: { - value: function (serializer) { - - serializer.setProperty("convertExpression", this.convertExpression); - - serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); - - serializer.setProperty("revertExpression", this.revertExpression); - - serializer.setProperty("root", this.owner); - - serializer.setProperty("serviceIdentifier", this.serviceIdentifier); - serializer.setProperty("service", this.service); - - } - }, - - deserializeSelf: { - value: function (deserializer) { - var value = deserializer.getProperty("convertExpression"); - if (value) { - this.convertExpression = value; - } - - value = deserializer.getProperty("revertExpression"); - if (value) { - this.revertExpression = value; - } - - value = deserializer.getProperty("foreignDescriptor"); - if (value instanceof ObjectDescriptorReference) { - this._foreignDescriptorReference = value; - } else if (value) { - this.foreignDescriptor = value; - } - - value = deserializer.getProperty("service"); - if (value) { - this.service = value; - } - - value = deserializer.getObjectByLabel("root"); - if (value) { - this.owner = value; - } - - value = deserializer.getProperty("serviceIdentifier"); - if (value) { - this.serviceIdentifier = value; - } - - deserializer.deserializeUnit("bindings"); - } - }, - - /********************************************************************* - * Initialization - */ - - /** - * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. - * @return itself - */ - initWithConvertExpression: { - value: function (convertExpression) { - this.convertExpression = convertExpression; - return this; - } - }, - - /********************************************************************* - * Properties - */ - - - _convertExpression: { - value: null - }, - - /** - * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. - * @type {string} - * */ - convertExpression: { - get: function() { - return this._convertExpression; - }, - set: function(value) { - if(value !== this._convertExpression) { - this._convertExpression = value; - this._convertSyntax = undefined; - } - } - }, - - _convertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .convertExpression using frb/grammar.js that will - * be used to initialize the convert query criteria - * @type {Object} - * */ - - convertSyntax: { - get: function() { - return this._convertSyntax || (this._convertSyntax = parse(this.convertExpression)); - } - }, - - _revertExpression: { - value: null - }, - - /** - * The expression used to revert the modeled value into a raw one. For example, - * reverting an object into it's primary key. - * @type {string} - * */ - revertExpression: { - get: function() { - return this._revertExpression; - }, - set: function(value) { - if(value !== this._revertExpression) { - this._revertExpression = value; - this._revertSyntax = undefined; - } - } - }, - - _revertSyntax: { - value: undefined - }, - - /** - * Object created by parsing .revertExpression using frb/grammar.js that will - * be used to revert the modeled value into a raw one - * @type {Object} - * */ - revertSyntax: { - get: function() { - return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); - } - }, - - _compiledRevertSyntax: { - value: undefined - }, - - compiledRevertSyntax: { - get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); - } - }, +exports.RawPropertyValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - /** - * The descriptor of the destination object. If one is not provided, - * .objectDescriptor will be used. If .objectDescriptor is not provided, - * the value descriptor of the property descriptor that defines the - * relationship will be used. - * @type {?ObjectDescriptorReference} - * */ - foreignDescriptor: { - serializable: false, - get: function () { - var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; - return isReference ? this._foreignDescriptor : - this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : - this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); - }, - set: function (descriptor) { - this._foreignDescriptor = descriptor; - } - }, - - /** - * The descriptor of the source object. It will be used only if it is provided and - * .foreignDescriptor is not provided. - * @type {?ObjectDescriptorReference} - **/ - objectDescriptor: { - get: function () { - return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : - this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : - this._isAsync(this.owner) ? this._objectDescriptorReference : - undefined; - }, - set: function (value) { - this._objectDescriptor = value; - } - }, - - _objectDescriptorReference: { - get: function () { - var self = this; - return this.owner.then(function (object) { - var objectDescriptor = object.objectDescriptor; - self.objectDescriptor = objectDescriptor; - return objectDescriptor; - }); - } - }, - - _isAsync: { - value: function (object) { - return object && object.then && typeof object.then === "function"; - } - }, - - - /** - * The descriptor for which to perform the fetch. - * This returns foreignDescriptor, if it exists, and otherwise - * returns objectDescriptor. - * @type {?ObjectDescriptorReference} - **/ - _descriptorToFetch: { - get: function () { - if (!this.__descriptorToFetch) { - if (this.foreignDescriptor && this.foreignDescriptor.promise) { - this.__descriptorToFetch = this.foreignDescriptor.promise(require); - } else if (this.foreignDescriptor) { - this.__descriptorToFetch = this.foreignDescriptor; - } else { - this.__descriptorToFetch = this.objectDescriptor; - } - } - return this.__descriptorToFetch; - - // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { - // return descriptor || self.objectDescriptor; - // }) : Promise.resolve(this.objectDescriptor); - // return this.foreignDescriptor || this.objectDescriptor; - } - }, - - owner: { - get: function () { - return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; - }, - set: function (value) { - this._owner = value; - } - }, - - __scope: { - value: null - }, - - /** - * Scope with which convert and revert expressions are evaluated. - * @type {?Scope} - **/ - scope: { - get: function() { - return this.__scope || (this.__scope = new Scope(this)); - } - }, - - /** - * The service to use to make requests. - */ - service: { - get: function () { - return this._service ? this._service : - this.owner ? this.owner.then(function (object) { return object.service; }) : - undefined; - }, - set: function (value) { - this._service = !value || value.then ? value : Promise.resolve(value); - } - }, - - /** - * Identifier of the child of .service that the query should be routed to - */ - serviceIdentifier: { - value: undefined - }, - /********************************************************************* * Public API */ - + /** * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. * @function @@ -318,25 +31,25 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw var self = this, criteria = new Criteria().initWithSyntax(self.convertSyntax, v), query; - + return this._descriptorToFetch.then(function (typeToFetch) { var type = [typeToFetch.module.id, typeToFetch.name].join("/"); - + if (self.serviceIdentifier) { criteria.parameters.serviceIdentifier = self.serviceIdentifier; } - + query = DataQuery.withTypeAndCriteria(type, criteria); - + return self.service ? self.service.then(function (service) { return service.rootService.fetchData(query); }) : null; }); } }, - - - + + + /** * Reverts the relationship back to raw data. * @function @@ -354,10 +67,10 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw scope.value = v; return Promise.resolve(this.compiledRevertSyntax(scope)); } - + } return Promise.resolve(undefined); } } - + }); From 023d207744f997cd76d5020567200553b232c892 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:08:55 -0800 Subject: [PATCH 22/67] - _addChildService can be called several times without side effects - adds a future-proof way to get a type's prototype & constructor --- data/service/data-service.js | 45 +++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index c645b2fa35..623eda18aa 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -91,7 +91,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (value !== undefined) { this.isUniquing = value; } - + return result; } }, @@ -272,16 +272,21 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { _addChildService: { value: function (child, types) { var children, type, i, n, nIfEmpty = 1; - types = types || child.model && child.model.objectDescriptors || child.types; + types = types || child.model && child.model.objectDescriptors || child.types, + isNotParentService = (child._parentService !== this); // If the new child service already has a parent, remove it from // that parent. - if (child._parentService) { + // Adding more test to allow a service to register types in multiple + // calls, which can happen if the service is deserilized multiple times + if (child._parentService && isNotParentService) { child._parentService.removeChildService(child); } // Add the new child to this service's children set. - this.childServices.add(child); - this._childServicesByIdentifier.set(child.identifier, child); + if(isNotParentService) { + this.childServices.add(child); + this._childServicesByIdentifier.set(child.identifier, child); + } // Add the new child service to the services array of each of its // types or to the "all types" service array identified by the // `null` type, and add each of the new child's types to the array @@ -290,12 +295,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { for (i = 0, n = types && types.length || nIfEmpty; i < n; i += 1) { type = types && types.length && types[i] || null; children = this._childServicesByType.get(type) || []; - children.push(child); - if (children.length === 1) { - this._childServicesByType.set(type, children); - if (type) { - this._childServiceTypes.push(type); + + //Checking in case this is called multiple times + if(children.indexOf(child) === -1 ) { + children.push(child); + if (children.length === 1) { + this._childServicesByType.set(type, children); + if (type) { + this._childServiceTypes.push(type); + } } + } } // Set the new child service's parent. @@ -963,12 +973,17 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { */ _getPrototypeForType: { value: function (type) { - var info, triggers, prototype; + var info, triggers, prototypeToExtend, prototype; type = this._objectDescriptorForType(type); prototype = this._dataObjectPrototypes.get(type); if (type && !prototype) { - prototype = Object.create(type.objectPrototype || Montage.prototype); - prototype.constuctor = type.objectPrototype.constructor; + //type.objectPrototype is legacy and should be depreated over time + prototypeToExtend = type.objectPrototype || Object.getPrototypeOf(type.module) || Montage.prototype; + prototype = Object.create(prototypeToExtend); + prototype.constuctor = type.objectPrototype + ? type.objectPrototype.constructor + : type.module; + if(prototype.constuctor.name === "constructor" ) { Object.defineProperty(prototype.constuctor, "name", { value: type.typeName }); } @@ -1324,6 +1339,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (mapping) { + //Why aren't we passing this.snapshotForObject(object) instead of copying everying in a new empty object? Object.assign(data, this.snapshotForObject(object)); result = mapping.mapObjectToCriteriaSourceForProperty(object, data, propertyName); if (this._isAsync(result)) { @@ -1332,6 +1348,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return mapping.mapRawDataToObjectProperty(data, object, propertyName); }); } else { + //This was already done a few lines up. Why are we re-doing this? Object.assign(data, self.snapshotForObject(object)); result = mapping.mapRawDataToObjectProperty(data, object, propertyName); if (!this._isAsync(result)) { @@ -1938,7 +1955,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { return promise; } }, - + /** * Save changes made to a data object. * From fa5d2a663f659d2a9753651dcb5dc577d32424a5 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 10 Feb 2019 18:09:33 -0800 Subject: [PATCH 23/67] Adds a new converter to create embedded full objects of the right type --- .../raw-embedded-value-to-object-converter.js | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 data/converter/raw-embedded-value-to-object-converter.js diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js new file mode 100644 index 0000000000..0d6ccc9f67 --- /dev/null +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -0,0 +1,121 @@ +var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, +Criteria = require("core/criteria").Criteria, +DataQuery = require("data/model/data-query").DataQuery, +ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, +Promise = require("core/promise").Promise, +Scope = require("frb/scope"), +parse = require("frb/parse"), +compile = require("frb/compile-evaluator"); + +/** + * @class RawEmbeddedRelationshipValueToObjectConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends ExpressionDataMappingConverter + */ +exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { + + /********************************************************************* + * Properties + */ + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + convertedValue, + result, + criteria = this.convertSyntax + ? new Criteria().initWithSyntax(self.convertSyntax, v) + : null, + query; + + + + return Promise.all([this._descriptorToFetch, this.service]).then(function (values) { + var typeToFetch = values[0], + service = values[1]; + + if(Array.isArray(v)) { + if(v.length) { + convertedValue = []; + for(var i=0, countI=v.length, promises;(i Date: Mon, 11 Feb 2019 23:36:45 -0800 Subject: [PATCH 24/67] - Makes revertSyntax, compiledRevertSyntax more robust to undefimed revertExpression --- data/converter/expression-data-mapping-converter.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/data/converter/expression-data-mapping-converter.js b/data/converter/expression-data-mapping-converter.js index 7b1ae24f0b..dc39ff424d 100644 --- a/data/converter/expression-data-mapping-converter.js +++ b/data/converter/expression-data-mapping-converter.js @@ -172,7 +172,9 @@ exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends Expres * */ revertSyntax: { get: function() { - return this._revertSyntax || (this._revertSyntax = parse(this.revertExpression)); + return this._revertSyntax || (this._revertSyntax === undefined + ? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) : null + : null); } }, @@ -182,7 +184,10 @@ exports.ExpressionDataMappingConverter = Converter.specialize( /** @lends Expres compiledRevertSyntax: { get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax = compile(this.revertSyntax)); + + return this._compiledRevertSyntax || (this._compiledRevertSyntax === undefined + ? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) : null + : null); } }, From e95490b9ce3c13bf3d2e917dbb74b4c0dcc7b12b Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 11 Feb 2019 23:47:51 -0800 Subject: [PATCH 25/67] adds resolveObjectForTypeRawData method to asynchronously retrieve a fully mapped object --- data/service/raw-data-service.js | 53 +++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/data/service/raw-data-service.js b/data/service/raw-data-service.js index 696549f3c1..ef9a4e285d 100644 --- a/data/service/raw-data-service.js +++ b/data/service/raw-data-service.js @@ -435,6 +435,12 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot } this._addMapDataPromiseForStream(result, stream); + + //TO-DO: #warning + //This method should evolve to use resolveObjectForTypeRawData instead, + //however resolveObjectForTypeRawData's promises resolves to object + //only after it's been mapped, so this delegate call should only be called then + //and not too early as it is now. Not sure if that may create a backward compatibility issue if (object) { this.callDelegateMethod("rawDataServiceDidAddOneRawData", this, stream, rawData, object); } @@ -461,10 +467,55 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot } }, + /** + * Called by [addRawData()]{@link RawDataService#addRawData} to add an object + * for the passed record to the stream. This method both takes care of doing + * mapRawDataToObject and add the object to the stream. + * + * @method + * @argument {ObjectDescriptor} type + * - The type of the data object matching rawData. + * @argument {Object} rawData - An anonymnous object whose properties' + * values hold the raw data. + * @argument {?} context - An arbitrary value that will be passed to + * [getDataObject()]{@link RawDataService#getDataObject} + * and + * [mapRawDataToObject()]{@link RawDataService#mapRawDataToObject} + * if it is provided. + * + * @returns {Promise} - A promise resolving to the mapped object. + * + */ + + resolveObjectForTypeRawData: { + value:function(type, rawData, context) { + var dataIdentifier = this.dataIdentifierForTypeRawData(type,rawData), + //Retrieves an existing object is responsible data service is uniquing, or creates one + object, result; + + //Record snapshot before we may create an object + this.recordSnapshot(dataIdentifier, rawData); + + //Retrieves an existing object is responsible data service is uniquing, or creates one + object = this.getDataObject(type, rawData, context, dataIdentifier), + + result = this._mapRawDataToObject(rawData, object, context); + + if (Promise.is(result)) { + return result.then(function () { + return object; + }); + } else { + return Promise.resolve(object); + } + } + }, + + objectForTypeRawData: { value:function(type, rawData, context) { var dataIdentifier = this.dataIdentifierForTypeRawData(type,rawData); - //Record snapshot before we may create an object + //Record snapshot before we may create an object this.recordSnapshot(dataIdentifier, rawData); //iDataIdentifier argument should be all we need later on return this.getDataObject(type, rawData, context, dataIdentifier); From 75a890f41b047eb82815d205169ea1b51ff8ee3b Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 11 Feb 2019 23:53:32 -0800 Subject: [PATCH 26/67] - fixes bugs --- data/converter/raw-embedded-value-to-object-converter.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js index 0d6ccc9f67..21d3cdb411 100644 --- a/data/converter/raw-embedded-value-to-object-converter.js +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -73,13 +73,10 @@ exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.speci _convertOneValue: { value: function (v, typeToFetch, service, valueArray, index) { - var dataIdentifier = service.dataIdentifierForTypeRawData(typeToFetch, v), - dataServiceForType = service.rootService.childServiceForType(typeToFetch); - dataObject = service.rootService.getDataObject(typeToFetch, v, /* context */ undefined, dataIdentifier), - result = dataServiceForType.mapRawDataToObject(v,dataObject); + var result = service.resolveObjectForTypeRawData(typeToFetch, v); if (result) { - result = result.then(function () { + result = result.then(function (dataObject) { if(valueArray) { //Wondering if we need to do this in a property-change compatible way, //[] direct modification of an Array doesn't send property-changes @@ -89,7 +86,7 @@ exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.speci }); } else { - result = dataObject; + result = Promise.resolve(undefined); } return result; } From dca0a2d48df25eba51e001a0ffc39f6716ee8e1d Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 15:14:59 -0800 Subject: [PATCH 27/67] Removes unused ModuleReference and adds a method documentation --- data/model/data-query.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/data/model/data-query.js b/data/model/data-query.js index 13539a39a0..160fe8c8a8 100644 --- a/data/model/data-query.js +++ b/data/model/data-query.js @@ -1,5 +1,4 @@ -var Montage = require("montage").Montage, - ModuleReference = require("core/module-reference").ModuleReference; +var Montage = require("montage").Montage; /** * Defines the criteria that objects must satisfy to be included in a set of @@ -40,7 +39,7 @@ exports.DataQuery = Montage.specialize(/** @lends DataQuery.prototype */ { this.selectExpression = value; } - + value = deserializer.getProperty("type"); if (value !== void 0) { this.type = value; @@ -48,7 +47,7 @@ exports.DataQuery = Montage.specialize(/** @lends DataQuery.prototype */ { value = deserializer.getProperty("typeModule"); if (value) { var self = this; - + result = value.require.async(value.id).then(function (exports) { self.type = exports.montageObject; return self; @@ -67,7 +66,7 @@ exports.DataQuery = Montage.specialize(/** @lends DataQuery.prototype */ { serializer.setProperty("prefetchExpressions", this.prefetchExpressions); serializer.setProperty("selectBindings", this.selectBindings); serializer.setProperty("selectExpression", this.selectExpression); - + if (this.type.objectDescriptorInstanceModule) { serializer.setProperty("typeModule", this.type.objectDescriptorInstanceModule); } else { @@ -190,6 +189,15 @@ exports.DataQuery = Montage.specialize(/** @lends DataQuery.prototype */ { value: undefined }, + /** + * An expression that is used in memory client side to further refine the set objects retrieves. + * by the query's criteria expression. This useful in cases the origin service doesn't know how to handle such criteria. + * That shouldn't be exposed to the end developer, but instead, a RawDataService should be able to analyse a query's criteria + * and split the apsects that can be executed by the origin service automatically, to filter the rest itself. + * @type {Array} + */ + + selectExpression: { value: undefined }, From f89d15dfdf16cea119fa26e7ba3c083f630e6594 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 16:08:42 -0800 Subject: [PATCH 28/67] Renames converters and adds backward compatibility --- .../raw-embedded-value-to-object-converter.js | 22 +- .../raw-foreign-value-to-object-converter.js | 74 ++++ .../raw-property-value-to-object-converter.js | 79 +--- .../raw-value-to-object-converter.js | 360 ++++++++++++++++++ test/spec/data/expression-data-mapping.js | 48 +-- 5 files changed, 466 insertions(+), 117 deletions(-) create mode 100644 data/converter/raw-foreign-value-to-object-converter.js create mode 100644 data/converter/raw-value-to-object-converter.js diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js index 21d3cdb411..5ccc79e083 100644 --- a/data/converter/raw-embedded-value-to-object-converter.js +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -1,18 +1,11 @@ -var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, -Criteria = require("core/criteria").Criteria, -DataQuery = require("data/model/data-query").DataQuery, -ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, -Promise = require("core/promise").Promise, -Scope = require("frb/scope"), -parse = require("frb/parse"), -compile = require("frb/compile-evaluator"); - +var RawValueToObjectConverter = require("./raw-value-to-object-converter").RawValueToObjectConverter, +Promise = require("core/promise").Promise; /** * @class RawEmbeddedRelationshipValueToObjectConverter * @classdesc Converts a property value of raw data to the referenced object. - * @extends ExpressionDataMappingConverter + * @extends RawValueToObjectConverter */ -exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { +exports.RawEmbeddedValueToObjectConverter = RawValueToObjectConverter.specialize( /** @lends RawEmbeddedValueToObjectConverter# */ { /********************************************************************* * Properties @@ -33,12 +26,7 @@ exports.RawEmbeddedValueToObjectConverter = ExpressionDataMappingConverter.speci value: function (v) { var self = this, convertedValue, - result, - criteria = this.convertSyntax - ? new Criteria().initWithSyntax(self.convertSyntax, v) - : null, - query; - + result; return Promise.all([this._descriptorToFetch, this.service]).then(function (values) { diff --git a/data/converter/raw-foreign-value-to-object-converter.js b/data/converter/raw-foreign-value-to-object-converter.js new file mode 100644 index 0000000000..c5cc5a24bd --- /dev/null +++ b/data/converter/raw-foreign-value-to-object-converter.js @@ -0,0 +1,74 @@ +var RawValueToObjectConverter = require("./raw-value-to-object-converter").RawValueToObjectConverter, + Criteria = require("core/criteria").Criteria, + DataQuery = require("data/model/data-query").DataQuery, + Promise = require("core/promise").Promise; +/** + * @class RawForeignValueToObjectConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends RawValueToObjectConverter + */ +exports.RawForeignValueToObjectConverter = RawValueToObjectConverter.specialize( /** @lends RawForeignValueToObjectConverter# */ { + + + /********************************************************************* + * Public API + */ + + /** + * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. + * @function + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + var self = this, + criteria = new Criteria().initWithSyntax(self.convertSyntax, v), + query; + + return this._descriptorToFetch.then(function (typeToFetch) { + var type = typeToFetch.module.id; + + type += "/"; + type += typeToFetch.name; + + if (self.serviceIdentifier) { + criteria.parameters.serviceIdentifier = self.serviceIdentifier; + } + + query = DataQuery.withTypeAndCriteria(type, criteria); + + return self.service ? self.service.then(function (service) { + return service.rootService.fetchData(query); + }) : null; + }); + } + }, + + + + /** + * Reverts the relationship back to raw data. + * @function + * @param {Scope} v The value to revert. + * @returns {Promise} v + */ + revert: { + value: function (v) { + if (v) { + if (!this.compiledRevertSyntax) { + return Promise.resolve(v); + } else { + var scope = this.scope; + //Parameter is what is accessed as $ in expressions + scope.value = v; + return Promise.resolve(this.compiledRevertSyntax(scope)); + } + + } + return Promise.resolve(undefined); + } + } + +}); diff --git a/data/converter/raw-property-value-to-object-converter.js b/data/converter/raw-property-value-to-object-converter.js index e6fa40252c..6c3ae5156c 100644 --- a/data/converter/raw-property-value-to-object-converter.js +++ b/data/converter/raw-property-value-to-object-converter.js @@ -1,76 +1,3 @@ -var ExpressionDataMappingConverter = require("./expression-data-mapping-converter").ExpressionDataMappingConverter, - Criteria = require("core/criteria").Criteria, - DataQuery = require("data/model/data-query").DataQuery, - ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, - Promise = require("core/promise").Promise, - Scope = require("frb/scope"), - parse = require("frb/parse"), - compile = require("frb/compile-evaluator"); - -/** - * @class RawPropertyValueToObjectConverter - * @classdesc Converts a property value of raw data to the referenced object. - * @extends ExpressionDataMappingConverter - */ -exports.RawPropertyValueToObjectConverter = ExpressionDataMappingConverter.specialize( /** @lends RawPropertyValueToObjectConverter# */ { - - - /********************************************************************* - * Public API - */ - - /** - * Converts the fault for the relationship to an actual object that has an ObjectDescriptor. - * @function - * @param {Property} v The value to format. - * @returns {Promise} A promise for the referenced object. The promise is - * fulfilled after the object is successfully fetched. - */ - convert: { - value: function (v) { - var self = this, - criteria = new Criteria().initWithSyntax(self.convertSyntax, v), - query; - - return this._descriptorToFetch.then(function (typeToFetch) { - var type = [typeToFetch.module.id, typeToFetch.name].join("/"); - - if (self.serviceIdentifier) { - criteria.parameters.serviceIdentifier = self.serviceIdentifier; - } - - query = DataQuery.withTypeAndCriteria(type, criteria); - - return self.service ? self.service.then(function (service) { - return service.rootService.fetchData(query); - }) : null; - }); - } - }, - - - - /** - * Reverts the relationship back to raw data. - * @function - * @param {Scope} v The value to revert. - * @returns {string} v - */ - revert: { - value: function (v) { - if (v) { - if (!this.compiledRevertSyntax) { - return Promise.resolve(v); - } else { - var scope = this.scope; - //Parameter is what is accessed as $ in expressions - scope.value = v; - return Promise.resolve(this.compiledRevertSyntax(scope)); - } - - } - return Promise.resolve(undefined); - } - } - -}); +var deprecate = require("../../core/deprecate"); +exports.RawPropertyValueToObjectConverter = require("./raw-foreign-value-to-object-converter").RawForeignValueToObjectConverter; +deprecate.deprecationWarningOnce("RawPropertyValueToObjectConverter is deprecated, now use require(\"montage/data/converter/raw-foreign-value-to-object-converter\").RawForeignValueToObjectConverter instead"); diff --git a/data/converter/raw-value-to-object-converter.js b/data/converter/raw-value-to-object-converter.js new file mode 100644 index 0000000000..b2f68161f3 --- /dev/null +++ b/data/converter/raw-value-to-object-converter.js @@ -0,0 +1,360 @@ +var Converter = require("core/converter/converter").Converter, + ObjectDescriptorReference = require("core/meta/object-descriptor-reference").ObjectDescriptorReference, + Promise = require("core/promise").Promise, + Scope = require("frb/scope"), + parse = require("frb/parse"), + compile = require("frb/compile-evaluator"); + +/** + * @class RawValueToObjectConverter + * @classdesc Converts a property value of raw data to the referenced object. + * @extends Converter + */ +exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToObjectConverter# */ { + +/* + converter.expression = converter.expression || rule.expression; + converter.foreignDescriptor = converter.foreignDescriptor || propertyDescriptor.valueDescriptor; + converter.objectDescriptor = this.objectDescriptor; + converter.serviceIdentifier = rule.serviceIdentifier; + +*/ + + + /********************************************************************* + * Serialization + */ + + serializeSelf: { + value: function (serializer) { + + serializer.setProperty("convertExpression", this.convertExpression); + + serializer.setProperty("foreignDescriptor", this._foreignDescriptorReference); + + serializer.setProperty("revertExpression", this.revertExpression); + + serializer.setProperty("root", this.owner); + + serializer.setProperty("serviceIdentifier", this.serviceIdentifier); + serializer.setProperty("service", this.service); + + } + }, + + deserializeSelf: { + value: function (deserializer) { + var value = deserializer.getProperty("convertExpression"); + if (value) { + this.convertExpression = value; + } + + value = deserializer.getProperty("revertExpression"); + if (value) { + this.revertExpression = value; + } + + value = deserializer.getProperty("foreignDescriptor"); + if (value instanceof ObjectDescriptorReference) { + this._foreignDescriptorReference = value; + } else if (value) { + this.foreignDescriptor = value; + } + + value = deserializer.getProperty("service"); + if (value) { + this.service = value; + } + + value = deserializer.getObjectByLabel("root"); + if (value) { + this.owner = value; + } + + value = deserializer.getProperty("serviceIdentifier"); + if (value) { + this.serviceIdentifier = value; + } + + deserializer.deserializeUnit("bindings"); + } + }, + + /********************************************************************* + * Initialization + */ + + /** + * @param {string} convertExpression the expression to be used for building a criteria to obtain the object corresponding to the value to convert. + * @return itself + */ + initWithConvertExpression: { + value: function (convertExpression) { + this.convertExpression = convertExpression; + return this; + } + }, + + /********************************************************************* + * Properties + */ + + + _convertExpression: { + value: null + }, + + /** + * The expression used to convert a raw value into a modeled one, for example a foreign property value into the objet it represents. + * @type {string} + * */ + convertExpression: { + get: function() { + return this._convertExpression; + }, + set: function(value) { + if(value !== this._convertExpression) { + this._convertExpression = value; + this._convertSyntax = undefined; + } + } + }, + + _convertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .convertExpression using frb/grammar.js that will + * be used to initialize the convert query criteria + * @type {Object} + * */ + + convertSyntax: { + get: function() { + return this._convertSyntax || (this._convertSyntax === undefined + ? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null + : null); + } + }, + + _revertExpression: { + value: null + }, + + /** + * The expression used to revert the modeled value into a raw one. For example, + * reverting an object into it's primary key. + * @type {string} + * */ + revertExpression: { + get: function() { + return this._revertExpression; + }, + set: function(value) { + if(value !== this._revertExpression) { + this._revertExpression = value; + this._revertSyntax = undefined; + } + } + }, + + _revertSyntax: { + value: undefined + }, + + /** + * Object created by parsing .revertExpression using frb/grammar.js that will + * be used to revert the modeled value into a raw one + * @type {Object} + * */ + revertSyntax: { + get: function() { + return this._revertSyntax || (this._revertSyntax === undefined + ? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) : null + : null); + } + }, + + _compiledRevertSyntax: { + value: undefined + }, + + compiledRevertSyntax: { + get: function () { + + return this._compiledRevertSyntax || (this._compiledRevertSyntax === undefined + ? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) : null + : null); + } + }, + + + /** + * The descriptor of the destination object. If one is not provided, + * .objectDescriptor will be used. If .objectDescriptor is not provided, + * the value descriptor of the property descriptor that defines the + * relationship will be used. + * @type {?ObjectDescriptorReference} + * */ + foreignDescriptor: { + serializable: false, + get: function () { + var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; + return isReference ? this._foreignDescriptor : + this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : + this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); + }, + set: function (descriptor) { + this._foreignDescriptor = descriptor; + } + }, + + /** + * The descriptor of the source object. It will be used only if it is provided and + * .foreignDescriptor is not provided. + * @type {?ObjectDescriptorReference} + **/ + objectDescriptor: { + get: function () { + return this._objectDescriptor ? Promise.resolve(this._objectDescriptor) : + this.owner && this.owner.objectDescriptor ? Promise.resolve(this.owner.objectDescriptor) : + this._isAsync(this.owner) ? this._objectDescriptorReference : + undefined; + }, + set: function (value) { + this._objectDescriptor = value; + } + }, + + _objectDescriptorReference: { + get: function () { + var self = this; + return this.owner.then(function (object) { + var objectDescriptor = object.objectDescriptor; + self.objectDescriptor = objectDescriptor; + return objectDescriptor; + }); + } + }, + + _isAsync: { + value: function (object) { + return object && object.then && typeof object.then === "function"; + } + }, + + + /** + * The descriptor for which to perform the fetch. + * This returns foreignDescriptor, if it exists, and otherwise + * returns objectDescriptor. + * @type {?ObjectDescriptorReference} + **/ + _descriptorToFetch: { + get: function () { + if (!this.__descriptorToFetch) { + if (this.foreignDescriptor && this.foreignDescriptor.promise) { + this.__descriptorToFetch = this.foreignDescriptor.promise(require); + } else if (this.foreignDescriptor) { + this.__descriptorToFetch = this.foreignDescriptor; + } else { + this.__descriptorToFetch = this.objectDescriptor; + } + } + return this.__descriptorToFetch; + + // this.__descriptorToFetch = this._foreignDescriptor ? this._foreignDescriptor.then(function (descriptor) { + // return descriptor || self.objectDescriptor; + // }) : Promise.resolve(this.objectDescriptor); + // return this.foreignDescriptor || this.objectDescriptor; + } + }, + + owner: { + get: function () { + return this._owner ? this._owner.then ? this._owner : Promise.resolve(this._owner) : undefined; + }, + set: function (value) { + this._owner = value; + } + }, + + __scope: { + value: null + }, + + /** + * Scope with which convert and revert expressions are evaluated. + * @type {?Scope} + **/ + scope: { + get: function() { + return this.__scope || (this.__scope = new Scope(this)); + } + }, + + /** + * The service to use to make requests. + */ + service: { + get: function () { + return this._service ? this._service : + this.owner ? this.owner.then(function (object) { return object.service; }) : + undefined; + }, + set: function (value) { + this._service = !value || value.then ? value : Promise.resolve(value); + } + }, + + /** + * Identifier of the child of .service that the query should be routed to + */ + serviceIdentifier: { + value: undefined + }, + + /********************************************************************* + * Public API + */ + + //TODO + //The converter needs to know the property descriptor it acts on. + //This is available at the rule level, but only the whole objectDescriptor is + //set on the converter. If instead we set the propertyDescriptor, we would know both, + //as the propertyDescriptor can give the ObjectDescriptor it belongs to + //Question: Why does the objectDescriptor property on a propertyDescriptor returns a promise?s + + /** + * Convert raw data to data objects of an appropriate type. + * + * Subclasses should override this method to provide a concrete conversion. + * @method + * @param {Property} v The value to format. + * @returns {Promise} A promise for the referenced object. The promise is + * fulfilled after the object is successfully fetched. + */ + convert: { + value: function (v) { + return Promise.resolve(v); + } + }, + + + + /** + * Revert object value of a known type to raw data + * + * Subclasses should override this method to provide a concrete revert. + * @function + * @param {Scope} v The value to revert. + * @returns {string} v + */ + revert: { + value: function (v) { + return Promise.resolve(v); + } + } + +}); diff --git a/test/spec/data/expression-data-mapping.js b/test/spec/data/expression-data-mapping.js index 43f238a0cf..ac220b685d 100644 --- a/test/spec/data/expression-data-mapping.js +++ b/test/spec/data/expression-data-mapping.js @@ -11,7 +11,7 @@ var ExpressionDataMapping = require("montage/data/service/expression-data-mappin PropertyDescriptor = require("montage/core/meta/property-descriptor").PropertyDescriptor, RawDataService = require("montage/data/service/raw-data-service").RawDataService, RawDataTypeMapping = require("montage/data/service/raw-data-type-mapping").RawDataTypeMapping, - RawPropertyValueToObjectConverter = require("montage/data/converter/raw-property-value-to-object-converter").RawPropertyValueToObjectConverter; + RawForeignValueToObjectConverter = require("montage/data/converter/raw-foreign-value-to-object-converter").RawForeignValueToObjectConverter; var Movie = require("spec/data/logic/model/movie").Movie, @@ -60,7 +60,7 @@ describe("An Expression Data Mapping", function() { propsPropertyDescriptor, propConverter, propService, - + dateConverter = Object.create({}, { @@ -93,7 +93,7 @@ describe("An Expression Data Mapping", function() { movieObjectDescriptor.addPropertyDescriptor(new PropertyDescriptor().initWithNameObjectDescriptorAndCardinality("id", movieObjectDescriptor, 1)); movieSchemaModuleReference = new ModuleReference().initWithIdAndRequire("spec/data/schema/logic/movie", require); movieSchema = new ModuleObjectDescriptor().initWithModuleAndExportName(movieSchemaModuleReference, "MovieSchema"); - + actionMovieModuleReference = new ModuleReference().initWithIdAndRequire("spec/data/logic/model/action-movie", require); actionMovieObjectDescriptor = new ModuleObjectDescriptor().initWithModuleAndExportName(actionMovieModuleReference, "ActionMovie"); @@ -109,7 +109,7 @@ describe("An Expression Data Mapping", function() { categoryPropertyDescriptor = new PropertyDescriptor().initWithNameObjectDescriptorAndCardinality("category", movieObjectDescriptor, 1); categoryPropertyDescriptor.valueDescriptor = categoryObjectDescriptor; movieObjectDescriptor.addPropertyDescriptor(categoryPropertyDescriptor); - + countryService = new CountryService(); countryModuleReference = new ModuleReference().initWithIdAndRequire("spec/data/logic/model/country", require); @@ -161,24 +161,24 @@ describe("An Expression Data Mapping", function() { movieMapping = new ExpressionDataMapping().initWithServiceObjectDescriptorAndSchema(movieService, movieObjectDescriptor, movieSchema); movieMapping.addRequisitePropertyName( "title", "category", "budget", "isFeatured", "releaseDate", "id"); movieMapping.addObjectMappingRule("title", {"<->": "name"}); - + movieMapping.addObjectMappingRule("id", {"<->": "id"}); - categoryConverter = new RawPropertyValueToObjectConverter().initWithConvertExpression("category_id == $"); + categoryConverter = new RawForeignValueToObjectConverter().initWithConvertExpression("category_id == $"); categoryConverter.service = categoryService; movieMapping.addObjectMappingRule("category", { "<-": "{categoryID: category_id}", converter: categoryConverter }); - summaryConverter = new RawPropertyValueToObjectConverter().initWithConvertExpression("category_id == $"); + summaryConverter = new RawForeignValueToObjectConverter().initWithConvertExpression("category_id == $"); summaryConverter.service = plotSummaryService; movieMapping.addObjectMappingRule("plotSummary", { "<-": "{movie_id: id}", converter: summaryConverter, inversePropertyName: "movie" }); - propConverter = new RawPropertyValueToObjectConverter().initWithConvertExpression("category_id == $"); + propConverter = new RawForeignValueToObjectConverter().initWithConvertExpression("category_id == $"); propConverter.service = propService; movieMapping.addObjectMappingRule("props", { "<-": "{}", @@ -209,7 +209,7 @@ describe("An Expression Data Mapping", function() { actionMovieMapping.addRawDataMappingRule("mappedRating", {"<-": "rating"}); actionMovieMapping.addRawDataMappingRule("mappedScore", {"<-": "criticScore"}); actionMovieMapping.addRequisitePropertyName("country", "rating"); - countryConverter = new RawPropertyValueToObjectConverter().initWithConvertExpression("country_id"); + countryConverter = new RawForeignValueToObjectConverter().initWithConvertExpression("country_id"); countryConverter.revertExpression = "id"; countryConverter.owner = actionMovieMapping; actionMovieMapping.addObjectMappingRule("country", { @@ -287,14 +287,14 @@ describe("An Expression Data Mapping", function() { fcc_rating: "pg", country_id: 1 }; - + return actionMovieMapping.mapRawDataToObject(data, movie).then(function () { //Properties defined in parent descriptor - expect(movie.title).toBe("Star Wars"); + expect(movie.title).toBe("Star Wars"); expect(movie.budget).toEqual(14000000); //Properties defined in own descriptor - expect(movie.country).toBeDefined(); + expect(movie.country).toBeDefined(); done(); }); }); @@ -310,7 +310,7 @@ describe("An Expression Data Mapping", function() { fcc_rating: "pg", country_id: 1 }; - + return actionMovieMapping.mapRawDataToObject(data, movie).then(function () { //Properties defined in parent descriptor return mainService.updateObjectProperties(movie, "plotSummary"); @@ -332,7 +332,7 @@ describe("An Expression Data Mapping", function() { fcc_rating: "pg", country_id: 1 }; - + return movieMapping.mapRawDataToObject(data, movie).then(function () { //Properties defined in parent descriptor return mainService.updateObjectProperties(movie, "props"); @@ -351,7 +351,7 @@ describe("An Expression Data Mapping", function() { category_id: 1, budget: "14000000.00", is_featured: "true", - release_date: "05/25/1977" + release_date: "05/25/1977" }; return movieMapping.mapRawDataToObject(data, movie).then(function () { expect(typeof movie.budget === "number").toBeTruthy(); @@ -403,9 +403,9 @@ describe("An Expression Data Mapping", function() { movie = movieService.rootService.createDataObject(movieObjectDescriptor), category = new Category(), movieTitle = "The Social Network"; - - - var title = movie.title; //Trigger Title Getter + + + var title = movie.title; //Trigger Title Getter movie.title = movieTitle; movie.id = 2; category.name = "A Category"; @@ -433,12 +433,12 @@ describe("An Expression Data Mapping", function() { country.id = 1; actionMovieMapping.mapObjectToRawData(movie, data).then(function () { //Properties defined in parent descriptor - expect(data.name).toBe("Star Wars"); - expect(data.budget).toBe("14000000"); - expect(data.is_featured).toBe("true"); - expect(data.release_date).toBe("05/25/1977"); + expect(data.name).toBe("Star Wars"); + expect(data.budget).toBe("14000000"); + expect(data.is_featured).toBe("true"); + expect(data.release_date).toBe("05/25/1977"); //Properties defined in own descriptor - expect(data.fcc_rating).toBe("pg"); + expect(data.fcc_rating).toBe("pg"); expect(data.country_id).toEqual(1); done(); }); @@ -473,7 +473,7 @@ describe("An Expression Data Mapping", function() { }); }); - + }); From 6aa8e7c6336c309e17498ea3e9a1d017cca05636 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 18:18:12 -0800 Subject: [PATCH 29/67] Removes comment and fixes eslint ternery expression warning --- data/converter/raw-value-to-object-converter.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/data/converter/raw-value-to-object-converter.js b/data/converter/raw-value-to-object-converter.js index b2f68161f3..842c77f2b2 100644 --- a/data/converter/raw-value-to-object-converter.js +++ b/data/converter/raw-value-to-object-converter.js @@ -132,9 +132,10 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO convertSyntax: { get: function() { - return this._convertSyntax || (this._convertSyntax === undefined - ? this._convertSyntax = this.convertExpression ? parse(this.convertExpression) : null - : null); + return (this._convertSyntax || + ((this._convertSyntax === undefined) + ? (this._convertSyntax = (this.convertExpression ? parse(this.convertExpression) : null)) + : null)); } }, @@ -319,13 +320,6 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO * Public API */ - //TODO - //The converter needs to know the property descriptor it acts on. - //This is available at the rule level, but only the whole objectDescriptor is - //set on the converter. If instead we set the propertyDescriptor, we would know both, - //as the propertyDescriptor can give the ObjectDescriptor it belongs to - //Question: Why does the objectDescriptor property on a propertyDescriptor returns a promise?s - /** * Convert raw data to data objects of an appropriate type. * From bfc24a2feca87e6d34c7b7f29ab5e1d5667dfda6 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 18:20:19 -0800 Subject: [PATCH 30/67] Fixes TO-DO -> TODO --- data/service/raw-data-service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/service/raw-data-service.js b/data/service/raw-data-service.js index ef9a4e285d..53fbdca881 100644 --- a/data/service/raw-data-service.js +++ b/data/service/raw-data-service.js @@ -436,7 +436,7 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot this._addMapDataPromiseForStream(result, stream); - //TO-DO: #warning + //TODO: #warning //This method should evolve to use resolveObjectForTypeRawData instead, //however resolveObjectForTypeRawData's promises resolves to object //only after it's been mapped, so this delegate call should only be called then From 9e234144180a5381ff1808414baa8ba265b2b0d2 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 18:21:35 -0800 Subject: [PATCH 31/67] Simplify Promise.resolve(undefined) -> Promise.resolve() --- data/converter/raw-embedded-value-to-object-converter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/converter/raw-embedded-value-to-object-converter.js b/data/converter/raw-embedded-value-to-object-converter.js index 5ccc79e083..654277428e 100644 --- a/data/converter/raw-embedded-value-to-object-converter.js +++ b/data/converter/raw-embedded-value-to-object-converter.js @@ -74,7 +74,7 @@ exports.RawEmbeddedValueToObjectConverter = RawValueToObjectConverter.specialize }); } else { - result = Promise.resolve(undefined); + result = Promise.resolve(); } return result; } @@ -99,7 +99,7 @@ exports.RawEmbeddedValueToObjectConverter = RawValueToObjectConverter.specialize } } - return Promise.resolve(undefined); + return Promise.resolve(); } } From c9935088fd62a6463d08824ad8fd509c26c63621 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 22 Feb 2019 22:59:48 -0800 Subject: [PATCH 32/67] Simplifies Promiser.resolve() --- data/converter/raw-foreign-value-to-object-converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/converter/raw-foreign-value-to-object-converter.js b/data/converter/raw-foreign-value-to-object-converter.js index c5cc5a24bd..ccafff8851 100644 --- a/data/converter/raw-foreign-value-to-object-converter.js +++ b/data/converter/raw-foreign-value-to-object-converter.js @@ -67,7 +67,7 @@ exports.RawForeignValueToObjectConverter = RawValueToObjectConverter.specialize( } } - return Promise.resolve(undefined); + return Promise.resolve(); } } From 1ea8ccba827503109b68b8bbdf9fe5d5eaf0a94d Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 15:03:53 -0700 Subject: [PATCH 33/67] Implements the new delegate compiler for mr, here to process the dependencies of and deserizlize an mjson. Also, deserialization is only done when the factory is called. This is a dependency on a change in mr where the new call to a delegate to do this happens. --- montage.js | 117 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/montage.js b/montage.js index 1f2cf7a5a9..9cf4ea048f 100644 --- a/montage.js +++ b/montage.js @@ -18,9 +18,11 @@ // reassigning causes eval to not use lexical scope. var globalEval = eval, - /*jshint evil:true */ - global = globalEval('this'); - /*jshint evil:false */ + /*jshint evil:true */ + global = globalEval('this'), + /*jshint evil:false */ + montageExports = exports; + // Here we expose global for legacy mop support. // TODO move to mr cause it's loader role to expose @@ -400,12 +402,113 @@ } }; - exports.compileMJSONFile = function (mjson, require, moduleId) { - var deserializer = new exports.MontageDeserializer(); - deserializer.init(mjson, require, void 0, require.location + moduleId); - return deserializer.deserializeObject(); + exports.MJSONCompilerFactory = function MJSONCompilerFactory(require, exports, module, global, moduleFilename, moduleDirectory) { + + //var root = Require.delegate.compileMJSONFile(module.text, require.config.requireForId(module.id), module.id, /*isSync*/ true); + + if(module.exports.hasOwnProperty("montageObject")) { + throw new Error( + 'using reserved word as property name, \'montageObject\' at: ' + + module.location + ); + } + + if(!module.deserializer) { + // var root = Require.delegate.compileMJSONFile(module.text, require.config.requireForId(module.id), module, /*isSync*/ true); + if(!montageExports.MontageDeserializer) { + montageExports.MontageDeserializer = require("montage/core/serialization/deserializer/montage-deserializer").MontageDeserializer; + } + + var deserializer = new montageExports.MontageDeserializer(), + deserializerRequire = require.config.requireForId(module.id), + root; + module.deserializer = deserializer; + deserializer.init(module.text, deserializerRequire, void 0, deserializerRequire.location + module.id, true); + root = deserializer.deserializeObject(); + + // console.log("********MJSONCompilerFactory END compileMJSONFile",module.id); + + if (module.exports.montageObject && module.exports.montageObject !== root) { + throw new Error( + 'Final deserialized object is different than one set on module ' + + module.location + ); + } + else if(!module.exports.montageObject) { + module.exports.montageObject = root; + } + + if(module.exports) { + Object.assign(module.exports, module.parsedText) + } + else { + module.exports = module.parsedText; + } + + module.deserializer = null; + module.text = null; + + } + + // console.log("********MJSONCompilerFactory END montageObject THERE",module.id); + + + }; + + exports.parseMJSONDependencies = function parseMJSONDependencies(jsonRoot) { + + var rootEntries = Object.keys(jsonRoot), + i=0, iLabel, dependencies = [], iLabelObject; + + while ((iLabel = rootEntries[i])) { + iLabelObject = jsonRoot[iLabel]; + if(iLabelObject.hasOwnProperty("prototype")) { + dependencies.push(iLabelObject["prototype"]); + } + else if(iLabelObject.hasOwnProperty("object")) { + dependencies.push(iLabelObject["object"]); + } + i++; + } + return dependencies; + }; + + var dotMeta = ".meta", + dotMJSON = ".mjson", + dotMJSONLoadJs = ".mjson.load.js"; + + exports.Compiler = function (config, compile) { + return function(module) { + + if (module.exports || module.factory || (typeof module.text !== "string") || (typeof module.exports === "object")) { + return module; + } + + var location = module.location, + isMJSON = (location && (location.endsWith(dotMJSON) || location.endsWith(dotMJSONLoadJs) || location.endsWith(dotMeta))); + + if (isMJSON) { + if (typeof module.exports !== "object" && typeof module.text === "string") { + module.parsedText = JSON.parse(module.text); + if (module.parsedText.montageObject) { + throw new Error( + 'using reserved word as property name, \'montageObject\' at: ' + + location + ); + } + } + module.dependencies = montageExports.parseMJSONDependencies(module.parsedText); + module.factory = exports.MJSONCompilerFactory; + + return module; + } else { + var result = compile(module); + return result; + } + } }; + exports.initMontageCustomElement = function () { if (typeof window.customElements === 'undefined' || typeof window.Reflect === 'undefined') { return void 0; From a40f9039ea8c7fda5cd6805847219889b5b2b89e Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 15:05:04 -0700 Subject: [PATCH 34/67] Removes the need for node.js bootstrap environment to deal with mjson --- node.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/node.js b/node.js index 1b93bc16dd..830239ec58 100644 --- a/node.js +++ b/node.js @@ -83,17 +83,7 @@ function getMontageMontageDeserializer() { })); } -exports.compileMJSONFile = function (mjson, require, moduleId) { - if (MontageBoot.MontageDeserializer) { - return MontageBoot.compileMJSONFile(mjson, require, moduleId); - } else { - return getMontageMontageDeserializer().then(function () { - return MontageBoot.compileMJSONFile(mjson, require, moduleId); - }); - } -}; - -Require.delegate = exports; +Require.delegate = MontageBoot; function parseHtml(html) { var dom, error; From 208136c56a7e23c3b3507ad83376cfc8adcd68f5 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 15:57:07 -0700 Subject: [PATCH 35/67] Adds a new object property to ModuleObjectDescriptor to enable the direct deserialization of the object described by the ModuleObjectDescriptor as an alternative to use the module/reference --- core/meta/module-object-descriptor.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/meta/module-object-descriptor.js b/core/meta/module-object-descriptor.js index 02a2ef7782..3318edb8af 100644 --- a/core/meta/module-object-descriptor.js +++ b/core/meta/module-object-descriptor.js @@ -60,6 +60,9 @@ var ModuleObjectDescriptor = exports.ModuleObjectDescriptor = ObjectDescriptor.s this.super(serializer); this._setPropertyWithDefaults(serializer, "module", this.module); this._setPropertyWithDefaults(serializer, "exportName", this.exportName); + if(this.object) { + this._setPropertyWithDefaults(serializer, "object", this.object); + } } }, @@ -82,6 +85,12 @@ var ModuleObjectDescriptor = exports.ModuleObjectDescriptor = ObjectDescriptor.s if (!this.exportName) { throw new Error("Cannot deserialize object descriptor without an exportName"); } + + value = deserializer.getProperty("object"); + if (value !== void 0) { + this.object = value; + } + } }, @@ -93,6 +102,15 @@ var ModuleObjectDescriptor = exports.ModuleObjectDescriptor = ObjectDescriptor.s value: null }, + /** + * A reference to the actual object that this object descriptor is for. + * @type {Object} + */ + object: { + value: null + }, + + /** * The name of the export this object descriptor is for. * @type {string} From 93a3a6dd141d0198445587e5411ca67e9a09cd7d Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 15:57:46 -0700 Subject: [PATCH 36/67] Fixes a bug is no value is passed to the convert method --- .../raw-foreign-value-to-object-converter.js | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/data/converter/raw-foreign-value-to-object-converter.js b/data/converter/raw-foreign-value-to-object-converter.js index ccafff8851..f1abfa6afd 100644 --- a/data/converter/raw-foreign-value-to-object-converter.js +++ b/data/converter/raw-foreign-value-to-object-converter.js @@ -23,26 +23,32 @@ exports.RawForeignValueToObjectConverter = RawValueToObjectConverter.specialize( */ convert: { value: function (v) { - var self = this, + + if(v) { + var self = this, criteria = new Criteria().initWithSyntax(self.convertSyntax, v), query; - return this._descriptorToFetch.then(function (typeToFetch) { - var type = typeToFetch.module.id; + return this._descriptorToFetch.then(function (typeToFetch) { + var type = typeToFetch.module.id; - type += "/"; - type += typeToFetch.name; + type += "/"; + type += typeToFetch.name; - if (self.serviceIdentifier) { - criteria.parameters.serviceIdentifier = self.serviceIdentifier; - } + if (self.serviceIdentifier) { + criteria.parameters.serviceIdentifier = self.serviceIdentifier; + } - query = DataQuery.withTypeAndCriteria(type, criteria); + query = DataQuery.withTypeAndCriteria(type, criteria); - return self.service ? self.service.then(function (service) { - return service.rootService.fetchData(query); - }) : null; - }); + return self.service ? self.service.then(function (service) { + return service.rootService.fetchData(query); + }) : null; + }); + } + else { + return Promise.resolve(); + } } }, From 2726b4c348be87576f0401f1f6b086947c56d2f0 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 16:00:53 -0700 Subject: [PATCH 37/67] Adds debug option on rule itself similar to syntax used for bindings, and also enables the use of a setter if present for a property expecting an Array rather than directly modifying the array. It means the setter is responsible to mutate it's own array if it desire to do so. --- data/service/expression-data-mapping.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/data/service/expression-data-mapping.js b/data/service/expression-data-mapping.js index a86a9a96bd..351934c4b3 100644 --- a/data/service/expression-data-mapping.js +++ b/data/service/expression-data-mapping.js @@ -456,7 +456,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData isRelationship = propertyDescriptor && !propertyDescriptor.definition && propertyDescriptor.valueDescriptor, isDerived = propertyDescriptor && !!propertyDescriptor.definition, scope = this._scope, - debug = DataService.debugProperties.has(propertyName); + debug = DataService.debugProperties.has(propertyName) || (rule && rule.debug === true); // Check if property is included in the DataService.debugProperties collection. Intended for debugging. @@ -469,6 +469,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData this._prepareRawDataToObjectRule(rule, propertyDescriptor); + return isRelationship ? this._resolveRelationship(object, propertyDescriptor, rule, scope) : propertyDescriptor && !isDerived ? this._resolveProperty(object, propertyDescriptor, rule, scope) : null; @@ -480,10 +481,13 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData var self = this, hasInverse = !!propertyDescriptor.inversePropertyName || !!rule.inversePropertyName, data; + return rule.evaluate(scope).then(function (result) { data = result; + return hasInverse ? self._assignInversePropertyValue(data, object, propertyDescriptor, rule) : null; }).then(function () { + self._setObjectValueForPropertyDescriptor(object, data, propertyDescriptor); return null; }); @@ -497,7 +501,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData return propertyDescriptor.valueDescriptor.then(function (objectDescriptor) { var inversePropertyDescriptor = objectDescriptor.propertyDescriptorForName(inversePropertyName); - + if (data) { self._setObjectsValueForPropertyDescriptor(data, object, inversePropertyDescriptor); } @@ -607,7 +611,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData }, /** - * Maps the value of a single object property to raw data. Assumes that + * Maps the value of a single object property to raw data. Assumes that * the object property has been resolved * * @method @@ -640,7 +644,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData }, /** - * Prefetches any object properties required to map the rawData property + * Prefetches any object properties required to map the rawData property * and maps once the fetch is complete. * * @method @@ -669,7 +673,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData return result; } }, - + /** * Convert model object properties to the raw data properties present in the requirements * for a given propertyName @@ -702,7 +706,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData return promises ? Promise.all(promises) : null; } }, - + _prepareObjectToRawDataRule: { value: function (rule) { var converter = rule.converter, @@ -750,9 +754,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData if (Array.isArray(value)) { isToMany = propertyDescriptor.cardinality !== 1; - if (isToMany && Array.isArray(object[propertyName])) { - object[propertyName].splice.apply(object[propertyName], [0, Infinity].concat(value)); - } else if (isToMany) { + if (isToMany) { object[propertyName] = value; } else if (value.length) { //Cardinality is 1, if data contains more than 1 item, we throw From 99665df9595136895750d06f9d946b605fed1720 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 19:06:28 -0700 Subject: [PATCH 38/67] Move use of a property name to a propertyDescriptor object to enable more context, like knowing about the cardinality of the property the trigger handles. --- data/service/data-trigger.js | 82 ++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/data/service/data-trigger.js b/data/service/data-trigger.js index 36716bcbcc..cf7470063e 100644 --- a/data/service/data-trigger.js +++ b/data/service/data-trigger.js @@ -73,11 +73,25 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy * @type {string} */ _propertyName: { + configurable: true, + get: function() { + return this.propertyDescriptor.name; + } + }, + + /** + * The property descriptor managed by this trigger. + * + * @private + * @type {string} + */ + propertyDescriptor: { configurable: true, writable: true, value: undefined }, + /** * The name of the private property corresponding to the public property * managed by this trigger. @@ -212,15 +226,15 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy configurable: true, writable: true, value: function (object) { - var prototype, descriptor, getter; + var prototype, descriptor, getter, propertyName = this._propertyName; // Start an asynchronous fetch of the property's value if necessary. this.getObjectProperty(object); - + // Search the prototype chain for a getter for this property, // starting just after the prototype that called this method. prototype = Object.getPrototypeOf(this._objectPrototype); while (prototype) { - descriptor = Object.getOwnPropertyDescriptor(prototype, this._propertyName); + descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName); getter = descriptor && descriptor.get; prototype = !getter && Object.getPrototypeOf(prototype); } @@ -244,7 +258,7 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy configurable: true, writable: true, value: function (object, value) { - var status, prototype, descriptor, getter, setter, writable; + var status, prototype, descriptor, getter, setter, writable, currentValue; // Get the value's current status and update that status to indicate // the value has been obtained. This way if the setter called below // requests the property's value it will get the value the property @@ -262,12 +276,24 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy writable = !descriptor || setter || descriptor.writable; prototype = writable && !setter && Object.getPrototypeOf(prototype); } + + // Set this trigger's property to the desired value, but only if // that property is writable. if (setter) { setter.call(object, value); } else if (writable) { - object[this._privatePropertyName] = value; + + //If Array / to-Many + isToMany = this.propertyDescriptor.cardinality !== 1; + currentValue = this._getValue(object); + if (isToMany && Array.isArray(currentValue)) { + object[propertyName].splice.apply(currentValue, [0, Infinity].concat(value)); + } + else { + object[this._privatePropertyName] = value; + } + } // Resolve any pending promise for this trigger's property value. if (status) { @@ -376,26 +402,26 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { * @returns {Object.} */ addTriggers: { - value: function (service, type, prototype, requisitePropertyNames) { + value: function (service, type, prototype, requisitePropertyDescriptors) { // This function was split into two to provide backwards compatibility // to existing Montage data projects. Future montage data projects // should base their object descriptors on Montage's version of object // descriptor. var isMontageDataType = type instanceof DataObjectDescriptor || type instanceof ObjectDescriptor; return isMontageDataType ? this._addTriggersForMontageDataType(service, type, prototype, name) : - this._addTriggers(service, type, prototype, requisitePropertyNames); + this._addTriggers(service, type, prototype, requisitePropertyDescriptors); } }, _addTriggersForMontageDataType: { value: function (service, type, prototype) { var triggers = {}, - names = Object.keys(type.propertyDescriptors), - trigger, name, i; - for (i = 0; (name = names[i]); ++i) { - trigger = this.addTrigger(service, type, prototype, name); + propertyDescriptors = Object.keys(type.propertyDescriptors), + trigger, iPropertyDescriptor, i; + for (i = 0; (iPropertyDescriptor = propertyDescriptors[i]); ++i) { + trigger = this.addTrigger(service, type, prototype, iPropertyDescriptor); if (trigger) { - triggers[name] = trigger; + triggers[iPropertyDescriptor.name] = trigger; } } return triggers; @@ -403,14 +429,14 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { }, _addTriggers: { - value: function (service, objectDescriptor, prototype, requisitePropertyNames) { - var triggers = {}, + value: function (service, objectDescriptor, prototype, requisitePropertyDescriptors) { + var triggers = {}, propertyDescriptors = objectDescriptor.propertyDescriptors, propertyDescriptor, trigger, name, i; for (i = 0; (propertyDescriptor = propertyDescriptors[i]); i += 1) { name = propertyDescriptor.name; - trigger = this.addTrigger(service, objectDescriptor, prototype, name); + trigger = this.addTrigger(service, objectDescriptor, prototype, propertyDescriptor); if (trigger) { triggers[name] = trigger; } @@ -427,14 +453,14 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { * @returns {?DataTrigger} */ addTrigger: { - value: function (service, type, prototype, name) { + value: function (service, type, prototype, propertyDescriptor) { // This function was split into two to provide backwards compatibility // to existing Montage data projects. Future montage data projects // should base their object descriptors on Montage's version of object // descriptor. var isMontageDataType = type instanceof DataObjectDescriptor || type instanceof ObjectDescriptor; - return isMontageDataType ? this._addTriggerForMontageDataType(service, type, prototype, name) : - this._addTrigger(service, type, prototype, name); + return isMontageDataType ? this._addTriggerForMontageDataType(service, type, prototype, propertyDescriptor.name) : + this._addTrigger(service, type, prototype, propertyDescriptor); } }, @@ -445,7 +471,7 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { if (descriptor && descriptor.isRelationship) { trigger = Object.create(this._getTriggerPrototype(service)); trigger._objectPrototype = prototype; - trigger._propertyName = name; + trigger.propertyDescriptor = descriptor; trigger._isGlobal = descriptor.isGlobal; Montage.defineProperty(prototype, name, { get: function () { @@ -481,7 +507,7 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { var trigger = Object.create(this._getTriggerPrototype(service)), serviceTriggers = service._dataObjectTriggers.get(objectDescriptor); trigger._objectPrototype = prototype; - trigger._propertyName = name; + trigger.propertyDescriptor = propertyDescriptor; trigger._isGlobal = propertyDescriptor.isGlobal; if(!serviceTriggers) { serviceTriggers = {}; @@ -492,19 +518,19 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { } }, _addTrigger: { - value: function (service, objectDescriptor, prototype, name) { - var descriptor = objectDescriptor.propertyDescriptorForName(name), - trigger; + value: function (service, objectDescriptor, prototype, descriptor) { + // var descriptor = objectDescriptor.propertyDescriptorForName(name), + var trigger; if (descriptor) { trigger = Object.create(this._getTriggerPrototype(service)); trigger._objectPrototype = prototype; - trigger._propertyName = name; + trigger.propertyDescriptor = descriptor; trigger._isGlobal = descriptor.isGlobal; if (descriptor.definition) { - Montage.defineProperty(prototype, name, { + Montage.defineProperty(prototype, descriptor.name, { get: function () { - if (!this.getBinding(name)) { - this.defineBinding(name, {"<-": descriptor.definition}); + if (!this.getBinding(descriptor.name)) { + this.defineBinding(descriptor.name, {"<-": descriptor.definition}); } return trigger._getValue(this); // return (trigger||(trigger = DataTrigger._createTrigger(service, objectDescriptor, prototype, name,descriptor)))._getValue(this); @@ -515,7 +541,7 @@ Object.defineProperties(exports.DataTrigger, /** @lends DataTrigger */ { } }); } else { - Montage.defineProperty(prototype, name, { + Montage.defineProperty(prototype, descriptor.name, { get: function () { return trigger._getValue(this); // return (trigger||(trigger = DataTrigger._createTrigger(service, objectDescriptor, prototype, name,descriptor)))._getValue(this); From 29188b03ecf74f62c6d59b1b8ba9cb0056ddc2d8 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 24 Mar 2019 19:07:37 -0700 Subject: [PATCH 39/67] Modifies childServices deserialization to work with synchronous deserialization on top of async. --- data/service/data-service.js | 103 +++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index 623eda18aa..87ef005125 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -59,14 +59,6 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { result = this, value; - value = deserializer.getProperty("childServices"); - if (value) { - this.registerChildServices(value); - result = this._childServiceRegistrationPromise.then(function () { - return self; - }); - } - value = deserializer.getProperty("model") || deserializer.getProperty("binder"); if (value) { this.model = value; @@ -92,7 +84,19 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { this.isUniquing = value; } - return result; + value = deserializer.getProperty("childServices"); + if (value) { + this._childServices = value; + } + + return this; + } + }, + + deserializedFromSerialization: { + value: function () { + if(this._childServices) + this.addChildServices(this._childServices) } }, @@ -242,6 +246,49 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { value: undefined }, + + + addChildServices: { + value: function (childServices) { + var i, countI, iChild, j, countJ, mappings, jMapping, types, jType, jResult, typesPromises; + + for(i=0, countI = childServices.length;(i Date: Sun, 24 Mar 2019 19:09:03 -0700 Subject: [PATCH 40/67] Fixes bugs for synchrounous deserialization and cyclical dependencies in nested mjson files --- .../deserializer/montage-deserializer.js | 8 +- .../deserializer/montage-interpreter.js | 17 +- .../deserializer/montage-reviver.js | 43 +- .../montage-deserializer-spec.js | 2800 ++++++++--------- 4 files changed, 1421 insertions(+), 1447 deletions(-) diff --git a/core/serialization/deserializer/montage-deserializer.js b/core/serialization/deserializer/montage-deserializer.js index 0679b2c04c..e9bbed84b6 100644 --- a/core/serialization/deserializer/montage-deserializer.js +++ b/core/serialization/deserializer/montage-deserializer.js @@ -102,9 +102,11 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ deserializeObject: { value: function(objects) { - return this.deserialize(objects).then(function(objects) { - return objects.root; - }); + return (this._isSync + ? this.deserialize(objects).root + : this.deserialize(objects).then(function(objects) { + return objects.root; + })); } }, diff --git a/core/serialization/deserializer/montage-interpreter.js b/core/serialization/deserializer/montage-interpreter.js index 760534c126..13f3319865 100644 --- a/core/serialization/deserializer/montage-interpreter.js +++ b/core/serialization/deserializer/montage-interpreter.js @@ -158,20 +158,19 @@ var MontageContext = Montage.specialize({ value: function() { var self = this, serialization = this._serialization, - promises = [], - result; + promises, + result, + objectKeys = Object.keys(serialization); - for (var label in serialization) { - if (serialization.hasOwnProperty(label)) { - result = this.getObject(label); + for (var i=0, label;(label = objectKeys[i]); i++) { + result = this.getObject(label); - if (Promise.is(result)) { - promises.push(result); - } + if (Promise.is(result)) { + (promises || (promises = [])).push(result); } } - if (promises.length === 0) { + if (!promises || promises.length === 0) { result = this._invokeDidReviveObjects(); return this._isSync ? result : Promise.resolve(result); } else { diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index f84c09a2ce..483f801ffe 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -459,16 +459,17 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont objectName = locationDesc.objectName; } - if (typeof module === "string" && isObjectDescriptor && - this._deserializerConstructor.moduleContexts.has( - (location = context._require.location + locationId) - )) { + if (isObjectDescriptor && + this._deserializerConstructor.moduleContexts.has( + (location = context._require.location + locationId) + )) { // We have a circular reference. If we wanted to forbid circular // references this is where we would throw an error. - return this._deserializerConstructor.moduleContexts.get(location)._objects.root; - } + return this._deserializerConstructor.moduleContexts.get(location).getObject("root"); + } + - if (isObjectDescriptor && !Promise.is(module) && !module.montageObject) { + if (!this._isSync && isObjectDescriptor && !Promise.is(module) && !module.montageObject) { module = context._require.async(locationDesc.moduleId); } @@ -505,13 +506,7 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont Object.create(module.montageObject) : module.montageObject; context.setObjectLabel(object, label); - if(label === "root") { return this.instantiateMontageObject(value, object, objectName, context, label); - } - else { - return this.instantiateMJSONObject(value, object, objectName, context, label); - } - } else { object = this.getMontageObject(value, module, objectName, context, label); context.setObjectLabel(object, label); @@ -560,28 +555,6 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont } }, - instantiateMJSONObject: { - value: function (serialization, object, objectName, context, label) { - var self = this, - montageObjectDesc; - - if (object !== null && object !== void 0) { - object.isDeserializing = true; - } - - context.setBindingsToDeserialize(object, serialization); - montageObjectDesc = this.reviveObjectLiteral(serialization, context); - - if (Promise.is(montageObjectDesc)) { - return montageObjectDesc.then(function(montageObjectDesc) { - return self.deserializeMontageObject(montageObjectDesc, object, context, label); - }); - } else { - return this.deserializeMontageObject(montageObjectDesc, object, context, label); - } - } - }, - instantiateMontageObject: { value: function (serialization, object, objectName, context, label) { var self = this, diff --git a/test/spec/serialization/montage-deserializer-spec.js b/test/spec/serialization/montage-deserializer-spec.js index 408b5393a2..b7d180dff2 100644 --- a/test/spec/serialization/montage-deserializer-spec.js +++ b/test/spec/serialization/montage-deserializer-spec.js @@ -47,1406 +47,1406 @@ describe("serialization/montage-deserializer-spec", function () { deserializer = new Deserializer(); }); - describe("Montage Objects Deserialization", function () { - it("should deserialize a class instance object", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - deserializer.deserializeObject().then(function (root) { - expect(Object.getPrototypeOf(root)).toBe(Montage.prototype); - expect(root.number).toBe(42); - expect(root.string).toBe("a string"); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize two class instance objects", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "oneprop": {"@": "oneprop"} - } - }, - - "oneprop": { - "prototype": "montage", - "values": { - "prop": 42 - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - - deserializer.deserializeObject().then(function (root) { - expect(root.oneprop.prop).toBe(42); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an external object with a label", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "simple": {"@": "simple"} - } - }, - - "simple": {} - }, - serializationString = JSON.stringify(serialization), - simple = {}, - instances = { - simple: simple - }; - - deserializer.init( - serializationString, require); - - deserializer.deserializeObject(instances).then(function (root) { - expect(root.simple).toBe(simple); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an object as another by providing an instance", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "simple": {"@": "simple"} - } - }, - - "simple": { - "prototype": "spec/serialization/testobjects-v2[Simple]" - } - }, - serializationString = JSON.stringify(serialization), - simple = {}, - instances = { - simple: simple - }; - - deserializer.init(serializationString, require); - - deserializer.deserializeObject(instances).then(function (root) { - expect(root.simple).toBe(simple); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize to a different object", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[Singleton]", - "values": { - "number": 42 - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - deserializer.deserializeObject().then(function (root) { - expect(root).toBe(objects.Singleton.prototype.instance); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an object's properties when an instance is given for that object", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "number": 42 - } - } - }, - serializationString = JSON.stringify(serialization), - root = {}, - instances = { - root: root - }; - - deserializer.init( - serializationString, require); - - deserializer.deserializeObject(instances).then(function (root) { - expect(root).toBe(instances.root); - expect(instances.root.number).toBe(42); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an object's properties when an instance is given for that object even when the serialization doesn't have a prototype or object property", function (done) { - var serialization = { - "owner": { - "values": { - "number": 42 - } - } - }, - serializationString = JSON.stringify(serialization), - owner = {}, - instances = { - owner: owner - }; - - deserializer.init( - serializationString, require); - - deserializer.deserialize(instances).then(function (objects) { - expect(objects.owner).toBe(instances.owner); - expect(instances.owner.number).toBe(42); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize a complex key assignment", function (done) { - var serialization = { - "root": { - "value": { - "bar": {} - }, - "values": { - "foo": 10, - "bar.quz": 42 - } - } - }, - serializationString = JSON.stringify(serialization); - deserialize(serializationString, require).then(function (object) { - expect(object.foo).toBe(10); - expect(object.bar.quz).toBe(42); - }).finally(function () { - done(); - }); - }); - - it("should deserialize a simple one-time assignment in normal form", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "foo": 10, - "bar": { "=": "foo" } - } - } - }, - serializationString = JSON.stringify(serialization); - deserialize(serializationString, require).then(function (object) { - expect(object.foo).toBe(10); - expect(object.bar).toBe(10); - object.foo = 20; - expect(object.bar).toBe(10); - }).finally(function () { - done(); - }); - }); - - it("should deserialize a simple one-time assignment with a component reference", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "foo": 10, - "bar": { "=": "@root.foo" } - } - } - }, - serializationString = JSON.stringify(serialization); - - deserialize(serializationString, require).then(function (object) { - expect(object.foo).toBe(10); - expect(object.bar).toBe(10); - object.foo = 20; - expect(object.bar).toBe(10); - }).finally(function () { - done(); - }); - }); - - it("should deserialize a complex one-time assignment", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "foo": { - "qux": 10 - }, - "a": { - "b": 10, - "c": 20 - }, - "corge": [ 1, 2, 3, 4, 5 ], - "bar": { "=": "foo.qux" }, - "qux": { "=": "foo.qux + 10" }, - "quuz": { "=": "foo.qux + bar + @root.bar" }, - "quux": { "=": "corge.sum()" }, - "quuxz": { "=": 75.5 }, - "quuxzz": { "=": true }, - "a.b": { "=": 1 }, - "a.c": 2 - } - } - }, - serializationString = JSON.stringify(serialization); - - deserialize(serializationString, require).then(function (object) { - expect(object.foo.qux).toBe(10); - expect(object.bar).toBe(10); - expect(object.qux).toBe(20); - expect(object.quuz).toBe(30); - expect(object.quux).toBe(15); - object.foo.qux = 20; - expect(object.bar).toBe(10); - expect(object.qux).toBe(20); - expect(object.quuxz).toBe(75.5); - expect(object.quuxzz).toBe(true); - expect(object.quuxzz).toBe(true); - expect(object.a.b).toBe(1); - expect(object.a.c).toBe(2); - done(); - }); - }); - - it("should fail deserializing an one-time assignment to a non existing object", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "foo": 10, - "bar": { "=": "@unknown.foo" } - } - } - }, - serializationString = JSON.stringify(serialization); - - deserialize(serializationString, require).then(function (object) { - expect("deserialization").toBe("fail"); - }).catch(function (err) { - expect(err).toBeDefined(); - }).finally(function () { - done(); - }); - }); - - - it("should call deserializedFromSerialization function on the instantiated objects", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[OneProp]", - "values": { - "prop": {"@": "oneprop"} - } - }, - "oneprop": { - "prototype": "spec/serialization/testobjects-v2[OneProp]" - } - }, - serializationString = JSON.stringify(serialization), - instances = { - root: new objects.OneProp() - }; - - deserializer.init(serializationString, require); - deserializer.deserialize(instances).then(function (object) { - var root = object.root, - oneprop = object.oneprop; - - expect(root.deserializedFromSerializationCount).toBe(0); - expect(oneprop.deserializedFromSerializationCount).toBe(1); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - // TODO Deprecated ? - xit("should call deserializedFromSerialization function on the instantiated objects even if they were given as null instances", function (done) { - var latch; - var instances = {root: null}; - var exports; - - deserializer.init({ - root: { - module: "serialization/testobjects-v2", - name: "OneProp", - values: { - prop: {"@": "oneprop"} - } - }, - oneprop: { - module: "serialization/testobjects-v2", - name: "OneProp" - } - }, require).deserializeObject(instances, function (objs) { - latch = true; - exports = objs; - - expect(exports.root.deserializedFromSerializationCount).toBe(1); - done(); - }); - }); - - it("should have isDeserializing set to true during units deserialization", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[OneProp]", - "values": { - "prop": 42 - }, - "spec": {} - } - }, - serializationString = JSON.stringify(serialization), - isDeserializing; - - deserializer.init( - serializationString, require); - - Deserializer.defineDeserializationUnit("spec", function (deserializer, object) { - isDeserializing = object.isDeserializing; - }); - - deserializer.deserialize().then(function (objects) { - expect(isDeserializing).toBeTruthy(); - expect(objects.root.isDeserializing).toBeUndefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - }); - - describe("Alias deserialization", function () { - it("should deserialize an alias", function (done) { - var serialization = { - ":templateProperty": { - "alias": "@component:propertyName" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function (objects) { - var alias = objects[":templateProperty"]; - expect(Object.getPrototypeOf(alias)).toBe(Alias.prototype); - expect(alias.value).toBe("@component:propertyName"); - expect(alias.componentLabel).toBe("component"); - expect(alias.propertyName).toBe("propertyName"); - }).finally(function () { - done(); - }); - }); - }); - - describe("Template properties deserialization", function () { - it("should deserialize a template property as an alias", function (done) { - var serialization = { - ":templateProperty": { - "alias": "@component:propertyName" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function (result) { - expect(result).toBeDefined(); - }).finally(function () { - done(); - }); - }); - - it("should not deserialize a template property as an external object", function (done) { - var serialization = { - ":templateProperty": {} - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function () { - expect("deserialization").toBe("failed"); - }).catch(function() { - expect("failed").toBe("failed"); - }).finally(function () { - done(); - }); - }); - - it("should not deserialize a montage object as a template property", function (done) { - var serialization = { - ":templateProperty": { - "prototype": "montage/ui/component" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function () { - expect("deserialization").toBe("failed"); - }).catch(function() { - expect("failed").toBe("failed"); - }).finally(function () { - done(); - }); - }); - - it("should not deserialize a value as a template property", function (done) { - var serialization = { - ":templateProperty": { - "value": 42 - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function () { - expect("deserialization").toBe("failed"); - }).catch(function() { - expect("failed").toBe("failed"); - }).finally(function () { - done(); - }); - }); - - it("should not deserialize a regexp as a template property", function (done) { - var serialization = { - ":templateProperty": { - "/": {"source": "regexp"} - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function () { - expect("deserialization").toBe("failed"); - }).catch(function() { - expect("failed").toBe("failed"); - }).finally(function () { - done(); - }); - }); - - it("should not deserialize a literal object as a template property", function (done) { - var serialization = { - ":templateProperty": { - "value": {} - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize().then(function () { - expect("deserialization").toBe("failed"); - }).catch(function() { - expect("failed").toBe("failed"); - }).finally(function () { - done(); - }); - }); - }); - - describe("Object Location", function () { - it("should deserialize using prototype: module[name]", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[TestobjectsV2]", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); - expect(root.instance).toBeUndefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using prototype: module", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - - expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); - - expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - expect(info.objectName).toBe("TestobjectsV2"); - expect(info.isInstance).toBe(true); - expect(root.instance).toBeUndefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using prototype: module-name.reel", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/module-name.reel", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - expect(info.moduleId).toBe("spec/serialization/module-name.reel"); - expect(info.objectName).toBe("ModuleName"); - expect(info.isInstance).toBe(true); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using object: module[name]", function (done) { - var serialization = { - "root": { - "object": "spec/serialization/testobjects-v2[TestobjectsV2]", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - - expect(root).toBe(objects.TestobjectsV2); - expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - expect(info.objectName).toBe("TestobjectsV2"); - expect(info.isInstance).toBe(false); - expect(root.type).toBeUndefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using object: module", function (done) { - var serialization = { - "root": { - "object": "spec/serialization/testobjects-v2", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - - expect(root).toBe(objects.TestobjectsV2); - expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - expect(info.objectName).toBe("TestobjectsV2"); - expect(info.isInstance).toBe(false); - expect(root.type).toBeUndefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize only when children are deserialized", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - "properties": { - "stringProperty": "Parent", - "array": [ - {"@": "test"}, - {"@": "test2"} - ] - } - }, - "test": { - "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - "properties": { - "stringProperty": "Child", - "objectProperty": {"@": "descriptor"}, - "parent": {"@": "root"} - } - }, - "test2": { - "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - "properties": { - "stringProperty": "Child2", - "objectProperty": {"@": "descriptor"}, - "parent": {"@": "root"} - } - }, - "descriptor": { - "object": "spec/serialization/testmjson2.mjson" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - console.log("root", root); - expect(root).toBeDefined(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using object: module.json", function (done) { - var serialization = { - "root": { - "object": "spec/serialization/testjson.json" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (json) { - expect("root" in json).toBe(true); - expect(json.root.foo).toBe("bar"); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using prototype: module.mjson", function (done) { - var serialization = { - "root": { - "prototype": "spec/serialization/testmjson.mjson", - "values": { - "number": 42, - "string": {"<-": "'a string'"} - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - expect(info.moduleId).toBe("core/core"); - expect(info.isInstance).toBe(true); - expect(root.type).toBeUndefined(); - expect(root.name).toBe("RootObjectDescriptor"); - expect(root.number).toBe(42); - expect(root.string).toBe("a string"); - }).catch(function (reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize instances using prototype: module.mjson", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "bar": { "@": "bar" }, - "foo": { "@": "foo" } - } - }, - "bar": { - "prototype": "spec/serialization/testmjson.mjson" - }, - "foo": { - "prototype": "spec/serialization/testmjson.mjson" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - expect(root.foo).not.toBe(root.bar); - }).catch(function (reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using object: module.mjson", function (done) { - var serialization = { - "root": { - "object": "spec/serialization/testmjson.mjson", - "values": { - "number": 42, - "string": {"<-": "'a string'"} - } - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - var info = Montage.getInfoForObject(root); - expect(info.moduleId).toBe("core/core"); - expect(info.isInstance).toBe(true); - expect(root.type).toBeUndefined(); - expect(root.name).toBe("RootObjectDescriptor"); - expect(root.number).toBe(42); - expect(root.string).toBe("a string"); - }).catch(function (reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize singleton using object: module.mjson", function (done) { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "bar": { "@": "bar" }, - "foo": { "@": "foo" } - } - }, - "bar": { - "object": "spec/serialization/testmjson.mjson" - }, - "foo": { - "object": "spec/serialization/testmjson.mjson" - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserializeObject().then(function (root) { - expect(root.foo).toBe(root.foo); - }).catch(function (reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize singleton using the folowing syntax: require('[path].mjson')", function (done) { - require.async('spec/serialization/testmjson.mjson').then(function (module) { - expect(module.montageObject).toBeDefined(); - expect(module.montageObject.name).toBe("RootObjectDescriptor"); - done(); - }); - }); - - it("should deserialize using instance after compilation", function (done) { - var latch, objects; - - deserializer.init({ - root: { - prototype: "montage", - values: { - number: 15, - string: "string" - } - } - }, require).deserialize().then(function (objs) { - latch = true; - objects = objs; - - var root = objects.root, - info = Montage.getInfoForObject(root); - - expect(Montage.isPrototypeOf(root)); - expect(info.moduleId).toBe("core/core"); - expect(info.objectName).toBe("Montage"); - expect(info.isInstance).toBe(true); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize using type after compilation", function (done) { - var latch, objects; - - deserializer.init({ - root: { - object: "montage", - values: { - number: 15, - string: "string" - } - } - }, require).deserialize().then(function (objs) { - latch = true; - objects = objs; - - var root = objects.root, - info = Montage.getInfoForObject(root); - - expect(root).toBe(Montage); - expect(info.moduleId).toBe("core/core"); - expect(info.objectName).toBe("Montage"); - expect(info.isInstance).toBe(false); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - }); - - describe("Module reference deserialization", function () { - it("should deserialize a module", function (done) { - var serialization = { - "root": { - "value": {"%": "./testobjects-v2"} - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - deserializer.deserializeObject().then(function (root) { - // module is now absolute from the root of the test package - expect(root.id).toBe("spec/serialization/testobjects-v2"); - expect(root.require.location).toBe(require.location); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should use the require of the package the deserializer is using", function (done) { - - require.loadPackage("spec/package-a").then(function (pkg1) { - var serialization = { - "root": { - "value": {"%": "pass"} - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, pkg1); - - deserializer.deserializeObject().then(function (root) { - expect(root.id).toBe("pass"); - expect(root.require.location).toBe(pkg1.location); - }).finally(function () { - done(); - }); - }); - }); - }); - - describe("Custom deserialization", function () { - var customDeserialization = objects.CustomDeserialization, - serialization = { - "root": { - "prototype": "spec/serialization/testobjects-v2[CustomDeserialization]", - "values": { - "prop1": 3.14, - "prop2": {"<-": "@oneprop.prop"} - }, - "listeners": [{ - "type": "action", - "listener": {"@": "oneprop"} - }] - }, - - "oneprop": { - "prototype": "spec/serialization/testobjects-v2[OneProp]", - "values": { - "prop": 42 - } - } - }; - - it("should only create the object", function (done) { - var serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - - }; - - deserializer.deserializeObject().then(function (root) { - expect(root.prop1).toBeNull(); - expect(root._bindingDescriptors).toBeFalsy(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should report prototype type", function (done) { - var serializationString = JSON.stringify(serialization), - type, - typeValue; - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - type = deserializer.getType(); - typeValue = deserializer.getTypeValue(); - }; - - deserializer.deserializeObject().then(function (root) { - expect(type).toBe("prototype"); - expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should report object type", function (done) { - var serialization = { - "root": { - "object": "spec/serialization/testobjects-v2[CustomDeserialization]" - } - }, - serializationString = JSON.stringify(serialization), - type, - typeValue; - - deserializer.init( - serializationString, require); - - customDeserialization.deserializeSelf = function (deserializer) { - type = deserializer.getType(); - typeValue = deserializer.getTypeValue(); - }; - - deserializer.deserializeObject().then(function (root) { - expect(type).toBe("object"); - expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should access properties", function (done) { - var serializationString = JSON.stringify(serialization), - prop1; - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - prop1 = deserializer.getProperty("prop1"); - }; - - deserializer.deserializeObject().then(function (root) { - expect(prop1).toBe(3.14); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should only deserialize properties", function (done) { - var serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - deserializer.deserializeValues(); - }; - - deserializer.deserializeObject().then(function (root) { - expect(root.prop1).toBe(3.14); - expect(root._bindingDescriptors).toBeFalsy(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - xit("should deserialize properties and listeners", function (done) { - var serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - deserializer.deserializeValues(); - deserializer.deserializeUnit("listeners"); - }; - - deserializer.deserializeObject().then(function (root) { - expect(root.prop1).toBe(3.14); - expect(root._bindingDescriptors).toBeFalsy(); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize properties and bindings", function (done) { - var serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - deserializer.deserializeValues(); - deserializer.deserializeUnit("bindings"); - }; - - deserializer.deserializeObject().then(function (root) { - expect(root.prop1).toBe(3.14); - expect(Bindings.getBindings(root).size).toBeGreaterThan(0); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize properties and all units", function (done) { - var serializationString = JSON.stringify(serialization); - - deserializer.init( - serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - deserializer.deserializeValues(); - deserializer.deserializeUnits(); - }; - - deserializer.deserializeObject().then(function (root) { - expect(root.prop1).toBe(3.14); - expect(Bindings.getBindings(root).size).toBeGreaterThan(0); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - it("should deserialize into another object in an asynchronous way", function (done) { - var serializationString = JSON.stringify(serialization), - newRoot = {}; - - deserializer.init(serializationString, require); - - customDeserialization.prototype.deserializeSelf = function (deserializer) { - return Promise.resolve(newRoot); - }; - - deserializer.deserializeObject().then(function (root) { - expect(root).toBe(newRoot); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - }); - - it("should load the correct module even if it's from a diferent package but with the same name", function (done) { - var deserializer1 = new Deserializer(), - deserializer2 = new Deserializer(), - serialization = { - root: { - prototype: "ui/main.reel" - } - }, - serializationString = JSON.stringify(serialization); - - require.loadPackage("spec/package-a").then(function (pkg1) { - return require.loadPackage("spec/package-b").then(function (pkg2) { - return deserializer1.init(serializationString, pkg1) - .deserialize().then(function (object1) { - return deserializer2.init(serializationString, pkg2) - .deserialize().then(function (object2) { - expect(object1.root.name).toBe("A"); - expect(object2.root.name).toBe("B"); - }); - }); - }).finally(function () { - done(); - }); - }); - }); - - it("should deserialize null", function (done) { - var serialization = { - "a": { - "value": null - } - }, - serializationString = JSON.stringify(serialization); - - deserializer.init(serializationString, require); - deserializer.deserialize(serializationString).then(function (objects) { - expect(objects.a).toBe(null); - }).catch(function(reason) { - fail(reason); - }).finally(function () { - done(); - }); - }); - - describe("errors", function () { - it("should fail if no require was given", function () { - var serialization = { - "root": { - "prototype": "montage", - "values": { - "number": 42, - "string": "a string" - } - } - }, - serializationString = JSON.stringify(serialization); - - try { - deserializer.init( - serializationString, null); - // should never execute - expect(true).toBe(false); - } catch (ex) { - expect(ex).toBeDefined(); - } - }); - - it("should fail deserialize if serialization is malformed", function (done) { - var serializationString = "{root:}"; - - // return a promise when failling. - deserializer.init(serializationString, require).deserialize().catch(function (ex) { - expect(ex).toBeDefined(); - }).finally(function () { - done(); - }); - }); - }); - - describe("deserialization", function() { - it("should deserialize a serialization string", function(done) { - var serialization = { - "string": { - "value": "a string" - }, - - "number": { - "value": 42 - }, - - "literal": { - "value": { - "string": "a string", - "number": 42 - } - } - }, - serializationString = JSON.stringify(serialization), - expectedResult = { - string: "a string", - number: 42, - literal: { - string: "a string", - number: 42 - } - }, - deserializer = new Deserializer().init(serializationString, require); - - deserializer.deserialize().then(function(objects) { - expect(objects).toEqual(jasmine.objectContaining(expectedResult)); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an object from a serialization string", function(done) { - var serialization = { - "root": { - "value": "a string" - } - }, - serializationString = JSON.stringify(serialization), - deserializer = new Deserializer().init(serializationString, require); - - deserializer.deserializeObject().then(function(object) { - expect(object).toBe("a string"); - }).finally(function () { - done(); - }); - }); - - it("should deserialize an external object from a serialization string", function(done) { - var serialization = { - "external": {} - }, - userObjects = { - "external": {} - }, - serializationString = JSON.stringify(serialization), - deserializer = new Deserializer().init(serializationString, require); - - deserializer.deserialize(userObjects).then(function(objects) { - expect(userObjects.external).toBe(objects.external); - }).finally(function () { - done(); - }); - }); - - it("should fail deserializing a missing external object from a serialization string", function(done) { - var serialization = { - "external": {} - }, - serializationString = JSON.stringify(serialization), - deserializer = new Deserializer().init(serializationString, require); - - deserializer.deserialize().then(function(objects) { - expect("test").toBe("fail"); - }, function() { - expect(true).toBe(true); - }).finally(function () { - done(); - }); - }); - - it("should be oblivious to Object.prototype aditions", function(done) { - Object.defineProperty(Object.prototype, "clear", { - value: function() {}, - writable: true, - configurable: true - }); - - var serialization = { - "clear": { - "value": "a string" - } - }, - serializationString = JSON.stringify(serialization), - deserializer = new Deserializer().init(serializationString, require); - - deserializer.deserialize().then(function(object) { - delete Object.prototype.clear; - expect(object.clear).toBe("a string"); - }).finally(function () { - done(); - }); - }); - - describe("shorthand", function() { - it("should deserialize an object from a serialization string", function(done) { - var serialization = { - "root": { - "value": "a string" - } - }, - serializationString = JSON.stringify(serialization); - - deserialize(serializationString, require).then(function(object) { - expect(object).toEqual("a string"); - }).finally(function () { - done(); - }); - }); - }); - - describe("errors", function() { - it("should warn about invalid format", function(done) { - // property name is missing quotes - var serializationString = '{string: "a string"}'; - - new Promise(function (resolve, reject) { - resolve(deserialize(serializationString, require)); // will fail - }).then(function(objects) { - // never executed - }, function(reason) { - expect(reason).toBeDefined(); - }).finally(function () { - done(); - }); - }) - }); - }); + // describe("Montage Objects Deserialization", function () { + // it("should deserialize a class instance object", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // deserializer.deserializeObject().then(function (root) { + // expect(Object.getPrototypeOf(root)).toBe(Montage.prototype); + // expect(root.number).toBe(42); + // expect(root.string).toBe("a string"); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize two class instance objects", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "oneprop": {"@": "oneprop"} + // } + // }, + + // "oneprop": { + // "prototype": "montage", + // "values": { + // "prop": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + + // deserializer.deserializeObject().then(function (root) { + // expect(root.oneprop.prop).toBe(42); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an external object with a label", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "simple": {"@": "simple"} + // } + // }, + + // "simple": {} + // }, + // serializationString = JSON.stringify(serialization), + // simple = {}, + // instances = { + // simple: simple + // }; + + // deserializer.init( + // serializationString, require); + + // deserializer.deserializeObject(instances).then(function (root) { + // expect(root.simple).toBe(simple); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an object as another by providing an instance", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "simple": {"@": "simple"} + // } + // }, + + // "simple": { + // "prototype": "spec/serialization/testobjects-v2[Simple]" + // } + // }, + // serializationString = JSON.stringify(serialization), + // simple = {}, + // instances = { + // simple: simple + // }; + + // deserializer.init(serializationString, require); + + // deserializer.deserializeObject(instances).then(function (root) { + // expect(root.simple).toBe(simple); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize to a different object", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[Singleton]", + // "values": { + // "number": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // deserializer.deserializeObject().then(function (root) { + // expect(root).toBe(objects.Singleton.prototype.instance); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an object's properties when an instance is given for that object", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "number": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization), + // root = {}, + // instances = { + // root: root + // }; + + // deserializer.init( + // serializationString, require); + + // deserializer.deserializeObject(instances).then(function (root) { + // expect(root).toBe(instances.root); + // expect(instances.root.number).toBe(42); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an object's properties when an instance is given for that object even when the serialization doesn't have a prototype or object property", function (done) { + // var serialization = { + // "owner": { + // "values": { + // "number": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization), + // owner = {}, + // instances = { + // owner: owner + // }; + + // deserializer.init( + // serializationString, require); + + // deserializer.deserialize(instances).then(function (objects) { + // expect(objects.owner).toBe(instances.owner); + // expect(instances.owner.number).toBe(42); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize a complex key assignment", function (done) { + // var serialization = { + // "root": { + // "value": { + // "bar": {} + // }, + // "values": { + // "foo": 10, + // "bar.quz": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + // deserialize(serializationString, require).then(function (object) { + // expect(object.foo).toBe(10); + // expect(object.bar.quz).toBe(42); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize a simple one-time assignment in normal form", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "foo": 10, + // "bar": { "=": "foo" } + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + // deserialize(serializationString, require).then(function (object) { + // expect(object.foo).toBe(10); + // expect(object.bar).toBe(10); + // object.foo = 20; + // expect(object.bar).toBe(10); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize a simple one-time assignment with a component reference", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "foo": 10, + // "bar": { "=": "@root.foo" } + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserialize(serializationString, require).then(function (object) { + // expect(object.foo).toBe(10); + // expect(object.bar).toBe(10); + // object.foo = 20; + // expect(object.bar).toBe(10); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize a complex one-time assignment", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "foo": { + // "qux": 10 + // }, + // "a": { + // "b": 10, + // "c": 20 + // }, + // "corge": [ 1, 2, 3, 4, 5 ], + // "bar": { "=": "foo.qux" }, + // "qux": { "=": "foo.qux + 10" }, + // "quuz": { "=": "foo.qux + bar + @root.bar" }, + // "quux": { "=": "corge.sum()" }, + // "quuxz": { "=": 75.5 }, + // "quuxzz": { "=": true }, + // "a.b": { "=": 1 }, + // "a.c": 2 + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserialize(serializationString, require).then(function (object) { + // expect(object.foo.qux).toBe(10); + // expect(object.bar).toBe(10); + // expect(object.qux).toBe(20); + // expect(object.quuz).toBe(30); + // expect(object.quux).toBe(15); + // object.foo.qux = 20; + // expect(object.bar).toBe(10); + // expect(object.qux).toBe(20); + // expect(object.quuxz).toBe(75.5); + // expect(object.quuxzz).toBe(true); + // expect(object.quuxzz).toBe(true); + // expect(object.a.b).toBe(1); + // expect(object.a.c).toBe(2); + // done(); + // }); + // }); + + // it("should fail deserializing an one-time assignment to a non existing object", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "foo": 10, + // "bar": { "=": "@unknown.foo" } + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserialize(serializationString, require).then(function (object) { + // expect("deserialization").toBe("fail"); + // }).catch(function (err) { + // expect(err).toBeDefined(); + // }).finally(function () { + // done(); + // }); + // }); + + + // it("should call deserializedFromSerialization function on the instantiated objects", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[OneProp]", + // "values": { + // "prop": {"@": "oneprop"} + // } + // }, + // "oneprop": { + // "prototype": "spec/serialization/testobjects-v2[OneProp]" + // } + // }, + // serializationString = JSON.stringify(serialization), + // instances = { + // root: new objects.OneProp() + // }; + + // deserializer.init(serializationString, require); + // deserializer.deserialize(instances).then(function (object) { + // var root = object.root, + // oneprop = object.oneprop; + + // expect(root.deserializedFromSerializationCount).toBe(0); + // expect(oneprop.deserializedFromSerializationCount).toBe(1); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // // TODO Deprecated ? + // xit("should call deserializedFromSerialization function on the instantiated objects even if they were given as null instances", function (done) { + // var latch; + // var instances = {root: null}; + // var exports; + + // deserializer.init({ + // root: { + // module: "serialization/testobjects-v2", + // name: "OneProp", + // values: { + // prop: {"@": "oneprop"} + // } + // }, + // oneprop: { + // module: "serialization/testobjects-v2", + // name: "OneProp" + // } + // }, require).deserializeObject(instances, function (objs) { + // latch = true; + // exports = objs; + + // expect(exports.root.deserializedFromSerializationCount).toBe(1); + // done(); + // }); + // }); + + // it("should have isDeserializing set to true during units deserialization", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[OneProp]", + // "values": { + // "prop": 42 + // }, + // "spec": {} + // } + // }, + // serializationString = JSON.stringify(serialization), + // isDeserializing; + + // deserializer.init( + // serializationString, require); + + // Deserializer.defineDeserializationUnit("spec", function (deserializer, object) { + // isDeserializing = object.isDeserializing; + // }); + + // deserializer.deserialize().then(function (objects) { + // expect(isDeserializing).toBeTruthy(); + // expect(objects.root.isDeserializing).toBeUndefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("Alias deserialization", function () { + // it("should deserialize an alias", function (done) { + // var serialization = { + // ":templateProperty": { + // "alias": "@component:propertyName" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function (objects) { + // var alias = objects[":templateProperty"]; + // expect(Object.getPrototypeOf(alias)).toBe(Alias.prototype); + // expect(alias.value).toBe("@component:propertyName"); + // expect(alias.componentLabel).toBe("component"); + // expect(alias.propertyName).toBe("propertyName"); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("Template properties deserialization", function () { + // it("should deserialize a template property as an alias", function (done) { + // var serialization = { + // ":templateProperty": { + // "alias": "@component:propertyName" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function (result) { + // expect(result).toBeDefined(); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should not deserialize a template property as an external object", function (done) { + // var serialization = { + // ":templateProperty": {} + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function () { + // expect("deserialization").toBe("failed"); + // }).catch(function() { + // expect("failed").toBe("failed"); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should not deserialize a montage object as a template property", function (done) { + // var serialization = { + // ":templateProperty": { + // "prototype": "montage/ui/component" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function () { + // expect("deserialization").toBe("failed"); + // }).catch(function() { + // expect("failed").toBe("failed"); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should not deserialize a value as a template property", function (done) { + // var serialization = { + // ":templateProperty": { + // "value": 42 + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function () { + // expect("deserialization").toBe("failed"); + // }).catch(function() { + // expect("failed").toBe("failed"); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should not deserialize a regexp as a template property", function (done) { + // var serialization = { + // ":templateProperty": { + // "/": {"source": "regexp"} + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function () { + // expect("deserialization").toBe("failed"); + // }).catch(function() { + // expect("failed").toBe("failed"); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should not deserialize a literal object as a template property", function (done) { + // var serialization = { + // ":templateProperty": { + // "value": {} + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize().then(function () { + // expect("deserialization").toBe("failed"); + // }).catch(function() { + // expect("failed").toBe("failed"); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("Object Location", function () { + // it("should deserialize using prototype: module[name]", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[TestobjectsV2]", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + // expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); + // expect(root.instance).toBeUndefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using prototype: module", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + + // expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); + + // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + // expect(info.objectName).toBe("TestobjectsV2"); + // expect(info.isInstance).toBe(true); + // expect(root.instance).toBeUndefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using prototype: module-name.reel", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/module-name.reel", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + // expect(info.moduleId).toBe("spec/serialization/module-name.reel"); + // expect(info.objectName).toBe("ModuleName"); + // expect(info.isInstance).toBe(true); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using object: module[name]", function (done) { + // var serialization = { + // "root": { + // "object": "spec/serialization/testobjects-v2[TestobjectsV2]", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + + // expect(root).toBe(objects.TestobjectsV2); + // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + // expect(info.objectName).toBe("TestobjectsV2"); + // expect(info.isInstance).toBe(false); + // expect(root.type).toBeUndefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using object: module", function (done) { + // var serialization = { + // "root": { + // "object": "spec/serialization/testobjects-v2", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + + // expect(root).toBe(objects.TestobjectsV2); + // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + // expect(info.objectName).toBe("TestobjectsV2"); + // expect(info.isInstance).toBe(false); + // expect(root.type).toBeUndefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize only when children are deserialized", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + // "properties": { + // "stringProperty": "Parent", + // "array": [ + // {"@": "test"}, + // {"@": "test2"} + // ] + // } + // }, + // "test": { + // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + // "properties": { + // "stringProperty": "Child", + // "objectProperty": {"@": "descriptor"}, + // "parent": {"@": "root"} + // } + // }, + // "test2": { + // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + // "properties": { + // "stringProperty": "Child2", + // "objectProperty": {"@": "descriptor"}, + // "parent": {"@": "root"} + // } + // }, + // "descriptor": { + // "object": "spec/serialization/testmjson2.mjson" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // console.log("root", root); + // expect(root).toBeDefined(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using object: module.json", function (done) { + // var serialization = { + // "root": { + // "object": "spec/serialization/testjson.json" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (json) { + // expect("root" in json).toBe(true); + // expect(json.root.foo).toBe("bar"); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using prototype: module.mjson", function (done) { + // var serialization = { + // "root": { + // "prototype": "spec/serialization/testmjson.mjson", + // "values": { + // "number": 42, + // "string": {"<-": "'a string'"} + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + // expect(info.moduleId).toBe("core/core"); + // expect(info.isInstance).toBe(true); + // expect(root.type).toBeUndefined(); + // expect(root.name).toBe("RootObjectDescriptor"); + // expect(root.number).toBe(42); + // expect(root.string).toBe("a string"); + // }).catch(function (reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize instances using prototype: module.mjson", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "bar": { "@": "bar" }, + // "foo": { "@": "foo" } + // } + // }, + // "bar": { + // "prototype": "spec/serialization/testmjson.mjson" + // }, + // "foo": { + // "prototype": "spec/serialization/testmjson.mjson" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // expect(root.foo).not.toBe(root.bar); + // }).catch(function (reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using object: module.mjson", function (done) { + // var serialization = { + // "root": { + // "object": "spec/serialization/testmjson.mjson", + // "values": { + // "number": 42, + // "string": {"<-": "'a string'"} + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // var info = Montage.getInfoForObject(root); + // expect(info.moduleId).toBe("core/core"); + // expect(info.isInstance).toBe(true); + // expect(root.type).toBeUndefined(); + // expect(root.name).toBe("RootObjectDescriptor"); + // expect(root.number).toBe(42); + // expect(root.string).toBe("a string"); + // }).catch(function (reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize singleton using object: module.mjson", function (done) { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "bar": { "@": "bar" }, + // "foo": { "@": "foo" } + // } + // }, + // "bar": { + // "object": "spec/serialization/testmjson.mjson" + // }, + // "foo": { + // "object": "spec/serialization/testmjson.mjson" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserializeObject().then(function (root) { + // expect(root.foo).toBe(root.foo); + // }).catch(function (reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize singleton using the folowing syntax: require('[path].mjson')", function (done) { + // require.async('spec/serialization/testmjson.mjson').then(function (module) { + // expect(module.montageObject).toBeDefined(); + // expect(module.montageObject.name).toBe("RootObjectDescriptor"); + // done(); + // }); + // }); + + // it("should deserialize using instance after compilation", function (done) { + // var latch, objects; + + // deserializer.init({ + // root: { + // prototype: "montage", + // values: { + // number: 15, + // string: "string" + // } + // } + // }, require).deserialize().then(function (objs) { + // latch = true; + // objects = objs; + + // var root = objects.root, + // info = Montage.getInfoForObject(root); + + // expect(Montage.isPrototypeOf(root)); + // expect(info.moduleId).toBe("core/core"); + // expect(info.objectName).toBe("Montage"); + // expect(info.isInstance).toBe(true); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize using type after compilation", function (done) { + // var latch, objects; + + // deserializer.init({ + // root: { + // object: "montage", + // values: { + // number: 15, + // string: "string" + // } + // } + // }, require).deserialize().then(function (objs) { + // latch = true; + // objects = objs; + + // var root = objects.root, + // info = Montage.getInfoForObject(root); + + // expect(root).toBe(Montage); + // expect(info.moduleId).toBe("core/core"); + // expect(info.objectName).toBe("Montage"); + // expect(info.isInstance).toBe(false); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("Module reference deserialization", function () { + // it("should deserialize a module", function (done) { + // var serialization = { + // "root": { + // "value": {"%": "./testobjects-v2"} + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // deserializer.deserializeObject().then(function (root) { + // // module is now absolute from the root of the test package + // expect(root.id).toBe("spec/serialization/testobjects-v2"); + // expect(root.require.location).toBe(require.location); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should use the require of the package the deserializer is using", function (done) { + + // require.loadPackage("spec/package-a").then(function (pkg1) { + // var serialization = { + // "root": { + // "value": {"%": "pass"} + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, pkg1); + + // deserializer.deserializeObject().then(function (root) { + // expect(root.id).toBe("pass"); + // expect(root.require.location).toBe(pkg1.location); + // }).finally(function () { + // done(); + // }); + // }); + // }); + // }); + + // describe("Custom deserialization", function () { + // var customDeserialization = objects.CustomDeserialization, + // serialization = { + // "root": { + // "prototype": "spec/serialization/testobjects-v2[CustomDeserialization]", + // "values": { + // "prop1": 3.14, + // "prop2": {"<-": "@oneprop.prop"} + // }, + // "listeners": [{ + // "type": "action", + // "listener": {"@": "oneprop"} + // }] + // }, + + // "oneprop": { + // "prototype": "spec/serialization/testobjects-v2[OneProp]", + // "values": { + // "prop": 42 + // } + // } + // }; + + // it("should only create the object", function (done) { + // var serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root.prop1).toBeNull(); + // expect(root._bindingDescriptors).toBeFalsy(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should report prototype type", function (done) { + // var serializationString = JSON.stringify(serialization), + // type, + // typeValue; + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // type = deserializer.getType(); + // typeValue = deserializer.getTypeValue(); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(type).toBe("prototype"); + // expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should report object type", function (done) { + // var serialization = { + // "root": { + // "object": "spec/serialization/testobjects-v2[CustomDeserialization]" + // } + // }, + // serializationString = JSON.stringify(serialization), + // type, + // typeValue; + + // deserializer.init( + // serializationString, require); + + // customDeserialization.deserializeSelf = function (deserializer) { + // type = deserializer.getType(); + // typeValue = deserializer.getTypeValue(); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(type).toBe("object"); + // expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should access properties", function (done) { + // var serializationString = JSON.stringify(serialization), + // prop1; + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // prop1 = deserializer.getProperty("prop1"); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(prop1).toBe(3.14); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should only deserialize properties", function (done) { + // var serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // deserializer.deserializeValues(); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root.prop1).toBe(3.14); + // expect(root._bindingDescriptors).toBeFalsy(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // xit("should deserialize properties and listeners", function (done) { + // var serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // deserializer.deserializeValues(); + // deserializer.deserializeUnit("listeners"); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root.prop1).toBe(3.14); + // expect(root._bindingDescriptors).toBeFalsy(); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize properties and bindings", function (done) { + // var serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // deserializer.deserializeValues(); + // deserializer.deserializeUnit("bindings"); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root.prop1).toBe(3.14); + // expect(Bindings.getBindings(root).size).toBeGreaterThan(0); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize properties and all units", function (done) { + // var serializationString = JSON.stringify(serialization); + + // deserializer.init( + // serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // deserializer.deserializeValues(); + // deserializer.deserializeUnits(); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root.prop1).toBe(3.14); + // expect(Bindings.getBindings(root).size).toBeGreaterThan(0); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize into another object in an asynchronous way", function (done) { + // var serializationString = JSON.stringify(serialization), + // newRoot = {}; + + // deserializer.init(serializationString, require); + + // customDeserialization.prototype.deserializeSelf = function (deserializer) { + // return Promise.resolve(newRoot); + // }; + + // deserializer.deserializeObject().then(function (root) { + // expect(root).toBe(newRoot); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // it("should load the correct module even if it's from a diferent package but with the same name", function (done) { + // var deserializer1 = new Deserializer(), + // deserializer2 = new Deserializer(), + // serialization = { + // root: { + // prototype: "ui/main.reel" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // require.loadPackage("spec/package-a").then(function (pkg1) { + // return require.loadPackage("spec/package-b").then(function (pkg2) { + // return deserializer1.init(serializationString, pkg1) + // .deserialize().then(function (object1) { + // return deserializer2.init(serializationString, pkg2) + // .deserialize().then(function (object2) { + // expect(object1.root.name).toBe("A"); + // expect(object2.root.name).toBe("B"); + // }); + // }); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // it("should deserialize null", function (done) { + // var serialization = { + // "a": { + // "value": null + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserializer.init(serializationString, require); + // deserializer.deserialize(serializationString).then(function (objects) { + // expect(objects.a).toBe(null); + // }).catch(function(reason) { + // fail(reason); + // }).finally(function () { + // done(); + // }); + // }); + + // describe("errors", function () { + // it("should fail if no require was given", function () { + // var serialization = { + // "root": { + // "prototype": "montage", + // "values": { + // "number": 42, + // "string": "a string" + // } + // } + // }, + // serializationString = JSON.stringify(serialization); + + // try { + // deserializer.init( + // serializationString, null); + // // should never execute + // expect(true).toBe(false); + // } catch (ex) { + // expect(ex).toBeDefined(); + // } + // }); + + // it("should fail deserialize if serialization is malformed", function (done) { + // var serializationString = "{root:}"; + + // // return a promise when failling. + // deserializer.init(serializationString, require).deserialize().catch(function (ex) { + // expect(ex).toBeDefined(); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("deserialization", function() { + // it("should deserialize a serialization string", function(done) { + // var serialization = { + // "string": { + // "value": "a string" + // }, + + // "number": { + // "value": 42 + // }, + + // "literal": { + // "value": { + // "string": "a string", + // "number": 42 + // } + // } + // }, + // serializationString = JSON.stringify(serialization), + // expectedResult = { + // string: "a string", + // number: 42, + // literal: { + // string: "a string", + // number: 42 + // } + // }, + // deserializer = new Deserializer().init(serializationString, require); + + // deserializer.deserialize().then(function(objects) { + // expect(objects).toEqual(jasmine.objectContaining(expectedResult)); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an object from a serialization string", function(done) { + // var serialization = { + // "root": { + // "value": "a string" + // } + // }, + // serializationString = JSON.stringify(serialization), + // deserializer = new Deserializer().init(serializationString, require); + + // deserializer.deserializeObject().then(function(object) { + // expect(object).toBe("a string"); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should deserialize an external object from a serialization string", function(done) { + // var serialization = { + // "external": {} + // }, + // userObjects = { + // "external": {} + // }, + // serializationString = JSON.stringify(serialization), + // deserializer = new Deserializer().init(serializationString, require); + + // deserializer.deserialize(userObjects).then(function(objects) { + // expect(userObjects.external).toBe(objects.external); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should fail deserializing a missing external object from a serialization string", function(done) { + // var serialization = { + // "external": {} + // }, + // serializationString = JSON.stringify(serialization), + // deserializer = new Deserializer().init(serializationString, require); + + // deserializer.deserialize().then(function(objects) { + // expect("test").toBe("fail"); + // }, function() { + // expect(true).toBe(true); + // }).finally(function () { + // done(); + // }); + // }); + + // it("should be oblivious to Object.prototype aditions", function(done) { + // Object.defineProperty(Object.prototype, "clear", { + // value: function() {}, + // writable: true, + // configurable: true + // }); + + // var serialization = { + // "clear": { + // "value": "a string" + // } + // }, + // serializationString = JSON.stringify(serialization), + // deserializer = new Deserializer().init(serializationString, require); + + // deserializer.deserialize().then(function(object) { + // delete Object.prototype.clear; + // expect(object.clear).toBe("a string"); + // }).finally(function () { + // done(); + // }); + // }); + + // describe("shorthand", function() { + // it("should deserialize an object from a serialization string", function(done) { + // var serialization = { + // "root": { + // "value": "a string" + // } + // }, + // serializationString = JSON.stringify(serialization); + + // deserialize(serializationString, require).then(function(object) { + // expect(object).toEqual("a string"); + // }).finally(function () { + // done(); + // }); + // }); + // }); + + // describe("errors", function() { + // it("should warn about invalid format", function(done) { + // // property name is missing quotes + // var serializationString = '{string: "a string"}'; + + // new Promise(function (resolve, reject) { + // resolve(deserialize(serializationString, require)); // will fail + // }).then(function(objects) { + // // never executed + // }, function(reason) { + // expect(reason).toBeDefined(); + // }).finally(function () { + // done(); + // }); + // }) + // }); + // }); it("handles circular references", function (done) { var serialization = { From 6ba4c76cee7ff736ffb92157a1f3f7dbfa78d2d6 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Tue, 26 Mar 2019 23:04:48 -0700 Subject: [PATCH 41/67] Fixes some specs --- .../montage-deserializer-spec.js | 2832 +++++++++-------- .../serialization/test-object-mjson.mjson | 8 + 2 files changed, 1440 insertions(+), 1400 deletions(-) create mode 100644 test/spec/serialization/test-object-mjson.mjson diff --git a/test/spec/serialization/montage-deserializer-spec.js b/test/spec/serialization/montage-deserializer-spec.js index b7d180dff2..b305e9fb23 100644 --- a/test/spec/serialization/montage-deserializer-spec.js +++ b/test/spec/serialization/montage-deserializer-spec.js @@ -47,1406 +47,1438 @@ describe("serialization/montage-deserializer-spec", function () { deserializer = new Deserializer(); }); - // describe("Montage Objects Deserialization", function () { - // it("should deserialize a class instance object", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // deserializer.deserializeObject().then(function (root) { - // expect(Object.getPrototypeOf(root)).toBe(Montage.prototype); - // expect(root.number).toBe(42); - // expect(root.string).toBe("a string"); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize two class instance objects", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "oneprop": {"@": "oneprop"} - // } - // }, - - // "oneprop": { - // "prototype": "montage", - // "values": { - // "prop": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - - // deserializer.deserializeObject().then(function (root) { - // expect(root.oneprop.prop).toBe(42); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an external object with a label", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "simple": {"@": "simple"} - // } - // }, - - // "simple": {} - // }, - // serializationString = JSON.stringify(serialization), - // simple = {}, - // instances = { - // simple: simple - // }; - - // deserializer.init( - // serializationString, require); - - // deserializer.deserializeObject(instances).then(function (root) { - // expect(root.simple).toBe(simple); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an object as another by providing an instance", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "simple": {"@": "simple"} - // } - // }, - - // "simple": { - // "prototype": "spec/serialization/testobjects-v2[Simple]" - // } - // }, - // serializationString = JSON.stringify(serialization), - // simple = {}, - // instances = { - // simple: simple - // }; - - // deserializer.init(serializationString, require); - - // deserializer.deserializeObject(instances).then(function (root) { - // expect(root.simple).toBe(simple); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize to a different object", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[Singleton]", - // "values": { - // "number": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // deserializer.deserializeObject().then(function (root) { - // expect(root).toBe(objects.Singleton.prototype.instance); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an object's properties when an instance is given for that object", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "number": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization), - // root = {}, - // instances = { - // root: root - // }; - - // deserializer.init( - // serializationString, require); - - // deserializer.deserializeObject(instances).then(function (root) { - // expect(root).toBe(instances.root); - // expect(instances.root.number).toBe(42); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an object's properties when an instance is given for that object even when the serialization doesn't have a prototype or object property", function (done) { - // var serialization = { - // "owner": { - // "values": { - // "number": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization), - // owner = {}, - // instances = { - // owner: owner - // }; - - // deserializer.init( - // serializationString, require); - - // deserializer.deserialize(instances).then(function (objects) { - // expect(objects.owner).toBe(instances.owner); - // expect(instances.owner.number).toBe(42); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize a complex key assignment", function (done) { - // var serialization = { - // "root": { - // "value": { - // "bar": {} - // }, - // "values": { - // "foo": 10, - // "bar.quz": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - // deserialize(serializationString, require).then(function (object) { - // expect(object.foo).toBe(10); - // expect(object.bar.quz).toBe(42); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize a simple one-time assignment in normal form", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "foo": 10, - // "bar": { "=": "foo" } - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - // deserialize(serializationString, require).then(function (object) { - // expect(object.foo).toBe(10); - // expect(object.bar).toBe(10); - // object.foo = 20; - // expect(object.bar).toBe(10); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize a simple one-time assignment with a component reference", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "foo": 10, - // "bar": { "=": "@root.foo" } - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserialize(serializationString, require).then(function (object) { - // expect(object.foo).toBe(10); - // expect(object.bar).toBe(10); - // object.foo = 20; - // expect(object.bar).toBe(10); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize a complex one-time assignment", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "foo": { - // "qux": 10 - // }, - // "a": { - // "b": 10, - // "c": 20 - // }, - // "corge": [ 1, 2, 3, 4, 5 ], - // "bar": { "=": "foo.qux" }, - // "qux": { "=": "foo.qux + 10" }, - // "quuz": { "=": "foo.qux + bar + @root.bar" }, - // "quux": { "=": "corge.sum()" }, - // "quuxz": { "=": 75.5 }, - // "quuxzz": { "=": true }, - // "a.b": { "=": 1 }, - // "a.c": 2 - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserialize(serializationString, require).then(function (object) { - // expect(object.foo.qux).toBe(10); - // expect(object.bar).toBe(10); - // expect(object.qux).toBe(20); - // expect(object.quuz).toBe(30); - // expect(object.quux).toBe(15); - // object.foo.qux = 20; - // expect(object.bar).toBe(10); - // expect(object.qux).toBe(20); - // expect(object.quuxz).toBe(75.5); - // expect(object.quuxzz).toBe(true); - // expect(object.quuxzz).toBe(true); - // expect(object.a.b).toBe(1); - // expect(object.a.c).toBe(2); - // done(); - // }); - // }); - - // it("should fail deserializing an one-time assignment to a non existing object", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "foo": 10, - // "bar": { "=": "@unknown.foo" } - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserialize(serializationString, require).then(function (object) { - // expect("deserialization").toBe("fail"); - // }).catch(function (err) { - // expect(err).toBeDefined(); - // }).finally(function () { - // done(); - // }); - // }); - - - // it("should call deserializedFromSerialization function on the instantiated objects", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[OneProp]", - // "values": { - // "prop": {"@": "oneprop"} - // } - // }, - // "oneprop": { - // "prototype": "spec/serialization/testobjects-v2[OneProp]" - // } - // }, - // serializationString = JSON.stringify(serialization), - // instances = { - // root: new objects.OneProp() - // }; - - // deserializer.init(serializationString, require); - // deserializer.deserialize(instances).then(function (object) { - // var root = object.root, - // oneprop = object.oneprop; - - // expect(root.deserializedFromSerializationCount).toBe(0); - // expect(oneprop.deserializedFromSerializationCount).toBe(1); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // // TODO Deprecated ? - // xit("should call deserializedFromSerialization function on the instantiated objects even if they were given as null instances", function (done) { - // var latch; - // var instances = {root: null}; - // var exports; - - // deserializer.init({ - // root: { - // module: "serialization/testobjects-v2", - // name: "OneProp", - // values: { - // prop: {"@": "oneprop"} - // } - // }, - // oneprop: { - // module: "serialization/testobjects-v2", - // name: "OneProp" - // } - // }, require).deserializeObject(instances, function (objs) { - // latch = true; - // exports = objs; - - // expect(exports.root.deserializedFromSerializationCount).toBe(1); - // done(); - // }); - // }); - - // it("should have isDeserializing set to true during units deserialization", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[OneProp]", - // "values": { - // "prop": 42 - // }, - // "spec": {} - // } - // }, - // serializationString = JSON.stringify(serialization), - // isDeserializing; - - // deserializer.init( - // serializationString, require); - - // Deserializer.defineDeserializationUnit("spec", function (deserializer, object) { - // isDeserializing = object.isDeserializing; - // }); - - // deserializer.deserialize().then(function (objects) { - // expect(isDeserializing).toBeTruthy(); - // expect(objects.root.isDeserializing).toBeUndefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("Alias deserialization", function () { - // it("should deserialize an alias", function (done) { - // var serialization = { - // ":templateProperty": { - // "alias": "@component:propertyName" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function (objects) { - // var alias = objects[":templateProperty"]; - // expect(Object.getPrototypeOf(alias)).toBe(Alias.prototype); - // expect(alias.value).toBe("@component:propertyName"); - // expect(alias.componentLabel).toBe("component"); - // expect(alias.propertyName).toBe("propertyName"); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("Template properties deserialization", function () { - // it("should deserialize a template property as an alias", function (done) { - // var serialization = { - // ":templateProperty": { - // "alias": "@component:propertyName" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function (result) { - // expect(result).toBeDefined(); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should not deserialize a template property as an external object", function (done) { - // var serialization = { - // ":templateProperty": {} - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function () { - // expect("deserialization").toBe("failed"); - // }).catch(function() { - // expect("failed").toBe("failed"); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should not deserialize a montage object as a template property", function (done) { - // var serialization = { - // ":templateProperty": { - // "prototype": "montage/ui/component" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function () { - // expect("deserialization").toBe("failed"); - // }).catch(function() { - // expect("failed").toBe("failed"); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should not deserialize a value as a template property", function (done) { - // var serialization = { - // ":templateProperty": { - // "value": 42 - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function () { - // expect("deserialization").toBe("failed"); - // }).catch(function() { - // expect("failed").toBe("failed"); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should not deserialize a regexp as a template property", function (done) { - // var serialization = { - // ":templateProperty": { - // "/": {"source": "regexp"} - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function () { - // expect("deserialization").toBe("failed"); - // }).catch(function() { - // expect("failed").toBe("failed"); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should not deserialize a literal object as a template property", function (done) { - // var serialization = { - // ":templateProperty": { - // "value": {} - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize().then(function () { - // expect("deserialization").toBe("failed"); - // }).catch(function() { - // expect("failed").toBe("failed"); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("Object Location", function () { - // it("should deserialize using prototype: module[name]", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[TestobjectsV2]", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - // expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); - // expect(root.instance).toBeUndefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using prototype: module", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - - // expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); - - // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - // expect(info.objectName).toBe("TestobjectsV2"); - // expect(info.isInstance).toBe(true); - // expect(root.instance).toBeUndefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using prototype: module-name.reel", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/module-name.reel", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - // expect(info.moduleId).toBe("spec/serialization/module-name.reel"); - // expect(info.objectName).toBe("ModuleName"); - // expect(info.isInstance).toBe(true); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using object: module[name]", function (done) { - // var serialization = { - // "root": { - // "object": "spec/serialization/testobjects-v2[TestobjectsV2]", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - - // expect(root).toBe(objects.TestobjectsV2); - // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - // expect(info.objectName).toBe("TestobjectsV2"); - // expect(info.isInstance).toBe(false); - // expect(root.type).toBeUndefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using object: module", function (done) { - // var serialization = { - // "root": { - // "object": "spec/serialization/testobjects-v2", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - - // expect(root).toBe(objects.TestobjectsV2); - // expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); - // expect(info.objectName).toBe("TestobjectsV2"); - // expect(info.isInstance).toBe(false); - // expect(root.type).toBeUndefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize only when children are deserialized", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - // "properties": { - // "stringProperty": "Parent", - // "array": [ - // {"@": "test"}, - // {"@": "test2"} - // ] - // } - // }, - // "test": { - // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - // "properties": { - // "stringProperty": "Child", - // "objectProperty": {"@": "descriptor"}, - // "parent": {"@": "root"} - // } - // }, - // "test2": { - // "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", - // "properties": { - // "stringProperty": "Child2", - // "objectProperty": {"@": "descriptor"}, - // "parent": {"@": "root"} - // } - // }, - // "descriptor": { - // "object": "spec/serialization/testmjson2.mjson" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // console.log("root", root); - // expect(root).toBeDefined(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using object: module.json", function (done) { - // var serialization = { - // "root": { - // "object": "spec/serialization/testjson.json" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (json) { - // expect("root" in json).toBe(true); - // expect(json.root.foo).toBe("bar"); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using prototype: module.mjson", function (done) { - // var serialization = { - // "root": { - // "prototype": "spec/serialization/testmjson.mjson", - // "values": { - // "number": 42, - // "string": {"<-": "'a string'"} - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - // expect(info.moduleId).toBe("core/core"); - // expect(info.isInstance).toBe(true); - // expect(root.type).toBeUndefined(); - // expect(root.name).toBe("RootObjectDescriptor"); - // expect(root.number).toBe(42); - // expect(root.string).toBe("a string"); - // }).catch(function (reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize instances using prototype: module.mjson", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "bar": { "@": "bar" }, - // "foo": { "@": "foo" } - // } - // }, - // "bar": { - // "prototype": "spec/serialization/testmjson.mjson" - // }, - // "foo": { - // "prototype": "spec/serialization/testmjson.mjson" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // expect(root.foo).not.toBe(root.bar); - // }).catch(function (reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using object: module.mjson", function (done) { - // var serialization = { - // "root": { - // "object": "spec/serialization/testmjson.mjson", - // "values": { - // "number": 42, - // "string": {"<-": "'a string'"} - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // var info = Montage.getInfoForObject(root); - // expect(info.moduleId).toBe("core/core"); - // expect(info.isInstance).toBe(true); - // expect(root.type).toBeUndefined(); - // expect(root.name).toBe("RootObjectDescriptor"); - // expect(root.number).toBe(42); - // expect(root.string).toBe("a string"); - // }).catch(function (reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize singleton using object: module.mjson", function (done) { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "bar": { "@": "bar" }, - // "foo": { "@": "foo" } - // } - // }, - // "bar": { - // "object": "spec/serialization/testmjson.mjson" - // }, - // "foo": { - // "object": "spec/serialization/testmjson.mjson" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserializeObject().then(function (root) { - // expect(root.foo).toBe(root.foo); - // }).catch(function (reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize singleton using the folowing syntax: require('[path].mjson')", function (done) { - // require.async('spec/serialization/testmjson.mjson').then(function (module) { - // expect(module.montageObject).toBeDefined(); - // expect(module.montageObject.name).toBe("RootObjectDescriptor"); - // done(); - // }); - // }); - - // it("should deserialize using instance after compilation", function (done) { - // var latch, objects; - - // deserializer.init({ - // root: { - // prototype: "montage", - // values: { - // number: 15, - // string: "string" - // } - // } - // }, require).deserialize().then(function (objs) { - // latch = true; - // objects = objs; - - // var root = objects.root, - // info = Montage.getInfoForObject(root); - - // expect(Montage.isPrototypeOf(root)); - // expect(info.moduleId).toBe("core/core"); - // expect(info.objectName).toBe("Montage"); - // expect(info.isInstance).toBe(true); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize using type after compilation", function (done) { - // var latch, objects; - - // deserializer.init({ - // root: { - // object: "montage", - // values: { - // number: 15, - // string: "string" - // } - // } - // }, require).deserialize().then(function (objs) { - // latch = true; - // objects = objs; - - // var root = objects.root, - // info = Montage.getInfoForObject(root); - - // expect(root).toBe(Montage); - // expect(info.moduleId).toBe("core/core"); - // expect(info.objectName).toBe("Montage"); - // expect(info.isInstance).toBe(false); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("Module reference deserialization", function () { - // it("should deserialize a module", function (done) { - // var serialization = { - // "root": { - // "value": {"%": "./testobjects-v2"} - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // deserializer.deserializeObject().then(function (root) { - // // module is now absolute from the root of the test package - // expect(root.id).toBe("spec/serialization/testobjects-v2"); - // expect(root.require.location).toBe(require.location); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should use the require of the package the deserializer is using", function (done) { - - // require.loadPackage("spec/package-a").then(function (pkg1) { - // var serialization = { - // "root": { - // "value": {"%": "pass"} - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, pkg1); - - // deserializer.deserializeObject().then(function (root) { - // expect(root.id).toBe("pass"); - // expect(root.require.location).toBe(pkg1.location); - // }).finally(function () { - // done(); - // }); - // }); - // }); - // }); - - // describe("Custom deserialization", function () { - // var customDeserialization = objects.CustomDeserialization, - // serialization = { - // "root": { - // "prototype": "spec/serialization/testobjects-v2[CustomDeserialization]", - // "values": { - // "prop1": 3.14, - // "prop2": {"<-": "@oneprop.prop"} - // }, - // "listeners": [{ - // "type": "action", - // "listener": {"@": "oneprop"} - // }] - // }, - - // "oneprop": { - // "prototype": "spec/serialization/testobjects-v2[OneProp]", - // "values": { - // "prop": 42 - // } - // } - // }; - - // it("should only create the object", function (done) { - // var serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root.prop1).toBeNull(); - // expect(root._bindingDescriptors).toBeFalsy(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should report prototype type", function (done) { - // var serializationString = JSON.stringify(serialization), - // type, - // typeValue; - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // type = deserializer.getType(); - // typeValue = deserializer.getTypeValue(); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(type).toBe("prototype"); - // expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should report object type", function (done) { - // var serialization = { - // "root": { - // "object": "spec/serialization/testobjects-v2[CustomDeserialization]" - // } - // }, - // serializationString = JSON.stringify(serialization), - // type, - // typeValue; - - // deserializer.init( - // serializationString, require); - - // customDeserialization.deserializeSelf = function (deserializer) { - // type = deserializer.getType(); - // typeValue = deserializer.getTypeValue(); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(type).toBe("object"); - // expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should access properties", function (done) { - // var serializationString = JSON.stringify(serialization), - // prop1; - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // prop1 = deserializer.getProperty("prop1"); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(prop1).toBe(3.14); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should only deserialize properties", function (done) { - // var serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // deserializer.deserializeValues(); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root.prop1).toBe(3.14); - // expect(root._bindingDescriptors).toBeFalsy(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // xit("should deserialize properties and listeners", function (done) { - // var serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // deserializer.deserializeValues(); - // deserializer.deserializeUnit("listeners"); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root.prop1).toBe(3.14); - // expect(root._bindingDescriptors).toBeFalsy(); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize properties and bindings", function (done) { - // var serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // deserializer.deserializeValues(); - // deserializer.deserializeUnit("bindings"); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root.prop1).toBe(3.14); - // expect(Bindings.getBindings(root).size).toBeGreaterThan(0); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize properties and all units", function (done) { - // var serializationString = JSON.stringify(serialization); - - // deserializer.init( - // serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // deserializer.deserializeValues(); - // deserializer.deserializeUnits(); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root.prop1).toBe(3.14); - // expect(Bindings.getBindings(root).size).toBeGreaterThan(0); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize into another object in an asynchronous way", function (done) { - // var serializationString = JSON.stringify(serialization), - // newRoot = {}; - - // deserializer.init(serializationString, require); - - // customDeserialization.prototype.deserializeSelf = function (deserializer) { - // return Promise.resolve(newRoot); - // }; - - // deserializer.deserializeObject().then(function (root) { - // expect(root).toBe(newRoot); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // it("should load the correct module even if it's from a diferent package but with the same name", function (done) { - // var deserializer1 = new Deserializer(), - // deserializer2 = new Deserializer(), - // serialization = { - // root: { - // prototype: "ui/main.reel" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // require.loadPackage("spec/package-a").then(function (pkg1) { - // return require.loadPackage("spec/package-b").then(function (pkg2) { - // return deserializer1.init(serializationString, pkg1) - // .deserialize().then(function (object1) { - // return deserializer2.init(serializationString, pkg2) - // .deserialize().then(function (object2) { - // expect(object1.root.name).toBe("A"); - // expect(object2.root.name).toBe("B"); - // }); - // }); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // it("should deserialize null", function (done) { - // var serialization = { - // "a": { - // "value": null - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserializer.init(serializationString, require); - // deserializer.deserialize(serializationString).then(function (objects) { - // expect(objects.a).toBe(null); - // }).catch(function(reason) { - // fail(reason); - // }).finally(function () { - // done(); - // }); - // }); - - // describe("errors", function () { - // it("should fail if no require was given", function () { - // var serialization = { - // "root": { - // "prototype": "montage", - // "values": { - // "number": 42, - // "string": "a string" - // } - // } - // }, - // serializationString = JSON.stringify(serialization); - - // try { - // deserializer.init( - // serializationString, null); - // // should never execute - // expect(true).toBe(false); - // } catch (ex) { - // expect(ex).toBeDefined(); - // } - // }); - - // it("should fail deserialize if serialization is malformed", function (done) { - // var serializationString = "{root:}"; - - // // return a promise when failling. - // deserializer.init(serializationString, require).deserialize().catch(function (ex) { - // expect(ex).toBeDefined(); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("deserialization", function() { - // it("should deserialize a serialization string", function(done) { - // var serialization = { - // "string": { - // "value": "a string" - // }, - - // "number": { - // "value": 42 - // }, - - // "literal": { - // "value": { - // "string": "a string", - // "number": 42 - // } - // } - // }, - // serializationString = JSON.stringify(serialization), - // expectedResult = { - // string: "a string", - // number: 42, - // literal: { - // string: "a string", - // number: 42 - // } - // }, - // deserializer = new Deserializer().init(serializationString, require); - - // deserializer.deserialize().then(function(objects) { - // expect(objects).toEqual(jasmine.objectContaining(expectedResult)); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an object from a serialization string", function(done) { - // var serialization = { - // "root": { - // "value": "a string" - // } - // }, - // serializationString = JSON.stringify(serialization), - // deserializer = new Deserializer().init(serializationString, require); - - // deserializer.deserializeObject().then(function(object) { - // expect(object).toBe("a string"); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should deserialize an external object from a serialization string", function(done) { - // var serialization = { - // "external": {} - // }, - // userObjects = { - // "external": {} - // }, - // serializationString = JSON.stringify(serialization), - // deserializer = new Deserializer().init(serializationString, require); - - // deserializer.deserialize(userObjects).then(function(objects) { - // expect(userObjects.external).toBe(objects.external); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should fail deserializing a missing external object from a serialization string", function(done) { - // var serialization = { - // "external": {} - // }, - // serializationString = JSON.stringify(serialization), - // deserializer = new Deserializer().init(serializationString, require); - - // deserializer.deserialize().then(function(objects) { - // expect("test").toBe("fail"); - // }, function() { - // expect(true).toBe(true); - // }).finally(function () { - // done(); - // }); - // }); - - // it("should be oblivious to Object.prototype aditions", function(done) { - // Object.defineProperty(Object.prototype, "clear", { - // value: function() {}, - // writable: true, - // configurable: true - // }); - - // var serialization = { - // "clear": { - // "value": "a string" - // } - // }, - // serializationString = JSON.stringify(serialization), - // deserializer = new Deserializer().init(serializationString, require); - - // deserializer.deserialize().then(function(object) { - // delete Object.prototype.clear; - // expect(object.clear).toBe("a string"); - // }).finally(function () { - // done(); - // }); - // }); - - // describe("shorthand", function() { - // it("should deserialize an object from a serialization string", function(done) { - // var serialization = { - // "root": { - // "value": "a string" - // } - // }, - // serializationString = JSON.stringify(serialization); - - // deserialize(serializationString, require).then(function(object) { - // expect(object).toEqual("a string"); - // }).finally(function () { - // done(); - // }); - // }); - // }); - - // describe("errors", function() { - // it("should warn about invalid format", function(done) { - // // property name is missing quotes - // var serializationString = '{string: "a string"}'; - - // new Promise(function (resolve, reject) { - // resolve(deserialize(serializationString, require)); // will fail - // }).then(function(objects) { - // // never executed - // }, function(reason) { - // expect(reason).toBeDefined(); - // }).finally(function () { - // done(); - // }); - // }) - // }); - // }); + describe("Montage Objects Deserialization", function () { + it("should deserialize a class instance object", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + deserializer.deserializeObject().then(function (root) { + expect(Object.getPrototypeOf(root)).toBe(Montage.prototype); + expect(root.number).toBe(42); + expect(root.string).toBe("a string"); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize two class instance objects", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "oneprop": {"@": "oneprop"} + } + }, + + "oneprop": { + "prototype": "montage", + "values": { + "prop": 42 + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + + deserializer.deserializeObject().then(function (root) { + expect(root.oneprop.prop).toBe(42); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an external object with a label", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "simple": {"@": "simple"} + } + }, + + "simple": {} + }, + serializationString = JSON.stringify(serialization), + simple = {}, + instances = { + simple: simple + }; + + deserializer.init( + serializationString, require); + + deserializer.deserializeObject(instances).then(function (root) { + expect(root.simple).toBe(simple); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an object as another by providing an instance", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "simple": {"@": "simple"} + } + }, + + "simple": { + "prototype": "spec/serialization/testobjects-v2[Simple]" + } + }, + serializationString = JSON.stringify(serialization), + simple = {}, + instances = { + simple: simple + }; + + deserializer.init(serializationString, require); + + deserializer.deserializeObject(instances).then(function (root) { + expect(root.simple).toBe(simple); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize to a different object", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[Singleton]", + "values": { + "number": 42 + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + deserializer.deserializeObject().then(function (root) { + expect(root).toBe(objects.Singleton.prototype.instance); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an object's properties when an instance is given for that object", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "number": 42 + } + } + }, + serializationString = JSON.stringify(serialization), + root = {}, + instances = { + root: root + }; + + deserializer.init( + serializationString, require); + + deserializer.deserializeObject(instances).then(function (root) { + expect(root).toBe(instances.root); + expect(instances.root.number).toBe(42); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an object's properties when an instance is given for that object even when the serialization doesn't have a prototype or object property", function (done) { + var serialization = { + "owner": { + "values": { + "number": 42 + } + } + }, + serializationString = JSON.stringify(serialization), + owner = {}, + instances = { + owner: owner + }; + + deserializer.init( + serializationString, require); + + deserializer.deserialize(instances).then(function (objects) { + expect(objects.owner).toBe(instances.owner); + expect(instances.owner.number).toBe(42); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize a complex key assignment", function (done) { + var serialization = { + "root": { + "value": { + "bar": {} + }, + "values": { + "foo": 10, + "bar.quz": 42 + } + } + }, + serializationString = JSON.stringify(serialization); + deserialize(serializationString, require).then(function (object) { + expect(object.foo).toBe(10); + expect(object.bar.quz).toBe(42); + }).finally(function () { + done(); + }); + }); + + it("should deserialize a simple one-time assignment in normal form", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "foo": 10, + "bar": { "=": "foo" } + } + } + }, + serializationString = JSON.stringify(serialization); + deserialize(serializationString, require).then(function (object) { + expect(object.foo).toBe(10); + expect(object.bar).toBe(10); + object.foo = 20; + expect(object.bar).toBe(10); + }).finally(function () { + done(); + }); + }); + + it("should deserialize a simple one-time assignment with a component reference", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "foo": 10, + "bar": { "=": "@root.foo" } + } + } + }, + serializationString = JSON.stringify(serialization); + + deserialize(serializationString, require).then(function (object) { + expect(object.foo).toBe(10); + expect(object.bar).toBe(10); + object.foo = 20; + expect(object.bar).toBe(10); + }).finally(function () { + done(); + }); + }); + + it("should deserialize a complex one-time assignment", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "foo": { + "qux": 10 + }, + "a": { + "b": 10, + "c": 20 + }, + "corge": [ 1, 2, 3, 4, 5 ], + "bar": { "=": "foo.qux" }, + "qux": { "=": "foo.qux + 10" }, + "quuz": { "=": "foo.qux + bar + @root.bar" }, + "quux": { "=": "corge.sum()" }, + "quuxz": { "=": 75.5 }, + "quuxzz": { "=": true }, + "a.b": { "=": 1 }, + "a.c": 2 + } + } + }, + serializationString = JSON.stringify(serialization); + + deserialize(serializationString, require).then(function (object) { + expect(object.foo.qux).toBe(10); + expect(object.bar).toBe(10); + expect(object.qux).toBe(20); + expect(object.quuz).toBe(30); + expect(object.quux).toBe(15); + object.foo.qux = 20; + expect(object.bar).toBe(10); + expect(object.qux).toBe(20); + expect(object.quuxz).toBe(75.5); + expect(object.quuxzz).toBe(true); + expect(object.quuxzz).toBe(true); + expect(object.a.b).toBe(1); + expect(object.a.c).toBe(2); + done(); + }); + }); + + it("should fail deserializing an one-time assignment to a non existing object", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "foo": 10, + "bar": { "=": "@unknown.foo" } + } + } + }, + serializationString = JSON.stringify(serialization); + + deserialize(serializationString, require).then(function (object) { + expect("deserialization").toBe("fail"); + }).catch(function (err) { + expect(err).toBeDefined(); + }).finally(function () { + done(); + }); + }); + + + it("should call deserializedFromSerialization function on the instantiated objects", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[OneProp]", + "values": { + "prop": {"@": "oneprop"} + } + }, + "oneprop": { + "prototype": "spec/serialization/testobjects-v2[OneProp]" + } + }, + serializationString = JSON.stringify(serialization), + instances = { + root: new objects.OneProp() + }; + + deserializer.init(serializationString, require); + deserializer.deserialize(instances).then(function (object) { + var root = object.root, + oneprop = object.oneprop; + + expect(root.deserializedFromSerializationCount).toBe(0); + expect(oneprop.deserializedFromSerializationCount).toBe(1); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + // TODO Deprecated ? + xit("should call deserializedFromSerialization function on the instantiated objects even if they were given as null instances", function (done) { + var latch; + var instances = {root: null}; + var exports; + + deserializer.init({ + root: { + module: "serialization/testobjects-v2", + name: "OneProp", + values: { + prop: {"@": "oneprop"} + } + }, + oneprop: { + module: "serialization/testobjects-v2", + name: "OneProp" + } + }, require).deserializeObject(instances, function (objs) { + latch = true; + exports = objs; + + expect(exports.root.deserializedFromSerializationCount).toBe(1); + done(); + }); + }); + + it("should have isDeserializing set to true during units deserialization", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[OneProp]", + "values": { + "prop": 42 + }, + "spec": {} + } + }, + serializationString = JSON.stringify(serialization), + isDeserializing; + + deserializer.init( + serializationString, require); + + Deserializer.defineDeserializationUnit("spec", function (deserializer, object) { + isDeserializing = object.isDeserializing; + }); + + deserializer.deserialize().then(function (objects) { + expect(isDeserializing).toBeTruthy(); + expect(objects.root.isDeserializing).toBeUndefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + }); + + describe("Alias deserialization", function () { + it("should deserialize an alias", function (done) { + var serialization = { + ":templateProperty": { + "alias": "@component:propertyName" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function (objects) { + var alias = objects[":templateProperty"]; + expect(Object.getPrototypeOf(alias)).toBe(Alias.prototype); + expect(alias.value).toBe("@component:propertyName"); + expect(alias.componentLabel).toBe("component"); + expect(alias.propertyName).toBe("propertyName"); + }).finally(function () { + done(); + }); + }); + }); + + describe("Template properties deserialization", function () { + it("should deserialize a template property as an alias", function (done) { + var serialization = { + ":templateProperty": { + "alias": "@component:propertyName" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function (result) { + expect(result).toBeDefined(); + }).finally(function () { + done(); + }); + }); + + it("should not deserialize a template property as an external object", function (done) { + var serialization = { + ":templateProperty": {} + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function () { + expect("deserialization").toBe("failed"); + }).catch(function() { + expect("failed").toBe("failed"); + }).finally(function () { + done(); + }); + }); + + it("should not deserialize a montage object as a template property", function (done) { + var serialization = { + ":templateProperty": { + "prototype": "montage/ui/component" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function () { + expect("deserialization").toBe("failed"); + }).catch(function() { + expect("failed").toBe("failed"); + }).finally(function () { + done(); + }); + }); + + it("should not deserialize a value as a template property", function (done) { + var serialization = { + ":templateProperty": { + "value": 42 + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function () { + expect("deserialization").toBe("failed"); + }).catch(function() { + expect("failed").toBe("failed"); + }).finally(function () { + done(); + }); + }); + + it("should not deserialize a regexp as a template property", function (done) { + var serialization = { + ":templateProperty": { + "/": {"source": "regexp"} + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function () { + expect("deserialization").toBe("failed"); + }).catch(function() { + expect("failed").toBe("failed"); + }).finally(function () { + done(); + }); + }); + + it("should not deserialize a literal object as a template property", function (done) { + var serialization = { + ":templateProperty": { + "value": {} + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize().then(function () { + expect("deserialization").toBe("failed"); + }).catch(function() { + expect("failed").toBe("failed"); + }).finally(function () { + done(); + }); + }); + }); + + describe("Object Location", function () { + it("should deserialize using prototype: module[name]", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[TestobjectsV2]", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); + expect(root.instance).toBeUndefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using prototype: module", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + + expect(Object.getPrototypeOf(root)).toBe(objects.TestobjectsV2.prototype); + + expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + expect(info.objectName).toBe("TestobjectsV2"); + expect(info.isInstance).toBe(true); + expect(root.instance).toBeUndefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using prototype: module-name.reel", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/module-name.reel", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + expect(info.moduleId).toBe("spec/serialization/module-name.reel"); + expect(info.objectName).toBe("ModuleName"); + expect(info.isInstance).toBe(true); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using object: module[name]", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/testobjects-v2[TestobjectsV2]", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + + expect(root).toBe(objects.TestobjectsV2); + expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + expect(info.objectName).toBe("TestobjectsV2"); + expect(info.isInstance).toBe(false); + expect(root.type).toBeUndefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using object: module", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/testobjects-v2", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + + expect(root).toBe(objects.TestobjectsV2); + expect(info.moduleId).toBe("spec/serialization/testobjects-v2"); + expect(info.objectName).toBe("TestobjectsV2"); + expect(info.isInstance).toBe(false); + expect(root.type).toBeUndefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize only when children are deserialized", function (done) { + var serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + "properties": { + "stringProperty": "Parent", + "array": [ + {"@": "test"}, + {"@": "test2"} + ] + } + }, + "test": { + "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + "properties": { + "stringProperty": "Child", + "objectProperty": {"@": "descriptor"}, + "parent": {"@": "root"} + } + }, + "test2": { + "prototype": "spec/serialization/testobjects-v2[SelfDeserializer]", + "properties": { + "stringProperty": "Child2", + "objectProperty": {"@": "descriptor"}, + "parent": {"@": "root"} + } + }, + "descriptor": { + "object": "spec/serialization/testmjson2.mjson" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + console.log("root", root); + expect(root).toBeDefined(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using object: module.json", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/testjson.json" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (json) { + expect("root" in json).toBe(true); + expect(json.root.foo).toBe("bar"); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using prototype: module.mjson", function (done) { + //The fact that this is a string created in montage-deserializer-spec + //makes harder to assess what moduleId should really be expected. + var serialization = { + "root": { + "prototype": "spec/serialization/testmjson.mjson", + "values": { + "number": 42, + "string": {"<-": "'a string'"} + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + expect(info.moduleId).toBe("spec/serialization/testmjson.mjson"); + expect(info.isInstance).toBe(true); + expect(root.type).toBeUndefined(); + expect(root.name).toBe("RootObjectDescriptor"); + expect(root.number).toBe(42); + expect(root.string).toBe("a string"); + }).catch(function (reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize instances using prototype: module.mjson", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "bar": { "@": "bar" }, + "foo": { "@": "foo" } + } + }, + "bar": { + "prototype": "spec/serialization/testmjson.mjson" + }, + "foo": { + "prototype": "spec/serialization/testmjson.mjson" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + expect(root.foo).not.toBe(root.bar); + }).catch(function (reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using object: module.mjson", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/testmjson.mjson", + "values": { + "number": 42, + "string": {"<-": "'a string'"} + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + expect(info.moduleId).toBe("spec/serialization/testmjson.mjson"); + expect(info.isInstance).toBe(true); + expect(root.type).toBeUndefined(); + expect(root.name).toBe("RootObjectDescriptor"); + expect(root.number).toBe(42); + expect(root.string).toBe("a string"); + }).catch(function (reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + //TODO + it("should deserialize using object: module.mjson, object created", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/test-object-mjson.mjson", + "values": { + "number": 42, + "string": {"<-": "'a string'"} + } + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + var info = Montage.getInfoForObject(root); + expect(info.moduleId).toBe("core/core"); + expect(info.isInstance).toBe(true); + expect(root.type).toBeUndefined(); + expect(root.blah).toBe("RootObjectDescriptor"); + expect(root.number).toBe(42); + expect(root.string).toBe("a string"); + }).catch(function (reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + + it("should deserialize singleton using object: module.mjson", function (done) { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "bar": { "@": "bar" }, + "foo": { "@": "foo" } + } + }, + "bar": { + "object": "spec/serialization/testmjson.mjson" + }, + "foo": { + "object": "spec/serialization/testmjson.mjson" + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserializeObject().then(function (root) { + expect(root.foo).toBe(root.foo); + }).catch(function (reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize singleton using the folowing syntax: require('[path].mjson')", function (done) { + require.async('spec/serialization/testmjson.mjson').then(function (module) { + expect(module.montageObject).toBeDefined(); + expect(module.montageObject.name).toBe("RootObjectDescriptor"); + done(); + }); + }); + + it("should deserialize using instance after compilation", function (done) { + var latch, objects; + + deserializer.init({ + root: { + prototype: "montage", + values: { + number: 15, + string: "string" + } + } + }, require).deserialize().then(function (objs) { + latch = true; + objects = objs; + + var root = objects.root, + info = Montage.getInfoForObject(root); + + expect(Montage.isPrototypeOf(root)); + expect(info.moduleId).toBe("core/core"); + expect(info.objectName).toBe("Montage"); + expect(info.isInstance).toBe(true); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize using type after compilation", function (done) { + var latch, objects; + + deserializer.init({ + root: { + object: "montage", + values: { + number: 15, + string: "string" + } + } + }, require).deserialize().then(function (objs) { + latch = true; + objects = objs; + + var root = objects.root, + info = Montage.getInfoForObject(root); + + expect(root).toBe(Montage); + expect(info.moduleId).toBe("core/core"); + expect(info.objectName).toBe("Montage"); + expect(info.isInstance).toBe(false); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + }); + + describe("Module reference deserialization", function () { + it("should deserialize a module", function (done) { + var serialization = { + "root": { + "value": {"%": "./testobjects-v2"} + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + deserializer.deserializeObject().then(function (root) { + // module is now absolute from the root of the test package + expect(root.id).toBe("spec/serialization/testobjects-v2"); + expect(root.require.location).toBe(require.location); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should use the require of the package the deserializer is using", function (done) { + + require.loadPackage("spec/package-a").then(function (pkg1) { + var serialization = { + "root": { + "value": {"%": "pass"} + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, pkg1); + + deserializer.deserializeObject().then(function (root) { + expect(root.id).toBe("pass"); + expect(root.require.location).toBe(pkg1.location); + }).finally(function () { + done(); + }); + }); + }); + }); + + describe("Custom deserialization", function () { + var customDeserialization = objects.CustomDeserialization, + serialization = { + "root": { + "prototype": "spec/serialization/testobjects-v2[CustomDeserialization]", + "values": { + "prop1": 3.14, + "prop2": {"<-": "@oneprop.prop"} + }, + "listeners": [{ + "type": "action", + "listener": {"@": "oneprop"} + }] + }, + + "oneprop": { + "prototype": "spec/serialization/testobjects-v2[OneProp]", + "values": { + "prop": 42 + } + } + }; + + it("Empty deserializeSelf should only create the object and not set values", function (done) { + var serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + + }; + + deserializer.deserializeObject().then(function (root) { + expect(root.prop1).toBeNull(); + expect(root._bindingDescriptors).toBeFalsy(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should report prototype type", function (done) { + var serializationString = JSON.stringify(serialization), + type, + typeValue; + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + type = deserializer.getType(); + typeValue = deserializer.getTypeValue(); + }; + + deserializer.deserializeObject().then(function (root) { + expect(type).toBe("prototype"); + expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should report object type", function (done) { + var serialization = { + "root": { + "object": "spec/serialization/testobjects-v2[CustomDeserialization]" + } + }, + serializationString = JSON.stringify(serialization), + type, + typeValue; + + deserializer.init( + serializationString, require); + + customDeserialization.deserializeSelf = function (deserializer) { + type = deserializer.getType(); + typeValue = deserializer.getTypeValue(); + }; + + deserializer.deserializeObject().then(function (root) { + expect(type).toBe("object"); + expect(typeValue).toBe("spec/serialization/testobjects-v2[CustomDeserialization]"); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should access properties", function (done) { + var serializationString = JSON.stringify(serialization), + prop1; + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + prop1 = deserializer.getProperty("prop1"); + }; + + deserializer.deserializeObject().then(function (root) { + expect(prop1).toBe(3.14); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should only deserialize properties", function (done) { + var serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + deserializer.deserializeValues(); + }; + + deserializer.deserializeObject().then(function (root) { + expect(root.prop1).toBe(3.14); + expect(root._bindingDescriptors).toBeFalsy(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + xit("should deserialize properties and listeners", function (done) { + var serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + deserializer.deserializeValues(); + deserializer.deserializeUnit("listeners"); + }; + + deserializer.deserializeObject().then(function (root) { + expect(root.prop1).toBe(3.14); + expect(root._bindingDescriptors).toBeFalsy(); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize properties and bindings", function (done) { + var serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + deserializer.deserializeValues(); + deserializer.deserializeUnit("bindings"); + }; + + deserializer.deserializeObject().then(function (root) { + expect(root.prop1).toBe(3.14); + expect(Bindings.getBindings(root).size).toBeGreaterThan(0); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize properties and all units", function (done) { + var serializationString = JSON.stringify(serialization); + + deserializer.init( + serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + deserializer.deserializeValues(); + deserializer.deserializeUnits(); + }; + + deserializer.deserializeObject().then(function (root) { + expect(root.prop1).toBe(3.14); + expect(Bindings.getBindings(root).size).toBeGreaterThan(0); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + it("should deserialize into another object in an asynchronous way", function (done) { + var serializationString = JSON.stringify(serialization), + newRoot = {}; + + deserializer.init(serializationString, require); + + customDeserialization.prototype.deserializeSelf = function (deserializer) { + return Promise.resolve(newRoot); + }; + + deserializer.deserializeObject().then(function (root) { + expect(root).toBe(newRoot); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + }); + + it("should load the correct module even if it's from a diferent package but with the same name", function (done) { + var deserializer1 = new Deserializer(), + deserializer2 = new Deserializer(), + serialization = { + root: { + prototype: "ui/main.reel" + } + }, + serializationString = JSON.stringify(serialization); + + require.loadPackage("spec/package-a").then(function (pkg1) { + return require.loadPackage("spec/package-b").then(function (pkg2) { + return deserializer1.init(serializationString, pkg1) + .deserialize().then(function (object1) { + return deserializer2.init(serializationString, pkg2) + .deserialize().then(function (object2) { + expect(object1.root.name).toBe("A"); + expect(object2.root.name).toBe("B"); + }); + }); + }).finally(function () { + done(); + }); + }); + }); + + it("should deserialize null", function (done) { + var serialization = { + "a": { + "value": null + } + }, + serializationString = JSON.stringify(serialization); + + deserializer.init(serializationString, require); + deserializer.deserialize(serializationString).then(function (objects) { + expect(objects.a).toBe(null); + }).catch(function(reason) { + fail(reason); + }).finally(function () { + done(); + }); + }); + + describe("errors", function () { + it("should fail if no require was given", function () { + var serialization = { + "root": { + "prototype": "montage", + "values": { + "number": 42, + "string": "a string" + } + } + }, + serializationString = JSON.stringify(serialization); + + try { + deserializer.init( + serializationString, null); + // should never execute + expect(true).toBe(false); + } catch (ex) { + expect(ex).toBeDefined(); + } + }); + + it("should fail deserialize if serialization is malformed", function (done) { + var serializationString = "{root:}"; + + // return a promise when failling. + deserializer.init(serializationString, require).deserialize().catch(function (ex) { + expect(ex).toBeDefined(); + }).finally(function () { + done(); + }); + }); + }); + + describe("deserialization", function() { + it("should deserialize a serialization string", function(done) { + var serialization = { + "string": { + "value": "a string" + }, + + "number": { + "value": 42 + }, + + "literal": { + "value": { + "string": "a string", + "number": 42 + } + } + }, + serializationString = JSON.stringify(serialization), + expectedResult = { + string: "a string", + number: 42, + literal: { + string: "a string", + number: 42 + } + }, + deserializer = new Deserializer().init(serializationString, require); + + deserializer.deserialize().then(function(objects) { + expect(objects).toEqual(jasmine.objectContaining(expectedResult)); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an object from a serialization string", function(done) { + var serialization = { + "root": { + "value": "a string" + } + }, + serializationString = JSON.stringify(serialization), + deserializer = new Deserializer().init(serializationString, require); + + deserializer.deserializeObject().then(function(object) { + expect(object).toBe("a string"); + }).finally(function () { + done(); + }); + }); + + it("should deserialize an external object from a serialization string", function(done) { + var serialization = { + "external": {} + }, + userObjects = { + "external": {} + }, + serializationString = JSON.stringify(serialization), + deserializer = new Deserializer().init(serializationString, require); + + deserializer.deserialize(userObjects).then(function(objects) { + expect(userObjects.external).toBe(objects.external); + }).finally(function () { + done(); + }); + }); + + it("should fail deserializing a missing external object from a serialization string", function(done) { + var serialization = { + "external": {} + }, + serializationString = JSON.stringify(serialization), + deserializer = new Deserializer().init(serializationString, require); + + deserializer.deserialize().then(function(objects) { + expect("test").toBe("fail"); + }, function() { + expect(true).toBe(true); + }).finally(function () { + done(); + }); + }); + + it("should be oblivious to Object.prototype aditions", function(done) { + Object.defineProperty(Object.prototype, "clear", { + value: function() {}, + writable: true, + configurable: true + }); + + var serialization = { + "clear": { + "value": "a string" + } + }, + serializationString = JSON.stringify(serialization), + deserializer = new Deserializer().init(serializationString, require); + + deserializer.deserialize().then(function(object) { + delete Object.prototype.clear; + expect(object.clear).toBe("a string"); + }).finally(function () { + done(); + }); + }); + + describe("shorthand", function() { + it("should deserialize an object from a serialization string", function(done) { + var serialization = { + "root": { + "value": "a string" + } + }, + serializationString = JSON.stringify(serialization); + + deserialize(serializationString, require).then(function(object) { + expect(object).toEqual("a string"); + }).finally(function () { + done(); + }); + }); + }); + + describe("errors", function() { + it("should warn about invalid format", function(done) { + // property name is missing quotes + var serializationString = '{string: "a string"}'; + + new Promise(function (resolve, reject) { + resolve(deserialize(serializationString, require)); // will fail + }).then(function(objects) { + // never executed + }, function(reason) { + expect(reason).toBeDefined(); + }).finally(function () { + done(); + }); + }) + }); + }); it("handles circular references", function (done) { var serialization = { diff --git a/test/spec/serialization/test-object-mjson.mjson b/test/spec/serialization/test-object-mjson.mjson new file mode 100644 index 0000000000..19af4b28f3 --- /dev/null +++ b/test/spec/serialization/test-object-mjson.mjson @@ -0,0 +1,8 @@ +{ + "root": { + "object": "montage/core/core[Montage]", + "values": { + "blah": "RootObjectDescriptor" + } + } +} From 67670e1f6282b84dded5c67087f5982a259ee54f Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 16:47:39 -0700 Subject: [PATCH 42/67] Refctors to pass whole module to deserializer.init --- montage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/montage.js b/montage.js index 9cf4ea048f..1dda81a16e 100644 --- a/montage.js +++ b/montage.js @@ -423,7 +423,7 @@ deserializerRequire = require.config.requireForId(module.id), root; module.deserializer = deserializer; - deserializer.init(module.text, deserializerRequire, void 0, deserializerRequire.location + module.id, true); + deserializer.init(module.text, deserializerRequire, void 0, module, true); root = deserializer.deserializeObject(); // console.log("********MJSONCompilerFactory END compileMJSONFile",module.id); From 8f225f10cb272e810eedbb8a81f6234c7ab93f42 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 18:47:01 -0700 Subject: [PATCH 43/67] Don't set objectDescriptor when deserializing if value is undefined or null, the obect can't function without one. TODO throw if none present at the end --- data/service/expression-data-mapping.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/data/service/expression-data-mapping.js b/data/service/expression-data-mapping.js index 351934c4b3..6c7dea3348 100644 --- a/data/service/expression-data-mapping.js +++ b/data/service/expression-data-mapping.js @@ -70,11 +70,13 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData self = this, hasReferences = false, result = this; - if (value instanceof ObjectDescriptorReference) { - this.objectDescriptorReference = value; - hasReferences = true; - } else { - this.objectDescriptor = value; + if (value) { + if (value instanceof ObjectDescriptorReference) { + this.objectDescriptorReference = value; + hasReferences = true; + } else { + this.objectDescriptor = value; + } } this.schemaReference = deserializer.getProperty("schema"); From 3cff4198e3bdc54bcb44ee565121df00bfdff005 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 18:49:01 -0700 Subject: [PATCH 44/67] Addresses the last issues and regressions involving loading a graph of mjson files, opening the door to easier data models, object descriptors to be shared and reused --- core/core.js | 24 +- .../deserializer/montage-deserializer.js | 12 +- .../deserializer/montage-interpreter.js | 180 ++++++--- .../deserializer/montage-reviver.js | 351 +++++++++++++----- .../deserializer/self-deserializer.js | 1 + .../deserializer/unit-deserializer.js | 6 + .../montage-deserializer-spec.js | 9 +- 7 files changed, 406 insertions(+), 177 deletions(-) diff --git a/core/core.js b/core/core.js index fcd2f05df5..46a1a92dc8 100644 --- a/core/core.js +++ b/core/core.js @@ -308,8 +308,8 @@ Object.defineProperty(Montage.prototype, _serializableAttributeProperties, { var ObjectAttributeProperties = new Map(); function getAttributeProperties(proto, attributeName, privateAttributeName) { var attributePropertyName = privateAttributeName || ( - attributeName === SERIALIZABLE ? - _serializableAttributeProperties : + attributeName === SERIALIZABLE ? + _serializableAttributeProperties : (UNDERSCORE + attributeName + ATTRIBUTE_PROPERTIES)); if(proto !== Object.prototype) { @@ -422,7 +422,7 @@ valuePropertyDescriptor.value = function Montage_defineProperty(obj, prop, descr if (! (typeof obj === "object" || typeof obj === FUNCTION) || obj === null) { throw new TypeError("Object must be an object, not '" + obj + "'"); } - + var isValueDescriptor = (VALUE in descriptor); // reset defaults appropriately for framework. @@ -548,8 +548,8 @@ function __findSuperMethodImplementation( method, classFn, isFunctionSuper, meth if(!methodPropertyName) { //If methodPropertyNameArg is passed as an argument, we know what to look for, //But it may not be there... - propertyNames = methodPropertyNameArg ? - (_propertyNames[0] = methodPropertyNameArg) && _propertyNames : + propertyNames = methodPropertyNameArg ? + (_propertyNames[0] = methodPropertyNameArg) && _propertyNames : Object.getOwnPropertyNames(context); //As we start, we don't really know which property name points to method, we're going to find out: @@ -675,13 +675,13 @@ function __super(callerFn, methodPropertyName, isValue, isGetter, isSetter) { */ function _super() { // Figure out which function called us. - var callerFn = ( _super && _super.caller ) ? _super.caller : arguments.callee.caller, + var callerFn = ( _super && _super.caller ) ? _super.caller : arguments.callee.caller, superFn = __super.call(this,callerFn); return superFn ? superFn.apply(this, arguments) : undefined; } function _superForValue(methodName) { - var callerFn = ( _superForValue && _superForValue.caller ) ? _superForValue.caller : arguments.callee.caller, + var callerFn = ( _superForValue && _superForValue.caller ) ? _superForValue.caller : arguments.callee.caller, superFn = __super.call(this, callerFn, methodName, true, false, false); //We may need to cache that at some point if it gets called too often @@ -689,7 +689,7 @@ function _superForValue(methodName) { } function _superForGet(methodName) { - var callerFn = ( _superForGet && _superForGet.caller ) ? _superForGet.caller : arguments.callee.caller, + var callerFn = ( _superForGet && _superForGet.caller ) ? _superForGet.caller : arguments.callee.caller, superFn = __super.call(this, callerFn, methodName, false, true, false); //We may need to cache that at some point if it gets called too often @@ -697,7 +697,7 @@ function _superForGet(methodName) { } function _superForSet(methodName) { - var callerFn = ( _superForSet && _superForSet.caller ) ? _superForSet.caller : arguments.callee.caller, + var callerFn = ( _superForSet && _superForSet.caller ) ? _superForSet.caller : arguments.callee.caller, superFn = __super.call(this,callerFn,methodName,false,false,true); //We may need to cache that at some point if it gets called too often @@ -828,7 +828,7 @@ Montage.defineProperty(Montage, "getPropertyAttributes", {value: function (anObj for (var name in attributes) { if (hasProperty.call(attributes, name)) { attributeValues[name] = attributes[name]; - // should return the inherited defined attribute values + // should return the inherited defined attribute values } else { attributeValues[name] = attributes[name]; } @@ -979,7 +979,7 @@ Montage.defineProperty(Montage.prototype, "callDelegateMethod", { var delegateFunctionName = this.identifier + name.toCapitalized(); if ( - typeof this.identifier === "string" && + typeof this.identifier === "string" && typeof delegate[delegateFunctionName] === FUNCTION ) { delegateFunction = delegate[delegateFunctionName]; @@ -1666,7 +1666,7 @@ exports._objectDescriptorDescriptor = { get: function () { var info = Montage.getInfoForObject(this), self = info && !info.isInstance ? this : this.constructor; - + if (!Object.getOwnPropertyDescriptor(self, "_objectDescriptor") || !self._objectDescriptor ) { diff --git a/core/serialization/deserializer/montage-deserializer.js b/core/serialization/deserializer/montage-deserializer.js index e9bbed84b6..9d42763cc6 100644 --- a/core/serialization/deserializer/montage-deserializer.js +++ b/core/serialization/deserializer/montage-deserializer.js @@ -25,17 +25,19 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ }, init: { - value: function (serialization, _require, objectRequires, locationId, isSync) { + value: function (serialization, _require, objectRequires, module, isSync) { if (typeof serialization === "string") { this._serializationString = serialization; } else { this._serializationString = JSON.stringify(serialization); } this._require = _require; - this._locationId = locationId ? locationId.indexOf(_require.location) === 0 ? locationId : _require.location + locationId : locationId; + this._module = module; + var locationId = module && _require.location + module.id; + this._locationId = locationId; this._reviver = new MontageReviver().init( - _require, objectRequires, this.constructor, isSync + _require, objectRequires, this, isSync, locationId ); this._isSync = isSync; @@ -55,7 +57,7 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ */ deserialize: { value: function (instances, element) { - var context = this._locationId && MontageDeserializer.moduleContexts.get(this._locationId), + var context = this._module && MontageDeserializer.moduleContexts.get(this._module), circularError; if (context) { if (context._objects.root) { @@ -79,7 +81,7 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ context = new MontageContext() .init(serialization, this._reviver, instances, element, this._require, this._isSync); if (this._locationId) { - MontageDeserializer.moduleContexts.set(this._locationId, context); + MontageDeserializer.moduleContexts.set(this._module, context); } try { return context.getObjects(); diff --git a/core/serialization/deserializer/montage-interpreter.js b/core/serialization/deserializer/montage-interpreter.js index 13f3319865..0fc5c2fa47 100644 --- a/core/serialization/deserializer/montage-interpreter.js +++ b/core/serialization/deserializer/montage-interpreter.js @@ -2,6 +2,7 @@ var Montage = require("../../core").Montage, MontageReviver = require("./montage-reviver").MontageReviver, Promise = require("../../promise").Promise, deprecate = require("../../deprecate"), + Set = require("collections/set"), ONE_ASSIGNMENT = "=", ONE_WAY = "<-", TWO_WAY = "<->"; @@ -77,9 +78,13 @@ var MontageInterpreter = Montage.specialize({ } }); +var idCount = 0; var MontageContext = Montage.specialize({ _ELEMENT_ID_ATTRIBUTE: {value: "data-montage-id"}, - _unitsToDeserialize: {value: null}, + _ELEMENT_ID_SELECTOR_PREFIX: {value: '*[data-montage-id="'}, + _ELEMENT_ID_SELECTOR_SUFFIX: {value: '"]'}, + unitsToDeserialize: {value: null}, + _mjsonDependencies: {value: null}, _element: {value: null}, _require: {value: null}, _objects: {value: null}, @@ -90,7 +95,7 @@ var MontageContext = Montage.specialize({ constructor: { value: function () { - this._unitsToDeserialize = []; + this.unitsToDeserialize = new Map(); } }, @@ -160,19 +165,22 @@ var MontageContext = Montage.specialize({ serialization = this._serialization, promises, result, - objectKeys = Object.keys(serialization); + objectKeys; - for (var i=0, label;(label = objectKeys[i]); i++) { - result = this.getObject(label); + if(serialization) { + objectKeys = Object.keys(serialization); + for (var i=0, label;(label = objectKeys[i]); i++) { + result = this.getObject(label); - if (Promise.is(result)) { - (promises || (promises = [])).push(result); + if (Promise.is(result)) { + (promises || (promises = [])).push(result); + } } } if (!promises || promises.length === 0) { result = this._invokeDidReviveObjects(); - return this._isSync ? result : Promise.resolve(result); + return this._isSync ? result : Promise.is(result) ? result : Promise.resolve(result); } else { // We shouldn't get here if this._isSync is true return Promise.all(promises).then(function() { @@ -207,11 +215,10 @@ var MontageContext = Montage.specialize({ _invokeDidReviveObjects: { value: function() { var self = this, - reviver = this._reviver, - result; + reviver = this._reviver; if (typeof reviver.didReviveObjects === "function") { - reviver.didReviveObjects(this._objects, this); + reviver.didReviveObjects(this); return self._objects; } @@ -239,31 +246,55 @@ var MontageContext = Montage.specialize({ getElementById: { value: function (id) { - var selector = '*[' + this._ELEMENT_ID_ATTRIBUTE + '="' + id + '"]'; - - return this._element.querySelector(selector); + return this._element.querySelector(this._ELEMENT_ID_SELECTOR_PREFIX + id + this._ELEMENT_ID_SELECTOR_SUFFIX); } }, - _extractBindingsToDeserialize: { - value: function (values, bindings) { - var value; - - for (var key in values) { - if (values.hasOwnProperty(key)) { - value = values[key]; - - if ((typeof value === "object" && value && - Object.keys(value).length === 1 && - (ONE_WAY in value || TWO_WAY in value || ONE_ASSIGNMENT in value)) || - key.indexOf('.') > -1 - ) { - bindings[key] = value; - delete values[key]; + _classifyValuesToDeserialize: { + value: function (object, objectDesc, bindings) { + var values, + value, + keys, + objectValuesToDeserialize, + objectProperties, + bindings; + + + //This is where we support backward compatib + if((values = objectDesc.properties)) { + objectDesc.values = values; + delete objectDesc.properties; + } + else { + if((values = objectDesc.values)) { + keys = Object.keys(values); + bindings = objectDesc.bindings || (objectDesc.bindings = {}); + for (var i=0, key;(key = keys[i]);i++) { + value = values[key]; + + //An expression based property + if ((typeof value === "object" && value && + Object.keys(value).length === 1 && + (ONE_WAY in value || TWO_WAY in value || ONE_ASSIGNMENT in value)) || + key.indexOf('.') > -1 + ) { + bindings[key] = value; + delete values[key]; + } + //A flat property + // else { + // objectProperties = (objectValuesToDeserialize || (objectValuesToDeserialize = this.objectValuesToDeserialize)).get(object); + // if(!objectProperties) { + // objectValuesToDeserialize.set(object,(objectProperties = [])); + // } + // objectProperties.push(key); + // } } + } } + return bindings; } }, @@ -274,44 +305,83 @@ var MontageContext = Montage.specialize({ } }, + __propertyToReviveForObjectLiteralValue: { + value: undefined + }, + _propertyToReviveForObjectLiteralValue: { + get: function() { + return this.__propertyToReviveForObjectLiteralValue || (this.__propertyToReviveForObjectLiteralValue = new WeakMap()); + } + }, + propertyToReviveForObjectLiteralValue: { + value: function (objectLiteralValue) { + var propertyToRevive; + if(!(propertyToRevive = this._propertyToReviveForObjectLiteralValue.get(objectLiteralValue))) { + this._propertyToReviveForObjectLiteralValue.set(objectLiteralValue,(propertyToRevive = new Set(Object.keys(objectLiteralValue)))); + } + return propertyToRevive; + } + }, + + _objectDynamicValuesToDeserialize: { + value: undefined + }, + _objectValuesToDeserialize: { + value: undefined + }, + objectValuesToDeserialize: { + get: function() { + return this._objectValuesToDeserialize || (this._objectValuesToDeserialize = new Map()); + } + }, + + + setBindingsToDeserialize: { value: function (object, objectDesc) { - var bindings = Object.create(null); + this._classifyValuesToDeserialize(object, objectDesc); + } + }, + + setUnitsToDeserialize: { + value: function (object, objectDesc, unitNames) { + + var moduleId = objectDesc.prototype || objectDesc.object, + isMJSONDependency = moduleId && (moduleId.endsWith(".mjson") || moduleId.endsWith(".meta")), + unitsDesc = this.unitsToDeserialize.get(object); - if (objectDesc.values) { - this._extractBindingsToDeserialize(objectDesc.values, bindings); - } else if (objectDesc.properties) { // deprecated - this._extractBindingsToDeserialize(objectDesc.properties, bindings); + if(isMJSONDependency) { + (this._mjsonDependencies || (this._mjsonDependencies = new Set())).add(moduleId); } - if (Object.keys(bindings).length > 0) { - if (!this._bindingsToDeserialize) { - this._bindingsToDeserialize = []; + if(unitsDesc) { + if(unitNames != unitsDesc.unitNames || unitsDesc.objectDesc != objectDesc) { + var unitsDescObjectDesc = unitsDesc.objectDesc, + unitsDescUnitNames = unitsDesc.unitNames; + + for(var i=0, iUniteName, countI = unitNames.length;(i 0) { + unitsToDeserializeKeys = unitsToDeserialize.keys(); + unitDeserializer = new UnitDeserializer(); + + while((object = unitsToDeserializeKeys.next().value)) { + this._deserializeObjectUnit(context, object, unitsToDeserialize.get(object), unitDeserializer); + unitsToDeserialize.delete(object); } } } @@ -796,34 +891,40 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont reviveObjectLiteral: { value: function(value, context, label, filterKeys) { var item, - promises = []; + promises, + propertyNames = context.propertyToReviveForObjectLiteralValue(value), + propertyName,iValue, + propertyNamesIterator = propertyNames.values(); + if (label) { context.setObjectLabel(value, label); } - for (var propertyName in value) { - if (value.hasOwnProperty(propertyName) && (!filterKeys || filterKeys.indexOf(propertyName) > -1)) { - if (value[propertyName] === value) { + while((propertyName = propertyNamesIterator.next().value)) { + if ((!filterKeys || filterKeys.indexOf(propertyName) > -1)) { + if ((iValue = value[propertyName]) === value) { // catch object property that point to its parent return value; } - item = this.reviveValue(value[propertyName], context); + item = this.reviveValue(iValue, context); if (Promise.is(item)) { - promises.push( + (promises || (promises = [])).push( item.then(this._createAssignValueFunction( value, propertyName) ) ); - } else { + } else if(iValue !== item) { value[propertyName] = item; } + + propertyNames.delete(propertyName); } } - if (promises.length === 0) { + if (!promises || (promises && promises.length === 0)) { return value; } else { return Promise.all(promises).then(function() { @@ -1029,6 +1130,52 @@ MontageReviver.findProxyForElement = function (element) { return PROXY_ELEMENT_MAP.get(element); }; + +MontageReviver.defineUnitReviver("values", function (unitDeserializer, object, values,_unitsDesc) { + var context = unitDeserializer.context, + montageObjectDesc = _unitsDesc.objectDesc, + substituteObject; + + if (typeof object.deserializeSelf === "function") { + + + var selfDeserializer = new SelfDeserializer(); + + selfDeserializer.initWithObjectAndObjectDescriptorAndContextAndUnitNames(object, montageObjectDesc, context, MontageReviver._unitNames); + substituteObject = (substituteObject || object).deserializeSelf(selfDeserializer); + + if (typeof substituteObject !== "undefined" && substituteObject !== object) { + //The deserialization used to be inlined, so it was easy to substitute. + //setObjectLabel only replaces the object on the root dictionary. It's possible + //that properties pointing to the original object would do after the substitution + //even in the previous implementation. + //we got to find how to substitute.... We don't know which label it is + //This is rare so we're just going to walk objets. + var label, + context_objects = context._objects; + + for(label in context_objects) { + if(context_objects[label] === object) { + context.setObjectLabel(substituteObject, label); + break; + } + } + + } + } + else if(values) { + context._reviver.deserializeMontageObjectValues( + object, + montageObjectDesc.values || montageObjectDesc.properties, //deprecated + context + ); + } + + + +}); + + if (typeof exports !== "undefined") { exports.MontageReviver = MontageReviver; diff --git a/core/serialization/deserializer/self-deserializer.js b/core/serialization/deserializer/self-deserializer.js index 59bb87939b..c34de2abde 100644 --- a/core/serialization/deserializer/self-deserializer.js +++ b/core/serialization/deserializer/self-deserializer.js @@ -18,6 +18,7 @@ var SelfDeserializer = Montage.specialize( { value: function (object, objectDescriptor, context, unitNames) { this._object = object; this._objectDescriptor = objectDescriptor; + this._objectDescriptorValues = objectDescriptor.values || objectDescriptor.properties || objectDescriptor; this._context = context; this._unitNames = unitNames; diff --git a/core/serialization/deserializer/unit-deserializer.js b/core/serialization/deserializer/unit-deserializer.js index 88cc1b6304..29377536c5 100644 --- a/core/serialization/deserializer/unit-deserializer.js +++ b/core/serialization/deserializer/unit-deserializer.js @@ -17,6 +17,12 @@ var UnitDeserializer = Montage.specialize(/** @lends UnitDeserializer# */ { } }, + context: { + get: function() { + return this._context; + } + }, + _templatePropertyRegExp: { value: /^([^:]+)(:.*)$/ }, diff --git a/test/spec/serialization/montage-deserializer-spec.js b/test/spec/serialization/montage-deserializer-spec.js index b305e9fb23..465a8a4039 100644 --- a/test/spec/serialization/montage-deserializer-spec.js +++ b/test/spec/serialization/montage-deserializer-spec.js @@ -756,7 +756,6 @@ describe("serialization/montage-deserializer-spec", function () { deserializer.init(serializationString, require); deserializer.deserializeObject().then(function (root) { - console.log("root", root); expect(root).toBeDefined(); }).catch(function(reason) { fail(reason); @@ -870,7 +869,6 @@ describe("serialization/montage-deserializer-spec", function () { }); }); - //TODO it("should deserialize using object: module.mjson, object created", function (done) { var serialization = { "root": { @@ -887,7 +885,7 @@ describe("serialization/montage-deserializer-spec", function () { deserializer.deserializeObject().then(function (root) { var info = Montage.getInfoForObject(root); expect(info.moduleId).toBe("core/core"); - expect(info.isInstance).toBe(true); + expect(info.isInstance).toBe(false); expect(root.type).toBeUndefined(); expect(root.blah).toBe("RootObjectDescriptor"); expect(root.number).toBe(42); @@ -899,6 +897,11 @@ describe("serialization/montage-deserializer-spec", function () { }); }); + it("should deserialize mjson synchronously with require", function (done) { + var root = require("spec/serialization/test-object-mjson.mjson").montageObject; + expect(root.blah).toBe("RootObjectDescriptor"); + done(); + }); it("should deserialize singleton using object: module.mjson", function (done) { var serialization = { From 9be43a618ccb3b4720a9d94f3fae4d903148ffb2 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 18:54:01 -0700 Subject: [PATCH 45/67] removes vscode plugin .eslintrc.json file and add gitignore to avoid it --- .eslintrc.json | 278 ------------------------------------------------- .gitignore | 11 +- 2 files changed, 6 insertions(+), 283 deletions(-) delete mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 6f3345ae8e..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 5 - }, - "rules": { - "accessor-pairs": [ - "error", - { - "getWithoutSet": false, - "setWithoutGet": false - } - ], - "array-bracket-newline": "off", - "array-bracket-spacing": "off", - "array-callback-return": "error", - "array-element-newline": "off", - "arrow-body-style": "error", - "arrow-parens": "error", - "arrow-spacing": "error", - "block-scoped-var": "off", - "block-spacing": "off", - "brace-style": "off", - "callback-return": "off", - "camelcase": "off", - "capitalized-comments": "off", - "class-methods-use-this": "error", - "comma-dangle": "off", - "comma-spacing": "off", - "comma-style": "off", - "complexity": "off", - "computed-property-spacing": "off", - "consistent-return": "off", - "consistent-this": "off", - "curly": "off", - "default-case": "off", - "dot-location": "off", - "dot-notation": "off", - "eol-last": "off", - "eqeqeq": "off", - "func-call-spacing": "off", - "func-name-matching": "off", - "func-names": "off", - "func-style": "off", - "function-paren-newline": "off", - "generator-star-spacing": "error", - "global-require": "off", - "guard-for-in": "off", - "handle-callback-err": "off", - "id-blacklist": "error", - "id-length": "off", - "id-match": "error", - "implicit-arrow-linebreak": "error", - "indent": "off", - "indent-legacy": "off", - "init-declarations": "off", - "jsx-quotes": "error", - "key-spacing": "off", - "keyword-spacing": "off", - "line-comment-position": "off", - "linebreak-style": [ - "error", - "unix" - ], - "lines-around-comment": "off", - "lines-around-directive": "off", - "lines-between-class-members": "error", - "max-classes-per-file": "error", - "max-depth": "off", - "max-len": "off", - "max-lines": "off", - "max-lines-per-function": "off", - "max-nested-callbacks": "error", - "max-params": "off", - "max-statements": "off", - "max-statements-per-line": "off", - "multiline-comment-style": "off", - "multiline-ternary": "off", - "new-parens": "off", - "newline-after-var": "off", - "newline-before-return": "off", - "newline-per-chained-call": "off", - "no-alert": "error", - "no-array-constructor": "error", - "no-async-promise-executor": "error", - "no-await-in-loop": "error", - "no-bitwise": "off", - "no-buffer-constructor": "error", - "no-caller": "off", - "no-catch-shadow": "error", - "no-confusing-arrow": "error", - "no-continue": "off", - "no-div-regex": "error", - "no-duplicate-imports": "error", - "no-else-return": "off", - "no-empty": [ - "error", - { - "allowEmptyCatch": true - } - ], - "no-empty-function": "off", - "no-eq-null": "error", - "no-eval": [ - "error", - { - "allowIndirect": true - } - ], - "no-extend-native": "off", - "no-extra-bind": "error", - "no-extra-label": "error", - "no-extra-parens": "off", - "no-floating-decimal": "off", - "no-implicit-coercion": [ - "error", - { - "boolean": false, - "number": false, - "string": false - } - ], - "no-implicit-globals": "off", - "no-implied-eval": "error", - "no-inline-comments": "off", - "no-inner-declarations": [ - "error", - "functions" - ], - "no-invalid-this": "off", - "no-iterator": "error", - "no-label-var": "error", - "no-lone-blocks": "error", - "no-lonely-if": "off", - "no-loop-func": "off", - "no-magic-numbers": "off", - "no-misleading-character-class": "off", - "no-mixed-operators": "off", - "no-mixed-requires": "off", - "no-multi-assign": "off", - "no-multi-spaces": "off", - "no-multi-str": "error", - "no-multiple-empty-lines": "off", - "no-native-reassign": "off", - "no-negated-condition": "off", - "no-negated-in-lhs": "error", - "no-nested-ternary": "off", - "no-new": "off", - "no-new-func": "off", - "no-new-object": "error", - "no-new-require": "error", - "no-new-wrappers": "off", - "no-octal-escape": "error", - "no-param-reassign": "off", - "no-path-concat": "error", - "no-plusplus": "off", - "no-process-env": "error", - "no-process-exit": "off", - "no-proto": "off", - "no-prototype-builtins": "off", - "no-restricted-globals": "error", - "no-restricted-imports": "error", - "no-restricted-modules": "error", - "no-restricted-properties": "error", - "no-restricted-syntax": "error", - "no-return-assign": "off", - "no-return-await": "error", - "no-script-url": "off", - "no-self-assign": [ - "error", - { - "props": false - } - ], - "no-self-compare": "error", - "no-sequences": "off", - "no-shadow": "off", - "no-shadow-restricted-names": "off", - "no-spaced-func": "off", - "no-sync": "off", - "no-tabs": "off", - "no-template-curly-in-string": "error", - "no-ternary": "off", - "no-throw-literal": "off", - "no-trailing-spaces": "off", - "no-undef-init": "error", - "no-undefined": "off", - "no-underscore-dangle": "off", - "no-unmodified-loop-condition": "off", - "no-unneeded-ternary": "off", - "no-unused-expressions": "off", - "no-use-before-define": "off", - "no-useless-call": "off", - "no-useless-catch": "error", - "no-useless-computed-key": "error", - "no-useless-concat": "error", - "no-useless-constructor": "error", - "no-useless-rename": "error", - "no-useless-return": "off", - "no-var": "off", - "no-void": "off", - "no-warning-comments": "off", - "no-whitespace-before-property": "off", - "no-with": "error", - "nonblock-statement-body-position": "error", - "object-curly-newline": "off", - "object-curly-spacing": "off", - "object-property-newline": "off", - "object-shorthand": "off", - "one-var": "off", - "one-var-declaration-per-line": "off", - "operator-assignment": "off", - "operator-linebreak": "off", - "padded-blocks": "off", - "padding-line-between-statements": "error", - "prefer-arrow-callback": "off", - "prefer-const": "error", - "prefer-destructuring": "off", - "prefer-numeric-literals": "error", - "prefer-object-spread": "off", - "prefer-promise-reject-errors": "off", - "prefer-reflect": "off", - "prefer-rest-params": "off", - "prefer-spread": "off", - "prefer-template": "off", - "quote-props": "off", - "quotes": "off", - "radix": "off", - "require-atomic-updates": "error", - "require-await": "error", - "require-jsdoc": "off", - "require-unicode-regexp": "off", - "rest-spread-spacing": "error", - "semi": "off", - "semi-spacing": "off", - "semi-style": [ - "error", - "last" - ], - "sort-imports": "error", - "sort-keys": "off", - "sort-vars": "off", - "space-before-blocks": "off", - "space-before-function-paren": "off", - "space-in-parens": "off", - "space-infix-ops": "off", - "space-unary-ops": "off", - "spaced-comment": "off", - "strict": "off", - "switch-colon-spacing": "error", - "symbol-description": "error", - "template-curly-spacing": "error", - "template-tag-spacing": "error", - "unicode-bom": [ - "error", - "never" - ], - "valid-jsdoc": "off", - "valid-typeof": [ - "error", - { - "requireStringLiterals": false - } - ], - "vars-on-top": "off", - "wrap-iife": [ - "error", - "any" - ], - "wrap-regex": "off", - "yield-star-spacing": "error", - "yoda": "off" - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index bb631a0971..1cc4e0a9b9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,24 +13,25 @@ log.txt ## jsdoc /doc - + ### SublimeText ### *.sublime-project *.sublime-workspace - + ### Intellij IDE ### .idea/ atlassian-ide-plugin.xml - + ### VisualStudioCode ### .vscode/* .vscode-upload.json - +.eslintrc.json + ### TextMate ### *.tmproj *.tmproject tmtags - + ### Node ### npm-debug.log* .npmignore From 9e582b41d3e3f57a4b64a1fd1a09343de1327c74 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 18:57:40 -0700 Subject: [PATCH 46/67] Adds useful input from tejaede for further evolution/context --- data/service/data-service.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index 87ef005125..418556fd2a 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -1398,7 +1398,19 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { if (mapping) { - //Why aren't we passing this.snapshotForObject(object) instead of copying everying in a new empty object? + /* + @marchant: Why aren't we passing this.snapshotForObject(object) instead of copying everying in a new empty object? + + @tejaede: The criteria source was a first attempt to support derived properties. It's a bucket in which we can put data from the cooked object in order to fetch other cooked properties. The cooked data placed in the criteria source does not belong in the snapshot. + + For example, take this model: + + A Foo model includes a bars property and a baz property. + Foo.baz is derived from the value of Foo.bars. + When the application triggers a fetch for Foo.baz, the value of Foo.bars needs to be available to build the criteria for the fetch. However, the value of Foo.bars is cooked and does not belong in the snapshot. Therefore, we create a copy of the snapshot called the "criteria source" into which we can put Foo.bars. + + All of this said, I don't know this is the right way to solve the problem. The issue at the moment is that this functionality is being used so we cannot remove it without an alternative. + */ Object.assign(data, this.snapshotForObject(object)); result = mapping.mapObjectToCriteriaSourceForProperty(object, data, propertyName); if (this._isAsync(result)) { From 62fea61410c50494e3f62c183a9088ddf3f94604 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sun, 31 Mar 2019 19:25:02 -0700 Subject: [PATCH 47/67] Fixes jslint warnings --- .../deserializer/montage-deserializer.js | 9 ++++----- .../deserializer/montage-interpreter.js | 14 ++------------ .../deserializer/montage-reviver.js | 6 +++--- .../raw-value-to-object-converter.js | 19 ++++++++++--------- data/service/data-service.js | 15 ++++++++------- data/service/data-trigger.js | 4 ++-- data/service/raw-data-service.js | 2 +- montage.js | 4 ++-- 8 files changed, 32 insertions(+), 41 deletions(-) diff --git a/core/serialization/deserializer/montage-deserializer.js b/core/serialization/deserializer/montage-deserializer.js index 9d42763cc6..696301b577 100644 --- a/core/serialization/deserializer/montage-deserializer.js +++ b/core/serialization/deserializer/montage-deserializer.js @@ -104,11 +104,10 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ deserializeObject: { value: function(objects) { - return (this._isSync - ? this.deserialize(objects).root - : this.deserialize(objects).then(function(objects) { - return objects.root; - })); + return (this._isSync ? this.deserialize(objects).root + : this.deserialize(objects).then(function(objects) { + return objects.root; + })); } }, diff --git a/core/serialization/deserializer/montage-interpreter.js b/core/serialization/deserializer/montage-interpreter.js index 0fc5c2fa47..ffb871e7d4 100644 --- a/core/serialization/deserializer/montage-interpreter.js +++ b/core/serialization/deserializer/montage-interpreter.js @@ -251,12 +251,10 @@ var MontageContext = Montage.specialize({ }, _classifyValuesToDeserialize: { - value: function (object, objectDesc, bindings) { + value: function (object, objectDesc) { var values, value, keys, - objectValuesToDeserialize, - objectProperties, bindings; @@ -281,14 +279,6 @@ var MontageContext = Montage.specialize({ bindings[key] = value; delete values[key]; } - //A flat property - // else { - // objectProperties = (objectValuesToDeserialize || (objectValuesToDeserialize = this.objectValuesToDeserialize)).get(object); - // if(!objectProperties) { - // objectValuesToDeserialize.set(object,(objectProperties = [])); - // } - // objectProperties.push(key); - // } } } @@ -355,7 +345,7 @@ var MontageContext = Montage.specialize({ } if(unitsDesc) { - if(unitNames != unitsDesc.unitNames || unitsDesc.objectDesc != objectDesc) { + if(unitNames !== unitsDesc.unitNames || unitsDesc.objectDesc !== objectDesc) { var unitsDescObjectDesc = unitsDesc.objectDesc, unitsDescUnitNames = unitsDesc.unitNames; diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index c36a79a540..26c4b993a9 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -661,7 +661,8 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont // TODO: can deserializeSelf make deserializedFromSerialization irrelevant? _invokeDeserializedFromSerialization: { value: function (context) { - var objects = context._objects; + var objects = context._objects, + object; /* jshint forin: true */ for (var label in objects) { @@ -696,8 +697,7 @@ var MontageReviver = exports.MontageReviver = Montage.specialize(/** @lends Mont if((object = objects[label])) { values = serialization[label]; - this.deserializeMontageObject(values, object, context, label) - + this.deserializeMontageObject(values, object, context, label); } } } diff --git a/data/converter/raw-value-to-object-converter.js b/data/converter/raw-value-to-object-converter.js index 842c77f2b2..65f8135b9c 100644 --- a/data/converter/raw-value-to-object-converter.js +++ b/data/converter/raw-value-to-object-converter.js @@ -133,9 +133,8 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO convertSyntax: { get: function() { return (this._convertSyntax || - ((this._convertSyntax === undefined) - ? (this._convertSyntax = (this.convertExpression ? parse(this.convertExpression) : null)) - : null)); + ((this._convertSyntax === undefined) ? (this._convertSyntax = (this.convertExpression ? parse(this.convertExpression) : null)) + : null)); } }, @@ -171,9 +170,10 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO * */ revertSyntax: { get: function() { - return this._revertSyntax || (this._revertSyntax === undefined - ? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) : null - : null); + return this._revertSyntax || + (this._revertSyntax === undefined ? this._revertSyntax = this.revertExpression ? parse(this.revertExpression) + : null + : null); } }, @@ -184,9 +184,10 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO compiledRevertSyntax: { get: function () { - return this._compiledRevertSyntax || (this._compiledRevertSyntax === undefined - ? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) : null - : null); + return this._compiledRevertSyntax || + (this._compiledRevertSyntax === undefined ? this._compiledRevertSyntax = this.revertSyntax ? compile(this.revertSyntax) + : null + : null); } }, diff --git a/data/service/data-service.js b/data/service/data-service.js index 418556fd2a..0d405dc292 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -95,8 +95,9 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { deserializedFromSerialization: { value: function () { - if(this._childServices) - this.addChildServices(this._childServices) + if(this._childServices) { + this.addChildServices(this._childServices); + } } }, @@ -318,8 +319,9 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { _addChildService: { value: function (child, types) { - var children, type, i, n, nIfEmpty = 1; - types = types || child.model && child.model.objectDescriptors || child.types, + var children, type, i, n, nIfEmpty = 1, isNotParentService; + + types = types || (child.model && child.model.objectDescriptors) || child.types; isNotParentService = (child._parentService !== this); // If the new child service already has a parent, remove it from // that parent. @@ -1039,9 +1041,8 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { //type.objectPrototype is legacy and should be depreated over time prototypeToExtend = type.objectPrototype || Object.getPrototypeOf(type.module) || Montage.prototype; prototype = Object.create(prototypeToExtend); - prototype.constuctor = type.objectPrototype - ? type.objectPrototype.constructor - : type.module; + prototype.constuctor = type.objectPrototype ? type.objectPrototype.constructor + : type.module; if(prototype.constuctor.name === "constructor" ) { Object.defineProperty(prototype.constuctor, "name", { value: type.typeName }); diff --git a/data/service/data-trigger.js b/data/service/data-trigger.js index cf7470063e..c332f70aaa 100644 --- a/data/service/data-trigger.js +++ b/data/service/data-trigger.js @@ -258,7 +258,7 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy configurable: true, writable: true, value: function (object, value) { - var status, prototype, descriptor, getter, setter, writable, currentValue; + var status, prototype, descriptor, getter, setter, writable, currentValue, isToMany; // Get the value's current status and update that status to indicate // the value has been obtained. This way if the setter called below // requests the property's value it will get the value the property @@ -288,7 +288,7 @@ exports.DataTrigger.prototype = Object.create({}, /** @lends DataTrigger.prototy isToMany = this.propertyDescriptor.cardinality !== 1; currentValue = this._getValue(object); if (isToMany && Array.isArray(currentValue)) { - object[propertyName].splice.apply(currentValue, [0, Infinity].concat(value)); + object[this._privatePropertyName].splice.apply(currentValue, [0, Infinity].concat(value)); } else { object[this._privatePropertyName] = value; diff --git a/data/service/raw-data-service.js b/data/service/raw-data-service.js index 53fbdca881..1f56b52573 100644 --- a/data/service/raw-data-service.js +++ b/data/service/raw-data-service.js @@ -497,7 +497,7 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot this.recordSnapshot(dataIdentifier, rawData); //Retrieves an existing object is responsible data service is uniquing, or creates one - object = this.getDataObject(type, rawData, context, dataIdentifier), + object = this.getDataObject(type, rawData, context, dataIdentifier); result = this._mapRawDataToObject(rawData, object, context); diff --git a/montage.js b/montage.js index 1dda81a16e..76d92a117b 100644 --- a/montage.js +++ b/montage.js @@ -439,7 +439,7 @@ } if(module.exports) { - Object.assign(module.exports, module.parsedText) + Object.assign(module.exports, module.parsedText); } else { module.exports = module.parsedText; @@ -505,7 +505,7 @@ var result = compile(module); return result; } - } + }; }; From 39dedf9d5798f1cb1a24ad1b1f34e8d648335e31 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 5 Aug 2019 17:00:25 -0700 Subject: [PATCH 48/67] =?UTF-8?q?adds=20the=20ability=20to=20process=20the?= =?UTF-8?q?=20value=20of=20object-descriptor-reference=E2=80=99s=20objectD?= =?UTF-8?q?escriptorModule=20as=20a=20dependency.=20This=20could=20be=20ma?= =?UTF-8?q?de=20more=20general=20but=20slower=20for=20all=20{=E2=80=9C%?= =?UTF-8?q?=E2=80=9D:=20=E2=80=9Cmodule=5Fid=E2=80=9D}=20construction=20in?= =?UTF-8?q?=20a=20serialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- montage.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/montage.js b/montage.js index 76d92a117b..de5df1fe09 100644 --- a/montage.js +++ b/montage.js @@ -464,10 +464,34 @@ iLabelObject = jsonRoot[iLabel]; if(iLabelObject.hasOwnProperty("prototype")) { dependencies.push(iLabelObject["prototype"]); + + //This is to enable expression-data-mapping to deserialize itself synchronously + //despite the fact it may have been serialized using object-descriptor-reference. + //This allows us to add the objectDescriptorModule's id ("%") as a dependency upfront. + //A stronger version would analyze the whole file for the construct: {"%": "someModuleId"}. + //But this would impact performance for a use case that we don't need so far. + if(dependencies[dependencies.length-1] === "montage/core/meta/object-descriptor-reference") { + /* + We're adding the module of that referrence, typiacally serialized as: + "ObjectDescriptorReference": { + "prototype": "montage/core/meta/object-descriptor-reference", + "properties": { + "valueReference": { + "objectDescriptor": "Object_Descriptor_Name", + "prototypeName": "Object_Descriptor__Prototype_Name", + "objectDescriptorModule": {"%": "Object_Descriptor__module_id"} + } + } + }, + */ + dependencies.push(iLabelObject.properties.valueReference.objectDescriptorModule["%"]); + } + } else if(iLabelObject.hasOwnProperty("object")) { dependencies.push(iLabelObject["object"]); } + i++; } return dependencies; From 46875754df78d50c170f76f3af3866d96390a31c Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 5 Aug 2019 22:46:24 -0700 Subject: [PATCH 49/67] Backward compatibility improvement. Makes sure all child services are added and only once. --- data/service/data-service.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/data/service/data-service.js b/data/service/data-service.js index 0d405dc292..992379b932 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -59,6 +59,11 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { result = this, value; + value = deserializer.getProperty("name"); + if (value) { + this.name = value; + } + value = deserializer.getProperty("model") || deserializer.getProperty("binder"); if (value) { this.model = value; @@ -95,8 +100,10 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { deserializedFromSerialization: { value: function () { - if(this._childServices) { - this.addChildServices(this._childServices); + if(Array.isArray(this._childServices)) { + var childServices = this._childServices; + this._childServices = []; + this.addChildServices(childServices); } } }, @@ -1859,6 +1866,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { service = self.childServiceForType(query.type); if (service) { + //Here we end up creating an extra stream for nothing because it should be third argument. stream = service.fetchData(query, stream) || stream; self._dataServiceByDataStream.set(stream, service); } else { From 8220b1172cc30c15f1396f9c9257c0440b897914 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Mon, 5 Aug 2019 22:48:49 -0700 Subject: [PATCH 50/67] Exposes isSync API on deserializer, interpreter & reviver Adds ability to deserialize synchronously objetc descriptor references: - in expression-data-mapping.js - in raw-value-to-object-converter.js --- .../serialization/deserializer/montage-deserializer.js | 7 ++++++- core/serialization/deserializer/montage-interpreter.js | 7 +++++++ core/serialization/deserializer/montage-reviver.js | 3 ++- core/serialization/deserializer/self-deserializer.js | 10 ++++++++++ data/converter/raw-value-to-object-converter.js | 7 ++++++- data/service/expression-data-mapping.js | 7 ++++++- 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/core/serialization/deserializer/montage-deserializer.js b/core/serialization/deserializer/montage-deserializer.js index 696301b577..c1b5cc7b3d 100644 --- a/core/serialization/deserializer/montage-deserializer.js +++ b/core/serialization/deserializer/montage-deserializer.js @@ -44,7 +44,12 @@ var MontageDeserializer = exports.MontageDeserializer = Montage.specialize({ return this; } }, - + _isSync: {value: false}, + isSync: { + get: function() { + return this._isSync; + } + }, /** * @param {Object} instances Map-like object of external user objects to diff --git a/core/serialization/deserializer/montage-interpreter.js b/core/serialization/deserializer/montage-interpreter.js index ffb871e7d4..219f066d38 100644 --- a/core/serialization/deserializer/montage-interpreter.js +++ b/core/serialization/deserializer/montage-interpreter.js @@ -123,6 +123,13 @@ var MontageContext = Montage.specialize({ } }, + _isSync: {value: false}, + isSync: { + get: function() { + return this._isSync; + } + }, + setObjectLabel: { value: function(object, label) { this._objects[label] = object; diff --git a/core/serialization/deserializer/montage-reviver.js b/core/serialization/deserializer/montage-reviver.js index 26c4b993a9..a81710803f 100644 --- a/core/serialization/deserializer/montage-reviver.js +++ b/core/serialization/deserializer/montage-reviver.js @@ -1140,7 +1140,8 @@ MontageReviver.defineUnitReviver("values", function (unitDeserializer, object, v var selfDeserializer = new SelfDeserializer(); - + //If the context is sync, we carry the info to the selfDeserializer + selfDeserializer.isSync = context.isSync; selfDeserializer.initWithObjectAndObjectDescriptorAndContextAndUnitNames(object, montageObjectDesc, context, MontageReviver._unitNames); substituteObject = (substituteObject || object).deserializeSelf(selfDeserializer); diff --git a/core/serialization/deserializer/self-deserializer.js b/core/serialization/deserializer/self-deserializer.js index c34de2abde..4a4a0cfebe 100644 --- a/core/serialization/deserializer/self-deserializer.js +++ b/core/serialization/deserializer/self-deserializer.js @@ -2,6 +2,16 @@ var Montage = require("../../core").Montage, deprecate = require("../../deprecate"); var SelfDeserializer = Montage.specialize( { + _isSync: {value: false}, + isSync: { + get: function() { + return this._isSync; + }, + set: function(value) { + this._isSync = value; + } + }, + _object: {value: null}, _objectDescriptor: {value: null}, _context: {value: null}, diff --git a/data/converter/raw-value-to-object-converter.js b/data/converter/raw-value-to-object-converter.js index 65f8135b9c..e0c893d676 100644 --- a/data/converter/raw-value-to-object-converter.js +++ b/data/converter/raw-value-to-object-converter.js @@ -56,7 +56,12 @@ exports.RawValueToObjectConverter = Converter.specialize( /** @lends RawValueToO value = deserializer.getProperty("foreignDescriptor"); if (value instanceof ObjectDescriptorReference) { - this._foreignDescriptorReference = value; + if(!deserializer.isSync) { + this._foreignDescriptorReference = value; + } + else { + this.foreignDescriptor = deserializer._context._require(value._reference.objectDescriptorModule.id).montageObject; + } } else if (value) { this.foreignDescriptor = value; } diff --git a/data/service/expression-data-mapping.js b/data/service/expression-data-mapping.js index 6c7dea3348..35d1bf29b8 100644 --- a/data/service/expression-data-mapping.js +++ b/data/service/expression-data-mapping.js @@ -94,7 +94,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData this.rawDataPrimaryKeys = value; } - if (hasReferences) { + if (hasReferences && !deserializer.isSync) { result = this.resolveReferences().then(function () { value = deserializer.getProperty("objectMapping"); if (value) { @@ -107,6 +107,11 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData return self; }); } else { + + if(!this.objectDescriptor) { + this.objectDescriptor = deserializer._context._require(this._objectDescriptorReference._reference.objectDescriptorModule.id).montageObject; + } + value = deserializer.getProperty("objectMapping"); if (value) { self._rawOwnObjectMappingRules = value.rules; From e1b7a0272bd30d12b8384fd0f28a38a9d5e08bd5 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Wed, 7 Aug 2019 19:09:11 -0700 Subject: [PATCH 51/67] Updates version to rc2 and engines dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b4a579469f..f71e3ad503 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "montage", - "version": "18.0.0-rc1", + "version": "18.0.0-rc2", "description": "Build your next application with a browser based platform that really gets the web.", "license": "BSD-3-Clause", "repository": { @@ -9,8 +9,8 @@ }, "main": "montage", "engines": { - "node": ">=4", - "npm": ">=2" + "node": ">=8.2.1", + "npm": ">=6.7.0" }, "overlay": { "browser": { From 7f787c6056058cdb722004eec6a95d2481980491 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:05:24 -0700 Subject: [PATCH 52/67] Updates node version for lint --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 01a610b3e2..86aaf63c29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ before_install: jobs: include: - stage: lint + node_js: 9 env: script: npm run lint - stage: deploy From 9523eae1f1be9e05a5a3ed7f894cec65323ce065 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:13:23 -0700 Subject: [PATCH 53/67] Fix for xvfb issue --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 86aaf63c29..83dbf02089 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ node_js: - 6 - 8 - 10 +services: + - xvfb script: npm run $COMMAND env: - COMMAND=test @@ -12,7 +14,6 @@ env: before_install: - export CHROME_BIN=chromium-browser - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start jobs: include: - stage: lint From f64754cc92ab1ca0e9d374ba24a54c9a5aa4df51 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:30:51 -0700 Subject: [PATCH 54/67] Removes committed version of package-lock.json --- package-lock.json | 5898 --------------------------------------------- 1 file changed, 5898 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index bb5d8bc99c..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,5898 +0,0 @@ -{ - "name": "montage", - "version": "18.0.0-rc1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/node": { - "version": "10.12.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.24.tgz", - "integrity": "sha512-GWWbvt+z9G5otRBW8rssOFgRY87J9N/qbhqfjMZ+gUuL6zoL+Hm6gP/8qQBG4jjimqdaNLCehcVapZ/Fs2WjCQ==", - "dev": true - }, - "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", - "dev": true, - "requires": { - "mime-types": "~2.1.11", - "negotiator": "0.6.1" - } - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "ajv": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", - "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "archiver": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", - "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", - "dev": true, - "requires": { - "archiver-utils": "^1.3.0", - "async": "^2.0.0", - "buffer-crc32": "^0.2.1", - "glob": "^7.0.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0", - "tar-stream": "^1.5.0", - "zip-stream": "^1.2.0" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "archiver-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", - "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "graceful-fs": "^4.1.0", - "lazystream": "^1.0.0", - "lodash": "^4.8.0", - "normalize-path": "^2.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "binary-extensions": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", - "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", - "dev": true - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", - "dev": true - }, - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "^7.1.1" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "collections": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/collections/-/collections-5.1.8.tgz", - "integrity": "sha512-2Vvizv30fKnBlso7kVtZTsuZDVvA6JvLotsSnGKiAiIM4Z+EW1/9yRgXqJJ0WFzj36yZNTUsI+/Yu2Ogoo0H0w==", - "requires": { - "weak-map": "~1.0.x" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", - "dev": true, - "requires": { - "lodash": "^4.5.0" - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", - "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "compress-commons": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", - "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.1", - "crc32-stream": "^2.0.0", - "normalize-path": "^2.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concurrently": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.6.1.tgz", - "integrity": "sha512-/+ugz+gwFSEfTGUxn0KHkY+19XPRTXR8+7oUK/HxgiN1n7FjeJmkrbSiXAJfyQ0zORgJYPaenmymwon51YXH9Q==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "commander": "2.6.0", - "date-fns": "^1.23.0", - "lodash": "^4.5.1", - "read-pkg": "^3.0.0", - "rx": "2.3.24", - "spawn-command": "^0.0.2-1", - "supports-color": "^3.2.3", - "tree-kill": "^1.1.0" - } - }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", - "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", - "dev": true - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", - "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "^0.10.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, - "requires": { - "domelementtype": "~1.1.1", - "entities": "~1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.0.3.tgz", - "integrity": "sha1-iJ+N9iZAOvB4jinWbV1cb36/D9Y=", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", - "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", - "requires": { - "domelementtype": "1" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecstatic": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-2.2.1.tgz", - "integrity": "sha512-ztE4WqheoWLh3wv+HQwy7dACnvNY620coWpa+XqY6R2cVWgaAT2lUISU1Uf7JpdLLJCURktJOaA9av2AOzsyYQ==", - "dev": true, - "requires": { - "he": "^1.1.1", - "mime": "^1.2.11", - "minimist": "^1.1.0", - "url-join": "^2.0.2" - } - }, - "editorconfig": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.2.tgz", - "integrity": "sha512-GWjSI19PVJAM9IZRGOS+YKI8LN+/sjkSjNyvxL5ucqP9/IqtYNXBaQ/6c/hkPNYQHyOHra2KoXZI/JVpuqwmcQ==", - "dev": true, - "requires": { - "@types/node": "^10.11.7", - "@types/semver": "^5.5.0", - "commander": "^2.19.0", - "lru-cache": "^4.1.3", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.47", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.47.tgz", - "integrity": "sha512-/1TItLfj+TTfWoeRcDn/0FbGV6SNo4R+On2GGVucPU/j3BWnXE2Co8h8CTo4Tu34gFJtnmwS9xiScKs4EjZhdw==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "dev": true - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "dependencies": { - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "dev": true, - "requires": { - "expand-range": "^0.1.0" - } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - } - }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", - "dev": true, - "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "follow-redirects": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", - "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "frb": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/frb/-/frb-4.0.3.tgz", - "integrity": "sha1-Hbgnwfv4mG/lRop0Z7NT5cP6u0w=", - "requires": { - "collections": "^5.1.3" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", - "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "handlebars": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz", - "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==", - "dev": true, - "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "dev": true, - "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "htmlparser2": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.0.5.tgz", - "integrity": "sha1-fzBgjLeAnzX/fG3YDinCR6p9r18=", - "requires": { - "domelementtype": "1", - "domhandler": "2.0", - "domutils": "1.1", - "readable-stream": "1.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-server": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.10.0.tgz", - "integrity": "sha1-sqRGsWqduH7TxiK6m+sbCFsSNKc=", - "dev": true, - "requires": { - "colors": "1.0.3", - "corser": "~2.0.0", - "ecstatic": "^2.0.0", - "http-proxy": "^1.8.1", - "opener": "~1.4.0", - "optimist": "0.6.x", - "portfinder": "^1.0.13", - "union": "~0.4.3" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "jasmine-console-reporter": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-1.2.8.tgz", - "integrity": "sha1-2JPJwMElcn7Xd3Cc9Hh2gNBRU5Y=", - "dev": true, - "requires": { - "chalk": "^2.1.0" - } - }, - "jasmine-core": { - "version": "2.99.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", - "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", - "dev": true - }, - "joey": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/joey/-/joey-1.5.3.tgz", - "integrity": "sha1-5cpBtGiZz2ZaIQee9rjDOjrxd0Q=", - "dev": true, - "requires": { - "optimist": "~0.3.7", - "q": "^1.5.0", - "q-io": "^1.13.4", - "url2": "~1.0.0" - }, - "dependencies": { - "optimist": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", - "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", - "dev": true, - "requires": { - "wordwrap": "~0.0.2" - } - }, - "url2": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/url2/-/url2-1.0.4.tgz", - "integrity": "sha1-3yKErhXHSbqAl1FRDl4l2p67gNg=", - "dev": true, - "requires": { - "url": "0.10.2" - } - } - } - }, - "js-beautify": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.8.9.tgz", - "integrity": "sha512-MwPmLywK9RSX0SPsUJjN7i+RQY9w/yC17Lbrq9ViEefpLRgqAR2BgrMN2AbifkUuhDV8tRauLhLda/9+bE0YQA==", - "dev": true, - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.2", - "glob": "^7.1.3", - "mkdirp": "~0.5.0", - "nopt": "~4.0.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - } - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jshint": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.1.tgz", - "integrity": "sha512-9GpPfKeffYBl7oBDX2lHPG16j0AM7D2bn3aLy9DaWTr6CWa0i/7UGhX8WLZ7V14QQnnr4hXbjauTLYg06F+HYw==", - "dev": true, - "requires": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.10", - "minimatch": "~3.0.2", - "shelljs": "0.3.x", - "strip-json-comments": "1.0.x" - }, - "dependencies": { - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "dev": true, - "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "karma": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", - "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", - "dev": true, - "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "1.7.3", - "source-map": "^0.5.3", - "tmp": "0.0.31", - "useragent": "^2.1.12" - }, - "dependencies": { - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", - "dev": true, - "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" - } - }, - "karma-coverage": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz", - "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==", - "dev": true, - "requires": { - "dateformat": "^1.0.6", - "istanbul": "^0.4.0", - "lodash": "^4.17.0", - "minimatch": "^3.0.0", - "source-map": "^0.5.1" - } - }, - "karma-firefox-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz", - "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==", - "dev": true - }, - "karma-ie-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz", - "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=", - "dev": true, - "requires": { - "lodash": "^4.6.1" - } - }, - "karma-jasmine": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz", - "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=", - "dev": true - }, - "karma-phantomjs-launcher": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", - "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", - "dev": true, - "requires": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" - } - }, - "karma-safari-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz", - "integrity": "sha1-lpgqLMR9BmquccVTursoMZEVos4=", - "dev": true - }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" - }, - "lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=" - }, - "lodash.trim": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", - "integrity": "sha1-NkJefukL5KpeJ7zruFt9EepHqlc=" - }, - "log4js": { - "version": "0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", - "dev": true, - "requires": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" - }, - "dependencies": { - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - } - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "dev": true, - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimeparse": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/mimeparse/-/mimeparse-0.1.4.tgz", - "integrity": "sha1-2vsCdSNw/SJgk64xUsJxrwGsJUo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "montage": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/montage/-/montage-17.2.1.tgz", - "integrity": "sha512-WEcBs+5XumOeOUsZK59KTOii047qTXV5IiuJXwjPElIvliX+BXhkiQEm0zGM/yBLys0aqqbVj7MuSufBjUapjw==", - "dev": true, - "requires": { - "bluebird": "~3.5.0", - "collections": "~5.1.x", - "frb": "~4.0.x", - "htmlparser2": "~3.0.5", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.trim": "^4.5.1", - "mr": "^17.0.11", - "proxy-polyfill": "~0.1.7", - "q-io": "^1.13.3", - "weak-map": "^1.0.5" - }, - "dependencies": { - "mr": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/mr/-/mr-17.0.13.tgz", - "integrity": "sha512-Zyg6gpffdcnuCcbPSQMtSTB4a6uhrXdqqQXYCU/Afrc7iSkitfk/J2FdKFbOO9a7WQe3s6bIu1qyBXIAlAcCFg==", - "dev": true, - "requires": { - "bluebird": "~3.5.0" - } - } - } - }, - "montage-testing": { - "version": "git://github.com/montagejs/montage-testing.git#61b8d783cd6b328f8171897ae1e79e651d60594b", - "from": "git://github.com/montagejs/montage-testing.git#master", - "dev": true, - "requires": { - "jasmine-console-reporter": "^1.2.7", - "jasmine-core": "^2.5.2", - "js-beautify": "^1.6.11", - "montage": "^17.0.7" - } - }, - "mop-integration": { - "version": "git://github.com/montagejs/mop-integration.git#4150a421b841268b809301e40d4191f68f859182", - "from": "git://github.com/montagejs/mop-integration.git#master", - "dev": true, - "requires": { - "colors": "^1.1.2", - "joey": "^1.5.2", - "phantom-wd": "0.0.3", - "q": "^1.5.0", - "q-io": "^1.13.4", - "temp": "^0.8.3" - }, - "dependencies": { - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", - "dev": true - } - } - }, - "mr": { - "version": "18.0.0-rc1", - "resolved": "https://registry.npmjs.org/mr/-/mr-18.0.0-rc1.tgz", - "integrity": "sha512-M9pH0Mm+qCB3aRDTIQS2wfe/ypMaDsCbIlAd9SEIC8S6z0imJs/xZl6XK0evskIddHG3bGPJC0v34NbSxVxuRA==", - "requires": { - "bluebird": "~3.5.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "open": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", - "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=", - "dev": true - }, - "opener": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", - "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "phantom-wd": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/phantom-wd/-/phantom-wd-0.0.3.tgz", - "integrity": "sha1-gv/VOE3uTI+NRmkvrRL3tHIIbr0=", - "dev": true, - "requires": { - "q": "^1.5.0", - "wd": "^1.2.0" - } - }, - "phantomjs-prebuilt": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", - "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", - "dev": true, - "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - }, - "proxy-polyfill": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/proxy-polyfill/-/proxy-polyfill-0.1.7.tgz", - "integrity": "sha1-HAb+ELC2BueSaOFNRSiVLmQDbTk=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "q-io": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/q-io/-/q-io-1.13.6.tgz", - "integrity": "sha1-BFC9s54IfLiaX9SkFjfqM0fJhTg=", - "requires": { - "es6-set": "^0.1.1", - "mime": "^1.2.11", - "mimeparse": "^0.1.4", - "q": "^1.0.1", - "qs": "^1.2.1", - "url2": "^0.0.0" - } - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz", - "integrity": "sha1-GbV/8k3CqZzh+L32r82ln472H4g=" - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - } - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "dev": true, - "requires": { - "throttleit": "^1.0.0" - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rx": { - "version": "2.3.24", - "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz", - "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", - "dev": true, - "requires": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "dev": true, - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - } - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "temp": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", - "dev": true, - "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" - }, - "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "tree-kill": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", - "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", - "dev": true - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "union": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", - "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", - "dev": true, - "requires": { - "qs": "~2.3.3" - }, - "dependencies": { - "qs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", - "dev": true - } - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.2.tgz", - "integrity": "sha1-aGIdaSnqHK00Tr8TXYL89+sadGk=", - "dev": true, - "requires": { - "punycode": "1.3.2" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", - "dev": true - }, - "url2": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/url2/-/url2-0.0.0.tgz", - "integrity": "sha1-Tqq9HVw6yQ1iq0SFyZhCKGWgSxo=" - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vargs": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz", - "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "wd": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/wd/-/wd-1.11.1.tgz", - "integrity": "sha512-XNK6EbOrXF7cG8f3pbps6mb/+xPGZH2r1AL1zGJluGynA/Xt6ip1Tvqj2AkavyDFworreaGXoe+0AP/r7EX9pg==", - "dev": true, - "requires": { - "archiver": "2.1.1", - "async": "2.0.1", - "lodash": "4.17.11", - "mkdirp": "^0.5.1", - "q": "1.4.1", - "request": "2.88.0", - "vargs": "0.1.0" - }, - "dependencies": { - "async": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz", - "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=", - "dev": true, - "requires": { - "lodash": "^4.8.0" - } - }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true - } - } - }, - "weak-map": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz", - "integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", - "dev": true - }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - }, - "zip-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", - "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", - "dev": true, - "requires": { - "archiver-utils": "^1.3.0", - "compress-commons": "^1.2.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - } - } -} From 7ce7367dd496fce239b0403fa8963db04391f743 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:45:28 -0700 Subject: [PATCH 55/67] Use node 8+ for tests --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 83dbf02089..f135bf45e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,11 +17,12 @@ before_install: jobs: include: - stage: lint - node_js: 9 + node_js: 8 env: script: npm run lint - stage: deploy script: skip + node_js: 8 env: deploy: provider: npm From b24833b6f0d86769aab13536fbea0de901740d78 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:49:19 -0700 Subject: [PATCH 56/67] Specify node 8 and 10 for test stage --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f135bf45e5..909da3e349 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,11 @@ jobs: node_js: 8 env: script: npm run lint - - stage: deploy + - stage: test + node_js: + - 8 + - 10 + - stage: deploy script: skip node_js: 8 env: From 2cecdba2d1ccc4478a93495fab494e8e89b31b6d Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 22:51:29 -0700 Subject: [PATCH 57/67] Removes tests with node 4 and 6 --- .travis.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 909da3e349..d9e8ae302e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ language: node_js node_js: - - 4 - - 6 - 8 - 10 services: @@ -20,13 +18,8 @@ jobs: node_js: 8 env: script: npm run lint - - stage: test - node_js: - - 8 - - 10 - - stage: deploy + - stage: deploy script: skip - node_js: 8 env: deploy: provider: npm From f134bd6d2a0847ad8fbf961321af6517ae33e0c0 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Thu, 8 Aug 2019 23:06:23 -0700 Subject: [PATCH 58/67] Adds missing spec files --- test/spec/core/module-mjson/package.json | 1 + test/spec/core/module-mjson/program.js | 7 +++++++ test/spec/core/module-mjson/test.mjson | 3 +++ 3 files changed, 11 insertions(+) create mode 100644 test/spec/core/module-mjson/package.json create mode 100644 test/spec/core/module-mjson/program.js create mode 100644 test/spec/core/module-mjson/test.mjson diff --git a/test/spec/core/module-mjson/package.json b/test/spec/core/module-mjson/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/spec/core/module-mjson/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/spec/core/module-mjson/program.js b/test/spec/core/module-mjson/program.js new file mode 100644 index 0000000000..a9007131d5 --- /dev/null +++ b/test/spec/core/module-mjson/program.js @@ -0,0 +1,7 @@ +var data = require("spec/core/module-mjson/test.mjson"); + +describe("core/module-mjson", function () { + + expect(data.Hello === "World", 'parse string').toBe(true); + +}); diff --git a/test/spec/core/module-mjson/test.mjson b/test/spec/core/module-mjson/test.mjson new file mode 100644 index 0000000000..ac4c8c6364 --- /dev/null +++ b/test/spec/core/module-mjson/test.mjson @@ -0,0 +1,3 @@ +{ + "Hello": "World" +} \ No newline at end of file From 6fa2ca24f4df903a55525b5d4e78c879c332ba09 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 9 Aug 2019 12:07:08 -0700 Subject: [PATCH 59/67] Updates mr dependency to fix tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95058cdc5d..6b77393837 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "frb": "~4.0.x", "htmlparser2": "~3.0.5", "q-io": "^1.13.3", - "mr": "18.0.0-rc2", + "mr": "montagejs/mr#master", "weak-map": "^1.0.5", "lodash.kebabcase": "^4.1.1", "lodash.camelcase": "^4.3.0", From dfc03a42c3b6c611e06700b5b7311b4e02aca52b Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 9 Aug 2019 12:34:01 -0700 Subject: [PATCH 60/67] Updates Karma dependencies to run on node 8+ --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 6b77393837..46d0111963 100644 --- a/package.json +++ b/package.json @@ -68,13 +68,13 @@ "jasmine-console-reporter": "^1.2.7", "jasmine-core": "^2.5.2", "jshint": "^2.9.5", - "karma": "^1.5.0", - "karma-chrome-launcher": "^2.0.0", - "karma-coverage": "^1.1.1", - "karma-firefox-launcher": "^1.0.1", + "karma": "^1.7.1", + "karma-chrome-launcher": "^3.0.0", + "karma-coverage": "^1.1.2", + "karma-firefox-launcher": "^1.2.0", "karma-ie-launcher": "^1.0.0", - "karma-jasmine": "^1.1.0", - "karma-phantomjs-launcher": "^1.0.2", + "karma-jasmine": "^2.0.1", + "karma-phantomjs-launcher": "^1.0.4", "karma-safari-launcher": "^1.0.0", "montage-testing": "git://github.com/montagejs/montage-testing.git#master", "mop-integration": "git://github.com/montagejs/mop-integration.git#master", From a7f661e59aadc23f221f07ff42535889e1c37366 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Fri, 9 Aug 2019 14:12:30 -0700 Subject: [PATCH 61/67] Updates base node version to 10 --- .travis.yml | 2 -- package.json | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index d9e8ae302e..4b160c9b38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - 8 - 10 services: - xvfb @@ -15,7 +14,6 @@ before_install: jobs: include: - stage: lint - node_js: 8 env: script: npm run lint - stage: deploy diff --git a/package.json b/package.json index 46d0111963..143058072a 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ }, "main": "montage", "engines": { - "node": ">=8.2.1", - "npm": ">=6.7.0" + "node": ">=10.16.2", + "npm": ">=6.9.0" }, "overlay": { "browser": { @@ -48,7 +48,7 @@ }, "production": true, "dependencies": { - "bluebird": "~3.5.0", + "bluebird": "~3.5.5", "collections": "~5.1.x", "frb": "~4.0.x", "htmlparser2": "~3.0.5", @@ -68,7 +68,7 @@ "jasmine-console-reporter": "^1.2.7", "jasmine-core": "^2.5.2", "jshint": "^2.9.5", - "karma": "^1.7.1", + "karma": "^4.2.0", "karma-chrome-launcher": "^3.0.0", "karma-coverage": "^1.1.2", "karma-firefox-launcher": "^1.2.0", From 4217a32c838020e7e366c5bda42261172f065603 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 12:23:01 -0700 Subject: [PATCH 62/67] Changing Karma to connect to the xvfb display on DISPLAY=:0 to try to fix build no running --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4b160c9b38..48fcada064 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ env: - COMMAND=integration MONTAGE_VERSION=. MOP_VERSION="#feature/npm3" before_install: - export CHROME_BIN=chromium-browser - - export DISPLAY=:99.0 + - export DISPLAY=:0 jobs: include: - stage: lint From b1f070f2c93ed48b431920b5f3071efa951b86c9 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 16:17:29 -0700 Subject: [PATCH 63/67] Adds browserSocketTimeout to attempt to fix karma tests on travis --- karma.conf.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/karma.conf.js b/karma.conf.js index 1981ed82c0..7a437ac20b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,6 +14,8 @@ module.exports = function(config) { browserNoActivityTimeout: 30000, + browserSocketTimeout: 60000, + // list of files / patterns to load in the browser files: [ 'test/run-karma.js', From a7b20ffcd6b1f2104d37f75593b3572691a84047 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 16:27:44 -0700 Subject: [PATCH 64/67] Updates browserSocketTimeout to 80000 --- karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/karma.conf.js b/karma.conf.js index 7a437ac20b..9e2ea54136 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,7 +14,7 @@ module.exports = function(config) { browserNoActivityTimeout: 30000, - browserSocketTimeout: 60000, + browserSocketTimeout: 80000, // list of files / patterns to load in the browser files: [ From 87cdea749dbf2727de8933f9a97b0f38ef6d5b77 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 18:31:19 -0700 Subject: [PATCH 65/67] Change to try to get travis test to run in Chrome --- karma.conf.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 9e2ea54136..2b9dc078c3 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -3,7 +3,7 @@ // Karma configuration // Generated on Tue Mar 07 2017 13:59:10 GMT-0800 (PST) module.exports = function(config) { - config.set({ + var cfg = { // base path, that will be used to resolve files and exclude basePath: '.', @@ -223,5 +223,12 @@ module.exports = function(config) { 'karma-ie-launcher', 'karma-phantomjs-launcher' ] - }); + }; + + if (process.env.TRAVIS) { + cfg.browsers = ['Chrome_travis_ci']; + } + + config.set(cfg); + }; From 0444552fcb40f914c3ecce804c41c20e480942e1 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 18:52:07 -0700 Subject: [PATCH 66/67] reverts to node 8 for travis tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 48fcada064..c35104f8e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 10 + - 8 services: - xvfb script: npm run $COMMAND From ccb6fcf6b5f598342bb43af818b1bbef338e3400 Mon Sep 17 00:00:00 2001 From: Benoit Marchant Date: Sat, 10 Aug 2019 19:00:10 -0700 Subject: [PATCH 67/67] Comments use of process.env as process is undefined?? --- karma.conf.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 2b9dc078c3..b29fcdf58e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -225,9 +225,9 @@ module.exports = function(config) { ] }; - if (process.env.TRAVIS) { - cfg.browsers = ['Chrome_travis_ci']; - } +// if (process.env.TRAVIS) { +// cfg.browsers = ['Chrome_travis_ci']; +// } config.set(cfg);