add turndown for m->d formatting
This commit is contained in:
		
							parent
							
								
									27b8c547e3
								
							
						
					
					
						commit
						8c4e16e255
					
				
					 5 changed files with 297 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -2,19 +2,41 @@
 | 
			
		|||
 | 
			
		||||
const Ty = require("../../types")
 | 
			
		||||
const DiscordTypes = require("discord-api-types/v10")
 | 
			
		||||
const markdown = require("discord-markdown")
 | 
			
		||||
const chunk = require("chunk-text")
 | 
			
		||||
const TurndownService = require("turndown")
 | 
			
		||||
 | 
			
		||||
const passthrough = require("../../passthrough")
 | 
			
		||||
const { sync, db, discord } = passthrough
 | 
			
		||||
/** @type {import("../../matrix/file")} */
 | 
			
		||||
const file = sync.require("../../matrix/file")
 | 
			
		||||
 | 
			
		||||
// https://github.com/mixmark-io/turndown/blob/97e4535ca76bb2e70d9caa2aa4d4686956b06d44/src/utilities.js#L26C28-L33C2
 | 
			
		||||
const BLOCK_ELEMENTS = [
 | 
			
		||||
	"ADDRESS", "ARTICLE", "ASIDE", "AUDIO", "BLOCKQUOTE", "BODY", "CANVAS",
 | 
			
		||||
	"CENTER", "DD", "DETAILS", "DIR", "DIV", "DL", "DT", "FIELDSET", "FIGCAPTION", "FIGURE",
 | 
			
		||||
	"FOOTER", "FORM", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER",
 | 
			
		||||
	"HGROUP", "HR", "HTML", "ISINDEX", "LI", "MAIN", "MENU", "NAV", "NOFRAMES",
 | 
			
		||||
	"NOSCRIPT", "OL", "OUTPUT", "P", "PRE", "SECTION", "SUMMARY", "TABLE", "TBODY", "TD",
 | 
			
		||||
	"TFOOT", "TH", "THEAD", "TR", "UL"
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const turndownService = new TurndownService({
 | 
			
		||||
	hr: "----"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
turndownService.addRule("strikethrough", {
 | 
			
		||||
	filter: ["del", "s", "strike"],
 | 
			
		||||
	replacement: function (content) {
 | 
			
		||||
		return "~~" + content + "~~"
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {Ty.Event.Outer<Ty.Event.M_Room_Message>} event
 | 
			
		||||
 */
 | 
			
		||||
function eventToMessage(event) {
 | 
			
		||||
	/** @type {(DiscordTypes.RESTPostAPIWebhookWithTokenJSONBody & {files?: {name: string, file: Buffer}[]})[]} */
 | 
			
		||||
	const messages = []
 | 
			
		||||
	let messages = []
 | 
			
		||||
 | 
			
		||||
	let displayName = event.sender
 | 
			
		||||
	let avatarURL = undefined
 | 
			
		||||
| 
						 | 
				
			
			@ -24,20 +46,51 @@ function eventToMessage(event) {
 | 
			
		|||
		// TODO: get the media repo domain and the avatar url from the matrix member event
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (event.content.msgtype === "m.text") {
 | 
			
		||||
		messages.push({
 | 
			
		||||
			content: event.content.body,
 | 
			
		||||
			username: displayName,
 | 
			
		||||
			avatar_url: avatarURL
 | 
			
		||||
		})
 | 
			
		||||
	} else if (event.content.msgtype === "m.emote") {
 | 
			
		||||
		messages.push({
 | 
			
		||||
			content: `\* _${displayName} ${event.content.body}_`,
 | 
			
		||||
			username: displayName,
 | 
			
		||||
			avatar_url: avatarURL
 | 
			
		||||
		})
 | 
			
		||||
	// Convert content depending on what the message is
 | 
			
		||||
	let content = event.content.body // ultimate fallback
 | 
			
		||||
	if (event.content.format === "org.matrix.custom.html" && event.content.formatted_body) {
 | 
			
		||||
		let input = event.content.formatted_body
 | 
			
		||||
		if (event.content.msgtype === "m.emote") {
 | 
			
		||||
			input = `* ${displayName} ${input}`
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Note: Element's renderers on Web and Android currently collapse whitespace, like the browser does. Turndown also collapses whitespace which is good for me.
 | 
			
		||||
		// If later I'm using a client that doesn't collapse whitespace and I want turndown to follow suit, uncomment the following line of code, and it Just Works:
 | 
			
		||||
		// input = input.replace(/ /g, " ")
 | 
			
		||||
		// There is also a corresponding test to uncomment, named "event2message: whitespace is retained"
 | 
			
		||||
 | 
			
		||||
		// The matrix spec hasn't decided whether \n counts as a newline or not, but I'm going to count it, because if it's in the data it's there for a reason.
 | 
			
		||||
		// But I should not count it if it's between block elements.
 | 
			
		||||
		input = input.replace(/(<\/?([^ >]+)[^>]*>)?\n(<\/?([^ >]+)[^>]*>)?/g, (whole, beforeContext, beforeTag, afterContext, afterTag) => {
 | 
			
		||||
			if (typeof beforeTag !== "string" && typeof afterTag !== "string") {
 | 
			
		||||
				return "<br>"
 | 
			
		||||
			}
 | 
			
		||||
			beforeContext = beforeContext || ""
 | 
			
		||||
			beforeTag = beforeTag || ""
 | 
			
		||||
			afterContext = afterContext || ""
 | 
			
		||||
			afterTag = afterTag || ""
 | 
			
		||||
			if (!BLOCK_ELEMENTS.includes(beforeTag.toUpperCase()) && !BLOCK_ELEMENTS.includes(afterTag.toUpperCase())) {
 | 
			
		||||
				return beforeContext + "<br>" + afterContext
 | 
			
		||||
			} else {
 | 
			
		||||
				return whole
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		// @ts-ignore
 | 
			
		||||
		content = turndownService.turndown(input)
 | 
			
		||||
 | 
			
		||||
		// It's optimised for commonmark, we need to replace the space-space-newline with just newline
 | 
			
		||||
		content = content.replace(/  \n/g, "\n")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Split into 2000 character chunks
 | 
			
		||||
	const chunks = chunk(content, 2000)
 | 
			
		||||
	messages = messages.concat(chunks.map(content => ({
 | 
			
		||||
		content,
 | 
			
		||||
		username: displayName,
 | 
			
		||||
		avatar_url: avatarURL
 | 
			
		||||
	})))
 | 
			
		||||
 | 
			
		||||
	return messages
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,12 @@ const {test} = require("supertape")
 | 
			
		|||
const {eventToMessage} = require("./event-to-message")
 | 
			
		||||
const data = require("../../test/data")
 | 
			
		||||
 | 
			
		||||
function sameFirstContentAndWhitespace(t, a, b) {
 | 
			
		||||
	const a2 = JSON.stringify(a[0].content)
 | 
			
		||||
	const b2 = JSON.stringify(b[0].content)
 | 
			
		||||
	t.equal(a2, b2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test("event2message: janky test", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +34,165 @@ test("event2message: janky test", t => {
 | 
			
		|||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: basic html is converted to markdown", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "this <strong>is</strong> a <strong><em>test</em></strong> of <del>formatting</del>"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "this **is** a **_test_** of ~~formatting~~",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: markdown syntax is escaped", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "this **is** an <strong><em>extreme</em></strong> \\*test\\* of"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "this \\*\\*is\\*\\* an **_extreme_** \\\\\\*test\\\\\\* of",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: html lines are bridged correctly", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "<p>paragraph one<br>line <em>two</em><br>line three<br><br>paragraph two\nline <em>two</em>\nline three\n\nparagraph three</p><p>paragraph four\nline two<br>line three\nline four</p>paragraph five"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "paragraph one\nline _two_\nline three\n\nparagraph two\nline _two_\nline three\n\nparagraph three\n\nparagraph four\nline two\nline three\nline four\n\nparagraph five",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
/*test("event2message: whitespace is retained", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "line one: test       test<br>line two: <strong>test</strong>       <strong>test</strong><br>line three: <strong>test       test</strong><br>line four: test<strong>       </strong>test<br>       line five"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "line one: test       test\nline two: **test**       **test**\nline three: **test       test**\nline four: test       test\n       line five",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})*/
 | 
			
		||||
 | 
			
		||||
test("event2message: whitespace is collapsed", t => {
 | 
			
		||||
	sameFirstContentAndWhitespace(
 | 
			
		||||
		t,
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "line one: test       test<br>line two: <strong>test</strong>       <strong>test</strong><br>line three: <strong>test       test</strong><br>line four: test<strong>       </strong>test<br>       line five"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "line one: test test\nline two: **test** **test**\nline three: **test test**\nline four: test test\nline five",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: lists are bridged correctly", t => {
 | 
			
		||||
	sameFirstContentAndWhitespace(
 | 
			
		||||
		t,
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			"type": "m.room.message",
 | 
			
		||||
			"sender": "@cadence:cadence.moe",
 | 
			
		||||
			"content": {
 | 
			
		||||
				"msgtype": "m.text",
 | 
			
		||||
				"body": "* line one\n* line two\n* line three\n  * nested one\n  * nested two\n* line four",
 | 
			
		||||
				"format": "org.matrix.custom.html",
 | 
			
		||||
				"formatted_body": "<ul>\n<li>line one</li>\n<li>line two</li>\n<li>line three\n<ul>\n<li>nested one</li>\n<li>nested two</li>\n</ul>\n</li>\n<li>line four</li>\n</ul>\n"
 | 
			
		||||
			},
 | 
			
		||||
			"origin_server_ts": 1692967314062,
 | 
			
		||||
			"unsigned": {
 | 
			
		||||
				"age": 112,
 | 
			
		||||
				"transaction_id": "m1692967313951.441"
 | 
			
		||||
			},
 | 
			
		||||
			"event_id": "$l-xQPY5vNJo3SNxU9d8aOWNVD1glMslMyrp4M_JEF70",
 | 
			
		||||
			"room_id": "!BpMdOUkWWhFxmTrENV:cadence.moe"
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "*   line one\n*   line two\n*   line three\n    *   nested one\n    *   nested two\n*   line four",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: long messages are split", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
| 
						 | 
				
			
			@ -55,3 +220,29 @@ test("event2message: long messages are split", t => {
 | 
			
		|||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: m.emote markdown syntax is escaped", t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.emote",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: "shows you **her** <strong><em>extreme</em></strong> \\*test\\* of"
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		[{
 | 
			
		||||
			username: "cadence",
 | 
			
		||||
			content: "\\* cadence shows you \\*\\*her\\*\\* **_extreme_** \\\\\\*test\\\\\\* of",
 | 
			
		||||
			avatar_url: undefined
 | 
			
		||||
		}]
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										37
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										37
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "better-sqlite3": "^8.3.0",
 | 
			
		||||
        "chunk-text": "^2.0.1",
 | 
			
		||||
        "cloudstorm": "^0.8.0",
 | 
			
		||||
        "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#440130ef343c8183a81c7c09809731484aa3a182",
 | 
			
		||||
        "heatsync": "^2.4.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +21,8 @@
 | 
			
		|||
        "node-fetch": "^2.6.7",
 | 
			
		||||
        "prettier-bytes": "^1.0.4",
 | 
			
		||||
        "snowtransfer": "^0.8.0",
 | 
			
		||||
        "try-to-catch": "^3.0.1"
 | 
			
		||||
        "try-to-catch": "^3.0.1",
 | 
			
		||||
        "turndown": "^7.1.2"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@types/node": "^18.16.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -732,6 +734,18 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
 | 
			
		||||
      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/chunk-text": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/chunk-text/-/chunk-text-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-ER6TSpe2DT4wjOVOKJ3FFAYv7wE77HA/Ztz88Peiv3lq/2oVMsItYJJsVVI0xNZM8cdImOOTNqlw+LQz7gYdJg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "runes": "^0.4.3"
 | 
			
		||||
      },
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "chunk": "bin/server.js",
 | 
			
		||||
        "chunk-text": "bin/server.js"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/ci-info": {
 | 
			
		||||
      "version": "3.8.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -1057,6 +1071,11 @@
 | 
			
		|||
        "simple-markdown": "^0.7.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/domino": {
 | 
			
		||||
      "version": "2.1.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz",
 | 
			
		||||
      "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/ee-first": {
 | 
			
		||||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2646,6 +2665,14 @@
 | 
			
		|||
        "node": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/runes": {
 | 
			
		||||
      "version": "0.4.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/runes/-/runes-0.4.3.tgz",
 | 
			
		||||
      "integrity": "sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=4.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/safe-buffer": {
 | 
			
		||||
      "version": "5.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -3216,6 +3243,14 @@
 | 
			
		|||
        "node": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/turndown": {
 | 
			
		||||
      "version": "7.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.1.2.tgz",
 | 
			
		||||
      "integrity": "sha512-ntI9R7fcUKjqBP6QU8rBK2Ehyt8LAzt3UBT9JR9tgo6GtuKvyUzpayWmeMKJw1DPdXzktvtIT8m2mVXz+bL/Qg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "domino": "^2.1.6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/type-is": {
 | 
			
		||||
      "version": "1.6.18",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
  "license": "MIT",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "better-sqlite3": "^8.3.0",
 | 
			
		||||
    "chunk-text": "^2.0.1",
 | 
			
		||||
    "cloudstorm": "^0.8.0",
 | 
			
		||||
    "discord-markdown": "git+https://git.sr.ht/~cadence/nodejs-discord-markdown#440130ef343c8183a81c7c09809731484aa3a182",
 | 
			
		||||
    "heatsync": "^2.4.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +27,8 @@
 | 
			
		|||
    "node-fetch": "^2.6.7",
 | 
			
		||||
    "prettier-bytes": "^1.0.4",
 | 
			
		||||
    "snowtransfer": "^0.8.0",
 | 
			
		||||
    "try-to-catch": "^3.0.1"
 | 
			
		||||
    "try-to-catch": "^3.0.1",
 | 
			
		||||
    "turndown": "^7.1.2"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/node": "^18.16.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -67,7 +67,7 @@ export namespace Event {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	export type M_Room_Message = {
 | 
			
		||||
		msgtype: "m.text"
 | 
			
		||||
		msgtype: "m.text" | "m.emote"
 | 
			
		||||
		body: string
 | 
			
		||||
		format?: "org.matrix.custom.html"
 | 
			
		||||
		formatted_body?: string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue