documentation, add json for Asset

This commit is contained in:
Jacob Nguyen
2024-06-11 00:27:36 -05:00
parent 67bb4d4b9f
commit 222ecd9b61
9 changed files with 58 additions and 36 deletions

View File

@@ -1,7 +1,7 @@
import { ApplicationCommandType, ComponentType, type Interaction, InteractionType } from 'discord.js';
import { CommandType, EventType } from './structures/enums';
const parseParams = (event: { customId: string }, id: string, append: string) => {
const parseParams = (event: { customId: string }, append: string) => {
const hasSlash = event.customId.indexOf('/')
if(hasSlash === -1) {
return { id:event.customId+append };
@@ -18,7 +18,7 @@ const parseParams = (event: { customId: string }, id: string, append: string) =>
export function reconstruct<T extends Interaction>(event: T) {
switch (event.type) {
case InteractionType.MessageComponent: {
const data = parseParams(event, event.customId, `_C${event.componentType}`)
const data = parseParams(event, `_C${event.componentType}`)
return [data];
}
case InteractionType.ApplicationCommand:
@@ -26,7 +26,7 @@ export function reconstruct<T extends Interaction>(event: T) {
return [{ id: `${event.commandName}_A${event.commandType}` }, { id: `${event.commandName}_B` }];
//Modal interactions are classified as components for sern
case InteractionType.ModalSubmit: {
const data = parseParams(event, event.customId, '_M');
const data = parseParams(event, '_M');
return [data];
}
}

View File

@@ -48,7 +48,16 @@ const dependencyBuilder = (container: Container) => {
type ValidDependencyConfig =
| ((c: ReturnType<typeof dependencyBuilder>) => any)
/**
* makeDependencies constructs a dependency injection container for sern handler to use.
* This is required to start the handler, and is to be called before Sern.init.
* @example
* ```ts
* await makeDependencies(({ add }) => {
* add('@sern/client', new Client({ intents, partials })
* })
* ```
*/
export async function makeDependencies (conf: ValidDependencyConfig) {
const container = await __init_container({ autowire: false });
//We only include logger if it does not exist

View File

@@ -33,7 +33,10 @@ export function Services<const T extends (keyof Dependencies)[]>(...keys: [...T]
* Creates a singleton object.
* @param cb
*/
export function single<T>(cb: () => T) { return cb(); }
export function single<T>(cb: () => T) {
console.log('The `single` function is deprecated and has no effect')
return cb();
}
/**
* @deprecated
@@ -41,5 +44,8 @@ export function single<T>(cb: () => T) { return cb(); }
* Creates a transient object
* @param cb
*/
export function transient<T>(cb: () => () => T) { return cb()(); }
export function transient<T>(cb: () => () => T) {
console.log('The `transient` function is deprecated and has no effect')
return cb()();
}

View File

@@ -27,7 +27,9 @@ export function commandModule(mod: InputCommand): Module {
* @param mod
*/
export function eventModule(mod: InputEvent): Module {
return mod as Module;
const [onEvent, plugins] = partitionPlugins(mod.plugins);
if(onEvent.length !== 0) throw Error("Event modules cannot have ControlPlugins");
return { ...mod, plugins } as Module;
}
/** Create event modules from discord.js client events,

View File

@@ -31,27 +31,26 @@ export const Presence = {
/**
* @example
* Presence
* .of({
* activities: [{ name: "deez nuts" }]
* }) //starts the presence with "deez nuts".
* .of({ activities: [{ name: "deez nuts" }] }) //starts presence with "deez nuts".
* .repeated(prev => {
* return {
* afk: true,
* activities: prev.activities?.map(s => ({ ...s, name: s.name+"s" }))
* };
* }, 10000)) //every 10 s, the callback sets the presence to the returned one.
* }, 10000)) //every 10 s, the callback sets the presence to the value returned.
*/
repeated: (onRepeat: PresenceReduce, repeat: number | [Emitter, string]) => {
return { repeat, onRepeat, ...root }
},
/**
* @example
* ```ts
* Presence.of({
* activities: [
* { name: "Chilling out" }
* ]
* })
* .once() // Sets the presence once, with what's provided in '.of()'
* }).once() // Sets the presence once, with what's provided in '.of()'
* ```
*/
once: () => root
};

View File

@@ -3,6 +3,7 @@ import path from 'node:path'
export * as Sern from './sern';
export type {
Module,
CommandModule,
EventModule,
BothCommand,
@@ -57,18 +58,17 @@ export { CommandType, PluginType, PayloadType, EventType } from './core/structur
export { Context } from './core/structures/context';
export * from './core/ioc';
export type AssetEncoding = "attachment"|"base64"|"binary"|"utf8"
export type AssetEncoding = "attachment"|"base64"|"binary"|"utf8"|"json"
type PartialAssetEncoding = Exclude<AssetEncoding, 'attachment' | 'json' >
const ASSETS_DIR = path.resolve('assets');
/**
* Reads an asset file from the 'assets' directory.
* If encoding is 'attachment', a discord.js AttachmentBuilder is provided, else
* fs.promises.readFile is called. The default is utf8.
* fs.promises.readFile is called. The default encoding is utf8.
*/
export async function Asset(p: string, opts?: { name?: string, encoding: Exclude<AssetEncoding, 'attachment'> }): Promise<string>;
export async function Asset(p: string, opts?: { name?: never, encoding: PartialAssetEncoding }): Promise<string>;
export async function Asset(p: string, opts?: { name?: never, encoding: 'json' }): Promise<any>;
export async function Asset(p: string, opts?: { name?: string, encoding: 'attachment' }): Promise<AttachmentBuilder>;
export async function Asset(p: string, opts?: { name?: string, encoding: AssetEncoding }): Promise<string|AttachmentBuilder> {
const encoding = opts?.encoding || 'utf8';
@@ -85,6 +85,9 @@ export async function Asset(p: string, opts?: { name?: string, encoding: AssetEn
if (encoding === 'attachment') {
const attachmentName = opts?.name || path.basename(filePath);
return new AttachmentBuilder(filePath, { name: attachmentName });
} else if(encoding === 'json') {
return fs.readFile(filePath, 'utf8')
.then(JSON.parse)
} else {
return fs.readFile(filePath, encoding);
}

View File

@@ -198,7 +198,10 @@ type EventModulesNoPlugins = {
};
export type InputEvent = {
[T in EventType]: EventModulesNoPlugins[T] & { once?: boolean };
[T in EventType]: EventModulesNoPlugins[T] & {
once?: boolean;
plugins?: InitPlugin[]
};
}[EventType];
export type InputCommand = {

View File

@@ -53,7 +53,7 @@ export interface ControlPlugin<Args extends any[] = any[]> extends Plugin<Args>
export type AnyPlugin = ControlPlugin | InitPlugin<[InitArgs<Processed<Module>>]>;
export type CommandArgs<I extends CommandType = CommandType > = CommandArgsMatrix[I]
export type CommandArgs<I extends CommandType = CommandType> = CommandArgsMatrix[I]
interface CommandArgsMatrix {
[CommandType.Text]: [Context, SDT];

View File

@@ -1,14 +1,14 @@
//@ts-nocheck
import { beforeEach, describe, expect, vi, it, test } from 'vitest';
import { callInitPlugins, eventDispatcher } from '../../src/handlers/event-utils';
import { callInitPlugins, eventDispatcher } from '../src/handlers/event-utils';
import { Client, ChatInputCommandInteraction } from 'discord.js'
import { faker } from '@faker-js/faker';
import { Module } from '../../src/types/core-modules';
import { Processed } from '../../src/types/core-modules';
import { Module } from '../src/types/core-modules';
import { Processed } from '../src/types/core-modules';
import { EventEmitter } from 'events';
import { EventType } from '../../dist/core/structures/enums';
import { CommandControlPlugin, CommandInitPlugin, CommandType, controller } from '../../src';
import { EventType } from '../dist/core/structures/enums';
import { CommandControlPlugin, CommandInitPlugin, CommandType, controller } from '../src';
vi.mock('discord.js', async (importOriginal) => {
const mod = await importOriginal()
@@ -129,16 +129,16 @@ test('form sdt', async () => {
"plugin2/abc": faker.git.branch(),
"plugin3/cheese": faker.person.jobArea()
}
// const plugin = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
// return controller.next({ "plugin/abc": expectedObject['plugin/abc'] });
// });
// const plugin2 = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
// return controller.next({ "plugin2/abc": expectedObject['plugin2/abc'] });
// });
// const plugin3 = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
// return controller.next({ "plugin3/cheese": expectedObject['plugin3/cheese'] });
// });
const plugin = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
return controller.next({ "plugin/abc": expectedObject['plugin/abc'] });
});
const plugin2 = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
return controller.next({ "plugin2/abc": expectedObject['plugin2/abc'] });
});
const plugin3 = CommandControlPlugin<CommandType.Slash>((ctx,sdt) => {
return controller.next({ "plugin3/cheese": expectedObject['plugin3/cheese'] });
});
})