mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
style: format & lint
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export * from './error-handling';
|
||||
export * from './logging';
|
||||
export * from './module-manager';
|
||||
export * from './module-store'
|
||||
export * from './module-store';
|
||||
export * from './init';
|
||||
|
||||
9
src/core/contracts/init.ts
Normal file
9
src/core/contracts/init.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Awaitable } from '../../shared';
|
||||
|
||||
/**
|
||||
* Represents an initialization contract.
|
||||
* Let dependencies implement this to initiate some logic.
|
||||
*/
|
||||
export interface Init {
|
||||
init() : Awaitable<unknown>
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CommandModule } from "../types/modules";
|
||||
import { CommandModule } from '../types/modules';
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
/**
|
||||
* Represents a core module store that stores IDs mapped to file paths.
|
||||
*/
|
||||
export interface CoreModuleStore {
|
||||
commands : Map<string, string>;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as assert from "assert";
|
||||
import { composeRoot, useContainer } from "./dependency-injection";
|
||||
import { DependencyConfiguration } from "./types";
|
||||
import { CoreContainer } from "../structures/container";
|
||||
import * as assert from 'assert';
|
||||
import { composeRoot, useContainer } from './dependency-injection';
|
||||
import { Dependencies, DependencyConfiguration } from './types';
|
||||
import { CoreContainer } from '../structures/container';
|
||||
|
||||
|
||||
//SIDE EFFECT: GLOBAL DI
|
||||
@@ -28,7 +28,7 @@ export async function makeDependencies<const T extends Dependencies>(
|
||||
) {
|
||||
//Until there are more optional dependencies, just check if the logger exists
|
||||
//SIDE EFFECT
|
||||
containerSubject = new CoreContainer()
|
||||
containerSubject = new CoreContainer();
|
||||
await composeRoot(containerSubject, conf);
|
||||
|
||||
return useContainer<T>();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { DependencyConfiguration, MapDeps, IntoDependencies } from './types';
|
||||
import type { DependencyConfiguration, MapDeps, IntoDependencies, Dependencies, CoreDependencies } from './types';
|
||||
import { DefaultLogging } from '../structures';
|
||||
import { SernError } from '../structures/errors';
|
||||
import { useContainerRaw } from './base';
|
||||
@@ -24,14 +24,14 @@ export function single<T>(cb: () => T) {
|
||||
export function transient<T>(cb: () => () => T) {
|
||||
return cb;
|
||||
}
|
||||
export function Service(key: string) : unknown
|
||||
export function Service<T extends keyof Dependencies>(key: T) {
|
||||
return useContainerRaw().get(key)!
|
||||
|
||||
export function Service<const T extends keyof Dependencies>(key: T) {
|
||||
return useContainerRaw().get(key)!;
|
||||
}
|
||||
|
||||
export function Services<const T extends (keyof Dependencies)[]>(...keys: [...T]) {
|
||||
const container = useContainerRaw();
|
||||
return keys.map(k => container.get(k)!) as IntoDependencies<T>
|
||||
return keys.map(k => container.get(k)!) as IntoDependencies<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,13 +56,13 @@ export async function composeRoot(
|
||||
try {
|
||||
container.get('@sern/client');
|
||||
} catch {
|
||||
throw new Error(SernError.MissingRequired + " No client was provided")
|
||||
throw new Error(SernError.MissingRequired + ' No client was provided');
|
||||
}
|
||||
|
||||
if (!hasLogger) {
|
||||
container.get('@sern/logger')?.info({ message: 'All dependencies loaded successfully.' });
|
||||
}
|
||||
|
||||
|
||||
container.ready();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { useContainerRaw, makeDependencies } from './base';
|
||||
export { Service, Services, single, transient } from './dependency-injection';
|
||||
export type { Singleton, Transient } from './types'
|
||||
export type { Singleton, Transient } from './types';
|
||||
|
||||
16
src/core/ioc/ioc.d.ts
vendored
16
src/core/ioc/ioc.d.ts
vendored
@@ -1,16 +0,0 @@
|
||||
|
||||
type Singleton<T> = () => T;
|
||||
type Transient<T> = () => () => T;
|
||||
|
||||
interface CoreDependencies {
|
||||
'@sern/logger'?: Singleton<import('../contracts/logging').Logging>;
|
||||
'@sern/emitter': Singleton<import('../structures/sern-emitter').SernEmitter>;
|
||||
'@sern/store': Singleton<import('../contracts/module-store').CoreModuleStore>;
|
||||
'@sern/modules': Singleton<import('../contracts/module-manager').ModuleManager>;
|
||||
'@sern/errors': Singleton<import('../contracts/error-handling').ErrorHandling>;
|
||||
}
|
||||
|
||||
interface Dependencies extends CoreDependencies {
|
||||
'@sern/client': Singleton<import('node:events').EventEmitter>;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import { Container, UnpackFunction } from "iti";
|
||||
|
||||
import { Container, UnpackFunction } from 'iti';
|
||||
import * as Contract from '../contracts';
|
||||
export type Singleton<T> = () => T;
|
||||
export type Transient<T> = () => () => T;
|
||||
|
||||
|
||||
export interface CoreDependencies {
|
||||
'@sern/logger'?: Singleton<Contract.Logging>;
|
||||
'@sern/emitter': Singleton<import('../structures/sern-emitter').SernEmitter>;
|
||||
'@sern/store': Singleton<Contract.CoreModuleStore>;
|
||||
'@sern/modules': Singleton<Contract.ModuleManager>;
|
||||
'@sern/errors': Singleton<Contract.ErrorHandling>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface Dependencies extends CoreDependencies {
|
||||
'@sern/client': Singleton<import('node:events').EventEmitter>;
|
||||
}
|
||||
export type DependencyFromKey<T extends keyof Dependencies> = Dependencies[T];
|
||||
|
||||
export type IntoDependencies<Tuple extends [...any[]]> = {
|
||||
@@ -31,4 +39,3 @@ export type MapDeps<Deps extends Dependencies, T extends readonly unknown[]> = T
|
||||
]
|
||||
: [never];
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { type Observable, from, mergeMap, ObservableInput } from 'rxjs';
|
||||
import { readdir, stat } from 'fs/promises';
|
||||
import { basename, join, resolve } from 'path';
|
||||
import { ImportPayload } from '../handler/types';
|
||||
import * as assert from 'node:assert'
|
||||
import * as assert from 'node:assert';
|
||||
import { sernMeta } from '../handler/commands';
|
||||
export type ModuleResult<T> = Promise<Result<ImportPayload<T>, SernError>>;
|
||||
|
||||
@@ -21,8 +21,8 @@ export async function defaultModuleLoader<T extends Module>(absPath: string): Mo
|
||||
if (module === undefined) {
|
||||
return Err(SernError.UndefinedModule);
|
||||
}
|
||||
|
||||
assert.ok(module.type > 0 && module.type < 1<<10, "Found a module that does not have a valid type");
|
||||
//todo readd class modules
|
||||
assert.ok(module.type > 0 && module.type < 1<<10, 'Found a module that does not have a valid type');
|
||||
assert.ok(module[sernMeta], "Found a module that isn't marked with sernMeta");
|
||||
|
||||
return Ok({ module, absPath });
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
import { Result } from 'ts-results-es';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { ErrorHandling, Logging } from './contracts';
|
||||
import util from 'node:util'
|
||||
import util from 'node:util';
|
||||
import { Awaitable } from '../shared';
|
||||
import { PluginResult, VoidResult } from './types/plugins';
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Container } from "iti";
|
||||
import { DefaultErrorHandling, DefaultModuleManager, SernEmitter } from "../";
|
||||
import { isAsyncFunction} from "node:util/types";
|
||||
import * as assert from 'node:assert'
|
||||
import { Subject } from "rxjs";
|
||||
import { ModuleStore } from "./module-store";
|
||||
import { Dependencies } from "../ioc/types";
|
||||
import { Container } from 'iti';
|
||||
import { DefaultErrorHandling, DefaultModuleManager, SernEmitter } from '../';
|
||||
import { isAsyncFunction} from 'node:util/types';
|
||||
import * as assert from 'node:assert';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ModuleStore } from './module-store';
|
||||
import { Dependencies } from '../ioc/types';
|
||||
|
||||
/**
|
||||
* Provides all the defaults for sern to function properly.
|
||||
@@ -23,13 +23,13 @@ export class CoreContainer<T extends Partial<Dependencies>> extends Container<T,
|
||||
'@sern/emitter': () => new SernEmitter(),
|
||||
'@sern/store': () => new ModuleStore(),
|
||||
}).add(ctx => {
|
||||
return { '@sern/modules': () => new DefaultModuleManager(ctx["@sern/store"]) };
|
||||
})
|
||||
return { '@sern/modules': () => new DefaultModuleManager(ctx['@sern/store']) };
|
||||
});
|
||||
}
|
||||
|
||||
private listenForInsertions() {
|
||||
assert.notEqual(this.isReady(), "listening for init functions should only occur prior to sern being ready.");
|
||||
const unsubscriber = this.on('containerUpserted', e => this.callInitHooks(e));
|
||||
assert.ok(!this.isReady(), 'listening for init functions should only occur prior to sern being ready.');
|
||||
const unsubscriber = this.on('containerUpserted', this.callInitHooks);
|
||||
|
||||
this.ready$.subscribe({
|
||||
complete: unsubscriber
|
||||
|
||||
@@ -19,6 +19,9 @@ import { ReplyOptions } from '../../shared';
|
||||
* Message and ChatInputCommandInteraction
|
||||
*/
|
||||
export class Context extends CoreContext<Message, ChatInputCommandInteraction> {
|
||||
/*
|
||||
* @Experimental
|
||||
*/
|
||||
get options() {
|
||||
return this.interaction.options;
|
||||
}
|
||||
@@ -81,7 +84,7 @@ export class Context extends CoreContext<Message, ChatInputCommandInteraction> {
|
||||
if ('interaction' in wrappable) {
|
||||
return new Context(Ok(wrappable));
|
||||
}
|
||||
assert.ok(wrappable.isChatInputCommand())
|
||||
assert.ok(wrappable.isChatInputCommand());
|
||||
return new Context(Err(wrappable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from './enums';
|
||||
export * from './context';
|
||||
export * from './sern-emitter';
|
||||
export * from './services'
|
||||
export * from './module-store'
|
||||
export * from './services';
|
||||
export * from './module-store';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CoreModuleStore } from "../contracts";
|
||||
import { CoreModuleStore } from '../contracts';
|
||||
|
||||
/*
|
||||
* @internal
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Module } from '../types/modules';
|
||||
export class SernEmitter extends EventEmitter {
|
||||
|
||||
constructor() {
|
||||
super({ captureRejections: true })
|
||||
super({ captureRejections: true });
|
||||
}
|
||||
/**
|
||||
* Listening to sern events with on. This event stays on until a crash or a normal exit
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ErrorHandling } from "../../contracts";
|
||||
import { ErrorHandling } from '../../contracts';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LogPayload, Logging } from "../../contracts";
|
||||
import { LogPayload, Logging } from '../../contracts';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CoreModuleStore, ModuleManager } from "../../contracts";
|
||||
import { importModule } from "../../module-loading";
|
||||
import { CommandModule } from "../../types/modules";
|
||||
import { CoreModuleStore, ModuleManager } from '../../contracts';
|
||||
import { importModule } from '../../module-loading';
|
||||
import { CommandModule } from '../../types/modules';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
||||
@@ -5,8 +5,8 @@ import { CommandModule, EventModule, InputCommand, InputEvent } from '../core/ty
|
||||
import { partition } from '../core/functions';
|
||||
import { Awaitable } from '../shared';
|
||||
export const sernMeta = Symbol('@sern/meta');
|
||||
export const UNREGISTERED = "meow meow meow";
|
||||
export const EMPTY_PATH = "purr purr purr";
|
||||
export const UNREGISTERED = 'meow meow meow';
|
||||
export const EMPTY_PATH = 'purr purr purr';
|
||||
/**
|
||||
* @since 1.0.0 The wrapper function to define command modules for sern
|
||||
* @param mod
|
||||
|
||||
@@ -29,7 +29,7 @@ export function dispatchMessage(module: Processed<CommandModule>, args: [Context
|
||||
return {
|
||||
module,
|
||||
args
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function dispatchAutocomplete(payload: { module: Processed<BothCommand>, event: AutocompleteInteraction }) {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import {
|
||||
Interaction,
|
||||
InteractionType,
|
||||
Message,
|
||||
} from 'discord.js';
|
||||
import { EMPTY, Observable, concatMap, filter, from, of, throwError, tap, MonoTypeOperatorFunction } from 'rxjs';
|
||||
import { CommandType, EventType, ModuleManager } from '../../core';
|
||||
import { ModuleManager } from '../../core';
|
||||
import { SernError } from '../../core/structures/errors';
|
||||
import { callPlugin, everyPluginOk, filterMap, filterMapTo } from '../../core/operators';
|
||||
import { defaultModuleLoader } from '../../core/module-loading';
|
||||
@@ -66,8 +65,8 @@ export function createMessageHandler(
|
||||
return defaultModuleLoader<Processed<CommandModule>>(fullPath)
|
||||
.then(result => {
|
||||
const args = contextArgs(event, rest);
|
||||
return result.map(payload => dispatchMessage(payload.module, args))
|
||||
})
|
||||
return result.map(payload => dispatchMessage(payload.module, args));
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -78,11 +77,11 @@ function assignDefaults<T extends Module>(): MonoTypeOperatorFunction<ImportPayl
|
||||
return tap(
|
||||
({ module, absPath }) => {
|
||||
module.name ??= Files.filename(absPath);
|
||||
module.description ??= "...";
|
||||
module.description ??= '...';
|
||||
module[sernMeta].fullPath = absPath;
|
||||
module[sernMeta].id = `${module.name}_${uniqueId(module.type)}`
|
||||
module[sernMeta].id = `${module.name}_${uniqueId(module.type)}`;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function buildModules<T extends AnyModule>(
|
||||
|
||||
@@ -25,7 +25,7 @@ export function makeMessageHandler(
|
||||
defaultPrefix: string | undefined,
|
||||
) {
|
||||
if (!defaultPrefix) {
|
||||
log?.debug({ message: 'No prefix found. message handler shut down' });
|
||||
log?.debug({ message: 'No prefix found. message handler shutting down' });
|
||||
return EMPTY;
|
||||
}
|
||||
const messageStream$ = sharedObservable<Message>(client, 'messageCreate');
|
||||
|
||||
@@ -8,6 +8,7 @@ import { buildModules, callInitPlugins } from './generic';
|
||||
import { handleError } from '../../core/operators';
|
||||
import { Service, useContainerRaw } from '../../core/ioc';
|
||||
import { DependencyList, Processed } from '../types';
|
||||
import { Dependencies } from '../../core/ioc/types';
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +25,7 @@ export function makeEventsHandler(
|
||||
case EventType.Discord:
|
||||
return eventDispatcher(e, client);
|
||||
case EventType.External:
|
||||
return eventDispatcher(e, Service(e.emitter));
|
||||
return eventDispatcher(e, Service(e.emitter as keyof Dependencies));
|
||||
default:
|
||||
return err.crash(
|
||||
Error(SernError.InvalidModuleType + ' while creating event handler'),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Interaction, InteractionType } from "discord.js";
|
||||
import { CommandType, EventType } from "../core";
|
||||
import { Interaction, InteractionType } from 'discord.js';
|
||||
import { CommandType, EventType } from '../core';
|
||||
|
||||
/**
|
||||
* Creates a unique ID for a given interaction object.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ErrorHandling, Logging, ModuleManager, SernEmitter } from "../core";
|
||||
import EventEmitter from "node:events";
|
||||
import { Module } from "../core/types/modules";
|
||||
import { ErrorHandling, Logging, ModuleManager, SernEmitter } from '../core';
|
||||
import EventEmitter from 'node:events';
|
||||
import { Module } from '../core/types/modules';
|
||||
|
||||
export type Processed<T> = T & { name: string; description: string };
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export * as Sern from './handler/sern';
|
||||
export * from './core';
|
||||
export { commandModule, eventModule, discordEvent } from './handler/commands'
|
||||
export { commandModule, eventModule, discordEvent } from './handler/commands';
|
||||
export { controller } from './handler/sern';
|
||||
export type { Wrapper, Args } from './shared'
|
||||
export type { Wrapper, Args } from './shared';
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
} from 'discord.js';
|
||||
import { PayloadType } from './core';
|
||||
import { AnyModule } from './core/types/modules';
|
||||
import { Dependencies } from './core/ioc/types';
|
||||
|
||||
export type ReplyOptions =
|
||||
| string
|
||||
|
||||
@@ -54,9 +54,9 @@ export default defineConfig([
|
||||
},
|
||||
{
|
||||
dts: {
|
||||
only: true,
|
||||
entry: 'src/index.ts'
|
||||
only: true
|
||||
},
|
||||
entry: ['src/index.ts'],
|
||||
outDir: 'dist'
|
||||
}
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user