Skip to content

Commit

Permalink
handling customId params working
Browse files Browse the repository at this point in the history
  • Loading branch information
jacoobes committed May 23, 2024
1 parent 327e56f commit 1de21b8
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 147 deletions.
4 changes: 2 additions & 2 deletions src/core/id.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ApplicationCommandType, ComponentType, Interaction, InteractionType } from 'discord.js';
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 hasSlash = event.customId.indexOf('/')
if(hasSlash === -1) {
return { id };
return { id:id+append };
}
const baseid = event.customId.substring(0, hasSlash);
const params = event.customId.substring(hasSlash+1);
Expand Down
75 changes: 17 additions & 58 deletions src/core/ioc/base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { DependencyConfiguration } from '../../types/ioc';
import { Container } from './container';
import * as __Services from '../structures/default-services';
import type { Logging } from '../interfaces';
Expand All @@ -11,11 +10,11 @@ export function disposeAll(logger: Logging|undefined) {
.then(() => logger?.info({ message: 'Cleaning container and crashing' }));
}


type Insertable =
| ((container: Dependencies) => object)
| object
const dependencyBuilder = (container: Container, excluded: string[] ) => {

const dependencyBuilder = (container: Container) => {
return {
/**
* Insert a dependency into your container.
Expand All @@ -29,14 +28,6 @@ const dependencyBuilder = (container: Container, excluded: string[] ) => {
container.addWiredSingleton(key, (cntr) => v(cntr))
}
},
/**
* Exclude any dependencies from being added.
* Warning: this could lead to bad errors if not used correctly
*/
exclude(...keys: (keyof Dependencies)[]) {
keys.forEach(key => excluded.push(key));
},

/**
* @param key the key of the dependency
* @param v The dependency to swap out.
Expand All @@ -49,60 +40,28 @@ const dependencyBuilder = (container: Container, excluded: string[] ) => {
};
};


/**
*
*
*
*/
type ValidDependencyConfig =
| ((c: ReturnType<typeof dependencyBuilder>) => any)
| DependencyConfiguration;

/**
* Given the user's conf, check for any excluded/included dependency keys.
* Then, call conf.build to get the rest of the users' dependencies.
* Finally, update the containerSubject with the new container state
* @param conf
*/
async function composeRoot(
container: Container,
conf: DependencyConfiguration,
) {
//container should have no client or logger yet.
const hasLogger = container.hasKey('@sern/logger');
if (!hasLogger) {
__add_container('@sern/logger', new __Services.DefaultLogging());
}
__add_container('@sern/errors', new __Services.DefaultErrorHandling());
__add_container('@sern/modules', new Map())
__add_container('@sern/emitter', new EventEmitter())
__add_wiredcontainer('@sern/cron', deps => new __Services.Cron(deps))
//Build the container based on the callback provided by the user
conf.build(container as Container);

if (!hasLogger) {
container.get<Logging>('@sern/logger')
?.info({ message: 'All dependencies loaded successfully.' });
}
await container.ready();
}

export async function makeDependencies (conf: ValidDependencyConfig) {
const container = await __init_container({ autowire: false });
if(typeof conf === 'function') {
const excluded: string[] = [];
conf(dependencyBuilder(container, excluded));
//We only include logger if it does not exist
const includeLogger =
!excluded.includes('@sern/logger')
&& !container.hasKey('@sern/logger');
conf(dependencyBuilder(container));
//We only include logger if it does not exist
const includeLogger = !container.hasKey('@sern/logger');

if(includeLogger) {
__add_container('@sern/logger', new __Services.DefaultLogging);
}
__add_container('@sern/errors', new __Services.DefaultErrorHandling());
__add_container('@sern/modules', new Map())
__add_container('@sern/emitter', new EventEmitter())
__add_wiredcontainer('@sern/cron', deps => new __Services.Cron(deps))
await container.ready();
} else {
await composeRoot(container, conf);
if(includeLogger) {
__add_container('@sern/logger', new __Services.DefaultLogging);
}
__add_container('@sern/errors', new __Services.DefaultErrorHandling);
__add_container('@sern/modules', new Map)
__add_container('@sern/emitter', new EventEmitter)
__add_wiredcontainer('@sern/cron', deps => new __Services.Cron(deps))
await container.ready();
}

8 changes: 5 additions & 3 deletions src/core/structures/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Context extends CoreContext<Message, ChatInputCommandInteraction> {
get options() {
return this.interaction.options;
}

//TODO
args(type: 'message'|'interaction', parser?: Function) {
switch(type) {
case 'message': {
Expand All @@ -42,10 +42,12 @@ export class Context extends CoreContext<Message, ChatInputCommandInteraction> {
}

protected constructor(protected ctx: Result<Message, ChatInputCommandInteraction>,
public prefix?: string) {
private __prefix?: string) {
super(ctx);
}

public get prefix() {
return this.__prefix;
}
public get id(): Snowflake {
return safeUnwrap(this.ctx
.map(m => m.id)
Expand Down
11 changes: 7 additions & 4 deletions src/handlers/event-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export function executeModule(
* - if all results are ok, the stream is converted to { config.onNext }
* config.onNext will be returned if everything is okay.
* @param config
* @returns receiver function for flattening a stream of data
* @returns function which calls all plugins and returns onNext or fail
*/
export function createResultResolver<Output>(config: {
onStop?: (module: Module, err?: string) => unknown;
Expand All @@ -198,19 +198,22 @@ export function createResultResolver<Output>(config: {
};
};

export async function callInitPlugins(module: Module, deps: Dependencies, sEmitter?: Emitter) {
export async function callInitPlugins(module: Module, deps: Dependencies, emit?: boolean ) {
let _module = module;
for(const plugin of _module.plugins ?? []) {
const res = await plugin.execute({
module, absPath: _module.meta.absPath ,
module, absPath: _module.meta.absPath,
updateModule: (partial: Partial<Module>) => {
_module = { ..._module, ...partial };
return _module;
},
deps
});
if(res.isErr()) {
sEmitter?.emit('module.register', resultPayload(PayloadType.Failure, module, SernError.PluginFailure));
if(emit) {
deps['@sern/emitter']
?.emit('module.register', resultPayload(PayloadType.Failure, module, SernError.PluginFailure));
}
throw Error("Plugin failed with controller.stop()");
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default async function(dir: string, deps : UnpackedDependencies) {
if(!validType) {
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has incorrect \`type\``);
}
const resultModule = await callInitPlugins(module, deps, sEmitter);
const resultModule = await callInitPlugins(module, deps, true);
// FREEZE! no more writing!!
commands.set(resultModule.meta.id, Object.freeze(resultModule));
sEmitter.emit('module.register', resultPayload(PayloadType.Success, resultModule));
Expand Down
5 changes: 1 addition & 4 deletions src/handlers/user-defined-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ export default async function(deps: UnpackedDependencies, eventDir: string) {
}
from(eventModules)
.pipe(map(intoDispatcher(deps)),
/**
* Where all events are turned on
*/
mergeAll(),
mergeAll(), // all eventListeners are turned on
handleCrash(deps))
.subscribe();
}
40 changes: 9 additions & 31 deletions test/core/functions.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//@ts-nocheck

import { afterEach, describe, expect, it, vi } from 'vitest';
import { PluginType, SernOptionsData, controller } from '../../src/index';
import { partitionPlugins, treeSearch } from '../../src/core/functions';
import { faker } from '@faker-js/faker';
import { ApplicationCommandOptionType, AutocompleteInteraction } from 'discord.js';

vi.mock('discord.js', () => {
const Collection = Map;
vi.mock('discord.js', async (importOriginal) => {
const mod = await importOriginal()
const ModalSubmitInteraction = class {
customId;
type = 5;
Expand Down Expand Up @@ -36,35 +38,11 @@ vi.mock('discord.js', () => {
};

return {
Collection,
ComponentType: {
Button: 2,
},
InteractionType: {
Ping: 1,
ApplicationCommand: 2,
MessageComponent: 3,
ApplicationCommandAutocomplete: 4,
ModalSubmit: 5,
},
ApplicationCommandOptionType: {
Subcommand: 1,
SubcommandGroup: 2,
String: 3,
Integer: 4,
Boolean: 5,
User: 6,
Channel: 7,
Role: 8,
Mentionable: 9,
Number: 10,
Attachment: 11,
},
ApplicationCommandType: {
ChatInput: 1,
User: 2,
Message: 3,
},
Collection: mod.Collection,
ComponentType: mod.ComponentType,
InteractionType: mod.InteractionType,
ApplicationCommandOptionType: mod.ApplicationCommandOptionType,
ApplicationCommandType: mod.ApplicationCommandType,
ModalSubmitInteraction,
ButtonInteraction,
AutocompleteInteraction,
Expand Down
78 changes: 77 additions & 1 deletion test/core/id.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
//@ts-nocheck
import { expect, test, vi } from 'vitest'
import { CommandType } from '../../src/core/structures/enums';

import * as Id from '../../src/core/id'
import { expect, test } from 'vitest'
import { ButtonInteraction, ModalSubmitInteraction } from 'discord.js';
vi.mock('discord.js', async (importOriginal) => {
const mod = await importOriginal()
const ModalSubmitInteraction = class {
customId;
type = 5;
isModalSubmit = vi.fn();
constructor(customId) {
this.customId = customId;
}
};
const ButtonInteraction = class {
customId;
type = 3;
componentType = 2;
isButton = vi.fn();
constructor(customId) {
this.customId = customId;
}
};
const AutocompleteInteraction = class {
type = 4;
option: string;
constructor(s: string) {
this.option = s;
}
options = {
getFocused: vi.fn(),
getSubcommand: vi.fn(),
};
};

return {
Collection: mod.Collection,
ComponentType: mod.ComponentType,
InteractionType: mod.InteractionType,
ApplicationCommandOptionType: mod.ApplicationCommandOptionType,
ApplicationCommandType: mod.ApplicationCommandType,
ModalSubmitInteraction,
ButtonInteraction,
AutocompleteInteraction,
};
});
test('id -> Text', () => {
const bothCmdId = Id.create("ping", CommandType.Text)
expect(bothCmdId).toBe("ping_T")
Expand Down Expand Up @@ -60,5 +104,37 @@ test('id -> ChannelSelect', () => {
expect(modal).toBe("mychannelselect_C8");
})

test('id reconstruct button', () => {
const idload = Id.reconstruct(new ButtonInteraction("btn"))
expect(idload[0].id).toBe("btn_C2")
})

test('id reconstruct button with params', () => {
const idload = Id.reconstruct(new ButtonInteraction("btn/asdf"))
expect(idload[0].id).toBe("btn_C2")
expect(idload[0].params).toBe("asdf")
})
test('id reconstruct modal with params', () => {
const idload = Id.reconstruct(new ModalSubmitInteraction("btn/asdf"))
expect(idload[0].id).toBe("btn_M")
expect(idload[0].params).toBe("asdf")
})
test('id reconstruct modal', () => {
const idload = Id.reconstruct(new ModalSubmitInteraction("btn"))
expect(idload[0].id).toBe("btn_M")
expect(idload[0].params).toBe(undefined)
})
test('id reconstruct button with empty params', () => {
const idload = Id.reconstruct(new ButtonInteraction("btn/"))
expect(idload[0].id).toBe("btn_C2")
expect(idload[0].params).toBe("")
})

test('id reconstruct button', () => {
const idload = Id.reconstruct(new ButtonInteraction("btn"))
expect(idload[0].id).toBe("btn_C2")
expect(idload[0].params).toBe(undefined)
})



43 changes: 0 additions & 43 deletions test/handlers/dispatchers.test.ts

This file was deleted.

Loading

0 comments on commit 1de21b8

Please sign in to comment.