Finish room diffing and syncing. All tests pass
This commit is contained in:
		
							parent
							
								
									f09eeccef3
								
							
						
					
					
						commit
						3fbe7eed6e
					
				
					 13 changed files with 658 additions and 529 deletions
				
			
		| 
						 | 
					@ -1,8 +1,6 @@
 | 
				
			||||||
// @ts-check
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const assert = require("assert").strict
 | 
					const assert = require("assert").strict
 | 
				
			||||||
const {test} = require("supertape")
 | 
					 | 
				
			||||||
const testData = require("../../test/data")
 | 
					 | 
				
			||||||
const DiscordTypes = require("discord-api-types/v10")
 | 
					const DiscordTypes = require("discord-api-types/v10")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const passthrough = require("../../passthrough")
 | 
					const passthrough = require("../../passthrough")
 | 
				
			||||||
| 
						 | 
					@ -12,37 +10,62 @@ const mreq = sync.require("../../matrix/mreq")
 | 
				
			||||||
/** @type {import("../../matrix/file")} */
 | 
					/** @type {import("../../matrix/file")} */
 | 
				
			||||||
const file = sync.require("../../matrix/file")
 | 
					const file = sync.require("../../matrix/file")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function kstateStripConditionals(kstate) {
 | 
				
			||||||
 | 
						for (const [k, content] of Object.entries(kstate)) {
 | 
				
			||||||
 | 
							if ("$if" in content) {
 | 
				
			||||||
 | 
								if (content.$if) delete content.$if
 | 
				
			||||||
 | 
								else delete kstate[k]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return kstate
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function kstateToState(kstate) {
 | 
					function kstateToState(kstate) {
 | 
				
			||||||
	return Object.entries(kstate).map(([k, content]) => {
 | 
						const events = []
 | 
				
			||||||
		console.log(k)
 | 
						for (const [k, content] of Object.entries(kstate)) {
 | 
				
			||||||
 | 
							// conditional for whether a key is even part of the kstate (doing this declaratively on json is hard, so represent it as a property instead.)
 | 
				
			||||||
 | 
							if ("$if" in content && !content.$if) continue
 | 
				
			||||||
 | 
							delete content.$if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const [type, state_key] = k.split("/")
 | 
							const [type, state_key] = k.split("/")
 | 
				
			||||||
		assert.ok(typeof type === "string")
 | 
							assert.ok(typeof type === "string")
 | 
				
			||||||
		assert.ok(typeof state_key === "string")
 | 
							assert.ok(typeof state_key === "string")
 | 
				
			||||||
		return {type, state_key, content}
 | 
							events.push({type, state_key, content})
 | 
				
			||||||
	})
 | 
						}
 | 
				
			||||||
 | 
						return events
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("kstate2state: general", t => {
 | 
					/**
 | 
				
			||||||
	t.deepEqual(kstateToState({
 | 
					 * @param {import("../../types").Event.BaseStateEvent[]} events
 | 
				
			||||||
		"m.room.name/": {name: "test name"},
 | 
					 * @returns {any}
 | 
				
			||||||
		"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
					 */
 | 
				
			||||||
	}), [
 | 
					function stateToKState(events) {
 | 
				
			||||||
		{
 | 
						const kstate = {}
 | 
				
			||||||
			type: "m.room.name",
 | 
						for (const event of events) {
 | 
				
			||||||
			state_key: "",
 | 
							kstate[event.type + "/" + event.state_key] = event.content
 | 
				
			||||||
			content: {
 | 
						}
 | 
				
			||||||
				name: "test name"
 | 
						return kstate
 | 
				
			||||||
			}
 | 
					}
 | 
				
			||||||
		},
 | 
					
 | 
				
			||||||
		{
 | 
					/**
 | 
				
			||||||
			type: "m.room.member",
 | 
					 * @param {string} roomID
 | 
				
			||||||
			state_key: "@cadence:cadence.moe",
 | 
					 */
 | 
				
			||||||
			content: {
 | 
					async function roomToKState(roomID) {
 | 
				
			||||||
				membership: "join"
 | 
						/** @type {import("../../types").Event.BaseStateEvent[]} */
 | 
				
			||||||
			}
 | 
						const root = await mreq.mreq("GET", `/client/v3/rooms/${roomID}/state`)
 | 
				
			||||||
		}
 | 
						return stateToKState(root)
 | 
				
			||||||
	])
 | 
					}
 | 
				
			||||||
})
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @params {string} roomID
 | 
				
			||||||
 | 
					 * @params {any} kstate
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function diffKState(actual, target) {
 | 
					function diffKState(actual, target) {
 | 
				
			||||||
	const diff = {}
 | 
						const diff = {}
 | 
				
			||||||
| 
						 | 
					@ -60,39 +83,11 @@ function diffKState(actual, target) {
 | 
				
			||||||
			// not present, needs to be added
 | 
								// not present, needs to be added
 | 
				
			||||||
			diff[key] = target[key]
 | 
								diff[key] = target[key]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// keys that are missing in "actual" will not be deleted on "target" (no action)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return diff
 | 
						return diff
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("diffKState: detects edits", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(
 | 
					 | 
				
			||||||
		diffKState({
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
			"same/": {a: 2}
 | 
					 | 
				
			||||||
		}, {
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "edited name"},
 | 
					 | 
				
			||||||
			"same/": {a: 2}
 | 
					 | 
				
			||||||
		}),
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "edited name"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test("diffKState: detects new properties", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(
 | 
					 | 
				
			||||||
		diffKState({
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
		}, {
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
			"new/": {a: 2}
 | 
					 | 
				
			||||||
		}),
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"new/": {a: 2}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
					 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
					 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
				
			||||||
| 
						 | 
					@ -107,14 +102,14 @@ async function channelToKState(channel, guild) {
 | 
				
			||||||
		avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path)
 | 
							avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const kstate = {
 | 
						const channelKState = {
 | 
				
			||||||
		"m.room.name/": {name: channel.name},
 | 
							"m.room.name/": {name: channel.name},
 | 
				
			||||||
		"m.room.topic/": {topic: channel.topic || undefined},
 | 
							"m.room.topic/": {$if: channel.topic, topic: channel.topic},
 | 
				
			||||||
		"m.room.avatar/": avatarEventContent,
 | 
							"m.room.avatar/": avatarEventContent,
 | 
				
			||||||
		"m.room.guest_access/": {guest_access: "can_join"},
 | 
							"m.room.guest_access/": {guest_access: "can_join"},
 | 
				
			||||||
		"m.room.history_visibility/": {history_visibility: "invited"},
 | 
							"m.room.history_visibility/": {history_visibility: "invited"},
 | 
				
			||||||
		[`m.space.parent/${spaceID}`]: { // TODO: put the proper server here
 | 
							[`m.space.parent/${spaceID}`]: {
 | 
				
			||||||
			via: ["cadence.moe"],
 | 
								via: ["cadence.moe"], // TODO: put the proper server here
 | 
				
			||||||
			canonical: true
 | 
								canonical: true
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"m.room.join_rules/": {
 | 
							"m.room.join_rules/": {
 | 
				
			||||||
| 
						 | 
					@ -126,13 +121,9 @@ async function channelToKState(channel, guild) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return {spaceID, kstate}
 | 
						return {spaceID, channelKState}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("channel2room: general", async t => {
 | 
					 | 
				
			||||||
	t.deepEqual(await channelToKState(testData.channel.general, testData.guild.general).then(x => x.kstate), {expected: true, ...testData.room.general})
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
					 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
				
			||||||
 * @param guild
 | 
					 * @param guild
 | 
				
			||||||
| 
						 | 
					@ -140,7 +131,7 @@ test("channel2room: general", async t => {
 | 
				
			||||||
 * @param {any} kstate
 | 
					 * @param {any} kstate
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function createRoom(channel, guild, spaceID, kstate) {
 | 
					async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
	/** @type {import("../../types").R_RoomCreated} */
 | 
						/** @type {import("../../types").R.RoomCreated} */
 | 
				
			||||||
	const root = await mreq.mreq("POST", "/client/v3/createRoom", {
 | 
						const root = await mreq.mreq("POST", "/client/v3/createRoom", {
 | 
				
			||||||
		name: channel.name,
 | 
							name: channel.name,
 | 
				
			||||||
		topic: channel.topic || undefined,
 | 
							topic: channel.topic || undefined,
 | 
				
			||||||
| 
						 | 
					@ -159,20 +150,46 @@ async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
					 * @param {import("discord-api-types/v10").APIGuildChannel} channel
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function syncRoom(channel) {
 | 
					function channelToGuild(channel) {
 | 
				
			||||||
	const guildID = channel.guild_id
 | 
						const guildID = channel.guild_id
 | 
				
			||||||
	assert(guildID)
 | 
						assert(guildID)
 | 
				
			||||||
	const guild = discord.guilds.get(guildID)
 | 
						const guild = discord.guilds.get(guildID)
 | 
				
			||||||
	assert(guild)
 | 
						assert(guild)
 | 
				
			||||||
 | 
						return guild
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const {spaceID, kstate} = await channelToKState(channel, guild)
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {string} channelID
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function syncRoom(channelID) {
 | 
				
			||||||
 | 
						/** @ts-ignore @type {import("discord-api-types/v10").APIGuildChannel} */
 | 
				
			||||||
 | 
						const channel = discord.channels.get(channelID)
 | 
				
			||||||
 | 
						assert.ok(channel)
 | 
				
			||||||
 | 
						const guild = channelToGuild(channel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const {spaceID, channelKState} = await channelToKState(channel, guild)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** @type {string?} */
 | 
						/** @type {string?} */
 | 
				
			||||||
	const existing = db.prepare("SELECT room_id from channel_room WHERE channel_id = ?").pluck().get(channel.id)
 | 
						const existing = db.prepare("SELECT room_id from channel_room WHERE channel_id = ?").pluck().get(channel.id)
 | 
				
			||||||
	if (!existing) {
 | 
						if (!existing) {
 | 
				
			||||||
		createRoom(channel, guild, spaceID, kstate)
 | 
							return createRoom(channel, guild, spaceID, channelKState)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// sync channel state to room
 | 
				
			||||||
 | 
							const roomKState = await roomToKState(existing)
 | 
				
			||||||
 | 
							const roomDiff = diffKState(roomKState, channelKState)
 | 
				
			||||||
 | 
							const roomApply = applyKStateDiffToRoom(existing, roomDiff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// sync room as space member
 | 
				
			||||||
 | 
							const spaceKState = await roomToKState(spaceID)
 | 
				
			||||||
 | 
							const spaceDiff = diffKState(spaceKState, {
 | 
				
			||||||
 | 
								[`m.space.child/${existing}`]: {
 | 
				
			||||||
 | 
									via: ["cadence.moe"] // TODO: use the proper server
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							const spaceApply = applyKStateDiffToRoom(spaceID, spaceDiff)
 | 
				
			||||||
 | 
							return Promise.all([roomApply, spaceApply])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,14 +197,15 @@ async function createAllForGuild(guildID) {
 | 
				
			||||||
	const channelIDs = discord.guildChannelMap.get(guildID)
 | 
						const channelIDs = discord.guildChannelMap.get(guildID)
 | 
				
			||||||
	assert.ok(channelIDs)
 | 
						assert.ok(channelIDs)
 | 
				
			||||||
	for (const channelID of channelIDs) {
 | 
						for (const channelID of channelIDs) {
 | 
				
			||||||
		const channel = discord.channels.get(channelID)
 | 
							await syncRoom(channelID).then(r => console.log(`synced ${channelID}:`, r))
 | 
				
			||||||
		assert.ok(channel)
 | 
					 | 
				
			||||||
		const existing = db.prepare("SELECT room_id FROM channel_room WHERE channel_id = ?").pluck().get(channel.id)
 | 
					 | 
				
			||||||
		if (channel.type === DiscordTypes.ChannelType.GuildText && !existing) {
 | 
					 | 
				
			||||||
			await createRoom(channel)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.createRoom = createRoom
 | 
					module.exports.createRoom = createRoom
 | 
				
			||||||
 | 
					module.exports.syncRoom = syncRoom
 | 
				
			||||||
module.exports.createAllForGuild = createAllForGuild
 | 
					module.exports.createAllForGuild = createAllForGuild
 | 
				
			||||||
 | 
					module.exports.kstateToState = kstateToState
 | 
				
			||||||
 | 
					module.exports.stateToKState = stateToKState
 | 
				
			||||||
 | 
					module.exports.diffKState = diffKState
 | 
				
			||||||
 | 
					module.exports.channelToKState = channelToKState
 | 
				
			||||||
 | 
					module.exports.kstateStripConditionals = kstateStripConditionals
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										83
									
								
								d2m/actions/create-room.test.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								d2m/actions/create-room.test.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,83 @@
 | 
				
			||||||
 | 
					const {kstateToState, stateToKState, diffKState, channelToKState, kstateStripConditionals} = require("./create-room")
 | 
				
			||||||
 | 
					const {test} = require("supertape")
 | 
				
			||||||
 | 
					const testData = require("../../test/data")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("kstate2state: general", t => {
 | 
				
			||||||
 | 
						t.deepEqual(kstateToState({
 | 
				
			||||||
 | 
							"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
				
			||||||
 | 
						}), [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.name",
 | 
				
			||||||
 | 
								state_key: "",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									name: "test name"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.member",
 | 
				
			||||||
 | 
								state_key: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									membership: "join"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						])
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("state2kstate: general", t => {
 | 
				
			||||||
 | 
						t.deepEqual(stateToKState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.name",
 | 
				
			||||||
 | 
								state_key: "",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									name: "test name"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.member",
 | 
				
			||||||
 | 
								state_key: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									membership: "join"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]), {
 | 
				
			||||||
 | 
							"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("diffKState: detects edits", t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							diffKState({
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
								"same/": {a: 2}
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								"m.room.name/": {name: "edited name"},
 | 
				
			||||||
 | 
								"same/": {a: 2}
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"m.room.name/": {name: "edited name"}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("diffKState: detects new properties", t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							diffKState({
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
								"new/": {a: 2}
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"new/": {a: 2}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("channel2room: general", async t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							kstateStripConditionals(await channelToKState(testData.channel.general, testData.guild.general).then(x => x.channelKState)),
 | 
				
			||||||
 | 
							testData.room.general
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ function createSpace(guild) {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		]
 | 
							]
 | 
				
			||||||
	}).then(/** @param {import("../../types").R_RoomCreated} root */ root => {
 | 
						}).then(/** @param {import("../../types").R.RoomCreated} root */ root => {
 | 
				
			||||||
		db.prepare("INSERT INTO guild_space (guild_id, space_id) VALUES (?, ?)").run(guild.id, root.room_id)
 | 
							db.prepare("INSERT INTO guild_space (guild_id, space_id) VALUES (?, ?)").run(guild.id, root.room_id)
 | 
				
			||||||
		return root
 | 
							return root
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
// @ts-check
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const reg = require("../../matrix/read-registration.js")
 | 
					const reg = require("../../matrix/read-registration.js")
 | 
				
			||||||
const fetch = require("node-fetch")
 | 
					const fetch = require("node-fetch").default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fetch("https://matrix.cadence.moe/_matrix/client/v3/register", {
 | 
					fetch("https://matrix.cadence.moe/_matrix/client/v3/register", {
 | 
				
			||||||
	method: "POST",
 | 
						method: "POST",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								index.js
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								index.js
									
										
									
									
									
								
							| 
						 | 
					@ -22,6 +22,3 @@ passthrough.discord = discord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	require("./stdin")
 | 
						require("./stdin")
 | 
				
			||||||
})()
 | 
					})()
 | 
				
			||||||
 | 
					 | 
				
			||||||
// process.on("unhandledRejection", console.error)
 | 
					 | 
				
			||||||
// process.on("uncaughtException", console.error)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ async function uploadDiscordFileToMxc(path) {
 | 
				
			||||||
		const body = res.body
 | 
							const body = res.body
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Upload to Matrix
 | 
							// Upload to Matrix
 | 
				
			||||||
		/** @type {import("../types").R_FileUploaded} */
 | 
							/** @type {import("../types").R.FileUploaded} */
 | 
				
			||||||
		const root = await mreq.mreq("POST", "/media/v3/upload", body, {
 | 
							const root = await mreq.mreq("POST", "/media/v3/upload", body, {
 | 
				
			||||||
			headers: {
 | 
								headers: {
 | 
				
			||||||
				"Content-Type": res.headers.get("content-type")
 | 
									"Content-Type": res.headers.get("content-type")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,8 +10,9 @@ const reg = sync.require("./read-registration.js")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const baseUrl = "https://matrix.cadence.moe/_matrix"
 | 
					const baseUrl = "https://matrix.cadence.moe/_matrix"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MatrixServerError {
 | 
					class MatrixServerError extends Error {
 | 
				
			||||||
	constructor(data) {
 | 
						constructor(data) {
 | 
				
			||||||
 | 
							super(data.error || data.errcode)
 | 
				
			||||||
		this.data = data
 | 
							this.data = data
 | 
				
			||||||
		/** @type {string} */
 | 
							/** @type {string} */
 | 
				
			||||||
		this.errcode = data.errcode
 | 
							this.errcode = data.errcode
 | 
				
			||||||
| 
						 | 
					@ -35,7 +36,7 @@ async function mreq(method, url, body, extra = {}) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}, extra)
 | 
						}, extra)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	console.log(baseUrl + url, opts)
 | 
						// console.log(baseUrl + url, opts)
 | 
				
			||||||
	const res = await fetch(baseUrl + url, opts)
 | 
						const res = await fetch(baseUrl + url, opts)
 | 
				
			||||||
	const root = await res.json()
 | 
						const root = await res.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										857
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										857
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
										
									
									
									
								
							| 
						 | 
					@ -24,13 +24,15 @@
 | 
				
			||||||
    "matrix-js-sdk": "^24.1.0",
 | 
					    "matrix-js-sdk": "^24.1.0",
 | 
				
			||||||
    "mixin-deep": "^2.0.1",
 | 
					    "mixin-deep": "^2.0.1",
 | 
				
			||||||
    "node-fetch": "^2.6.7",
 | 
					    "node-fetch": "^2.6.7",
 | 
				
			||||||
    "snowtransfer": "^0.7.0",
 | 
					    "snowtransfer": "^0.7.0"
 | 
				
			||||||
    "supertape": "^8.3.0"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@types/node": "^18.16.0"
 | 
					    "@types/node": "^18.16.0",
 | 
				
			||||||
 | 
					    "@types/node-fetch": "^2.6.3",
 | 
				
			||||||
 | 
					    "supertape": "^8.3.0",
 | 
				
			||||||
 | 
					    "tap-dot": "github:cloudrac3r/tap-dot#223a4e67a6f7daf015506a12a7af74605f06c7f4"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "test": "supertape --format short test/test.js"
 | 
					    "test": "FORCE_COLOR=true supertape --format tap test/test.js | tap-dot"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								stdin.js
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								stdin.js
									
										
									
									
									
								
							| 
						 | 
					@ -43,7 +43,7 @@ async function customEval(input, _context, _filename, callback) {
 | 
				
			||||||
		const output = util.inspect(result, false, depth, true)
 | 
							const output = util.inspect(result, false, depth, true)
 | 
				
			||||||
		return callback(null, output)
 | 
							return callback(null, output)
 | 
				
			||||||
	} catch (e) {
 | 
						} catch (e) {
 | 
				
			||||||
		return callback(null, util.inspect(e, true, 100, true))
 | 
							return callback(null, util.inspect(e, false, 100, true))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ module.exports = {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			"m.room.avatar/": {
 | 
								"m.room.avatar/": {
 | 
				
			||||||
				discord_path: "/icons/112760669178241024/a_f83622e09ead74f0c5c527fe241f8f8c.png?size=1024",
 | 
									discord_path: "/icons/112760669178241024/a_f83622e09ead74f0c5c527fe241f8f8c.png?size=1024",
 | 
				
			||||||
				url: "mxc://cadence.moe/sZtPwbfOIsvfSoWCWPrGnzql"
 | 
									url: "mxc://cadence.moe/zKXGZhmImMHuGQZWJEFKJbsF"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,4 +12,4 @@ const sync = new HeatSync({persistent: false})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Object.assign(passthrough, { config, sync, db })
 | 
					Object.assign(passthrough, { config, sync, db })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require("../d2m/actions/create-room")
 | 
					require("../d2m/actions/create-room.test")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -8,17 +8,42 @@ export type AppServiceRegistrationConfig = {
 | 
				
			||||||
	rate_limited: boolean
 | 
						rate_limited: boolean
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type M_Room_Message_content = {
 | 
					namespace Event {
 | 
				
			||||||
	msgtype: "m.text"
 | 
						export type BaseStateEvent = {
 | 
				
			||||||
	body: string
 | 
							type: string
 | 
				
			||||||
	formatted_body?: "org.matrix.custom.html"
 | 
							room_id: string
 | 
				
			||||||
	format?: string
 | 
							sender: string
 | 
				
			||||||
 | 
							content: any
 | 
				
			||||||
 | 
							state_key: string
 | 
				
			||||||
 | 
							origin_server_ts: number
 | 
				
			||||||
 | 
							unsigned: any
 | 
				
			||||||
 | 
							event_id: string
 | 
				
			||||||
 | 
							user_id: string
 | 
				
			||||||
 | 
							age: number
 | 
				
			||||||
 | 
							replaces_state: string
 | 
				
			||||||
 | 
							prev_content?: any
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Room_Message = {
 | 
				
			||||||
 | 
							msgtype: "m.text"
 | 
				
			||||||
 | 
							body: string
 | 
				
			||||||
 | 
							formatted_body?: "org.matrix.custom.html"
 | 
				
			||||||
 | 
							format?: string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export type M_Room_Member = {
 | 
				
			||||||
 | 
							membership: string
 | 
				
			||||||
 | 
							display_name?: string
 | 
				
			||||||
 | 
							avatar_url?: string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type R_RoomCreated = {
 | 
					namespace R {
 | 
				
			||||||
	room_id: string
 | 
						export type RoomCreated = {
 | 
				
			||||||
}
 | 
							room_id: string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type R_FileUploaded = {
 | 
						export type FileUploaded = {
 | 
				
			||||||
	content_uri: string
 | 
							content_uri: string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue