Skip to content
This repository has been archived by the owner on Nov 18, 2024. It is now read-only.

Commit

Permalink
Clean up & comment
Browse files Browse the repository at this point in the history
  • Loading branch information
Froxcey committed Dec 19, 2023
1 parent 935ac79 commit 9ab990b
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 216 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "multichat",
"version": "0.4",
"module": "src/index.ts",
"type": "module",
"homepage": "https://github.com/Chiissu/multichat",
Expand Down
3 changes: 2 additions & 1 deletion src/adapters/discord.js/toCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { messageRebuild } from "./toPlatform";

export function adaptMessage(message: DiscordMessage, client: Client): Message {
return {
platform: "discord",
type: "Message",
platform: { name: "Discord", host: "discord.com" },
content: message.content,
author: {
name: message.author.displayName,
Expand Down
55 changes: 1 addition & 54 deletions src/adapters/discord.js/toPlatform.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,5 @@
import { Embed, EmbedDataSchema, MessageContent, EmbedData } from "../";
import { EmbedBuilder } from "discord.js";
import { safeParse } from "valibot";
import { MessageContent } from "../";

export function messageRebuild(content: MessageContent) {
if (typeof content == "string") return content;

if (!content)
return console.warn(
"Type Error: Embed data is invalid and has been blocked",
);

if ((content as { baseU64: string }).baseU64)
return console.log("Message content of non-string is not yet supported");

// is embed
let embedParsed = safeParse(EmbedDataSchema, content);
if (!embedParsed.success)
return console.warn(
"Type Error: Embed data is invalid and has been blocked by Valibot",
);
return { embeds: [embedRebuild(embedParsed.output)] };
}

export function embedRebuild(embedData: EmbedData) {
let embed = new Embed(embedData);
let discordEmbed = new EmbedBuilder({
title: embed.title,
url: embed.link,
description: embed.description,
thumbnail: embed.thumbnail,
fields: embed.contents?.map((val) => {
return {
name: val.key ?? "",
value: val.value,
inline: !!val.inline,
};
}),
image: embed.image,
timestamp: embed.timestamp?.toString(),
color: embed.color,
});

if (embed.author)
discordEmbed.setAuthor({
name: embed.author.name,
iconURL: embed.author.icon,
url: embed.author.link,
});

if (embed.footer)
discordEmbed.setFooter({
text: embed.footer.text,
iconURL: embed.footer.icon,
});

return discordEmbed;
}
3 changes: 2 additions & 1 deletion src/adapters/guilded.js/toCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { messageRebuild } from "./toPlatform";

export function adaptMessage(message: GuildedMessage, client: Client): Message {
return {
platform: "guilded",
type: "Message",
platform: {name: "guilded", host: "guilded.gg"},
content: message.content as string,
author: {
name: message.author?.name ?? null,
Expand Down
52 changes: 1 addition & 51 deletions src/adapters/guilded.js/toPlatform.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,5 @@
import { MessageContent, Embed, EmbedDataSchema, EmbedData } from "../";
import { Embed as GuildedEmbed } from "guilded.js";
import { safeParse } from "valibot";
import {} from "discord.js";
import { MessageContent } from "../";

export function messageRebuild(content: MessageContent) {
if (typeof content == "string") return content;

if (!content)
return console.warn(
"Type Error: Embed data is invalid and has been blocked",
);

if ((content as { baseU64: string }).baseU64)
return console.log("Message content of non-string is not yet supported");

// is embed
let embedParsed = safeParse(EmbedDataSchema, content);
if (!embedParsed.success)
return console.warn(
"Type Error: Embed data is invalid and has been blocked by Valibot",
);
return { embeds: [embedRebuild(embedParsed.output)] };
}

export function embedRebuild(embedData: EmbedData) {
let embed = new Embed(embedData);
let guildedEmbed = new GuildedEmbed({
title: embed.title,
url: embed.link,
description: embed.description,
thumbnail: embed.thumbnail,
fields: embed.contents?.map((val) => {
return {
name: val.key ?? "",
value: val.value,
inline: !!val.inline,
};
}),
image: embed.image,
timestamp: embed.timestamp?.toString(),
color: embed.color,
});

if (embed.author)
guildedEmbed.setAuthor(
embed.author.name,
embed.author.icon,
embed.author.link,
);
if (embed.footer)
guildedEmbed.setFooter(embed.footer.text, embed.footer.icon);

return guildedEmbed;
}
141 changes: 32 additions & 109 deletions src/adapters/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import { Emitter } from "strict-event-emitter";
import {
string,
object,
optional,
Input,
union,
array,
boolean,
date,
number,
} from "valibot";

export type MessageContent = string | { baseU64: string } | Embed;
export type MessageContent = string;

export interface User {
name: string | null;
Expand All @@ -20,124 +9,58 @@ export interface User {
avatarURL: string | null;
}

export const EmbedDataSchema = object({
author: union([
object({
name: string(),
link: optional(string()),
icon: optional(string()),
}),
string(),
]),
title: optional(string()),
link: optional(string()),
description: optional(string()),
thumbnail: optional(union([string(), object({ url: string() })])),
contents: array(
union([
string(),
object({
value: string(),
key: optional(string()),
inline: optional(boolean()),
}),
]),
),
image: optional(union([string(), object({ url: string() })])),
footer: optional(
union([string(), object({ text: string(), icon: optional(string()) })]),
),
timestamp: optional(union([boolean(), date(), string(), number()])),
color: optional(number()),
});

export type EmbedData = Input<typeof EmbedDataSchema>;

export class Embed implements EmbedData {
author;
title;
link;
description;
thumbnail;
contents;
image;
footer;
timestamp;
color;
constructor(content: EmbedData) {
this.author =
typeof content.author == "string"
? { name: content.author }
: content.author;
this.title = content?.title;
this.link = content?.link;
this.description = content?.description;
this.thumbnail =
typeof content?.thumbnail == "string"
? { url: content.thumbnail }
: content.thumbnail;
this.contents = content?.contents?.map((val) => {
return typeof val == "string" ? { value: val } : val;
});
this.image =
typeof content?.image == "string"
? { url: content.image }
: content.image;
this.footer =
typeof content?.footer == "string"
? { text: content.footer }
: content.footer;
this.timestamp =
content?.timestamp == true ? new Date() : content.timestamp;
this.color = content?.color;
}
}

export interface Message {
type: "Message";
/**
* Information on the platform that the message was sent on
*/
platform: {
name: "discord" | "guilded" | string;
/**
* The name of the platform
*/
name: "Discord" | "Guilded" | string;
/**
* The location of the platform
* For decentralised platforms, this might come in handy
*/
host: string;
id: string;
}
};
content: string;
author: User;
mentions: {
/**
* True if the bot was mentioned
*/
me: boolean;
/**
* True if everyone got mentioned
*/
everyone: boolean;
};
/**
* A special id of the message issued by the extension host
*/
id: string;
/**
* Send a reply to the message
* @param content The message to reply with
*/
reply: (content: MessageContent) => void;
/**
* Send a message in the same place as the message
* @param content The message to send
*/
send: (content: MessageContent) => void;
}

export interface CommandInteraction {
type: "CommandInteraction";
name: string;
send: (content: MessageContent) => void;
reply: (content: MessageContent) => void;
}

export const CommandInfoSchema = object({
name: string(),
description: optional(string()),
adminOnly: optional(boolean()),
});

export type CommandInfo = Input<typeof CommandInfoSchema>;

export type AdapterEvents = {
messageCreate: [message: Message];
commandInteraction: [interaction: CommandInteraction];
};

export class BaseAdapter extends Emitter<AdapterEvents> {
static eventList: (keyof AdapterEvents)[] = [
"messageCreate",
"commandInteraction",
];
static eventList: (keyof AdapterEvents)[] = ["messageCreate"];
}

export abstract class Platform extends BaseAdapter {
registerCommand(commandInfo: CommandInfo): void {}
//registerCommand(commandInfo: CommandInfo): void {}
}
Empty file removed src/common/platform.ts
Empty file.
17 changes: 17 additions & 0 deletions src/devkit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { Remapper } from "./remapper";
export class MtcClient extends Emitter<Events> {
private socket: Socket;
private remapper: Remapper;
/**
* Helps you connect to the Nebula extension host
* @param location The location of the extension host
* @param config Configurations of your extension
*/
constructor(location: URL | string, config: ExtConfig) {
super();
this.socket = io(location, {
Expand Down Expand Up @@ -33,7 +38,19 @@ export class MtcClient extends Emitter<Events> {
console.error(err);
});
}

/**
* Disconnect this extension from the extension host
*/
disconnect() {
this.socket.disconnect();
}

/**
* Reconnect this extension after disconnecting
* WARNING: You normally shouldn't need this
*/
reconnect() {
this.socket.connect();
}
}
8 changes: 8 additions & 0 deletions src/devkit/protocol.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { AdapterEvents } from "../adapters";

export interface ExtConfig {
/**
* The unique ID of your extension
* Make sure this ID is registered on the extension host
*/
id: string;
/**
* The token to run your extension
* This should be issued by the admin of the extension host
*/
token?: string;
}

Expand Down

0 comments on commit 9ab990b

Please sign in to comment.