Skip to content

Commit b40a5f0

Browse files
committed
Backport of #2407
1 parent 52f1645 commit b40a5f0

File tree

20 files changed

+336
-165
lines changed

20 files changed

+336
-165
lines changed

browser/current-context.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6+
var g = require('strong-globalize')();
7+
68
module.exports = function(loopback) {
79
loopback.getCurrentContext = function() {
810
return null;
911
};
1012

1113
loopback.runInContext =
1214
loopback.createContext = function() {
13-
throw new Error('Current context is not supported in the browser.');
15+
throw new Error(g.f('Current context is not supported in the browser.'));
1416
};
1517
};

common/models/access-token.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Module Dependencies.
88
*/
99

10+
var g = require('strong-globalize')();
11+
1012
var loopback = require('../../lib/loopback');
1113
var assert = require('assert');
1214
var uid = require('uid2');
@@ -112,7 +114,7 @@ module.exports = function(AccessToken) {
112114
} else if (isValid) {
113115
cb(null, token);
114116
} else {
115-
var e = new Error('Invalid Access Token');
117+
var e = new Error(g.f('Invalid Access Token'));
116118
e.status = e.statusCode = 401;
117119
e.code = 'INVALID_TOKEN';
118120
cb(e);

common/models/acl.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
3737
*/
3838

39+
var g = require('strong-globalize')();
40+
3941
var loopback = require('../../lib/loopback');
4042
var async = require('async');
4143
var assert = require('assert');
@@ -535,7 +537,7 @@ module.exports = function(ACL) {
535537
break;
536538
default:
537539
process.nextTick(function() {
538-
var err = new Error('Invalid principal type: ' + type);
540+
var err = new Error(g.f('Invalid principal type: %s', type));
539541
err.statusCode = 400;
540542
cb(err);
541543
});

common/models/change.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Module Dependencies.
88
*/
99

10+
var g = require('strong-globalize')();
11+
1012
var PersistedModel = require('../../lib/loopback').PersistedModel;
1113
var loopback = require('../../lib/loopback');
1214
var utils = require('../../lib/utils');
@@ -112,7 +114,7 @@ module.exports = function(Change) {
112114
})
113115
.join('\n');
114116

115-
var msg = 'Cannot rectify ' + modelName + ' changes:\n' + desc;
117+
var msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc);
116118
err = new Error(msg);
117119
err.details = { errors: errors };
118120
return callback(err);

common/models/email.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* @inherits {Model}
1616
*/
1717

18+
var g = require('strong-globalize')();
19+
1820
module.exports = function(Email) {
1921

2022
/**
@@ -44,13 +46,13 @@ module.exports = function(Email) {
4446
*/
4547

4648
Email.send = function() {
47-
throw new Error('You must connect the Email Model to a Mail connector');
49+
throw new Error(g.f('You must connect the {{Email}} Model to a {{Mail}} connector'));
4850
};
4951

5052
/**
5153
* A shortcut for Email.send(this).
5254
*/
5355
Email.prototype.send = function() {
54-
throw new Error('You must connect the Email Model to a Mail connector');
56+
throw new Error(g.f('You must connect the {{Email}} Model to a {{Mail}} connector'));
5557
};
5658
};

common/models/user.js

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* Module Dependencies.
88
*/
99

10+
var g = require('strong-globalize')();
11+
1012
var loopback = require('../../lib/loopback');
1113
var utils = require('../../lib/utils');
1214
var path = require('path');
@@ -205,22 +207,22 @@ module.exports = function(User) {
205207
realmDelimiter);
206208

207209
if (realmRequired && !query.realm) {
208-
var err1 = new Error('realm is required');
210+
var err1 = new Error(g.f('{{realm}} is required'));
209211
err1.statusCode = 400;
210212
err1.code = 'REALM_REQUIRED';
211213
fn(err1);
212214
return fn.promise;
213215
}
214216
if (!query.email && !query.username) {
215-
var err2 = new Error('username or email is required');
217+
var err2 = new Error(g.f('{{username}} or {{email}} is required'));
216218
err2.statusCode = 400;
217219
err2.code = 'USERNAME_EMAIL_REQUIRED';
218220
fn(err2);
219221
return fn.promise;
220222
}
221223

222224
self.findOne({where: query}, function(err, user) {
223-
var defaultError = new Error('login failed');
225+
var defaultError = new Error(g.f('login failed'));
224226
defaultError.statusCode = 401;
225227
defaultError.code = 'LOGIN_FAILED';
226228

@@ -250,7 +252,7 @@ module.exports = function(User) {
250252
if (self.settings.emailVerificationRequired && !user.emailVerified) {
251253
// Fail to log in if email verification is not done yet
252254
debug('User email has not been verified');
253-
err = new Error('login failed as the email has not been verified');
255+
err = new Error(g.f('login failed as the email has not been verified'));
254256
err.statusCode = 401;
255257
err.code = 'LOGIN_FAILED_EMAIL_NOT_VERIFIED';
256258
fn(err);
@@ -296,7 +298,7 @@ module.exports = function(User) {
296298
} else if (accessToken) {
297299
accessToken.destroy(fn);
298300
} else {
299-
fn(new Error('could not find accessToken'));
301+
fn(new Error(g.f('could not find {{accessToken}}')));
300302
}
301303
});
302304
return fn.promise;
@@ -438,15 +440,21 @@ module.exports = function(User) {
438440

439441
options.text = options.text.replace(/\{href\}/g, options.verifyHref);
440442

443+
options.text = g.f(options.text);
444+
441445
options.to = options.to || user.email;
442446

443447
options.subject = options.subject || 'Thanks for Registering';
444448

449+
options.subject = g.f(options.subject);
450+
445451
options.headers = options.headers || {};
446452

447453
var template = loopback.template(options.template);
448454
options.html = template(options);
449455

456+
options.html = g.f(options.html);
457+
450458
Email.send(options, function(err, email) {
451459
if (err) {
452460
fn(err);
@@ -501,11 +509,11 @@ module.exports = function(User) {
501509
});
502510
} else {
503511
if (user) {
504-
err = new Error('Invalid token: ' + token);
512+
err = new Error(g.f('Invalid token: %s', token));
505513
err.statusCode = 400;
506514
err.code = 'INVALID_TOKEN';
507515
} else {
508-
err = new Error('User not found: ' + uid);
516+
err = new Error(g.f('User not found: %s', uid));
509517
err.statusCode = 404;
510518
err.code = 'USER_NOT_FOUND';
511519
}
@@ -533,7 +541,7 @@ module.exports = function(User) {
533541

534542
options = options || {};
535543
if (typeof options.email !== 'string') {
536-
var err = new Error('Email is required');
544+
var err = new Error(g.f('Email is required'));
537545
err.statusCode = 400;
538546
err.code = 'EMAIL_REQUIRED';
539547
cb(err);
@@ -545,7 +553,7 @@ module.exports = function(User) {
545553
return cb(err);
546554
}
547555
if (!user) {
548-
err = new Error('Email not found');
556+
err = new Error(g.f('Email not found'));
549557
err.statusCode = 404;
550558
err.code = 'EMAIL_NOT_FOUND';
551559
return cb(err);
@@ -581,7 +589,7 @@ module.exports = function(User) {
581589
if (typeof plain === 'string' && plain) {
582590
return true;
583591
}
584-
var err = new Error('Invalid password: ' + plain);
592+
var err = new Error(g.f('Invalid password: %s', plain));
585593
err.statusCode = 422;
586594
throw err;
587595
};
@@ -640,20 +648,21 @@ module.exports = function(User) {
640648
UserModel.remoteMethod(
641649
'login',
642650
{
643-
description: 'Login a user with username/email and password.',
651+
description: g.f('Login a user with username/email and password.'),
644652
accepts: [
645653
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
646-
{arg: 'include', type: ['string'], http: {source: 'query' },
647-
description: 'Related objects to include in the response. ' +
648-
'See the description of return value for more details.'}
654+
{arg: 'include', type: ['string'], http: {source: 'query'},
655+
description: g.f('Related objects to include in the response. ' +
656+
'See the description of return value for more details.') },
649657
],
650658
returns: {
651659
arg: 'accessToken', type: 'object', root: true,
652660
description:
653-
'The response body contains properties of the AccessToken created on login.\n' +
661+
g.f('The response body contains properties of the {{AccessToken}} created on login.\n' +
654662
'Depending on the value of `include` parameter, the body may contain ' +
655663
'additional properties:\n\n' +
656-
' - `user` - `{User}` - Data of the currently logged in user. (`include=user`)\n\n'
664+
' - `user` - `U+007BUserU+007D` - Data of the currently logged in user. ' +
665+
'{{(`include=user`)}}\n\n'),
657666
},
658667
http: {verb: 'post'}
659668
}
@@ -662,25 +671,25 @@ module.exports = function(User) {
662671
UserModel.remoteMethod(
663672
'logout',
664673
{
665-
description: 'Logout a user with access token.',
674+
description: g.f('Logout a user with access token.'),
666675
accepts: [
667676
{arg: 'access_token', type: 'string', required: true, http: function(ctx) {
668-
var req = ctx && ctx.req;
669-
var accessToken = req && req.accessToken;
670-
var tokenID = accessToken && accessToken.id;
671-
672-
return tokenID;
673-
}, description: 'Do not supply this argument, it is automatically extracted ' +
674-
'from request headers.'
675-
}],
677+
var req = ctx && ctx.req;
678+
var accessToken = req && req.accessToken;
679+
var tokenID = accessToken && accessToken.id;
680+
return tokenID;
681+
}, description: g.f('Do not supply this argument, it is automatically extracted ' +
682+
'from request headers.'),
683+
},
684+
],
676685
http: {verb: 'all'}
677686
}
678687
);
679688

680689
UserModel.remoteMethod(
681690
'confirm',
682691
{
683-
description: 'Confirm a user registration with email verification token.',
692+
description: g.f('Confirm a user registration with email verification token.'),
684693
accepts: [
685694
{arg: 'uid', type: 'string', required: true},
686695
{arg: 'token', type: 'string', required: true},
@@ -693,7 +702,7 @@ module.exports = function(User) {
693702
UserModel.remoteMethod(
694703
'resetPassword',
695704
{
696-
description: 'Reset password for a user with email.',
705+
description: g.f('Reset password for a user with email.'),
697706
accepts: [
698707
{arg: 'options', type: 'object', required: true, http: {source: 'body'}}
699708
],
@@ -704,7 +713,7 @@ module.exports = function(User) {
704713
UserModel.afterRemote('confirm', function(ctx, inst, next) {
705714
if (ctx.args.redirect !== undefined) {
706715
if (!ctx.res) {
707-
return next(new Error('The transport does not support HTTP redirects.'));
716+
return next(new Error(g.f('The transport does not support HTTP redirects.')));
708717
}
709718
ctx.res.location(ctx.args.redirect);
710719
ctx.res.status(302);
@@ -722,7 +731,7 @@ module.exports = function(User) {
722731
// email validation regex
723732
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
724733

725-
UserModel.validatesFormatOf('email', {with: re, message: 'Must provide a valid email'});
734+
UserModel.validatesFormatOf('email', {with: re, message: g.f('Must provide a valid email')});
726735

727736
// FIXME: We need to add support for uniqueness of composite keys in juggler
728737
if (!(UserModel.settings.realmRequired || UserModel.settings.realmDelimiter)) {

example/client-server/client.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6+
var g = require('strong-globalize')();
7+
68
var loopback = require('../../');
79
var client = loopback();
810
var CartItem = require('./models').CartItem;
@@ -16,10 +18,10 @@ CartItem.attachTo(remote);
1618

1719
// call the remote method
1820
CartItem.sum(1, function(err, total) {
19-
console.log('result:', err || total);
21+
g.log('result:%s', err || total);
2022
});
2123

2224
// call a built in remote method
2325
CartItem.find(function(err, items) {
24-
console.log(items);
26+
g.log(items);
2527
});

example/colors/app.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6+
var g = require('strong-globalize')();
7+
68
var loopback = require('../../');
79
var app = loopback();
810

@@ -22,4 +24,4 @@ Color.create({name: 'blue'});
2224

2325
app.listen(3000);
2426

25-
console.log('a list of colors is available at http://localhost:3000/colors');
27+
g.log('a list of colors is available at {{http://localhost:3000/colors}}');

example/context/app.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6+
var g = require('strong-globalize')();
7+
68
var loopback = require('../../');
79
var app = loopback();
810

@@ -22,13 +24,13 @@ var Color = loopback.createModel('color', { 'name': String });
2224
Color.beforeRemote('**', function (ctx, unused, next) {
2325
// Inside LoopBack code, you can read the property from the context
2426
var ns = loopback.getCurrentContext();
25-
console.log('Request to host', ns && ns.get('host'));
27+
g.log('Request to host %s', ns && ns.get('host'));
2628
next();
2729
});
2830

2931
app.dataSource('db', { connector: 'memory' });
3032
app.model(Color, { dataSource: 'db' });
3133

3234
app.listen(3000, function() {
33-
console.log('A list of colors is available at http://localhost:3000/colors');
35+
g.log('A list of colors is available at {{http://localhost:3000/colors}}');
3436
});

example/mobile-models/app.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// This file is licensed under the MIT License.
44
// License text available at https://opensource.org/licenses/MIT
55

6+
var g = require('strong-globalize')();
7+
68
var models = require('../../lib/models');
79

810
var loopback = require('../../');
@@ -37,14 +39,15 @@ var data = {pushSettings: [
3739
]}
3840

3941
Application.create(data, function(err, data) {
40-
console.log('Created: ', data.toObject());
42+
g.log('Created: %s', data.toObject());
4143
});
4244

4345

44-
Application.register('rfeng', 'MyApp', {description: 'My first mobile application'}, function (err, result) {
45-
console.log(result.toObject());
46+
Application.register('rfeng', 'MyApp', { description: g.f('My first mobile application') },
47+
function(err, result) {
48+
console.log(result.toObject());
4649

47-
result.resetKeys(function (err, result) {
48-
console.log(result.toObject());
49-
});
50+
result.resetKeys(function(err, result) {
51+
console.log(result.toObject());
52+
});
5053
});

0 commit comments

Comments
 (0)