Skip to content

Commit 7ae1e3e

Browse files
authored
Merge pull request #219 from keithajackson/feature/optional-common-modules
Add option to leave out definitions for common modules + namespace models
2 parents 811ea79 + 1c7ec4c commit 7ae1e3e

File tree

5 files changed

+190
-19
lines changed

5 files changed

+190
-19
lines changed

lib/services.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ module.exports = function generateServices(app, options) {
5454
options = extend({
5555
ngModuleName: 'lbServices',
5656
apiUrl: '/',
57+
includeCommonModules: true,
58+
namespaceModels: false,
59+
namespaceDelimiter: '.',
5760
}, options);
5861

5962
var models = describeModels(app, options);
@@ -67,13 +70,26 @@ module.exports = function generateServices(app, options) {
6770
moduleName: options.ngModuleName,
6871
models: models,
6972
urlBase: options.apiUrl.replace(/\/+$/, ''),
73+
includeCommonModules: options.includeCommonModules,
7074
});
7175
};
7276

77+
function getFormattedModelName(modelName, options) {
78+
// Always capitalize first letter of model name
79+
var resourceModelName = modelName[0].toUpperCase() + modelName.slice(1);
80+
81+
// Prefix with the module name and delimiter if namespacing is on
82+
if (options.namespaceModels) {
83+
resourceModelName = options.ngModuleName +
84+
options.namespaceDelimiter + resourceModelName;
85+
}
86+
return resourceModelName;
87+
}
88+
7389
function describeModels(app, options) {
7490
var result = {};
7591
app.handler('rest').adapter.getClasses().forEach(function(c) {
76-
var name = c.name;
92+
var name = getFormattedModelName(c.name, options);
7793
c.description = c.sharedClass.ctor.settings.description;
7894

7995
if (!c.ctor) {

lib/services.template.ejs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' &&
3737

3838
<% for (var modelName in models) {
3939
var meta = models[modelName];
40-
// capitalize the model name
41-
modelName = modelName[0].toUpperCase() + modelName.slice(1);
4240
-%>
4341
/**
4442
* @ngdoc object
@@ -300,7 +298,7 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' &&
300298
}]);
301299
302300
<% } // for modelName in models -%>
303-
301+
<% if (includeCommonModules) { %>
304302
module
305303
.factory('LoopBackAuth', function() {
306304
var props = ['accessTokenId', 'currentUserId', 'rememberMe'];
@@ -490,7 +488,8 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' &&
490488
return LoopBackResource;
491489
}];
492490
});
493-
<%
491+
<% } // end if (includeCommonModules)
492+
494493
function getJsDocType(arg) {
495494
var type = arg.type == 'any' ? '*' : arg.type;
496495
if (!arg.required) type += '=';

test.e2e/given.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ define(['angular', 'angularMocks', 'angularResource'], function(angular) {
5858
* ```
5959
*/
6060
given.servicesForLoopBackApp = function(options, cb) {
61-
options.name = generateUniqueServiceName(options.name);
61+
if (!options.name) {
62+
options.name = generateUniqueServiceName(options.name);
63+
}
6264

6365
var promise = callSetup(options)
6466
.then(function(config) { return config.servicesUrl; })

test.e2e/spec/services.spec.js

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,150 @@ define(['angular', 'given', 'util'], function(angular, given, util) {
10441044
});
10451045
});
10461046

1047+
describe('$resource generated with includeCommonModules:false', function() {
1048+
var $injector;
1049+
before(function() {
1050+
return given.servicesForLoopBackApp(
1051+
{
1052+
models: {
1053+
Product: {
1054+
properties: {
1055+
name: 'string',
1056+
price: { type: 'number' },
1057+
},
1058+
},
1059+
},
1060+
includeCommonModules: false,
1061+
})
1062+
.then(function(createInjector) {
1063+
$injector = createInjector();
1064+
});
1065+
});
1066+
1067+
it('does not have "LoopBackAuth module"', function() {
1068+
expect(function() {
1069+
$injector.get('LoopBackAuth');
1070+
}).to.throw(/Unknown provider/);
1071+
});
1072+
1073+
it('does not have "LoopBackResource provider"', function() {
1074+
expect(function() {
1075+
$injector.get('LoopBackResource');
1076+
}).to.throw(/Unknown provider/);
1077+
});
1078+
1079+
it('does not have "LoopBackAuthRequestInterceptor module"',
1080+
function() {
1081+
expect(function() {
1082+
$injector.get('LoopBackAuthRequestInterceptor');
1083+
}).to.throw(/Unknown provider/);
1084+
});
1085+
});
1086+
1087+
describe('$resource generated with includeCommonModules:true (by default)',
1088+
function() {
1089+
var $injector;
1090+
before(function() {
1091+
return given.servicesForLoopBackApp(
1092+
{
1093+
models: {
1094+
Product: {
1095+
properties: {
1096+
name: 'string',
1097+
price: { type: 'number' },
1098+
},
1099+
},
1100+
},
1101+
})
1102+
.then(function(createInjector) {
1103+
$injector = createInjector();
1104+
});
1105+
});
1106+
1107+
it('has "LoopBackAuth module"', function() {
1108+
expect(function() {
1109+
$injector.get('LoopBackAuth');
1110+
}).to.not.throw();
1111+
});
1112+
1113+
it('has "LoopBackResource provider"', function() {
1114+
expect(function() {
1115+
$injector.get('LoopBackResource');
1116+
}).to.not.throw();
1117+
});
1118+
1119+
it('has "LoopBackAuthRequestInterceptor module"',
1120+
function() {
1121+
expect(function() {
1122+
$injector.get('LoopBackAuthRequestInterceptor');
1123+
}).to.not.throw();
1124+
});
1125+
});
1126+
1127+
describe('$resource generated with namespaceModels:true', function() {
1128+
var $injector;
1129+
before(function() {
1130+
return given.servicesForLoopBackApp(
1131+
{
1132+
models: {
1133+
Product: {
1134+
properties: {
1135+
name: 'string',
1136+
price: { type: 'number' },
1137+
},
1138+
},
1139+
},
1140+
name: 'lbServices',
1141+
namespaceModels: true,
1142+
})
1143+
.then(function(createInjector) {
1144+
$injector = createInjector();
1145+
});
1146+
});
1147+
1148+
it('defines the "Product" model as "lbServices.Product"', function() {
1149+
expect(function() {
1150+
$injector.get('Product');
1151+
}).to.throw(/Unknown provider/);
1152+
expect(function() {
1153+
$injector.get('lbServices.Product');
1154+
}).to.not.throw();
1155+
});
1156+
});
1157+
1158+
describe('$resource generated with namespaceModels:true and ' +
1159+
'namespaceDelimiter:_', function() {
1160+
var $injector;
1161+
before(function() {
1162+
return given.servicesForLoopBackApp(
1163+
{
1164+
models: {
1165+
Product: {
1166+
properties: {
1167+
name: 'string',
1168+
price: { type: 'number' },
1169+
},
1170+
},
1171+
},
1172+
name: 'lbServices',
1173+
namespaceModels: true,
1174+
namespaceDelimiter: '_',
1175+
})
1176+
.then(function(createInjector) {
1177+
$injector = createInjector();
1178+
});
1179+
});
1180+
1181+
it('defines the "Product" model as "lbServices.Product"', function() {
1182+
expect(function() {
1183+
$injector.get('Product');
1184+
}).to.throw(/Unknown provider/);
1185+
expect(function() {
1186+
$injector.get('lbServices_Product');
1187+
}).to.not.throw();
1188+
});
1189+
});
1190+
10471191
describe('for models with belongsTo relation', function() {
10481192
var $injector, Town, Country, testData;
10491193
before(function() {

test.e2e/test-server.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ masterApp.post('/setup', function(req, res, next) {
6767
var name = opts.name;
6868
var models = opts.models;
6969
var enableAuth = opts.enableAuth;
70-
var includeSchema = opts.includeSchema;
7170
var setupFn = compileSetupFn(name, opts.setupFn);
7271

7372
if (!name)
@@ -105,19 +104,8 @@ masterApp.post('/setup', function(req, res, next) {
105104
res.send(500, err);
106105
return;
107106
}
108-
109107
try {
110-
if (includeSchema) {
111-
// the new options-based API
112-
servicesScript = generator.services(lbApp, {
113-
ngModuleName: name,
114-
apiUrl: apiUrl,
115-
includeSchema: includeSchema,
116-
});
117-
} else {
118-
// the old API, test it to verify backwards compatibility
119-
servicesScript = generator.services(lbApp, name, apiUrl);
120-
}
108+
servicesScript = generateService(generator, lbApp, apiUrl, opts);
121109
} catch (err) {
122110
console.error('Cannot generate services script:', err.stack);
123111
servicesScript = 'throw new Error("Error generating services script.");';
@@ -161,6 +149,28 @@ masterApp.listen(port, function() {
161149
runAndExit(process.argv[2], process.argv.slice(3));
162150
});
163151

152+
function generateService(generator, lbApp, apiUrl, opts) {
153+
var servicesScript;
154+
if (opts.includeSchema !== undefined ||
155+
opts.includeCommonModules !== undefined ||
156+
opts.namespaceModels !== undefined ||
157+
opts.namespaceDelimiter !== undefined) {
158+
// the new options-based API
159+
160+
// build options object for new options-based API
161+
var generatorOptions = opts;
162+
generatorOptions.ngModuleName = opts.name;
163+
generatorOptions.apiUrl = apiUrl;
164+
165+
servicesScript = generator.services(lbApp, generatorOptions);
166+
} else {
167+
// the old API, test it to verify backwards compatibility
168+
servicesScript = generator.services(lbApp, opts.name, apiUrl);
169+
}
170+
171+
return servicesScript;
172+
}
173+
164174
function runAndExit(cmd, args) {
165175
console.log('Running %s %s', cmd, args.join(' '));
166176
var child = require('child_process').spawn(cmd, args, { stdio: 'inherit' });

0 commit comments

Comments
 (0)