snoowrap
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -15,16 +15,17 @@ 'use strict'; | ||
let default_config = require('./default_config'); | ||
let actions = require('./actions'); | ||
let assign_mixins = require('./assign_mixins'); | ||
let objects = {}; | ||
let helpers = {}; | ||
let snoowrap = class AuthenticatedClient { | ||
constructor(options) { | ||
this.client_id = options.client_id; | ||
this.client_secret = options.client_secret; | ||
this.refresh_token = options.refresh_token; | ||
this.user_agent = options.user_agent; | ||
this.access_token = options.access_token; | ||
this.token_expiration = options.token_expiration; | ||
this.ratelimit_remaining = options.ratelimit_remaining; | ||
this.ratelimit_reset_point = options.ratelimit_reset_point; | ||
let snoowrap = class snoowrap { | ||
constructor(_ref) { | ||
let client_id = _ref.client_id; | ||
let client_secret = _ref.client_secret; | ||
let refresh_token = _ref.refresh_token; | ||
let user_agent = _ref.user_agent; | ||
this.client_id = client_id; | ||
this.client_secret = client_secret; | ||
this.refresh_token = refresh_token; | ||
this.user_agent = user_agent; | ||
this.config = default_config; | ||
@@ -36,2 +37,8 @@ this.throttle = Promise.resolve(); | ||
} | ||
get _base_client_requester() { | ||
return request.defaults({ | ||
auth: { user: this.client_id, pass: this.client_secret }, | ||
headers: { 'user-agent': this.user_agent } | ||
}); | ||
} | ||
_update_access_token() { | ||
@@ -41,6 +48,4 @@ var _this = this; | ||
return _asyncToGenerator(function* () { | ||
let token_info = yield request.post({ | ||
let token_info = yield _this._base_client_requester.post({ | ||
url: `https://www.${ _this.config.endpoint_domain }/api/v1/access_token`, | ||
auth: { user: _this.client_id, pass: _this.client_secret }, | ||
headers: { 'user-agent': _this.user_agent }, | ||
form: { grant_type: 'refresh_token', refresh_token: _this.refresh_token } | ||
@@ -50,3 +55,3 @@ }); | ||
_this.token_expiration = moment().add(token_info.expires_in, 'seconds'); | ||
_this.scopes = token_info.scope.split(' '); | ||
_this.scope = token_info.scope.split(' '); | ||
})(); | ||
@@ -63,3 +68,7 @@ } | ||
this.ratelimit_reset_point = moment().add(response.headers['x-ratelimit-reset'], 'seconds'); | ||
return helpers._populate(body, this); | ||
let populated = helpers._populate(body, this); | ||
if (populated instanceof objects.Listing) { | ||
populated.uri = response.request.uri.path; | ||
} | ||
return populated; | ||
} | ||
@@ -92,3 +101,3 @@ }); | ||
// If the access token has expired (or will expire in the next 10 seconds), refresh it. | ||
if (!_this2.token_expiration || moment(_this2.token_expiration).subtract(10, 'seconds').isBefore()) { | ||
if (!_this2.access_token || !_this2.token_expiration || moment(_this2.token_expiration).subtract(10, 'seconds').isBefore()) { | ||
yield _this2._update_access_token(); | ||
@@ -115,2 +124,18 @@ } | ||
} | ||
_revoke_token(token) { | ||
return this._base_client_requester.post({ | ||
url: `https://www.${ this.config.endpoint_domain }/api/v1/revoke_token`, | ||
form: { token } | ||
}); | ||
} | ||
revoke_access_token() { | ||
return this._revoke_token(this.access_token).then(() => { | ||
this.access_token = undefined; | ||
}); | ||
} | ||
revoke_refresh_token() { | ||
return this._revoke_token(this.refresh_token).then(() => { | ||
this.refresh_token = undefined; | ||
}); | ||
} | ||
inspect() { | ||
@@ -130,3 +155,3 @@ // Hide confidential information (tokens, client IDs, etc.) from the console.log output. | ||
}).value()); | ||
return `<${ constants.MODULE_NAME }.objects.${ this.constructor.name }> ${ formatted }`; | ||
return `<${ constants.MODULE_NAME } authenticated client> ${ formatted }`; | ||
} | ||
@@ -145,26 +170,114 @@ warn() { | ||
get_user(name) { | ||
return new objects.RedditUser({ name }, this); | ||
return new snoowrap.objects.RedditUser({ name }, this); | ||
} | ||
get_comment(comment_id) { | ||
return new objects.Comment({ name: `t1_${ comment_id }` }, this); | ||
return new snoowrap.objects.Comment({ name: `t1_${ comment_id }` }, this); | ||
} | ||
get_subreddit(display_name) { | ||
return new objects.Subreddit({ display_name }, this); | ||
return new snoowrap.objects.Subreddit({ display_name }, this); | ||
} | ||
get_submission(submission_id) { | ||
return new objects.Submission({ name: `t3_${ submission_id }` }, this); | ||
return new snoowrap.objects.Submission({ name: `t3_${ submission_id }` }, this); | ||
} | ||
get_hot() { | ||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
get_karma() { | ||
return this.get({ uri: 'api/v1/me/karma' }); | ||
} | ||
get_preferences() { | ||
return this.get({ uri: 'api/v1/me/prefs' }); | ||
} | ||
update_preferences(updated_preferences) { | ||
// reddit expects all fields to be present in the patch request, so get the current values of the fields | ||
// and then apply the changes. | ||
return this.get_preferences().then(current_prefs => { | ||
return this.patch({ uri: 'api/v1/me/prefs', body: _.assign(current_prefs, updated_preferences) }); | ||
}); | ||
} | ||
get_trophies() { | ||
return this.get({ uri: 'api/v1/me/trophies' }); | ||
} | ||
get_friends() { | ||
return this.get({ uri: 'prefs/friends' }); | ||
} | ||
get_blocked() { | ||
return this.get({ uri: 'prefs/blocked' }); | ||
} | ||
needs_captcha() { | ||
return this.get({ uri: 'api/needs_captcha' }); | ||
} | ||
get_new_captcha_identifier() { | ||
return this.post({ uri: 'api/new_captcha', form: { api_type: 'json' } }).json.data.iden; | ||
} | ||
get_captcha_image(_ref2) { | ||
let identifier = _ref2.identifier; | ||
let subreddit_name = _ref.subreddit_name; | ||
return this.get({ uri: `captcha/${ identifier }` }); | ||
} | ||
get_saved_categories() { | ||
return this.get({ uri: 'api/saved_categories' }); | ||
} | ||
mark_as_visited(links) { | ||
return this.post({ uri: 'api/store_visits', links: links.join(',') }); | ||
} | ||
_submit(_ref3) { | ||
let captcha_response = _ref3.captcha_response; | ||
let captcha_iden = _ref3.captcha_iden; | ||
let kind = _ref3.kind; | ||
var _ref3$resubmit = _ref3.resubmit; | ||
let resubmit = _ref3$resubmit === undefined ? true : _ref3$resubmit; | ||
var _ref3$send_replies = _ref3.send_replies; | ||
let send_replies = _ref3$send_replies === undefined ? true : _ref3$send_replies; | ||
let text = _ref3.text; | ||
let title = _ref3.title; | ||
let url = _ref3.url; | ||
let subreddit_name = _ref3.subreddit_name; | ||
return new objects.Listing({ uri: (subreddit_name ? `r/${ subreddit_name }/` : '') + 'hot' }, this); | ||
return promise_wrap(this.post({ uri: 'api/submit', form: { captcha: captcha_response, iden: captcha_iden, | ||
sendreplies: send_replies, sr: subreddit_name, kind, resubmit, text, title, url } }).then(response => { | ||
return response.json.data.things[0]; | ||
})); | ||
} | ||
submit_selfpost(options) { | ||
return this._submit(_.assign(options, { kind: 'self' })); | ||
} | ||
submit_link(options) { | ||
return this._submit(_.assign(options, { kind: 'link' })); | ||
} | ||
_get_sorted_frontpage(sort_type, subreddit_name) { | ||
let options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | ||
// Handle things properly if only a time parameter is provided but not the subreddit name | ||
if (typeof subreddit_name === 'object' && _(options).omitBy(_.isUndefined).isEmpty()) { | ||
/* In this case, "subreddit_name" ends up referring to the second argument, which is not actually a name since the user | ||
decided to omit that parameter. */ | ||
options = subreddit_name; | ||
subreddit_name = undefined; | ||
} | ||
return this.get({ uri: (subreddit_name ? `r/${ subreddit_name }/` : '') + sort_type, qs: { t: options.time } }); | ||
} | ||
get_hot(subreddit_name) { | ||
return this._get_sorted_frontpage('hot', subreddit_name); | ||
} | ||
get_new(subreddit_name) { | ||
return this._get_sorted_frontpage('new', subreddit_name); | ||
} | ||
get_top(subreddit_name) { | ||
var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
let time = _ref4.time; | ||
return this._get_sorted_frontpage('top', subreddit_name, { time }); | ||
} | ||
get_controversial(subreddit_name) { | ||
var _ref5 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
let time = _ref5.time; | ||
return this._get_sorted_frontpage('controversial', subreddit_name, { time }); | ||
} | ||
}; | ||
_.assign(snoowrap.prototype, actions.self_getters); | ||
objects.RedditContent = class RedditContent { | ||
constructor(options, _ac, has_fetched) { | ||
/* `_ac` stands for `Authenticated Client`; it refers to the snoowrap requester that this object is tied to (which is | ||
also used to make future requests if necessary). */ | ||
this._ac = _ac; | ||
@@ -174,3 +287,5 @@ this.has_fetched = !!has_fetched; | ||
this._initialize_fetch_function(); | ||
constants.REQUEST_TYPES.forEach(type => { | ||
/* Omit the 'delete' request shortcut, since that property name is used by Comments and Submissions. To send an HTTP DELETE | ||
request, use `this._ac.delete` rather than the shortcut `this.delete`. */ | ||
_.without(constants.REQUEST_TYPES, 'delete').forEach(type => { | ||
Object.defineProperty(this, type, { get: () => this._ac[type] }); | ||
@@ -192,7 +307,5 @@ }); | ||
_initialize_fetch_function() { | ||
this.fetch = this.fetch || _.once(() => { | ||
this.fetch = 'fetch' in this ? this.fetch : _.once(() => { | ||
return promise_wrap(this._ac.get({ uri: this._uri }).then(this._transform_api_response.bind(this)).then(response => { | ||
/* The line below is equivalent to _.assign(this, response);, but _.assign ends up triggering warning messages when | ||
used on Proxies, since the patched globals from harmony-reflect aren't applied to lodash. This won't be a problem once | ||
Proxies are correctly implemented natively. https://github.com/tvcutsem/harmony-reflect#dependencies */ | ||
helpers._assign_proxy(this, response); | ||
_.forIn(response, (value, key) => { | ||
@@ -235,5 +348,2 @@ this[key] = value; | ||
} | ||
static get inherited_action_categories() { | ||
return ['reply', 'vote', 'moderate_posts']; | ||
} | ||
}; | ||
@@ -251,4 +361,11 @@ | ||
} | ||
static get inherited_action_categories() { | ||
return []; | ||
give_gold(_ref6) { | ||
let months = _ref6.months; | ||
/* Ideally this would allow for more than 36 months by sending multiple requests, but I wouldn't have the resources to test | ||
that code, and it's probably better that such a big investment be deliberate anyway. */ | ||
if (typeof months !== 'number' || months < 1 || months > 36) { | ||
throw new errors.InvalidMethodCallError('Invalid argument to RedditUser.give_gold; `months` must be between 1 and 36.'); | ||
} | ||
return this.post({ uri: `api/v1/gold/give/${ this.name }` }); | ||
} | ||
@@ -269,5 +386,56 @@ }; | ||
} | ||
static get inherited_action_categories() { | ||
return ['reply', 'vote', 'moderate_posts']; | ||
// TODO: Get rid of the repeated {id: this.name} form parameters | ||
hide() { | ||
return this.post({ uri: 'api/hide', form: { id: this.name } }); | ||
} | ||
unhide() { | ||
return this.post({ uri: 'api/unhide', form: { id: this.name } }); | ||
} | ||
lock() { | ||
return this.post({ uri: 'api/lock', form: { id: this.name } }); | ||
} | ||
unlock() { | ||
return this.post({ uri: 'api/unlock', form: { id: this.name } }); | ||
} | ||
mark_nsfw() { | ||
return this.post({ uri: 'api/marknsfw', form: { id: this.name } }); | ||
} | ||
unmark_nsfw() { | ||
return this.post({ uri: 'api/unmarknsfw', form: { id: this.name } }); | ||
} | ||
set_contest_mode_enabled(state) { | ||
return this.post({ uri: 'api/set_contest_mode', form: { state, id: this.name } }); | ||
} | ||
_set_stickied(_ref7) { | ||
let state = _ref7.state; | ||
let num = _ref7.num; | ||
return this.post({ uri: 'api/set_subreddit_sticky', form: { state, num, id: this.name } }); | ||
} | ||
sticky() { | ||
var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
let num = _ref8.num; | ||
return this._set_stickied({ state: true, num }); | ||
} | ||
unsticky() { | ||
return this._set_stickied({ state: false }); | ||
} | ||
set_suggested_sort(sort) { | ||
if (typeof sort !== 'string') { | ||
throw new errors.InvalidMethodCallError('`sort` must be a string (such as "best" or "new") for set_suggested_sort'); | ||
} | ||
return this.post({ uri: 'api/set_suggested_sort', form: { api_type: 'json', id: this.name, sort } }); | ||
} | ||
mark_as_read() { | ||
// Requires reddit gold | ||
return this.post({ uri: 'api/store_visits', form: { links: this.name } }); | ||
} | ||
get_duplicates() { | ||
return this.get({ uri: `duplicates/${ this.name }` }); | ||
} | ||
get_related() { | ||
return this.get({ uri: `related/${ this.name }` }); | ||
} | ||
}; | ||
@@ -282,5 +450,2 @@ | ||
} | ||
static get inherited_action_categories() { | ||
return ['reply', 'moderate_posts']; | ||
} | ||
}; | ||
@@ -298,5 +463,149 @@ | ||
} | ||
static get inherited_action_categories() { | ||
return ['subreddit_flair']; | ||
_delete_flair_templates(_ref9) { | ||
let flair_type = _ref9.flair_type; | ||
return this.post({ uri: `r/${ this.display_name }/api/clearflairtemplates`, form: { api_type: 'json', flair_type } }); | ||
} | ||
delete_all_user_flair_templates() { | ||
return this._delete_flair_templates({ flair_type: 'USER_FLAIR' }); | ||
} | ||
delete_all_link_flair_templates() { | ||
return this._delete_flair_templates({ flair_type: 'LINK_FLAIR' }); | ||
} | ||
delete_flair_template(_ref10) { | ||
let flair_template_id = _ref10.flair_template_id; | ||
return this.post({ uri: `r/${ this.display_name }/api/deleteflairtemplate`, form: { api_type: 'json', flair_template_id } }); | ||
} | ||
_create_flair_template(_ref11) { | ||
let text = _ref11.text; | ||
let css_class = _ref11.css_class; | ||
let flair_type = _ref11.flair_type; | ||
var _ref11$text_editable = _ref11.text_editable; | ||
let text_editable = _ref11$text_editable === undefined ? false : _ref11$text_editable; | ||
return this.post({ | ||
uri: `r/${ this.display_name }/api/flairtemplate`, | ||
form: { api_type: 'json', text, css_class, flair_type, text_editable } | ||
}); | ||
} | ||
create_user_flair_template(_ref12) { | ||
let text = _ref12.text; | ||
let css_class = _ref12.css_class; | ||
var _ref12$text_editable = _ref12.text_editable; | ||
let text_editable = _ref12$text_editable === undefined ? false : _ref12$text_editable; | ||
return this._create_flair_template({ text, css_class, text_editable, flair_type: 'USER_FLAIR' }); | ||
} | ||
create_link_flair_template(_ref13) { | ||
let text = _ref13.text; | ||
let css_class = _ref13.css_class; | ||
var _ref13$text_editable = _ref13.text_editable; | ||
let text_editable = _ref13$text_editable === undefined ? false : _ref13$text_editable; | ||
return this._create_flair_template({ text, css_class, text_editable, flair_type: 'LINK_FLAIR' }); | ||
} | ||
get_flair_options() { | ||
var _ref14 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
let name = _ref14.name; | ||
let link = _ref14.link; | ||
// TODO: Add shortcuts for this on RedditUser and Submission | ||
return this.post({ uri: `r/${ this.display_name }/api/flairselector`, form: { name, link } }); | ||
} | ||
get_user_flair_templates() { | ||
return this.get_flair_options().choices; | ||
} | ||
set_flair(_ref15) { | ||
let link = _ref15.link; | ||
let name = _ref15.name; | ||
let text = _ref15.text; | ||
let css_class = _ref15.css_class; | ||
return this.post({ | ||
uri: `r/${ this.display_name }/api/flair`, | ||
form: { api_type: 'json', link, name, text: text || '', css_class: css_class || '' } | ||
}); | ||
} | ||
delete_user_flair(_ref16) { | ||
let name = _ref16.name; | ||
return this.post({ uri: `r/${ this.display_name }/api/deleteflair`, form: { api_type: 'json', name } }); | ||
} | ||
get_user_flair(_ref17) { | ||
let name = _ref17.name; | ||
return this.get_flair_options({ name }).current; | ||
} | ||
_set_flair_from_csv(flair_csv) { | ||
return this.post({ uri: `r/${ this.display_name }/api/flaircsv`, form: { flair_csv } }); | ||
} | ||
set_multiple_user_flairs(flair_array) { | ||
// Each entry of flair_array has the properties {name, text, css_class} | ||
let requests = []; | ||
while (flair_array.length > 0) { | ||
// The endpoint only accepts at most 100 lines of csv at a time, so split the array into chunks of 100. | ||
requests.push(this._set_flair_from_csv(flair_array.splice(0, 100).map(item => `${ item.name },${ item.text || '' },${ item.css_class || '' }`).join('\n'))); | ||
} | ||
return promise_wrap(Promise.all(requests)); | ||
} | ||
get_user_flair_list() { | ||
return this.get({ uri: `r/${ this.display_name }/api/flairlist` }).users; | ||
} | ||
configure_flair(_ref18) { | ||
let user_flair_enabled = _ref18.user_flair_enabled; | ||
let user_flair_position = _ref18.user_flair_position; | ||
let user_flair_self_assign_enabled = _ref18.user_flair_self_assign_enabled; | ||
let link_flair_position = _ref18.link_flair_position; | ||
let link_flair_self_assign_enabled = _ref18.link_flair_self_assign_enabled; | ||
return this.post({ | ||
uri: `r/${ this.display_name }/api/flairconfig`, | ||
form: { | ||
api_type: 'json', | ||
flair_enabled: user_flair_enabled, | ||
flair_position: user_flair_position, | ||
flair_self_assign_enabled: user_flair_self_assign_enabled, | ||
link_flair_position, link_flair_self_assign_enabled | ||
} | ||
}); | ||
} | ||
_set_my_flair_visibility(flair_enabled) { | ||
return this.post({ uri: `r/${ this.display_name }/api/setflairenabled`, form: { api_type: 'json', flair_enabled } }); | ||
} | ||
show_my_flair() { | ||
return this._set_my_flair_visibility(true); | ||
} | ||
hide_my_flair() { | ||
return this._set_my_flair_visibility(false); | ||
} | ||
submit_selfpost(options) { | ||
return this._ac.submit_selfpost(_.assign(options, { subreddit_name: this.display_name })); | ||
} | ||
submit_link(options) { | ||
return this._ac.submit_link(_.assign(options, { subreddit_name: this.display_name })); | ||
} | ||
get_hot() { | ||
return this._ac.get_hot(this.display_name); | ||
} | ||
get_new() { | ||
return this._ac.get_new(this.display_name); | ||
} | ||
get_comments() { | ||
return this._ac.get_comments(this.display_name); | ||
} | ||
get_top() { | ||
var _ref19 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
let time = _ref19.time; | ||
return this._ac.get_top(this.display_name, { time }); | ||
} | ||
get_controversial() { | ||
var _ref20 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
let time = _ref20.time; | ||
return this._ac.get_controversial(this.display_name, { time }); | ||
} | ||
}; | ||
@@ -318,22 +627,22 @@ | ||
constructor() { | ||
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var _ref21 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var _ref2$children = _ref2.children; | ||
let children = _ref2$children === undefined ? [] : _ref2$children; | ||
var _ref2$query = _ref2.query; | ||
let query = _ref2$query === undefined ? {} : _ref2$query; | ||
var _ref2$show_all = _ref2.show_all; | ||
let show_all = _ref2$show_all === undefined ? true : _ref2$show_all; | ||
let limit = _ref2.limit; | ||
var _ref2$_transform = _ref2._transform; | ||
var _ref21$children = _ref21.children; | ||
let children = _ref21$children === undefined ? [] : _ref21$children; | ||
var _ref21$query = _ref21.query; | ||
let query = _ref21$query === undefined ? {} : _ref21$query; | ||
var _ref21$show_all = _ref21.show_all; | ||
let show_all = _ref21$show_all === undefined ? true : _ref21$show_all; | ||
let limit = _ref21.limit; | ||
var _ref21$_transform = _ref21._transform; | ||
let _transform = _ref2$_transform === undefined ? _.identity : _ref2$_transform; | ||
let _transform = _ref21$_transform === undefined ? _.identity : _ref21$_transform; | ||
let uri = _ref2.uri; | ||
let method = _ref2.method; | ||
let after = _ref2.after; | ||
let before = _ref2.before; | ||
var _ref2$_is_comment_lis = _ref2._is_comment_list; | ||
let uri = _ref21.uri; | ||
let method = _ref21.method; | ||
let after = _ref21.after; | ||
let before = _ref21.before; | ||
var _ref21$_is_comment_li = _ref21._is_comment_list; | ||
let _is_comment_list = _ref2$_is_comment_lis === undefined ? false : _ref2$_is_comment_lis; | ||
let _is_comment_list = _ref21$_is_comment_li === undefined ? false : _ref21$_is_comment_li; | ||
@@ -346,3 +655,5 @@ let _ac = arguments[1]; | ||
this._ac = _ac; | ||
this._requester = _ac._oauth_requester.defaults({ uri, method, qs: constant_params }); | ||
this.uri = uri; | ||
this.method = method; | ||
this.constant_params = constant_params; | ||
this._transform = _transform; | ||
@@ -355,3 +666,3 @@ this.limit = limit; | ||
if (!isNaN(key) && key >= target.length) { | ||
return promise_wrap(target.fetch({ amount: key - target.length + 1 }).then(_.last)); | ||
return promise_wrap(target.fetch(key - target.length + 1).then(_.last)); | ||
} | ||
@@ -361,2 +672,5 @@ return Reflect.get(target, key, thisArg); | ||
} | ||
get _requester() { | ||
return this._ac._oauth_requester.defaults({ uri: this.uri, method: this.method, qs: this.constant_params }); | ||
} | ||
get is_finished() { | ||
@@ -368,5 +682,4 @@ if (this._is_comment_list) { | ||
} | ||
fetch(_ref3) { | ||
var _ref3$amount = _ref3.amount; | ||
let amount = _ref3$amount === undefined ? this.limit : _ref3$amount; | ||
fetch() { | ||
let amount = arguments.length <= 0 || arguments[0] === undefined ? this.limit : arguments[0]; | ||
@@ -380,10 +693,9 @@ if (typeof amount !== 'number') { | ||
if (this._is_comment_list) { | ||
return promise_wrap(this._fetch_more_comments({ amount })); | ||
return promise_wrap(this._fetch_more_comments(amount)); | ||
} | ||
return promise_wrap(this._fetch_more_regular({ amount })); | ||
return promise_wrap(this._fetch_more_regular(amount)); | ||
} | ||
_fetch_more_regular(_ref4) { | ||
_fetch_more_regular(amount) { | ||
var _this3 = this; | ||
let amount = _ref4.amount; | ||
return _asyncToGenerator(function* () { | ||
@@ -400,3 +712,3 @@ let limit_for_request = Math.min(amount, _this3.limit) || _this3.limit; | ||
_this3.after = response.after; | ||
return _this3.slice(0, amount).concat((yield _this3.fetch({ amount: amount - response.length }))); | ||
return response.slice(0, amount).concat((yield _this3.fetch(amount - response.length))); | ||
})(); | ||
@@ -421,3 +733,3 @@ } | ||
fetch_all() { | ||
return this.fetch({ amount: Infinity }); | ||
return this.fetch(Infinity); | ||
} | ||
@@ -436,7 +748,5 @@ inspect() { | ||
to /api/info. */ | ||
fetch(_ref5) { | ||
fetch(amount) { | ||
var _this5 = this; | ||
var _ref5$amount = _ref5.amount; | ||
let amount = _ref5$amount === undefined ? Infinity : _ref5$amount; | ||
return _asyncToGenerator(function* () { | ||
@@ -454,4 +764,4 @@ if (isNaN(amount)) { | ||
// (This speed-requesting is only possible with comment listings since the entire list of ids is present initially.) | ||
let promise_for_this_batch = _this5._ac.get({ uri: 'api/info', qs: { id: ids_for_this_request.join(',') } }); | ||
let promise_for_remaining_items = _this5.fetch({ amount: amount - ids_for_this_request.length }); | ||
let promise_for_this_batch = _this5.get({ uri: 'api/info', qs: { id: ids_for_this_request.join(',') } }); | ||
let promise_for_remaining_items = _this5.fetch(amount - ids_for_this_request.length); | ||
return _.toArray((yield promise_for_this_batch)).concat((yield promise_for_remaining_items)); | ||
@@ -491,2 +801,3 @@ })(); | ||
_ac.warn(`Unknown type ${ response_tree.kind }. This may be a bug; please report it at ${ constants.ISSUE_REPORT_LINK }.`); | ||
return remainder_of_tree; | ||
} | ||
@@ -496,6 +807,6 @@ let mapFunction = Array.isArray(response_tree) ? _.map : _.mapValues; | ||
// Map {..., author: 'some_username', ...} to {..., author: RedditUser {}, ... } (e.g.) | ||
if (_.includes(constants.USER_KEYS, key)) { | ||
if (_.includes(constants.USER_KEYS, key) && value !== null) { | ||
return new objects.RedditUser({ name: value }, _ac); | ||
} | ||
if (_.includes(constants.SUBREDDIT_KEYS, key)) { | ||
if (_.includes(constants.SUBREDDIT_KEYS, key) && value !== null) { | ||
return new objects.Subreddit({ display_name: value }, _ac); | ||
@@ -508,14 +819,14 @@ } | ||
}; | ||
/* Assign all the action functions to the class prototypes. Actions are split into categories (moderation, voting, etc.), | ||
which are defined in actions.js. Each class should have the inherited_action_categories property, which is a list of strings | ||
corresponding to the action categories which apply to objects of that class. */ | ||
_(objects).forOwn(object_class => { | ||
_(actions).pick(object_class.inherited_action_categories || []).forOwn(action_category => { | ||
_.assign(object_class.prototype, action_category); | ||
helpers._assign_proxy = (proxied_object, values) => { | ||
/* The line below is equivalent to _.assign(this, response);, but _.assign ends up triggering warning messages when | ||
used on Proxies, since the patched globals from harmony-reflect aren't applied to lodash. This won't be a problem once | ||
Proxies are correctly implemented natively. https://github.com/tvcutsem/harmony-reflect#dependencies */ | ||
_.forIn(values, (value, key) => { | ||
proxied_object[key] = value; | ||
}); | ||
}); | ||
}; | ||
snoowrap.objects = objects; | ||
snoowrap.helpers = helpers; | ||
assign_mixins(snoowrap); | ||
module.exports = snoowrap; |
217
LICENSE.md
@@ -1,201 +0,26 @@ | ||
Apache License | ||
Version 2.0, January 2004 | ||
http://www.apache.org/licenses/ | ||
The MIT License (MIT) | ||
===================== | ||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
Copyright © `<year>` `<copyright holders>` | ||
1. Definitions. | ||
Permission is hereby granted, free of charge, to any person | ||
obtaining a copy of this software and associated documentation | ||
files (the “Software”), to deal in the Software without | ||
restriction, including without limitation the rights to use, | ||
copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the | ||
Software is furnished to do so, subject to the following | ||
conditions: | ||
"License" shall mean the terms and conditions for use, reproduction, | ||
and distribution as defined by Sections 1 through 9 of this document. | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
"Licensor" shall mean the copyright owner or entity authorized by | ||
the copyright owner that is granting the License. | ||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
OTHER DEALINGS IN THE SOFTWARE. | ||
"Legal Entity" shall mean the union of the acting entity and all | ||
other entities that control, are controlled by, or are under common | ||
control with that entity. For the purposes of this definition, | ||
"control" means (i) the power, direct or indirect, to cause the | ||
direction or management of such entity, whether by contract or | ||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
outstanding shares, or (iii) beneficial ownership of such entity. | ||
"You" (or "Your") shall mean an individual or Legal Entity | ||
exercising permissions granted by this License. | ||
"Source" form shall mean the preferred form for making modifications, | ||
including but not limited to software source code, documentation | ||
source, and configuration files. | ||
"Object" form shall mean any form resulting from mechanical | ||
transformation or translation of a Source form, including but | ||
not limited to compiled object code, generated documentation, | ||
and conversions to other media types. | ||
"Work" shall mean the work of authorship, whether in Source or | ||
Object form, made available under the License, as indicated by a | ||
copyright notice that is included in or attached to the work | ||
(an example is provided in the Appendix below). | ||
"Derivative Works" shall mean any work, whether in Source or Object | ||
form, that is based on (or derived from) the Work and for which the | ||
editorial revisions, annotations, elaborations, or other modifications | ||
represent, as a whole, an original work of authorship. For the purposes | ||
of this License, Derivative Works shall not include works that remain | ||
separable from, or merely link (or bind by name) to the interfaces of, | ||
the Work and Derivative Works thereof. | ||
"Contribution" shall mean any work of authorship, including | ||
the original version of the Work and any modifications or additions | ||
to that Work or Derivative Works thereof, that is intentionally | ||
submitted to Licensor for inclusion in the Work by the copyright owner | ||
or by an individual or Legal Entity authorized to submit on behalf of | ||
the copyright owner. For the purposes of this definition, "submitted" | ||
means any form of electronic, verbal, or written communication sent | ||
to the Licensor or its representatives, including but not limited to | ||
communication on electronic mailing lists, source code control systems, | ||
and issue tracking systems that are managed by, or on behalf of, the | ||
Licensor for the purpose of discussing and improving the Work, but | ||
excluding communication that is conspicuously marked or otherwise | ||
designated in writing by the copyright owner as "Not a Contribution." | ||
"Contributor" shall mean Licensor and any individual or Legal Entity | ||
on behalf of whom a Contribution has been received by Licensor and | ||
subsequently incorporated within the Work. | ||
2. Grant of Copyright License. Subject to the terms and conditions of | ||
this License, each Contributor hereby grants to You a perpetual, | ||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
copyright license to reproduce, prepare Derivative Works of, | ||
publicly display, publicly perform, sublicense, and distribute the | ||
Work and such Derivative Works in Source or Object form. | ||
3. Grant of Patent License. Subject to the terms and conditions of | ||
this License, each Contributor hereby grants to You a perpetual, | ||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
(except as stated in this section) patent license to make, have made, | ||
use, offer to sell, sell, import, and otherwise transfer the Work, | ||
where such license applies only to those patent claims licensable | ||
by such Contributor that are necessarily infringed by their | ||
Contribution(s) alone or by combination of their Contribution(s) | ||
with the Work to which such Contribution(s) was submitted. If You | ||
institute patent litigation against any entity (including a | ||
cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
or a Contribution incorporated within the Work constitutes direct | ||
or contributory patent infringement, then any patent licenses | ||
granted to You under this License for that Work shall terminate | ||
as of the date such litigation is filed. | ||
4. Redistribution. You may reproduce and distribute copies of the | ||
Work or Derivative Works thereof in any medium, with or without | ||
modifications, and in Source or Object form, provided that You | ||
meet the following conditions: | ||
(a) You must give any other recipients of the Work or | ||
Derivative Works a copy of this License; and | ||
(b) You must cause any modified files to carry prominent notices | ||
stating that You changed the files; and | ||
(c) You must retain, in the Source form of any Derivative Works | ||
that You distribute, all copyright, patent, trademark, and | ||
attribution notices from the Source form of the Work, | ||
excluding those notices that do not pertain to any part of | ||
the Derivative Works; and | ||
(d) If the Work includes a "NOTICE" text file as part of its | ||
distribution, then any Derivative Works that You distribute must | ||
include a readable copy of the attribution notices contained | ||
within such NOTICE file, excluding those notices that do not | ||
pertain to any part of the Derivative Works, in at least one | ||
of the following places: within a NOTICE text file distributed | ||
as part of the Derivative Works; within the Source form or | ||
documentation, if provided along with the Derivative Works; or, | ||
within a display generated by the Derivative Works, if and | ||
wherever such third-party notices normally appear. The contents | ||
of the NOTICE file are for informational purposes only and | ||
do not modify the License. You may add Your own attribution | ||
notices within Derivative Works that You distribute, alongside | ||
or as an addendum to the NOTICE text from the Work, provided | ||
that such additional attribution notices cannot be construed | ||
as modifying the License. | ||
You may add Your own copyright statement to Your modifications and | ||
may provide additional or different license terms and conditions | ||
for use, reproduction, or distribution of Your modifications, or | ||
for any such Derivative Works as a whole, provided Your use, | ||
reproduction, and distribution of the Work otherwise complies with | ||
the conditions stated in this License. | ||
5. Submission of Contributions. Unless You explicitly state otherwise, | ||
any Contribution intentionally submitted for inclusion in the Work | ||
by You to the Licensor shall be under the terms and conditions of | ||
this License, without any additional terms or conditions. | ||
Notwithstanding the above, nothing herein shall supersede or modify | ||
the terms of any separate license agreement you may have executed | ||
with Licensor regarding such Contributions. | ||
6. Trademarks. This License does not grant permission to use the trade | ||
names, trademarks, service marks, or product names of the Licensor, | ||
except as required for reasonable and customary use in describing the | ||
origin of the Work and reproducing the content of the NOTICE file. | ||
7. Disclaimer of Warranty. Unless required by applicable law or | ||
agreed to in writing, Licensor provides the Work (and each | ||
Contributor provides its Contributions) on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
implied, including, without limitation, any warranties or conditions | ||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
PARTICULAR PURPOSE. You are solely responsible for determining the | ||
appropriateness of using or redistributing the Work and assume any | ||
risks associated with Your exercise of permissions under this License. | ||
8. Limitation of Liability. In no event and under no legal theory, | ||
whether in tort (including negligence), contract, or otherwise, | ||
unless required by applicable law (such as deliberate and grossly | ||
negligent acts) or agreed to in writing, shall any Contributor be | ||
liable to You for damages, including any direct, indirect, special, | ||
incidental, or consequential damages of any character arising as a | ||
result of this License or out of the use or inability to use the | ||
Work (including but not limited to damages for loss of goodwill, | ||
work stoppage, computer failure or malfunction, or any and all | ||
other commercial damages or losses), even if such Contributor | ||
has been advised of the possibility of such damages. | ||
9. Accepting Warranty or Additional Liability. While redistributing | ||
the Work or Derivative Works thereof, You may choose to offer, | ||
and charge a fee for, acceptance of support, warranty, indemnity, | ||
or other liability obligations and/or rights consistent with this | ||
License. However, in accepting such obligations, You may act only | ||
on Your own behalf and on Your sole responsibility, not on behalf | ||
of any other Contributor, and only if You agree to indemnify, | ||
defend, and hold each Contributor harmless for any liability | ||
incurred by, or claims asserted against, such Contributor by reason | ||
of your accepting any such warranty or additional liability. | ||
END OF TERMS AND CONDITIONS | ||
APPENDIX: How to apply the Apache License to your work. | ||
To apply the Apache License to your work, attach the following | ||
boilerplate notice, with the fields enclosed by brackets "{}" | ||
replaced with your own identifying information. (Don't include | ||
the brackets!) The text should be enclosed in the appropriate | ||
comment syntax for the file format. We also recommend that a | ||
file or class name and description of purpose be included on the | ||
same "printed page" as the copyright notice for easier | ||
identification within third-party archives. | ||
Copyright {yyyy} {name of copyright owner} | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. |
{ | ||
"name": "snoowrap", | ||
"version": "0.4.0", | ||
"license": "Apache-2.0", | ||
"version": "0.5.0", | ||
"license": "MIT", | ||
"description": "A Node.js wrapper for the reddit API", | ||
@@ -39,3 +39,3 @@ "main": "lib/snoowrap.js", | ||
"harmony-reflect": "^1.4.2", | ||
"lodash": "^4.1.0", | ||
"lodash": "^4.2.0", | ||
"moment": "^2.11.1", | ||
@@ -48,3 +48,3 @@ "promise-chains": "^0.1.3", | ||
"babel-core": "^6.4.5", | ||
"babel-eslint": "^5.0.0-beta8", | ||
"babel-eslint": "^5.0.0-beta9", | ||
"babel-plugin-transform-async-to-generator": "^6.4.6", | ||
@@ -51,0 +51,0 @@ "babel-plugin-transform-es2015-destructuring": "^6.4.0", |
spdx disjunction for an artifact's license information
Licensespdx disjunction for an artifact's license information
Found 1 instance in 1 package
spdx disjunction for an artifact's license information
Licensespdx disjunction for an artifact's license information
Found 1 instance in 1 package
941
46268
Updatedlodash@^4.2.0