Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found
Sélectionner une révision Git
  • cherry-pick-moise
  • develop
  • rebase-v4
  • renovate/configure
4 résultats

Cible

Sélectionner le projet cible
  • arise/matrix-appservice-discord
  • Deurstann/matrix-appservice-discord
2 résultats
Sélectionner une révision Git
  • cherry-pick-moise
  • develop
  • fix-oversized-file-transfer
  • implement-discord-markdown-update
  • matrix-answer-modified-fix
  • matrix-attachment-order-fix
  • matrix-attachments-order-fix
7 résultats
Afficher les modifications
Validations sur la source (14)
...@@ -20,7 +20,7 @@ import { DiscordStore } from "./store"; ...@@ -20,7 +20,7 @@ import { DiscordStore } from "./store";
import { DbEmoji } from "./db/dbdataemoji"; import { DbEmoji } from "./db/dbdataemoji";
import { DbEvent } from "./db/dbdataevent"; import { DbEvent } from "./db/dbdataevent";
import { DiscordMessageProcessor } from "./discordmessageprocessor"; import { DiscordMessageProcessor } from "./discordmessageprocessor";
import { IDiscordMessageParserResult } from "@mx-puppet/matrix-discord-parser"; import { IDiscordMessageParserResult } from "@deurstann/matrix-discord-parser";
import { MatrixEventProcessor, MatrixEventProcessorOpts, IMatrixEventProcessorResult } from "./matrixeventprocessor"; import { MatrixEventProcessor, MatrixEventProcessorOpts, IMatrixEventProcessorResult } from "./matrixeventprocessor";
import { PresenceHandler } from "./presencehandler"; import { PresenceHandler } from "./presencehandler";
import { Provisioner } from "./provisioner"; import { Provisioner } from "./provisioner";
...@@ -567,7 +567,7 @@ export class DiscordBot { ...@@ -567,7 +567,7 @@ export class DiscordBot {
return; return;
} }
const link = `https://discord.com/channels/${chan.guild.id}/${chan.id}/${editEventId}`; const link = `https://discord.com/channels/${chan.guild.id}/${chan.id}/${editEventId}`;
embedSet.messageEmbed.description = `[Edit](${link}): ${embedSet.messageEmbed.description}`; embedSet.messageEmbed.description = `[Edit](<${link}>): ${embedSet.messageEmbed.description}`;
await this.send(embedSet, opts, roomLookup, event); await this.send(embedSet, opts, roomLookup, event);
} catch (err) { } catch (err) {
// throw wrapError(err, Unstable.ForeignNetworkError, "Couldn't edit message"); // throw wrapError(err, Unstable.ForeignNetworkError, "Couldn't edit message");
...@@ -1041,65 +1041,14 @@ export class DiscordBot { ...@@ -1041,65 +1041,14 @@ export class DiscordBot {
} }
try { try {
const intent = this.GetIntentFromDiscordMember(msg.author, msg.webhookID); const intent = this.GetIntentFromDiscordMember(msg.author, msg.webhookID);
// Check Attachements if (!msg.content && msg.embeds.length === 0 && msg.attachments.array().length === 0) {
if (!editEventId) {
// on discord you can't edit in images, you can only edit text
// so it is safe to only check image upload stuff if we don't have
// an edit
await Util.AsyncForEach(msg.attachments.array(), async (attachment) => {
const content = await Util.DownloadFile(attachment.url);
const fileMime = content.mimeType || mime.getType(attachment.name || "")
|| "application/octet-stream";
const mxcUrl = await intent.underlyingClient.uploadContent(
content.buffer,
fileMime,
attachment.name || "",
);
const type = fileMime.split("/")[0];
let msgtype = {
audio: "m.audio",
image: "m.image",
video: "m.video",
}[type];
if (!msgtype) {
msgtype = "m.file";
}
const info = {
mimetype: fileMime,
size: attachment.size,
} as IMatrixMediaInfo;
if (msgtype === "m.image" || msgtype === "m.video") {
info.w = attachment.width!;
info.h = attachment.height!;
}
await Util.AsyncForEach(rooms, async (room) => {
const eventId = await intent.sendEvent(room, {
body: attachment.name || "file",
external_url: attachment.url,
info,
msgtype,
url: mxcUrl,
});
this.lastEventIds[room] = eventId;
const evt = new DbEvent();
evt.MatrixId = `${eventId};${room}`;
evt.DiscordId = msg.id;
evt.ChannelId = msg.channel.id;
if (msg.guild) {
evt.GuildId = msg.guild.id;
}
await this.store.Insert(evt);
this.userActivity.updateUserActivity(intent.userId);
});
});
}
if (!msg.content && msg.embeds.length === 0) {
return; return;
} }
const result = await this.discordMsgProcessor.FormatMessage(msg); const result = await this.discordMsgProcessor.FormatMessage(msg);
if (!result.body) { if (!result.body && msg.attachments.array().length === 0) {
return; return;
} }
if(result.body){
await Util.AsyncForEach(rooms, async (room) => { await Util.AsyncForEach(rooms, async (room) => {
const sendContent: IMatrixMessage = { const sendContent: IMatrixMessage = {
body: result.body, body: result.body,
...@@ -1107,6 +1056,30 @@ export class DiscordBot { ...@@ -1107,6 +1056,30 @@ export class DiscordBot {
formatted_body: result.formattedBody, formatted_body: result.formattedBody,
msgtype: result.msgtype, msgtype: result.msgtype,
}; };
if (msg.reference) {
const storeEvent = await this.store.Get(DbEvent, { discord_id: msg.reference?.messageID });
if (storeEvent && storeEvent.Result) {
let replyToEventId: string | undefined = undefined;
while (storeEvent.Next()) {
const [eventId] = storeEvent.MatrixId.split(";");
// Try to get the "deepest" event ID if this event replaces another ID
// We need to do this since a m.in_reply_to relation requires the original event ID and not the replacement one
const { chunk } = await intent.underlyingClient.unstableApis.getRelationsForEvent(room, eventId, "m.replace");
if (!!chunk?.length) {
replyToEventId = chunk[0].content['m.relates_to'].event_id;
} else {
replyToEventId ??= eventId;
}
}
if (replyToEventId) {
sendContent["m.relates_to"] = {
"m.in_reply_to": {
event_id: replyToEventId
}
};
}
}
}
if (editEventId) { if (editEventId) {
sendContent.body = `* ${result.body}`; sendContent.body = `* ${result.body}`;
sendContent.formatted_body = `* ${result.formattedBody}`; sendContent.formatted_body = `* ${result.formattedBody}`;
...@@ -1152,6 +1125,59 @@ export class DiscordBot { ...@@ -1152,6 +1125,59 @@ export class DiscordBot {
await afterSend(res); await afterSend(res);
} }
}); });
}
// Check Attachements
if (!editEventId) {
// on discord you can't edit in images, you can only edit text
// so it is safe to only check image upload stuff if we don't have
// an edit
await Util.AsyncForEach(msg.attachments.array(), async (attachment) => {
const content = await Util.DownloadFile(attachment.url);
const fileMime = content.mimeType || mime.getType(attachment.name || "")
|| "application/octet-stream";
const mxcUrl = await intent.underlyingClient.uploadContent(
content.buffer,
fileMime,
attachment.name || "",
);
const type = fileMime.split("/")[0];
let msgtype = {
audio: "m.audio",
image: "m.image",
video: "m.video",
}[type];
if (!msgtype) {
msgtype = "m.file";
}
const info = {
mimetype: fileMime,
size: attachment.size,
} as IMatrixMediaInfo;
if (msgtype === "m.image" || msgtype === "m.video") {
info.w = attachment.width!;
info.h = attachment.height!;
}
await Util.AsyncForEach(rooms, async (room) => {
const eventId = await intent.sendEvent(room, {
body: attachment.name || "file",
external_url: attachment.url,
info,
msgtype,
url: mxcUrl,
});
this.lastEventIds[room] = eventId;
const evt = new DbEvent();
evt.MatrixId = `${eventId};${room}`;
evt.DiscordId = msg.id;
evt.ChannelId = msg.channel.id;
if (msg.guild) {
evt.GuildId = msg.guild.id;
}
await this.store.Insert(evt);
this.userActivity.updateUserActivity(intent.userId);
});
});
}
MetricPeg.get.requestOutcome(msg.id, true, "success"); MetricPeg.get.requestOutcome(msg.id, true, "success");
} catch (err) { } catch (err) {
MetricPeg.get.requestOutcome(msg.id, true, "fail"); MetricPeg.get.requestOutcome(msg.id, true, "fail");
...@@ -1169,6 +1195,9 @@ export class DiscordBot { ...@@ -1169,6 +1195,9 @@ export class DiscordBot {
if (storeEvent && storeEvent.Result) { if (storeEvent && storeEvent.Result) {
while (storeEvent.Next()) { while (storeEvent.Next()) {
const matrixIds = storeEvent.MatrixId.split(";"); const matrixIds = storeEvent.MatrixId.split(";");
if(!oldMsg.content && oldMsg.attachments.array().length>0){
newMsg.content = newMsg.content + " " + oldMsg.attachments.array()[0].url;
}
await this.OnMessage(newMsg, matrixIds[0]); await this.OnMessage(newMsg, matrixIds[0]);
return; return;
} }
......
...@@ -22,7 +22,7 @@ import { ...@@ -22,7 +22,7 @@ import {
IDiscordMessageParserOpts, IDiscordMessageParserOpts,
IDiscordMessageParserCallbacks, IDiscordMessageParserCallbacks,
IDiscordMessageParserResult, IDiscordMessageParserResult,
} from "@mx-puppet/matrix-discord-parser"; } from "@deurstann/matrix-discord-parser";
const log = new Log("DiscordMessageProcessor"); const log = new Log("DiscordMessageProcessor");
......
...@@ -72,7 +72,9 @@ export class MatrixCommandHandler { ...@@ -72,7 +72,9 @@ export class MatrixCommandHandler {
cat: "events", cat: "events",
level: PROVISIONING_DEFAULT_POWER_LEVEL, level: PROVISIONING_DEFAULT_POWER_LEVEL,
selfService: true, selfService: true,
subcat: "m.room.power_levels", //subcat: "m.room.power_levels",
// use default power level (50)
subcat: "null",
}, },
run: async ({guildId, channelId}) => { run: async ({guildId, channelId}) => {
if (roomEntry && roomEntry.remote) { if (roomEntry && roomEntry.remote) {
...@@ -118,7 +120,7 @@ export class MatrixCommandHandler { ...@@ -118,7 +120,7 @@ export class MatrixCommandHandler {
cat: "events", cat: "events",
level: PROVISIONING_DEFAULT_POWER_LEVEL, level: PROVISIONING_DEFAULT_POWER_LEVEL,
selfService: true, selfService: true,
subcat: "m.room.power_levels", subcat: "null",
}, },
run: async () => { run: async () => {
if (!roomEntry || !roomEntry.remote) { if (!roomEntry || !roomEntry.remote) {
......
...@@ -391,7 +391,8 @@ export class MatrixEventProcessor { ...@@ -391,7 +391,8 @@ export class MatrixEventProcessor {
if (!sourceEvent || !sourceEvent.content || !sourceEvent.content.body) { if (!sourceEvent || !sourceEvent.content || !sourceEvent.content.body) {
throw Error("No content could be found"); throw Error("No content could be found");
} }
const replyEmbed = (await this.EventToEmbed(sourceEvent, channel, true)).messageEmbed; const eventToTakeTextFrom = sourceEvent.unsigned?.["m.relations"]?.["m.replace"] ?? sourceEvent;
const replyEmbed = (await this.EventToEmbed(eventToTakeTextFrom, channel, true)).messageEmbed;
// if we reply to a discord member, ping them! // if we reply to a discord member, ping them!
if (this.bridge.isNamespacedUser(sourceEvent.sender)) { if (this.bridge.isNamespacedUser(sourceEvent.sender)) {
...@@ -533,7 +534,7 @@ export class MatrixEventProcessor { ...@@ -533,7 +534,7 @@ export class MatrixEventProcessor {
embed.setAuthor( embed.setAuthor(
displayName.substring(0, MAX_NAME_LENGTH), displayName.substring(0, MAX_NAME_LENGTH),
avatarUrl, avatarUrl,
`https://matrix.to/#/${sender}`, ``,
); );
} }
......
...@@ -24,7 +24,7 @@ import { ...@@ -24,7 +24,7 @@ import {
IMatrixMessageParserCallbacks, IMatrixMessageParserCallbacks,
IMatrixMessageParserOpts, IMatrixMessageParserOpts,
MatrixMessageParser, MatrixMessageParser,
} from "@mx-puppet/matrix-discord-parser"; } from "@deurstann/matrix-discord-parser";
const DEFAULT_ROOM_NOTIFY_POWER_LEVEL = 50; const DEFAULT_ROOM_NOTIFY_POWER_LEVEL = 50;
......
...@@ -317,7 +317,7 @@ export class UserSyncroniser { ...@@ -317,7 +317,7 @@ export class UserSyncroniser {
// for webhooks we append the username to the mxid, as webhooks with the same // for webhooks we append the username to the mxid, as webhooks with the same
// id can have multiple different usernames set. This way we don't spam // id can have multiple different usernames set. This way we don't spam
// userstate changes // userstate changes
mxidExtra = "_" + Util.ParseMxid(`@${user.username}`, false).localpart; mxidExtra = "_" + Util.ParseMxid(`@${user.username}`).localpart;
} }
const guildState: IGuildMemberState = Object.assign({}, DEFAULT_GUILD_STATE, { const guildState: IGuildMemberState = Object.assign({}, DEFAULT_GUILD_STATE, {
bot: user.bot, bot: user.bot,
......
...@@ -365,10 +365,7 @@ export class Util { ...@@ -365,10 +365,7 @@ export class Util {
const badChars = new Set(localpart.replace(/([a-z0-9]|-|\.|=|_)+/g, "")); const badChars = new Set(localpart.replace(/([a-z0-9]|-|\.|=|_)+/g, ""));
badChars.forEach((c) => { badChars.forEach((c) => {
const hex = c.charCodeAt(0).toString(RADIX).toLowerCase(); const hex = c.charCodeAt(0).toString(RADIX).toLowerCase();
localpart = localpart.replace( localpart = localpart.replaceAll(c, `=${hex}`);
new RegExp(`\\${c}`, "g"),
`=${hex}`,
);
}); });
} }
return { return {
...@@ -380,17 +377,7 @@ export class Util { ...@@ -380,17 +377,7 @@ export class Util {
// Taken from https://github.com/matrix-org/matrix-appservice-bridge/blob/master/lib/models/users/matrix.js // Taken from https://github.com/matrix-org/matrix-appservice-bridge/blob/master/lib/models/users/matrix.js
public static EscapeStringForUserId(localpart: string) { public static EscapeStringForUserId(localpart: string) {
// NOTE: Currently Matrix accepts / in the userId, although going forward it will be removed. return localpart.replace(/[^a-z0-9-._]/g, a => `=${a.codePointAt(0)!.toString(16).toLowerCase()}`)
const badChars = new Set(localpart.replace(/([a-z]|[0-9]|-|\.|=|_)+/g, ""));
let res = localpart;
badChars.forEach((c) => {
const hex = c.charCodeAt(0).toString(16).toLowerCase();
res = res.replace(
new RegExp(`\\x${hex}`, "g"),
`=${hex}`,
);
});
return res;
} }
} }
......
...@@ -146,7 +146,7 @@ export class AppserviceMock extends AppserviceMockBase { ...@@ -146,7 +146,7 @@ export class AppserviceMock extends AppserviceMockBase {
class IntentMock extends AppserviceMockBase { class IntentMock extends AppserviceMockBase {
public readonly underlyingClient: MatrixClientMock; public readonly underlyingClient: MatrixClientMock;
constructor(private opts: IAppserviceMockOpts = {}, private id: string) { constructor(private opts: IAppserviceMockOpts = {}, public userId: string) {
super(); super();
this.underlyingClient = new MatrixClientMock(opts); this.underlyingClient = new MatrixClientMock(opts);
} }
...@@ -177,9 +177,10 @@ class IntentMock extends AppserviceMockBase { ...@@ -177,9 +177,10 @@ class IntentMock extends AppserviceMockBase {
} }
class MatrixClientMock extends AppserviceMockBase { class MatrixClientMock extends AppserviceMockBase {
public readonly unstableApis: UnstableApis;;
constructor(private opts: IAppserviceMockOpts = {}) { constructor(private opts: IAppserviceMockOpts = {}) {
super(); super();
this.unstableApis = new UnstableApis();
} }
public banUser(roomId: string, userId: string) { public banUser(roomId: string, userId: string) {
...@@ -276,4 +277,19 @@ class MatrixClientMock extends AppserviceMockBase { ...@@ -276,4 +277,19 @@ class MatrixClientMock extends AppserviceMockBase {
public async setPresenceStatus(presence: string, status: string) { public async setPresenceStatus(presence: string, status: string) {
this.funcCalled("setPresenceStatus", presence, status); this.funcCalled("setPresenceStatus", presence, status);
} }
public async redactEvent(roomId: string, eventId: string, reason?: string | null) {
this.funcCalled("redactEvent", roomId, eventId, reason);
}
}
class UnstableApis extends AppserviceMockBase {
public async addReactionToEvent(roomId: string, eventId: string, emoji: string) {
this.funcCalled("addReactionToEvent", roomId, eventId, emoji);
}
public async getRelationsForEvent(roomId: string, eventId: string, relationType?: string, eventType?: string): Promise<any> {
this.funcCalled("getRelationsForEvent", roomId, eventId, relationType, eventType);
}
} }
...@@ -29,12 +29,21 @@ export class MockMessage { ...@@ -29,12 +29,21 @@ export class MockMessage {
public guild: Discord.Guild | undefined; public guild: Discord.Guild | undefined;
public author: MockUser; public author: MockUser;
public mentions: any = {}; public mentions: any = {};
constructor(channel?: Discord.TextChannel) { public reference?: Discord.MessageReference = undefined;
constructor(
channel?: Discord.TextChannel,
content: string = "",
author: MockUser = new MockUser("123456"),
reference = undefined
) {
this.mentions.everyone = false; this.mentions.everyone = false;
this.channel = channel; this.channel = channel;
if (channel && channel.guild) { if (channel && channel.guild) {
this.guild = channel.guild; this.guild = channel.guild;
} }
this.author = new MockUser("123456"); this.content = content;
this.author = author;
this.reference = reference;
} }
} }
...@@ -16,6 +16,7 @@ limitations under the License. ...@@ -16,6 +16,7 @@ limitations under the License.
import { expect } from "chai"; import { expect } from "chai";
import * as Proxyquire from "proxyquire"; import * as Proxyquire from "proxyquire";
import * as Discord from "better-discord.js";
import { MockGuild } from "./mocks/guild"; import { MockGuild } from "./mocks/guild";
import { MockMember } from "./mocks/member"; import { MockMember } from "./mocks/member";
...@@ -105,8 +106,15 @@ describe("DiscordBot", () => { ...@@ -105,8 +106,15 @@ describe("DiscordBot", () => {
describe("OnMessage()", () => { describe("OnMessage()", () => {
const channel = new MockTextChannel(); const channel = new MockTextChannel();
const msg = new MockMessage(channel); const msg = new MockMessage(channel);
const author = new MockUser("11111"); const msgReply: Discord.MessageReference = {
messageID: '111',
guildID: '111',
channelID: '111',
};
const authorId = '11111';
const author = new MockUser(authorId);
let HANDLE_COMMAND = false; let HANDLE_COMMAND = false;
const roomId = "!asdf:localhost";
function getDiscordBot() { function getDiscordBot() {
HANDLE_COMMAND = false; HANDLE_COMMAND = false;
mockBridge.cleanup(); mockBridge.cleanup();
...@@ -120,7 +128,7 @@ describe("DiscordBot", () => { ...@@ -120,7 +128,7 @@ describe("DiscordBot", () => {
OnUpdateUser: async () => { }, OnUpdateUser: async () => { },
}; };
discord.channelSync = { discord.channelSync = {
GetRoomIdsFromChannel: async () => ["!asdf:localhost"], GetRoomIdsFromChannel: async () => [roomId],
}; };
discord.discordCommandHandler = { discord.discordCommandHandler = {
Process: async () => { HANDLE_COMMAND = true; }, Process: async () => { HANDLE_COMMAND = true; },
...@@ -161,6 +169,89 @@ describe("DiscordBot", () => { ...@@ -161,6 +169,89 @@ describe("DiscordBot", () => {
await discordBot.OnMessage(msg as any); await discordBot.OnMessage(msg as any);
mockBridge.getIntent(author.id).wasCalled("sendEvent"); mockBridge.getIntent(author.id).wasCalled("sendEvent");
}); });
describe("sends replies", () => {
const originalMxId = "$mAKet_w5WYFCgh1WaHVOvyn9LJLbolFeuELTKVfm0Po";
const replacementMxId = "$grdFSE_12LFSELOIFMSOEIJOIJ98kljnfIfESJOIFESO";
msg.author = author;
msg.content = "Foxies are amazing!";
msg.reference = msgReply;
it("to a Discord message", async () => {
discordBot = getDiscordBot();
discordBot.store = {
Get: async (a, b) => {
let storeMockResults = 0;
return Promise.resolve({
Result: true,
MatrixId: `${originalMxId};${roomId}`,
Next: () => storeMockResults-- >= 0
});
},
Insert: async () => { },
};
const intent = mockBridge.getIntent(author.id);
intent.underlyingClient.unstableApis.getRelationsForEvent = async () => ({
chunk: []
});
await discordBot.OnMessage(msg);
mockBridge.getIntent(author.id).wasCalled("sendEvent", true, roomId, {
body: msg.content,
format: "org.matrix.custom.html",
formatted_body: msg.content,
msgtype: 'm.text',
"m.relates_to": {
"m.in_reply_to": {
event_id: originalMxId
}
}
});
});
it("to an edited Discord message", async () => {
let storeEventData = { MatrixId: `${originalMxId};${roomId}` };
discordBot = getDiscordBot();
discordBot.store = {
Get: async (a, b) => {
let storeMockResults = 1;
return Promise.resolve({
Result: true,
...storeEventData,
Next: () => {
storeEventData = {
MatrixId: `${replacementMxId};${roomId}`,
}
return storeMockResults-- >= 0;
}
})
},
Insert: async () => { },
}
const intent = mockBridge.getIntent(author.id);
intent.underlyingClient.unstableApis.getRelationsForEvent = async () => ({
chunk: [{
sender: "11111",
room_id: roomId,
event_id: originalMxId,
content: {
"m.relates_to": {
event_id: replacementMxId,
rel_type: 'm.replace'
}
}
}]
});
await discordBot.OnMessage(msg);
mockBridge.getIntent(author.id).wasCalled("sendEvent", true, roomId, {
body: msg.content,
format: "org.matrix.custom.html",
formatted_body: msg.content,
msgtype: 'm.text',
"m.relates_to": {
"m.in_reply_to": {
event_id: replacementMxId
}
}
});
});
});
it("sends edit messages", async () => { it("sends edit messages", async () => {
discordBot = getDiscordBot(); discordBot = getDiscordBot();
msg.author = author; msg.author = author;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"target": "es2016", "target": "es2021",
"noImplicitAny": false, "noImplicitAny": false,
"inlineSourceMap": true, "inlineSourceMap": true,
"outDir": "./build", "outDir": "./build",
......
...@@ -215,6 +215,18 @@ ...@@ -215,6 +215,18 @@
enabled "2.0.x" enabled "2.0.x"
kuler "^2.0.0" kuler "^2.0.0"
"@deurstann/matrix-discord-parser@1.10.7":
version "1.10.7"
resolved "https://registry.yarnpkg.com/@deurstann/matrix-discord-parser/-/matrix-discord-parser-1.10.7.tgz#570d0563c3f916faed877cdf6c06be0f3cf607ee"
integrity sha512-Ud/KKGkCdsDMoBW2UZNwiR5UNvkmJJJODAmsSQL/vXh9Iz7zfLqnI/cbP4nUrv1Txd5XqGi/pGSNnZ5Kd6AreQ==
dependencies:
"@mx-puppet/discord-markdown" "2.3.1"
escape-html "^1.0.3"
got "^11.6.0"
highlight.js "^10.4.1"
node-html-parser "^1.4.5"
unescape-html "^1.1.0"
"@discordjs/collection@^0.1.6": "@discordjs/collection@^0.1.6":
version "0.1.6" version "0.1.6"
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c"
...@@ -337,18 +349,6 @@ ...@@ -337,18 +349,6 @@
node-emoji "^1.10.0" node-emoji "^1.10.0"
simple-markdown "^0.7.2" simple-markdown "^0.7.2"
"@mx-puppet/matrix-discord-parser@0.1.10":
version "0.1.10"
resolved "https://gitlab.com/api/v4/projects/35066311/packages/npm/@mx-puppet/matrix-discord-parser/-/@mx-puppet/matrix-discord-parser-0.1.10.tgz#0a37a3f9430ff7c29512d29882e25ae738a31283"
integrity sha1-Cjej+UMP98KVEtKYguJa5zijEoM=
dependencies:
"@mx-puppet/discord-markdown" "2.3.1"
escape-html "^1.0.3"
got "^11.6.0"
highlight.js "^10.4.1"
node-html-parser "^1.4.5"
unescape-html "^1.1.0"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
......