-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add subscriptions * types: fix fetch options types * fix: correct properties in patch method * chore: requested changes Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> * fix: correct export syntax * chore(Entitlement): mark `ends_at` as nullable` * types(FetchSubscriptionOptions): add missing `cache` option * Revert "types(FetchSubscriptionOptions): add missing `cache` option" This reverts commit ba472bd. * chore(Entitlement): mark `startsTimestamp` as nullable * fix: requested changes * docs(SubscriptionManager): correct return type --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
388783d
commit 4cca33d
Showing
11 changed files
with
301 additions
and
6 deletions.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
packages/discord.js/src/client/websocket/handlers/SUBSCRIPTION_CREATE.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
'use strict'; | ||
|
||
const Events = require('../../../util/Events'); | ||
|
||
module.exports = (client, { d: data }) => { | ||
const subscription = client.application.subscriptions._add(data); | ||
|
||
/** | ||
* Emitted whenever a subscription is created. | ||
* @event Client#subscriptionCreate | ||
* @param {Subscription} subscription The subscription that was created | ||
*/ | ||
client.emit(Events.SubscriptionCreate, subscription); | ||
}; |
16 changes: 16 additions & 0 deletions
16
packages/discord.js/src/client/websocket/handlers/SUBSCRIPTION_DELETE.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict'; | ||
|
||
const Events = require('../../../util/Events'); | ||
|
||
module.exports = (client, { d: data }) => { | ||
const subscription = client.application.subscriptions._add(data, false); | ||
|
||
client.application.subscriptions.cache.delete(subscription.id); | ||
|
||
/** | ||
* Emitted whenever a subscription is deleted. | ||
* @event Client#subscriptionDelete | ||
* @param {Subscription} subscription The subscription that was deleted | ||
*/ | ||
client.emit(Events.SubscriptionDelete, subscription); | ||
}; |
16 changes: 16 additions & 0 deletions
16
packages/discord.js/src/client/websocket/handlers/SUBSCRIPTION_UPDATE.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict'; | ||
|
||
const Events = require('../../../util/Events'); | ||
|
||
module.exports = (client, { d: data }) => { | ||
const oldSubscription = client.application.subscriptions.cache.get(data.id)?._clone() ?? null; | ||
const newSubscription = client.application.subscriptions._add(data); | ||
|
||
/** | ||
* Emitted whenever a subscription is updated - i.e. when a user's subscription renews. | ||
* @event Client#subscriptionUpdate | ||
* @param {?Subscription} oldSubscription The subscription before the update | ||
* @param {Subscription} newSubscription The subscription after the update | ||
*/ | ||
client.emit(Events.SubscriptionUpdate, oldSubscription, newSubscription); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use strict'; | ||
|
||
const { Collection } = require('@discordjs/collection'); | ||
const { makeURLSearchParams } = require('@discordjs/rest'); | ||
const { Routes } = require('discord-api-types/v10'); | ||
const CachedManager = require('./CachedManager'); | ||
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index'); | ||
const { Subscription } = require('../structures/Subscription'); | ||
const { resolveSKUId } = require('../util/Util'); | ||
|
||
/** | ||
* Manages API methods for subscriptions and stores their cache. | ||
* @extends {CachedManager} | ||
*/ | ||
class SubscriptionManager extends CachedManager { | ||
constructor(client, iterable) { | ||
super(client, Subscription, iterable); | ||
} | ||
|
||
/** | ||
* The cache of this manager | ||
* @type {Collection<Snowflake, Subscription>} | ||
* @name SubscriptionManager#cache | ||
*/ | ||
|
||
/** | ||
* Options used to fetch a subscription | ||
* @typedef {BaseFetchOptions} FetchSubscriptionOptions | ||
* @property {SKUResolvable} sku The SKU to fetch the subscription for | ||
* @property {Snowflake} subscriptionId The id of the subscription to fetch | ||
*/ | ||
|
||
/** | ||
* Options used to fetch subscriptions | ||
* @typedef {Object} FetchSubscriptionsOptions | ||
* @property {Snowflake} [after] Consider only subscriptions after this subscription id | ||
* @property {Snowflake} [before] Consider only subscriptions before this subscription id | ||
* @property {number} [limit] The maximum number of subscriptions to fetch | ||
* @property {SKUResolvable} sku The SKU to fetch subscriptions for | ||
* @property {UserResolvable} user The user to fetch entitlements for | ||
* <warn>If both `before` and `after` are provided, only `before` is respected</warn> | ||
*/ | ||
|
||
/** | ||
* Fetches subscriptions for this application | ||
* @param {FetchSubscriptionOptions|FetchSubscriptionsOptions} [options={}] Options for fetching the subscriptions | ||
* @returns {Promise<Subscription|Collection<Snowflake, Subscription>>} | ||
*/ | ||
async fetch(options = {}) { | ||
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); | ||
|
||
const { after, before, cache, limit, sku, subscriptionId, user } = options; | ||
|
||
const skuId = resolveSKUId(sku); | ||
|
||
if (!skuId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable'); | ||
|
||
if (subscriptionId) { | ||
const subscription = await this.client.rest.get(Routes.skuSubscription(skuId, subscriptionId)); | ||
|
||
return this._add(subscription, cache); | ||
} | ||
|
||
const query = makeURLSearchParams({ | ||
limit, | ||
user_id: this.client.users.resolveId(user) ?? undefined, | ||
sku_id: skuId, | ||
before, | ||
after, | ||
}); | ||
|
||
const subscriptions = await this.client.rest.get(Routes.skuSubscriptions(skuId), { query }); | ||
|
||
return subscriptions.reduce( | ||
(coll, subscription) => coll.set(subscription.id, this._add(subscription, cache)), | ||
new Collection(), | ||
); | ||
} | ||
} | ||
|
||
exports.SubscriptionManager = SubscriptionManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
'use strict'; | ||
|
||
const Base = require('./Base'); | ||
|
||
/** | ||
* Represents a Subscription | ||
* @extends {Base} | ||
*/ | ||
class Subscription extends Base { | ||
constructor(client, data) { | ||
super(client); | ||
|
||
/** | ||
* The id of the subscription | ||
* @type {Snowflake} | ||
*/ | ||
this.id = data.id; | ||
|
||
/** | ||
* The id of the user who subscribed | ||
* @type {Snowflake} | ||
*/ | ||
this.userId = data.user_id; | ||
|
||
this._patch(data); | ||
} | ||
|
||
_patch(data) { | ||
/** | ||
* The SKU ids subscribed to | ||
* @type {Snowflake[]} | ||
*/ | ||
this.skuIds = data.sku_ids; | ||
|
||
/** | ||
* The entitlement ids granted for this subscription | ||
* @type {Snowflake[]} | ||
*/ | ||
this.entitlementIds = data.entitlement_ids; | ||
|
||
/** | ||
* The timestamp the current subscription period will start at | ||
* @type {number} | ||
*/ | ||
this.currentPeriodStartTimestamp = Date.parse(data.current_period_start); | ||
|
||
/** | ||
* The timestamp the current subscription period will end at | ||
* @type {number} | ||
*/ | ||
this.currentPeriodEndTimestamp = Date.parse(data.current_period_end); | ||
|
||
/** | ||
* The current status of the subscription | ||
* @type {SubscriptionStatus} | ||
*/ | ||
this.status = data.status; | ||
|
||
if ('canceled_at' in data) { | ||
/** | ||
* The timestamp of when the subscription was canceled | ||
* @type {?number} | ||
*/ | ||
this.canceledTimestamp = data.canceled_at ? Date.parse(data.canceled_at) : null; | ||
} else { | ||
this.canceledTimestamp ??= null; | ||
} | ||
|
||
if ('country' in data) { | ||
/** | ||
* ISO 3166-1 alpha-2 country code of the payment source used to purchase the subscription. | ||
* Missing unless queried with a private OAuth scope. | ||
* @type {?string} | ||
*/ | ||
this.country = data.country; | ||
} else { | ||
this.country ??= null; | ||
} | ||
} | ||
|
||
/** | ||
* The time the subscription was canceled | ||
* @type {?Date} | ||
* @readonly | ||
*/ | ||
get canceledAt() { | ||
return this.canceledTimestamp && new Date(this.canceledTimestamp); | ||
} | ||
|
||
/** | ||
* The time the current subscription period will start at | ||
* @type {Date} | ||
* @readonly | ||
*/ | ||
get currentPeriodStartAt() { | ||
return new Date(this.currentPeriodStartTimestamp); | ||
} | ||
|
||
/** | ||
* The time the current subscription period will end at | ||
* @type {Date} | ||
* @readonly | ||
*/ | ||
get currentPeriodEndAt() { | ||
return new Date(this.currentPeriodEndTimestamp); | ||
} | ||
} | ||
|
||
exports.Subscription = Subscription; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.