diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bb95546..9a830be 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -10,15 +10,7 @@ }, "problemMatcher": [], "label": "npm: test", - "detail": "cross-env FORCE_COLOR=true supertape --format tap test/test.js | tap-dot", - "presentation": { - "echo": false, - "reveal": "always", - "focus": false, - "panel": "shared", - "showReuseMessage": false, - "clear": true - } + "detail": "cross-env FORCE_COLOR=true supertape --format tap test/test.js | tap-dot" } ] -} \ No newline at end of file +} diff --git a/d2m/actions/create-room.js b/d2m/actions/create-room.js index 214d026..7e9abed 100644 --- a/d2m/actions/create-room.js +++ b/d2m/actions/create-room.js @@ -5,10 +5,10 @@ const DiscordTypes = require("discord-api-types/v10") const passthrough = require("../../passthrough") const { discord, sync, db } = passthrough -/** @type {import("../../matrix/mreq")} */ -const mreq = sync.require("../../matrix/mreq") /** @type {import("../../matrix/file")} */ const file = sync.require("../../matrix/file") +/** @type {import("../../matrix/api")} */ +const api = sync.require("../../matrix/api") function kstateStripConditionals(kstate) { for (const [k, content] of Object.entries(kstate)) { @@ -51,8 +51,7 @@ function stateToKState(events) { * @param {string} roomID */ async function roomToKState(roomID) { - /** @type {import("../../types").Event.BaseStateEvent[]} */ - const root = await mreq.mreq("GET", `/client/v3/rooms/${roomID}/state`) + const root = await api.getAllState(roomID) return stateToKState(root) } @@ -63,7 +62,7 @@ async function roomToKState(roomID) { function applyKStateDiffToRoom(roomID, kstate) { const events = kstateToState(kstate) return Promise.all(events.map(({type, state_key, content}) => - mreq.mreq("PUT", `/client/v3/rooms/${roomID}/state/${type}/${state_key}`, content) + api.sendState(roomID, type, state_key, content) )) } @@ -131,8 +130,7 @@ async function channelToKState(channel, guild) { * @param {any} kstate */ async function createRoom(channel, guild, spaceID, kstate) { - /** @type {import("../../types").R.RoomCreated} */ - const root = await mreq.mreq("POST", "/client/v3/createRoom", { + const root = await api.createRoom({ name: channel.name, topic: channel.topic || undefined, preset: "private_chat", @@ -144,7 +142,7 @@ async function createRoom(channel, guild, spaceID, kstate) { db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, root.room_id) // Put the newly created child into the space - await mreq.mreq("PUT", `/client/v3/rooms/${spaceID}/state/m.space.child/${root.room_id}`, { + await api.sendState(spaceID, "m.space.child", root.room_id, { via: ["cadence.moe"] // TODO: use the proper server }) } diff --git a/d2m/actions/create-space.js b/d2m/actions/create-space.js index b3d7e95..517dad4 100644 --- a/d2m/actions/create-space.js +++ b/d2m/actions/create-space.js @@ -2,14 +2,14 @@ const passthrough = require("../../passthrough") const { sync, db } = passthrough -/** @type {import("../../matrix/mreq")} */ -const mreq = sync.require("../../matrix/mreq") +/** @type {import("../../matrix/api")} */ +const api = sync.require("../../matrix/api") /** * @param {import("discord-api-types/v10").RESTGetAPIGuildResult} guild */ function createSpace(guild) { - return mreq.mreq("POST", "/client/v3/createRoom", { + return api.createRoom({ name: guild.name, preset: "private_chat", visibility: "private", @@ -37,7 +37,7 @@ function createSpace(guild) { } } ] - }).then(/** @param {import("../../types").R.RoomCreated} root */ root => { + }).then(root => { db.prepare("INSERT INTO guild_space (guild_id, space_id) VALUES (?, ?)").run(guild.id, root.room_id) return root }) diff --git a/d2m/actions/register-user.js b/d2m/actions/register-user.js index 8f31f23..f970218 100644 --- a/d2m/actions/register-user.js +++ b/d2m/actions/register-user.js @@ -8,12 +8,16 @@ const { discord, sync, db } = passthrough const api = sync.require("../../matrix/api") /** @type {import("../../matrix/file")} */ const file = sync.require("../../matrix/file") +/** @type {import("../converters/user-to-mxid")} */ +const userToMxid = sync.require("../converters/user-to-mxid") /** * A sim is an account that is being simulated by the bridge to copy events from the other side. * @param {import("discord-api-types/v10").APIUser} user */ async function createSim(user) { - assert.notEqual(user.discriminator, "0000", "user is not a webhook") - api.register("_ooye_example") + const simName = userToMxid.userToSimName(user) + const appservicePrefix = "_ooye_" + const localpart = appservicePrefix + simName + await api.register(localpart) } diff --git a/d2m/converters/message-to-event.js b/d2m/converters/message-to-event.js index 6f9bc37..dd6aabc 100644 --- a/d2m/converters/message-to-event.js +++ b/d2m/converters/message-to-event.js @@ -4,7 +4,7 @@ const markdown = require("discord-markdown") /** * @param {import("discord-api-types/v10").APIMessage} message - * @returns {import("../../types").M_Room_Message_content} + * @returns {import("../../types").Event.M_Room_Message} */ function messageToEvent(message) { const body = message.content @@ -25,4 +25,4 @@ function messageToEvent(message) { } } -module.exports.messageToEvent = messageToEvent \ No newline at end of file +module.exports.messageToEvent = messageToEvent diff --git a/d2m/converters/user-to-mxid.js b/d2m/converters/user-to-mxid.js index 15b997f..35d9368 100644 --- a/d2m/converters/user-to-mxid.js +++ b/d2m/converters/user-to-mxid.js @@ -43,6 +43,7 @@ function* generateLocalpartAlternatives(preferences) { } /** + * Whole process for checking the database and generating the right sim name. * @param {import("discord-api-types/v10").APIUser} user * @returns {string} */ @@ -71,4 +72,4 @@ function userToSimName(user) { throw new Error(`Ran out of suggestions when generating sim name. downcased: "${downcased}"`) } -module.exports.userToSimName = userToSimName \ No newline at end of file +module.exports.userToSimName = userToSimName diff --git a/matrix/api.js b/matrix/api.js index 4335585..88c62d8 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -1,5 +1,7 @@ // @ts-check +const assert = require("assert") + const passthrough = require("../passthrough") const { discord, sync, db } = passthrough /** @type {import("./mreq")} */ @@ -8,6 +10,7 @@ const mreq = sync.require("./mreq") const file = sync.require("./file") /** + * @param {string} username * @returns {Promise} */ function register(username) { @@ -17,4 +20,34 @@ function register(username) { }) } -module.exports.register = register \ No newline at end of file +/** + * @returns {Promise} + */ +function createRoom(content) { + return mreq.mreq("POST", "/client/v3/createRoom", content) +} + +/** + * @param {string} roomID + * @returns {Promise} + */ +function getAllState(roomID) { + return mreq.mreq("GET", `/client/v3/rooms/${roomID}/state`) +} + +/** + * @param {string} roomID + * @param {string} type + * @param {string} stateKey + * @returns {Promise} + */ +function sendState(roomID, type, stateKey, content) { + assert.ok(type) + assert.ok(stateKey) + return mreq.mreq("PUT", `/client/v3/rooms/${roomID}/state/${type}/${stateKey}`, content) +} + +module.exports.register = register +module.exports.createRoom = createRoom +module.exports.getAllState = getAllState +module.exports.sendState = sendState diff --git a/stdin.js b/stdin.js index a57c044..551d7d2 100644 --- a/stdin.js +++ b/stdin.js @@ -6,9 +6,10 @@ const util = require("util") const passthrough = require("./passthrough") const { discord, config, sync, db } = passthrough -const createSpace = sync.require("./d2m/actions/create-space.js") -const createRoom = sync.require("./d2m/actions/create-room.js") -const mreq = sync.require("./matrix/mreq.js") +const createSpace = sync.require("./d2m/actions/create-space") +const createRoom = sync.require("./d2m/actions/create-room") +const mreq = sync.require("./matrix/mreq") +const api = sync.require("./matrix/api") const guildID = "112760669178241024" const extraContext = {} diff --git a/types.d.ts b/types.d.ts index 8d15d6b..b3a9acc 100644 --- a/types.d.ts +++ b/types.d.ts @@ -54,4 +54,8 @@ namespace R { access_token: string device_id: string } + + export type EventSent = { + event_id: string + } }