diff --git a/Makefile.am b/Makefile.am index ea443f0104..c5e5425d24 100644 --- a/Makefile.am +++ b/Makefile.am @@ -240,17 +240,26 @@ arangosysconf_DATA = $(shell find @builddir@/etc/arangodb -name "*$(PROGRAM_SUFF ### @brief /share data ################################################################################ -nobase_pkgdata_DATA = \ - $(shell find @srcdir@/js/actions -name "*.js" -print) \ - $(shell find @srcdir@/js/common -name "*.js" -print) \ - $(shell find @srcdir@/js/server -name "*.js" -print) \ - $(shell find @srcdir@/js/client -name "*.js" -print) \ - $(shell find @srcdir@/js/node -type f "(" -name .travis.yml -o -name .npmignore -o -print ")") \ - $(shell find @srcdir@/js/apps/system -type f "(" -path "*/test/*" -o -path "*/test_data/*" -o -print ")") +pkgdataACTIONSdir = $(datadir) +pkgdataCOMMONdir = $(datadir) +pkgdataSERVERdir = $(datadir) +pkgdataCLIENTdir = $(datadir) +pkgdataNODEdir = $(datadir) +pkgdataAPPSdir = $(datadir) +pkgdataMRUBYdir = $(datadir) + +nobase_pkgdata_DATA = + +nobase_pkgdataACTIONS_DATA = $(shell find @srcdir@/js/actions -name "*.js" -print) +nobase_pkgdataCOMMON_DATA = $(shell find @srcdir@/js/common -name "*.js" -print) +nobase_pkgdataSERVER_DATA = $(shell find @srcdir@/js/server -name "*.js" -print) +nobase_pkgdataCLIENT_DATA = $(shell find @srcdir@/js/client -name "*.js" -print) +nobase_pkgdataNODE_DATA = $(shell find @srcdir@/js/node -type f "(" -name .travis.yml -o -name .npmignore -o -print ")") +nobase_pkgdataAPPS_DATA = $(shell find @srcdir@/js/apps/system -type f "(" -path "*/test/*" -o -path "*/test_data/*" -o -print ")") if ENABLE_MRUBY -nobase_pkgdata_DATA += \ +nobase_pkgdataMRUBY_DATA = \ $(shell find @srcdir@/mr/actions -name "*.rb" -print) \ $(shell find @srcdir@/mr/client -name "*.rb" -print) \ $(shell find @srcdir@/mr/common -name "*.rb" -print) \ diff --git a/js/common/bootstrap/modules.js b/js/common/bootstrap/modules.js index a17dcaf30a..465306cbbb 100644 --- a/js/common/bootstrap/modules.js +++ b/js/common/bootstrap/modules.js @@ -834,6 +834,17 @@ function require (path) { } } + // check if there is a package containing this module + path = path.substr(1); + if (path.indexOf('/') !== -1) { + var p = path.split('/'); + localModule = requirePackage(currentModule, '/' + p.shift()); + if (localModule !== null) { + localModule = requirePackage(localModule, '/' + p.join('/')); + return localModule; + } + } + // nothing found return null; } diff --git a/js/server/modules/org/arangodb/foxx/model.js b/js/server/modules/org/arangodb/foxx/model.js index 0e6a261feb..7fd50da443 100644 --- a/js/server/modules/org/arangodb/foxx/model.js +++ b/js/server/modules/org/arangodb/foxx/model.js @@ -32,6 +32,7 @@ var Model, _ = require("underscore"), is = require("org/arangodb/is"), backbone_helpers = require("backbone"), + metadataKeys = ['_id', '_key', '_rev'], parseAttributes, parseRequiredAttributes; @@ -56,22 +57,30 @@ var Model, /// @endcode //////////////////////////////////////////////////////////////////////////////// -var whitelistProperties = function (properties, constructorProperties) { +var whitelistProperties = function (properties, constructorProperties, whitelistMetadata) { 'use strict'; - var filteredProperties, - whitelistedProperties = _.keys(constructorProperties); - - if (whitelistedProperties) { - filteredProperties = _.pick(properties, whitelistedProperties); - } else { - filteredProperties = properties; + if (!properties) { + return {}; } - return filteredProperties; + if (!constructorProperties) { + return _.clone(properties); + } + + var whitelistedKeys = _.keys(constructorProperties); + + if (whitelistMetadata) { + whitelistedKeys = whitelistedKeys.concat(metadataKeys); + } + + return _.pick(properties, whitelistedKeys); }; var fillInDefaults = function (properties, constructorProperties) { 'use strict'; + if (!constructorProperties) { + return properties; + } var defaults = _.reduce(constructorProperties, function (result, value, key) { if (_.has(value, "defaultValue")) { result[key] = value.defaultValue; @@ -91,12 +100,15 @@ Model = function (attributes) { /// @brief The attributes property is the internal hash containing the model's state. //////////////////////////////////////////////////////////////////////////////// - if (is.object(this.constructor.attributes)) { - this.attributes = whitelistProperties(attributes, this.constructor.attributes); - this.attributes = fillInDefaults(this.attributes, this.constructor.attributes); - } else { - this.attributes = attributes || {}; - } + this.attributes = whitelistProperties(attributes, this.constructor.attributes, true); + this.attributes = fillInDefaults(this.attributes, this.constructor.attributes); +}; + +Model.fromClient = function (attributes) { + var instance = new this(); + instance.attributes = whitelistProperties(attributes, this.attributes, false); + instance.attributes = fillInDefaults(instance.attributes, this.attributes); + return instance; }; parseAttributes = function (rawAttributes) { @@ -156,7 +168,7 @@ _.extend(Model.prototype, { /// @FUN{FoxxModel::get(@FA{name})} /// /// Get the value of an attribute -/// +/// /// @EXAMPLES /// /// @code @@ -255,7 +267,8 @@ _.extend(Model.prototype, { forClient: function () { 'use strict'; - return this.attributes; + var result = whitelistProperties(this.attributes, this.constructor.attributes); + return result; } }); diff --git a/js/server/tests/shell-foxx-model.js b/js/server/tests/shell-foxx-model.js index b130e35a6f..0bf011ee53 100644 --- a/js/server/tests/shell-foxx-model.js +++ b/js/server/tests/shell-foxx-model.js @@ -90,9 +90,80 @@ function ModelSpec () { }; instance = new FoxxModel(raw); + var dbData = instance.forDB(); + var clientData = instance.forClient(); - assertEqual(instance.forDB(), raw); - assertEqual(instance.forClient(), raw); + Object.keys(raw).forEach(function(key) { + assertEqual(raw[key], dbData[key]); + assertEqual(raw[key], clientData[key]); + }); + }, + + testFilterUnknownProperties: function () { + var Model = FoxxModel.extend({}, { + attributes: { + a: {type: 'integer'} + } + }); + + var raw = { + a: 1, + b: 2 + }; + + instance = new Model(raw); + var dbData = instance.forDB(); + var clientData = instance.forClient(); + + assertEqual(Object.keys(dbData).length, 1); + assertEqual(Object.keys(clientData).length, 1); + assertEqual(dbData.a, raw.a); + assertEqual(clientData.a, raw.a); + }, + + testFilterMetadata: function () { + var Model = FoxxModel.extend({}, { + attributes: { + a: {type: 'integer'} + } + }); + + var raw = { + a: 1, + _key: 2 + }; + + instance = new Model(raw); + var dbData = instance.forDB(); + var clientData = instance.forClient(); + + assertEqual(Object.keys(dbData).length, 2); + assertEqual(Object.keys(clientData).length, 1); + assertEqual(dbData.a, raw.a); + assertEqual(dbData._key, raw._key); + assertEqual(clientData.a, raw.a); + }, + + testFromClient: function () { + var Model = FoxxModel.extend({}, { + attributes: { + a: {type: 'integer'} + } + }); + + var raw = { + a: 1, + _key: 2 + }; + + instance = Model.fromClient(raw); + var dbData = instance.forDB(); + var clientData = instance.forClient(); + + assertEqual(Object.keys(dbData).length, 1); + assertEqual(Object.keys(clientData).length, 1); + assertEqual(dbData.a, raw.a); + assertEqual(clientData.a, raw.a); } }; }