feat: smart types context.metadata

This commit is contained in:
MARCROCK22 2024-03-25 19:19:13 -04:00
parent 9c9e421217
commit 0ab003f8d6
4 changed files with 36 additions and 17 deletions

View File

@ -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<any> = 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;

View File

@ -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<any> = 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;

View File

@ -1,9 +1,10 @@
import type { BaseClient } from '../../client/base';
import type { IsStrictlyUndefined } from '../../common';
import type { RegisteredMiddlewares } from '../decorators';
export type OKFunction<T> = (value: T) => void;
export type StopFunction = (error: string) => void;
export type NextFunction<T = unknown> = (data: T) => void;
export type NextFunction<T = unknown> = IsStrictlyUndefined<T> 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<T = any, C = any> = (context: {
stop: StopFunction;
pass: PassFunction;
}) => any;
export type MetadataMiddleware<T extends MiddlewareContext> = Parameters<Parameters<T>[0]['next']>[0];
export type MetadataMiddleware<T extends MiddlewareContext> = IsStrictlyUndefined<
Parameters<Parameters<T>[0]['next']>[0]
> extends true
? never
: Parameters<Parameters<T>[0]['next']>[0];
export type CommandMetadata<T extends readonly (keyof RegisteredMiddlewares)[]> = T extends readonly [
infer first,
...infer rest,
]
? first extends keyof RegisteredMiddlewares
? {
[key in first]: MetadataMiddleware<RegisteredMiddlewares[first]>;
} & (rest extends readonly (keyof RegisteredMiddlewares)[] ? CommandMetadata<rest> : {})
? (MetadataMiddleware<RegisteredMiddlewares[first]> extends never
? {}
: {
[key in first]: MetadataMiddleware<RegisteredMiddlewares[first]>;
}) &
(rest extends readonly (keyof RegisteredMiddlewares)[] ? CommandMetadata<rest> : {})
: {}
: {};

View File

@ -69,6 +69,14 @@ export type TypeArray<T> = T | T[];
export type When<T extends boolean, A, B = never> = T extends true ? A : B;
export type AuxIsStrictlyUndefined<T> = T extends undefined | null | never | void ? true : false;
export type IsStrictlyUndefined<T> = AuxIsStrictlyUndefined<T> extends true
? true
: AuxIsStrictlyUndefined<T> extends false
? false
: false;
export type If<T extends boolean, A, B = null> = T extends true ? A : B extends null ? A | null : B;
export type PickPartial<T, K extends keyof T> = {