Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.github/
*.md
*.md
dist/
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<div align="center">
<img src="https://raw.githubusercontent.com/sern-handler/.github/main/banner.png" width="900px">
<img src="https://raw.githubusercontent.com/sern-handler/.github/main/banner.png" width="900px" />
</div>

<h1 align="center">Handlers. Redefined.</h1>
<h4 align="center">A customizable, batteries-included, powerful discord.js framework to streamline bot development.</h4>

<div align="center" style="margin-top: 10px">
<img src="https://img.shields.io/badge/open-source-brightgreen">
<div align="center" styles="margin-top: 10px">
<img src="https://img.shields.io/badge/open-source-brightgreen" />
<a href="https://www.npmjs.com/package/@sern/handler"><img src="https://img.shields.io/npm/v/@sern/handler?maxAge=3600" alt="NPM version" /></a>
<a href="https://www.npmjs.com/package/@sern/handler"><img src="https://img.shields.io/npm/dt/@sern/handler?maxAge=3600" alt="NPM downloads" /></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen" alt="License MIT"></a>
<a href="https://sern-handler.js.org"><img alt="docs.rs" src="https://img.shields.io/docsrs/docs"></a>
<img alt="Lines of code" src="https://img.shields.io/badge/total%20lines-2k-blue">
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen" alt="License MIT" /></a>
<a href="https://sern-handler.js.org"><img alt="docs.rs" src="https://img.shields.io/docsrs/docs" /></a>
<img alt="Lines of code" src="https://img.shields.io/badge/total%20lines-2k-blue" />
</div>


Expand Down
302 changes: 205 additions & 97 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sern/handler",
"version": "1.1.0",
"version": "1.2.0",
"description": "A customizable, batteries-included, powerful discord.js framework to automate and streamline bot development.",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand Down Expand Up @@ -41,10 +41,10 @@
"eslint": "8.22.0",
"prettier": "2.7.1",
"tsup": "^6.1.3",
"typescript": "4.7.4"
"typescript": "^4.8.3"
},
"peerDependencies": {
"discord.js": "^14.2.x"
"discord.js": "^14.5.x"
},
"repository": {
"type": "git",
Expand Down
25 changes: 22 additions & 3 deletions src/handler/sern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import { Err, Ok } from 'ts-results-es';
import { ExternalEventEmitters } from './utilities/readFile';
import type { EventEmitter } from 'events';
import { processEvents } from './events/userDefinedEventsHandling';
import type { CommandModule, EventModule } from './structures/module';
import { EventType, PluginType } from './structures/enums';
import type {
CommandModule,
CommandModuleDefs,
EventModule,
EventModuleDefs,
} from './structures/module';
import { CommandType, EventType, PluginType } from './structures/enums';
import type {
CommandPlugin,
EventModuleCommandPluginDefs,
Expand Down Expand Up @@ -42,7 +47,7 @@ export function init(wrapper: Wrapper) {
}

/**
*
* @deprecated - use Sern#makeDependencies instead
* @param emitter Any external event emitter.
* The object will be stored in a map, and then fetched by the name of the instance's class.
* As there are infinite possibilities to adding external event emitters,
Expand Down Expand Up @@ -119,3 +124,17 @@ export function eventModule(mod: InputEventModule): EventModule {
plugins,
} as EventModule;
}

export abstract class CommandExecutable<Type extends CommandType> {
abstract type: Type;
plugins: CommandPlugin<Type>[] = [];
onEvent: EventPlugin<Type>[] = [];
abstract execute: CommandModuleDefs[Type]['execute'];
}

export abstract class EventExecutable<Type extends EventType> {
abstract type: Type;
plugins: EventModuleCommandPluginDefs[Type][] = [];
onEvent: EventModuleEventPluginDefs[Type][] = [];
abstract execute: EventModuleDefs[Type]['execute'];
}
10 changes: 4 additions & 6 deletions src/handler/structures/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import type {
GuildMember,
InteractionReplyOptions,
Message,
ReplyMessageOptions,
Snowflake,
TextBasedChannel,
MessageReplyOptions,
User,
} from 'discord.js';
import { type Option, None, Some } from 'ts-results-es';
import type { Nullish } from '../../types/handler';
import type { Nullish, ReplyOptions } from '../../types/handler';
import { SernError } from './errors';

function firstSome<T>(...args: Option<T>[]): Nullish<T> {
Expand Down Expand Up @@ -130,17 +130,15 @@ export default class Context {
return this.oMsg.none && this.oInterac.none;
}
//Make queueable
public reply(
content: string | Omit<InteractionReplyOptions, 'fetchReply'> | ReplyMessageOptions,
) {
public reply(content: ReplyOptions) {
return firstSome(
this.oInterac.map(i => {
return i
.reply(content as string | InteractionReplyOptions)
.then(() => i.fetchReply());
}),
this.oMsg.map(m => {
return m.reply(content as string | ReplyMessageOptions);
return m.reply(content as string | MessageReplyOptions);
Comment thread
jacoobes marked this conversation as resolved.
}),
)!;
}
Expand Down
4 changes: 4 additions & 0 deletions src/handler/structures/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import type { EventModule } from './module';
* @typedef {object} Wrapper
*/
interface Wrapper {
//@deprecated - Use Sern#makeDependencies instead
readonly client: Client;
//@deprecated - Use Sern#makeDependencies instead
readonly sernEmitter?: SernEmitter;
readonly defaultPrefix?: string;
readonly commands: string;
readonly events?:
| string
//@deprecated - array and function options will be removed
| { mod: EventModule; absPath: string }[]
//@deprecated - array and function options will be removed
| (() => { mod: EventModule; absPath: string }[]);
}

Expand Down
10 changes: 7 additions & 3 deletions src/handler/utilities/readFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ export function buildData<T>(commandDir: string): Observable<
} catch {
mod = (await import(`file:///` + absPath)).default;
}
if (mod !== undefined) {
return Ok({ mod, absPath });
} else return Err(SernError.UndefinedModule);
if (mod === undefined) {
return Err(SernError.UndefinedModule);
}
try {
mod = new (mod as unknown as new () => T)();
} catch {}
return Ok({ mod, absPath });
}),
),
).pipe(concatAll());
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SernEmitter from './handler/sernEmitter';
export { eventModule, commandModule } from './handler/sern';
export { eventModule, commandModule, EventExecutable, CommandExecutable } from './handler/sern';
export * as Sern from './handler/sern';
export * from './types/handler';
export * from './handler/structures/structxports';
Expand Down
12 changes: 6 additions & 6 deletions src/types/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { CommandInteractionOptionResolver } from 'discord.js';
import type { CommandModule, EventModule, Module } from '../handler/structures/module';
import type { PayloadType } from '../handler/structures/enums';
import type { InteractionReplyOptions, MessageReplyOptions } from 'discord.js';
export type Nullish<T> = T | undefined | null;

// Thanks to @kelsny
Expand All @@ -26,12 +27,6 @@ export type EventInput =
| { mod: EventModule; absPath: string }[]
| (() => { mod: EventModule; absPath: string }[]);

export type Reconstruct<T> = T extends Omit<infer O, never> ? O & Reconstruct<O> : T;

export type IsOptional<T> = {
[K in keyof T]-?: T[K] extends Required<T>[K] ? false : true;
};

/**
* Turns a function with a union of array of args into a single union
* [ T , V , B ] | [ A ] => T | V | B | A
Expand All @@ -56,3 +51,8 @@ export type SernEventsMapping = {
['error']: [Payload];
['warning']: [string];
};

export type ReplyOptions =
| string
| Omit<InteractionReplyOptions, 'fetchReply'>
| MessageReplyOptions;