fix: NodeJS is not defined (eslint bug) + fix most linter errors (which fixes #102) (#106)

* fix: silly eslint bug

* fix: Linter Errors (#105)

* fix

* revert linter bug

Co-authored-by: Marcos Susaña <marcosjgs03@gmail.com>
This commit is contained in:
Yuzu 2022-09-02 15:07:15 +00:00 committed by GitHub
parent d1f952be27
commit 6915258093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 111 additions and 96 deletions

View File

@ -1,4 +1,5 @@
node_modules/
build
dist
examples/**
examples/**
tsup.config.ts

View File

@ -20,12 +20,18 @@ ignorePatterns:
parser: '@typescript-eslint/parser'
parserOptions:
project: 'tsconfig.json'
project: './packages/**/tsconfig.json'
sourceType: 'module'
plugins:
- '@typescript-eslint'
# silly eslint bug
overrides:
- files: ['*.ts']
rules:
no-undef: 'off'
rules:
'@typescript-eslint/consistent-type-imports': 'error'
'@typescript-eslint/no-duplicate-imports': 'error'

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ package-lock.json
# Eater asked for this dunno why
bot/
apps/
# Enviorment
.env

View File

@ -1,4 +1,3 @@
/* eslint-disable no-mixed-spaces-and-tabs */
/** https://discord.com/developers/docs/resources/user#user-object-premium-types */
export enum PremiumTypes {
None,
@ -1253,9 +1252,9 @@ export type Camelize<T> = {
// eslint-disable-next-line @typescript-eslint/array-type
[K in keyof T as CamelCase<string & K>]: T[K] extends Array<infer U>
? // eslint-disable-next-line @typescript-eslint/ban-types
U extends {}
U extends {}
? // eslint-disable-next-line @typescript-eslint/array-type
Array<Camelize<U>>
Array<Camelize<U>>
: T[K]
: // eslint-disable-next-line @typescript-eslint/ban-types
T[K] extends {}

View File

@ -81,8 +81,8 @@ export interface ListGuildMembers {
export function GUILD_MEMBERS(guildId: Snowflake, options?: ListGuildMembers) {
let url = `/guilds/${guildId}/members?`;
if (options?.limit) url += `limit=${options.limit}`;
if (options?.after) url += `&after=${options.after}`;
if (options?.limit) { url += `limit=${options.limit}`; }
if (options?.after) { url += `&after=${options.after}`; }
return url;
}
@ -129,13 +129,13 @@ export function USER_DM() {
}
export function GUILD_EMOJIS(guildId: Snowflake, emojiId?: Snowflake): string {
if (emojiId) return `/guilds/${guildId}/emojis/${emojiId}`;
if (emojiId) { return `/guilds/${guildId}/emojis/${emojiId}`; }
return `/guilds/${guildId}/emojis`;
}
export interface GetAuditLogs {
userId?: Snowflake;
actionType?: AuditLogEvents
actionType?: AuditLogEvents;
before?: Snowflake;
limit?: number;
}
@ -150,8 +150,8 @@ export function GUILD_AUDIT_LOGS(guildId: Snowflake, options?: GetAuditLogs) {
limit: options.limit
};
for (const [key, value] of Object.entries(obj)) {
if (!value) continue;
url += `&${key}=${value}`
if (!value) { continue; }
url += `&${key}=${value}`;
}
}
return url;

View File

@ -1,4 +1,3 @@
/* eslint-disable no-mixed-spaces-and-tabs */
import type {
ActivityTypes,
AllowedMentionsTypes,
@ -18,8 +17,6 @@ import type {
GuildNsfwLevel,
IntegrationExpireBehaviors,
InteractionTypes,
// No used
// Locales,
Localization,
MessageActivityTypes,
MessageComponentTypes,

View File

@ -1,5 +1,5 @@
import type { CacheAdapter } from './cache-adapter';
interface Options {
expire?: number;
}

View File

@ -1,6 +1,7 @@
import type { CacheAdapter } from './cache-adapter';
import Redis, { RedisOptions } from 'ioredis';
import type { RedisOptions } from 'ioredis';
import type Redis from 'ioredis';
import IORedis from 'ioredis';
interface BaseOptions {
@ -13,7 +14,7 @@ interface BuildOptions extends BaseOptions, RedisOptions { }
interface ClientOptions extends BaseOptions {
client: Redis;
}
type Options = BuildOptions | ClientOptions;
export class RedisCacheAdapter implements CacheAdapter {
@ -114,7 +115,7 @@ export class RedisCacheAdapter implements CacheAdapter {
* @inheritDoc
*/
composite(id: string): string {
composite(id: string): string {
return `${this.options.namespace}:${id}`;
}
}
}

View File

@ -1,3 +1,4 @@
/* eslint-disable no-case-declarations */
import { MemoryCacheAdapter } from './adapters/memory-cache-adapter';
// import { RedisCacheAdapter } from './adapters/redis-cache-adapter';
@ -69,7 +70,7 @@ export class Cache {
case 'READY':
await this.users.set(event.d.user.id, event.d.user);
const guilds: Array<Promise<any> | undefined> = [];
const guilds: (Promise<any> | undefined)[] = [];
for (const guild of event.d.guilds) {
guilds.push(this.guilds.set(guild.id, guild));
@ -170,7 +171,7 @@ export class Cache {
break;
case 'GUILD_MEMBERS_CHUNK':
const members: Array<Promise<any> | undefined> = [];
const members: (Promise<any> | undefined)[] = [];
for (const member of event.d.members) {
members.push(

View File

@ -1,14 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import type { CacheAdapter } from '../adapters/cache-adapter';
export class BaseResource {
namespace = 'base';
adapter!: CacheAdapter; // replace
constructor() {
//
}
/**
* @inheritDoc
*/

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordChannel } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordChannel } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class ChannelResource extends BaseResource {
namespace: 'channel' = 'channel';
namespace = 'channel' as const;
adapter: CacheAdapter;

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordEmoji } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordEmoji } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildEmojiResource extends BaseResource {
namespace: 'emoji' = 'emoji';
namespace = 'emoji' as const;
adapter: CacheAdapter;

View File

@ -1,11 +1,11 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordMember } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordMember } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
import { UserResource } from './user-resource';
export class GuildMemberResource extends BaseResource {
namespace: 'member' = 'member';
namespace = 'member' as const;
adapter: CacheAdapter;
users: UserResource;

View File

@ -1,5 +1,5 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordGuild } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordGuild } from '@biscuitland/api-types';
import { ChannelResource } from './channel-resource';
import { GuildEmojiResource } from './guild-emoji-resource';
@ -11,7 +11,7 @@ import { VoiceResource } from './voice-resource';
import { BaseResource } from './base-resource';
export class GuildResource extends BaseResource {
namespace: 'guild' = 'guild';
namespace = 'guild' as const;
adapter: CacheAdapter;
@ -55,7 +55,7 @@ export class GuildResource extends BaseResource {
async set(id: string, data: any, expire?: number): Promise<void> {
if (data.channels) {
const channels: Array<Promise<any> | undefined> = [];
const channels: (Promise<any> | undefined)[] = [];
for (const channel of data.channels) {
await this.channels.set(channel.id, channel);
@ -65,7 +65,7 @@ export class GuildResource extends BaseResource {
}
if (data.members) {
const members: Array<Promise<any> | undefined> = [];
const members: (Promise<any> | undefined)[] = [];
for (const member of data.members) {
await this.members.set(member.user.id, id, member);
@ -75,7 +75,7 @@ export class GuildResource extends BaseResource {
}
if (data.roles) {
const roles: Array<Promise<any> | undefined> = [];
const roles: (Promise<any> | undefined)[] = [];
for (const role of data.roles) {
await this.roles.set(role.id, id, role);
@ -85,7 +85,7 @@ export class GuildResource extends BaseResource {
}
if (data.stickers) {
const stickers: Array<Promise<any> | undefined> = [];
const stickers: (Promise<any> | undefined)[] = [];
for (const sticker of data.stickers) {
await this.stickers.set(sticker.id, id, sticker);
@ -95,7 +95,7 @@ export class GuildResource extends BaseResource {
}
if (data.emojis) {
const emojis: Array<Promise<any> | undefined> = [];
const emojis: (Promise<any> | undefined)[] = [];
for (const emoji of data.emojis) {
await this.emojis.set(emoji.id, id, emoji);
@ -105,7 +105,7 @@ export class GuildResource extends BaseResource {
}
if (data.voice_states) {
const voices: Array<Promise<any>> = [];
const voices: Promise<any>[] = [];
for (const voice of data.voice_states) {
if (!voice.guild_id) {

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordRole } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordRole } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildRoleResource extends BaseResource {
namespace: 'role' = 'role';
namespace = 'role' as const;
adapter: CacheAdapter;

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordSticker } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordSticker } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class GuildStickerResource extends BaseResource {
namespace: 'sticker' = 'sticker';
namespace = 'sticker' as const;
adapter: CacheAdapter;

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordUser } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordUser } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class UserResource extends BaseResource {
namespace: 'user' = 'user';
namespace = 'user' as const;
adapter: CacheAdapter;

View File

@ -1,10 +1,10 @@
import { CacheAdapter } from '../adapters/cache-adapter';
import { DiscordVoiceState } from '@biscuitland/api-types';
import type { CacheAdapter } from '../adapters/cache-adapter';
import type { DiscordVoiceState } from '@biscuitland/api-types';
import { BaseResource } from './base-resource';
export class VoiceResource extends BaseResource {
namespace: 'voice' = 'voice';
namespace = 'voice' as const;
adapter: CacheAdapter;

View File

@ -28,6 +28,7 @@
"@biscuitland/ws": "^2.0.5"
},
"devDependencies": {
"@types/node": "^18.7.14",
"tsup": "^6.1.3"
},
"license": "Apache-2.0",

View File

@ -1,7 +1,6 @@
import type { EventEmitter } from 'stream';
import type { Events } from './events';
export interface EventAdapter extends Omit<EventEmitter, 'emit' | 'on' | 'off' | 'once'> {
export interface EventAdapter extends Omit<NodeJS.EventEmitter, 'emit' | 'on' | 'off' | 'once'> {
options?: any;
emit<K extends keyof Events>(

View File

@ -27,6 +27,7 @@
"@biscuitland/core": "^2.0.5"
},
"devDependencies": {
"@types/node": "^18.7.14",
"tsup": "^6.1.3"
},
"license": "Apache-2.0",

View File

@ -1,10 +1,12 @@
import { DiscordInputTextComponent, MessageComponentTypes, TextStyles } from '@biscuitland/api-types';
import type { DiscordInputTextComponent, TextStyles } from '@biscuitland/api-types';
import { MessageComponentTypes } from '@biscuitland/api-types';
export class InputTextBuilder {
constructor() {
this.#data = {} as DiscordInputTextComponent;
this.type = MessageComponentTypes.InputText;
}
#data: DiscordInputTextComponent;
type: MessageComponentTypes.InputText;
@ -43,6 +45,7 @@ export class InputTextBuilder {
this.#data.required = required;
return this;
}
toJSON(): DiscordInputTextComponent {
return { ...this.#data, type: this.type };
}

View File

@ -1,4 +1,5 @@
import { DiscordActionRow, MessageComponentTypes } from '@biscuitland/api-types';
import type { DiscordActionRow } from '@biscuitland/api-types';
import { MessageComponentTypes } from '@biscuitland/api-types';
import type { ComponentBuilder } from '../../../../core/src/utils/util';
export class ActionRowBuilder<T extends ComponentBuilder> {
@ -6,6 +7,7 @@ export class ActionRowBuilder<T extends ComponentBuilder> {
this.components = [] as T[];
this.type = MessageComponentTypes.ActionRow;
}
components: T[];
type: MessageComponentTypes.ActionRow;
@ -27,7 +29,7 @@ export class ActionRowBuilder<T extends ComponentBuilder> {
return {
type: this.type,
// @ts-ignore: socram fix this
components: this.components.map((c) => c.toJSON()) as DiscordActionRow['components'],
components: this.components.map(c => c.toJSON()) as DiscordActionRow['components'],
};
}
}

View File

@ -1,4 +1,5 @@
import { ButtonStyles, DiscordButtonComponent, MessageComponentTypes } from '@biscuitland/api-types';
import type { ButtonStyles, DiscordButtonComponent } from '@biscuitland/api-types';
import { MessageComponentTypes } from '@biscuitland/api-types';
import type { ComponentEmoji } from '../../../../core/src/utils/util';
export class ButtonBuilder {
@ -6,6 +7,7 @@ export class ButtonBuilder {
this.#data = {} as DiscordButtonComponent;
this.type = MessageComponentTypes.Button;
}
#data: DiscordButtonComponent;
type: MessageComponentTypes.Button;

View File

@ -1,11 +1,12 @@
import type { DiscordSelectOption, DiscordSelectMenuComponent, } from '@biscuitland/api-types';
import type { ComponentEmoji } from '../../../../core/src/utils/util';
import { MessageComponentTypes } from '@biscuitland/api-types';
import { MessageComponentTypes } from '@biscuitland/api-types';
export class SelectMenuOptionBuilder {
constructor() {
this.#data = {} as DiscordSelectOption;
}
#data: DiscordSelectOption;
setLabel(label: string): SelectMenuOptionBuilder {
@ -44,6 +45,7 @@ export class SelectMenuBuilder {
this.type = MessageComponentTypes.SelectMenu;
this.options = [];
}
#data: DiscordSelectMenuComponent;
type: MessageComponentTypes.SelectMenu;
options: SelectMenuOptionBuilder[];
@ -86,6 +88,6 @@ export class SelectMenuBuilder {
}
toJSON(): DiscordSelectMenuComponent {
return { ...this.#data, type: this.type, options: this.options.map((option) => option.toJSON()) };
return { ...this.#data, type: this.type, options: this.options.map(option => option.toJSON()) };
}
}

View File

@ -36,7 +36,7 @@ export class EmbedBuilder {
#data: Embed;
constructor(data: Embed = {}) {
this.#data = data;
if (!this.#data.fields) this.#data.fields = [];
if (!this.#data.fields) { this.#data.fields = []; }
}
setAuthor(author: EmbedAuthor): EmbedBuilder {
@ -86,7 +86,7 @@ export class EmbedBuilder {
setTitle(title: string, url?: string): EmbedBuilder {
this.#data.title = title;
if (url) this.setUrl(url);
if (url) { this.setUrl(url); }
return this;
}

View File

@ -1,20 +1,21 @@
import {
import type {
Localization,
PermissionStrings,
PermissionStrings } from '@biscuitland/api-types';
import {
ApplicationCommandTypes
} from '@biscuitland/api-types';
import { CreateApplicationCommand } from '@biscuitland/core';
import type { CreateApplicationCommand } from '@biscuitland/core';
import { OptionBased } from './ApplicationCommandOption';
export abstract class ApplicationCommandBuilder {
constructor(
type: ApplicationCommandTypes = ApplicationCommandTypes.ChatInput,
name: string = '',
description: string = '',
name = '',
description = '',
defaultMemberPermissions?: PermissionStrings[],
nameLocalizations?: Localization,
descriptionLocalizations?: Localization,
dmPermission: boolean = true
dmPermission = true
) {
this.type = type;
this.name = name;
@ -24,6 +25,7 @@ export abstract class ApplicationCommandBuilder {
this.descriptionLocalizations = descriptionLocalizations;
this.dmPermission = dmPermission;
}
type: ApplicationCommandTypes;
name: string;
description: string;
@ -79,7 +81,7 @@ export class MessageApplicationCommandBuilder {
}
toJSON(): MessageApplicationCommandBuilderJSON {
if (!this.name) throw new TypeError("Propety 'name' is required");
if (!this.name) { throw new TypeError("Propety 'name' is required"); }
return {
type: ApplicationCommandTypes.Message,
@ -92,8 +94,8 @@ export class ChatInputApplicationCommandBuilder extends ApplicationCommandBuilde
type: ApplicationCommandTypes.ChatInput = ApplicationCommandTypes.ChatInput;
toJSON(): CreateApplicationCommand {
if (!this.type) throw new TypeError("Propety 'type' is required");
if (!this.name) throw new TypeError("Propety 'name' is required");
if (!this.type) { throw new TypeError("Propety 'type' is required"); }
if (!this.name) { throw new TypeError("Propety 'name' is required"); }
if (!this.description) {
throw new TypeError("Propety 'description' is required");
}

View File

@ -1,5 +1,6 @@
import { ChannelTypes, Localization, Locales, ApplicationCommandOptionTypes } from '@biscuitland/api-types';
import { ApplicationCommandOptionChoice } from '@biscuitland/core';
import type { ChannelTypes, Localization, Locales } from '@biscuitland/api-types';
import { ApplicationCommandOptionTypes } from '@biscuitland/api-types';
import type { ApplicationCommandOptionChoice } from '@biscuitland/core';
export type Localizations = typeof Locales[keyof typeof Locales] & string;
@ -19,8 +20,8 @@ export class ChoiceBuilder {
}
toJSON(): ApplicationCommandOptionChoice {
if (!this.name) throw new TypeError('Property \'name\' is required');
if (!this.value) throw new TypeError('Property \'value\' is required');
if (!this.name) { throw new TypeError('Property \'name\' is required'); }
if (!this.value) { throw new TypeError('Property \'value\' is required'); }
return {
name: this.name,
@ -67,8 +68,8 @@ export class OptionBuilder {
}
toJSON(): ApplicationCommandOption {
if (!this.type) throw new TypeError('Property \'type\' is required');
if (!this.name) throw new TypeError('Property \'name\' is required');
if (!this.type) { throw new TypeError('Property \'type\' is required'); }
if (!this.name) { throw new TypeError('Property \'name\' is required'); }
if (!this.description) {
throw new TypeError('Property \'description\' is required');
}
@ -120,7 +121,7 @@ export class OptionBuilderLimitedValues extends OptionBuilder {
override toJSON(): ApplicationCommandOption {
return {
...super.toJSON(),
choices: this.choices?.map((c) => c.toJSON()) ?? [],
choices: this.choices?.map(c => c.toJSON()) ?? [],
min_value: this.minValue,
max_value: this.maxValue,
};
@ -151,7 +152,7 @@ export class OptionBuilderString extends OptionBuilder {
override toJSON(): ApplicationCommandOption {
return {
...super.toJSON(),
choices: this.choices?.map((c) => c.toJSON()) ?? [],
choices: this.choices?.map(c => c.toJSON()) ?? [],
};
}
}
@ -271,8 +272,9 @@ export class OptionBased {
return this.addOption(fn, ApplicationCommandOptionTypes.Mentionable);
}
static applyTo(klass: Function, ignore: Array<keyof OptionBased> = []): void {
const methods: Array<keyof OptionBased> = [
// eslint-disable-next-line @typescript-eslint/ban-types
static applyTo(klass: Function, ignore: (keyof OptionBased)[] = []): void {
const methods: (keyof OptionBased)[] = [
'addOption',
'addNestedOption',
'addStringOption',
@ -288,7 +290,7 @@ export class OptionBased {
];
for (const method of methods) {
if (ignore.includes(method)) continue;
if (ignore.includes(method)) { continue; }
klass.prototype[method] = OptionBased.prototype[method];
}
@ -308,8 +310,8 @@ export class OptionBuilderNested extends OptionBuilder {
}
override toJSON(): ApplicationCommandOption {
if (!this.type) throw new TypeError('Property \'type\' is required');
if (!this.name) throw new TypeError('Property \'name\' is required');
if (!this.type) { throw new TypeError('Property \'type\' is required'); }
if (!this.name) { throw new TypeError('Property \'name\' is required'); }
if (!this.description) {
throw new TypeError('Property \'description\' is required');
}
@ -318,7 +320,7 @@ export class OptionBuilderNested extends OptionBuilder {
type: this.type,
name: this.name,
description: this.description,
options: this.options?.map((o) => o.toJSON()) ?? [],
options: this.options?.map(o => o.toJSON()) ?? [],
required: this.required ? true : false,
};
}

View File

@ -1,6 +1,7 @@
import type { Session, Events } from '@biscuitland/core';
import { EventEmitter } from 'node:events';
export interface CollectorOptions<E extends keyof Events> {
event: E;
filter?(...args: Parameters<Events[E]>): unknown;
@ -12,16 +13,15 @@ export interface CollectorOptions<E extends keyof Events> {
export class Collector<E extends keyof Events> extends EventEmitter {
collected = new Set<Parameters<Events[E]>[0]>();
ended = false;
private timeout: NodeJS.Timeout;
constructor(readonly session: Session, public options: CollectorOptions<E>) {
super();
if (!('filter' in this.options))
this.options.filter = (() => true);
if (!('filter' in this.options)) { this.options.filter = (() => true); }
if (!('max' in this.options))
this.options.max = -1;
if (!('max' in this.options)) { this.options.max = -1; }
this.session.events.setMaxListeners(this.session.events.getMaxListeners() + 1);
@ -41,12 +41,11 @@ export class Collector<E extends keyof Events> extends EventEmitter {
this.timeout = setTimeout(() => this.stop('time'), this.options.idle);
}
if (this.collected.size >= this.options.max!)
this.stop('max');
if (this.collected.size >= this.options.max!) { this.stop('max'); }
}
stop(reason?: string) {
if (this.ended) return;
if (this.ended) { return; }
clearTimeout(this.timeout);