UNPKG

leancloud-storage

Version:
586 lines (516 loc) 18.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise")); var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map")); var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat")); var _ = require('underscore'); var _require = require('./request'), request = _require.request; var _require2 = require('./utils'), ensureArray = _require2.ensureArray, parseDate = _require2.parseDate; var AV = require('./av'); /** * The version change interval for Leaderboard * @enum */ AV.LeaderboardVersionChangeInterval = { NEVER: 'never', DAY: 'day', WEEK: 'week', MONTH: 'month' }; /** * The order of the leaderboard results * @enum */ AV.LeaderboardOrder = { ASCENDING: 'ascending', DESCENDING: 'descending' }; /** * The update strategy for Leaderboard * @enum */ AV.LeaderboardUpdateStrategy = { /** Only keep the best statistic. If the leaderboard is in descending order, the best statistic is the highest one. */ BETTER: 'better', /** Keep the last updated statistic */ LAST: 'last', /** Keep the sum of all updated statistics */ SUM: 'sum' }; /** * @typedef {Object} Ranking * @property {number} rank Starts at 0 * @property {number} value the statistic value of this ranking * @property {AV.User} user The user of this ranking * @property {Statistic[]} [includedStatistics] Other statistics of the user, specified by the `includeStatistic` option of `AV.Leaderboard.getResults()` */ /** * @typedef {Object} LeaderboardArchive * @property {string} statisticName * @property {number} version version of the leaderboard * @property {string} status * @property {string} url URL for the downloadable archive * @property {Date} activatedAt time when this version became active * @property {Date} deactivatedAt time when this version was deactivated by a version incrementing */ /** * @class */ function Statistic(_ref) { var name = _ref.name, value = _ref.value, version = _ref.version; /** * @type {string} */ this.name = name; /** * @type {number} */ this.value = value; /** * @type {number?} */ this.version = version; } var parseStatisticData = function parseStatisticData(statisticData) { var _AV$_decode = AV._decode(statisticData), name = _AV$_decode.statisticName, value = _AV$_decode.statisticValue, version = _AV$_decode.version; return new Statistic({ name: name, value: value, version: version }); }; /** * @class */ AV.Leaderboard = function Leaderboard(statisticName) { /** * @type {string} */ this.statisticName = statisticName; /** * @type {AV.LeaderboardOrder} */ this.order = undefined; /** * @type {AV.LeaderboardUpdateStrategy} */ this.updateStrategy = undefined; /** * @type {AV.LeaderboardVersionChangeInterval} */ this.versionChangeInterval = undefined; /** * @type {number} */ this.version = undefined; /** * @type {Date?} */ this.nextResetAt = undefined; /** * @type {Date?} */ this.createdAt = undefined; }; var Leaderboard = AV.Leaderboard; /** * Create an instance of Leaderboard for the give statistic name. * @param {string} statisticName * @return {AV.Leaderboard} */ AV.Leaderboard.createWithoutData = function (statisticName) { return new Leaderboard(statisticName); }; /** * (masterKey required) Create a new Leaderboard. * @param {Object} options * @param {string} options.statisticName * @param {AV.LeaderboardOrder} options.order * @param {AV.LeaderboardVersionChangeInterval} [options.versionChangeInterval] default to WEEK * @param {AV.LeaderboardUpdateStrategy} [options.updateStrategy] default to BETTER * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ AV.Leaderboard.createLeaderboard = function (_ref2, authOptions) { var statisticName = _ref2.statisticName, order = _ref2.order, versionChangeInterval = _ref2.versionChangeInterval, updateStrategy = _ref2.updateStrategy; return request({ method: 'POST', path: '/leaderboard/leaderboards', data: { statisticName: statisticName, order: order, versionChangeInterval: versionChangeInterval, updateStrategy: updateStrategy }, authOptions: authOptions }).then(function (data) { var leaderboard = new Leaderboard(statisticName); return leaderboard._finishFetch(data); }); }; /** * Get the Leaderboard with the specified statistic name. * @param {string} statisticName * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ AV.Leaderboard.getLeaderboard = function (statisticName, authOptions) { return Leaderboard.createWithoutData(statisticName).fetch(authOptions); }; /** * Get Statistics for the specified user. * @param {AV.User} user The specified AV.User pointer. * @param {Object} [options] * @param {string[]} [options.statisticNames] Specify the statisticNames. If not set, all statistics of the user will be fetched. * @param {AuthOptions} [authOptions] * @return {Promise<Statistic[]>} */ AV.Leaderboard.getStatistics = function (user) { var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, statisticNames = _ref3.statisticNames; var authOptions = arguments.length > 2 ? arguments[2] : undefined; return _promise.default.resolve().then(function () { if (!(user && user.id)) throw new Error('user must be an AV.User'); return request({ method: 'GET', path: "/leaderboard/users/".concat(user.id, "/statistics"), query: { statistics: statisticNames ? ensureArray(statisticNames).join(',') : undefined }, authOptions: authOptions }).then(function (_ref4) { var results = _ref4.results; return (0, _map.default)(results).call(results, parseStatisticData); }); }); }; /** * Update Statistics for the specified user. * @param {AV.User} user The specified AV.User pointer. * @param {Object} statistics A name-value pair representing the statistics to update. * @param {AuthOptions} [options] AuthOptions plus: * @param {boolean} [options.overwrite] Wethere to overwrite these statistics disregarding the updateStrategy of there leaderboards * @return {Promise<Statistic[]>} */ AV.Leaderboard.updateStatistics = function (user, statistics) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return _promise.default.resolve().then(function () { if (!(user && user.id)) throw new Error('user must be an AV.User'); var data = (0, _map.default)(_).call(_, statistics, function (value, key) { return { statisticName: key, statisticValue: value }; }); var overwrite = options.overwrite; return request({ method: 'POST', path: "/leaderboard/users/".concat(user.id, "/statistics"), query: { overwrite: overwrite ? 1 : undefined }, data: data, authOptions: options }).then(function (_ref5) { var results = _ref5.results; return (0, _map.default)(results).call(results, parseStatisticData); }); }); }; /** * Delete Statistics for the specified user. * @param {AV.User} user The specified AV.User pointer. * @param {Object} statistics A name-value pair representing the statistics to delete. * @param {AuthOptions} [options] * @return {Promise<void>} */ AV.Leaderboard.deleteStatistics = function (user, statisticNames, authOptions) { return _promise.default.resolve().then(function () { if (!(user && user.id)) throw new Error('user must be an AV.User'); return request({ method: 'DELETE', path: "/leaderboard/users/".concat(user.id, "/statistics"), query: { statistics: ensureArray(statisticNames).join(',') }, authOptions: authOptions }).then(function () { return undefined; }); }); }; _.extend(Leaderboard.prototype, /** @lends AV.Leaderboard.prototype */ { _finishFetch: function _finishFetch(data) { var _this = this; _.forEach(data, function (value, key) { if (key === 'updatedAt' || key === 'objectId') return; if (key === 'expiredAt') { key = 'nextResetAt'; } if (key === 'createdAt') { value = parseDate(value); } if (value && value.__type === 'Date') { value = parseDate(value.iso); } _this[key] = value; }); return this; }, /** * Fetch data from the srever. * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ fetch: function fetch(authOptions) { var _this2 = this; return request({ method: 'GET', path: "/leaderboard/leaderboards/".concat(this.statisticName), authOptions: authOptions }).then(function (data) { return _this2._finishFetch(data); }); }, /** * Counts the number of users participated in this leaderboard * @param {Object} [options] * @param {number} [options.version] Specify the version of the leaderboard * @param {AuthOptions} [authOptions] * @return {Promise<number>} */ count: function count() { var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, version = _ref6.version; var authOptions = arguments.length > 1 ? arguments[1] : undefined; return request({ method: 'GET', path: "/leaderboard/leaderboards/".concat(this.statisticName, "/ranks"), query: { count: 1, limit: 0, version: version }, authOptions: authOptions }).then(function (_ref7) { var count = _ref7.count; return count; }); }, _getResults: function _getResults(_ref8, authOptions, userId) { var _context; var skip = _ref8.skip, limit = _ref8.limit, selectUserKeys = _ref8.selectUserKeys, includeUserKeys = _ref8.includeUserKeys, includeStatistics = _ref8.includeStatistics, version = _ref8.version; return request({ method: 'GET', path: (0, _concat.default)(_context = "/leaderboard/leaderboards/".concat(this.statisticName, "/ranks")).call(_context, userId ? "/".concat(userId) : ''), query: { skip: skip, limit: limit, selectUserKeys: _.union(ensureArray(selectUserKeys), ensureArray(includeUserKeys)).join(',') || undefined, includeUser: includeUserKeys ? ensureArray(includeUserKeys).join(',') : undefined, includeStatistics: includeStatistics ? ensureArray(includeStatistics).join(',') : undefined, version: version }, authOptions: authOptions }).then(function (_ref9) { var rankings = _ref9.results; return (0, _map.default)(rankings).call(rankings, function (rankingData) { var _AV$_decode2 = AV._decode(rankingData), user = _AV$_decode2.user, value = _AV$_decode2.statisticValue, rank = _AV$_decode2.rank, _AV$_decode2$statisti = _AV$_decode2.statistics, statistics = _AV$_decode2$statisti === void 0 ? [] : _AV$_decode2$statisti; return { user: user, value: value, rank: rank, includedStatistics: (0, _map.default)(statistics).call(statistics, parseStatisticData) }; }); }); }, /** * Retrieve a list of ranked users for this Leaderboard. * @param {Object} [options] * @param {number} [options.skip] The number of results to skip. This is useful for pagination. * @param {number} [options.limit] The limit of the number of results. * @param {string[]} [options.selectUserKeys] Specify keys of the users to include in the Rankings * @param {string[]} [options.includeUserKeys] If the value of a selected user keys is a Pointer, use this options to include its value. * @param {string[]} [options.includeStatistics] Specify other statistics to include in the Rankings * @param {number} [options.version] Specify the version of the leaderboard * @param {AuthOptions} [authOptions] * @return {Promise<Ranking[]>} */ getResults: function getResults() { var _ref10 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, skip = _ref10.skip, limit = _ref10.limit, selectUserKeys = _ref10.selectUserKeys, includeUserKeys = _ref10.includeUserKeys, includeStatistics = _ref10.includeStatistics, version = _ref10.version; var authOptions = arguments.length > 1 ? arguments[1] : undefined; return this._getResults({ skip: skip, limit: limit, selectUserKeys: selectUserKeys, includeUserKeys: includeUserKeys, includeStatistics: includeStatistics, version: version }, authOptions); }, /** * Retrieve a list of ranked users for this Leaderboard, centered on the specified user. * @param {AV.User} user The specified AV.User pointer. * @param {Object} [options] * @param {number} [options.limit] The limit of the number of results. * @param {string[]} [options.selectUserKeys] Specify keys of the users to include in the Rankings * @param {string[]} [options.includeUserKeys] If the value of a selected user keys is a Pointer, use this options to include its value. * @param {string[]} [options.includeStatistics] Specify other statistics to include in the Rankings * @param {number} [options.version] Specify the version of the leaderboard * @param {AuthOptions} [authOptions] * @return {Promise<Ranking[]>} */ getResultsAroundUser: function getResultsAroundUser(user) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var authOptions = arguments.length > 2 ? arguments[2] : undefined; // getResultsAroundUser(options, authOptions) if (user && typeof user.id !== 'string') { return this.getResultsAroundUser(undefined, user, options); } var limit = options.limit, selectUserKeys = options.selectUserKeys, includeUserKeys = options.includeUserKeys, includeStatistics = options.includeStatistics, version = options.version; return this._getResults({ limit: limit, selectUserKeys: selectUserKeys, includeUserKeys: includeUserKeys, includeStatistics: includeStatistics, version: version }, authOptions, user ? user.id : 'self'); }, _update: function _update(data, authOptions) { var _this3 = this; return request({ method: 'PUT', path: "/leaderboard/leaderboards/".concat(this.statisticName), data: data, authOptions: authOptions }).then(function (result) { return _this3._finishFetch(result); }); }, /** * (masterKey required) Update the version change interval of the Leaderboard. * @param {AV.LeaderboardVersionChangeInterval} versionChangeInterval * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ updateVersionChangeInterval: function updateVersionChangeInterval(versionChangeInterval, authOptions) { return this._update({ versionChangeInterval: versionChangeInterval }, authOptions); }, /** * (masterKey required) Update the version change interval of the Leaderboard. * @param {AV.LeaderboardUpdateStrategy} updateStrategy * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ updateUpdateStrategy: function updateUpdateStrategy(updateStrategy, authOptions) { return this._update({ updateStrategy: updateStrategy }, authOptions); }, /** * (masterKey required) Reset the Leaderboard. The version of the Leaderboard will be incremented by 1. * @param {AuthOptions} [authOptions] * @return {Promise<AV.Leaderboard>} */ reset: function reset(authOptions) { var _this4 = this; return request({ method: 'PUT', path: "/leaderboard/leaderboards/".concat(this.statisticName, "/incrementVersion"), authOptions: authOptions }).then(function (data) { return _this4._finishFetch(data); }); }, /** * (masterKey required) Delete the Leaderboard and its all archived versions. * @param {AuthOptions} [authOptions] * @return {void} */ destroy: function destroy(authOptions) { return AV.request({ method: 'DELETE', path: "/leaderboard/leaderboards/".concat(this.statisticName), authOptions: authOptions }).then(function () { return undefined; }); }, /** * (masterKey required) Get archived versions. * @param {Object} [options] * @param {number} [options.skip] The number of results to skip. This is useful for pagination. * @param {number} [options.limit] The limit of the number of results. * @param {AuthOptions} [authOptions] * @return {Promise<LeaderboardArchive[]>} */ getArchives: function getArchives() { var _this5 = this; var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, skip = _ref11.skip, limit = _ref11.limit; var authOptions = arguments.length > 1 ? arguments[1] : undefined; return request({ method: 'GET', path: "/leaderboard/leaderboards/".concat(this.statisticName, "/archives"), query: { skip: skip, limit: limit }, authOptions: authOptions }).then(function (_ref12) { var results = _ref12.results; return (0, _map.default)(results).call(results, function (_ref13) { var version = _ref13.version, status = _ref13.status, url = _ref13.url, activatedAt = _ref13.activatedAt, deactivatedAt = _ref13.deactivatedAt; return { statisticName: _this5.statisticName, version: version, status: status, url: url, activatedAt: parseDate(activatedAt.iso), deactivatedAt: parseDate(deactivatedAt.iso) }; }); }); } });