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

knockout-sync

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

knockout-sync - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5

2

package.json
{
"name": "knockout-sync",
"version": "0.1.4",
"version": "0.1.5",
"description": "A small backend using knockout mapping to sync entities with a RESTful Backend",

@@ -5,0 +5,0 @@ "main": "Gruntfile.js",

@@ -1,2 +0,2 @@

define(['knockout-mapping', './EntityModel', 'Amplify'], function(koMapping, EntityModel, amplify) {
define(['knockout-mapping', './EntityModel', 'Amplify', 'lodash'], function(koMapping, EntityModel, amplify, _) {

@@ -6,3 +6,2 @@ /**

knockout-sync.entity-saved

@@ -17,5 +16,7 @@ triggered when an entity with an existing id was saved again

return function Backend(driver, entityModel) {
return function Backend(driver, entityModel, prefixUrl) {
var that = this;
that.prefixUrl = prefixUrl || '/api/';
if (!entityModel || !(entityModel instanceof EntityModel)) {

@@ -32,3 +33,3 @@ throw new Error('missing parameter #2 for EntityManager. Provide the entity model');

this.save = function(entity) {
this.save = function(entity, callback) {
var method, url;

@@ -39,6 +40,6 @@ var entityMeta = that.model.getEntityMeta(entity.fqn);

method = 'put';
url = '/api/'+entityMeta.singular+'/'+entity.id();
url = that.prefixUrl+entityMeta.singular+'/'+entity.id();
} else {
method = 'post';
url = '/api/'+entityMeta.plural;
url = that.prefixUrl+entityMeta.plural;
}

@@ -64,2 +65,6 @@

}
if (callback) {
callback.call(error);
}
});

@@ -74,3 +79,3 @@ };

that.driver.dispatch('GET', '/api/'+entityMeta.plural, undefined, function(error, result) {
that.driver.dispatch('GET', that.prefixUrl+entityMeta.plural, undefined, function(error, result) {
callback(undefined, result);

@@ -80,2 +85,49 @@ });

/**
* Queries a single entity returned by backend
*/
this.get = function(entityFQN, identifiers, callback) {
var entityMeta = that.model.getEntityMeta(entityFQN);
if (_.isPlainObject(identifiers)) {
// maybe map to filter here
identifiers = _.values(identifiers);
} else if (!_.isArray(identifiers)) { // single scalars
identifiers = [identifiers];
}
that.driver.dispatch('GET', that.prefixUrl+entityMeta.plural+'/'+identifiers.join('/'), undefined, function(error, result) {
/*
normalize single responses to always use repsonse plural form
like:
{
"page": {
"id": 7
"slug": "start"
}
}
to
{
"pages": [
{
"id": 7,
"slug": "start"
}
]
}
*/
if (result[entityMeta.singular] && !result[entityMeta.plural]) {
result[entityMeta.plural] = [ result[entityMeta.singular] ];
delete result[entityMeta.singular];
}
callback(undefined, result);
});
};
this.serializeEntity = function(entity) {

@@ -87,4 +139,4 @@ if (typeof(entity.serialize) === 'function') {

return koMapping.toJS(entity);
}
};
};
});

@@ -31,8 +31,10 @@ define(['./Exception', './EntityModel', 'lodash', 'knockout', 'knockout-mapping', 'Amplify'], function(Exception, EntityModel, _, ko, koMapping, amplify) {

this.isInit = false;
this.init = function() {
if (that.isInit) {
throw new Error('dont init the em twice!');
}
var firstFakeResponse = {};
// initialize empty collections
// the ko.observableArray([]) has not the mapped* functions (like mappedRemove), when it is not mapped yet, so we do the first mapping by hand with empty collections

@@ -44,3 +46,5 @@ _.each(that.model.getEntities(), function(entityMeta) {

this.mapResponse(firstFakeResponse);
// initialize all collections with a fully empty response
that.mapResponse(firstFakeResponse);
that.isInit = true;
};

@@ -137,2 +141,13 @@

/*
* returns the observable referencing the current collection of all entities fetched with entityFQN
* @return ko.observableArray()
*/
this.refAll = function(entityFQN) {
var meta = this.getEntityMeta(entityFQN);
return that.entities[meta.plural];
};
this.getKnockoutMappingMetadata = function() {

@@ -190,2 +205,6 @@ var mapping = {};

create: function(options) {
if (!options.data) {
return ko.observable(null);
}
if (options.data.$type) {

@@ -192,0 +211,0 @@ var relatedEntity = that.find(propertyEntityMeta.fqn, options.data.$ref);

@@ -11,6 +11,5 @@ var chai = require('chai');

_.extend(config, {
nodeRequire: require,
baseUrl: "src/js", // seems to be relative to the dir where mocha is called
}
)
nodeRequire: require,
baseUrl: "src/js", // seems to be relative to the dir where mocha is called
})
);

@@ -21,4 +20,3 @@

var EntityModel = requirejs('KnockoutSync/EntityModel');
var AjaxDriver = function() {
};
var AjaxDriver = function() {};
var amplify = requirejs('Amplify');

@@ -38,3 +36,4 @@

}).to.throw (Error, 'Provide the entity model');
}).to.
throw (Error, 'Provide the entity model');

@@ -47,3 +46,4 @@ });

}).to.throw (Error, 'Provide the driver');
}).to.
throw (Error, 'Provide the driver');

@@ -55,3 +55,7 @@ });

var user = new UserModel({name: 'Ross', email: 'ross@ps-webforge.com', id: undefined});
var user = new UserModel({
name: 'Ross',
email: 'ross@ps-webforge.com',
id: undefined
});

@@ -77,6 +81,10 @@ driver.dispatch = function(method, url, data, callback) {

backend.save(user);
var saveCalled = false;
backend.save(user, function(error) {
saveCalled = true;
expect(error).to.not.exist;
});
expect(dispatched, 'dispatch is called').to.be.true;
expect(published, 'publishe is called').to.be.true;
expect(saveCalled, 'save callback was called').to.be.true;
expect(user.id(), 'user.id').to.be.equal(7);

@@ -88,3 +96,7 @@ });

var user = new UserModel({name: 'Ross', email: 'ross@ps-webforge.net', id: 7});
var user = new UserModel({
name: 'Ross',
email: 'ross@ps-webforge.net',
id: 7
});

@@ -107,6 +119,11 @@ driver.dispatch = function(method, url, data, callback) {

backend.save(user);
var saveCalled = false;
backend.save(user, function(error) {
saveCalled = true;
expect(error).to.not.exist;
});
expect(dispatched, 'dispatch is called').to.be.true;
expect(published, 'published is called').to.be.true;
expect(user.id(), 'user.id').to.be.equal(7);
expect(saveCalled, 'save callback was called').to.be.true;
});

@@ -117,5 +134,15 @@

var user1 = new UserModel({name: 'Ross', email: 'ross@ps-webforge.net', id: 7});
var user2 = new UserModel({name: 'Rachel', email: 'rachel@ps-webforge.net', id: 8});
var result = { 'users': [user1.serialize, user2.serialize()] };
var user1 = new UserModel({
name: 'Ross',
email: 'ross@ps-webforge.net',
id: 7
});
var user2 = new UserModel({
name: 'Rachel',
email: 'rachel@ps-webforge.net',
id: 8
});
var result = {
'users': [user1.serialize, user2.serialize()]
};

@@ -138,2 +165,67 @@ driver.dispatch = function(method, url, data, callback) {

});
});
var DispatchExpectation = function(settings) {
var that = this;
this.dispatched = false;
driver.dispatch = function(method, url, data, callback) {
that.dispatched = true;
expect(method, 'method').to.be.equal(settings.method);
expect(url, 'url').to.be.equal(settings.url);
expect(data, 'data').to.be.eql(settings.data);
callback(settings.error, settings.result);
};
this.wasDispatched = function() {
expect(that.dispatched, 'driver did dispatch the request').to.be.true;
};
this.resultEquals = function(returnedResult) {
expect(returnedResult, 'result returned').to.be.eql(settings.normalizedResult || settings.result);
};
};
var expectDriverToReturnSingleUser = function() {
var user = new UserModel({
name: 'Rachel',
email: 'rachel@ps-webforge.net',
id: 8
});
return new DispatchExpectation({
result: {
'user': user.serialize()
},
normalizedResult: {
'users': [user.serialize()]
},
method: 'GET',
url: '/api/users/8',
data: undefined
});
};
it("queries one of specific entity by single scalar", function() {
var expectation = expectDriverToReturnSingleUser();
backend.get('ACME.Blog.Entities.User', 8, function(error, returnedResult) {
expectation.wasDispatched();
expect(error).to.be.not.existing;
expectation.resultEquals(returnedResult);
});
});
it("queries one of specific entity by identifiers object", function() {
var expectation = expectDriverToReturnSingleUser();
backend.get('ACME.Blog.Entities.User', {id: 8}, function(error, returnedResult) {
expectation.wasDispatched();
expect(error).to.be.not.existing;
expectation.resultEquals(returnedResult);
});
});
});

@@ -162,2 +162,21 @@ var chai = require('chai'),

});
it("applies nested empty entities without error to empty observables (todo: define mapping to what)", function() {
var response = {
"posts": [{
"id": 1,
"title": "Working with associations",
"author": null
}]
};
em.mapResponse(response);
var post1 = em.find('ACME.Blog.Entities.Post', 1);
expect(post1).to.have.property('author');
// to define: empty observable or just null or undefined?
expect(post1.author(), 'author from post1').to.be.not.existing;
});
});

@@ -164,0 +183,0 @@ });

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc