diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..e67a2ee --- /dev/null +++ b/.jshintrc @@ -0,0 +1,14 @@ +{ + "strict": true, + "undef": true, + "unused": true, + "node": true, + "globals" : { + "describe" : false, + "it" : false, + "before" : false, + "beforeEach" : false, + "after" : false, + "afterEach" : false + } +} diff --git a/lib/av-extra.js b/lib/av-extra.js index 612cafd..977dfb4 100644 --- a/lib/av-extra.js +++ b/lib/av-extra.js @@ -1,8 +1,9 @@ +'use strict'; var http = require('http'); var https = require('https'); var urlParser = require('url'); var util = require('util'); -var querystring = require('querystring'); +var qs = require('querystring'); var iconvlite = require('iconv-lite'); var AV = require('avoscloud-sdk').AV; var utils = require('./utils'); @@ -12,7 +13,7 @@ var version = require('../package.json').version; // 调用 API 时增加 prod 信息 if (!AV._old_request) { AV._old_request = AV._request; - AV._request = function (route, className, objectId, method, dataObject, options) { + AV._request = function (route, className, objectId, method, dataObject) { if (!dataObject) { dataObject = {}; } @@ -108,7 +109,7 @@ AV._ajax = function(method, url, data, success, error) { return promise._thenRunCallbacks(options); }; -mimeTypes = [ +var mimeTypes = [ { pattern: /^text\/plain.*/i, process: function(res) { @@ -138,13 +139,13 @@ var trySetData = function(httpRes) { } if (type) { try { - return httpRes.data = type.process(httpRes); + httpRes.data = type.process(httpRes); } catch (_error) { e = _error; - return httpRes.data = httpRes.buffer; + httpRes.data = httpRes.buffer; } } else { - return httpRes.data = httpRes.buffer; + httpRes.data = httpRes.buffer; } }; @@ -191,7 +192,7 @@ AV.Cloud.httpRequest = function(options) { } promise = new AV.Promise(); params = options.params; - headers = options.headers || ''; + headers = options.headers || {}; method = options.method || 'GET'; body = options.body; text = options.text ? options.text : true; @@ -210,16 +211,16 @@ AV.Cloud.httpRequest = function(options) { if (params) { path = !search ? path + '?' : path + '&'; if (utils.typeOf(params) === 'string') { - params = querystring.parse(params); + params = qs.parse(params); } - params = querystring.stringify(params); + params = qs.stringify(params); path = path + params; } - contentType = headers['Content-Type'] || headers['content-type']; + contentType = headers['Content-Type']; if ((method === 'POST') && (!contentType)) { headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; } - theBody = castBody(body, headers['Content-Type'] || headers['content-type']); + theBody = castBody(body, headers['Content-Type']); contentLen = theBody ? theBody.length : 0; if (!headers['Content-Length']) { headers['Content-Length'] = contentLen; diff --git a/lib/avosExpressCookieSession/index.js b/lib/avosExpressCookieSession/index.js index 93cc269..7ff85aa 100644 --- a/lib/avosExpressCookieSession/index.js +++ b/lib/avosExpressCookieSession/index.js @@ -2,9 +2,9 @@ * update from cookie-sesion middleware */ (function() { + 'use strict'; var domain = require('domain'); var Cookies = require('cookies'); - var url = require('url'); var onHeaders = require('on-headers'); var debug = require('debug')('AV:cookieSession'); @@ -37,7 +37,6 @@ return function cookieSession(req, res, next) { var cookieSetter = function() { var cookies = req.sessionCookies = new Cookies(req, res, keys); - var sess; // to pass to Session() req.sessionOptions = opts; diff --git a/lib/avosExpressHttpsRedirect/index.js b/lib/avosExpressHttpsRedirect/index.js index 00ce092..b1ed101 100644 --- a/lib/avosExpressHttpsRedirect/index.js +++ b/lib/avosExpressHttpsRedirect/index.js @@ -1,5 +1,6 @@ // Generated by CoffeeScript 1.8.0 (function() { + 'use strict'; module.exports = function(AV) { return function() { return function(req, res, next) { diff --git a/lib/leanengine.js b/lib/leanengine.js index 7bd203a..42959e6 100644 --- a/lib/leanengine.js +++ b/lib/leanengine.js @@ -1,3 +1,4 @@ +'use strict'; var connect = require('connect'), bodyParser = require('body-parser'), https = require('https'), @@ -5,7 +6,7 @@ var connect = require('connect'), crypto = require('crypto'), version = require('../package.json').version, AV = require('./av-extra'), - utils = require('./utils'); + utils = require('./utils'), avosExpressCookieSession = require('./avosExpressCookieSession'), avosExpressHttpsRedirect = require('./avosExpressHttpsRedirect'), debug = require('debug')('AV:LeanEngine'); @@ -43,7 +44,7 @@ Cloud.use('/__engine/1/ping', function(req, res) { ['1', '1.1'].forEach(function(apiVersion) { ['', '/__engine'].forEach(function(urlNamespace) { var route = '/' + apiVersion + '/functions'; - if (urlNamespace != '') { + if (urlNamespace !== '') { route = urlNamespace + '/' + apiVersion + '/functions'; } @@ -83,7 +84,7 @@ Cloud.use('/__engine/1/ping', function(req, res) { // parse authInfo Cloud.use(route, function(req, res, next) { - var appId, appKey, contentType, param, prod, prodHeader, prodValue, sessionToken; + var appId, appKey, masterKey, contentType, param, prod, prodHeader, prodValue, sessionToken; contentType = req.headers['content-type']; if (/^text\/plain.*/i.test(contentType)) { if (req.body && req.body !== '') { @@ -146,7 +147,10 @@ Cloud.use('/__engine/1/ping', function(req, res) { } requestSign = req.headers['x-avoscloud-request-sign']; if (requestSign) { - _ref = requestSign.split(','), sign = _ref[0], timestamp = _ref[1], master = _ref[2]; + _ref = requestSign.split(','); + sign = _ref[0]; + timestamp = _ref[1]; + master = _ref[2]; key = master === 'master' ? AV.masterKey : AV.applicationKey; validSign = signByKey(timestamp, key); if (validSign === sign.toLowerCase()) { @@ -161,7 +165,7 @@ Cloud.use('/__engine/1/ping', function(req, res) { }); // get metadatas func - Cloud.use(route + '/_ops/metadatas', function(req, res, next) { + Cloud.use(route + '/_ops/metadatas', function(req, res) { if (req.AV.authMasterKey) { return resp(res, Object.keys(Cloud.__code)); } @@ -177,7 +181,7 @@ Cloud.use('/__engine/1/ping', function(req, res) { next(); }, error: function(user, err) { - next(err) + next(err); } }); } else if (req.body.user) { @@ -210,7 +214,7 @@ Cloud.use('/__engine/1/ping', function(req, res) { var meta = { remoteAddress: req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress, }; - split = req.url.split('/'); + var split = req.url.split('/'); if (split.length == 2) { // cloud function call(split[1], req.body, req.AV.user, meta, function(err, data) { cb(err, data); @@ -237,9 +241,10 @@ Cloud.use('/__engine/1/ping', function(req, res) { } }); - Cloud.use(route, function(err, req, res, next) { + // next 参数即使不使用,也一定要存在,否则 error handler 不生效 + Cloud.use(route, function(err, req, res, next) { // jshint ignore:line respError(res, err); - }) + }); }); }); @@ -268,10 +273,6 @@ var respBare = function(res, data) { return res.end(JSON.stringify(data)); }; -var respOk = function(res) { - resp(res, 'ok'); -}; - var respError = function(res, err) { res.setHeader('Content-Type', 'application/json; charset=UTF-8'); res.statusCode = err.statusCode || 400; @@ -334,12 +335,12 @@ var hookMarks = [ // 如果对象有 hook 标记,则需要明确 set 一次,标记才会保存在 changed 列表 // 这样调用 REST API 时才会将标记一同传到存储服务端 var setHookMark = function (obj) { - for (i in hookMarks) { + for (var i in hookMarks) { if (obj.get(hookMarks[i])) { obj.set(hookMarks[i], obj.get(hookMarks[i])); } } -} +}; var classHook = function(className, hook, object, user, meta, cb) { if (!Cloud.__code[hook + className]) { @@ -349,7 +350,7 @@ var classHook = function(className, hook, object, user, meta, cb) { } var obj = createAVObject(className); obj._finishFetch(object, true); - setHookMark(obj) + setHookMark(obj); try { if (hook.indexOf('__after_') === 0) { // after 的 hook 不需要 response 参数,并且请求默认返回 ok @@ -419,7 +420,7 @@ var onCompleteBigQueryJob = function(data) { } catch (err) { console.warn('Execute onCompleteBigQueryJob failed with error: ' + (err.stack || err)); } -} +}; Cloud.__code = {}; diff --git a/lib/utils.js b/lib/utils.js index c7f8bd4..24d7a33 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,4 @@ +'use strict'; exports.typeOf = function(obj) { var classToType; if (obj === void 0 || obj === null) { diff --git a/test/authorization_test.js b/test/authorization_test.js index 3306fca..6e4ac77 100644 --- a/test/authorization_test.js +++ b/test/authorization_test.js @@ -1,6 +1,6 @@ +'use strict'; var config = require('./config'), - AV = require('..'), - assert = require('assert'); + AV = require('..'); var appId = config.appId; var appKey = config.appKey; diff --git a/test/av-extra_test.js b/test/av-extra_test.js index acc11de..ca421e8 100644 --- a/test/av-extra_test.js +++ b/test/av-extra_test.js @@ -1,4 +1,5 @@ -var should = require('should'), +'use strict'; +var should = require('should'), // jshint ignore:line AV = require('../lib/av-extra'); describe('av-extra', function() { diff --git a/test/function_test.js b/test/function_test.js index 175afaf..332ef1a 100644 --- a/test/function_test.js +++ b/test/function_test.js @@ -1,3 +1,4 @@ +'use strict'; var config = require('./config'), AV = require('..'), should = require('should'), @@ -12,7 +13,6 @@ var masterKey = config.masterKey; AV.initialize(appId, appKey, masterKey); var TestObject = AV.Object.extend('TestObject'); -var ComplexObject = AV.Object.extend('ComplexObject'); AV.Cloud.define('foo', function(request, response) { assert.ok(request.meta.remoteAddress); @@ -76,7 +76,7 @@ AV.Cloud.define('testRun_options_callback', function(request, response) { assert.equal('OK~', data); AV.Cloud.run('choice', {choice: false}, { success: function(data) { - assert.ifError(err); + assert.ifError(data); }, error: function(err) { assert.equal('OMG...', err); @@ -137,7 +137,9 @@ AV.Cloud.onVerified('sms', function(request) { }); AV.Cloud.define('testThrowError', function(request, response) { + /* jshint ignore:start */ noThisMethod(); + /* jshint ignore:end */ response.success(); }); @@ -149,7 +151,7 @@ AV.Cloud.define("userMatching", function(req, res) { success: function(obj) { assert.equal(obj.get('foo'), 'bar'); res.success({reqUser: req.user, currentUser: AV.User.current()}); - }, error: function(err) { + }, error: function() { res.success({reqUser: req.user, currentUser: AV.User.current()}); } }); diff --git a/test/hook_test.js b/test/hook_test.js index d358866..5645029 100644 --- a/test/hook_test.js +++ b/test/hook_test.js @@ -1,6 +1,7 @@ +'use strict'; var config = require('./config'), AV = require('..'), - should = require('should'), + should = require('should'), // jshint ignore:line assert = require('assert'); var appId = config.appId; @@ -38,15 +39,15 @@ AV.Cloud.beforeSave("ErrorObject", function(request, response) { var a = {}; a.noThisMethod(); response.success(); -}) +}); AV.Cloud.afterSave("TestReview", function(request) { assert.equal(request.object.className, 'TestReview'); assert.equal(request.object.id, '5403e36be4b0b77b5746b292'); }); -AV.Cloud.afterSave("TestError", function(request) { - noThisMethod(); +AV.Cloud.afterSave("TestError", function() { + noThisMethod(); // jshint ignore:line }); AV.Cloud.afterUpdate("TestClass", function(request) { @@ -152,7 +153,7 @@ describe('hook', function() { var warnLogs = []; console.warn = function() { warnLogs.push(arguments); - } + }; request(AV.Cloud) .post("/1.1/functions/ErrorObject/beforeSave") .set('X-AVOSCloud-Application-Id', appId) diff --git a/test/webHosting_test.js b/test/webHosting_test.js index c685bfc..c6e0933 100644 --- a/test/webHosting_test.js +++ b/test/webHosting_test.js @@ -1,3 +1,4 @@ +'use strict'; var config = require('./config'), AV = require('..'), assert = require('assert'), @@ -41,13 +42,13 @@ app.post('/testCookieSession', function(req, res) { assert.equal(req.body.username, user.get('username')); assert.equal(AV.User.current(), user); AV.User.logOut(); - assert(!AV.User.current()) + assert(!AV.User.current()); // 登出再登入不会有问题 - return AV.User.logIn(req.body.username, req.body.password) + return AV.User.logIn(req.body.username, req.body.password); }).then(function(user) { assert.equal(AV.User.current(), user); // 在已登录状态,直接用另外一个账户登录 - return AV.User.logIn('zhangsan', 'zhangsan') + return AV.User.logIn('zhangsan', 'zhangsan'); }).then(function(user) { assert.equal('zhangsan', user.get('username')); assert.equal(AV.User.current(), user); @@ -55,7 +56,7 @@ app.post('/testCookieSession', function(req, res) { }, function(err) { assert.ifError(err); }); -}) +}); app.get('/profile', function(req, res) { if (req.AV.user) {