fix(ws): typing things

This commit is contained in:
Marcos Susaña 2023-07-21 15:28:30 -04:00
parent fa32071d4e
commit 10ae21de2a
3 changed files with 59 additions and 57 deletions

View File

@ -1,19 +1,19 @@
import { setTimeout } from 'node:timers/promises'; import { setTimeout } from "node:timers/promises";
import { ObjectToLower, ObjectToSnake } from './Types'; import { ObjectToLower, ObjectToSnake } from "./Types";
const isPlainObject = (value: any) => { const isPlainObject = (value: any) => {
return ( return (
(value !== null && (value !== null &&
typeof value === 'object' && typeof value === "object" &&
typeof value.constructor === 'function' && typeof value.constructor === "function" &&
// rome-ignore lint/suspicious/noPrototypeBuiltins: js tricks // rome-ignore lint/suspicious/noPrototypeBuiltins: js tricks
(value.constructor.prototype.hasOwnProperty('isPrototypeOf') || Object.getPrototypeOf(value.constructor.prototype) === null)) || (value.constructor.prototype.hasOwnProperty("isPrototypeOf") || Object.getPrototypeOf(value.constructor.prototype) === null)) ||
(value != undefined && Object.getPrototypeOf(value) === null) (value !== undefined && Object.getPrototypeOf(value) === null)
); );
}; };
const isObject = (o: any) => { const isObject = (o: any) => {
return !!o && typeof o === 'object' && !Array.isArray(o); return !!o && typeof o === "object" && !Array.isArray(o);
}; };
export const Options = <T = any>(defaults: any, ...options: any[]): T => { export const Options = <T = any>(defaults: any, ...options: any[]): T => {
@ -28,7 +28,7 @@ export const Options = <T = any>(defaults: any, ...options: any[]): T => {
if (isObject($) && isPlainObject(source)) { if (isObject($) && isPlainObject(source)) {
Object.entries(source).forEach(([key, value]) => { Object.entries(source).forEach(([key, value]) => {
if (typeof value === 'undefined') { if (typeof value === "undefined") {
return; return;
} }
@ -55,21 +55,21 @@ export function toSnakeCase<Obj extends Record<string, any>>(target: Obj): Objec
const result = {}; const result = {};
for (const [key, value] of Object.entries(target)) { for (const [key, value] of Object.entries(target)) {
switch (typeof value) { switch (typeof value) {
case 'string': case "string":
case 'bigint': case "bigint":
case 'boolean': case "boolean":
case 'function': case "function":
case 'symbol': case "symbol":
case 'undefined': case "undefined":
result[ReplaceRegex.snake(key)] = value; result[ReplaceRegex.snake(key)] = value;
break; break;
case 'object': case "object":
if (Array.isArray(value)) { if (Array.isArray(value)) {
result[ReplaceRegex.snake(key)] = value.map((prop) => typeof prop === 'object' && prop ? toSnakeCase(prop) : prop); result[ReplaceRegex.snake(key)] = value.map((prop) => (typeof prop === "object" && prop ? toSnakeCase(prop) : prop));
break; break;
} }
if (isObject(value)) { if (isObject(value)) {
result[ReplaceRegex.snake(key)] = toSnakeCase({ ...value }) result[ReplaceRegex.snake(key)] = toSnakeCase({ ...value });
break; break;
} }
if (!Number.isNaN(value)) { if (!Number.isNaN(value)) {
@ -92,21 +92,21 @@ export function toCamelCase<Obj extends Record<string, any>>(target: Obj): Objec
const result = {}; const result = {};
for (const [key, value] of Object.entries(target)) { for (const [key, value] of Object.entries(target)) {
switch (typeof value) { switch (typeof value) {
case 'string': case "string":
case 'bigint': case "bigint":
case 'boolean': case "boolean":
case 'function': case "function":
case 'symbol': case "symbol":
case 'undefined': case "undefined":
result[ReplaceRegex.camel(key)] = value; result[ReplaceRegex.camel(key)] = value;
break; break;
case 'object': case "object":
if (Array.isArray(value)) { if (Array.isArray(value)) {
result[ReplaceRegex.camel(key)] = value.map((prop) => typeof prop === 'object' && prop ? toCamelCase(prop) : prop); result[ReplaceRegex.camel(key)] = value.map((prop) => (typeof prop === "object" && prop ? toCamelCase(prop) : prop));
break; break;
} }
if (isObject(value)) { if (isObject(value)) {
result[ReplaceRegex.camel(key)] = toCamelCase({ ...value }) result[ReplaceRegex.camel(key)] = toCamelCase({ ...value });
break; break;
} }
if (!Number.isNaN(value)) { if (!Number.isNaN(value)) {
@ -126,7 +126,7 @@ export const ReplaceRegex = {
}, },
snake: (s: string) => { snake: (s: string) => {
return s.replace(/[A-Z]/g, (a) => `_${a.toLowerCase()}`); return s.replace(/[A-Z]/g, (a) => `_${a.toLowerCase()}`);
} },
}; };
// https://github.com/discordeno/discordeno/blob/main/packages/utils/src/colors.ts // https://github.com/discordeno/discordeno/blob/main/packages/utils/src/colors.ts
@ -166,9 +166,9 @@ export function getColorEnabled(): boolean {
*/ */
function code(open: number[], close: number): Code { function code(open: number[], close: number): Code {
return { return {
open: `\x1b[${open.join(';')}m`, open: `\x1b[${open.join(";")}m`,
close: `\x1b[${close}m`, close: `\x1b[${close}m`,
regexp: new RegExp(`\\x1b\\[${close}m`, 'g') regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
}; };
} }
@ -557,7 +557,7 @@ export function bgRgb8(str: string, color: number): string {
* @param color code * @param color code
*/ */
export function rgb24(str: string, color: number | Rgb): string { export function rgb24(str: string, color: number | Rgb): string {
if (typeof color === 'number') { if (typeof color === "number") {
return run(str, code([38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39)); return run(str, code([38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39));
} }
return run(str, code([38, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 39)); return run(str, code([38, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 39));
@ -579,7 +579,7 @@ export function rgb24(str: string, color: number | Rgb): string {
* @param color code * @param color code
*/ */
export function bgRgb24(str: string, color: number | Rgb): string { export function bgRgb24(str: string, color: number | Rgb): string {
if (typeof color === 'number') { if (typeof color === "number") {
return run(str, code([48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49)); return run(str, code([48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49));
} }
return run(str, code([48, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 49)); return run(str, code([48, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 49));
@ -588,10 +588,10 @@ export function bgRgb24(str: string, color: number | Rgb): string {
// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js // https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
const ANSI_PATTERN = new RegExp( const ANSI_PATTERN = new RegExp(
[ [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))' "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))",
].join('|'), ].join("|"),
'g' "g",
); );
/** /**
@ -599,7 +599,7 @@ const ANSI_PATTERN = new RegExp(
* @param string to remove ANSI escape codes from * @param string to remove ANSI escape codes from
*/ */
export function stripColor(string: string): string { export function stripColor(string: string): string {
return string.replace(ANSI_PATTERN, ''); return string.replace(ANSI_PATTERN, "");
} }
export function delay<T>(time: number, result?: T) { export function delay<T>(time: number, result?: T) {

View File

@ -1,9 +1,11 @@
import type { Session } from '../index'; import type { GatewayEvents } from "@biscuitland/ws";
import type { GatewayEvents } from '@biscuitland/ws'; import type { Session } from "../index";
export function actionHandler([session, payload, shardId]: Parameters<ActionHandler>) { export function actionHandler([session, payload, shardId]: Parameters<ActionHandler>) {
// @ts-expect-error At this point, typescript sucks // @ts-expect-error At this point, typescript sucks
session.emit(payload.t, payload.d, shardId); session.emit(payload.t, payload.d, shardId);
// @ts-expect-error At this point, typescript sucks
session.emit("RAW", payload.d, shardId);
} }
export type ActionHandler<G extends keyof GatewayEvents = keyof GatewayEvents,> = ( export type ActionHandler<G extends keyof GatewayEvents = keyof GatewayEvents,> = (

View File

@ -1,16 +1,13 @@
import type { import type {
GatewayPresenceUpdateData,
PresenceUpdateStatus,
GatewayActivity,
APIGuildMember,
GatewayRequestGuildMembersDataWithQuery,
GatewayRequestGuildMembersDataWithUserIds,
APIAuditLogEntry, APIAuditLogEntry,
APIAutoModerationRule, APIAutoModerationRule,
APIChannel, APIChannel,
APIGuild, APIGuild,
APIGuildMember,
APIGuildScheduledEvent, APIGuildScheduledEvent,
APIStageInstance, APIStageInstance,
APIUser,
GatewayActivity,
GatewayAutoModerationActionExecutionDispatchData, GatewayAutoModerationActionExecutionDispatchData,
GatewayChannelPinsUpdateDispatchData, GatewayChannelPinsUpdateDispatchData,
GatewayChannelUpdateDispatchData, GatewayChannelUpdateDispatchData,
@ -43,8 +40,11 @@ import type {
GatewayMessageReactionRemoveDispatchData, GatewayMessageReactionRemoveDispatchData,
GatewayMessageReactionRemoveEmojiDispatchData, GatewayMessageReactionRemoveEmojiDispatchData,
GatewayMessageUpdateDispatchData, GatewayMessageUpdateDispatchData,
GatewayPresenceUpdateData,
GatewayPresenceUpdateDispatchData, GatewayPresenceUpdateDispatchData,
GatewayReadyDispatchData, GatewayReadyDispatchData,
GatewayRequestGuildMembersDataWithQuery,
GatewayRequestGuildMembersDataWithUserIds,
GatewayThreadCreateDispatchData, GatewayThreadCreateDispatchData,
GatewayThreadDeleteDispatchData, GatewayThreadDeleteDispatchData,
GatewayThreadListSyncDispatchData, GatewayThreadListSyncDispatchData,
@ -55,9 +55,9 @@ import type {
GatewayVoiceServerUpdateDispatchData, GatewayVoiceServerUpdateDispatchData,
GatewayVoiceStateUpdateData, GatewayVoiceStateUpdateData,
GatewayWebhooksUpdateDispatchData, GatewayWebhooksUpdateDispatchData,
PresenceUpdateStatus,
RestToKeys, RestToKeys,
APIUser } from "@biscuitland/common";
} from '@biscuitland/common';
export enum ShardState { export enum ShardState {
/** Shard is fully connected to the gateway and receiving events from Discord. */ /** Shard is fully connected to the gateway and receiving events from Discord. */
@ -73,7 +73,7 @@ export enum ShardState {
/** Shard is trying to resume a session with the gateway. */ /** Shard is trying to resume a session with the gateway. */
Resuming = 5, Resuming = 5,
/** Shard got shut down studied or due to a not (self) fixable error and may not attempt to reconnect on its own. */ /** Shard got shut down studied or due to a not (self) fixable error and may not attempt to reconnect on its own. */
Offline = 6 Offline = 6,
} }
export enum ShardSocketCloseCodes { export enum ShardSocketCloseCodes {
@ -90,13 +90,13 @@ export enum ShardSocketCloseCodes {
/** Special close code reserved for Discordeno's zero-downtime resharding system. */ /** Special close code reserved for Discordeno's zero-downtime resharding system. */
Resharded = 3065, Resharded = 3065,
/** Shard is re-identifying therefore the old connection needs to be closed. */ /** Shard is re-identifying therefore the old connection needs to be closed. */
ReIdentifying = 3066 ReIdentifying = 3066,
} }
/** https://discord.com/developers/docs/topics/gateway-events#update-presence */ /** https://discord.com/developers/docs/topics/gateway-events#update-presence */
export interface StatusUpdate { export interface StatusUpdate {
/** The user's activities */ /** The user's activities */
activities?: Omit<GatewayActivity, 'created_at'>[]; activities?: Omit<GatewayActivity, "created_at" | "id">[];
/** The user's new status */ /** The user's new status */
status: PresenceUpdateStatus; status: PresenceUpdateStatus;
} }
@ -113,7 +113,7 @@ export interface UpdateVoiceState {
self_deaf: boolean; self_deaf: boolean;
} }
export type ShardStatusUpdate = Pick<GatewayPresenceUpdateData, 'activities' | 'status'>; export type ShardStatusUpdate = Pick<GatewayPresenceUpdateData, "activities" | "status">;
export interface RequestGuildMembersOptions extends GatewayRequestGuildMembersDataWithQuery, GatewayRequestGuildMembersDataWithUserIds {} export interface RequestGuildMembersOptions extends GatewayRequestGuildMembersDataWithQuery, GatewayRequestGuildMembersDataWithUserIds {}
@ -130,7 +130,7 @@ export type AtLeastOne<
T, T,
U = { U = {
[K in keyof T]: Pick<T, K>; [K in keyof T]: Pick<T, K>;
} },
> = Partial<T> & U[keyof U]; > = Partial<T> & U[keyof U];
export type ClientUser = { bot: true } & APIUser; export type ClientUser = { bot: true } & APIUser;
@ -189,7 +189,7 @@ export type StageSameEvents = RestToKeys<
APIStageInstance, APIStageInstance,
GatewayDispatchEvents.StageInstanceCreate, GatewayDispatchEvents.StageInstanceCreate,
GatewayDispatchEvents.StageInstanceUpdate, GatewayDispatchEvents.StageInstanceUpdate,
GatewayDispatchEvents.StageInstanceDelete GatewayDispatchEvents.StageInstanceDelete,
] ]
>; >;
@ -201,7 +201,7 @@ export type GuildScheduledUserSameEvents = RestToKeys<
[ [
GatewayGuildScheduledEventUserRemoveDispatchData, GatewayGuildScheduledEventUserRemoveDispatchData,
GatewayDispatchEvents.GuildScheduledEventUserRemove, GatewayDispatchEvents.GuildScheduledEventUserRemove,
GatewayDispatchEvents.GuildScheduledEventUserAdd GatewayDispatchEvents.GuildScheduledEventUserAdd,
] ]
>; >;
@ -210,7 +210,7 @@ export type GuildScheduledSameEvents = RestToKeys<
APIGuildScheduledEvent, APIGuildScheduledEvent,
GatewayDispatchEvents.GuildScheduledEventCreate, GatewayDispatchEvents.GuildScheduledEventCreate,
GatewayDispatchEvents.GuildScheduledEventDelete, GatewayDispatchEvents.GuildScheduledEventDelete,
GatewayDispatchEvents.GuildScheduledEventUpdate GatewayDispatchEvents.GuildScheduledEventUpdate,
] ]
>; >;
@ -223,7 +223,7 @@ export type AutoModetaractionRuleEvents = RestToKeys<
APIAutoModerationRule, APIAutoModerationRule,
GatewayDispatchEvents.AutoModerationRuleCreate, GatewayDispatchEvents.AutoModerationRuleCreate,
GatewayDispatchEvents.AutoModerationRuleDelete, GatewayDispatchEvents.AutoModerationRuleDelete,
GatewayDispatchEvents.AutoModerationRuleUpdate GatewayDispatchEvents.AutoModerationRuleUpdate,
] ]
>; >;
@ -233,6 +233,6 @@ export type NormalizeEvents = Events &
GuildScheduledSameEvents & GuildScheduledSameEvents &
GuildScheduledUserSameEvents & GuildScheduledUserSameEvents &
IntegrationSameEvents & IntegrationSameEvents &
StageSameEvents; StageSameEvents & { RAW: GatewayDispatchEvents };
export type GatewayEvents = { [x in keyof Events]: Events[x] }; export type GatewayEvents = { [x in keyof NormalizeEvents]: NormalizeEvents[x] };