Merge pull request #94 from Helloyunho/some-fixes
Fix Some Bugs and Add Some Useful Things
This commit is contained in:
		
						commit
						108bd3ea62
					
				
					 14 changed files with 301 additions and 47 deletions
				
			
		
							
								
								
									
										10
									
								
								mod.ts
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								mod.ts
									
										
									
									
									
								
							|  | @ -102,12 +102,16 @@ export type { | |||
|   MessageOptions | ||||
| } from './src/types/channel.ts' | ||||
| export type { EmojiPayload } from './src/types/emoji.ts' | ||||
| export { Verification } from './src/types/guild.ts' | ||||
| export type { | ||||
|   GuildBanPayload, | ||||
|   GuildFeatures, | ||||
|   GuildIntegrationPayload, | ||||
|   GuildPayload, | ||||
|   GuildChannels | ||||
|   GuildBanPayload, | ||||
|   GuildFeatures, | ||||
|   GuildChannels, | ||||
|   GuildCreateOptions, | ||||
|   GuildCreateChannelOptions, | ||||
|   GuildCreateRolePayload | ||||
| } from './src/types/guild.ts' | ||||
| export type { InvitePayload, PartialInvitePayload } from './src/types/invite.ts' | ||||
| export { PermissionFlags } from './src/types/permissionFlags.ts' | ||||
|  |  | |||
|  | @ -70,45 +70,45 @@ export class GuildManager extends BaseManager<GuildPayload, Guild> { | |||
|     if (options.icon !== undefined && !options.icon.startsWith('data:')) { | ||||
|       options.icon = await fetchAuto(options.icon) | ||||
|     } | ||||
|     if (options.roles !== undefined && options.roles[0].name !== '@everyone') { | ||||
|       options.roles.unshift({ | ||||
|         id: Math.floor(Math.random() * 18392375458).toString(), | ||||
|         name: '@everyone' | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|     const body: GuildCreatePayload = { | ||||
|       name: options.name, | ||||
|       region: options.region, | ||||
|       icon: options.icon, | ||||
|       verification_level: options.verificationLevel, | ||||
|       roles: | ||||
|         options.roles !== undefined | ||||
|           ? options.roles.map((obj) => { | ||||
|               let result: GuildCreateRolePayload | ||||
|               if (obj instanceof Role) { | ||||
|                 result = { | ||||
|                   id: obj.id, | ||||
|                   name: obj.name, | ||||
|                   color: obj.color, | ||||
|                   hoist: obj.hoist, | ||||
|                   position: obj.position, | ||||
|                   permissions: obj.permissions.bitfield.toString(), | ||||
|                   managed: obj.managed, | ||||
|                   mentionable: obj.mentionable | ||||
|                 } | ||||
|               } else { | ||||
|                 result = obj | ||||
|               } | ||||
|       roles: options.roles?.map((obj) => { | ||||
|         let result: GuildCreateRolePayload | ||||
|         if (obj instanceof Role) { | ||||
|           result = { | ||||
|             id: obj.id, | ||||
|             name: obj.name, | ||||
|             color: obj.color, | ||||
|             hoist: obj.hoist, | ||||
|             position: obj.position, | ||||
|             permissions: obj.permissions.bitfield.toString(), | ||||
|             managed: obj.managed, | ||||
|             mentionable: obj.mentionable | ||||
|           } | ||||
|         } else { | ||||
|           result = obj | ||||
|         } | ||||
| 
 | ||||
|               return result | ||||
|             }) | ||||
|           : undefined, | ||||
|       channels: | ||||
|         options.channels !== undefined | ||||
|           ? options.channels.map( | ||||
|               (obj): GuildCreateChannelPayload => ({ | ||||
|                 id: obj.id, | ||||
|                 name: obj.name, | ||||
|                 type: obj.type, | ||||
|                 parent_id: obj.parentID | ||||
|               }) | ||||
|             ) | ||||
|           : undefined, | ||||
|         return result | ||||
|       }), | ||||
|       channels: options.channels?.map( | ||||
|         (obj): GuildCreateChannelPayload => ({ | ||||
|           id: obj.id, | ||||
|           name: obj.name, | ||||
|           type: obj.type, | ||||
|           parent_id: obj.parentID | ||||
|         }) | ||||
|       ), | ||||
|       afk_channel_id: options.afkChannelID, | ||||
|       afk_timeout: options.afkTimeout, | ||||
|       system_channel_id: options.systemChannelID | ||||
|  |  | |||
|  | @ -41,6 +41,12 @@ export class RolesManager extends BaseManager<RolePayload, Role> { | |||
|     return new Role(this.client, raw, this.guild) | ||||
|   } | ||||
| 
 | ||||
|   async array(): Promise<Role[]> { | ||||
|     let arr = await (this.client.cache.array(this.cacheName) as RolePayload[]) | ||||
|     if (arr === undefined) arr = [] | ||||
|     return arr.map((e) => new Role(this.client, e, this.guild)) | ||||
|   } | ||||
| 
 | ||||
|   async fromPayload(roles: RolePayload[]): Promise<boolean> { | ||||
|     for (const role of roles) { | ||||
|       await this.set(role.id, role) | ||||
|  |  | |||
|  | @ -144,7 +144,7 @@ export class Client extends HarmonyEventEmitter<ClientEvents> { | |||
|     if (this.upSince === undefined) return 0 | ||||
|     else { | ||||
|       const dif = Date.now() - this.upSince.getTime() | ||||
|       if (dif < 0) return dif | ||||
|       if (dif < 0) return 0 | ||||
|       else return dif | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -28,8 +28,23 @@ export interface RequestHeaders { | |||
|   [name: string]: string | ||||
| } | ||||
| 
 | ||||
| export interface DiscordAPIErrorPayload { | ||||
|   url: string | ||||
|   status: number | ||||
|   method: string | ||||
|   code?: number | ||||
|   message?: string | ||||
|   errors: object | ||||
| } | ||||
| 
 | ||||
| export class DiscordAPIError extends Error { | ||||
|   name = 'DiscordAPIError' | ||||
|   error?: DiscordAPIErrorPayload | ||||
| 
 | ||||
|   constructor(message?: string, error?: DiscordAPIErrorPayload) { | ||||
|     super(message) | ||||
|     this.error = error | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export interface QueuedItem { | ||||
|  | @ -399,7 +414,7 @@ export class RESTManager { | |||
|       ) | ||||
| 
 | ||||
|     // At this point we know it is error
 | ||||
|     const error: { [name: string]: any } = { | ||||
|     const error: DiscordAPIErrorPayload = { | ||||
|       url: response.url, | ||||
|       status, | ||||
|       method: data.method, | ||||
|  | @ -443,9 +458,9 @@ export class RESTManager { | |||
|         HttpResponseCode.MethodNotAllowed | ||||
|       ].includes(status) | ||||
|     ) { | ||||
|       reject(new DiscordAPIError(Deno.inspect(error))) | ||||
|       reject(new DiscordAPIError(Deno.inspect(error), error)) | ||||
|     } else if (status === HttpResponseCode.GatewayUnavailable) { | ||||
|       reject(new DiscordAPIError(Deno.inspect(error))) | ||||
|       reject(new DiscordAPIError(Deno.inspect(error), error)) | ||||
|     } else reject(new DiscordAPIError('Request - Unknown Error')) | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -378,9 +378,7 @@ export class SlashClient { | |||
|     this.token = options.token | ||||
|     this.publicKey = options.publicKey | ||||
| 
 | ||||
|     if (options !== undefined) { | ||||
|       this.enabled = options.enabled ?? true | ||||
|     } | ||||
|     this.enabled = options.enabled ?? true | ||||
| 
 | ||||
|     if (this.client?._decoratedSlash !== undefined) { | ||||
|       this.client._decoratedSlash.forEach((e) => { | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ import { RequestMembersOptions } from '../gateway/index.ts' | |||
| import { GuildPresencesManager } from '../managers/presences.ts' | ||||
| import { TemplatePayload } from '../types/template.ts' | ||||
| import { Template } from './template.ts' | ||||
| import { DiscordAPIError } from '../models/rest.ts' | ||||
| 
 | ||||
| export class GuildBan extends Base { | ||||
|   guild: Guild | ||||
|  | @ -403,7 +404,22 @@ export class Guild extends Base { | |||
| 
 | ||||
|   /** Returns a partial invite object for guilds with that feature enabled. */ | ||||
|   async getVanity(): Promise<{ code: string | null; uses: number }> { | ||||
|     return this.client.rest.api.guilds[this.id]['vanity-url'].get() | ||||
|     try { | ||||
|       const value = await this.client.rest.api.guilds[this.id][ | ||||
|         'vanity-url' | ||||
|       ].get() | ||||
|       return value | ||||
|     } catch (error) { | ||||
|       if (error instanceof DiscordAPIError) { | ||||
|         if (error.error?.code === 50020) { | ||||
|           return { | ||||
|             code: null, | ||||
|             uses: 0 | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       throw error | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** Returns a PNG (URL) image widget for the guild. */ | ||||
|  | @ -446,7 +462,7 @@ export class Guild extends Base { | |||
|   async syncTemplate(code: string): Promise<Template> { | ||||
|     const payload = await this.client.rest.api.guilds[this.id].templates[ | ||||
|       code | ||||
|     ].sync.put() | ||||
|     ].put() | ||||
|     return new Template(this.client, payload) | ||||
|   } | ||||
| 
 | ||||
|  | @ -515,7 +531,7 @@ export class Guild extends Base { | |||
| 
 | ||||
|   async prune(options?: { | ||||
|     days?: number | ||||
|     computePruneCount: true | undefined | ||||
|     computePruneCount?: true | ||||
|     includeRoles?: Array<Role | string> | ||||
|   }): Promise<number> | ||||
|   async prune(options?: { | ||||
|  | @ -525,7 +541,7 @@ export class Guild extends Base { | |||
|   }): Promise<null> | ||||
|   async prune(options?: { | ||||
|     days?: number | ||||
|     computePruneCount?: boolean | undefined | ||||
|     computePruneCount?: boolean | ||||
|     includeRoles?: Array<Role | string> | ||||
|   }): Promise<number | null> { | ||||
|     const body: GuildBeginPrunePayload = { | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ import { Base } from './base.ts' | |||
| import { RoleModifyPayload, RolePayload } from '../types/role.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { User } from './user.ts' | ||||
| 
 | ||||
| export class Role extends Base { | ||||
|   id: string | ||||
|  | @ -50,6 +52,38 @@ export class Role extends Base { | |||
|     this.mentionable = data.mentionable ?? this.mentionable | ||||
|   } | ||||
| 
 | ||||
|   async addTo(member: Member | User | string): Promise<boolean> { | ||||
|     if (member instanceof User) { | ||||
|       member = member.id | ||||
|     } | ||||
|     if (typeof member === 'string') { | ||||
|       const tempMember = await this.guild.members.get(member) | ||||
|       if (tempMember === undefined) { | ||||
|         throw new Error(`Couldn't find the member ${member}.`) | ||||
|       } else { | ||||
|         member = tempMember | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return member.roles.add(this.id) | ||||
|   } | ||||
| 
 | ||||
|   async removeFrom(member: Member | User | string): Promise<boolean> { | ||||
|     if (member instanceof User) { | ||||
|       member = member.id | ||||
|     } | ||||
|     if (typeof member === 'string') { | ||||
|       const tempMember = await this.guild.members.get(member) | ||||
|       if (tempMember === undefined) { | ||||
|         throw new Error(`Couldn't find the member ${member}.`) | ||||
|       } else { | ||||
|         member = tempMember | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return member.roles.remove(this.id) | ||||
|   } | ||||
| 
 | ||||
|   async delete(): Promise<Role | undefined> { | ||||
|     return this.guild.roles.delete(this) | ||||
|   } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import { Base } from './base.ts' | |||
| import { ImageURL } from './cdn.ts' | ||||
| import { ImageSize, ImageFormats } from '../types/cdn.ts' | ||||
| import { DEFAULT_USER_AVATAR, USER_AVATAR } from '../types/endpoint.ts' | ||||
| import { DMChannel } from './dmChannel.ts' | ||||
| 
 | ||||
| export class User extends Base { | ||||
|   id: string | ||||
|  | @ -89,4 +90,8 @@ export class User extends Base { | |||
|   toString(): string { | ||||
|     return this.mention | ||||
|   } | ||||
| 
 | ||||
|   async getDMchannel(): Promise<DMChannel> { | ||||
|     return this.client.createDM(this) | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										137
									
								
								src/test/guild.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								src/test/guild.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| import { | ||||
|   Client, | ||||
|   Intents | ||||
|   // Verification
 | ||||
|   // PermissionFlags,
 | ||||
|   // ChannelTypes,
 | ||||
|   // GuildCreateOptions
 | ||||
| } from '../../mod.ts' | ||||
| import { TOKEN } from './config.ts' | ||||
| 
 | ||||
| const client = new Client() | ||||
| 
 | ||||
| // client.on('guildLoaded', async (guild) => {
 | ||||
| //   if (guild.name === 'OH WOW') {
 | ||||
| //     guild.delete()
 | ||||
| //   }
 | ||||
| // })
 | ||||
| 
 | ||||
| // client.on('ready', async () => {
 | ||||
| //   await new Promise((resolve, reject) => setTimeout(resolve, 1000))
 | ||||
| //   const body: GuildCreateOptions = {
 | ||||
| //     name: 'OH WOW',
 | ||||
| //     icon: 'https://helloyunho.xyz/_dist_/images/avatar.png',
 | ||||
| //     verificationLevel: Verification.NONE,
 | ||||
| //     roles: [
 | ||||
| //       {
 | ||||
| //         id: '1',
 | ||||
| //         name: 'a role',
 | ||||
| //         color: 0x103021,
 | ||||
| //         hoist: false,
 | ||||
| //         permissions: PermissionFlags.ADMINISTRATOR.toString(),
 | ||||
| //         mentionable: true
 | ||||
| //       }
 | ||||
| //     ],
 | ||||
| //     channels: [
 | ||||
| //       {
 | ||||
| //         name: 'fucking-awesome',
 | ||||
| //         type: ChannelTypes.GUILD_TEXT,
 | ||||
| //         id: '1'
 | ||||
| //       }
 | ||||
| //     ],
 | ||||
| //     systemChannelID: '1'
 | ||||
| //   }
 | ||||
| //   const guild = await client.guilds.create(body)
 | ||||
| 
 | ||||
| //   const channels = await guild.channels.array()
 | ||||
| //   console.log(channels.length)
 | ||||
| //   const invite = await guild.invites.create(channels[0].id)
 | ||||
| //   console.log(invite.link)
 | ||||
| // })
 | ||||
| 
 | ||||
| // client.on('guildLoaded', async (guild) => {
 | ||||
| //   if (guild.id === 'GUILD_ID') {
 | ||||
| //     // const roles = await guild.roles.array()
 | ||||
| //     // if (roles.length > 0) {
 | ||||
| //     //   roles.forEach(async (role) => {
 | ||||
| //     //     if (role.name !== '@everyone') {
 | ||||
| //     //       role.addTo('USER_ID')
 | ||||
| //     //     }
 | ||||
| //     //   })
 | ||||
| //     // }
 | ||||
| 
 | ||||
| //     // guild.edit({
 | ||||
| //     //   name: 'OH BOI',
 | ||||
| //     //   verificationLevel: Verification.MEDIUM
 | ||||
| //     // })
 | ||||
| 
 | ||||
| //     // const role1 = await guild.roles.create({
 | ||||
| //     //   name: 'IDK1'
 | ||||
| //     // })
 | ||||
| //     // const role2 = await guild.roles.create({
 | ||||
| //     //   name: 'IDK2'
 | ||||
| //     // })
 | ||||
| 
 | ||||
| //     // alert()
 | ||||
| 
 | ||||
| //     // await guild.roles.editPositions(
 | ||||
| //     //   {
 | ||||
| //     //     id: role1.id,
 | ||||
| //     //     position: 1
 | ||||
| //     //   },
 | ||||
| //     //   {
 | ||||
| //     //     id: role2.id,
 | ||||
| //     //     position: 2
 | ||||
| //     //   }
 | ||||
| //     // )
 | ||||
| 
 | ||||
| //     // alert()
 | ||||
| 
 | ||||
| //     // role1.delete()
 | ||||
| //     // role2.delete()
 | ||||
| 
 | ||||
| //     // const role = await guild.roles.create({
 | ||||
| //     //   name: 'IDK'
 | ||||
| //     // })
 | ||||
| 
 | ||||
| //     // alert()
 | ||||
| 
 | ||||
| //     // await role.edit({
 | ||||
| //     //   name: 'DUMB'
 | ||||
| //     // })
 | ||||
| 
 | ||||
| //     // alert()
 | ||||
| 
 | ||||
| //     // console.log(
 | ||||
| //     //   await guild.getPruneCount({
 | ||||
| //     //     days: 7,
 | ||||
| //     //     includeRoles: ['ROLE_ID']
 | ||||
| //     //   })
 | ||||
| //     // )
 | ||||
| 
 | ||||
| //     // console.log(
 | ||||
| //     //   await guild.prune({
 | ||||
| //     //     days: 7,
 | ||||
| //     //     includeRoles: ['ROLE_ID']
 | ||||
| //     //   })
 | ||||
| //     // )
 | ||||
| //     // console.log(
 | ||||
| //     //   await guild.prune({
 | ||||
| //     //     days: 7,
 | ||||
| //     //     computePruneCount: false,
 | ||||
| //     //     includeRoles: ['ROLE_ID']
 | ||||
| //     //   })
 | ||||
| //     // )
 | ||||
| 
 | ||||
| //     // await guild.editWidget({
 | ||||
| //     //   enabled: true,
 | ||||
| //     //   channel: 'CHANNEL_ID'
 | ||||
| //     // })
 | ||||
| 
 | ||||
| //     // console.log(await guild.getWidget())
 | ||||
| //     // console.log(await guild.getVanity())
 | ||||
| //     // console.log(await guild.getWidgetImageURL())
 | ||||
| //   }
 | ||||
| // })
 | ||||
| 
 | ||||
| client.connect(TOKEN, Intents.All) | ||||
							
								
								
									
										21
									
								
								src/test/template.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/test/template.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| import { Client, Intents } from '../../mod.ts' | ||||
| import { TOKEN } from './config.ts' | ||||
| 
 | ||||
| const client = new Client() | ||||
| 
 | ||||
| client.on('guildLoaded', async (guild) => { | ||||
|   if (guild.id === 'GUILD_ID') { | ||||
|     console.log((await guild.syncTemplate('TEMPLATE_ID')).code) | ||||
|     console.log( | ||||
|       ( | ||||
|         await guild.editTemplate('TEMPLATE_ID', { | ||||
|           name: 'asdf', | ||||
|           description: 'asdfasdfasdf' | ||||
|         }) | ||||
|       ).code | ||||
|     ) | ||||
|     console.log((await guild.deleteTemplate('TEMPLATE_ID')).id) | ||||
|   } | ||||
| }) | ||||
| 
 | ||||
| client.connect(TOKEN, Intents.All) | ||||
							
								
								
									
										14
									
								
								src/test/user.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/test/user.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| import { Client, Intents } from '../../mod.ts' | ||||
| import { TOKEN } from './config.ts' | ||||
| 
 | ||||
| const client = new Client() | ||||
| 
 | ||||
| client.on('ready', async () => { | ||||
|   client.editUser({ | ||||
|     username: 'Learning' | ||||
|   }) | ||||
|   const channel = await client.createDM('USER_ID') | ||||
|   channel.send('nice') | ||||
| }) | ||||
| 
 | ||||
| client.connect(TOKEN, Intents.All) | ||||
|  | @ -192,7 +192,7 @@ export interface GuildCreatePayload { | |||
| } | ||||
| 
 | ||||
| export interface GuildCreateRolePayload { | ||||
|   id?: string | ||||
|   id: string | ||||
|   name: string | ||||
|   color?: number | ||||
|   hoist?: boolean | ||||
|  |  | |||
|  | @ -24,4 +24,8 @@ export class Snowflake { | |||
|   get increment(): string { | ||||
|     return (this.snowflake & 0xfffn).toString() | ||||
|   } | ||||
| 
 | ||||
|   get toString(): string { | ||||
|     return this.id | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue