deploy built in support

This commit is contained in:
DjDeveloperr 2021-03-30 15:21:29 +05:30
parent 62b2aa07de
commit 768fec7195
3 changed files with 166 additions and 69 deletions

87
deploy.ts Normal file
View File

@ -0,0 +1,87 @@
import {
SlashCommandsManager,
SlashClient,
SlashCommandHandlerCallback
} from './src/models/slashClient.ts'
import { InteractionResponseType, InteractionType } from './src/types/slash.ts'
export interface DeploySlashInitOptions {
env?: boolean
publicKey?: string
token?: string
id?: string
}
let client: SlashClient
let commands: SlashCommandsManager
export function init(options: DeploySlashInitOptions): void {
if (client !== undefined) throw new Error('Already initialized')
if (options.env === true) {
options.publicKey = Deno.env.get('PUBLIC_KEY')
options.token = Deno.env.get('TOKEN')
options.id = Deno.env.get('ID')
}
if (options.publicKey === undefined)
throw new Error('Public Key not provided')
client = new SlashClient({
id: options.id,
token: options.token,
publicKey: options.publicKey
})
commands = client.commands
const cb = async (evt: {
respondWith: CallableFunction
request: Request
}): Promise<void> => {
try {
const d = await client.verifyFetchEvent(evt)
if (d === false) {
await evt.respondWith(
new Response(null, {
status: 400
})
)
return
}
if (d.type === InteractionType.PING) {
await d.respond({ type: InteractionResponseType.PONG })
return
}
await (client as any)._process(d)
} catch (e) {
await client.emit('interactionError', e)
}
}
addEventListener('fetch', cb as any)
}
export function handle(
cmd:
| string
| {
name: string
parent?: string
group?: string
guild?: string
},
handler: SlashCommandHandlerCallback
): void {
client.handle({
name: typeof cmd === 'string' ? cmd : cmd.name,
handler,
...(typeof cmd === 'string' ? {} : cmd)
})
}
export { commands, client }
export * from './src/types/slash.ts'
export * from './src/structures/slash.ts'
export * from './src/models/slashClient.ts'

View File

@ -13,7 +13,6 @@ import { ActivityGame, ClientActivity } from '../types/presence.ts'
import { Extension } from './extensions.ts'
import { SlashClient } from './slashClient.ts'
import { Interaction } from '../structures/slash.ts'
import { SlashModule } from './slashModule.ts'
import { ShardManager } from './shard.ts'
import { Application } from '../structures/application.ts'
import { Invite } from '../structures/invite.ts'
@ -190,10 +189,10 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
this.clientProperties =
options.clientProperties === undefined
? {
os: Deno.build.os,
browser: 'harmony',
device: 'harmony'
}
os: Deno.build.os,
browser: 'harmony',
device: 'harmony'
}
: options.clientProperties
if (options.shard !== undefined) this.shard = options.shard
@ -208,7 +207,7 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
this.token = token
this.debug('Info', 'Found token in ENV')
}
} catch (e) {}
} catch (e) { }
}
const restOptions: RESTOptions = {
@ -436,59 +435,3 @@ export function event(name?: keyof ClientEvents) {
client._decoratedEvents[key] = listener
}
}
/** Decorator to create a Slash Command handler */
export function slash(name?: string, guild?: string) {
return function (client: Client | SlashClient | SlashModule, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@slash decorator requires a function')
} else
client._decoratedSlash.push({
name: name ?? prop,
guild,
handler: item
})
}
}
/** Decorator to create a Sub-Slash Command handler */
export function subslash(parent: string, name?: string, guild?: string) {
return function (client: Client | SlashModule | SlashClient, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@subslash decorator requires a function')
} else
client._decoratedSlash.push({
parent,
name: name ?? prop,
guild,
handler: item
})
}
}
/** Decorator to create a Grouped Slash Command handler */
export function groupslash(
parent: string,
group: string,
name?: string,
guild?: string
) {
return function (client: Client | SlashModule | SlashClient, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@groupslash decorator requires a function')
} else
client._decoratedSlash.push({
group,
parent,
name: name ?? prop,
guild,
handler: item
})
}
}

View File

@ -1,4 +1,4 @@
import { Guild } from '../structures/guild.ts'
import type { Guild } from '../structures/guild.ts'
import {
Interaction,
InteractionApplicationCommandResolved
@ -14,11 +14,12 @@ import {
SlashCommandPayload
} from '../types/slash.ts'
import { Collection } from '../utils/collection.ts'
import { Client } from './client.ts'
import type { Client } from './client.ts'
import { RESTManager } from './rest.ts'
import { SlashModule } from './slashModule.ts'
import { verify as edverify } from 'https://deno.land/x/ed25519@1.0.1/mod.ts'
import { User } from '../structures/user.ts'
import { HarmonyEventEmitter } from "../utils/events.ts"
export class SlashCommand {
slash: SlashCommandsManager
@ -380,8 +381,14 @@ export interface SlashOptions {
const encoder = new TextEncoder()
const decoder = new TextDecoder('utf-8')
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type SlashClientEvents = {
interaction: [Interaction]
interactionError: [Error]
}
/** Slash Client represents an Interactions Client which can be used without Harmony Client. */
export class SlashClient {
export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
id: string | (() => string)
client?: Client
token?: string
@ -401,6 +408,7 @@ export class SlashClient {
}>
constructor(options: SlashOptions) {
super()
let id = options.id
if (options.token !== undefined) id = atob(options.token?.split('.')[0])
if (id === undefined)
@ -435,8 +443,8 @@ export class SlashClient {
: options.rest
: options.client.rest
this.client?.on('interactionCreate', (interaction) =>
this._process(interaction)
this.client?.on('interactionCreate', async (interaction) =>
await this._process(interaction)
)
this.commands = new SlashCommandsManager(this)
@ -506,7 +514,7 @@ export class SlashClient {
}
/** Process an incoming Interaction */
private _process(interaction: Interaction): void {
private async _process(interaction: Interaction): Promise<void> {
if (!this.enabled) return
if (
@ -523,7 +531,10 @@ export class SlashClient {
if (cmd === undefined) return
cmd.handler(interaction)
await this.emit('interaction', interaction)
try { await cmd.handler(interaction) } catch (e) {
await this.emit('interactionError', e)
}
}
/** Verify HTTP based Interaction */
@ -672,3 +683,59 @@ export class SlashClient {
return true
}
}
/** Decorator to create a Slash Command handler */
export function slash(name?: string, guild?: string) {
return function (client: Client | SlashClient | SlashModule, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@slash decorator requires a function')
} else
client._decoratedSlash.push({
name: name ?? prop,
guild,
handler: item
})
}
}
/** Decorator to create a Sub-Slash Command handler */
export function subslash(parent: string, name?: string, guild?: string) {
return function (client: Client | SlashModule | SlashClient, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@subslash decorator requires a function')
} else
client._decoratedSlash.push({
parent,
name: name ?? prop,
guild,
handler: item
})
}
}
/** Decorator to create a Grouped Slash Command handler */
export function groupslash(
parent: string,
group: string,
name?: string,
guild?: string
) {
return function (client: Client | SlashModule | SlashClient, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = []
const item = (client as { [name: string]: any })[prop]
if (typeof item !== 'function') {
throw new Error('@groupslash decorator requires a function')
} else
client._decoratedSlash.push({
group,
parent,
name: name ?? prop,
guild,
handler: item
})
}
}