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 = | ||||
|     Object.defineProperty(this, 'clientProperties', { | ||||
|       value: | ||||
|         options.clientProperties === undefined | ||||
|           ? { | ||||
|               os: Deno.build.os, | ||||
|               browser: 'harmony', | ||||
|               device: 'harmony' | ||||
|             } | ||||
|         : options.clientProperties | ||||
|           : 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 = | ||||
|     Object.defineProperty(this, 'rest', { | ||||
|       value: | ||||
|         options.client === undefined | ||||
|           ? options.rest === undefined | ||||
|             ? new RESTManager({ | ||||
|                 token: this.token | ||||
|               }) | ||||
|             : options.rest | ||||
|         : options.client.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…
	
	Add table
		Add a link
		
	
		Reference in a new issue