forked from cadence/out-of-your-element
Emergency sync #11
6 changed files with 62 additions and 163 deletions
|
|
@ -89,7 +89,7 @@ Whether you read those or not, I'm more than happy to help you 1-on-1 with codin
|
|||
|
||||
# Dependency justification
|
||||
|
||||
Total transitive production dependencies: 134
|
||||
Total transitive production dependencies: 121
|
||||
|
||||
### <font size="+2">🦕</font>
|
||||
|
||||
|
|
@ -108,6 +108,7 @@ Total transitive production dependencies: 134
|
|||
* (0) @cloudrac3r/in-your-element: This is my Matrix Appservice API library. It depends on h3 and zod, which are already pulled in by OOYE.
|
||||
* (0) @cloudrac3r/mixin-deep: This is my fork. (It fixes a bug in regular mixin-deep.)
|
||||
* (0) @cloudrac3r/pngjs: Lottie stickers are converted to bitmaps with the vendored Rlottie WASM build, then the bitmaps are converted to PNG with pngjs.
|
||||
* (0) @cloudrac3r/stream-type: Determine type of Matrix files that don't specify it in info. Switched from stream-mime-type to this.
|
||||
* (0) @cloudrac3r/turndown: This HTML-to-Markdown converter looked the most suitable. I forked it to change the escaping logic to match the way Discord works.
|
||||
* (3) @stackoverflow/stacks: Stack Overflow design language and icons.
|
||||
* (0) ansi-colors: Helps with interactive prompting for the initial setup, and it's already pulled in by enquirer.
|
||||
|
|
|
|||
177
package-lock.json
generated
177
package-lock.json
generated
|
|
@ -10,13 +10,14 @@
|
|||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@chriscdn/promise-semaphore": "^3.0.1",
|
||||
"@cloudrac3r/discord-markdown": "^2.6.10",
|
||||
"@cloudrac3r/discord-markdown": "^2.7.0",
|
||||
"@cloudrac3r/giframe": "^0.4.3",
|
||||
"@cloudrac3r/html-template-tag": "^5.0.1",
|
||||
"@cloudrac3r/in-your-element": "^1.1.1",
|
||||
"@cloudrac3r/mixin-deep": "^3.0.1",
|
||||
"@cloudrac3r/pngjs": "^7.0.3",
|
||||
"@cloudrac3r/pug": "^4.0.4",
|
||||
"@cloudrac3r/stream-type": "^1.0.0",
|
||||
"@cloudrac3r/turndown": "^7.1.4",
|
||||
"@stackoverflow/stacks": "^2.5.4",
|
||||
"@stackoverflow/stacks-icons": "^6.0.2",
|
||||
|
|
@ -37,7 +38,6 @@
|
|||
"prettier-bytes": "^1.0.4",
|
||||
"sharp": "^0.34.5",
|
||||
"snowtransfer": "^0.17.5",
|
||||
"stream-mime-type": "^1.0.2",
|
||||
"try-to-catch": "^4.0.5",
|
||||
"uqr": "^0.1.2",
|
||||
"xxhash-wasm": "^1.0.2",
|
||||
|
|
@ -68,6 +68,22 @@
|
|||
"ts-node": "^10.9.2"
|
||||
}
|
||||
},
|
||||
"../nodejs-stream-type": {
|
||||
"name": "@cloudrac3r/stream-type",
|
||||
"version": "1.0.0",
|
||||
"license": "AGPL-3.0-only",
|
||||
"devDependencies": {
|
||||
"@cloudrac3r/tap-dot": "^2.0.3",
|
||||
"@types/node": "^22.19.15",
|
||||
"c8": "^11.0.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"supertape": "^12.10.4",
|
||||
"try-to-catch": "^4.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.6.0"
|
||||
}
|
||||
},
|
||||
"../tap-dot": {
|
||||
"name": "@cloudrac3r/tap-dot",
|
||||
"version": "2.0.0",
|
||||
|
|
@ -156,9 +172,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@cloudrac3r/discord-markdown": {
|
||||
"version": "2.6.10",
|
||||
"resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.6.10.tgz",
|
||||
"integrity": "sha512-E+F9UYDUHP2kHDCciX63SBzgsUnHpu2Pp/h98x9Zo+vKuzXjCQ5PcFNdUlH6M18bvHDZPoIsKVmjnON8UYaAPQ==",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@cloudrac3r/discord-markdown/-/discord-markdown-2.7.0.tgz",
|
||||
"integrity": "sha512-1iR9tKI2WJe8UNB+4VSh7D8m6RP7ugByuf8RNWyJwyhIrSlqQ8ljY1BKXodSvDg7seZkf7B7V2t5FfK7UpTw/A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"simple-markdown": "^0.7.3"
|
||||
|
|
@ -246,6 +262,10 @@
|
|||
"pug-error": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cloudrac3r/stream-type": {
|
||||
"resolved": "../nodejs-stream-type",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@cloudrac3r/tap-dot": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@cloudrac3r/tap-dot/-/tap-dot-2.0.3.tgz",
|
||||
|
|
@ -1027,11 +1047,6 @@
|
|||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@tokenizer/token": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
||||
|
|
@ -1616,22 +1631,6 @@
|
|||
"node": ">= 4.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/file-type": {
|
||||
"version": "16.5.4",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
|
||||
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
|
||||
"dependencies": {
|
||||
"readable-web-to-node-stream": "^3.0.0",
|
||||
"strtok3": "^6.2.4",
|
||||
"token-types": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
|
|
@ -1654,10 +1653,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||
"dev": true
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz",
|
||||
"integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
|
|
@ -2183,18 +2183,6 @@
|
|||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/peek-readable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
|
||||
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
|
||||
|
|
@ -2362,34 +2350,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readable-web-to-node-stream": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
|
||||
"integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
|
||||
"dependencies": {
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-web-to-node-stream/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
|
|
@ -2625,30 +2585,6 @@
|
|||
"get-source": "^2.0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/stream-head": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stream-head/-/stream-head-2.0.2.tgz",
|
||||
"integrity": "sha512-aRkUMcmgbDl2Yjd5LqsB1LKB58Ot3JZ4ffuFMkFuvkPQT5X5XFMr4YK2dctApc+d3o52CXU1KUFisYaF/4zjAQ==",
|
||||
"dependencies": {
|
||||
"through2": "4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/stream-mime-type": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stream-mime-type/-/stream-mime-type-1.0.2.tgz",
|
||||
"integrity": "sha512-80GzRn7JICPDEPBhSyqJjbztqX66+3DpkuUUcgDHtRBQlZRTkbCz0BsISggUl7AnyinJk9zyHVnd2lftlZXDdg==",
|
||||
"dependencies": {
|
||||
"file-type": "^16.0.1",
|
||||
"mime-types": "^2.1.27",
|
||||
"stream-head": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
|
|
@ -2700,22 +2636,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strtok3": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
|
||||
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"peek-readable": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/supertape": {
|
||||
"version": "12.7.0",
|
||||
"resolved": "https://registry.npmjs.org/supertape/-/supertape-12.7.0.tgz",
|
||||
|
|
@ -2845,27 +2765,6 @@
|
|||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/through2": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
|
||||
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
|
||||
"dependencies": {
|
||||
"readable-stream": "3"
|
||||
}
|
||||
},
|
||||
"node_modules/through2/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/timer-node": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/timer-node/-/timer-node-5.0.9.tgz",
|
||||
|
|
@ -2878,22 +2777,6 @@
|
|||
"resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg=="
|
||||
},
|
||||
"node_modules/token-types": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
|
||||
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"ieee754": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/try-catch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/try-catch/-/try-catch-4.0.7.tgz",
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@chriscdn/promise-semaphore": "^3.0.1",
|
||||
"@cloudrac3r/discord-markdown": "^2.6.10",
|
||||
"@cloudrac3r/discord-markdown": "^2.7.0",
|
||||
"@cloudrac3r/giframe": "^0.4.3",
|
||||
"@cloudrac3r/html-template-tag": "^5.0.1",
|
||||
"@cloudrac3r/in-your-element": "^1.1.1",
|
||||
"@cloudrac3r/mixin-deep": "^3.0.1",
|
||||
"@cloudrac3r/pngjs": "^7.0.3",
|
||||
"@cloudrac3r/pug": "^4.0.4",
|
||||
"@cloudrac3r/stream-type": "^1.0.0",
|
||||
"@cloudrac3r/turndown": "^7.1.4",
|
||||
"@stackoverflow/stacks": "^2.5.4",
|
||||
"@stackoverflow/stacks-icons": "^6.0.2",
|
||||
|
|
@ -46,7 +47,6 @@
|
|||
"prettier-bytes": "^1.0.4",
|
||||
"sharp": "^0.34.5",
|
||||
"snowtransfer": "^0.17.5",
|
||||
"stream-mime-type": "^1.0.2",
|
||||
"try-to-catch": "^4.0.5",
|
||||
"uqr": "^0.1.2",
|
||||
"xxhash-wasm": "^1.0.2",
|
||||
|
|
|
|||
|
|
@ -977,6 +977,21 @@ test("message2event: written @mentions do not match in inline code", async t =>
|
|||
}])
|
||||
})
|
||||
|
||||
test("message2event: written @mentions do not match in code block", async t => {
|
||||
const events = await messageToEvent({
|
||||
...data.message.advanced_written_at_mention_for_matrix,
|
||||
content: "```java\npublic @Nullable EntityType<?>\n```"
|
||||
}, data.guild.general, {}, {})
|
||||
t.deepEqual(events, [{
|
||||
$type: "m.room.message",
|
||||
"m.mentions": {},
|
||||
msgtype: "m.text",
|
||||
body: "```java\npublic @Nullable EntityType<?>\n```",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: `<pre><code class="language-java">public @Nullable EntityType<?></code></pre>`
|
||||
}])
|
||||
})
|
||||
|
||||
test("message2event: entire message may match elaborate display name", async t => {
|
||||
let called = 0
|
||||
const events = await messageToEvent({
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const sharp = require("sharp")
|
|||
const api = sync.require("../../matrix/api")
|
||||
/** @type {import("../../matrix/mreq")} */
|
||||
const mreq = sync.require("../../matrix/mreq")
|
||||
const streamMimeType = require("stream-mime-type")
|
||||
const {streamType} = require("@cloudrac3r/stream-type")
|
||||
|
||||
const WIDTH = 160
|
||||
const HEIGHT = 160
|
||||
|
|
@ -26,13 +26,13 @@ async function getAndResizeSticker(mxc) {
|
|||
}
|
||||
|
||||
const streamIn = Readable.fromWeb(res.body)
|
||||
const { stream, mime } = await streamMimeType.getMimeType(streamIn)
|
||||
const animated = ["image/gif", "image/webp"].includes(mime)
|
||||
const {streamThrough, type} = await streamType(streamIn)
|
||||
const animated = ["image/gif", "image/webp"].includes(type)
|
||||
|
||||
const transformer = sharp({animated: animated})
|
||||
.resize(WIDTH, HEIGHT, {fit: "inside", background: {r: 0, g: 0, b: 0, alpha: 0}})
|
||||
.webp()
|
||||
stream.pipe(transformer)
|
||||
streamThrough.pipe(transformer)
|
||||
return Readable.toWeb(transformer)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const {pipeline} = require("stream").promises
|
|||
const sharp = require("sharp")
|
||||
const {GIFrame} = require("@cloudrac3r/giframe")
|
||||
const {PNG} = require("@cloudrac3r/pngjs")
|
||||
const streamMimeType = require("stream-mime-type")
|
||||
const {streamType} = require("@cloudrac3r/stream-type")
|
||||
|
||||
const SIZE = 48
|
||||
const RESULT_WIDTH = 400
|
||||
|
|
@ -54,11 +54,11 @@ async function compositeMatrixEmojis(mxcs, mxcDownloader) {
|
|||
* @returns {Promise<Buffer | undefined>} Uncompressed PNG image
|
||||
*/
|
||||
async function convertImageStream(streamIn, stopStream) {
|
||||
const {stream, mime} = await streamMimeType.getMimeType(streamIn)
|
||||
assert(["image/png", "image/jpeg", "image/webp", "image/gif", "image/apng"].includes(mime), `Mime type ${mime} is impossible for emojis`)
|
||||
const {streamThrough, type} = await streamType(streamIn)
|
||||
assert(["image/png", "image/jpeg", "image/webp", "image/gif", "image/apng"].includes(type), `Mime type ${type} is impossible for emojis`)
|
||||
|
||||
try {
|
||||
if (mime === "image/png" || mime === "image/jpeg" || mime === "image/webp") {
|
||||
if (type === "image/png" || type === "image/jpeg" || type === "image/webp") {
|
||||
/** @type {{info: sharp.OutputInfo, buffer: Buffer}} */
|
||||
const result = await new Promise((resolve, reject) => {
|
||||
const transformer = sharp()
|
||||
|
|
@ -70,15 +70,15 @@ async function convertImageStream(streamIn, stopStream) {
|
|||
resolve({info, buffer})
|
||||
})
|
||||
pipeline(
|
||||
stream,
|
||||
streamThrough,
|
||||
transformer
|
||||
)
|
||||
})
|
||||
return result.buffer
|
||||
|
||||
} else if (mime === "image/gif") {
|
||||
} else if (type === "image/gif") {
|
||||
const giframe = new GIFrame(0)
|
||||
stream.on("data", chunk => {
|
||||
streamThrough.on("data", chunk => {
|
||||
giframe.feed(chunk)
|
||||
})
|
||||
const frame = await giframe.getFrame()
|
||||
|
|
@ -91,10 +91,10 @@ async function convertImageStream(streamIn, stopStream) {
|
|||
.toBuffer({resolveWithObject: true})
|
||||
return buffer.data
|
||||
|
||||
} else if (mime === "image/apng") {
|
||||
} else if (type === "image/apng") {
|
||||
const png = new PNG({maxFrames: 1})
|
||||
// @ts-ignore
|
||||
stream.pipe(png)
|
||||
streamThrough.pipe(png)
|
||||
/** @type {Buffer} */ // @ts-ignore
|
||||
const frame = await new Promise(resolve => png.on("parsed", resolve))
|
||||
stopStream()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue