From e16bd42092e2c3134bf4a937505a2af86f2df718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Susa=C3=B1a?= Date: Thu, 29 Aug 2024 20:34:40 -0400 Subject: [PATCH] feat: subscriptions (#257) --- src/api/Routes/applications.ts | 1 - src/api/Routes/skus.ts | 18 +++++++++++++++ src/events/hooks/subscriptions.ts | 15 +++++++++++++ src/types/gateway.ts | 35 +++++++++++++++++++++++++++++- src/types/payloads/monetization.ts | 32 ++++++++++++++++++++++++++- src/types/rest/monetization.ts | 26 +++++++++++++++++++++- src/websocket/SharedTypes.ts | 18 ++++++++++----- 7 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 src/api/Routes/skus.ts create mode 100644 src/events/hooks/subscriptions.ts diff --git a/src/api/Routes/applications.ts b/src/api/Routes/applications.ts index eed01f0..ee15c01 100644 --- a/src/api/Routes/applications.ts +++ b/src/api/Routes/applications.ts @@ -57,7 +57,6 @@ export interface ApplicationRoutes { get( args?: RestArguments, ): Promise; - // put(args?: RestArguments): Promise }; ( id: string, diff --git a/src/api/Routes/skus.ts b/src/api/Routes/skus.ts new file mode 100644 index 0000000..088b5b1 --- /dev/null +++ b/src/api/Routes/skus.ts @@ -0,0 +1,18 @@ +import type { + RESTGetAPISKUSubscriptionsResult, + RESTGetAPISKUSubscriptionsQuery, + RESTGetAPISKUSubscriptionResult, +} from '../../types'; +import type { RestArguments } from '../api'; +import type { ProxyRequestMethod } from '../Router'; + +export interface SKuRoutes { + skus(id: string): { + get: ( + args?: RestArguments, + ) => Promise; + subscriptions(id: string): { + get: (args?: RestArguments) => Promise; + }; + }; +} diff --git a/src/events/hooks/subscriptions.ts b/src/events/hooks/subscriptions.ts new file mode 100644 index 0000000..3e47ce5 --- /dev/null +++ b/src/events/hooks/subscriptions.ts @@ -0,0 +1,15 @@ +import type { UsingClient } from '../../commands'; +import { toCamelCase } from '../../common'; +import type { APISubscription } from '../../types'; + +export const SUBSCRIPTION_CREATE = (_: UsingClient, data: APISubscription) => { + return toCamelCase(data); +}; + +export const SUBSCRIPTION_UPDATE = (_: UsingClient, data: APISubscription) => { + return toCamelCase(data); +}; + +export const SUBSCRIPTION_DELETE = (_: UsingClient, data: APISubscription) => { + return toCamelCase(data); +}; diff --git a/src/types/gateway.ts b/src/types/gateway.ts index e92888b..89f70db 100644 --- a/src/types/gateway.ts +++ b/src/types/gateway.ts @@ -33,6 +33,7 @@ import type { APIAuditLogEntry, APIEntitlement, APIPartialEmoji, + APISubscription, } from './payloads/index'; import type { ReactionType } from './rest/index'; import type { AnimationTypes, Nullable } from './utils'; @@ -479,7 +480,9 @@ export type GatewayEntitlementModifyDispatch = DataPayload< /** * https://discord.com/developers/docs/topics/gateway-events#entitlement-create */ -export type GatewayEntitlementCreateDispatchData = GatewayEntitlementModifyDispatchData; +export type GatewayEntitlementCreateDispatchData = Omit & { + ends_at: null; +}; /** * https://discord.com/developers/docs/topics/gateway-events#entitlement-create @@ -1338,6 +1341,36 @@ export type GatewayStageInstanceUpdateDispatch = DataPayload< */ export type GatewayStageInstanceUpdateDispatchData = APIStageInstance; +/** + * https://canary.discord.com/developers/docs/topics/gateway-events#subscription-create + */ +export type GatewaySubscriptionCreateDispatch = DataPayload< + GatewayDispatchEvents.SubscriptionCreate, + GatewaySubscriptionCreateDispatchData +>; + +export type GatewaySubscriptionCreateDispatchData = APISubscription; + +/** + * https://canary.discord.com/developers/docs/topics/gateway-events#subscription-update + */ +export type GatewaySubscriptionUpdateDispatch = DataPayload< + GatewayDispatchEvents.SubscriptionUpdate, + GatewaySubscriptionUpdateDispatchData +>; + +export type GatewaySubscriptionUpdateDispatchData = APISubscription; + +/** + * https://canary.discord.com/developers/docs/topics/gateway-events#subscription-delete + */ +export type GatewaySubscriptionDeleteDispatch = DataPayload< + GatewayDispatchEvents.SubscriptionDelete, + GatewaySubscriptionDeleteDispatchData +>; + +export type GatewaySubscriptionDeleteDispatchData = APISubscription; + /** * https://discord.com/developers/docs/topics/gateway-events#thread-list-sync */ diff --git a/src/types/payloads/monetization.ts b/src/types/payloads/monetization.ts index a8026e2..a08e433 100644 --- a/src/types/payloads/monetization.ts +++ b/src/types/payloads/monetization.ts @@ -39,7 +39,7 @@ export interface APIEntitlement { /** * Date at which the entitlement is no longer valid. Not present when using test entitlements. */ - ends_at?: string; + ends_at?: string | null; /** * For consumable items, whether or not the entitlement has been consumed */ @@ -153,3 +153,33 @@ export enum SKUType { */ SubscriptionGroup = 6, } + +export interface APISubscription { + /** ID of the subscription */ + id: string; + /** ID of the user who is subscribed */ + user_id: string; + /** List of SKUs subscribed to */ + sku_ids: string[]; + /** List of entitlements granted for this subscription */ + entitlements_ids: string[]; + /** Start of the current subscription period */ + current_period_start: string; + /** End of the current subscription period */ + current_period_end: string; + /** Current status of the subscription */ + status: SubscriptionStatus; + /** When the subscription was canceled */ + canceled_at: string | null; + /** ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope. */ + country?: string; +} + +export enum SubscriptionStatus { + /** Subscription is active and scheduled to renew. */ + Active, + /** Subscription is active but will not renew. */ + Ending, + /** Subscription is inactive and not being charged. */ + Inactive, +} diff --git a/src/types/rest/monetization.ts b/src/types/rest/monetization.ts index 61de952..e6646fe 100644 --- a/src/types/rest/monetization.ts +++ b/src/types/rest/monetization.ts @@ -1,5 +1,5 @@ import type { Snowflake } from '..'; -import type { APIEntitlement, APISKU } from '../payloads'; +import type { APIEntitlement, APISKU, APISubscription } from '../payloads'; /** * https://discord.com/developers/docs/monetization/entitlements#list-entitlements @@ -88,3 +88,27 @@ export type RESTGetAPISKUsResult = APISKU[]; * https://discord.com/developers/docs/monetization/entitlements#consume-an-entitlement */ export type RESTPostAPIEntitlementConsumeResult = never; + +/** + * https://canary.discord.com/developers/docs/resources/subscription#query-string-params + */ +export interface RESTGetAPISKUSubscriptionsQuery { + /** List subscriptions before this ID */ + before?: string; + /** List subscriptions after this ID */ + after?: string; + /** Number of results to return (1-100) */ + limit?: number; + /** User ID for which to return subscriptions. Required except for OAuth queries. */ + user_id?: string; +} + +/** + * https://canary.discord.com/developers/docs/resources/subscription#list-sku-subscriptions + */ +export type RESTGetAPISKUSubscriptionsResult = APISubscription[]; + +/** + * https://canary.discord.com/developers/docs/resources/subscription#get-sku-subscription + */ +export type RESTGetAPISKUSubscriptionResult = APISubscription; diff --git a/src/websocket/SharedTypes.ts b/src/websocket/SharedTypes.ts index fa76d20..4f44501 100644 --- a/src/websocket/SharedTypes.ts +++ b/src/websocket/SharedTypes.ts @@ -59,6 +59,8 @@ import type { APIAutoModerationRule, APIEntitlement, GatewayVoiceChannelEffectSendDispachData, + APISubscription, + GatewayEntitlementCreateDispatchData, } from '../types'; import { GatewayDispatchEvents } from '../types'; @@ -147,6 +149,7 @@ export interface Events { [GatewayDispatchEvents.VoiceServerUpdate]: GatewayVoiceServerUpdateDispatchData; [GatewayDispatchEvents.WebhooksUpdate]: GatewayWebhooksUpdateDispatchData; [GatewayDispatchEvents.InteractionCreate]: GatewayInteractionCreateDispatchData; + [GatewayDispatchEvents.EntitlementCreate]: GatewayEntitlementCreateDispatchData; } export type StageSameEvents = RestToKeys< @@ -210,11 +213,15 @@ export type AutoModetaractionRuleEvents = RestToKeys< >; export type EntitlementEvents = RestToKeys< + [APIEntitlement, GatewayDispatchEvents.EntitlementDelete, GatewayDispatchEvents.EntitlementUpdate] +>; + +export type SubscriptionEvents = RestToKeys< [ - APIEntitlement, - GatewayDispatchEvents.EntitlementCreate, - GatewayDispatchEvents.EntitlementDelete, - GatewayDispatchEvents.EntitlementUpdate, + APISubscription, + GatewayDispatchEvents.SubscriptionCreate, + GatewayDispatchEvents.SubscriptionDelete, + GatewayDispatchEvents.SubscriptionUpdate, ] >; @@ -226,6 +233,7 @@ export type NormalizeEvents = Events & IntegrationSameEvents & EntitlementEvents & PollVoteSameEvents & - StageSameEvents & { RAW: GatewayDispatchEvents }; + StageSameEvents & + SubscriptionEvents & { RAW: GatewayDispatchEvents }; export type GatewayEvents = { [x in keyof NormalizeEvents]: NormalizeEvents[x] };