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

loopback-angular

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

loopback-angular - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

8

karma.conf.js

@@ -18,3 +18,2 @@ // Karma configuration

'test.e2e/test-main.js',
{ pattern: 'node_modules/mocha-as-promised/**/*.js', included: false },
{ pattern: 'bower_components/**/*.js', included: false },

@@ -35,5 +34,10 @@ { pattern: 'test.e2e/**/*.js', included: false },

// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress'],
reporters: ['progress', 'junit'],
// CI friendly test output
junitReporter: {
outputFile: 'karma-xunit.xml'
},
// web server port

@@ -40,0 +44,0 @@ port: 9876,

@@ -38,5 +38,115 @@ var fs = require('fs');

// The URL of prototype methods include sharedCtor parameters like ":id"
// Because all $resource methods are static (non-prototype) in ngResource,
// the sharedCtor parameters should be added to the parameters
// of prototype methods.
c.methods.forEach(function fixArgsOfPrototypeMethods(method) {
var ctor = method.restClass.ctor;
if (!ctor || method.sharedMethod.isStatic) return;
method.accepts = ctor.accepts.concat(method.accepts);
});
result[name] = c;
});
buildScopes(result);
return result;
}
var SCOPE_METHOD_REGEX = /^prototype.__([^_]+)__(.+)$/;
function buildScopes(models) {
for (var modelName in models) {
buildScopesOfModel(models, modelName);
}
}
function buildScopesOfModel(models, modelName) {
var modelClass = models[modelName];
modelClass.scopes = {};
modelClass.methods.forEach(function(method) {
buildScopeMethod(models, modelName, method);
});
return modelClass;
}
// reverse-engineer scope method
// defined by loopback-datasource-juggler/lib/scope.js
function buildScopeMethod(models, modelName, method) {
var modelClass = models[modelName];
var match = method.name.match(SCOPE_METHOD_REGEX);
if (!match) return;
var op = match[1];
var scopeName = match[2];
var modelPrototype = modelClass.sharedClass.ctor.prototype;
var targetClass = modelPrototype[scopeName]._targetClass;
if (modelClass.scopes[scopeName] === undefined) {
if (!targetClass) {
console.error(
'Warning: scope %s.%s is missing _targetClass property.' +
'\nThe Angular code for this scope won\'t be generated.' +
'\nPlease upgrade to the latest version of' +
'\nloopback-datasource-juggler to fix the problem.',
modelName, scopeName);
modelClass.scopes[scopeName] = null;
return;
}
if (!findModelByName(models, targetClass)) {
console.error(
'Warning: scope %s.%s targets class %j, which is not exposed ' +
'\nvia remoting. The Angular code for this scope won\'t be generated.',
modelName, scopeName, targetClass);
modelClass.scopes[scopeName] = null;
return;
}
modelClass.scopes[scopeName] = {
methods: {},
targetClass: targetClass
};
} else if (modelClass.scopes[scopeName] === null) {
// Skip the scope, the warning was already reported
return;
}
var apiName = scopeName;
if (op == 'get') {
// no-op, create the scope accessor
} else if (op == 'delete') {
apiName += '.destroyAll';
} else {
apiName += '.' + op;
}
method.deprecated = 'Use ' + modelName + '.' + apiName + '() instead.';
// build a reverse record to be used in ngResource
// Product.__find__categories -> Category.::find::product::categories
var reverseName = '::' + op + '::' + modelName + '::' + scopeName;
var reverseMethod = Object.create(method);
reverseMethod.name = reverseName;
delete reverseMethod.deprecated;
reverseMethod.internal = 'Use ' + modelName + '.' + apiName + '() instead.';
var reverseModel = findModelByName(models, targetClass);
reverseModel.methods.push(reverseMethod);
var scopeMethod = Object.create(method);
scopeMethod.name = reverseName;
delete scopeMethod.deprecated;
modelClass.scopes[scopeName].methods[apiName] = scopeMethod;
}
function findModelByName(models, name) {
for (var n in models) {
if (n.toLowerCase() == name.toLowerCase())
return models[n];
}
}
{
"name": "loopback-angular",
"version": "1.0.0",
"version": "1.1.0",
"description": "Tool for auto-generating Angular $resource services for LoopBack",
"main": "index.js",
"bin": {
"lb-ng": "bin/lb-ng",
"lb-ng-doc": "bin/lb-ng-doc"
},
"scripts": {
"pretest": "jshint . ; bower install",
"test": "node test.e2e/test-server.js karma start --single-run --browsers PhantomJS"
"test": "node ./test.e2e/test-server.js node_modules/karma/bin/karma start --single-run --browsers PhantomJS"
},

@@ -31,29 +27,24 @@ "repository": {

"dependencies": {
"ejs": "~0.8.5"
"ejs": "^1.0"
},
"devDependencies": {
"chai": "*",
"mocha": "*",
"express": "~3.4.8",
"loopback-datasource-juggler": "~1.3.0",
"loopback": "~1.6.2",
"cors": "~2.1.1",
"karma-script-launcher": "~0.1.0",
"karma-chrome-launcher": "~0.1.2",
"karma-html2js-preprocessor": "~0.1.0",
"karma-firefox-launcher": "~0.1.2",
"karma-jasmine": "~0.1.5",
"karma-coffee-preprocessor": "~0.1.1",
"requirejs": "~2.1.9",
"karma-requirejs": "~0.2.1",
"karma-phantomjs-launcher": "~0.1.1",
"karma": "~0.10.8",
"karma-mocha": "~0.1.1",
"mocha-as-promised": "~2.0.0",
"bluebird": "~1.0.1",
"debug": "~0.7.4",
"fs.extra": "~1.2.1",
"bower": "~1.2.8",
"jshint": "~2.4.3"
"bluebird": "^1.2",
"bower": "^1.3",
"chai": "^1.9",
"cors": "^2.2",
"debug": "^0.8",
"express": "^3.5",
"fs.extra": "^1.2",
"jshint": "^2.4",
"karma": "^0.12.2",
"karma-chrome-launcher": "^0.1.2",
"karma-junit-reporter": "^0.2.1",
"karma-mocha": "^0.1.3",
"karma-phantomjs-launcher": "^0.1.2",
"karma-requirejs": "^0.2.1",
"loopback": "^1.7",
"loopback-datasource-juggler": "^1.3",
"mocha": "^1.18",
"requirejs": "^2.1.9"
}
}

@@ -261,3 +261,201 @@ define(['angular', 'given', 'util'], function(angular, given, util) {

});
describe('for models with hasAndBelongsToMany relations', function() {
var $injector, Product, Category, testData;
before(function() {
return given.servicesForLoopBackApp(
{
models: {
Product: {
properties: { name: 'string' },
options: {
relations: {
categories: {
model: 'Category',
type: 'hasAndBelongsToMany'
}
}
}
},
Category: {
properties: { name: 'string' },
options: {
relations: {
products: {
model: 'Product',
type: 'hasAndBelongsToMany'
}
}
}
}
},
setupFn: (function(app, cb) {
/*globals debug:true */
app.models.Product.create({ name: 'p1' }, function(err, prod) {
if (err) return cb(err);
debug('Created product', prod);
prod.categories.create({ name: 'c1' }, function(err, cat) {
if (err) return cb(err);
debug('Created category', cat);
prod.categories(true, function(err, list) {
if (err) return cb(err);
debug('Categories of product', list);
cb(null, {
product: prod,
category: cat
});
});
});
});
}).toString()
})
.then(function(createInjector) {
$injector = createInjector();
Product = $injector.get('Product');
Category = $injector.get('Category');
testData = $injector.get('testData');
});
});
it('provides scope methods', function() {
expect(Object.keys(Product), 'Product properties')
.to.contain('categories');
expect(Object.keys(Product.categories), 'Product.categories properties')
.to.have.members([
'create',
'destroyAll'
]);
});
it('gets related models with correct prototype', function() {
var list = Product.categories({ id: testData.product.id });
return list.$promise.then(function() {
// eql does not work for arrays with objects correctly :(
expect(list).to.have.length(1);
expect(list[0]).to.eql(new Category(testData.category));
});
});
it('creates a related model', function() {
var cat = Product.categories.create(
{ id: testData.product.id },
{ name: 'another-cat' });
return cat.$promise
.then(function() {
expect(cat).to.be.an.instanceof(Category);
expect(cat).to.have.property('name', 'another-cat');
})
.then(function() {
var list = Product.categories({ id: testData.product.id });
return list.$promise.then(function() {
var names = list.map(function(c) { return c.name; });
expect(names).to.eql([testData.category.name, cat.name]);
});
});
});
// Skipped due to strongloop/loopback-datasource-juggler#95
it.skip('removes all related models', function() {
return Product.categories.destroyAll({ id: testData.product.id })
.$promise
.then(function() {
var list = Product.categories({ id: testData.product.id });
return list.$promise.then(function() {
expect(list, 'product categories').to.have.length(0);
});
})
.then(function() {
var all = Product.find({ filter: true });
return all.$promise
.then(function() {
expect(all, 'all categories').to.have.length(0);
});
});
});
});
describe('for models with belongsTo relation', function() {
var $injector, Town, Country, testData;
before(function() {
return given.servicesForLoopBackApp(
{
models: {
Town: {
properties: { name: 'string' },
options: {
relations: {
country: {
model: 'Country',
type: 'belongsTo'
}
}
}
},
Country: {
properties: { name: 'string' },
options: {
relations: {
towns: {
model: 'Town',
type: 'hasMany'
}
}
}
}
},
setupFn: (function(app, cb) {
/*globals debug:true */
app.models.Country.create(
{ name: 'a-country' },
function(err, country) {
if (err) return cb(err);
debug('Created country', country);
country.towns.create({ name: 'a-town' },
function(err, town) {
if (err) return cb(err);
debug('Created town', town);
town.country(true, function(err, res) {
if (err) return cb(err);
debug('Country of the town', res);
cb(null, {
country: country,
town: town
});
});
}
);
}
);
}).toString()
})
.then(function(createInjector) {
$injector = createInjector();
Town = $injector.get('Town');
Country = $injector.get('Country');
testData = $injector.get('testData');
});
});
it('provides scope methods', function() {
expect(Object.keys(Town), 'Town properties')
.to.contain('country');
});
it('gets the related model with the correct prototype', function() {
var country = Town.country({ id: testData.town.id });
return country.$promise.then(function() {
expect(country).to.be.instanceof(Country);
for (var k in testData.country) {
expect(country[k], 'country.' + k).to.equal(testData.country[k]);
}
});
});
});
});
});

@@ -20,3 +20,2 @@ var tests = [];

angularMocks: 'bower_components/angular-mocks/angular-mocks',
mochaAsPromised: 'node_modules/mocha-as-promised/mocha-as-promised',
given: 'test.e2e/given',

@@ -46,5 +45,4 @@ util: 'test.e2e/util'

require(['chai', 'mochaAsPromised'], function(chai, mochaAsPromised) {
mochaAsPromised(window.Mocha);
require(['chai'], function(chai) {
window.expect = chai.expect;
});

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

var generator = require('..');
var extend = require('util')._extend;

@@ -24,2 +25,6 @@ var port = process.env.PORT || 3838;

// Save the pre-build models so that we can restore them before every test
var initialModels = loopback.Model.modelBuilder.models;
var initialDefinitions = loopback.Model.modelBuilder.definitions;
// Enable all domains to access our server via AJAX

@@ -47,4 +52,13 @@ // This way the script running in Karma page can

// other model objects
}
*/
},
setupFn: (function(app, cb) {
Customer.create(
{ name: 'a-customer' },
function(err, customer) {
if (err) return cb(err);
cb(null, { customer: customer });
});
}).toString()
}
*/
masterApp.post('/setup', function(req, res, next) {

@@ -55,2 +69,3 @@ var opts = req.body;

var enableAuth = opts.enableAuth;
var setupFn = compileSetupFn(name, opts.setupFn);

@@ -63,2 +78,6 @@ if (!name)

// hack: clear the static model registry populated by previous test apps
loopback.Model.modelBuilder.models = extend({}, initialModels);
loopback.Model.modelBuilder.definitions = extend({}, initialDefinitions);
lbApp = loopback();

@@ -82,12 +101,33 @@

try {
servicesScript = generator.services(lbApp, name, apiUrl);
} catch (err) {
console.error('Cannot generate services script:', err.stack);
servicesScript = 'throw new Error("Error generating services script.");';
}
setupFn(lbApp, function(err, data) {
if (err) {
console.error('app setup function failed', err);
res.send(500, err);
return;
}
res.send(200, { servicesUrl: baseUrl + 'services?' + name });
try {
servicesScript = generator.services(lbApp, name, apiUrl);
} catch (err) {
console.error('Cannot generate services script:', err.stack);
servicesScript = 'throw new Error("Error generating services script.");';
}
servicesScript += '\nangular.module(' + JSON.stringify(name) + ')' +
'.value("testData", ' + JSON.stringify(data, null, 2) + ');\n';
res.send(200, { servicesUrl: baseUrl + 'services?' + name });
}.bind(this));
});
function compileSetupFn(name, source) {
if (!source)
return function(app, cb) { cb(); };
var debug = require('debug')('test:' + name);
/*jshint evil:true */
return eval('(' + source + ')');
}
masterApp.get('/services', function(req, res, next) {

@@ -119,3 +159,4 @@ res.set('Content-Type', 'application/javascript');

child.on('error', function(err) {
console.log(err);
console.log('child_process.spawn failed', err);
process.exit(1);
});

@@ -122,0 +163,0 @@ child.on('exit', function() {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc