From 11c72e66f645abf7d50beaff735c7a62043ab3a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Susa=C3=B1a?= Date: Sat, 27 Jul 2024 22:05:18 -0400 Subject: [PATCH] feat: monetization (#227) * feat: monetization * chore: apply formatting * fix: query list entitlements --- src/api/Routes/applications.ts | 25 ++++++++++++++++++++++++ src/client/base.ts | 2 ++ src/common/index.ts | 1 + src/common/shorters/application.ts | 31 ++++++++++++++++++++++++++++++ src/events/hooks/entitlement.ts | 14 +++++++------- src/structures/Entitlement.ts | 19 ++++++++++++++++++ src/structures/Interaction.ts | 3 +++ 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 src/common/shorters/application.ts create mode 100644 src/structures/Entitlement.ts diff --git a/src/api/Routes/applications.ts b/src/api/Routes/applications.ts index ae982fa..eed01f0 100644 --- a/src/api/Routes/applications.ts +++ b/src/api/Routes/applications.ts @@ -30,6 +30,11 @@ import type { RESTPostAPIApplicationEmojiResult, RESTPatchAPIApplicationEmojiResult, RESTDeleteAPIApplicationEmojiResult, + RESTGetAPIEntitlementsResult, + RESTGetAPIEntitlementsQuery, + RESTPostAPIEntitlementBody, + RESTPostAPIEntitlementResult, + RESTGetAPISKUsResult, } from '../../types'; import type { ProxyRequestMethod } from '../Router'; @@ -118,5 +123,25 @@ export interface ApplicationRoutes { args?: RestArguments, ): Promise; }; + entitlements: { + get( + args?: RestArguments, + ): Promise; + post( + args: RestArguments, + ): Promise; + + ( + id: string, + ): { + delete(args?: RestArguments): Promise; + consume: { + post(args?: RestArguments): Promise; + }; + }; + }; + skus: { + get(args?: RestArguments): Promise; + }; }; } diff --git a/src/client/base.ts b/src/client/base.ts index 2e343c1..2db17a9 100644 --- a/src/client/base.ts +++ b/src/client/base.ts @@ -15,6 +15,7 @@ import type { import { IgnoreCommand, type InferWithPrefix, type MiddlewareContext } from '../commands/applications/shared'; import { CommandHandler } from '../commands/handler'; import { + ApplicationShorter, ChannelShorter, EmojiShorter, GuildShorter, @@ -56,6 +57,7 @@ export class BaseClient { rest!: ApiHandler; cache!: Cache; + applications = new ApplicationShorter(this); users = new UsersShorter(this); channels = new ChannelShorter(this); guilds = new GuildShorter(this); diff --git a/src/common/index.ts b/src/common/index.ts index a034ca5..3fcb53f 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -16,6 +16,7 @@ export * from './shorters/users'; export * from './shorters/threads'; export * from './shorters/webhook'; export * from './shorters/interaction'; +export * from './shorters/application'; // export * from './types/options'; export * from './types/resolvables'; diff --git a/src/common/shorters/application.ts b/src/common/shorters/application.ts new file mode 100644 index 0000000..595e1d4 --- /dev/null +++ b/src/common/shorters/application.ts @@ -0,0 +1,31 @@ +import { Entitlement } from '../../structures/Entitlement'; +import type { APIEntitlement, RESTGetAPIEntitlementsQuery, RESTPostAPIEntitlementBody } from '../../types'; +import { BaseShorter } from './base'; + +export class ApplicationShorter extends BaseShorter { + async listEntitlements(applicationId: string, query?: RESTGetAPIEntitlementsQuery) { + return this.client.proxy + .applications(applicationId) + .entitlements.get({ query }) + .then(et => et.map(e => new Entitlement(this.client, e))); + } + + async consumeEntitlement(applicationId: string, entitlementId: string) { + return this.client.proxy.applications(applicationId).entitlements(entitlementId).consume.post(); + } + + async createTestEntitlement(applicationId: string, body: RESTPostAPIEntitlementBody) { + return this.client.proxy + .applications(applicationId) + .entitlements.post({ body }) + .then(et => new Entitlement(this.client, et as APIEntitlement)); + } + + async deleteTestEntitlement(applicationId: string, entitlementId: string) { + return this.client.proxy.applications(applicationId).entitlements(entitlementId).delete(); + } + + async listSKUs(applicationId: string) { + return this.client.proxy.applications(applicationId).skus.get(); + } +} diff --git a/src/events/hooks/entitlement.ts b/src/events/hooks/entitlement.ts index fc99c81..c4dc88d 100644 --- a/src/events/hooks/entitlement.ts +++ b/src/events/hooks/entitlement.ts @@ -1,15 +1,15 @@ import type { APIEntitlement } from '../../types'; -import { toCamelCase } from '../../common'; import type { UsingClient } from '../../commands'; +import { Entitlement } from '../../structures/Entitlement'; -export const ENTITLEMENT_CREATE = (_: UsingClient, data: APIEntitlement) => { - return toCamelCase(data); +export const ENTITLEMENT_CREATE = (client: UsingClient, data: APIEntitlement) => { + return new Entitlement(client, data); }; -export const ENTITLEMENT_UPDATE = (_: UsingClient, data: APIEntitlement) => { - return toCamelCase(data); +export const ENTITLEMENT_UPDATE = (client: UsingClient, data: APIEntitlement) => { + return new Entitlement(client, data); }; -export const ENTITLEMENT_DELETE = (_: UsingClient, data: APIEntitlement) => { - return toCamelCase(data); +export const ENTITLEMENT_DELETE = (client: UsingClient, data: APIEntitlement) => { + return new Entitlement(client, data); }; diff --git a/src/structures/Entitlement.ts b/src/structures/Entitlement.ts new file mode 100644 index 0000000..bbe32de --- /dev/null +++ b/src/structures/Entitlement.ts @@ -0,0 +1,19 @@ +import type { ObjectToLower } from '../common'; +import type { APIEntitlement } from '../types'; +import { DiscordBase } from './extra/DiscordBase'; + +export interface Entitlement extends ObjectToLower {} + +export class Entitlement extends DiscordBase { + get startsAtTimestamp() { + return this.startsAt ? Date.parse(this.startsAt) : null; + } + + get endsAtTimestamp() { + return this.endsAt ? Date.parse(this.endsAt) : null; + } + + consume() { + return this.client.applications.consumeEntitlement(this.applicationId, this.id); + } +} diff --git a/src/structures/Interaction.ts b/src/structures/Interaction.ts index fc109a6..f56c431 100644 --- a/src/structures/Interaction.ts +++ b/src/structures/Interaction.ts @@ -68,6 +68,7 @@ import { type OptionResolverStructure, } from '../client/transformers'; import { mix } from '../deps/mixer'; +import { Entitlement } from './Entitlement'; export type ReplyInteractionBody = | { type: InteractionResponseType.Modal; data: ModalCreateBodyRequest } @@ -123,6 +124,8 @@ export class BaseInteraction< this.channel = channelFrom(interaction.channel, client); } this.user = this.member?.user ?? Transformers.User(client, interaction.user!); + + this.entitlements = interaction.entitlements.map(e => new Entitlement(this.client, e)); } static transformBodyRequest(