diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-06-13 07:13:19 +0000 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-06-13 07:13:19 +0000 |
| commit | 4b11fd2523a9d6352683ec9fe5aa5af69e370870 (patch) | |
| tree | 5679bf3ef1a89e399692fc4e76b966ac2a2f18f4 | |
| parent | merge: Make defederation rocket use theme colors. (!1109) (diff) | |
| parent | downgrade htmlparser2 to match cheerio (diff) | |
| download | sharkey-4b11fd2523a9d6352683ec9fe5aa5af69e370870.tar.gz sharkey-4b11fd2523a9d6352683ec9fe5aa5af69e370870.tar.bz2 sharkey-4b11fd2523a9d6352683ec9fe5aa5af69e370870.zip | |
merge: Consolidate duplicate HTML/XML parser libraries (!1083)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1083
Approved-by: Marie <github@yuugi.dev>
Approved-by: dakkar <dakkar@thenautilus.net>
50 files changed, 1030 insertions, 1336 deletions
diff --git a/package.json b/package.json index dfa7afda02..609836b8ee 100644 --- a/package.json +++ b/package.json @@ -54,17 +54,7 @@ "lodash": "4.17.21" }, "dependencies": { - "cssnano": "7.0.6", - "esbuild": "0.25.3", - "execa": "9.5.2", - "fast-glob": "3.3.3", - "glob": "11.0.2", - "ignore-walk": "7.0.0", - "js-yaml": "4.1.0", - "postcss": "8.5.3", - "tar": "7.4.3", - "terser": "5.39.0", - "typescript": "5.8.3" + "js-yaml": "4.1.0" }, "optionalDependencies": { "cypress": "14.3.2" @@ -75,10 +65,20 @@ "@typescript-eslint/eslint-plugin": "8.31.0", "@typescript-eslint/parser": "8.31.0", "cross-env": "7.0.3", + "cssnano": "7.0.6", + "esbuild": "0.25.3", "eslint": "9.25.1", - "globals": "16.0.0", + "execa": "9.5.2", + "fast-glob": "3.3.3", + "glob": "11.0.2", + "globals": "16.1.0", "ncp": "2.0.0", - "pnpm": "10.10.0", - "start-server-and-test": "2.0.11" + "pnpm": "9.6.0", + "ignore-walk": "7.0.0", + "postcss": "8.5.3", + "start-server-and-test": "2.0.11", + "tar": "7.4.3", + "terser": "5.39.0", + "typescript": "5.8.3" } } diff --git a/packages/backend/package.json b/packages/backend/package.json index bad6990ba5..5ec6ededba 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -80,7 +80,7 @@ "@fastify/static": "8.1.1", "@fastify/view": "10.0.2", "@misskey-dev/sharp-read-bmp": "1.3.0", - "@misskey-dev/summaly": "5.2.1", + "@misskey-dev/summaly": "npm:@transfem-org/summaly@5.2.2", "@nestjs/common": "11.1.0", "@nestjs/core": "11.1.0", "@nestjs/testing": "11.1.0", @@ -90,33 +90,30 @@ "@simplewebauthn/server": "12.0.0", "@sinonjs/fake-timers": "11.3.1", "@smithy/node-http-handler": "2.5.0", - "@swc/cli": "0.7.3", - "@swc/core": "1.11.24", - "@transfem-org/sfm-js": "0.24.6", + "mfm-js": "npm:@transfem-org/sfm-js@0.24.6", "@twemoji/parser": "15.1.1", "accepts": "1.3.8", "ajv": "8.17.1", "archiver": "7.0.1", - "argon2": "^0.40.1", + "argon2": "0.43.0", "axios": "1.7.4", - "async-mutex": "0.5.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", - "body-parser": "1.20.3", "bullmq": "5.51.1", "cacheable-lookup": "7.0.0", - "canvas": "^3.1.0", + "canvas": "3.1.0", "cbor": "9.0.2", "chalk": "5.4.1", "chalk-template": "1.1.0", "cheerio": "1.0.0", - "chokidar": "3.6.0", - "cli-highlight": "2.1.11", + "cli-highlight": "npm:@transfem-org/cli-highlight@2.1.12", "color-convert": "2.0.1", "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fast-xml-parser": "4.4.1", + "dom-serializer": "2.0.0", + "domhandler": "5.0.3", + "domutils": "3.2.2", "fastify": "5.3.2", "fastify-raw-body": "5.0.0", "feed": "4.2.2", @@ -125,10 +122,9 @@ "form-data": "4.0.2", "glob": "11.0.0", "got": "14.4.7", - "happy-dom": "16.8.1", "hpagent": "1.2.0", "htmlescape": "1.1.1", - "http-link-header": "1.1.3", + "htmlparser2": "9.1.0", "ioredis": "5.6.1", "ip-cidr": "4.0.2", "ipaddr.js": "2.2.0", @@ -136,49 +132,39 @@ "js-yaml": "4.1.0", "json5": "2.2.3", "jsonld": "8.3.3", - "jsrsasign": "11.1.0", "juice": "11.0.1", "megalodon": "workspace:*", "meilisearch": "0.50.0", - "microformats-parser": "2.0.2", "mime-types": "2.1.35", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", - "moment": "^2.30.1", + "moment": "2.30.1", "ms": "3.0.0-canary.1", "nanoid": "5.1.5", "nested-property": "4.0.0", "node-fetch": "3.3.2", "nodemailer": "6.10.1", - "oauth": "0.10.2", - "oauth2orize": "1.12.0", - "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", "otpauth": "9.4.0", - "parse5": "7.3.0", "pg": "8.15.6", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", - "proxy-addr": "^2.0.7", - "psl": "^1.13.0", + "proxy-addr": "2.0.7", + "psl": "1.15.0", "pug": "3.0.3", "qrcode": "1.5.4", "random-seed": "0.3.0", - "ratelimiter": "3.4.1", "re2": "1.21.4", "redis-info": "3.1.0", "redis-lock": "0.1.4", "reflect-metadata": "0.2.2", "rename": "1.0.4", - "rss-parser": "3.13.0", - "rxjs": "7.8.2", "sanitize-html": "2.16.0", "secure-json-parse": "3.0.2", "sharp": "0.34.1", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", - "stringz": "2.1.0", "systeminformation": "5.25.11", "tinycolor2": "1.6.0", "tmp": "0.2.3", @@ -187,7 +173,7 @@ "typeorm": "0.3.22", "typescript": "5.8.3", "ulid": "2.4.0", - "uuid": "^9.0.1", + "uuid": "11.1.0", "vary": "1.1.2", "web-push": "3.6.7", "ws": "8.18.1", @@ -198,16 +184,16 @@ "@nestjs/platform-express": "11.1.0", "@sentry/vue": "9.14.0", "@simplewebauthn/types": "12.0.0", + "@swc/cli": "0.7.3", + "@swc/core": "1.11.24", "@swc/jest": "0.2.38", "@types/accepts": "1.3.7", "@types/archiver": "6.0.3", "@types/bcryptjs": "2.4.6", - "@types/body-parser": "1.19.5", "@types/color-convert": "2.0.4", "@types/content-disposition": "0.5.8", "@types/fluent-ffmpeg": "2.1.27", "@types/htmlescape": "1.1.3", - "@types/http-link-header": "1.0.7", "@types/jest": "29.5.14", "@types/js-yaml": "4.0.9", "@types/jsonld": "1.5.15", @@ -220,12 +206,11 @@ "@types/oauth2orize": "1.11.5", "@types/oauth2orize-pkce": "0.1.2", "@types/pg": "8.11.14", - "@types/proxy-addr": "^2.0.3", - "@types/psl": "^1.1.3", + "@types/proxy-addr": "2.0.3", + "@types/psl": "1.1.3", "@types/pug": "2.0.10", "@types/qrcode": "1.5.5", "@types/random-seed": "0.3.5", - "@types/ratelimiter": "3.4.6", "@types/redis-info": "3.0.3", "@types/rename": "1.0.7", "@types/sanitize-html": "2.15.0", @@ -235,7 +220,6 @@ "@types/supertest": "6.0.3", "@types/tinycolor2": "1.4.6", "@types/tmp": "0.2.6", - "@types/uuid": "^9.0.4", "@types/vary": "1.1.3", "@types/web-push": "3.6.4", "@types/ws": "8.18.1", @@ -244,7 +228,7 @@ "aws-sdk-client-mock": "4.1.0", "cross-env": "7.0.3", "eslint-plugin-import": "2.31.0", - "execa": "8.0.1", + "execa": "9.5.2", "fkill": "9.0.0", "jest": "29.7.0", "jest-mock": "29.7.0", diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 9bfd7381f1..6fcfdfb596 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -7,7 +7,7 @@ import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import tinycolor from 'tinycolor2'; import * as Redis from 'ioredis'; -import { load as cheerio } from 'cheerio'; +import { load as cheerio } from 'cheerio/slim'; import type { MiInstance } from '@/models/Instance.js'; import type Logger from '@/logger.js'; import { DI } from '@/di-symbols.js'; @@ -16,7 +16,7 @@ import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { renderInlineError } from '@/misc/render-inline-error.js'; -import type { CheerioAPI } from 'cheerio'; +import type { CheerioAPI } from 'cheerio/slim'; type NodeInfo = { openRegistrations?: unknown; diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index 1ee3bd2275..551b25394a 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -5,25 +5,22 @@ import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; -import * as parse5 from 'parse5'; -import { type Document, type HTMLParagraphElement, Window } from 'happy-dom'; +import { isText, isTag, Text } from 'domhandler'; +import * as htmlparser2 from 'htmlparser2'; +import { Node, Document, ChildNode, Element, ParentNode } from 'domhandler'; +import * as domserializer from 'dom-serializer'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { intersperse } from '@/misc/prelude/array.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import type { IMentionedRemoteUsers } from '@/models/Note.js'; import { bindThis } from '@/decorators.js'; -import type { DefaultTreeAdapterMap } from 'parse5'; -import type * as mfm from '@transfem-org/sfm-js'; - -const treeAdapter = parse5.defaultTreeAdapter; -type Node = DefaultTreeAdapterMap['node']; -type ChildNode = DefaultTreeAdapterMap['childNode']; +import type * as mfm from 'mfm-js'; const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/; const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/; -export type Appender = (document: Document, body: HTMLParagraphElement) => void; +export type Appender = (document: Document, body: Element) => void; @Injectable() export class MfmService { @@ -40,7 +37,7 @@ export class MfmService { const normalizedHashtagNames = hashtagNames == null ? undefined : new Set<string>(hashtagNames.map(x => normalizeForSearch(x))); - const dom = parse5.parseFragment(html); + const dom = htmlparser2.parseDocument(html); let text = ''; @@ -51,37 +48,31 @@ export class MfmService { return text.trim(); function getText(node: Node): string { - if (treeAdapter.isTextNode(node)) return node.value; - if (!treeAdapter.isElementNode(node)) return ''; - if (node.nodeName === 'br') return '\n'; - - if (node.childNodes) { - return node.childNodes.map(n => getText(n)).join(''); - } + if (isText(node)) return node.data; + if (!isTag(node)) return ''; + if (node.tagName === 'br') return '\n'; - return ''; + return node.childNodes.map(n => getText(n)).join(''); } function appendChildren(childNodes: ChildNode[]): void { - if (childNodes) { - for (const n of childNodes) { - analyze(n); - } + for (const n of childNodes) { + analyze(n); } } function analyze(node: Node) { - if (treeAdapter.isTextNode(node)) { - text += node.value; + if (isText(node)) { + text += node.data; return; } // Skip comment or document type node - if (!treeAdapter.isElementNode(node)) { + if (!isTag(node)) { return; } - switch (node.nodeName) { + switch (node.tagName) { case 'br': { text += '\n'; break; @@ -89,19 +80,19 @@ export class MfmService { case 'a': { const txt = getText(node); - const rel = node.attrs.find(x => x.name === 'rel'); - const href = node.attrs.find(x => x.name === 'href'); + const rel = node.attribs.rel; + const href = node.attribs.href; // ハッシュタグ if (normalizedHashtagNames && href && normalizedHashtagNames.has(normalizeForSearch(txt))) { text += txt; // メンション - } else if (txt.startsWith('@') && !(rel && rel.value.startsWith('me '))) { + } else if (txt.startsWith('@') && !(rel && rel.startsWith('me '))) { const part = txt.split('@'); if (part.length === 2 && href) { //#region ホスト名部分が省略されているので復元する - const acct = `${txt}@${(new URL(href.value)).hostname}`; + const acct = `${txt}@${(new URL(href)).hostname}`; text += acct; //#endregion } else if (part.length === 3) { @@ -116,17 +107,17 @@ export class MfmService { if (!href) { return txt; } - if (!txt || txt === href.value) { // #6383: Missing text node - if (href.value.match(urlRegexFull)) { - return href.value; + if (!txt || txt === href) { // #6383: Missing text node + if (href.match(urlRegexFull)) { + return href; } else { - return `<${href.value}>`; + return `<${href}>`; } } - if (href.value.match(urlRegex) && !href.value.match(urlRegexFull)) { - return `[${txt}](<${href.value}>)`; // #6846 + if (href.match(urlRegex) && !href.match(urlRegexFull)) { + return `[${txt}](<${href}>)`; // #6846 } else { - return `[${txt}](${href.value})`; + return `[${txt}](${href})`; } }; @@ -185,14 +176,17 @@ export class MfmService { case 'ruby--': { let ruby: [string, string][] = []; for (const child of node.childNodes) { - if (child.nodeName === 'rp') { + if (isText(child) && !/\s|\[|\]/.test(child.data)) { + ruby.push([child.data, '']); + continue; + } + if (!isTag(child)) { continue; } - if (treeAdapter.isTextNode(child) && !/\s|\[|\]/.test(child.value)) { - ruby.push([child.value, '']); + if (child.tagName === 'rp') { continue; } - if (child.nodeName === 'rt' && ruby.length > 0) { + if (child.tagName === 'rt' && ruby.length > 0) { const rt = getText(child); if (/\s|\[|\]/.test(rt)) { // If any space is included in rt, it is treated as a normal text @@ -217,7 +211,7 @@ export class MfmService { // block code (<pre><code>) case 'pre': { - if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') { + if (node.childNodes.length === 1 && isTag(node.childNodes[0]) && node.childNodes[0].tagName === 'code') { text += '\n```\n'; text += getText(node.childNodes[0]); text += '\n```\n'; @@ -302,17 +296,17 @@ export class MfmService { let nonRtNodes = []; // scan children, ignore `rp`, split on `rt` for (const child of node.childNodes) { - if (treeAdapter.isTextNode(child)) { + if (isText(child)) { nonRtNodes.push(child); continue; } - if (!treeAdapter.isElementNode(child)) { + if (!isTag(child)) { continue; } - if (child.nodeName === 'rp') { + if (child.tagName === 'rp') { continue; } - if (child.nodeName === 'rt') { + if (child.tagName === 'rt') { // the only case in which we don't need a `$[group ]` // is when both sides of the ruby are simple words const needsGroup = nonRtNodes.length > 1 || @@ -350,45 +344,44 @@ export class MfmService { return null; } - const { happyDOM, window } = new Window(); - - const doc = window.document; + const doc = new Document([]); - const body = doc.createElement('p'); + const body = new Element('p', {}); + doc.childNodes.push(body); - function appendChildren(children: mfm.MfmNode[], targetElement: any): void { - if (children) { - for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child); + function appendChildren(children: mfm.MfmNode[], targetElement: ParentNode): void { + for (const child of children.map(x => handle(x))) { + targetElement.childNodes.push(child); } } function fnDefault(node: mfm.MfmFn) { - const el = doc.createElement('i'); + const el = new Element('i', {}); appendChildren(node.children, el); return el; } - const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => any } = { + const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => ChildNode } = { bold: (node) => { - const el = doc.createElement('b'); + const el = new Element('b', {}); appendChildren(node.children, el); return el; }, small: (node) => { - const el = doc.createElement('small'); + const el = new Element('small', {}); appendChildren(node.children, el); return el; }, strike: (node) => { - const el = doc.createElement('del'); + const el = new Element('del', {}); appendChildren(node.children, el); return el; }, italic: (node) => { - const el = doc.createElement('i'); + const el = new Element('i', {}); appendChildren(node.children, el); return el; }, @@ -399,11 +392,12 @@ export class MfmService { const text = node.children[0].type === 'text' ? node.children[0].props.text : ''; try { const date = new Date(parseInt(text, 10) * 1000); - const el = doc.createElement('time'); - el.setAttribute('datetime', date.toISOString()); - el.textContent = date.toISOString(); + const el = new Element('time', { + datetime: date.toISOString(), + }); + el.childNodes.push(new Text(date.toISOString())); return el; - } catch (err) { + } catch { return fnDefault(node); } } @@ -412,20 +406,20 @@ export class MfmService { if (node.children.length === 1) { const child = node.children[0]; const text = child.type === 'text' ? child.props.text : ''; - const rubyEl = doc.createElement('ruby'); - const rtEl = doc.createElement('rt'); + const rubyEl = new Element('ruby', {}); + const rtEl = new Element('rt', {}); // ruby未対応のHTMLサニタイザーを通したときにルビが「劉備(りゅうび)」となるようにする - const rpStartEl = doc.createElement('rp'); - rpStartEl.appendChild(doc.createTextNode('(')); - const rpEndEl = doc.createElement('rp'); - rpEndEl.appendChild(doc.createTextNode(')')); + const rpStartEl = new Element('rp', {}); + rpStartEl.childNodes.push(new Text('(')); + const rpEndEl = new Element('rp', {}); + rpEndEl.childNodes.push(new Text(')')); - rubyEl.appendChild(doc.createTextNode(text.split(' ')[0])); - rtEl.appendChild(doc.createTextNode(text.split(' ')[1])); - rubyEl.appendChild(rpStartEl); - rubyEl.appendChild(rtEl); - rubyEl.appendChild(rpEndEl); + rubyEl.childNodes.push(new Text(text.split(' ')[0])); + rtEl.childNodes.push(new Text(text.split(' ')[1])); + rubyEl.childNodes.push(rpStartEl); + rubyEl.childNodes.push(rtEl); + rubyEl.childNodes.push(rpEndEl); return rubyEl; } else { const rt = node.children.at(-1); @@ -435,20 +429,20 @@ export class MfmService { } const text = rt.type === 'text' ? rt.props.text : ''; - const rubyEl = doc.createElement('ruby'); - const rtEl = doc.createElement('rt'); + const rubyEl = new Element('ruby', {}); + const rtEl = new Element('rt', {}); // ruby未対応のHTMLサニタイザーを通したときにルビが「劉備(りゅうび)」となるようにする - const rpStartEl = doc.createElement('rp'); - rpStartEl.appendChild(doc.createTextNode('(')); - const rpEndEl = doc.createElement('rp'); - rpEndEl.appendChild(doc.createTextNode(')')); + const rpStartEl = new Element('rp', {}); + rpStartEl.childNodes.push(new Text('(')); + const rpEndEl = new Element('rp', {}); + rpEndEl.childNodes.push(new Text(')')); appendChildren(node.children.slice(0, node.children.length - 1), rubyEl); - rtEl.appendChild(doc.createTextNode(text.trim())); - rubyEl.appendChild(rpStartEl); - rubyEl.appendChild(rtEl); - rubyEl.appendChild(rpEndEl); + rtEl.childNodes.push(new Text(text.trim())); + rubyEl.childNodes.push(rpStartEl); + rubyEl.childNodes.push(rtEl); + rubyEl.childNodes.push(rpEndEl); return rubyEl; } } @@ -456,7 +450,7 @@ export class MfmService { // hack for ruby, should never be needed because we should // never send this out to other instances case 'group': { - const el = doc.createElement('span'); + const el = new Element('span', {}); appendChildren(node.children, el); return el; } @@ -468,125 +462,135 @@ export class MfmService { }, blockCode: (node) => { - const pre = doc.createElement('pre'); - const inner = doc.createElement('code'); - inner.textContent = node.props.code; - pre.appendChild(inner); + const pre = new Element('pre', {}); + const inner = new Element('code', {}); + inner.childNodes.push(new Text(node.props.code)); + pre.childNodes.push(inner); return pre; }, center: (node) => { - const el = doc.createElement('div'); + const el = new Element('div', {}); appendChildren(node.children, el); return el; }, emojiCode: (node) => { - return doc.createTextNode(`\u200B:${node.props.name}:\u200B`); + return new Text(`\u200B:${node.props.name}:\u200B`); }, unicodeEmoji: (node) => { - return doc.createTextNode(node.props.emoji); + return new Text(node.props.emoji); }, hashtag: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', `${this.config.url}/tags/${node.props.hashtag}`); - a.textContent = `#${node.props.hashtag}`; - a.setAttribute('rel', 'tag'); + const a = new Element('a', { + href: `${this.config.url}/tags/${node.props.hashtag}`, + rel: 'tag', + }); + a.childNodes.push(new Text(`#${node.props.hashtag}`)); return a; }, inlineCode: (node) => { - const el = doc.createElement('code'); - el.textContent = node.props.code; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.code)); return el; }, mathInline: (node) => { - const el = doc.createElement('code'); - el.textContent = node.props.formula; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.formula)); return el; }, mathBlock: (node) => { - const el = doc.createElement('code'); - el.textContent = node.props.formula; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.formula)); return el; }, link: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', node.props.url); + const a = new Element('a', { + href: node.props.url, + }); appendChildren(node.children, a); return a; }, mention: (node) => { - const a = doc.createElement('a'); const { username, host, acct } = node.props; const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username.toLowerCase() === username.toLowerCase() && remoteUser.host?.toLowerCase() === host?.toLowerCase()); - a.setAttribute('href', remoteUserInfo - ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) - : `${this.config.url}/${acct.endsWith(`@${this.config.url}`) ? acct.substring(0, acct.length - this.config.url.length - 1) : acct}`); - a.className = 'u-url mention'; - a.textContent = acct; + + const a = new Element('a', { + href: remoteUserInfo + ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) + : `${this.config.url}/${acct.endsWith(`@${this.config.url}`) ? acct.substring(0, acct.length - this.config.url.length - 1) : acct}`, + class: 'u-url mention', + }); + a.childNodes.push(new Text(acct)); return a; }, quote: (node) => { - const el = doc.createElement('blockquote'); + const el = new Element('blockquote', {}); appendChildren(node.children, el); return el; }, text: (node) => { if (!node.props.text.match(/[\r\n]/)) { - return doc.createTextNode(node.props.text); + return new Text(node.props.text); } - const el = doc.createElement('span'); - const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x)); + const el = new Element('span', {}); + const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => new Text(x)); for (const x of intersperse<FIXME | 'br'>('br', nodes)) { - el.appendChild(x === 'br' ? doc.createElement('br') : x); + el.childNodes.push(x === 'br' ? new Element('br', {}) : x); } return el; }, url: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', node.props.url); - a.textContent = node.props.url; + const a = new Element('a', { + href: node.props.url, + }); + a.childNodes.push(new Text(node.props.url)); return a; }, search: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', `https://www.google.com/search?q=${node.props.query}`); - a.textContent = node.props.content; + const a = new Element('a', { + href: `https://www.google.com/search?q=${node.props.query}`, + }); + a.childNodes.push(new Text(node.props.content)); return a; }, plain: (node) => { - const el = doc.createElement('span'); + const el = new Element('span', {}); appendChildren(node.children, el); return el; }, }; + // Utility function to make TypeScript behave + function handle<T extends mfm.MfmNode>(node: T): ChildNode { + const handler = handlers[node.type] as (node: T) => ChildNode; + return handler(node); + } + appendChildren(nodes, body); for (const additionalAppender of additionalAppenders) { additionalAppender(doc, body); } - const serialized = body.outerHTML; - - happyDOM.close().catch(err => {}); - - return serialized; + return domserializer.render(body, { + encodeEntities: 'utf8' + }); } // the toMastoApiHtml function was taken from Iceshrimp and written by zotan and modified by marie to work with the current MK version @@ -598,55 +602,55 @@ export class MfmService { return null; } - const { happyDOM, window } = new Window(); - - const doc = window.document; + const doc = new Document([]); - const body = doc.createElement('p'); + const body = new Element('p', {}); + doc.childNodes.push(body); - function appendChildren(children: mfm.MfmNode[], targetElement: any): void { - if (children) { - for (const child of children.map((x) => (handlers as any)[x.type](x))) targetElement.appendChild(child); + function appendChildren(children: mfm.MfmNode[], targetElement: ParentNode): void { + for (const child of children) { + const result = handle(child); + targetElement.childNodes.push(result); } } const handlers: { - [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => any; + [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => ChildNode; } = { bold(node) { - const el = doc.createElement('span'); - el.textContent = '**'; + const el = new Element('span', {}); + el.childNodes.push(new Text('**')); appendChildren(node.children, el); - el.textContent += '**'; + el.childNodes.push(new Text('**')); return el; }, small(node) { - const el = doc.createElement('small'); + const el = new Element('small', {}); appendChildren(node.children, el); return el; }, strike(node) { - const el = doc.createElement('span'); - el.textContent = '~~'; + const el = new Element('span', {}); + el.childNodes.push(new Text('~~')); appendChildren(node.children, el); - el.textContent += '~~'; + el.childNodes.push(new Text('~~')); return el; }, italic(node) { - const el = doc.createElement('span'); - el.textContent = '*'; + const el = new Element('span', {}); + el.childNodes.push(new Text('*')); appendChildren(node.children, el); - el.textContent += '*'; + el.childNodes.push(new Text('*')); return el; }, fn(node) { switch (node.props.name) { case 'group': { // hack for ruby - const el = doc.createElement('span'); + const el = new Element('span', {}); appendChildren(node.children, el); return el; } @@ -654,119 +658,121 @@ export class MfmService { if (node.children.length === 1) { const child = node.children[0]; const text = child.type === 'text' ? child.props.text : ''; - const rubyEl = doc.createElement('ruby'); - const rtEl = doc.createElement('rt'); + const rubyEl = new Element('ruby', {}); + const rtEl = new Element('rt', {}); - const rpStartEl = doc.createElement('rp'); - rpStartEl.appendChild(doc.createTextNode('(')); - const rpEndEl = doc.createElement('rp'); - rpEndEl.appendChild(doc.createTextNode(')')); + const rpStartEl = new Element('rp', {}); + rpStartEl.childNodes.push(new Text('(')); + const rpEndEl = new Element('rp', {}); + rpEndEl.childNodes.push(new Text(')')); - rubyEl.appendChild(doc.createTextNode(text.split(' ')[0])); - rtEl.appendChild(doc.createTextNode(text.split(' ')[1])); - rubyEl.appendChild(rpStartEl); - rubyEl.appendChild(rtEl); - rubyEl.appendChild(rpEndEl); + rubyEl.childNodes.push(new Text(text.split(' ')[0])); + rtEl.childNodes.push(new Text(text.split(' ')[1])); + rubyEl.childNodes.push(rpStartEl); + rubyEl.childNodes.push(rtEl); + rubyEl.childNodes.push(rpEndEl); return rubyEl; } else { const rt = node.children.at(-1); if (!rt) { - const el = doc.createElement('span'); + const el = new Element('span', {}); appendChildren(node.children, el); return el; } const text = rt.type === 'text' ? rt.props.text : ''; - const rubyEl = doc.createElement('ruby'); - const rtEl = doc.createElement('rt'); + const rubyEl = new Element('ruby', {}); + const rtEl = new Element('rt', {}); - const rpStartEl = doc.createElement('rp'); - rpStartEl.appendChild(doc.createTextNode('(')); - const rpEndEl = doc.createElement('rp'); - rpEndEl.appendChild(doc.createTextNode(')')); + const rpStartEl = new Element('rp', {}); + rpStartEl.childNodes.push(new Text('(')); + const rpEndEl = new Element('rp', {}); + rpEndEl.childNodes.push(new Text(')')); appendChildren(node.children.slice(0, node.children.length - 1), rubyEl); - rtEl.appendChild(doc.createTextNode(text.trim())); - rubyEl.appendChild(rpStartEl); - rubyEl.appendChild(rtEl); - rubyEl.appendChild(rpEndEl); + rtEl.childNodes.push(new Text(text.trim())); + rubyEl.childNodes.push(rpStartEl); + rubyEl.childNodes.push(rtEl); + rubyEl.childNodes.push(rpEndEl); return rubyEl; } } default: { - const el = doc.createElement('span'); - el.textContent = '*'; + const el = new Element('span', {}); + el.childNodes.push(new Text('*')); appendChildren(node.children, el); - el.textContent += '*'; + el.childNodes.push(new Text('*')); return el; } } }, blockCode(node) { - const pre = doc.createElement('pre'); - const inner = doc.createElement('code'); + const pre = new Element('pre', {}); + const inner = new Element('code', {}); const nodes = node.props.code .split(/\r\n|\r|\n/) - .map((x) => doc.createTextNode(x)); + .map((x) => new Text(x)); for (const x of intersperse<FIXME | 'br'>('br', nodes)) { - inner.appendChild(x === 'br' ? doc.createElement('br') : x); + inner.childNodes.push(x === 'br' ? new Element('br', {}) : x); } - pre.appendChild(inner); + pre.childNodes.push(inner); return pre; }, center(node) { - const el = doc.createElement('div'); + const el = new Element('div', {}); appendChildren(node.children, el); return el; }, emojiCode(node) { - return doc.createTextNode(`\u200B:${node.props.name}:\u200B`); + return new Text(`\u200B:${node.props.name}:\u200B`); }, unicodeEmoji(node) { - return doc.createTextNode(node.props.emoji); + return new Text(node.props.emoji); }, hashtag: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', `${this.config.url}/tags/${node.props.hashtag}`); - a.textContent = `#${node.props.hashtag}`; - a.setAttribute('rel', 'tag'); - a.setAttribute('class', 'hashtag'); + const a = new Element('a', { + href: `${this.config.url}/tags/${node.props.hashtag}`, + rel: 'tag', + class: 'hashtag', + }); + a.childNodes.push(new Text(`#${node.props.hashtag}`)); return a; }, inlineCode(node) { - const el = doc.createElement('code'); - el.textContent = node.props.code; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.code)); return el; }, mathInline(node) { - const el = doc.createElement('code'); - el.textContent = node.props.formula; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.formula)); return el; }, mathBlock(node) { - const el = doc.createElement('code'); - el.textContent = node.props.formula; + const el = new Element('code', {}); + el.childNodes.push(new Text(node.props.formula)); return el; }, link(node) { - const a = doc.createElement('a'); - a.setAttribute('rel', 'nofollow noopener noreferrer'); - a.setAttribute('target', '_blank'); - a.setAttribute('href', node.props.url); + const a = new Element('a', { + rel: 'nofollow noopener noreferrer', + target: '_blank', + href: node.props.url, + }); appendChildren(node.children, a); return a; }, @@ -775,92 +781,107 @@ export class MfmService { const { username, host, acct } = node.props; const resolved = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host); - const el = doc.createElement('span'); + const el = new Element('span', {}); if (!resolved) { - el.textContent = acct; + el.childNodes.push(new Text(acct)); } else { - el.setAttribute('class', 'h-card'); - el.setAttribute('translate', 'no'); - const a = doc.createElement('a'); - a.setAttribute('href', resolved.url ? resolved.url : resolved.uri); - a.className = 'u-url mention'; - const span = doc.createElement('span'); - span.textContent = resolved.username || username; - a.textContent = '@'; - a.appendChild(span); - el.appendChild(a); + el.attribs.class = 'h-card'; + el.attribs.translate = 'no'; + const a = new Element('a', { + href: resolved.url ? resolved.url : resolved.uri, + class: 'u-url mention', + }); + const span = new Element('span', {}); + span.childNodes.push(new Text(resolved.username || username)); + a.childNodes.push(new Text('@')); + a.childNodes.push(span); + el.childNodes.push(a); } return el; }, quote(node) { - const el = doc.createElement('blockquote'); + const el = new Element('blockquote', {}); appendChildren(node.children, el); return el; }, text(node) { - const el = doc.createElement('span'); + if (!node.props.text.match(/[\r\n]/)) { + return new Text(node.props.text); + } + + const el = new Element('span', {}); const nodes = node.props.text .split(/\r\n|\r|\n/) - .map((x) => doc.createTextNode(x)); + .map((x) => new Text(x)); for (const x of intersperse<FIXME | 'br'>('br', nodes)) { - el.appendChild(x === 'br' ? doc.createElement('br') : x); + el.childNodes.push(x === 'br' ? new Element('br', {}) : x); } return el; }, url(node) { - const a = doc.createElement('a'); - a.setAttribute('rel', 'nofollow noopener noreferrer'); - a.setAttribute('target', '_blank'); - a.setAttribute('href', node.props.url); - a.textContent = node.props.url.replace(/^https?:\/\//, ''); + const a = new Element('a', { + rel: 'nofollow noopener noreferrer', + target: '_blank', + href: node.props.url, + }); + a.childNodes.push(new Text(node.props.url.replace(/^https?:\/\//, ''))); return a; }, search: (node) => { - const a = doc.createElement('a'); - a.setAttribute('href', `https://www.google.com/search?q=${node.props.query}`); - a.textContent = node.props.content; + const a = new Element('a', { + href: `https://www.google.com/search?q=${node.props.query}`, + }); + a.childNodes.push(new Text(node.props.content)); return a; }, plain(node) { - const el = doc.createElement('span'); + const el = new Element('span', {}); appendChildren(node.children, el); return el; }, }; + // Utility function to make TypeScript behave + function handle<T extends mfm.MfmNode>(node: T): ChildNode { + const handler = handlers[node.type] as (node: T) => ChildNode; + return handler(node); + } + appendChildren(nodes, body); if (quoteUri !== null) { - const a = doc.createElement('a'); - a.setAttribute('href', quoteUri); - a.textContent = quoteUri.replace(/^https?:\/\//, ''); + const a = new Element('a', { + href: quoteUri, + }); + a.childNodes.push(new Text(quoteUri.replace(/^https?:\/\//, ''))); - const quote = doc.createElement('span'); - quote.setAttribute('class', 'quote-inline'); - quote.appendChild(doc.createElement('br')); - quote.appendChild(doc.createElement('br')); - quote.innerHTML += 'RE: '; - quote.appendChild(a); + const quote = new Element('span', { + class: 'quote-inline', + }); + quote.childNodes.push(new Element('br', {})); + quote.childNodes.push(new Element('br', {})); + quote.childNodes.push(new Text('RE: ')); + quote.childNodes.push(a); - body.appendChild(quote); + body.childNodes.push(quote); } - let result = body.outerHTML; + let result = domserializer.render(body, { + encodeEntities: 'utf8' + }); if (inline) { result = result.replace(/^<p>/, '').replace(/<\/p>$/, ''); } - happyDOM.close().catch(() => {}); - return result; } } diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index a9f4083446..f8584a4a48 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -4,7 +4,7 @@ */ import { setImmediate } from 'node:timers/promises'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { In, DataSource, IsNull, LessThan } from 'typeorm'; import * as Redis from 'ioredis'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts index a359381573..d963bf1945 100644 --- a/packages/backend/src/core/NoteEditService.ts +++ b/packages/backend/src/core/NoteEditService.ts @@ -4,7 +4,7 @@ */ import { setImmediate } from 'node:timers/promises'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { DataSource, In, IsNull, LessThan } from 'typeorm'; import * as Redis from 'ioredis'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; diff --git a/packages/backend/src/core/WebfingerService.ts b/packages/backend/src/core/WebfingerService.ts index 664963f3a3..bb9f0be4c6 100644 --- a/packages/backend/src/core/WebfingerService.ts +++ b/packages/backend/src/core/WebfingerService.ts @@ -5,7 +5,7 @@ import { URL } from 'node:url'; import { Injectable } from '@nestjs/common'; -import { XMLParser } from 'fast-xml-parser'; +import { load as cheerio } from 'cheerio/slim'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; import type Logger from '@/logger.js'; @@ -101,14 +101,12 @@ export class WebfingerService { private async fetchWebFingerTemplateFromHostMeta(url: string): Promise<string | null> { try { const res = await this.httpRequestService.getHtml(url, 'application/xrd+xml'); - const options = { - ignoreAttributes: false, - isArray: (_name: string, jpath: string) => jpath === 'XRD.Link', - }; - const parser = new XMLParser(options); - const hostMeta = parser.parse(res); - const template = (hostMeta['XRD']['Link'] as Array<any>).filter(p => p['@_rel'] === 'lrdd')[0]['@_template']; - return template.indexOf('{uri}') < 0 ? null : template; + const hostMeta = cheerio(res, { + xml: true, + }); + + const template = hostMeta('XRD > Link[rel="lrdd"][template*="{uri}"]').attr('template'); + return template ?? null; } catch (err) { this.logger.error(`error while request host-meta for ${url}: ${renderInlineError(err)}`); return null; diff --git a/packages/backend/src/core/activitypub/ApMfmService.ts b/packages/backend/src/core/activitypub/ApMfmService.ts index c4a948429a..ddb6461746 100644 --- a/packages/backend/src/core/activitypub/ApMfmService.ts +++ b/packages/backend/src/core/activitypub/ApMfmService.ts @@ -4,7 +4,7 @@ */ import { Injectable } from '@nestjs/common'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { MfmService, Appender } from '@/core/MfmService.js'; import type { MiNote } from '@/models/Note.js'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 6068d707de..08a8f30049 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -6,8 +6,9 @@ import { createPublicKey, randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { UnrecoverableError } from 'bullmq'; +import { Element, Text } from 'domhandler'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js'; @@ -475,16 +476,18 @@ export class ApRendererService { // the claas name `quote-inline` is used in non-misskey clients for styling quote notes. // For compatibility, the span part should be kept as possible. apAppend.push((doc, body) => { - body.appendChild(doc.createElement('br')); - body.appendChild(doc.createElement('br')); - const span = doc.createElement('span'); - span.className = 'quote-inline'; - span.appendChild(doc.createTextNode('RE: ')); - const link = doc.createElement('a'); - link.setAttribute('href', quote); - link.textContent = quote; - span.appendChild(link); - body.appendChild(span); + body.childNodes.push(new Element('br', {})); + body.childNodes.push(new Element('br', {})); + const span = new Element('span', { + class: 'quote-inline', + }); + span.childNodes.push(new Text('RE: ')); + const link = new Element('a', { + href: quote, + }); + link.childNodes.push(new Text(quote)); + span.childNodes.push(link); + body.childNodes.push(span); }); } @@ -839,16 +842,18 @@ export class ApRendererService { // the claas name `quote-inline` is used in non-misskey clients for styling quote notes. // For compatibility, the span part should be kept as possible. apAppend.push((doc, body) => { - body.appendChild(doc.createElement('br')); - body.appendChild(doc.createElement('br')); - const span = doc.createElement('span'); - span.className = 'quote-inline'; - span.appendChild(doc.createTextNode('RE: ')); - const link = doc.createElement('a'); - link.setAttribute('href', quote); - link.textContent = quote; - span.appendChild(link); - body.appendChild(span); + body.childNodes.push(new Element('br', {})); + body.childNodes.push(new Element('br', {})); + const span = new Element('span', { + class: 'quote-inline', + }); + span.childNodes.push(new Text('RE: ')); + const link = new Element('a', { + href: quote, + }); + link.childNodes.push(new Text(quote)); + span.childNodes.push(link); + body.childNodes.push(span); }); } diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index 4c7cac2169..e4db9b237c 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -6,7 +6,7 @@ import * as crypto from 'node:crypto'; import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; -import { Window } from 'happy-dom'; +import { load as cheerio } from 'cheerio/slim'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import type { MiUser } from '@/models/User.js'; @@ -18,6 +18,8 @@ import { bindThis } from '@/decorators.js'; import type Logger from '@/logger.js'; import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js'; import type { IObject, IObjectWithId } from './type.js'; +import type { Cheerio, CheerioAPI } from 'cheerio/slim'; +import type { AnyNode } from 'domhandler'; type Request = { url: string; @@ -219,53 +221,33 @@ export class ApRequestService { (contentType ?? '').split(';')[0].trimEnd().toLowerCase() === 'text/html' && _followAlternate === true ) { - const html = await res.text(); - const { window, happyDOM } = new Window({ - settings: { - disableJavaScriptEvaluation: true, - disableJavaScriptFileLoading: true, - disableCSSFileLoading: true, - disableComputedStyleRendering: true, - handleDisabledFileLoadingAsSuccess: true, - navigation: { - disableMainFrameNavigation: true, - disableChildFrameNavigation: true, - disableChildPageNavigation: true, - disableFallbackToSetURL: true, - }, - timer: { - maxTimeout: 0, - maxIntervalTime: 0, - maxIntervalIterations: 0, - }, - }, - }); - const document = window.document; + let alternate: Cheerio<AnyNode> | null; try { - document.documentElement.innerHTML = html; + const html = await res.text(); + const document = cheerio(html); // Search for any matching value in priority order: // 1. Type=AP > Type=none > Type=anything // 2. Alternate > Canonical // 3. Page order (fallback) - const alternate = - document.querySelector('head > link[href][rel="alternate"][type="application/activity+json"]') ?? - document.querySelector('head > link[href][rel="canonical"][type="application/activity+json"]') ?? - document.querySelector('head > link[href][rel="alternate"]:not([type])') ?? - document.querySelector('head > link[href][rel="canonical"]:not([type])') ?? - document.querySelector('head > link[href][rel="alternate"]') ?? - document.querySelector('head > link[href][rel="canonical"]'); - - if (alternate) { - const href = alternate.getAttribute('href'); - if (href && this.apUtilityService.haveSameAuthority(url, href)) { - return await this.signedGet(href, user, allowAnonymous, false); - } - } + alternate = selectFirst(document, [ + 'head > link[href][rel="alternate"][type="application/activity+json"]', + 'head > link[href][rel="canonical"][type="application/activity+json"]', + 'head > link[href][rel="alternate"]:not([type])', + 'head > link[href][rel="canonical"]:not([type])', + 'head > link[href][rel="alternate"]', + 'head > link[href][rel="canonical"]', + ]); } catch { // something went wrong parsing the HTML, ignore the whole thing - } finally { - happyDOM.close().catch(err => {}); + alternate = null; + } + + if (alternate) { + const href = alternate.attr('href'); + if (href && this.apUtilityService.haveSameAuthority(url, href)) { + return await this.signedGet(href, user, allowAnonymous, false); + } } } //#endregion @@ -285,3 +267,14 @@ export class ApRequestService { return activity as IObjectWithId; } } + +function selectFirst($: CheerioAPI, selectors: string[]): Cheerio<AnyNode> | null { + for (const selector of selectors) { + const selection = $(selector); + if (selection.length > 0) { + return selection; + } + } + + return null; +} diff --git a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts index 36a9b8e1f4..73ae9abb54 100644 --- a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts +++ b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { unique } from '@/misc/prelude/array.js'; export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] { diff --git a/packages/backend/src/misc/extract-hashtags.ts b/packages/backend/src/misc/extract-hashtags.ts index ed7606d995..d3d245d414 100644 --- a/packages/backend/src/misc/extract-hashtags.ts +++ b/packages/backend/src/misc/extract-hashtags.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { unique } from '@/misc/prelude/array.js'; export function extractHashtags(nodes: mfm.MfmNode[]): string[] { diff --git a/packages/backend/src/misc/extract-mentions.ts b/packages/backend/src/misc/extract-mentions.ts index bb21c32ffb..2ec9349718 100644 --- a/packages/backend/src/misc/extract-mentions.ts +++ b/packages/backend/src/misc/extract-mentions.ts @@ -5,7 +5,7 @@ // test is located in test/extract-mentions -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] { // TODO: 重複を削除 diff --git a/packages/backend/src/misc/truncate.ts b/packages/backend/src/misc/truncate.ts index 1c8a274609..a313ab7854 100644 --- a/packages/backend/src/misc/truncate.ts +++ b/packages/backend/src/misc/truncate.ts @@ -3,14 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { substring } from 'stringz'; - export function truncate(input: string, size: number): string; export function truncate(input: string | undefined, size: number): string | undefined; export function truncate(input: string | undefined, size: number): string | undefined { if (!input) { return input; } else { - return substring(input, 0, size); + return input.slice(0, size); } } diff --git a/packages/backend/src/misc/verify-field-link.ts b/packages/backend/src/misc/verify-field-link.ts index 62542eaaa0..f9fc352806 100644 --- a/packages/backend/src/misc/verify-field-link.ts +++ b/packages/backend/src/misc/verify-field-link.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { load as cheerio } from 'cheerio'; +import { load as cheerio } from 'cheerio/slim'; import type { HttpRequestService } from '@/core/HttpRequestService.js'; type Field = { name: string, value: string }; diff --git a/packages/backend/src/server/api/endpoints/fetch-rss.ts b/packages/backend/src/server/api/endpoints/fetch-rss.ts index 03f35f16a5..11244b30f6 100644 --- a/packages/backend/src/server/api/endpoints/fetch-rss.ts +++ b/packages/backend/src/server/api/endpoints/fetch-rss.ts @@ -3,12 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import Parser from 'rss-parser'; import { Injectable } from '@nestjs/common'; +import { parseFeed } from 'htmlparser2'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; - -const rssParser = new Parser(); +import { ApiError } from '../error.js'; +import type { FeedItem } from 'domutils'; export const meta = { tags: ['meta'], @@ -17,52 +17,32 @@ export const meta = { allowGet: true, cacheSec: 60 * 3, + errors: { + fetchFailed: { + id: '88f4356f-719d-4715-b4fc-703a10a812d2', + code: 'FETCH_FAILED', + message: 'Failed to fetch RSS feed', + }, + }, + res: { type: 'object', properties: { - image: { - type: 'object', + type: { + type: 'string', + optional: false, + }, + id: { + type: 'string', optional: true, - properties: { - link: { - type: 'string', - optional: true, - }, - url: { - type: 'string', - optional: false, - }, - title: { - type: 'string', - optional: true, - }, - }, }, - paginationLinks: { - type: 'object', + updated: { + type: 'string', + optional: true, + }, + author: { + type: 'string', optional: true, - properties: { - self: { - type: 'string', - optional: true, - }, - first: { - type: 'string', - optional: true, - }, - next: { - type: 'string', - optional: true, - }, - last: { - type: 'string', - optional: true, - }, - prev: { - type: 'string', - optional: true, - }, - }, }, link: { type: 'string', @@ -94,113 +74,42 @@ export const meta = { type: 'string', optional: true, }, - creator: { - type: 'string', - optional: true, - }, - summary: { - type: 'string', - optional: true, - }, - content: { - type: 'string', - optional: true, - }, - isoDate: { + description: { type: 'string', optional: true, }, - categories: { + media: { type: 'array', - optional: true, + optional: false, items: { - type: 'string', - }, - }, - contentSnippet: { - type: 'string', - optional: true, - }, - enclosure: { - type: 'object', - optional: true, - properties: { - url: { - type: 'string', - optional: false, - }, - length: { - type: 'number', - optional: true, - }, - type: { - type: 'string', - optional: true, + type: 'object', + properties: { + medium: { + type: 'string', + optional: true, + }, + url: { + type: 'string', + optional: true, + }, + type: { + type: 'string', + optional: true, + }, + lang: { + type: 'string', + optional: true, + }, }, }, }, }, }, }, - feedUrl: { - type: 'string', - optional: true, - }, description: { type: 'string', optional: true, }, - itunes: { - type: 'object', - optional: true, - additionalProperties: true, - properties: { - image: { - type: 'string', - optional: true, - }, - owner: { - type: 'object', - optional: true, - properties: { - name: { - type: 'string', - optional: true, - }, - email: { - type: 'string', - optional: true, - }, - }, - }, - author: { - type: 'string', - optional: true, - }, - summary: { - type: 'string', - optional: true, - }, - explicit: { - type: 'string', - optional: true, - }, - categories: { - type: 'array', - optional: true, - items: { - type: 'string', - }, - }, - keywords: { - type: 'array', - optional: true, - items: { - type: 'string', - }, - }, - }, - }, }, }, @@ -224,7 +133,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- constructor( private httpRequestService: HttpRequestService, ) { - super(meta, paramDef, async (ps, me) => { + super(meta, paramDef, async (ps) => { const res = await this.httpRequestService.send(ps.url, { method: 'GET', headers: { @@ -234,8 +143,38 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); const text = await res.text(); + const feed = parseFeed(text, { + xmlMode: true, + }); + + if (!feed) { + throw new ApiError(meta.errors.fetchFailed); + } - return rssParser.parseString(text); + return { + type: feed.type, + id: feed.id, + title: feed.title, + link: feed.link, + description: feed.description, + updated: feed.updated?.toISOString(), + author: feed.author, + items: feed.items + .filter((item): item is FeedItem & { link: string, title: string } => !!item.link && !!item.title) + .map(item => ({ + guid: item.id, + title: item.title, + link: item.link, + description: item.description, + pubDate: item.pubDate?.toISOString(), + media: item.media.map(media => ({ + medium: media.medium, + url: media.url, + type: media.type, + lang: media.lang, + })), + })), + }; }); } } diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index e632915f62..5767880531 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; diff --git a/packages/backend/src/server/api/mastodon/MastodonConverters.ts b/packages/backend/src/server/api/mastodon/MastodonConverters.ts index 02ce31c4f8..df8d68042a 100644 --- a/packages/backend/src/server/api/mastodon/MastodonConverters.ts +++ b/packages/backend/src/server/api/mastodon/MastodonConverters.ts @@ -5,7 +5,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Entity, MastodonEntity, MisskeyEntity } from 'megalodon'; -import mfm from '@transfem-org/sfm-js'; +import mfm from 'mfm-js'; import { MastodonNotificationType } from 'megalodon/lib/src/mastodon/notification.js'; import { NotificationType } from 'megalodon/lib/src/notification.js'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index dcd4d80303..a622ae7e34 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -15,7 +15,7 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; import { MfmService } from "@/core/MfmService.js"; -import { parse as mfmParse } from '@transfem-org/sfm-js'; +import { parse as mfmParse } from 'mfm-js'; @Injectable() export class FeedService { diff --git a/packages/backend/test/e2e/oauth.ts b/packages/backend/test/e2e/oauth.ts index 47851e9474..1dc8d87593 100644 --- a/packages/backend/test/e2e/oauth.ts +++ b/packages/backend/test/e2e/oauth.ts @@ -19,7 +19,7 @@ import { ResourceOwnerPassword, } from 'simple-oauth2'; import pkceChallenge from 'pkce-challenge'; -import { load as cheerio } from 'cheerio'; +import { load as cheerio } from 'cheerio/slim'; import Fastify, { type FastifyInstance, type FastifyReply } from 'fastify'; import { api, port, sendEnvUpdateRequest, signup } from '../utils.js'; import type * as misskey from 'misskey-js'; diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts index e54c006a4f..af1fc4e132 100644 --- a/packages/backend/test/unit/MfmService.ts +++ b/packages/backend/test/unit/MfmService.ts @@ -4,7 +4,7 @@ */ import * as assert from 'assert'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { Test } from '@nestjs/testing'; import { CoreModule } from '@/core/CoreModule.js'; @@ -86,7 +86,7 @@ describe('MfmService', () => { test('ruby', async () => { const input = '$[ruby $[group *some* text] ignore me]'; - const output = '<p><ruby><span><span>*some*</span><span> text</span></span><rp>(</rp><rt>ignore me</rt><rp>)</rp></ruby></p>'; + const output = '<p><ruby><span><span>*some*</span> text</span><rp>(</rp><rt>ignore me</rt><rp>)</rp></ruby></p>'; assert.equal(await mfmService.toMastoApiHtml(mfm.parse(input)), output); }); }); diff --git a/packages/backend/test/unit/extract-mentions.ts b/packages/backend/test/unit/extract-mentions.ts index 2aad89d65b..3403387e30 100644 --- a/packages/backend/test/unit/extract-mentions.ts +++ b/packages/backend/test/unit/extract-mentions.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; -import { parse } from '@transfem-org/sfm-js'; +import { parse } from 'mfm-js'; import { extractMentions } from '@/misc/extract-mentions.js'; describe('Extract mentions', () => { diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 7f2768488f..5da5353e09 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -11,12 +11,12 @@ import { inspect } from 'node:util'; import WebSocket, { ClientOptions } from 'ws'; import fetch, { File, RequestInit, type Headers } from 'node-fetch'; import { DataSource } from 'typeorm'; -import { load as cheerio } from 'cheerio'; +import { load as cheerio } from 'cheerio/slim'; import { type Response } from 'node-fetch'; import Fastify from 'fastify'; import { entities } from '../src/postgres.js'; import { loadConfig } from '../src/config.js'; -import type { CheerioAPI } from 'cheerio'; +import type { CheerioAPI } from 'cheerio/slim'; import type * as misskey from 'misskey-js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js'; diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json index 1a851df49b..6cdfd8f3f1 100644 --- a/packages/frontend-embed/package.json +++ b/packages/frontend-embed/package.json @@ -11,35 +11,25 @@ }, "dependencies": { "@discordapp/twemoji": "15.1.0", - "@phosphor-icons/web": "^2.0.3", - "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-replace": "6.0.2", - "@rollup/pluginutils": "5.1.4", - "@transfem-org/sfm-js": "0.24.5", - "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.2.3", - "@vue/compiler-sfc": "3.5.14", - "astring": "1.9.0", + "@phosphor-icons/web": "2.1.2", + "mfm-js": "npm:@transfem-org/sfm-js@0.24.6", "buraha": "0.0.1", - "estree-walker": "3.0.3", "frontend-shared": "workspace:*", "json5": "2.2.3", "misskey-js": "workspace:*", "punycode.js": "2.3.1", - "rollup": "4.40.0", - "sass": "1.87.0", "shiki": "3.3.0", "tinycolor2": "1.6.0", - "tsc-alias": "1.8.15", - "tsconfig-paths": "4.2.0", - "typescript": "5.8.3", "uuid": "11.1.0", - "vite": "6.3.3", "vue": "3.5.14" }, "devDependencies": { - "@misskey-dev/summaly": "5.2.1", + "@misskey-dev/summaly": "npm:@transfem-org/summaly@5.2.2", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-replace": "6.0.2", + "@rollup/pluginutils": "5.1.4", "@testing-library/vue": "8.1.0", + "@twemoji/parser": "15.1.1", "@types/estree": "1.0.7", "@types/micromatch": "4.0.9", "@types/node": "22.15.2", @@ -48,12 +38,16 @@ "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "8.31.0", "@typescript-eslint/parser": "8.31.0", + "@vitejs/plugin-vue": "5.2.3", "@vitest/coverage-v8": "3.1.2", + "@vue/compiler-sfc": "3.5.14", "@vue/runtime-core": "3.5.14", "acorn": "8.14.1", + "astring": "1.9.0", "cross-env": "7.0.3", "eslint-plugin-import": "2.31.0", "eslint-plugin-vue": "10.0.0", + "estree-walker": "3.0.3", "fast-glob": "3.3.3", "happy-dom": "17.4.4", "intersection-observer": "0.12.2", @@ -61,7 +55,13 @@ "msw": "2.7.5", "nodemon": "3.1.10", "prettier": "3.5.3", + "rollup": "4.40.0", + "sass": "1.87.0", "start-server-and-test": "2.0.11", + "tsc-alias": "1.8.15", + "tsconfig-paths": "4.2.0", + "typescript": "5.8.3", + "vite": "6.3.3", "vite-plugin-turbosnap": "1.0.3", "vue-component-type-helpers": "2.2.10", "vue-eslint-parser": "10.1.3", diff --git a/packages/frontend-embed/src/components/EmMfm.ts b/packages/frontend-embed/src/components/EmMfm.ts index d377d492e0..74ae3373ef 100644 --- a/packages/frontend-embed/src/components/EmMfm.ts +++ b/packages/frontend-embed/src/components/EmMfm.ts @@ -5,7 +5,7 @@ import { h, provide } from 'vue'; import type { VNode, SetupContext } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { host } from '@@/js/config.js'; import EmUrl from '@/components/EmUrl.vue'; diff --git a/packages/frontend-embed/src/components/EmNote.vue b/packages/frontend-embed/src/components/EmNote.vue index 666cbde72d..0dc77d09a7 100644 --- a/packages/frontend-embed/src/components/EmNote.vue +++ b/packages/frontend-embed/src/components/EmNote.vue @@ -105,7 +105,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, ref, shallowRef } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { shouldCollapsed } from '@@/js/collapsed.js'; import { url } from '@@/js/config.js'; diff --git a/packages/frontend-embed/src/components/EmNoteDetailed.vue b/packages/frontend-embed/src/components/EmNoteDetailed.vue index 9f4be8c666..716a5fbf81 100644 --- a/packages/frontend-embed/src/components/EmNoteDetailed.vue +++ b/packages/frontend-embed/src/components/EmNoteDetailed.vue @@ -128,7 +128,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, ref } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { computeMergedCw } from '@@/js/compute-merged-cw.js'; import I18n from '@/components/I18n.vue'; diff --git a/packages/frontend-shared/package.json b/packages/frontend-shared/package.json index f129121d19..b4a5dd89f5 100644 --- a/packages/frontend-shared/package.json +++ b/packages/frontend-shared/package.json @@ -35,7 +35,6 @@ ], "dependencies": { "misskey-js": "workspace:*", - "nodemon": "3.1.7", "vue": "3.5.13" } } diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 640ebe70d6..5d028ce142 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -20,19 +20,11 @@ "@github/webauthn-json": "2.1.1", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@misskey-dev/browser-image-resizer": "2024.1.0", - "@phosphor-icons/web": "^2.0.3", - "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-replace": "6.0.2", - "@rollup/pluginutils": "5.1.4", + "@phosphor-icons/web": "2.1.2", "@ruffle-rs/ruffle": "0.1.0-nightly.2024.10.15", "@sentry/vue": "9.14.0", "@syuilo/aiscript": "0.19.0", - "@transfem-org/sfm-js": "0.24.6", - "@twemoji/parser": "15.1.1", - "@vitejs/plugin-vue": "5.2.3", - "@vue/compiler-sfc": "3.5.14", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15", - "astring": "1.9.0", "broadcast-channel": "7.1.0", "buraha": "0.0.1", "canvas-confetti": "1.9.3", @@ -45,38 +37,30 @@ "compare-versions": "6.1.1", "cropperjs": "2.0.0", "date-fns": "4.1.0", - "estree-walker": "3.0.3", "eventemitter3": "5.0.1", "frontend-shared": "workspace:*", "idb-keyval": "6.2.1", "insert-text-at-cursor": "0.3.0", "is-file-animated": "1.0.2", "json5": "2.2.3", - "katex": "0.16.10", - "magic-string": "0.30.17", + "katex": "0.16.22", "matter-js": "0.20.0", "misskey-bubble-game": "workspace:*", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", - "moment": "^2.30.1", + "moment": "2.30.1", "photoswipe": "5.4.4", "promise-limit": "2.7.0", "punycode.js": "2.3.1", - "rollup": "4.40.0", "sanitize-html": "2.16.0", - "sass": "1.87.0", "shiki": "3.3.0", "strict-event-emitter-types": "2.0.0", "textarea-caret": "3.1.0", - "three": "0.176.0", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", - "tsc-alias": "1.8.15", - "tsconfig-paths": "4.2.0", "typescript": "5.8.3", "uuid": "11.1.0", "v-code-diff": "1.13.1", - "vite": "6.3.3", "vue": "3.5.14", "vuedraggable": "next", "wanakana": "5.3.1" @@ -85,7 +69,10 @@ "cypress": "14.3.2" }, "devDependencies": { - "@misskey-dev/summaly": "5.2.1", + "@misskey-dev/summaly": "npm:@transfem-org/summaly@5.2.2", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-replace": "6.0.2", + "@rollup/pluginutils": "5.1.4", "@storybook/addon-actions": "8.6.12", "@storybook/addon-essentials": "8.6.12", "@storybook/addon-interactions": "8.6.12", @@ -105,9 +92,10 @@ "@storybook/vue3": "8.6.12", "@storybook/vue3-vite": "8.6.12", "@testing-library/vue": "8.1.0", + "@twemoji/parser": "15.1.1", "@types/canvas-confetti": "1.9.0", "@types/estree": "1.0.7", - "@types/katex": "^0.16.7", + "@types/katex": "0.16.7", "@types/matter-js": "0.19.8", "@types/micromatch": "4.0.9", "@types/node": "22.15.2", @@ -119,16 +107,22 @@ "@types/ws": "8.18.1", "@typescript-eslint/eslint-plugin": "8.31.0", "@typescript-eslint/parser": "8.31.0", + "@vitejs/plugin-vue": "5.2.3", "@vitest/coverage-v8": "3.1.2", "@vue/compiler-core": "3.5.14", + "@vue/compiler-sfc": "3.5.14", "@vue/runtime-core": "3.5.14", + "mfm-js": "npm:@transfem-org/sfm-js@0.24.6", "acorn": "8.14.1", + "astring": "1.9.0", "cross-env": "7.0.3", "eslint-plugin-import": "2.31.0", "eslint-plugin-vue": "10.0.0", + "estree-walker": "3.0.3", "fast-glob": "3.3.3", "happy-dom": "17.4.4", "intersection-observer": "0.12.2", + "magic-string": "0.30.17", "micromatch": "4.0.8", "minimatch": "10.0.1", "msw": "2.7.5", @@ -137,10 +131,16 @@ "prettier": "3.5.3", "react": "19.1.0", "react-dom": "19.1.0", + "rollup": "4.40.0", + "sass": "1.87.0", "seedrandom": "3.0.5", "start-server-and-test": "2.0.11", "storybook": "8.6.12", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", + "three": "0.176.0", + "tsc-alias": "1.8.15", + "tsconfig-paths": "4.2.0", + "vite": "6.3.3", "vite-plugin-turbosnap": "1.0.3", "vitest": "3.1.2", "vitest-fetch-mock": "0.4.5", diff --git a/packages/frontend/src/components/MkAbuseReport.vue b/packages/frontend/src/components/MkAbuseReport.vue index 7ad0ad647c..6025bc44f0 100644 --- a/packages/frontend/src/components/MkAbuseReport.vue +++ b/packages/frontend/src/components/MkAbuseReport.vue @@ -99,7 +99,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, provide, ref, watch } from 'vue'; import * as Misskey from 'misskey-js'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import MkButton from '@/components/MkButton.vue'; import MkSwitch from '@/components/MkSwitch.vue'; import MkKeyValue from '@/components/MkKeyValue.vue'; diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 37882ef5b9..ef9d4c68fa 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -180,7 +180,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, onMounted, ref, useTemplateRef, watch, provide } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import { shouldCollapsed } from '@@/js/collapsed.js'; diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 3f692d4964..b941d776de 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -233,7 +233,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, onMounted, provide, ref, useTemplateRef, watch } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import * as config from '@@/js/config.js'; diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index e02b4f9dd6..a650365a28 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -107,7 +107,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, shallowRef, ref, computed, useTemplateRef, toRaw } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import insertTextAtCursor from 'insert-text-at-cursor'; import { toASCII } from 'punycode.js'; diff --git a/packages/frontend/src/components/MkSubNoteContent.vue b/packages/frontend/src/components/MkSubNoteContent.vue index 0780f6c910..b7eddb9536 100644 --- a/packages/frontend/src/components/MkSubNoteContent.vue +++ b/packages/frontend/src/components/MkSubNoteContent.vue @@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, computed, watch } from 'vue'; import * as Misskey from 'misskey-js'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { shouldCollapsed } from '@@/js/collapsed.js'; import MkMediaList from '@/components/MkMediaList.vue'; import MkPoll from '@/components/MkPoll.vue'; diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 24293343ac..c554319c30 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -181,7 +181,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, onMounted, ref, useTemplateRef, watch, provide } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import { shouldCollapsed } from '@@/js/collapsed.js'; diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index 3c867a9559..f678c85431 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -238,7 +238,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, onMounted, onUnmounted, onUpdated, provide, ref, useTemplateRef, watch } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import * as config from '@@/js/config.js'; diff --git a/packages/frontend/src/components/SkOldNoteWindow.vue b/packages/frontend/src/components/SkOldNoteWindow.vue index 39ad2bd7c2..aa1da2d6e3 100644 --- a/packages/frontend/src/components/SkOldNoteWindow.vue +++ b/packages/frontend/src/components/SkOldNoteWindow.vue @@ -76,7 +76,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { inject, onMounted, ref, shallowRef, computed } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import MkNoteSimple from '@/components/MkNoteSimple.vue'; import MkMediaList from '@/components/MkMediaList.vue'; diff --git a/packages/frontend/src/components/SkUrlPreviewGroup.vue b/packages/frontend/src/components/SkUrlPreviewGroup.vue index 32b11d9db4..dbd930248a 100644 --- a/packages/frontend/src/components/SkUrlPreviewGroup.vue +++ b/packages/frontend/src/components/SkUrlPreviewGroup.vue @@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script setup lang="ts"> import * as Misskey from 'misskey-js'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import { computed, ref, watch } from 'vue'; import { versatileLang } from '@@/js/intl-const'; import promiseLimit from 'promise-limit'; diff --git a/packages/frontend/src/components/global/MkMfm.ts b/packages/frontend/src/components/global/MkMfm.ts index dea486e66d..9f92c43b68 100644 --- a/packages/frontend/src/components/global/MkMfm.ts +++ b/packages/frontend/src/components/global/MkMfm.ts @@ -4,7 +4,7 @@ */ import { h, defineAsyncComponent } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { host } from '@@/js/config.js'; import CkFollowMouse from '../CkFollowMouse.vue'; diff --git a/packages/frontend/src/pages/chat/XMessage.vue b/packages/frontend/src/pages/chat/XMessage.vue index 1536a91196..b72583214b 100644 --- a/packages/frontend/src/pages/chat/XMessage.vue +++ b/packages/frontend/src/pages/chat/XMessage.vue @@ -53,7 +53,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, defineAsyncComponent, provide } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { url } from '@@/js/config.js'; import { isLink } from '@@/js/is-link.js'; diff --git a/packages/frontend/src/utility/check-animated-mfm.ts b/packages/frontend/src/utility/check-animated-mfm.ts index 2614dfb4f1..371a631af7 100644 --- a/packages/frontend/src/utility/check-animated-mfm.ts +++ b/packages/frontend/src/utility/check-animated-mfm.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; export function checkAnimationFromMfm(nodes: mfm.MfmNode[]): boolean { const animatedNodes = mfm.extract(nodes, (node) => { diff --git a/packages/frontend/src/utility/extract-mentions.ts b/packages/frontend/src/utility/extract-mentions.ts index 89a5ce1df8..d518562053 100644 --- a/packages/frontend/src/utility/extract-mentions.ts +++ b/packages/frontend/src/utility/extract-mentions.ts @@ -5,7 +5,7 @@ // test is located in test/extract-mentions -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] { // TODO: 重複を削除 diff --git a/packages/frontend/src/utility/extract-preview-urls.ts b/packages/frontend/src/utility/extract-preview-urls.ts index e3bd62c993..264359f179 100644 --- a/packages/frontend/src/utility/extract-preview-urls.ts +++ b/packages/frontend/src/utility/extract-preview-urls.ts @@ -4,7 +4,7 @@ */ import type * as Misskey from 'misskey-js'; -import type * as mfm from '@transfem-org/sfm-js'; +import type * as mfm from 'mfm-js'; import { extractUrlFromMfm } from '@/utility/extract-url-from-mfm.js'; import { getNoteUrls } from '@/utility/getNoteUrls'; diff --git a/packages/frontend/src/utility/extract-url-from-mfm.ts b/packages/frontend/src/utility/extract-url-from-mfm.ts index 260dba030e..99d80f3624 100644 --- a/packages/frontend/src/utility/extract-url-from-mfm.ts +++ b/packages/frontend/src/utility/extract-url-from-mfm.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; // unique without hash // [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ] diff --git a/packages/megalodon/package.json b/packages/megalodon/package.json index f10a9cf9dc..4c7f9750de 100644 --- a/packages/megalodon/package.json +++ b/packages/megalodon/package.json @@ -1,75 +1,69 @@ { - "name": "megalodon", - "version": "7.0.1", - "description": "Mastodon API client for node.js and browser", - "main": "./lib/src/index.js", - "typings": "./lib/src/index.d.ts", - "scripts": { - "build": "tsc -p ./", - "doc": "typedoc --out ../docs ./src", - "test": "cross-env NODE_ENV=test jest -u --maxWorkers=3" - }, - "engines": { - "node": "^22.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/h3poteto/megalodon.git" - }, - "keywords": [ - "mastodon", - "client", - "api", - "streaming", - "rest", - "proxy" - ], - "author": "h3poteto", - "license": "MIT", - "bugs": { - "url": "https://github.com/h3poteto/megalodon/issues" - }, - "jest": { - "moduleFileExtensions": [ - "ts", - "js" - ], - "moduleNameMapper": { - "^@/(.+)": "<rootDir>/src/$1", - "^~/(.+)": "<rootDir>/$1" - }, - "testMatch": [ - "**/test/**/*.spec.ts" - ], - "preset": "ts-jest/presets/default", - "transform": { - "^.+\\.(ts|tsx)$": [ - "ts-jest", - { - "tsconfig": "tsconfig.json" - } - ] - }, - "testEnvironment": "node" - }, - "homepage": "https://github.com/h3poteto/megalodon#readme", - "dependencies": { - "@types/jest": "^29.5.10", - "@types/oauth": "^0.9.4", - "axios": "1.7.4", - "dayjs": "^1.11.10", - "form-data": "4.0.2", - "oauth": "0.10.2", + "name": "megalodon", + "version": "7.0.1", + "description": "Mastodon API client for node.js and browser", + "main": "./lib/src/index.js", + "typings": "./lib/src/index.d.ts", + "scripts": { + "build": "tsc -p ./", + "test": "cross-env NODE_ENV=test jest -u --maxWorkers=3" + }, + "engines": { + "node": "^22.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/h3poteto/megalodon.git" + }, + "keywords": [ + "mastodon", + "client", + "api", + "streaming", + "rest", + "proxy" + ], + "author": "h3poteto", + "license": "MIT", + "bugs": { + "url": "https://github.com/h3poteto/megalodon/issues" + }, + "jest": { + "moduleFileExtensions": [ + "ts", + "js" + ], + "moduleNameMapper": { + "^@/(.+)": "<rootDir>/src/$1", + "^~/(.+)": "<rootDir>/$1" + }, + "testMatch": [ + "**/test/**/*.spec.ts" + ], + "preset": "ts-jest/presets/default", + "transform": { + "^.+\\.(ts|tsx)$": [ + "ts-jest", + { + "tsconfig": "tsconfig.json" + } + ] + }, + "testEnvironment": "node" + }, + "homepage": "https://github.com/h3poteto/megalodon#readme", + "dependencies": { + "axios": "1.9.0", + "dayjs": "1.11.13", + "form-data": "4.0.2", + "oauth": "0.10.2", "typescript": "5.8.3" - }, - "devDependencies": { - "@typescript-eslint/eslint-plugin": "8.31.0", - "@typescript-eslint/parser": "8.31.0", - "eslint": "9.25.1", - "eslint-config-prettier": "^9.0.0", - "jest": "29.7.0", - "jest-worker": "29.7.0", - "prettier": "3.5.3", - "ts-jest": "^29.1.1" - } + }, + "devDependencies": { + "@types/jest": "29.5.14", + "@types/oauth": "0.9.6", + "jest": "29.7.0", + "jest-worker": "29.7.0", + "ts-jest": "29.3.4" + } } diff --git a/packages/megalodon/src/index.ts b/packages/megalodon/src/index.ts index bacd0574d4..e13e1a1faf 100644 --- a/packages/megalodon/src/index.ts +++ b/packages/megalodon/src/index.ts @@ -12,17 +12,17 @@ import MastodonEntity from './mastodon/entity'; import MisskeyEntity from './misskey/entity'; export { - Response, - OAuth, - RequestCanceledError, - isCancel, - detector, - MegalodonInterface, - NotificationType, - FilterContext, - Misskey, - Entity, - Converter, - MastodonEntity, - MisskeyEntity, + type Response, + OAuth, + RequestCanceledError, + isCancel, + detector, + type MegalodonInterface, + NotificationType, + FilterContext, + Misskey, + type Entity, + Converter, + type MastodonEntity, + type MisskeyEntity, } diff --git a/packages/megalodon/tsconfig.json b/packages/megalodon/tsconfig.json index 2b90738318..0a30b30cff 100644 --- a/packages/megalodon/tsconfig.json +++ b/packages/megalodon/tsconfig.json @@ -1,65 +1,105 @@ { - "compilerOptions": { - /* Basic Options */ - "target": "ES2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["ES2022", "dom"], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./lib", /* Redirect output structure to the directory. */ - "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + "compilerOptions": { + /* Basic Options */ + "target": "ES2022", + /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ + "module": "commonjs", + /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "lib": [ + "ES2022", + "dom" + ], + /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true, + /* Generates corresponding '.d.ts' file. */ + "declarationMap": true, + /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./lib", + /* Redirect output structure to the directory. */ + "rootDir": "./", + /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + "removeComments": true, + /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + "downlevelIteration": false, + /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + "isolatedModules": true, + /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + "incremental": true, + /* Strict Type-Checking Options */ + "strict": true, + /* Enable all strict type-checking options. */ + "noImplicitAny": true, + /* Raise error on expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, + /* Enable strict null checks. */ + "strictFunctionTypes": true, + /* Enable strict checking of function types. */ + "strictPropertyInitialization": true, + /* Enable strict checking of property initialization in classes. */ + "noImplicitThis": true, + /* Raise error on 'this' expressions with an implied 'any' type. */ + "alwaysStrict": true, + /* Parse in strict mode and emit "use strict" for each source file. */ - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - "strictFunctionTypes": true, /* Enable strict checking of function types. */ - "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - "noUnusedLocals": true, /* Report errors on unused locals. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ - "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Additional Checks */ + "noUnusedLocals": true, + /* Report errors on unused locals. */ + "noUnusedParameters": true, + /* Report errors on unused parameters. */ + "noImplicitReturns": true, + /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, + /* Report errors for fallthrough cases in switch statement. */ "skipLibCheck": true, + /* Module Resolution Options */ + "moduleResolution": "node", + /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "baseUrl": "./", + /* Base directory to resolve non-absolute module names. */ + "paths": { + "@*": [ + "src*" + ], + "~*": [ + "./*" + ] + }, + /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, + /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - "paths": { - "@*": ["src*"], - "~*": ["./*"] - }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + "inlineSourceMap": false, + /* Emit a single file with source maps instead of having a separate file. */ + "inlineSources": false, + /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - }, - "include": ["./src", "./test"], - "exclude": ["node_modules", "example"] + /* Experimental Options */ + "experimentalDecorators": true + /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "include": [ + "./src", + "./test" + ], + "exclude": [ + "node_modules", + "example" + ] } diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 7b52f02178..0c0878ef9b 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -36,6 +36,7 @@ }, "devDependencies": { "@microsoft/api-extractor": "7.52.5", + "@simplewebauthn/types": "12.0.0", "@swc/jest": "0.2.38", "@types/jest": "29.5.14", "@types/node": "22.15.2", @@ -47,7 +48,7 @@ "mock-socket": "9.3.1", "ncp": "2.0.0", "nodemon": "3.1.10", - "execa": "8.0.1", + "execa": "9.5.2", "tsd": "0.32.0", "typescript": "5.8.3", "esbuild": "0.25.3", @@ -57,7 +58,6 @@ "built" ], "dependencies": { - "@simplewebauthn/types": "12.0.0", "eventemitter3": "5.0.1", "reconnecting-websocket": "4.4.0" } diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index c09901c214..6cb52fcbea 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -19581,18 +19581,10 @@ export type operations = { 200: { content: { 'application/json': { - image?: { - link?: string; - url: string; - title?: string; - }; - paginationLinks?: { - self?: string; - first?: string; - next?: string; - last?: string; - prev?: string; - }; + type: string; + id?: string; + updated?: string; + author?: string; link?: string; title?: string; items: { @@ -19600,33 +19592,15 @@ export type operations = { guid?: string; title?: string; pubDate?: string; - creator?: string; - summary?: string; - content?: string; - isoDate?: string; - categories?: string[]; - contentSnippet?: string; - enclosure?: { - url: string; - length?: number; - type?: string; - }; + description?: string; + media: { + medium?: string; + url?: string; + type?: string; + lang?: string; + }[]; }[]; - feedUrl?: string; description?: string; - itunes?: { - image?: string; - owner?: { - name?: string; - email?: string; - }; - author?: string; - summary?: string; - explicit?: string; - categories?: string[]; - keywords?: string[]; - [key: string]: unknown; - }; }; }; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 880715e20e..a8b6784dc6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,39 +12,9 @@ importers: .: dependencies: - cssnano: - specifier: 7.0.6 - version: 7.0.6(postcss@8.5.3) - esbuild: - specifier: 0.25.3 - version: 0.25.3 - execa: - specifier: 9.5.2 - version: 9.5.2 - fast-glob: - specifier: 3.3.3 - version: 3.3.3 - glob: - specifier: 11.0.2 - version: 11.0.2 - ignore-walk: - specifier: 7.0.0 - version: 7.0.0 js-yaml: specifier: 4.1.0 version: 4.1.0 - postcss: - specifier: 8.5.3 - version: 8.5.3 - tar: - specifier: 7.4.3 - version: 7.4.3 - terser: - specifier: 5.39.0 - version: 5.39.0 - typescript: - specifier: 5.8.3 - version: 5.8.3 optionalDependencies: cypress: specifier: 14.3.2 @@ -52,7 +22,7 @@ importers: devDependencies: '@misskey-dev/eslint-plugin': specifier: 2.1.0 - version: 2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@4.2.0(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.0.0) + version: 2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@4.2.0(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.1.0) '@types/node': specifier: 22.15.2 version: 22.15.2 @@ -65,21 +35,51 @@ importers: cross-env: specifier: 7.0.3 version: 7.0.3 + cssnano: + specifier: 7.0.6 + version: 7.0.6(postcss@8.5.3) + esbuild: + specifier: 0.25.3 + version: 0.25.3 eslint: specifier: 9.25.1 version: 9.25.1 + execa: + specifier: 9.5.2 + version: 9.5.2 + fast-glob: + specifier: 3.3.3 + version: 3.3.3 + glob: + specifier: 11.0.2 + version: 11.0.2 globals: - specifier: 16.0.0 - version: 16.0.0 + specifier: 16.1.0 + version: 16.1.0 + ignore-walk: + specifier: 7.0.0 + version: 7.0.0 ncp: specifier: 2.0.0 version: 2.0.0 pnpm: - specifier: 10.10.0 - version: 10.10.0 + specifier: 9.6.0 + version: 9.6.0 + postcss: + specifier: 8.5.3 + version: 8.5.3 start-server-and-test: specifier: 2.0.11 version: 2.0.11 + tar: + specifier: 7.4.3 + version: 7.4.3 + terser: + specifier: 5.39.0 + version: 5.39.0 + typescript: + specifier: 5.8.3 + version: 5.8.3 packages/backend: dependencies: @@ -120,8 +120,8 @@ importers: specifier: 1.3.0 version: 1.3.0 '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 + specifier: npm:@transfem-org/summaly@5.2.2 + version: '@transfem-org/summaly@5.2.2' '@nestjs/common': specifier: 11.1.0 version: 11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -149,15 +149,6 @@ importers: '@smithy/node-http-handler': specifier: 2.5.0 version: 2.5.0 - '@swc/cli': - specifier: 0.7.3 - version: 0.7.3(@swc/core@1.11.24)(chokidar@4.0.3) - '@swc/core': - specifier: 1.11.24 - version: 1.11.24 - '@transfem-org/sfm-js': - specifier: 0.24.6 - version: 0.24.6 '@twemoji/parser': specifier: 15.1.1 version: 15.1.1 @@ -171,11 +162,8 @@ importers: specifier: 7.0.1 version: 7.0.1 argon2: - specifier: ^0.40.1 - version: 0.40.1 - async-mutex: - specifier: 0.5.0 - version: 0.5.0 + specifier: 0.43.0 + version: 0.43.0 axios: specifier: 1.7.4 version: 1.7.4 @@ -185,9 +173,6 @@ importers: blurhash: specifier: 2.0.5 version: 2.0.5 - body-parser: - specifier: 1.20.3 - version: 1.20.3 bullmq: specifier: 5.51.1 version: 5.51.1 @@ -195,7 +180,7 @@ importers: specifier: 7.0.0 version: 7.0.0 canvas: - specifier: ^3.1.0 + specifier: 3.1.0 version: 3.1.0 cbor: specifier: 9.0.2 @@ -209,12 +194,9 @@ importers: cheerio: specifier: 1.0.0 version: 1.0.0 - chokidar: - specifier: 4.0.3 - version: 4.0.3 cli-highlight: - specifier: 2.1.11 - version: 2.1.11 + specifier: npm:@transfem-org/cli-highlight@2.1.12 + version: '@transfem-org/cli-highlight@2.1.12' color-convert: specifier: 2.0.1 version: 2.0.1 @@ -227,9 +209,15 @@ importers: deep-email-validator: specifier: 0.1.21 version: 0.1.21 - fast-xml-parser: - specifier: 4.4.1 - version: 4.4.1 + dom-serializer: + specifier: 2.0.0 + version: 2.0.0 + domhandler: + specifier: 5.0.3 + version: 5.0.3 + domutils: + specifier: 3.2.2 + version: 3.2.2 fastify: specifier: 5.3.2 version: 5.3.2 @@ -254,18 +242,15 @@ importers: got: specifier: 14.4.7 version: 14.4.7 - happy-dom: - specifier: 16.8.1 - version: 16.8.1 hpagent: specifier: 1.2.0 version: 1.2.0 htmlescape: specifier: 1.1.1 version: 1.1.1 - http-link-header: - specifier: 1.1.3 - version: 1.1.3 + htmlparser2: + specifier: 9.1.0 + version: 9.1.0 ioredis: specifier: 5.6.1 version: 5.6.1 @@ -287,9 +272,6 @@ importers: jsonld: specifier: 8.3.3 version: 8.3.3(web-streams-polyfill@4.0.0) - jsrsasign: - specifier: 11.1.0 - version: 11.1.0 juice: specifier: 11.0.1 version: 11.0.1 @@ -299,9 +281,9 @@ importers: meilisearch: specifier: 0.50.0 version: 0.50.0 - microformats-parser: - specifier: 2.0.2 - version: 2.0.2 + mfm-js: + specifier: npm:@transfem-org/sfm-js@0.24.6 + version: '@transfem-org/sfm-js@0.24.6' mime-types: specifier: 2.1.35 version: 2.1.35 @@ -312,7 +294,7 @@ importers: specifier: workspace:* version: link:../misskey-reversi moment: - specifier: ^2.30.1 + specifier: 2.30.1 version: 2.30.1 ms: specifier: 3.0.0-canary.1 @@ -329,24 +311,12 @@ importers: nodemailer: specifier: 6.10.1 version: 6.10.1 - oauth: - specifier: 0.10.2 - version: 0.10.2 - oauth2orize: - specifier: 1.12.0 - version: 1.12.0 - oauth2orize-pkce: - specifier: 0.1.2 - version: 0.1.2 os-utils: specifier: 0.0.14 version: 0.0.14 otpauth: specifier: 9.4.0 version: 9.4.0 - parse5: - specifier: 7.3.0 - version: 7.3.0 pg: specifier: 8.15.6 version: 8.15.6 @@ -360,11 +330,11 @@ importers: specifier: 2.7.0 version: 2.7.0 proxy-addr: - specifier: ^2.0.7 + specifier: 2.0.7 version: 2.0.7 psl: - specifier: ^1.13.0 - version: 1.13.0 + specifier: 1.15.0 + version: 1.15.0 pug: specifier: 3.0.3 version: 3.0.3 @@ -374,9 +344,6 @@ importers: random-seed: specifier: 0.3.0 version: 0.3.0 - ratelimiter: - specifier: 3.4.1 - version: 3.4.1 re2: specifier: 1.21.4 version: 1.21.4 @@ -392,12 +359,6 @@ importers: rename: specifier: 1.0.4 version: 1.0.4 - rss-parser: - specifier: 3.13.0 - version: 3.13.0 - rxjs: - specifier: 7.8.2 - version: 7.8.2 sanitize-html: specifier: 2.16.0 version: 2.16.0 @@ -413,9 +374,6 @@ importers: strict-event-emitter-types: specifier: 2.0.0 version: 2.0.0 - stringz: - specifier: 2.1.0 - version: 2.1.0 systeminformation: specifier: 5.25.11 version: 5.25.11 @@ -441,8 +399,8 @@ importers: specifier: 2.4.0 version: 2.4.0 uuid: - specifier: ^9.0.1 - version: 9.0.1 + specifier: 11.1.0 + version: 11.1.0 vary: specifier: 1.1.2 version: 1.1.2 @@ -550,6 +508,12 @@ importers: '@simplewebauthn/types': specifier: 12.0.0 version: 12.0.0 + '@swc/cli': + specifier: 0.7.3 + version: 0.7.3(@swc/core@1.11.24)(chokidar@4.0.3) + '@swc/core': + specifier: 1.11.24 + version: 1.11.24 '@swc/jest': specifier: 0.2.38 version: 0.2.38(@swc/core@1.11.24) @@ -562,9 +526,6 @@ importers: '@types/bcryptjs': specifier: 2.4.6 version: 2.4.6 - '@types/body-parser': - specifier: 1.19.5 - version: 1.19.5 '@types/color-convert': specifier: 2.0.4 version: 2.0.4 @@ -577,9 +538,6 @@ importers: '@types/htmlescape': specifier: 1.1.3 version: 1.1.3 - '@types/http-link-header': - specifier: 1.0.7 - version: 1.0.7 '@types/jest': specifier: 29.5.14 version: 29.5.14 @@ -617,10 +575,10 @@ importers: specifier: 8.11.14 version: 8.11.14 '@types/proxy-addr': - specifier: ^2.0.3 + specifier: 2.0.3 version: 2.0.3 '@types/psl': - specifier: ^1.1.3 + specifier: 1.1.3 version: 1.1.3 '@types/pug': specifier: 2.0.10 @@ -631,9 +589,6 @@ importers: '@types/random-seed': specifier: 0.3.5 version: 0.3.5 - '@types/ratelimiter': - specifier: 3.4.6 - version: 3.4.6 '@types/redis-info': specifier: 3.0.3 version: 3.0.3 @@ -661,9 +616,6 @@ importers: '@types/tmp': specifier: 0.2.6 version: 0.2.6 - '@types/uuid': - specifier: ^9.0.4 - version: 9.0.8 '@types/vary': specifier: 1.1.3 version: 1.1.3 @@ -689,8 +641,8 @@ importers: specifier: 2.31.0 version: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) execa: - specifier: 8.0.1 - version: 8.0.1 + specifier: 9.5.2 + version: 9.5.2 fkill: specifier: 9.0.0 version: 9.0.0 @@ -728,17 +680,8 @@ importers: specifier: 2024.1.0 version: 2024.1.0 '@phosphor-icons/web': - specifier: ^2.0.3 - version: 2.1.1 - '@rollup/plugin-json': - specifier: 6.1.0 - version: 6.1.0(rollup@4.40.0) - '@rollup/plugin-replace': - specifier: 6.0.2 - version: 6.0.2(rollup@4.40.0) - '@rollup/pluginutils': - specifier: 5.1.4 - version: 5.1.4(rollup@4.40.0) + specifier: 2.1.2 + version: 2.1.2 '@ruffle-rs/ruffle': specifier: 0.1.0-nightly.2024.10.15 version: 0.1.0-nightly.2024.10.15 @@ -748,24 +691,9 @@ importers: '@syuilo/aiscript': specifier: 0.19.0 version: 0.19.0 - '@transfem-org/sfm-js': - specifier: 0.24.6 - version: 0.24.6 - '@twemoji/parser': - specifier: 15.1.1 - version: 15.1.1 - '@vitejs/plugin-vue': - specifier: 5.2.3 - version: 5.2.3(vite@6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) - '@vue/compiler-sfc': - specifier: 3.5.14 - version: 3.5.14 aiscript-vscode: specifier: github:aiscript-dev/aiscript-vscode#v0.1.15 version: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/c3cde89e79a41d93540cf8a48cd619c3f2dcb1b7 - astring: - specifier: 1.9.0 - version: 1.9.0 broadcast-channel: specifier: 7.1.0 version: 7.1.0 @@ -802,9 +730,6 @@ importers: date-fns: specifier: 4.1.0 version: 4.1.0 - estree-walker: - specifier: 3.0.3 - version: 3.0.3 eventemitter3: specifier: 5.0.1 version: 5.0.1 @@ -824,11 +749,8 @@ importers: specifier: 2.2.3 version: 2.2.3 katex: - specifier: 0.16.10 - version: 0.16.10 - magic-string: - specifier: 0.30.17 - version: 0.30.17 + specifier: 0.16.22 + version: 0.16.22 matter-js: specifier: 0.20.0 version: 0.20.0 @@ -842,7 +764,7 @@ importers: specifier: workspace:* version: link:../misskey-reversi moment: - specifier: ^2.30.1 + specifier: 2.30.1 version: 2.30.1 photoswipe: specifier: 5.4.4 @@ -853,15 +775,9 @@ importers: punycode.js: specifier: 2.3.1 version: 2.3.1 - rollup: - specifier: 4.40.0 - version: 4.40.0 sanitize-html: specifier: 2.16.0 version: 2.16.0 - sass: - specifier: 1.87.0 - version: 1.87.0 shiki: specifier: 3.3.0 version: 3.3.0 @@ -871,21 +787,12 @@ importers: textarea-caret: specifier: 3.1.0 version: 3.1.0 - three: - specifier: 0.176.0 - version: 0.176.0 throttle-debounce: specifier: 5.0.2 version: 5.0.2 tinycolor2: specifier: 1.6.0 version: 1.6.0 - tsc-alias: - specifier: 1.8.15 - version: 1.8.15 - tsconfig-paths: - specifier: 4.2.0 - version: 4.2.0 typescript: specifier: 5.8.3 version: 5.8.3 @@ -895,9 +802,6 @@ importers: v-code-diff: specifier: 1.13.1 version: 1.13.1(vue@3.5.14(typescript@5.8.3)) - vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vue: specifier: 3.5.14 version: 3.5.14(typescript@5.8.3) @@ -913,8 +817,17 @@ importers: version: 14.3.2 devDependencies: '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 + specifier: npm:@transfem-org/summaly@5.2.2 + version: '@transfem-org/summaly@5.2.2' + '@rollup/plugin-json': + specifier: 6.1.0 + version: 6.1.0(rollup@4.40.0) + '@rollup/plugin-replace': + specifier: 6.0.2 + version: 6.0.2(rollup@4.40.0) + '@rollup/pluginutils': + specifier: 5.1.4 + version: 5.1.4(rollup@4.40.0) '@storybook/addon-actions': specifier: 8.6.12 version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) @@ -972,6 +885,9 @@ importers: '@testing-library/vue': specifier: 8.1.0 version: 8.1.0(@vue/compiler-sfc@3.5.14)(@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)) + '@twemoji/parser': + specifier: 15.1.1 + version: 15.1.1 '@types/canvas-confetti': specifier: 1.9.0 version: 1.9.0 @@ -979,7 +895,7 @@ importers: specifier: 1.0.7 version: 1.0.7 '@types/katex': - specifier: ^0.16.7 + specifier: 0.16.7 version: 0.16.7 '@types/matter-js': specifier: 0.19.8 @@ -1014,18 +930,27 @@ importers: '@typescript-eslint/parser': specifier: 8.31.0 version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + '@vitejs/plugin-vue': + specifier: 5.2.3 + version: 5.2.3(vite@6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 3.1.2 version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) '@vue/compiler-core': specifier: 3.5.14 version: 3.5.14 + '@vue/compiler-sfc': + specifier: 3.5.14 + version: 3.5.14 '@vue/runtime-core': specifier: 3.5.14 version: 3.5.14 acorn: specifier: 8.14.1 version: 8.14.1 + astring: + specifier: 1.9.0 + version: 1.9.0 cross-env: specifier: 7.0.3 version: 7.0.3 @@ -1035,6 +960,9 @@ importers: eslint-plugin-vue: specifier: 10.0.0 version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + estree-walker: + specifier: 3.0.3 + version: 3.0.3 fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -1044,6 +972,12 @@ importers: intersection-observer: specifier: 0.12.2 version: 0.12.2 + magic-string: + specifier: 0.30.17 + version: 0.30.17 + mfm-js: + specifier: npm:@transfem-org/sfm-js@0.24.6 + version: '@transfem-org/sfm-js@0.24.6' micromatch: specifier: 4.0.8 version: 4.0.8 @@ -1068,6 +1002,12 @@ importers: react-dom: specifier: 19.1.0 version: 19.1.0(react@19.1.0) + rollup: + specifier: 4.40.0 + version: 4.40.0 + sass: + specifier: 1.87.0 + version: 1.87.0 seedrandom: specifier: 3.0.5 version: 3.0.5 @@ -1080,6 +1020,18 @@ importers: storybook-addon-misskey-theme: specifier: github:misskey-dev/storybook-addon-misskey-theme version: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/components@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/core-events@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/manager-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/preview-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/theming@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/types@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + three: + specifier: 0.176.0 + version: 0.176.0 + tsc-alias: + specifier: 1.8.15 + version: 1.8.15 + tsconfig-paths: + specifier: 4.2.0 + version: 4.2.0 + vite: + specifier: 6.3.3 + version: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vite-plugin-turbosnap: specifier: 1.0.3 version: 1.0.3 @@ -1105,87 +1057,57 @@ importers: specifier: 15.1.0 version: 15.1.0 '@phosphor-icons/web': - specifier: ^2.0.3 - version: 2.1.1 - '@rollup/plugin-json': - specifier: 6.1.0 - version: 6.1.0(rollup@4.40.0) - '@rollup/plugin-replace': - specifier: 6.0.2 - version: 6.0.2(rollup@4.40.0) - '@rollup/pluginutils': - specifier: 5.1.4 - version: 5.1.4(rollup@4.40.0) - '@transfem-org/sfm-js': - specifier: 0.24.5 - version: 0.24.5 - '@twemoji/parser': - specifier: 15.1.1 - version: 15.1.1 - '@vitejs/plugin-vue': - specifier: 5.2.3 - version: 5.2.3(vite@6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) - '@vue/compiler-sfc': - specifier: 3.5.14 - version: 3.5.14 - astring: - specifier: 1.9.0 - version: 1.9.0 + specifier: 2.1.2 + version: 2.1.2 buraha: specifier: 0.0.1 version: 0.0.1 - estree-walker: - specifier: 3.0.3 - version: 3.0.3 frontend-shared: specifier: workspace:* version: link:../frontend-shared json5: specifier: 2.2.3 version: 2.2.3 + mfm-js: + specifier: npm:@transfem-org/sfm-js@0.24.6 + version: '@transfem-org/sfm-js@0.24.6' misskey-js: specifier: workspace:* version: link:../misskey-js punycode.js: specifier: 2.3.1 version: 2.3.1 - rollup: - specifier: 4.40.0 - version: 4.40.0 - sass: - specifier: 1.87.0 - version: 1.87.0 shiki: specifier: 3.3.0 version: 3.3.0 tinycolor2: specifier: 1.6.0 version: 1.6.0 - tsc-alias: - specifier: 1.8.15 - version: 1.8.15 - tsconfig-paths: - specifier: 4.2.0 - version: 4.2.0 - typescript: - specifier: 5.8.3 - version: 5.8.3 uuid: specifier: 11.1.0 version: 11.1.0 - vite: - specifier: 6.3.3 - version: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vue: specifier: 3.5.14 version: 3.5.14(typescript@5.8.3) devDependencies: '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 + specifier: npm:@transfem-org/summaly@5.2.2 + version: '@transfem-org/summaly@5.2.2' + '@rollup/plugin-json': + specifier: 6.1.0 + version: 6.1.0(rollup@4.40.0) + '@rollup/plugin-replace': + specifier: 6.0.2 + version: 6.0.2(rollup@4.40.0) + '@rollup/pluginutils': + specifier: 5.1.4 + version: 5.1.4(rollup@4.40.0) '@testing-library/vue': specifier: 8.1.0 version: 8.1.0(@vue/compiler-sfc@3.5.14)(@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)) + '@twemoji/parser': + specifier: 15.1.1 + version: 15.1.1 '@types/estree': specifier: 1.0.7 version: 1.0.7 @@ -1210,15 +1132,24 @@ importers: '@typescript-eslint/parser': specifier: 8.31.0 version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + '@vitejs/plugin-vue': + specifier: 5.2.3 + version: 5.2.3(vite@6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.14(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 3.1.2 version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) + '@vue/compiler-sfc': + specifier: 3.5.14 + version: 3.5.14 '@vue/runtime-core': specifier: 3.5.14 version: 3.5.14 acorn: specifier: 8.14.1 version: 8.14.1 + astring: + specifier: 1.9.0 + version: 1.9.0 cross-env: specifier: 7.0.3 version: 7.0.3 @@ -1228,6 +1159,9 @@ importers: eslint-plugin-vue: specifier: 10.0.0 version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + estree-walker: + specifier: 3.0.3 + version: 3.0.3 fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -1249,9 +1183,27 @@ importers: prettier: specifier: 3.5.3 version: 3.5.3 + rollup: + specifier: 4.40.0 + version: 4.40.0 + sass: + specifier: 1.87.0 + version: 1.87.0 start-server-and-test: specifier: 2.0.11 version: 2.0.11 + tsc-alias: + specifier: 1.8.15 + version: 1.8.15 + tsconfig-paths: + specifier: 4.2.0 + version: 4.2.0 + typescript: + specifier: 5.8.3 + version: 5.8.3 + vite: + specifier: 6.3.3 + version: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vite-plugin-turbosnap: specifier: 1.0.3 version: 1.0.3 @@ -1270,9 +1222,6 @@ importers: misskey-js: specifier: workspace:* version: link:../misskey-js - nodemon: - specifier: 3.1.7 - version: 3.1.7 vue: specifier: 3.5.13 version: 3.5.13(typescript@5.8.3) @@ -1292,6 +1241,9 @@ importers: eslint-plugin-vue: specifier: 10.0.0 version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + nodemon: + specifier: 3.1.10 + version: 3.1.10 typescript: specifier: 5.8.3 version: 5.8.3 @@ -1301,18 +1253,12 @@ importers: packages/megalodon: dependencies: - '@types/jest': - specifier: ^29.5.10 - version: 29.5.12 - '@types/oauth': - specifier: ^0.9.4 - version: 0.9.6 axios: - specifier: 1.7.4 - version: 1.7.4 + specifier: 1.9.0 + version: 1.9.0(debug@4.4.0) dayjs: - specifier: ^1.11.10 - version: 1.11.10 + specifier: 1.11.13 + version: 1.11.13 form-data: specifier: 4.0.2 version: 4.0.2 @@ -1323,30 +1269,21 @@ importers: specifier: 5.8.3 version: 5.8.3 devDependencies: - '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) - eslint: - specifier: 9.25.1 - version: 9.25.1 - eslint-config-prettier: - specifier: ^9.0.0 - version: 9.1.0(eslint@9.25.1) + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 + '@types/oauth': + specifier: 0.9.6 + version: 0.9.6 jest: specifier: 29.7.0 version: 29.7.0(@types/node@22.15.2) jest-worker: specifier: 29.7.0 version: 29.7.0 - prettier: - specifier: 3.5.3 - version: 3.5.3 ts-jest: - specifier: ^29.1.1 - version: 29.1.2(@babel/core@7.24.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.3)(jest@29.7.0(@types/node@22.15.2))(typescript@5.8.3) + specifier: 29.3.4 + version: 29.3.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.3)(jest@29.7.0(@types/node@22.15.2))(typescript@5.8.3) packages/misskey-bubble-game: dependencies: @@ -1393,9 +1330,6 @@ importers: packages/misskey-js: dependencies: - '@simplewebauthn/types': - specifier: 12.0.0 - version: 12.0.0 eventemitter3: specifier: 5.0.1 version: 5.0.1 @@ -1406,6 +1340,9 @@ importers: '@microsoft/api-extractor': specifier: 7.52.5 version: 7.52.5(@types/node@22.15.2) + '@simplewebauthn/types': + specifier: 12.0.0 + version: 12.0.0 '@swc/jest': specifier: 0.2.38 version: 0.2.38(@swc/core@1.11.24) @@ -1425,8 +1362,8 @@ importers: specifier: 0.25.3 version: 0.25.3 execa: - specifier: 8.0.1 - version: 8.0.1 + specifier: 9.5.2 + version: 9.5.2 glob: specifier: 11.0.2 version: 11.0.2 @@ -1848,11 +1785,6 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.7': - resolution: {integrity: sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.27.2': resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} engines: {node: '>=6.0.0'} @@ -2693,9 +2625,6 @@ packages: '@misskey-dev/sharp-read-bmp@1.3.0': resolution: {integrity: sha512-18K95y0tXTtwl4BVfQb0JCr/9KHoHOfTKUUmZ7ibjzbS4bR/kGKoRkADsrdqBllF3nvu7PQN8zjUoM4SWoBLBg==} - '@misskey-dev/summaly@5.2.1': - resolution: {integrity: sha512-fcFd7ssHAghRntewRROOpRxv+VH18uz85Kzg6pZK1EFyqPOXxf39ErRA9HnJSzPYQT6KJTqBWuKHbCGoFlceXg==} - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==} cpu: [arm64] @@ -3149,8 +3078,8 @@ packages: resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} engines: {node: '>=10'} - '@phosphor-icons/web@2.1.1': - resolution: {integrity: sha512-QjrfbItu5Rb2i37GzsKxmrRHfZPTVk3oXSPBnQ2+oACDbQRWGAeB0AsvZw263n1nFouQuff+khOCtRbrc6+k+A==} + '@phosphor-icons/web@2.1.2': + resolution: {integrity: sha512-rPAR9o/bEcp4Cw4DEeZHXf+nlGCMNGkNDRizYHM47NLxz9vvEHp/Tt6FMK1NcWadzw/pFDPnRBGi/ofRya958A==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -3167,7 +3096,6 @@ packages: '@readme/json-schema-ref-parser@1.2.0': resolution: {integrity: sha512-Bt3QVovFSua4QmHa65EHUmh2xS0XJ3rgTEUPH998f4OW4VVJke3BuS16f+kM0ZLOGdvIrzrPRqwihuv5BAjtrA==} - deprecated: This package is no longer maintained. Please use `@apidevtools/json-schema-ref-parser` instead. '@readme/openapi-parser@2.7.0': resolution: {integrity: sha512-P8WSr8WTOxilnT89tcCRKWYsG/II4sAwt1a/DIWub8xTtkrG9cCBBy/IUcvc5X8oGWN82MwcTA3uEkDrXZd/7A==} @@ -4080,12 +4008,16 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@transfem-org/sfm-js@0.24.5': - resolution: {integrity: sha1-c9qJO12lIG+kovDGKjZmK2qPqcw=, tarball: https://activitypub.software/api/v4/projects/2/packages/npm/@transfem-org/sfm-js/-/@transfem-org/sfm-js-0.24.5.tgz} + '@transfem-org/cli-highlight@2.1.12': + resolution: {integrity: sha1-LSVFMGgZU9oQlHSVb5XEzOG+yeQ=, tarball: https://activitypub.software/api/v4/projects/229/packages/npm/@transfem-org/cli-highlight/-/@transfem-org/cli-highlight-2.1.12.tgz} + engines: {node: ^22.0.0} '@transfem-org/sfm-js@0.24.6': resolution: {integrity: sha1-7t+TkCd3PZk+RbbrGbZ/iMs2y7o=, tarball: https://activitypub.software/api/v4/projects/2/packages/npm/@transfem-org/sfm-js/-/@transfem-org/sfm-js-0.24.6.tgz} + '@transfem-org/summaly@5.2.2': + resolution: {integrity: sha1-MO7cCppxE0luitQqz9A6RiWHpco=, tarball: https://activitypub.software/api/v4/projects/217/packages/npm/@transfem-org/summaly/-/@transfem-org/summaly-5.2.2.tgz} + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -4199,9 +4131,6 @@ packages: '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - '@types/http-link-header@1.0.7': - resolution: {integrity: sha512-snm5oLckop0K3cTDAiBnZDy6ncx9DJ3mCRDvs42C884MbVYPP74Tiq2hFsSDRTyjK6RyDYDIulPiW23ge+g5Lw==} - '@types/istanbul-lib-coverage@2.0.4': resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} @@ -4211,9 +4140,6 @@ packages: '@types/istanbul-reports@3.0.1': resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - '@types/jest@29.5.12': - resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} - '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} @@ -4319,9 +4245,6 @@ packages: '@types/range-parser@1.2.4': resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - '@types/ratelimiter@3.4.6': - resolution: {integrity: sha512-Bv6WLSXPGLVsBjkizXtn+ef78R92e36/DFQo2wXPTHtp1cYXF6rCULMqf9WcZPAtyMZMvQAtIPeYMA1xAyxghw==} - '@types/react@18.0.28': resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==} @@ -4811,9 +4734,6 @@ packages: resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} engines: {node: '>=14'} - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -4842,8 +4762,8 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - argon2@0.40.1: - resolution: {integrity: sha512-DjtHDwd7pm12qeWyfihHoM8Bn5vGcgH6sKwgPqwNYroRmxlrzadHEvMyuvQxN/V8YSyRRKD5x6ito09q1e9OyA==} + argon2@0.43.0: + resolution: {integrity: sha512-u/HKLcbWShVDhkfwI4hWyiUf3qyX8QhTfaIv2cWE18uqhXCmR5hb6Ed7oqYi2KCQegeAnRhiFzbjzm7i5yl1GA==} engines: {node: '>=16.17.0'} argparse@1.0.10: @@ -4929,9 +4849,6 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - async-mutex@0.5.0: - resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} - async@0.2.10: resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} @@ -4975,8 +4892,8 @@ packages: axios@1.7.4: resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} - axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.9.0: + resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} b4a@1.6.4: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} @@ -5356,11 +5273,6 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} - cli-highlight@2.1.11: - resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} - engines: {node: '>=8.0.0', npm: '>=5.0.0'} - hasBin: true - cli-table3@0.6.5: resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} @@ -5376,9 +5288,6 @@ packages: cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -5669,9 +5578,6 @@ packages: date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} - dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} - dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} @@ -5901,11 +5807,8 @@ packages: domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.0.1: - resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} - - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} dotenv@16.5.0: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} @@ -5935,6 +5838,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + electron-to-chromium@1.4.686: resolution: {integrity: sha512-3avY1B+vUzNxEgkBDpKOP8WarvUAEwpRaiCL0He5OKWEFxzaOFiq4WoZEZe7qh0ReS7DiWoHMnYoQCKxNZNzSg==} @@ -6085,12 +5993,6 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - eslint-formatter-pretty@4.1.0: resolution: {integrity: sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==} engines: {node: '>=10'} @@ -6393,6 +6295,9 @@ packages: resolution: {integrity: sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==} engines: {node: '>=18'} + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filename-reserved-regex@3.0.0: resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6630,12 +6535,10 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} @@ -6649,8 +6552,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globals@16.1.0: + resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} globalthis@1.0.3: @@ -6690,10 +6593,6 @@ packages: resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==} engines: {node: '>=0.8.0'} - happy-dom@16.8.1: - resolution: {integrity: sha512-n0QrmT9lD81rbpKsyhnlz3DgnMZlaOkJPpgi746doA+HvaMC79bdWkwjrNnGJRvDrWTI8iOcJiVTJ5CdT/AZRw==} - engines: {node: '>=18.0.0'} - happy-dom@17.4.4: resolution: {integrity: sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==} engines: {node: '>=18.0.0'} @@ -6771,11 +6670,8 @@ packages: headers-polyfill@4.0.2: resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} - highlight.js@10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - - highlight.js@11.10.0: - resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==} + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} hosted-git-info@2.8.9: @@ -6822,10 +6718,6 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} - http-link-header@1.1.3: - resolution: {integrity: sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==} - engines: {node: '>=6.0.0'} - http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -6932,7 +6824,6 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -7245,6 +7136,11 @@ packages: resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} engines: {node: 20 || >=22} + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7497,9 +7393,6 @@ packages: resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} engines: {'0': node >=0.6.0} - jsrsasign@11.1.0: - resolution: {integrity: sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==} - jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} @@ -7517,8 +7410,8 @@ packages: jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} - katex@0.16.10: - resolution: {integrity: sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==} + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} hasBin: true keyv@4.5.4: @@ -7598,7 +7491,6 @@ packages: lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} @@ -7798,10 +7690,6 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - microformats-parser@2.0.2: - resolution: {integrity: sha512-tUf9DmN4Jq/tGyp1YH2V6D/Cud+9Uc0WhjjUFirqVeHTRkkfLDacv6BQFT7h7HFsD0Z8wja5eKkRgzZU8bv0Fw==} - engines: {node: '>=18'} - micromark-core-commonmark@2.0.0: resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} @@ -8093,9 +7981,6 @@ packages: resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} engines: {node: '>=12.0.0'} - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.20.0: resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} @@ -8160,10 +8045,13 @@ packages: resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==} engines: {node: ^16 || ^18 || >= 20} + node-addon-api@8.3.1: + resolution: {integrity: sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==} + engines: {node: ^18 || ^20 || >= 21} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -8186,6 +8074,10 @@ packages: resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} hasBin: true + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-gyp@10.2.0: resolution: {integrity: sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==} engines: {node: ^16.14.0 || >=18.0.0} @@ -8209,11 +8101,6 @@ packages: engines: {node: '>=10'} hasBin: true - nodemon@3.1.7: - resolution: {integrity: sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==} - engines: {node: '>=10'} - hasBin: true - nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} @@ -8269,13 +8156,6 @@ packages: nwsapi@2.2.19: resolution: {integrity: sha512-94bcyI3RsqiZufXjkr3ltkI86iEl+I7uiHVDtcq9wJUTwYQJ5odHDeSzkkrRzi80jJ8MaeZgqKjH1bAWAFw9bA==} - oauth2orize-pkce@0.1.2: - resolution: {integrity: sha512-grto2UYhXHi9GLE3IBgBBbV87xci55+bCyjpVuxKyzol6I5Rg0K1MiTuXE+JZk54R86SG2wqXODMiZYHraPpxw==} - - oauth2orize@1.12.0: - resolution: {integrity: sha512-j4XtFDQUBsvUHPjUmvmNDUDMYed2MphMIJBhyxVVe8hGCjkuYnjIsW+D9qk8c5ciXRdnk6x6tEbiO6PLeOZdCQ==} - engines: {node: '>= 0.4.0'} - oauth@0.10.2: resolution: {integrity: sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q==} @@ -8442,21 +8322,12 @@ packages: parse-srcset@1.0.2: resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} - parse5-htmlparser2-tree-adapter@6.0.1: - resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} - parse5-htmlparser2-tree-adapter@7.0.0: resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} parse5-parser-stream@7.1.2: resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} - parse5@5.1.1: - resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} - - parse5@6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -8636,8 +8507,8 @@ packages: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} - pnpm@10.10.0: - resolution: {integrity: sha512-1hXbJG/nDyXc/qbY1z3ueCziPiJF48T2+Igkn7VoFJMYY33Kc8LFyO8qTKDVZX+5VnGIv6tH9WbR7mzph4FcOQ==} + pnpm@9.6.0: + resolution: {integrity: sha512-ONxvuo26NbOTQLlwARLC/h4S8QsXE0cVpKqYzPe7A152/Zgc8Ls4TfqY+NavVIHCvvL0Jmokv6IMNOtxR84LXg==} engines: {node: '>=18.12'} hasBin: true @@ -8968,8 +8839,8 @@ packages: engines: {node: '>= 0.10'} hasBin: true - psl@1.13.0: - resolution: {integrity: sha512-BFwmFXiJoFqlUpZ5Qssolv15DMyc84gTBds1BjsV1BfXEo1UyyD7GsmN67n7J77uRhoSNW1AXtXKPLcBFQn9Aw==} + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} pstree.remy@1.1.8: resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} @@ -9078,9 +8949,6 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - ratelimiter@3.4.1: - resolution: {integrity: sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ==} - raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -9301,9 +9169,6 @@ packages: rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - rss-parser@3.13.0: - resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -9404,6 +9269,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} @@ -9966,13 +9836,6 @@ packages: textarea-caret@3.1.0: resolution: {integrity: sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q==} - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -10111,12 +9974,13 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} - ts-jest@29.1.2: - resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} - engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} + ts-jest@29.3.4: + resolution: {integrity: sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 '@jest/types': ^29.0.0 babel-jest: ^29.0.0 esbuild: '*' @@ -10125,6 +9989,8 @@ packages: peerDependenciesMeta: '@babel/core': optional: true + '@jest/transform': + optional: true '@jest/types': optional: true babel-jest: @@ -10204,6 +10070,10 @@ packages: resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} engines: {node: '>=16'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -10300,9 +10170,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - uid2@0.0.4: - resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} - uid@2.0.2: resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} engines: {node: '>=8'} @@ -10809,14 +10676,6 @@ packages: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} - xml2js@0.5.0: - resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} - engines: {node: '>=4.0.0'} - - xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} @@ -10857,10 +10716,6 @@ packages: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -11563,10 +11418,6 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/parser@7.25.7': - dependencies: - '@babel/types': 7.25.7 - '@babel/parser@7.27.2': dependencies: '@babel/types': 7.27.1 @@ -12596,7 +12447,7 @@ snapshots: '@misskey-dev/browser-image-resizer@2024.1.0': {} - '@misskey-dev/eslint-plugin@2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@4.2.0(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.0.0)': + '@misskey-dev/eslint-plugin@2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@4.2.0(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.1.0)': dependencies: '@eslint/compat': 1.1.1 '@stylistic/eslint-plugin': 4.2.0(eslint@9.25.1)(typescript@5.8.3) @@ -12604,7 +12455,7 @@ snapshots: '@typescript-eslint/parser': 8.31.0(eslint@9.25.1)(typescript@5.8.3) eslint: 9.25.1 eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) - globals: 16.0.0 + globals: 16.1.0 '@misskey-dev/sharp-read-bmp@1.3.0': dependencies: @@ -12612,16 +12463,6 @@ snapshots: decode-ico: 0.4.1 sharp: 0.34.1 - '@misskey-dev/summaly@5.2.1': - dependencies: - cheerio: 1.0.0 - escape-regexp: 0.0.1 - got: 14.4.7 - html-entities: 2.5.2 - iconv-lite: 0.6.3 - jschardet: 3.1.4 - private-ip: 3.0.2 - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': optional: true @@ -12843,7 +12684,7 @@ snapshots: '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 forwarded-parse: 2.1.2 - semver: 7.6.3 + semver: 7.7.1 transitivePeerDependencies: - supports-color @@ -12976,7 +12817,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.11.2 require-in-the-middle: 7.3.0 - semver: 7.6.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -12988,7 +12829,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.11.2 require-in-the-middle: 7.3.0 - semver: 7.6.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -13000,7 +12841,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.11.2 require-in-the-middle: 7.3.0 - semver: 7.6.3 + semver: 7.7.1 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -13136,7 +12977,7 @@ snapshots: '@phc/format@1.0.0': {} - '@phosphor-icons/web@2.1.1': {} + '@phosphor-icons/web@2.1.2': {} '@pkgjs/parseargs@0.11.0': optional: true @@ -14311,14 +14152,27 @@ snapshots: '@tokenizer/token@0.3.0': {} - '@transfem-org/sfm-js@0.24.5': + '@transfem-org/cli-highlight@2.1.12': dependencies: - '@twemoji/parser': 15.0.0 + chalk: 5.4.1 + domhandler: 5.0.3 + highlight.js: 11.11.1 + htmlparser2: 9.1.0 '@transfem-org/sfm-js@0.24.6': dependencies: '@twemoji/parser': 15.0.0 + '@transfem-org/summaly@5.2.2': + dependencies: + cheerio: 1.0.0 + escape-regexp: 0.0.1 + got: 14.4.7 + html-entities: 2.5.2 + iconv-lite: 0.6.3 + jschardet: 3.1.4 + private-ip: 3.0.2 + '@trysound/sax@0.2.0': {} '@tsd/typescript@5.8.3': {} @@ -14439,10 +14293,6 @@ snapshots: '@types/http-cache-semantics@4.0.4': {} - '@types/http-link-header@1.0.7': - dependencies: - '@types/node': 22.15.2 - '@types/istanbul-lib-coverage@2.0.4': {} '@types/istanbul-lib-report@3.0.0': @@ -14453,11 +14303,6 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.0 - '@types/jest@29.5.12': - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - '@types/jest@29.5.14': dependencies: expect: 29.7.0 @@ -14562,8 +14407,6 @@ snapshots: '@types/range-parser@1.2.4': {} - '@types/ratelimiter@3.4.6': {} - '@types/react@18.0.28': dependencies: '@types/prop-types': 15.7.14 @@ -15207,8 +15050,6 @@ snapshots: ansis@3.17.0: {} - any-promise@1.3.0: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -15245,11 +15086,11 @@ snapshots: arg@5.0.2: {} - argon2@0.40.1: + argon2@0.43.0: dependencies: '@phc/format': 1.0.0 - node-addon-api: 7.1.0 - node-gyp-build: 4.8.1 + node-addon-api: 8.3.1 + node-gyp-build: 4.8.4 argparse@1.0.10: dependencies: @@ -15353,10 +15194,6 @@ snapshots: astring@1.9.0: {} - async-mutex@0.5.0: - dependencies: - tslib: 2.6.2 - async@0.2.10: {} async@3.2.4: {} @@ -15405,7 +15242,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.8.4(debug@4.4.0): + axios@1.9.0(debug@4.4.0): dependencies: follow-redirects: 1.15.9(debug@4.4.0) form-data: 4.0.2 @@ -15862,14 +15699,14 @@ snapshots: css-what: 6.1.0 domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 cheerio@1.0.0: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 encoding-sniffer: 0.2.0 htmlparser2: 9.1.0 parse5: 7.3.0 @@ -15908,15 +15745,6 @@ snapshots: restore-cursor: 3.1.0 optional: true - cli-highlight@2.1.11: - dependencies: - chalk: 4.1.2 - highlight.js: 10.7.3 - mz: 2.7.0 - parse5: 5.1.1 - parse5-htmlparser2-tree-adapter: 6.0.1 - yargs: 16.2.0 - cli-table3@0.6.5: dependencies: string-width: 4.2.3 @@ -15938,12 +15766,6 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 6.2.0 - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -16142,7 +15964,7 @@ snapshots: boolbase: 1.0.0 css-what: 6.1.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 nth-check: 2.1.1 css-tree@2.2.1: @@ -16300,8 +16122,6 @@ snapshots: date-fns@4.1.0: {} - dayjs@1.11.10: {} - dayjs@1.11.13: {} de-indent@1.0.2: {} @@ -16320,11 +16140,9 @@ snapshots: dependencies: ms: 2.1.2 - debug@4.3.5(supports-color@5.5.0): + debug@4.3.5: dependencies: ms: 2.1.2 - optionalDependencies: - supports-color: 5.5.0 debug@4.4.0(supports-color@5.5.0): dependencies: @@ -16515,13 +16333,7 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 - domutils@3.0.1: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - domutils@3.1.0: + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -16557,6 +16369,10 @@ snapshots: ee-first@1.1.1: {} + ejs@3.1.10: + dependencies: + jake: 10.9.2 + electron-to-chromium@1.4.686: {} electron-to-chromium@1.5.123: {} @@ -16761,10 +16577,6 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.25.1): - dependencies: - eslint: 9.25.1 - eslint-formatter-pretty@4.1.0: dependencies: '@types/eslint': 7.29.0 @@ -16949,7 +16761,7 @@ snapshots: execa@5.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 6.0.1 human-signals: 2.1.0 is-stream: 2.0.1 @@ -16961,7 +16773,7 @@ snapshots: execa@6.1.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 6.0.1 human-signals: 3.0.1 is-stream: 3.0.0 @@ -16986,7 +16798,7 @@ snapshots: execa@9.5.2: dependencies: '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 figures: 6.1.0 get-stream: 9.0.1 human-signals: 8.0.0 @@ -17242,6 +17054,10 @@ snapshots: transitivePeerDependencies: - supports-color + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + filename-reserved-regex@3.0.0: {} filenamify@6.0.0: @@ -17328,7 +17144,7 @@ snapshots: foreground-child@3.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 forever-agent@0.6.1: @@ -17548,7 +17364,7 @@ snapshots: globals@14.0.0: {} - globals@16.0.0: {} + globals@16.1.0: {} globalthis@1.0.3: dependencies: @@ -17605,11 +17421,6 @@ snapshots: hammerjs@2.0.8: {} - happy-dom@16.8.1: - dependencies: - webidl-conversions: 7.0.0 - whatwg-mimetype: 3.0.0 - happy-dom@17.4.4: dependencies: webidl-conversions: 7.0.0 @@ -17683,9 +17494,7 @@ snapshots: headers-polyfill@4.0.2: {} - highlight.js@10.7.3: {} - - highlight.js@11.10.0: {} + highlight.js@11.11.1: {} hosted-git-info@2.8.9: {} @@ -17719,14 +17528,14 @@ snapshots: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.0.1 + domutils: 3.2.2 entities: 4.5.0 htmlparser2@9.1.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 entities: 4.5.0 http-cache-semantics@4.1.1: {} @@ -17739,8 +17548,6 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - http-link-header@1.1.3: {} - http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 @@ -18150,6 +17957,13 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jake@10.9.2: + dependencies: + async: 3.2.4 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -18614,8 +18428,6 @@ snapshots: verror: 1.10.0 optional: true - jsrsasign@11.1.0: {} - jstransformer@1.0.0: dependencies: is-promise: 2.2.2 @@ -18643,7 +18455,7 @@ snapshots: jwa: 2.0.0 safe-buffer: 5.2.1 - katex@0.16.10: + katex@0.16.22: dependencies: commander: 8.3.0 @@ -18778,7 +18590,7 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.25.7 + '@babel/parser': 7.27.2 '@babel/types': 7.25.7 source-map-js: 1.2.1 @@ -18978,10 +18790,6 @@ snapshots: methods@1.1.2: {} - microformats-parser@2.0.2: - dependencies: - parse5: 7.3.0 - micromark-core-commonmark@2.0.0: dependencies: decode-named-character-reference: 1.0.2 @@ -19372,12 +19180,6 @@ snapshots: mylas@2.1.13: {} - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - nan@2.20.0: {} nanoid@3.3.11: {} @@ -19431,6 +19233,8 @@ snapshots: node-addon-api@7.1.0: {} + node-addon-api@8.3.1: {} + node-domexception@1.0.0: {} node-fetch@2.7.0(encoding@0.1.13): @@ -19448,7 +19252,10 @@ snapshots: node-gyp-build-optional-packages@5.0.7: optional: true - node-gyp-build@4.8.1: {} + node-gyp-build@4.8.1: + optional: true + + node-gyp-build@4.8.4: {} node-gyp@10.2.0: dependencies: @@ -19486,19 +19293,6 @@ snapshots: touch: 3.1.0 undefsafe: 2.0.5 - nodemon@3.1.7: - dependencies: - chokidar: 4.0.3 - debug: 4.3.5(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.6.0 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.0 - undefsafe: 2.0.5 - nofilter@3.1.0: {} nopt@1.0.10: @@ -19555,16 +19349,6 @@ snapshots: nwsapi@2.2.19: optional: true - oauth2orize-pkce@0.1.2: {} - - oauth2orize@1.12.0: - dependencies: - debug: 2.6.9 - uid2: 0.0.4 - utils-merge: 1.0.1 - transitivePeerDependencies: - - supports-color - oauth@0.10.2: {} object-assign@4.1.1: {} @@ -19736,10 +19520,6 @@ snapshots: parse-srcset@1.0.2: {} - parse5-htmlparser2-tree-adapter@6.0.1: - dependencies: - parse5: 6.0.1 - parse5-htmlparser2-tree-adapter@7.0.0: dependencies: domhandler: 5.0.3 @@ -19749,10 +19529,6 @@ snapshots: dependencies: parse5: 7.3.0 - parse5@5.1.1: {} - - parse5@6.0.1: {} - parse5@7.3.0: dependencies: entities: 6.0.0 @@ -19913,7 +19689,7 @@ snapshots: pngjs@5.0.0: {} - pnpm@10.10.0: {} + pnpm@9.6.0: {} polished@4.2.2: dependencies: @@ -20222,7 +19998,7 @@ snapshots: dependencies: event-stream: 3.3.4 - psl@1.13.0: + psl@1.15.0: dependencies: punycode: 2.3.1 @@ -20348,8 +20124,6 @@ snapshots: range-parser@1.2.1: {} - ratelimiter@3.4.1: {} - raw-body@2.5.2: dependencies: bytes: 3.1.2 @@ -20645,11 +20419,6 @@ snapshots: rrweb-cssom@0.8.0: optional: true - rss-parser@3.13.0: - dependencies: - entities: 2.2.0 - xml2js: 0.5.0 - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -20743,6 +20512,8 @@ snapshots: semver@7.7.1: {} + semver@7.7.2: {} + send@0.19.0: dependencies: debug: 2.6.9 @@ -20923,7 +20694,7 @@ snapshots: dependencies: '@hapi/hoek': 11.0.4 '@hapi/wreck': 18.0.1 - debug: 4.3.5(supports-color@5.5.0) + debug: 4.3.5 joi: 17.11.0 transitivePeerDependencies: - supports-color @@ -20934,7 +20705,7 @@ snapshots: simple-update-notifier@2.0.0: dependencies: - semver: 7.6.3 + semver: 7.7.1 sinon@18.0.1: dependencies: @@ -21435,14 +21206,6 @@ snapshots: textarea-caret@3.1.0: {} - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -21514,7 +21277,7 @@ snapshots: tough-cookie@4.1.4: dependencies: - psl: 1.13.0 + psl: 1.15.0 punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 @@ -21553,20 +21316,23 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@29.1.2(@babel/core@7.24.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.3)(jest@29.7.0(@types/node@22.15.2))(typescript@5.8.3): + ts-jest@29.3.4(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.3)(jest@29.7.0(@types/node@22.15.2))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 + ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 jest: 29.7.0(@types/node@22.15.2) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.6.0 + semver: 7.7.2 + type-fest: 4.41.0 typescript: 5.8.3 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.24.7 + '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.7) esbuild: 0.25.3 @@ -21643,6 +21409,8 @@ snapshots: type-fest@4.27.0: {} + type-fest@4.41.0: {} + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -21714,8 +21482,6 @@ snapshots: typescript@5.8.3: {} - uid2@0.0.4: {} - uid@2.0.2: dependencies: '@lukeed/csprng': 1.0.1 @@ -21858,7 +21624,7 @@ snapshots: dependencies: diff: 5.2.0 diff-match-patch: 1.0.5 - highlight.js: 11.10.0 + highlight.js: 11.11.1 vue: 3.5.14(typescript@5.8.3) vue-demi: 0.14.7(vue@3.5.14(typescript@5.8.3)) @@ -22024,7 +21790,7 @@ snapshots: vue-docgen-api@4.75.1(vue@3.5.14(typescript@5.8.3)): dependencies: - '@babel/parser': 7.25.7 + '@babel/parser': 7.27.2 '@babel/types': 7.25.7 '@vue/compiler-dom': 3.5.14 '@vue/compiler-sfc': 3.5.14 @@ -22097,7 +21863,7 @@ snapshots: wait-on@8.0.3(debug@4.4.0): dependencies: - axios: 1.8.4(debug@4.4.0) + axios: 1.9.0(debug@4.4.0) joi: 17.13.3 lodash: 4.17.21 minimist: 1.2.8 @@ -22261,13 +22027,6 @@ snapshots: xml-name-validator@5.0.0: optional: true - xml2js@0.5.0: - dependencies: - sax: 1.2.4 - xmlbuilder: 11.0.1 - - xmlbuilder@11.0.1: {} - xmlchars@2.2.0: optional: true @@ -22306,16 +22065,6 @@ snapshots: y18n: 4.0.3 yargs-parser: 18.1.3 - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - yargs@17.7.2: dependencies: cliui: 8.0.1 |