x
This commit is contained in:
parent
fee3e0cfa0
commit
e8371408e2
10 changed files with 250 additions and 49 deletions
|
@ -38,7 +38,7 @@ export interface ClientOptions {
|
|||
/** Token of the Bot/User */
|
||||
token?: string
|
||||
/** Gateway Intents */
|
||||
intents?: GatewayIntents[]
|
||||
intents?: Array<GatewayIntents | keyof typeof GatewayIntents>
|
||||
/** Cache Adapter to use, defaults to Collections one */
|
||||
cache?: ICacheAdapter
|
||||
/** Force New Session and don't use cached Session (by persistent caching) */
|
||||
|
@ -77,10 +77,29 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
|||
rest: RESTManager
|
||||
/** User which Client logs in to, undefined until logs in */
|
||||
user?: User
|
||||
|
||||
#token?: string
|
||||
|
||||
/** Token of the Bot/User */
|
||||
token?: string
|
||||
get token(): string | undefined {
|
||||
return this.#token
|
||||
}
|
||||
|
||||
set token(val: string | undefined) {
|
||||
this.#token = val
|
||||
}
|
||||
|
||||
/** Cache Adapter */
|
||||
cache: ICacheAdapter = new DefaultCacheAdapter()
|
||||
get cache(): ICacheAdapter {
|
||||
return this.#cache
|
||||
}
|
||||
|
||||
set cache(val: ICacheAdapter) {
|
||||
this.#cache = val
|
||||
}
|
||||
|
||||
#cache: ICacheAdapter = new DefaultCacheAdapter()
|
||||
|
||||
/** Gateway Intents */
|
||||
intents?: GatewayIntents[]
|
||||
/** Whether to force new session or not */
|
||||
|
@ -91,21 +110,23 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
|||
reactionCacheLifetime: number = 3600000
|
||||
/** Whether to fetch Uncached Message of Reaction or not? */
|
||||
fetchUncachedReactions: boolean = false
|
||||
|
||||
/** Client Properties */
|
||||
clientProperties: ClientProperties
|
||||
readonly clientProperties!: ClientProperties
|
||||
|
||||
/** Slash-Commands Management client */
|
||||
slash: SlashClient
|
||||
/** Whether to fetch Gateway info or not */
|
||||
fetchGatewayInfo: boolean = true
|
||||
|
||||
/** Users Manager, containing all Users cached */
|
||||
users: UsersManager = new UsersManager(this)
|
||||
readonly users: UsersManager = new UsersManager(this)
|
||||
/** Guilds Manager, providing cache & API interface to Guilds */
|
||||
guilds: GuildManager = new GuildManager(this)
|
||||
readonly guilds: GuildManager = new GuildManager(this)
|
||||
/** Channels Manager, providing cache interface to Channels */
|
||||
channels: ChannelsManager = new ChannelsManager(this)
|
||||
readonly channels: ChannelsManager = new ChannelsManager(this)
|
||||
/** Channels Manager, providing cache interface to Channels */
|
||||
emojis: EmojisManager = new EmojisManager(this)
|
||||
readonly emojis: EmojisManager = new EmojisManager(this)
|
||||
|
||||
/** Last READY timestamp */
|
||||
upSince?: Date
|
||||
|
@ -146,7 +167,9 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
|||
super()
|
||||
this._id = options.id
|
||||
this.token = options.token
|
||||
this.intents = options.intents
|
||||
this.intents = options.intents?.map((e) =>
|
||||
typeof e === 'string' ? GatewayIntents[e] : e
|
||||
)
|
||||
this.shards = new ShardManager(this)
|
||||
this.forceNewSession = options.forceNewSession
|
||||
if (options.cache !== undefined) this.cache = options.cache
|
||||
|
@ -172,14 +195,17 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
|
|||
;(this as any)._decoratedEvents = undefined
|
||||
}
|
||||
|
||||
this.clientProperties =
|
||||
options.clientProperties === undefined
|
||||
? {
|
||||
os: Deno.build.os,
|
||||
browser: 'harmony',
|
||||
device: 'harmony'
|
||||
}
|
||||
: options.clientProperties
|
||||
Object.defineProperty(this, 'clientProperties', {
|
||||
value:
|
||||
options.clientProperties === undefined
|
||||
? {
|
||||
os: Deno.build.os,
|
||||
browser: 'harmony',
|
||||
device: 'harmony'
|
||||
}
|
||||
: options.clientProperties,
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
if (options.shard !== undefined) this.shard = options.shard
|
||||
if (options.shardCount !== undefined) this.shardCount = options.shardCount
|
||||
|
|
|
@ -62,7 +62,7 @@ export class Gateway extends HarmonyEventEmitter<GatewayTypedEvents> {
|
|||
lastPingTimestamp = 0
|
||||
sessionID?: string
|
||||
private heartbeatServerResponded = false
|
||||
client: Client
|
||||
client!: Client
|
||||
cache: GatewayCache
|
||||
private timedIdentify: number | null = null
|
||||
shards?: number[]
|
||||
|
@ -70,7 +70,7 @@ export class Gateway extends HarmonyEventEmitter<GatewayTypedEvents> {
|
|||
|
||||
constructor(client: Client, shards?: number[]) {
|
||||
super()
|
||||
this.client = client
|
||||
Object.defineProperty(this, 'client', { value: client, enumerable: false })
|
||||
this.cache = new GatewayCache(client)
|
||||
this.shards = shards
|
||||
}
|
||||
|
|
|
@ -47,11 +47,21 @@ export type SlashClientEvents = {
|
|||
export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
||||
id: string | (() => string)
|
||||
client?: Client
|
||||
token?: string
|
||||
|
||||
#token?: string
|
||||
|
||||
get token(): string | undefined {
|
||||
return this.#token
|
||||
}
|
||||
|
||||
set token(val: string | undefined) {
|
||||
this.#token = val
|
||||
}
|
||||
|
||||
enabled: boolean = true
|
||||
commands: SlashCommandsManager
|
||||
handlers: SlashCommandHandler[] = []
|
||||
rest: RESTManager
|
||||
readonly rest!: RESTManager
|
||||
modules: SlashModule[] = []
|
||||
publicKey?: string
|
||||
|
||||
|
@ -62,7 +72,14 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
|||
if (id === undefined)
|
||||
throw new Error('ID could not be found. Pass at least client or token')
|
||||
this.id = id
|
||||
this.client = options.client
|
||||
|
||||
if (options.client !== undefined) {
|
||||
Object.defineProperty(this, 'client', {
|
||||
value: options.client,
|
||||
enumerable: false
|
||||
})
|
||||
}
|
||||
|
||||
this.token = options.token
|
||||
this.publicKey = options.publicKey
|
||||
|
||||
|
@ -85,14 +102,17 @@ export class SlashClient extends HarmonyEventEmitter<SlashClientEvents> {
|
|||
})
|
||||
}
|
||||
|
||||
this.rest =
|
||||
options.client === undefined
|
||||
? options.rest === undefined
|
||||
? new RESTManager({
|
||||
token: this.token
|
||||
})
|
||||
: options.rest
|
||||
: options.client.rest
|
||||
Object.defineProperty(this, 'rest', {
|
||||
value:
|
||||
options.client === undefined
|
||||
? options.rest === undefined
|
||||
? new RESTManager({
|
||||
token: this.token
|
||||
})
|
||||
: options.rest
|
||||
: options.client.rest,
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
this.client?.on(
|
||||
'interactionCreate',
|
||||
|
|
|
@ -198,12 +198,15 @@ export class SlashBuilder {
|
|||
|
||||
/** Manages Slash Commands, allows fetching/modifying/deleting/creating Slash Commands. */
|
||||
export class SlashCommandsManager {
|
||||
slash: SlashClient
|
||||
rest: RESTManager
|
||||
readonly slash!: SlashClient
|
||||
readonly rest!: RESTManager
|
||||
|
||||
constructor(client: SlashClient) {
|
||||
this.slash = client
|
||||
this.rest = client.rest
|
||||
Object.defineProperty(this, 'slash', { value: client, enumerable: false })
|
||||
Object.defineProperty(this, 'rest', {
|
||||
enumerable: false,
|
||||
value: client.rest
|
||||
})
|
||||
}
|
||||
|
||||
/** Get all Global Slash Commands */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { Client } from '../client/mod.ts'
|
||||
import { Base } from '../structures/base.ts'
|
||||
import { Collection } from '../utils/collection.ts'
|
||||
|
||||
/**
|
||||
|
@ -6,15 +7,14 @@ import { Collection } from '../utils/collection.ts'
|
|||
*
|
||||
* You should not be making Managers yourself.
|
||||
*/
|
||||
export class BaseManager<T, T2> {
|
||||
client: Client
|
||||
export class BaseManager<T, T2> extends Base {
|
||||
/** Caches Name or Key used to differentiate caches */
|
||||
cacheName: string
|
||||
/** Which data type does this cache have */
|
||||
DataType: any
|
||||
|
||||
constructor(client: Client, cacheName: string, DataType: any) {
|
||||
this.client = client
|
||||
super(client)
|
||||
this.cacheName = cacheName
|
||||
this.DataType = DataType
|
||||
}
|
||||
|
@ -87,4 +87,8 @@ export class BaseManager<T, T2> {
|
|||
flush(): any {
|
||||
return this.client.cache.deleteCache(this.cacheName)
|
||||
}
|
||||
|
||||
[Deno.customInspect](): string {
|
||||
return `Manager(${this.cacheName})`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import type { Client } from '../client/mod.ts'
|
||||
import { Base } from '../structures/base.ts'
|
||||
import { Collection } from '../utils/collection.ts'
|
||||
import { BaseManager } from './base.ts'
|
||||
|
||||
/** Child Managers validate data from their parents i.e. from Managers */
|
||||
export class BaseChildManager<T, T2> {
|
||||
client: Client
|
||||
export class BaseChildManager<T, T2> extends Base {
|
||||
/** Parent Manager */
|
||||
parent: BaseManager<T, T2>
|
||||
|
||||
constructor(client: Client, parent: BaseManager<T, T2>) {
|
||||
this.client = client
|
||||
super(client)
|
||||
this.parent = parent
|
||||
}
|
||||
|
||||
|
@ -62,4 +62,8 @@ export class BaseChildManager<T, T2> {
|
|||
if (fetchValue !== undefined) return fetchValue
|
||||
}
|
||||
}
|
||||
|
||||
[Deno.customInspect](): string {
|
||||
return `ChildManager(${this.parent.cacheName})`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,8 +103,18 @@ export class RESTManager {
|
|||
* ```
|
||||
*/
|
||||
api: APIMap
|
||||
|
||||
#token?: string | (() => string | undefined)
|
||||
|
||||
/** Token being used for Authorization */
|
||||
token?: string | (() => string | undefined)
|
||||
get token(): string | (() => string | undefined) | undefined {
|
||||
return this.#token
|
||||
}
|
||||
|
||||
set token(val: string | (() => string | undefined) | undefined) {
|
||||
this.#token = val
|
||||
}
|
||||
|
||||
/** Token Type of the Token if any */
|
||||
tokenType: TokenType = TokenType.Bot
|
||||
/** Headers object which patch the current ones */
|
||||
|
@ -114,13 +124,13 @@ export class RESTManager {
|
|||
/** Whether REST Manager is using Canary API */
|
||||
canary?: boolean
|
||||
/** Optional Harmony Client object */
|
||||
client?: Client
|
||||
readonly client?: Client
|
||||
endpoints: RESTEndpoints
|
||||
requestTimeout = 30000
|
||||
timers: Set<number> = new Set()
|
||||
readonly timers!: Set<number>
|
||||
apiURL = Constants.DISCORD_API_URL
|
||||
|
||||
handlers = new Collection<string, BucketHandler>()
|
||||
readonly handlers!: Collection<string, BucketHandler>
|
||||
globalLimit = Infinity
|
||||
globalRemaining = this.globalLimit
|
||||
globalReset: number | null = null
|
||||
|
@ -136,11 +146,28 @@ export class RESTManager {
|
|||
if (options?.tokenType !== undefined) this.tokenType = options.tokenType
|
||||
if (options?.userAgent !== undefined) this.userAgent = options.userAgent
|
||||
if (options?.canary !== undefined) this.canary = options.canary
|
||||
if (options?.client !== undefined) this.client = options.client
|
||||
if (options?.retryLimit !== undefined) this.retryLimit = options.retryLimit
|
||||
if (options?.requestTimeout !== undefined)
|
||||
this.requestTimeout = options.requestTimeout
|
||||
|
||||
if (options?.client !== undefined) {
|
||||
Object.defineProperty(this, 'client', {
|
||||
value: options.client,
|
||||
enumerable: false
|
||||
})
|
||||
}
|
||||
|
||||
this.endpoints = new RESTEndpoints(this)
|
||||
|
||||
Object.defineProperty(this, 'timers', {
|
||||
value: new Set(),
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
Object.defineProperty(this, 'handlers', {
|
||||
value: new Collection<string, BucketHandler>(),
|
||||
enumerable: false
|
||||
})
|
||||
}
|
||||
|
||||
setTimeout(fn: (...args: any[]) => any, ms: number): number {
|
||||
|
|
30
test/eval.ts
Normal file
30
test/eval.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* eslint-disable no-eval */
|
||||
import * as discord from '../mod.ts'
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new discord.Client({
|
||||
token: TOKEN,
|
||||
intents: ['GUILD_MESSAGES', 'GUILDS']
|
||||
})
|
||||
|
||||
client.on('messageCreate', async (msg) => {
|
||||
if (msg.author.id !== '422957901716652033') return
|
||||
|
||||
if (msg.content.startsWith('.eval') === true) {
|
||||
let code = msg.content.slice(5).trim()
|
||||
if (code.startsWith('```') === true) code = code.slice(3).trim()
|
||||
if (code.endsWith('```') === true) code = code.substr(0, code.length - 3)
|
||||
try {
|
||||
const result = await eval(code)
|
||||
msg.reply(
|
||||
`\`\`\`js\n${Deno.inspect(result).substr(0, 2000 - 20)}\n\`\`\``
|
||||
)
|
||||
} catch (e) {
|
||||
msg.reply(`\`\`\`js\n${e}\n\`\`\``, {
|
||||
allowedMentions: { replied_user: false }
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
client.connect().then(() => console.log('Ready!'))
|
|
@ -8,12 +8,12 @@ import {
|
|||
CommandContext,
|
||||
Extension,
|
||||
Collection,
|
||||
GuildTextChannel
|
||||
} from '../../mod.ts'
|
||||
GuildTextChannel,
|
||||
Interaction,
|
||||
slash
|
||||
} from '../mod.ts'
|
||||
import { LL_IP, LL_PASS, LL_PORT, TOKEN } from './config.ts'
|
||||
import { Manager, Player } from 'https://deno.land/x/lavadeno/mod.ts'
|
||||
import { Interaction } from '../structures/slash.ts'
|
||||
import { slash } from '../client/mod.ts'
|
||||
// import { SlashCommandOptionType } from '../types/slash.ts'
|
||||
|
||||
export const nodes = [
|
||||
|
|
87
test/trigger.ts
Normal file
87
test/trigger.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
/* eslint-disable no-control-regex */
|
||||
import { Client, Embed } from '../mod.ts'
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new Client({
|
||||
token: TOKEN,
|
||||
intents: ['GUILDS', 'GUILD_MESSAGES']
|
||||
})
|
||||
|
||||
const NAME_MATCH = /[^a-zA-Z0-9_]/
|
||||
const STD_REGEX = /\/?std(@[\x00-\x2e\x30-\xff]+)?\/([a-zA-Z0-9]+)(\/[\S\s]+)?/
|
||||
const X_REGEX = /\/?x\/([a-zA-Z0-9]+)(@[\x00-\x2e\x30-\xff]+)?(\/[\S\s]+)?/
|
||||
|
||||
export async function fetchModule(name: string): Promise<any> {
|
||||
if (name.match(NAME_MATCH) !== null) return null
|
||||
return fetch(`https://api.deno.land/modules/${name}`, {
|
||||
credentials: 'omit',
|
||||
headers: {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0',
|
||||
Accept: 'application/json',
|
||||
'Accept-Language': 'en-US,en;q=0.5',
|
||||
Pragma: 'no-cache',
|
||||
'Cache-Control': 'no-cache'
|
||||
},
|
||||
referrer: 'https://deno.land/x',
|
||||
mode: 'cors'
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.status !== 200) throw new Error('not found')
|
||||
return res
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.then((json) => {
|
||||
if (!json.success) throw new Error('failed')
|
||||
return json
|
||||
})
|
||||
.then((data) => data.data)
|
||||
.catch(() => null)
|
||||
}
|
||||
|
||||
client.on('messageCreate', async (msg) => {
|
||||
if (msg.author.bot === true) return
|
||||
|
||||
let match
|
||||
if (
|
||||
(match = msg.content.match(STD_REGEX)) ||
|
||||
(match = msg.content.match(X_REGEX))
|
||||
) {
|
||||
let x = match[0].trim()
|
||||
|
||||
if (!x.startsWith('/')) x = `/${x}`
|
||||
|
||||
let type
|
||||
if (x.startsWith('/std')) {
|
||||
x = x.slice(4)
|
||||
type = 'std'
|
||||
} else {
|
||||
x = x.slice(3)
|
||||
type = 'x'
|
||||
}
|
||||
|
||||
x = x.trim()
|
||||
const name = x.split('/')[0].split('@')[0]
|
||||
const mod = await fetchModule(type === 'std' ? 'std' : name)
|
||||
if (mod === null) return
|
||||
|
||||
msg.channel.send(
|
||||
new Embed()
|
||||
.setColor('#7289DA')
|
||||
.setURL(
|
||||
`https://deno.land/${type}${
|
||||
x.startsWith('/') || x.startsWith('@') ? '' : '/'
|
||||
}${x}`
|
||||
)
|
||||
.setTitle(
|
||||
`${type}${x.startsWith('/') || x.startsWith('@') ? '' : '/'}${x}`
|
||||
)
|
||||
.setDescription(mod.description ?? 'No description.')
|
||||
.setFooter(`${mod.star_count ?? 0}`, 'https://kokoro.pw/colleague.png')
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Connecting...')
|
||||
client.connect().then(() => console.log('Ready!'))
|
Loading…
Reference in a new issue