From 0ab003f8d63ee5a5d01d042ce66235f0daa49e0f Mon Sep 17 00:00:00 2001 From: MARCROCK22 <57925328+MARCROCK22@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:19:13 -0400 Subject: [PATCH] feat: smart types context.metadata --- src/commands/applications/chat.ts | 13 +++++++------ src/commands/applications/menu.ts | 14 ++++++++------ src/commands/applications/shared.ts | 18 +++++++++++++----- src/common/types/util.ts | 8 ++++++++ 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/commands/applications/chat.ts b/src/commands/applications/chat.ts index 816ebf6..1224928 100644 --- a/src/commands/applications/chat.ts +++ b/src/commands/applications/chat.ts @@ -15,7 +15,6 @@ import type { OptionResolver } from '../optionresolver'; import type { CommandContext } from './chatcontext'; import type { DefaultLocale, - NextFunction, OKFunction, OnOptionsReturnObject, PassFunction, @@ -200,19 +199,21 @@ class BaseCommand { running = false; return res({ pass: true }); }; - const next: NextFunction = obj => { + function next(obj: any) { if (!running) { return; } - context[global ? 'globalMetadata' : 'metadata'] ??= {}; - // @ts-expect-error - context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; + // biome-ignore lint/style/noArguments: yes + if (arguments.length) { + // @ts-expect-error + context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; + } if (++index >= middlewares.length) { running = false; return res({}); } context.client.middlewares![middlewares[index]]({ context, next, stop, pass }); - }; + } const stop: StopFunction = err => { if (!running) { return; diff --git a/src/commands/applications/menu.ts b/src/commands/applications/menu.ts index 442a169..99d9c53 100644 --- a/src/commands/applications/menu.ts +++ b/src/commands/applications/menu.ts @@ -1,7 +1,7 @@ import { magicImport, type ApplicationCommandType, type LocaleString, type PermissionStrings } from '../../common'; import type { IntegrationTypes, InteractionContextTypes, RegisteredMiddlewares } from '../decorators'; import type { MenuCommandContext } from './menucontext'; -import type { NextFunction, PassFunction, StopFunction, UsingClient } from './shared'; +import type { PassFunction, StopFunction, UsingClient } from './shared'; export abstract class ContextMenuCommand { middlewares: (keyof RegisteredMiddlewares)[] = []; @@ -42,19 +42,21 @@ export abstract class ContextMenuCommand { running = false; return res({ pass: true }); }; - const next: NextFunction = obj => { + function next(obj: any) { if (!running) { return; } - context[global ? 'globalMetadata' : 'metadata'] ??= {}; - // @ts-expect-error - context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; + // biome-ignore lint/style/noArguments: yes + if (arguments.length) { + // @ts-expect-error + context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; + } if (++index >= middlewares.length) { running = false; return res({}); } context.client.middlewares![middlewares[index]]({ context, next, stop, pass }); - }; + } const stop: StopFunction = err => { if (!running) { return; diff --git a/src/commands/applications/shared.ts b/src/commands/applications/shared.ts index 02169ef..298ce36 100644 --- a/src/commands/applications/shared.ts +++ b/src/commands/applications/shared.ts @@ -1,9 +1,10 @@ import type { BaseClient } from '../../client/base'; +import type { IsStrictlyUndefined } from '../../common'; import type { RegisteredMiddlewares } from '../decorators'; export type OKFunction = (value: T) => void; export type StopFunction = (error: string) => void; -export type NextFunction = (data: T) => void; +export type NextFunction = IsStrictlyUndefined extends true ? () => void : (data: T) => void; export type PassFunction = () => void; export type InferWithPrefix = InternalOptions extends { withPrefix: infer P } ? P : false; @@ -21,15 +22,22 @@ export type MiddlewareContext = (context: { stop: StopFunction; pass: PassFunction; }) => any; -export type MetadataMiddleware = Parameters[0]['next']>[0]; +export type MetadataMiddleware = IsStrictlyUndefined< + Parameters[0]['next']>[0] +> extends true + ? never + : Parameters[0]['next']>[0]; export type CommandMetadata = T extends readonly [ infer first, ...infer rest, ] ? first extends keyof RegisteredMiddlewares - ? { - [key in first]: MetadataMiddleware; - } & (rest extends readonly (keyof RegisteredMiddlewares)[] ? CommandMetadata : {}) + ? (MetadataMiddleware extends never + ? {} + : { + [key in first]: MetadataMiddleware; + }) & + (rest extends readonly (keyof RegisteredMiddlewares)[] ? CommandMetadata : {}) : {} : {}; diff --git a/src/common/types/util.ts b/src/common/types/util.ts index 77a352d..edace6b 100644 --- a/src/common/types/util.ts +++ b/src/common/types/util.ts @@ -69,6 +69,14 @@ export type TypeArray = T | T[]; export type When = T extends true ? A : B; +export type AuxIsStrictlyUndefined = T extends undefined | null | never | void ? true : false; + +export type IsStrictlyUndefined = AuxIsStrictlyUndefined extends true + ? true + : AuxIsStrictlyUndefined extends false + ? false + : false; + export type If = T extends true ? A : B extends null ? A | null : B; export type PickPartial = {