Giter Site home page Giter Site logo

leanengine-node-sdk's Issues

koa 发起save请求 提示 response: { error: 'Config not found.' }

我想知道这个配置文件是什么 我在函数初始化时候已经传入了必要参数

除了模块依赖之外。
的代码
//init leanCloud
lg.init({
    appId: process.env.LEANCLOUD_APP_ID || 'GcEEi4mef5f6LjXb....省略',
    appKey: process.env.LEANCLOUD_APP_KEY || 'PI2khm4E6....省略',
    masterKey: process.env.LEANCLOUD_APP_MASTER_KEY || '1EXlsv8....省略'
});
lg.Cloud.useMasterKey();

// 声明一个 Todo 类型
var Todo = lg.Object.extend('Todo');
// 新建一个 Todo 对象
var todo = new Todo();
todo.set('title', '工程师周会');
todo.set('content', '每周工程师会议,周一下午2点');
todo.save().then(function(todo) {
    // 成功保存之后,执行其他逻辑.
    console.log('New object created with objectId: ' + todo.id);
}, function(error) {
    // 异常处理
    console.error(error);
});


支持 beforeUpdate

类似 beforeSave,约定保持一致,只是名字换了

@sdjcw

今天凌晨上线。

beforeSave 的 request.object 是将更新作用到当前对象后的临时新对象,它不保证是对象更新后的状态,而只是“当时”的最新状态。

梳理调用 response.error 时指定 code 的逻辑并补充文档

因为 JS SDK 取消了 AV.Error:

AV.Error() is deprecated, and will be removed in next release.

很多用户会疑惑应该如何在 response.error 时指定 code,目前的替代方案是(注意是 message 而不是 error):

response.error({"code":"4444","message":"请先登录!"})

可能需要改进一下这个 API(例如将 code 作为第二个参数)并补充到文档上。

指定 avoscloud-sdk 为 peerDependency

由用户自己安装维护 avoscloud-sdk 的版本,避免出现现在 sdk 会自动升级的问题。

leanengine-sdk 本身不再持有 AV,需要用户初始化传进来:

var AV = require('leanengine')(require('avoscloud-sdk'));

Usage with koa?

koa needs a generator function.So I couldn't make it works like the example:

// cloud.js
var AV = require('leanengine');
AV.Cloud.define('hello', function(request, response) {
  response.success('Hello world!');
});
module.exports = AV.Cloud;
var koa = require("koa");
var cloud = require('./cloud');
var app = koa();
app.use(cloud);

module.exports = app

It throw an error:AssertionError: app.use() requires a generator function.

beforeSave hook导致object内容错误

在数据库中,有beforeSave hook的新创建的User是这样的:

{
  "result": {
    "email": "xxxxxxxx",
    "username": "xxxx",
    "emailVerified": false,
    "__before": 1432921032633,
    "mobilePhoneVerified": false,
    "somecustomattr": "somevalue"
  },
  "ACL": {
    "*": {
      "write": true,
      "read": true
    }
  },
  "objectId": "5568a3c8e4b0a9a97408bfbe",
  "createdAt": "2015-05-30T01:37:12.676Z",
  "updatedAt": "2015-05-30T01:37:12.676Z"
}

回滚LeanEngine SDK 仍然 出现此问题。

回滚到CloudCode 2.0版本,没有 出现此问题。

使用在线定义函数,没有 问题。

猜测是由于beforeSave返回的数据格式不对,不应该带有{"result": data}.

在leanengine/lib/leanengine.js中:

beforeSave hook中将obj返回给callback:

324       Cloud.__code[hook + className]({
325         user: user,
326         object: obj
327       }, {
328         success: function() {
329           if ('__before_delete_for_' === hook) {
330             return cb(null, {});
331           } else {
332             return cb(null, obj);
333           }
334         },
335         error: function(err) {
336           cb(new Error(err));
337         }
338       });

这个callback在此定义:

196       var cb = function(err, data) {
197         if (err) {
198           return respError(res, err);
199         }
200         return resp(res, data);
201       };

resp返回{"result": data},将刚创建的object给返回了

247 var resp = function(res, data) {
248   res.setHeader('Content-Type', 'application/json; charset=UTF-8');
249   res.statusCode = 200;
250   return res.end(JSON.stringify({"result": data}));
251 };

向普通 Express 路由提供 parse authInfo 和 authorization 的支持

有用户希望在普通 Express 路由中使用这两个中间件(

// parse authInfo
Cloud.use(route, function(req, res, next) {
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 !== '') {
req.body = JSON.parse(req.body);
}
appId = req.body._ApplicationId;
appKey = req.body._ApplicationKey;
masterKey = req.body._MasterKey;
prodValue = req.body._ApplicationProduction;
sessionToken = req.body._SessionToken;
for (param in req.body) {
if (param.charAt(0) === '_') {
delete req.body[param];
}
}
prod = 1;
if (prodValue === 0 || prodValue === false) {
prod = 0;
}
req.AV = {
id: appId,
key: appKey,
masterKey: masterKey,
prod: prod,
sessionToken: sessionToken
};
} else {
appId = req.headers['x-lc-id'] ||
req.headers['x-avoscloud-application-id'] ||
req.headers['x-uluru-application-id'];
appKey = req.headers['x-lc-key'] ||
req.headers['x-avoscloud-application-key'] ||
req.headers['x-uluru-application-key'];
masterKey = req.headers['x-avoscloud-master-key'] || req.headers['x-uluru-master-key'];
prodHeader = req.headers['x-lc-prod'] ||
req.headers['x-avoscloud-application-production'] ||
req.headers['x-uluru-application-production'];
sessionToken = req.headers['x-lc-session'] ||
req.headers['x-uluru-session-token'] ||
req.headers['x-avoscloud-session-token'];
prod = 1;
if (prodHeader === '0' || prodHeader === 'false') {
prod = 0;
}
if (appKey && (appKey.indexOf(',master') > 0)) {
masterKey = appKey.slice(0, appKey.indexOf(','));
appKey = null;
}
req.AV = {
id: appId,
key: appKey,
masterKey: masterKey,
prod: prod,
sessionToken: sessionToken
};
}
return next();
});
// authorization
Cloud.use(route, function(req, res, next) {
var key, master, requestSign, sign, timestamp, validSign, _ref;
if (!req.AV.id) {
return unauthResp(res);
}
if (AV.applicationId === req.AV.id &&
(AV.applicationKey === req.AV.key ||
AV.masterKey === req.AV.key ||
AV.masterKey === req.AV.masterKey)) {
if (AV.masterKey === req.AV.masterKey) {
req.AV.authMasterKey = true;
}
return next();
}
requestSign = req.headers['x-lc-sign'] || req.headers['x-avoscloud-request-sign'];
if (requestSign) {
_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()) {
if (master === 'master') {
req.AV.authMasterKey = true;
req.AV.masterKey = key;
} else {
req.AV.key = key;
}
return next();
}
}
return unauthResp(res);
});
),可以考虑将 leanengine.js 中主要的中间件都拆分到单独的文件,以便用户可以自行使用。

Node SDK 2.0 计划

主要是为了在更新 JavaScript SDK 2.0 的时候顺便做一些不兼容的修改,尽量能够在一个月内发布:

  • 更新 JavaScript SDK 2.0(不兼容,小程序相关支持)
  • 移除 AV.Cloud.httpRequest(不兼容)
  • 云函数 Promise 支持、移除 domain、onError(少量不兼容) #90 #67 #96
  • 向 res.saveCurrentUser 传入没有 sessionToken 的用户时需要向用户发出警告(细微不兼容) #80
  • 不正确的云函数名称、重复的云函数抛异常(细微不兼容)

还有一些不太可能引起不兼容的修改,可以做也可以往后放一放:

统计调用存储服务的请求

记录包括:请求次数,响应时间,响应码等信息。

分为 5 秒钟的实时信息和 5 分钟的持久化信息。

leanengine 里 hack 的 avoscloud-sdk 方法实现不一样

https://github.com/leancloud/leanengine-node-sdk/blob/master/lib/leanengine.js#L266

Cloud.run = function(name, data, options) {
  try {
    Cloud.__code[name]({params: data, user: AV.User.current()}, options );
  } catch (err) {
    console.log('Run function \'' + name + '\' failed with error:', err);
    options.error(err);
  }
};

这里返回的是 promise
https://github.com/leancloud/javascript-sdk/blob/master/lib/cloudfunction.js#L28

    run: function(name, data, options) {
      var request = AV._request("functions", name, null, 'POST',
                                   AV._encode(data, null, true));

      return request.then(function(resp) {
        return AV._decode(null, resp).result;
      })._thenRunCallbacks(options);
    },

导致我迁移后的代码都不能用了

高并发跳号问题

leanengine-node-sdk/lib/av-extra.js

AV.User._saveCurrentUser = function(user) {
  debug('_saveCurrentUser %s', user.get('username'));
  if (process.domain) {
    if (process.domain._currentUser === user) {
      return;
    }
    if (process.domain._currentUser) {
      AV.User.logOut();
    }
    if (user) {
      user._isCurrentUser = true;
    }
    process.domain._currentUser = user;
    return;
  }
  throw new Error('请添加 AV.Cloud.CookieSession 中间件以支持 AV.User 的操作。');
};

先设置了_isCurrentUser在高并发情况下会导致串号

AV.User._saveCurrentUser = function(user) {
  debug('_saveCurrentUser %s', user.get('username'));
  if (process.domain) {
    if (process.domain._currentUser === user) {
      return;
    }
    if (process.domain._currentUser) {
      AV.User.logOut();
    }
    if (user) {
      process.domain._currentUser = user;
      user._isCurrentUser = true;
    }  
    return;
  }
  throw new Error('请添加 AV.Cloud.CookieSession 中间件以支持 AV.User 的操作。');
};

云函数提供 Promise 支持

之前曾在 https://github.com/leancloud/cloud-code/issues/756 讨论过,结论是因为 Promise 只能够表示「成功」和「不成功」两种状态,而我们的云函数实际上有「成功」、「失败」、「出现异常」三种情况。

目前云函数会用 domain 捕捉异步的异常,但因为 domian 本身的不确定性,在之后的 Node 版本中不好保证一定有效。@leeyeh 提议支持用 Promise 去表示「出现异常」的情况,即也去捕捉通过 Promise 传递出的异常,保持和同步异常一样的处理方式。

有关实现不依赖 domain 的用户状态管理的几种方案

每次操作都需要传 sessionToken 参数

var Topic = AV.Object.extend('Topic');

AV.Cloud.define('func', function(request, response) {
  var query = new AV.Query(Topic);
  query.find({
    sessionToken: request.user._sessionToken,
    success: function(results) {
      response.success(results);
    }
  })
});

实现简单、容易理解;但用户需要修改现有代码,很容易遗漏某些地方,需要在函数间传递 user.

为每个请求提供一个 AV 实例

AV.Cloud.define('func', function(request, response) {
  var Topic = request.AV.Object.extend('Topic');
  var query = new AV.Query(Topic);
  query.find({
    success: function(results) {
      response.success(results);
    }
  })
});

可以通过改写 AV._request 来实现,用户需要修改一部分代码,也需要在函数间传递 AV.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.