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 { CommandContext } from './chatcontext';
import type { import type {
DefaultLocale, DefaultLocale,
NextFunction,
OKFunction, OKFunction,
OnOptionsReturnObject, OnOptionsReturnObject,
PassFunction, PassFunction,
@ -200,19 +199,21 @@ class BaseCommand {
running = false; running = false;
return res({ pass: true }); return res({ pass: true });
}; };
const next: NextFunction<any> = obj => { function next(obj: any) {
if (!running) { if (!running) {
return; return;
} }
context[global ? 'globalMetadata' : 'metadata'] ??= {}; // biome-ignore lint/style/noArguments: yes
if (arguments.length) {
// @ts-expect-error // @ts-expect-error
context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj;
}
if (++index >= middlewares.length) { if (++index >= middlewares.length) {
running = false; running = false;
return res({}); return res({});
} }
context.client.middlewares![middlewares[index]]({ context, next, stop, pass }); context.client.middlewares![middlewares[index]]({ context, next, stop, pass });
}; }
const stop: StopFunction = err => { const stop: StopFunction = err => {
if (!running) { if (!running) {
return; return;

View File

@ -1,7 +1,7 @@
import { magicImport, type ApplicationCommandType, type LocaleString, type PermissionStrings } from '../../common'; import { magicImport, type ApplicationCommandType, type LocaleString, type PermissionStrings } from '../../common';
import type { IntegrationTypes, InteractionContextTypes, RegisteredMiddlewares } from '../decorators'; import type { IntegrationTypes, InteractionContextTypes, RegisteredMiddlewares } from '../decorators';
import type { MenuCommandContext } from './menucontext'; import type { MenuCommandContext } from './menucontext';
import type { NextFunction, PassFunction, StopFunction, UsingClient } from './shared'; import type { PassFunction, StopFunction, UsingClient } from './shared';
export abstract class ContextMenuCommand { export abstract class ContextMenuCommand {
middlewares: (keyof RegisteredMiddlewares)[] = []; middlewares: (keyof RegisteredMiddlewares)[] = [];
@ -42,19 +42,21 @@ export abstract class ContextMenuCommand {
running = false; running = false;
return res({ pass: true }); return res({ pass: true });
}; };
const next: NextFunction<any> = obj => { function next(obj: any) {
if (!running) { if (!running) {
return; return;
} }
context[global ? 'globalMetadata' : 'metadata'] ??= {}; // biome-ignore lint/style/noArguments: yes
if (arguments.length) {
// @ts-expect-error // @ts-expect-error
context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj; context[global ? 'globalMetadata' : 'metadata'][middlewares[index]] = obj;
}
if (++index >= middlewares.length) { if (++index >= middlewares.length) {
running = false; running = false;
return res({}); return res({});
} }
context.client.middlewares![middlewares[index]]({ context, next, stop, pass }); context.client.middlewares![middlewares[index]]({ context, next, stop, pass });
}; }
const stop: StopFunction = err => { const stop: StopFunction = err => {
if (!running) { if (!running) {
return; return;

View File

@ -1,9 +1,10 @@
import type { BaseClient } from '../../client/base'; import type { BaseClient } from '../../client/base';
import type { IsStrictlyUndefined } from '../../common';
import type { RegisteredMiddlewares } from '../decorators'; import type { RegisteredMiddlewares } from '../decorators';
export type OKFunction<T> = (value: T) => void; export type OKFunction<T> = (value: T) => void;
export type StopFunction = (error: string) => 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 PassFunction = () => void;
export type InferWithPrefix = InternalOptions extends { withPrefix: infer P } ? P : false; export type InferWithPrefix = InternalOptions extends { withPrefix: infer P } ? P : false;
@ -21,15 +22,22 @@ export type MiddlewareContext<T = any, C = any> = (context: {
stop: StopFunction; stop: StopFunction;
pass: PassFunction; pass: PassFunction;
}) => any; }) => 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 [ export type CommandMetadata<T extends readonly (keyof RegisteredMiddlewares)[]> = T extends readonly [
infer first, infer first,
...infer rest, ...infer rest,
] ]
? first extends keyof RegisteredMiddlewares ? first extends keyof RegisteredMiddlewares
? { ? (MetadataMiddleware<RegisteredMiddlewares[first]> extends never
? {}
: {
[key in first]: MetadataMiddleware<RegisteredMiddlewares[first]>; [key in first]: MetadataMiddleware<RegisteredMiddlewares[first]>;
} & (rest extends readonly (keyof RegisteredMiddlewares)[] ? CommandMetadata<rest> : {}) }) &
(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 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 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> = { export type PickPartial<T, K extends keyof T> = {