mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-26 01:33:08 +02:00
Compare commits
24 commits
990e53fee4
...
f93a8e2d38
Author | SHA1 | Date | |
---|---|---|---|
|
f93a8e2d38 | ||
|
d3d0e510d8 | ||
|
65a1bc2199 | ||
|
469c3f3f1a | ||
|
75bce2228f | ||
|
65a7623944 | ||
|
b2d520369f | ||
|
441523b6d4 | ||
|
fc06494908 | ||
|
f091b84c6e | ||
|
4bc517ca89 | ||
|
bb3694bfed | ||
|
1bb5021c54 | ||
|
a981bca7a3 | ||
|
3a3a051bb5 | ||
|
7684f45a5e | ||
|
25948c9232 | ||
|
83f1c596b0 | ||
|
93bd4dc8fe | ||
|
074c47fdf8 | ||
|
c6e3ec07d1 | ||
|
e93e73673a | ||
|
b0fcc11d9e | ||
|
83e9057b27 |
49 changed files with 655 additions and 298 deletions
2
.npmrc
2
.npmrc
|
@ -1,2 +1,2 @@
|
||||||
@sharkey:registry=https://git.joinsharkey.org/api/packages/Sharkey/npm/
|
@transfem-org:registry=https://activitypub.software/api/v4/packages/npm/
|
||||||
engine-strict = true
|
engine-strict = true
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href="https://joinsharkey.org">
|
<a href="https://fedidb.org/software/sharkey">
|
||||||
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=sharkey&labelColor=363B40" alt="find an instance"/></a>
|
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=sharkey&labelColor=363B40" alt="find an instance"/></a>
|
||||||
|
|
||||||
<a href="https://docs.joinsharkey.org/docs/install/fresh/">
|
<a href="https://docs.joinsharkey.org/docs/install/fresh/">
|
||||||
|
|
|
@ -553,6 +553,8 @@ objectStorageUseProxy: "Connect over Proxy"
|
||||||
objectStorageUseProxyDesc: "Turn this off if you are not going to use a Proxy for API connections"
|
objectStorageUseProxyDesc: "Turn this off if you are not going to use a Proxy for API connections"
|
||||||
objectStorageSetPublicRead: "Set \"public-read\" on upload"
|
objectStorageSetPublicRead: "Set \"public-read\" on upload"
|
||||||
s3ForcePathStyleDesc: "If s3ForcePathStyle is enabled, the bucket name has to included in the path of the URL as opposed to the hostname of the URL. You may need to enable this setting when using services such as a self-hosted Minio instance."
|
s3ForcePathStyleDesc: "If s3ForcePathStyle is enabled, the bucket name has to included in the path of the URL as opposed to the hostname of the URL. You may need to enable this setting when using services such as a self-hosted Minio instance."
|
||||||
|
deeplFreeMode: "Use DeepLX-JS (No Auth Key)"
|
||||||
|
deeplFreeModeDescription: "Need Help? Check our documentation to know how to setup DeepLX-JS."
|
||||||
serverLogs: "Server logs"
|
serverLogs: "Server logs"
|
||||||
deleteAll: "Delete all"
|
deleteAll: "Delete all"
|
||||||
showFixedPostForm: "Display the posting form at the top of the timeline"
|
showFixedPostForm: "Display the posting form at the top of the timeline"
|
||||||
|
|
8
locales/index.d.ts
vendored
8
locales/index.d.ts
vendored
|
@ -2240,6 +2240,14 @@ export interface Locale extends ILocale {
|
||||||
* s3ForcePathStyleを有効にすると、バケット名をURLのホスト名ではなくパスの一部として指定することを強制します。セルフホストされたMinioなどの使用時に有効にする必要がある場合があります。
|
* s3ForcePathStyleを有効にすると、バケット名をURLのホスト名ではなくパスの一部として指定することを強制します。セルフホストされたMinioなどの使用時に有効にする必要がある場合があります。
|
||||||
*/
|
*/
|
||||||
"s3ForcePathStyleDesc": string;
|
"s3ForcePathStyleDesc": string;
|
||||||
|
/**
|
||||||
|
* DeepLX-JS を使用する (認証キーなし)
|
||||||
|
*/
|
||||||
|
"deeplFreeMode": string;
|
||||||
|
/**
|
||||||
|
* ヘルプが必要ですか? DeepLX-JSのセットアップ方法については、ドキュメントを参照してください。
|
||||||
|
*/
|
||||||
|
"deeplFreeModeDescription": string;
|
||||||
/**
|
/**
|
||||||
* サーバーログ
|
* サーバーログ
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -556,6 +556,8 @@ objectStorageUseProxy: "Proxyを利用する"
|
||||||
objectStorageUseProxyDesc: "API接続にproxyを利用しない場合はオフにしてください"
|
objectStorageUseProxyDesc: "API接続にproxyを利用しない場合はオフにしてください"
|
||||||
objectStorageSetPublicRead: "アップロード時に'public-read'を設定する"
|
objectStorageSetPublicRead: "アップロード時に'public-read'を設定する"
|
||||||
s3ForcePathStyleDesc: "s3ForcePathStyleを有効にすると、バケット名をURLのホスト名ではなくパスの一部として指定することを強制します。セルフホストされたMinioなどの使用時に有効にする必要がある場合があります。"
|
s3ForcePathStyleDesc: "s3ForcePathStyleを有効にすると、バケット名をURLのホスト名ではなくパスの一部として指定することを強制します。セルフホストされたMinioなどの使用時に有効にする必要がある場合があります。"
|
||||||
|
deeplFreeMode: "DeepLX-JS を使用する (認証キーなし)"
|
||||||
|
deeplFreeModeDescription: "ヘルプが必要ですか? DeepLX-JSのセットアップ方法については、ドキュメントを参照してください。"
|
||||||
serverLogs: "サーバーログ"
|
serverLogs: "サーバーログ"
|
||||||
deleteAll: "全て削除"
|
deleteAll: "全て削除"
|
||||||
showFixedPostForm: "タイムライン上部に投稿フォームを表示する"
|
showFixedPostForm: "タイムライン上部に投稿フォームを表示する"
|
||||||
|
|
18
packages/backend/migration/1706232992000-deeplx.js
Normal file
18
packages/backend/migration/1706232992000-deeplx.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class Deeplx1706232992000 {
|
||||||
|
name = 'Deeplx1706232992000';
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplFreeMode" boolean NOT NULL DEFAULT false`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplFreeInstance" character varying(1024)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplFreeMode"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplFreeInstance"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,7 +83,7 @@
|
||||||
"@nestjs/core": "10.2.10",
|
"@nestjs/core": "10.2.10",
|
||||||
"@nestjs/testing": "10.2.10",
|
"@nestjs/testing": "10.2.10",
|
||||||
"@peertube/http-signature": "1.7.0",
|
"@peertube/http-signature": "1.7.0",
|
||||||
"@sharkey/sfm-js": "0.24.4",
|
"@transfem-org/sfm-js": "0.24.4",
|
||||||
"@simplewebauthn/server": "9.0.0",
|
"@simplewebauthn/server": "9.0.0",
|
||||||
"@sinonjs/fake-timers": "11.2.2",
|
"@sinonjs/fake-timers": "11.2.2",
|
||||||
"@smithy/node-http-handler": "2.1.10",
|
"@smithy/node-http-handler": "2.1.10",
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { intersperse } from '@/misc/prelude/array.js';
|
||||||
import type { IMentionedRemoteUsers } from '@/models/Note.js';
|
import type { IMentionedRemoteUsers } from '@/models/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import * as TreeAdapter from '../../node_modules/parse5/dist/tree-adapters/default.js';
|
import * as TreeAdapter from '../../node_modules/parse5/dist/tree-adapters/default.js';
|
||||||
import type * as mfm from '@sharkey/sfm-js';
|
import type * as mfm from '@transfem-org/sfm-js';
|
||||||
|
|
||||||
const treeAdapter = TreeAdapter.defaultTreeAdapter;
|
const treeAdapter = TreeAdapter.defaultTreeAdapter;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setImmediate } from 'node:timers/promises';
|
import { setImmediate } from 'node:timers/promises';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { In, DataSource, IsNull, LessThan } from 'typeorm';
|
import { In, DataSource, IsNull, LessThan } from 'typeorm';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
@ -328,6 +328,9 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH);
|
data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH);
|
||||||
}
|
}
|
||||||
data.text = data.text.trim();
|
data.text = data.text.trim();
|
||||||
|
if (data.text === '') {
|
||||||
|
data.text = null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data.text = null;
|
data.text = null;
|
||||||
}
|
}
|
||||||
|
@ -807,7 +810,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||||
|
|
||||||
if (!isThreadMuted || !muted) {
|
if (!isThreadMuted && !muted) {
|
||||||
nm.push(data.reply.userId, 'reply');
|
nm.push(data.reply.userId, 'reply');
|
||||||
this.globalEventService.publishMainStream(data.reply.userId, 'reply', noteObj);
|
this.globalEventService.publishMainStream(data.reply.userId, 'reply', noteObj);
|
||||||
|
|
||||||
|
@ -842,7 +845,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||||
|
|
||||||
if (!isThreadMuted || !muted) {
|
if (!isThreadMuted && !muted) {
|
||||||
nm.push(data.renote.userId, type);
|
nm.push(data.renote.userId, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setImmediate } from 'node:timers/promises';
|
import { setImmediate } from 'node:timers/promises';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { DataSource, In, IsNull, LessThan } from 'typeorm';
|
import { DataSource, In, IsNull, LessThan } from 'typeorm';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
@ -46,6 +46,11 @@ import { MetaService } from '@/core/MetaService.js';
|
||||||
import { SearchService } from '@/core/SearchService.js';
|
import { SearchService } from '@/core/SearchService.js';
|
||||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
|
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
||||||
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
|
import { isReply } from '@/misc/is-reply.js';
|
||||||
|
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||||
|
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||||
|
|
||||||
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
|
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
|
||||||
|
|
||||||
|
@ -206,6 +211,8 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
private activeUsersChart: ActiveUsersChart,
|
private activeUsersChart: ActiveUsersChart,
|
||||||
private instanceChart: InstanceChart,
|
private instanceChart: InstanceChart,
|
||||||
private utilityService: UtilityService,
|
private utilityService: UtilityService,
|
||||||
|
private userBlockingService: UserBlockingService,
|
||||||
|
private cacheService: CacheService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -255,16 +262,18 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
if (data.channel != null) data.localOnly = true;
|
if (data.channel != null) data.localOnly = true;
|
||||||
if (data.updatedAt == null) data.updatedAt = new Date();
|
if (data.updatedAt == null) data.updatedAt = new Date();
|
||||||
|
|
||||||
|
const meta = await this.metaService.fetch();
|
||||||
|
|
||||||
if (data.visibility === 'public' && data.channel == null) {
|
if (data.visibility === 'public' && data.channel == null) {
|
||||||
const sensitiveWords = (await this.metaService.fetch()).sensitiveWords;
|
const sensitiveWords = meta.sensitiveWords;
|
||||||
if (this.isSensitive(data, sensitiveWords)) {
|
if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) {
|
||||||
data.visibility = 'home';
|
data.visibility = 'home';
|
||||||
} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
|
} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
|
||||||
data.visibility = 'home';
|
data.visibility = 'home';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const inSilencedInstance = this.utilityService.isSilencedHost((await this.metaService.fetch()).silencedHosts, user.host);
|
const inSilencedInstance = this.utilityService.isSilencedHost((meta).silencedHosts, user.host);
|
||||||
|
|
||||||
if (data.visibility === 'public' && inSilencedInstance && user.host !== null) {
|
if (data.visibility === 'public' && inSilencedInstance && user.host !== null) {
|
||||||
data.visibility = 'home';
|
data.visibility = 'home';
|
||||||
|
@ -296,6 +305,18 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check blocking
|
||||||
|
if (data.renote && !this.isQuote(data)) {
|
||||||
|
if (data.renote.userHost === null) {
|
||||||
|
if (data.renote.userId !== user.id) {
|
||||||
|
const blocked = await this.userBlockingService.checkBlocked(data.renote.userId, user.id);
|
||||||
|
if (blocked) {
|
||||||
|
throw new Error('blocked');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 返信対象がpublicではないならhomeにする
|
// 返信対象がpublicではないならhomeにする
|
||||||
if (data.reply && data.reply.visibility !== 'public' && data.visibility === 'public') {
|
if (data.reply && data.reply.visibility !== 'public' && data.visibility === 'public') {
|
||||||
data.visibility = 'home';
|
data.visibility = 'home';
|
||||||
|
@ -316,6 +337,9 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH);
|
data.text = data.text.slice(0, DB_MAX_NOTE_TEXT_LENGTH);
|
||||||
}
|
}
|
||||||
data.text = data.text.trim();
|
data.text = data.text.trim();
|
||||||
|
if (data.text === '') {
|
||||||
|
data.text = null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data.text = null;
|
data.text = null;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +385,14 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.host && !data.cw) {
|
||||||
|
await this.federatedInstanceService.fetch(user.host).then(async i => {
|
||||||
|
if (i.isNSFW) {
|
||||||
|
data.cw = 'Instance is marked as NSFW';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const update: Partial<MiNote> = {};
|
const update: Partial<MiNote> = {};
|
||||||
if (data.text !== oldnote.text) {
|
if (data.text !== oldnote.text) {
|
||||||
update.text = data.text;
|
update.text = data.text;
|
||||||
|
@ -557,7 +589,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
} else {
|
} else {
|
||||||
this.globalEventService.publishNoteStream(note.id, 'updated', {
|
this.globalEventService.publishNoteStream(note.id, 'updated', {
|
||||||
cw: note.cw,
|
cw: note.cw,
|
||||||
text: note.text!
|
text: note.text!,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,7 +619,15 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isThreadMuted) {
|
const [
|
||||||
|
userIdsWhoMeMuting,
|
||||||
|
] = data.reply.userId ? await Promise.all([
|
||||||
|
this.cacheService.userMutingsCache.fetch(data.reply.userId),
|
||||||
|
]) : [new Set<string>()];
|
||||||
|
|
||||||
|
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||||
|
|
||||||
|
if (!isThreadMuted && !muted) {
|
||||||
nm.push(data.reply.userId, 'reply');
|
nm.push(data.reply.userId, 'reply');
|
||||||
this.globalEventService.publishMainStream(data.reply.userId, 'reply', noteObj);
|
this.globalEventService.publishMainStream(data.reply.userId, 'reply', noteObj);
|
||||||
|
|
||||||
|
@ -603,12 +643,29 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
|
|
||||||
// If it is renote
|
// If it is renote
|
||||||
if (data.renote) {
|
if (data.renote) {
|
||||||
const type = data.text ? 'quote' : 'renote';
|
const type = this.isQuote(data) ? 'quote' : 'renote';
|
||||||
|
|
||||||
// Notify
|
// Notify
|
||||||
if (data.renote.userHost === null) {
|
if (data.renote.userHost === null) {
|
||||||
|
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||||
|
where: {
|
||||||
|
userId: data.renote.userId,
|
||||||
|
threadId: data.renote.threadId ?? data.renote.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const [
|
||||||
|
userIdsWhoMeMuting,
|
||||||
|
] = data.renote.userId ? await Promise.all([
|
||||||
|
this.cacheService.userMutingsCache.fetch(data.renote.userId),
|
||||||
|
]) : [new Set<string>()];
|
||||||
|
|
||||||
|
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||||
|
|
||||||
|
if (!isThreadMuted && !muted) {
|
||||||
nm.push(data.renote.userId, type);
|
nm.push(data.renote.userId, type);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Publish event
|
// Publish event
|
||||||
if ((user.id !== data.renote.userId) && data.renote.userHost === null) {
|
if ((user.id !== data.renote.userId) && data.renote.userHost === null) {
|
||||||
|
@ -657,7 +714,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
this.relayService.deliverToRelays(user, noteActivity);
|
this.relayService.deliverToRelays(user, noteActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
dm.execute();
|
trackPromise(dm.execute());
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
@ -686,28 +743,9 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private isSensitive(note: Option, sensitiveWord: string[]): boolean {
|
private isQuote(note: Option): note is Option & { renote: MiNote } {
|
||||||
if (sensitiveWord.length > 0) {
|
// sync with misc/is-quote.ts
|
||||||
const text = note.cw ?? note.text ?? '';
|
return !!note.renote && (!!note.text || !!note.cw || (!!note.files && !!note.files.length) || !!note.poll);
|
||||||
if (text === '') return false;
|
|
||||||
const matched = sensitiveWord.some(filter => {
|
|
||||||
// represents RegExp
|
|
||||||
const regexp = filter.match(/^\/(.+)\/(.*)$/);
|
|
||||||
// This should never happen due to input sanitisation.
|
|
||||||
if (!regexp) {
|
|
||||||
const words = filter.split(' ');
|
|
||||||
return words.every(keyword => text.includes(keyword));
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new RE2(regexp[1], regexp[2]).test(text);
|
|
||||||
} catch (err) {
|
|
||||||
// This should never happen due to input sanitisation.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (matched) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -720,7 +758,15 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isThreadMuted) {
|
const [
|
||||||
|
userIdsWhoMeMuting,
|
||||||
|
] = u.id ? await Promise.all([
|
||||||
|
this.cacheService.userMutingsCache.fetch(u.id),
|
||||||
|
]) : [new Set<string>()];
|
||||||
|
|
||||||
|
const muted = isUserRelated(note, userIdsWhoMeMuting);
|
||||||
|
|
||||||
|
if (isThreadMuted || muted) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +794,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
const user = await this.usersRepository.findOneBy({ id: note.userId });
|
const user = await this.usersRepository.findOneBy({ id: note.userId });
|
||||||
if (user == null) throw new Error('user not found');
|
if (user == null) throw new Error('user not found');
|
||||||
|
|
||||||
const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0)
|
const content = data.renote && !this.isQuote(data)
|
||||||
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
|
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
|
||||||
: this.apRendererService.renderUpdate(await this.apRendererService.renderUpNote(note, false), user);
|
: this.apRendererService.renderUpdate(await this.apRendererService.renderUpNote(note, false), user);
|
||||||
|
|
||||||
|
@ -782,6 +828,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
@bindThis
|
@bindThis
|
||||||
private async pushToTl(note: MiNote, user: { id: MiUser['id']; host: MiUser['host']; }) {
|
private async pushToTl(note: MiNote, user: { id: MiUser['id']; host: MiUser['host']; }) {
|
||||||
const meta = await this.metaService.fetch();
|
const meta = await this.metaService.fetch();
|
||||||
|
if (!meta.enableFanoutTimeline) return;
|
||||||
|
|
||||||
const r = this.redisForTimelines.pipeline();
|
const r = this.redisForTimelines.pipeline();
|
||||||
|
|
||||||
|
@ -825,7 +872,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
|
|
||||||
if (note.visibility === 'followers') {
|
if (note.visibility === 'followers') {
|
||||||
// TODO: 重そうだから何とかしたい Set 使う?
|
// TODO: 重そうだから何とかしたい Set 使う?
|
||||||
userListMemberships = userListMemberships.filter(x => followings.some(f => f.followerId === x.userListUserId));
|
userListMemberships = userListMemberships.filter(x => x.userListUserId === user.id || followings.some(f => f.followerId === x.userListUserId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: あまりにも数が多いと redisPipeline.exec に失敗する(理由は不明)ため、3万件程度を目安に分割して実行するようにする
|
// TODO: あまりにも数が多いと redisPipeline.exec に失敗する(理由は不明)ため、3万件程度を目安に分割して実行するようにする
|
||||||
|
@ -834,7 +881,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
if (note.visibility === 'specified' && !note.visibleUserIds.some(v => v === following.followerId)) continue;
|
if (note.visibility === 'specified' && !note.visibleUserIds.some(v => v === following.followerId)) continue;
|
||||||
|
|
||||||
// 「自分自身への返信 or そのフォロワーへの返信」のどちらでもない場合
|
// 「自分自身への返信 or そのフォロワーへの返信」のどちらでもない場合
|
||||||
if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === following.followerId)) {
|
if (isReply(note, following.followerId)) {
|
||||||
if (!following.withReplies) continue;
|
if (!following.withReplies) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,11 +895,12 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
// ダイレクトのとき、そのリストが対象外のユーザーの場合
|
// ダイレクトのとき、そのリストが対象外のユーザーの場合
|
||||||
if (
|
if (
|
||||||
note.visibility === 'specified' &&
|
note.visibility === 'specified' &&
|
||||||
|
note.userId !== userListMembership.userListUserId &&
|
||||||
!note.visibleUserIds.some(v => v === userListMembership.userListUserId)
|
!note.visibleUserIds.some(v => v === userListMembership.userListUserId)
|
||||||
) continue;
|
) continue;
|
||||||
|
|
||||||
// 「自分自身への返信 or そのリストの作成者への返信」のどちらでもない場合
|
// 「自分自身への返信 or そのリストの作成者への返信」のどちらでもない場合
|
||||||
if (note.replyId && !(note.replyUserId === note.userId || note.replyUserId === userListMembership.userListUserId)) {
|
if (isReply(note, userListMembership.userListUserId)) {
|
||||||
if (!userListMembership.withReplies) continue;
|
if (!userListMembership.withReplies) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,11 +918,14 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自分自身以外への返信
|
// 自分自身以外への返信
|
||||||
if (note.replyId && note.replyUserId !== note.userId) {
|
if (isReply(note)) {
|
||||||
this.fanoutTimelineService.push(`userTimelineWithReplies:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
|
this.fanoutTimelineService.push(`userTimelineWithReplies:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
|
||||||
|
|
||||||
if (note.visibility === 'public' && note.userHost == null) {
|
if (note.visibility === 'public' && note.userHost == null) {
|
||||||
this.fanoutTimelineService.push('localTimelineWithReplies', note.id, 300, r);
|
this.fanoutTimelineService.push('localTimelineWithReplies', note.id, 300, r);
|
||||||
|
if (note.replyUserHost == null) {
|
||||||
|
this.fanoutTimelineService.push(`localTimelineWithReplyTo:${note.replyUserId}`, note.id, 300 / 10, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.fanoutTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
|
this.fanoutTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { MfmService } from '@/core/MfmService.js';
|
import { MfmService } from '@/core/MfmService.js';
|
||||||
import type { MiNote } from '@/models/Note.js';
|
import type { MiNote } from '@/models/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { createPublicKey, randomUUID } from 'node:crypto';
|
import { createPublicKey, randomUUID } from 'node:crypto';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { In } from 'typeorm';
|
import { In } from 'typeorm';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
||||||
|
@ -28,10 +28,10 @@ import { bindThis } from '@/decorators.js';
|
||||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||||
import { isNotNull } from '@/misc/is-not-null.js';
|
import { isNotNull } from '@/misc/is-not-null.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
import { MetaService } from '../MetaService.js';
|
||||||
import { LdSignatureService } from './LdSignatureService.js';
|
import { LdSignatureService } from './LdSignatureService.js';
|
||||||
import { ApMfmService } from './ApMfmService.js';
|
import { ApMfmService } from './ApMfmService.js';
|
||||||
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';
|
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js';
|
||||||
import { MetaService } from '../MetaService.js';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApRendererService {
|
export class ApRendererService {
|
||||||
|
@ -821,12 +821,12 @@ export class ApRendererService {
|
||||||
'_misskey_summary': 'misskey:_misskey_summary',
|
'_misskey_summary': 'misskey:_misskey_summary',
|
||||||
'isCat': 'misskey:isCat',
|
'isCat': 'misskey:isCat',
|
||||||
// Firefish
|
// Firefish
|
||||||
firefish: "https://joinfirefish.org/ns#",
|
firefish: 'https://joinfirefish.org/ns#',
|
||||||
speakAsCat: "firefish:speakAsCat",
|
speakAsCat: 'firefish:speakAsCat',
|
||||||
// Sharkey
|
// Sharkey
|
||||||
sharkey: "https://joinsharkey.org/ns#",
|
sharkey: 'https://joinsharkey.org/ns#',
|
||||||
backgroundUrl: "sharkey:backgroundUrl",
|
backgroundUrl: 'sharkey:backgroundUrl',
|
||||||
listenbrainz: "sharkey:listenbrainz",
|
listenbrainz: 'sharkey:listenbrainz',
|
||||||
// vcard
|
// vcard
|
||||||
vcard: 'http://www.w3.org/2006/vcard/ns#',
|
vcard: 'http://www.w3.org/2006/vcard/ns#',
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { unique } from '@/misc/prelude/array.js';
|
import { unique } from '@/misc/prelude/array.js';
|
||||||
|
|
||||||
export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
|
export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { unique } from '@/misc/prelude/array.js';
|
import { unique } from '@/misc/prelude/array.js';
|
||||||
|
|
||||||
export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
|
export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// test is located in test/extract-mentions
|
// test is located in test/extract-mentions
|
||||||
|
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
|
|
||||||
export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] {
|
export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] {
|
||||||
// TODO: 重複を削除
|
// TODO: 重複を削除
|
||||||
|
|
|
@ -353,6 +353,17 @@ export class MiMeta {
|
||||||
})
|
})
|
||||||
public deeplIsPro: boolean;
|
public deeplIsPro: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public deeplFreeMode: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public deeplFreeInstance: string | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 1024,
|
length: 1024,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
|
import * as fsp from 'node:fs/promises';
|
||||||
import * as vm from 'node:vm';
|
import * as vm from 'node:vm';
|
||||||
import * as crypto from 'node:crypto';
|
import * as crypto from 'node:crypto';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
@ -51,7 +52,7 @@ export class ImportNotesProcessorService {
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async uploadFiles(dir: string, user: MiUser, folder?: MiDriveFolder['id']) {
|
private async uploadFiles(dir: string, user: MiUser, folder?: MiDriveFolder['id']) {
|
||||||
const fileList = fs.readdirSync(dir);
|
const fileList = await fsp.readdir(dir);
|
||||||
for await (const file of fileList) {
|
for await (const file of fileList) {
|
||||||
const name = `${dir}/${file}`;
|
const name = `${dir}/${file}`;
|
||||||
if (fs.statSync(name).isDirectory()) {
|
if (fs.statSync(name).isDirectory()) {
|
||||||
|
@ -130,14 +131,16 @@ export class ImportNotesProcessorService {
|
||||||
return typeof obj[Symbol.iterator] === 'function';
|
return typeof obj[Symbol.iterator] === 'function';
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseTwitterFile(str : string) : null | [{ tweet: any }] {
|
@bindThis
|
||||||
const removed = str.replace(new RegExp('window\\.YTD\\.tweets\\.part0 = ', 'g'), '');
|
private parseTwitterFile(str : string) : { tweet: object }[] {
|
||||||
|
const jsonStr = str.replace(/^\s*window\.YTD\.tweets\.part0\s*=\s*/, '');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return JSON.parse(removed);
|
return JSON.parse(jsonStr);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
//The format is not what we expected. Either this file was tampered with or twitters exports changed
|
//The format is not what we expected. Either this file was tampered with or twitters exports changed
|
||||||
return null;
|
this.logger.warn('Failed to import twitter notes due to malformed file');
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +176,7 @@ export class ImportNotesProcessorService {
|
||||||
const destPath = path + '/twitter.zip';
|
const destPath = path + '/twitter.zip';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(destPath, '', 'binary');
|
await fsp.writeFile(destPath, '', 'binary');
|
||||||
await this.downloadService.downloadUrl(file.url, destPath);
|
await this.downloadService.downloadUrl(file.url, destPath);
|
||||||
} catch (e) { // TODO: 何度か再試行
|
} catch (e) { // TODO: 何度か再試行
|
||||||
if (e instanceof Error || typeof e === 'string') {
|
if (e instanceof Error || typeof e === 'string') {
|
||||||
|
@ -185,21 +188,13 @@ export class ImportNotesProcessorService {
|
||||||
const outputPath = path + '/twitter';
|
const outputPath = path + '/twitter';
|
||||||
try {
|
try {
|
||||||
this.logger.succ(`Unzipping to ${outputPath}`);
|
this.logger.succ(`Unzipping to ${outputPath}`);
|
||||||
ZipReader.withDestinationPath(outputPath).viaBuffer(await fs.promises.readFile(destPath));
|
ZipReader.withDestinationPath(outputPath).viaBuffer(await fsp.readFile(destPath));
|
||||||
|
|
||||||
const unprocessedTweetJson = this.parseTwitterFile(fs.readFileSync(outputPath + '/data/tweets.js', 'utf-8'));
|
const unprocessedTweets = this.parseTwitterFile(await fsp.readFile(outputPath + '/data/tweets.js', 'utf-8'));
|
||||||
|
|
||||||
//Make sure that it isnt null (because if something went wrong in parseTwitterFile it returns null)
|
|
||||||
if (unprocessedTweetJson) {
|
|
||||||
const tweets = Object.keys(unprocessedTweetJson).reduce((m, key, i, obj) => {
|
|
||||||
return m.concat(unprocessedTweetJson[i].tweet);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
const tweets = unprocessedTweets.map(e => e.tweet);
|
||||||
const processedTweets = await this.recreateChain(['id_str'], ['in_reply_to_status_id_str'], tweets, false);
|
const processedTweets = await this.recreateChain(['id_str'], ['in_reply_to_status_id_str'], tweets, false);
|
||||||
this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
|
this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
|
||||||
} else {
|
|
||||||
this.logger.warn('Failed to import twitter notes due to malformed file');
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
@ -211,7 +206,7 @@ export class ImportNotesProcessorService {
|
||||||
const destPath = path + '/facebook.zip';
|
const destPath = path + '/facebook.zip';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(destPath, '', 'binary');
|
await fsp.writeFile(destPath, '', 'binary');
|
||||||
await this.downloadService.downloadUrl(file.url, destPath);
|
await this.downloadService.downloadUrl(file.url, destPath);
|
||||||
} catch (e) { // TODO: 何度か再試行
|
} catch (e) { // TODO: 何度か再試行
|
||||||
if (e instanceof Error || typeof e === 'string') {
|
if (e instanceof Error || typeof e === 'string') {
|
||||||
|
@ -223,8 +218,8 @@ export class ImportNotesProcessorService {
|
||||||
const outputPath = path + '/facebook';
|
const outputPath = path + '/facebook';
|
||||||
try {
|
try {
|
||||||
this.logger.succ(`Unzipping to ${outputPath}`);
|
this.logger.succ(`Unzipping to ${outputPath}`);
|
||||||
ZipReader.withDestinationPath(outputPath).viaBuffer(await fs.promises.readFile(destPath));
|
ZipReader.withDestinationPath(outputPath).viaBuffer(await fsp.readFile(destPath));
|
||||||
const postsJson = fs.readFileSync(outputPath + '/your_activity_across_facebook/posts/your_posts__check_ins__photos_and_videos_1.json', 'utf-8');
|
const postsJson = await fsp.readFile(outputPath + '/your_activity_across_facebook/posts/your_posts__check_ins__photos_and_videos_1.json', 'utf-8');
|
||||||
const posts = JSON.parse(postsJson);
|
const posts = JSON.parse(postsJson);
|
||||||
const facebookFolder = await this.driveFoldersRepository.findOneBy({ name: 'Facebook', userId: job.data.user.id, parentId: folder?.id });
|
const facebookFolder = await this.driveFoldersRepository.findOneBy({ name: 'Facebook', userId: job.data.user.id, parentId: folder?.id });
|
||||||
if (facebookFolder == null && folder) {
|
if (facebookFolder == null && folder) {
|
||||||
|
@ -244,7 +239,7 @@ export class ImportNotesProcessorService {
|
||||||
const destPath = path + '/unknown.zip';
|
const destPath = path + '/unknown.zip';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(destPath, '', 'binary');
|
await fsp.writeFile(destPath, '', 'binary');
|
||||||
await this.downloadService.downloadUrl(file.url, destPath);
|
await this.downloadService.downloadUrl(file.url, destPath);
|
||||||
} catch (e) { // TODO: 何度か再試行
|
} catch (e) { // TODO: 何度か再試行
|
||||||
if (e instanceof Error || typeof e === 'string') {
|
if (e instanceof Error || typeof e === 'string') {
|
||||||
|
@ -256,11 +251,11 @@ export class ImportNotesProcessorService {
|
||||||
const outputPath = path + '/unknown';
|
const outputPath = path + '/unknown';
|
||||||
try {
|
try {
|
||||||
this.logger.succ(`Unzipping to ${outputPath}`);
|
this.logger.succ(`Unzipping to ${outputPath}`);
|
||||||
ZipReader.withDestinationPath(outputPath).viaBuffer(await fs.promises.readFile(destPath));
|
ZipReader.withDestinationPath(outputPath).viaBuffer(await fsp.readFile(destPath));
|
||||||
const isInstagram = type === 'Instagram' || fs.existsSync(outputPath + '/instagram_live') || fs.existsSync(outputPath + '/instagram_ads_and_businesses');
|
const isInstagram = type === 'Instagram' || fs.existsSync(outputPath + '/instagram_live') || fs.existsSync(outputPath + '/instagram_ads_and_businesses');
|
||||||
const isOutbox = type === 'Mastodon' || fs.existsSync(outputPath + '/outbox.json');
|
const isOutbox = type === 'Mastodon' || fs.existsSync(outputPath + '/outbox.json');
|
||||||
if (isInstagram) {
|
if (isInstagram) {
|
||||||
const postsJson = fs.readFileSync(outputPath + '/content/posts_1.json', 'utf-8');
|
const postsJson = await fsp.readFile(outputPath + '/content/posts_1.json', 'utf-8');
|
||||||
const posts = JSON.parse(postsJson);
|
const posts = JSON.parse(postsJson);
|
||||||
const igFolder = await this.driveFoldersRepository.findOneBy({ name: 'Instagram', userId: job.data.user.id, parentId: folder?.id });
|
const igFolder = await this.driveFoldersRepository.findOneBy({ name: 'Instagram', userId: job.data.user.id, parentId: folder?.id });
|
||||||
if (igFolder == null && folder) {
|
if (igFolder == null && folder) {
|
||||||
|
@ -270,16 +265,16 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
this.queueService.createImportIGToDbJob(job.data.user, posts);
|
this.queueService.createImportIGToDbJob(job.data.user, posts);
|
||||||
} else if (isOutbox) {
|
} else if (isOutbox) {
|
||||||
const actorJson = fs.readFileSync(outputPath + '/actor.json', 'utf-8');
|
const actorJson = await fsp.readFile(outputPath + '/actor.json', 'utf-8');
|
||||||
const actor = JSON.parse(actorJson);
|
const actor = JSON.parse(actorJson);
|
||||||
const isPleroma = actor['@context'].some((v: any) => typeof v === 'string' && v.match(/litepub(.*)/));
|
const isPleroma = actor['@context'].some((v: any) => typeof v === 'string' && v.match(/litepub(.*)/));
|
||||||
if (isPleroma) {
|
if (isPleroma) {
|
||||||
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
const outboxJson = await fsp.readFile(outputPath + '/outbox.json', 'utf-8');
|
||||||
const outbox = JSON.parse(outboxJson);
|
const outbox = JSON.parse(outboxJson);
|
||||||
const processedToots = await this.recreateChain(['object', 'id'], ['object', 'inReplyTo'], outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'), true);
|
const processedToots = await this.recreateChain(['object', 'id'], ['object', 'inReplyTo'], outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'), true);
|
||||||
this.queueService.createImportPleroToDbJob(job.data.user, processedToots, null);
|
this.queueService.createImportPleroToDbJob(job.data.user, processedToots, null);
|
||||||
} else {
|
} else {
|
||||||
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
const outboxJson = await fsp.readFile(outputPath + '/outbox.json', 'utf-8');
|
||||||
const outbox = JSON.parse(outboxJson);
|
const outbox = JSON.parse(outboxJson);
|
||||||
let mastoFolder = await this.driveFoldersRepository.findOneBy({ name: 'Mastodon', userId: job.data.user.id, parentId: folder?.id });
|
let mastoFolder = await this.driveFoldersRepository.findOneBy({ name: 'Mastodon', userId: job.data.user.id, parentId: folder?.id });
|
||||||
if (mastoFolder == null && folder) {
|
if (mastoFolder == null && folder) {
|
||||||
|
@ -302,7 +297,7 @@ export class ImportNotesProcessorService {
|
||||||
this.logger.info(`Temp dir is ${path}`);
|
this.logger.info(`Temp dir is ${path}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(path, '', 'utf-8');
|
await fsp.writeFile(path, '', 'utf-8');
|
||||||
await this.downloadService.downloadUrl(file.url, path);
|
await this.downloadService.downloadUrl(file.url, path);
|
||||||
} catch (e) { // TODO: 何度か再試行
|
} catch (e) { // TODO: 何度か再試行
|
||||||
if (e instanceof Error || typeof e === 'string') {
|
if (e instanceof Error || typeof e === 'string') {
|
||||||
|
@ -311,7 +306,7 @@ export class ImportNotesProcessorService {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
const notesJson = fs.readFileSync(path, 'utf-8');
|
const notesJson = await fsp.readFile(path, 'utf-8');
|
||||||
const notes = JSON.parse(notesJson);
|
const notes = JSON.parse(notesJson);
|
||||||
const processedNotes = await this.recreateChain(['id'], ['replyId'], notes, false);
|
const processedNotes = await this.recreateChain(['id'], ['replyId'], notes, false);
|
||||||
this.queueService.createImportKeyNotesToDbJob(job.data.user, processedNotes, null);
|
this.queueService.createImportKeyNotesToDbJob(job.data.user, processedNotes, null);
|
||||||
|
@ -590,7 +585,8 @@ export class ImportNotesProcessorService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const date = new Date(tweet.created_at);
|
const date = new Date(tweet.created_at);
|
||||||
const textReplaceURLs = tweet.entities.urls && tweet.entities.urls.length > 0 ? await replaceTwitterUrls(tweet.full_text, tweet.entities.urls) : tweet.full_text;
|
const decodedText = tweet.full_text.replaceAll('>', '>').replaceAll('<', '<').replaceAll('&', '&');
|
||||||
|
const textReplaceURLs = tweet.entities.urls && tweet.entities.urls.length > 0 ? await replaceTwitterUrls(decodedText, tweet.entities.urls) : decodedText;
|
||||||
const text = tweet.entities.user_mentions && tweet.entities.user_mentions.length > 0 ? await replaceTwitterMentions(textReplaceURLs, tweet.entities.user_mentions) : textReplaceURLs;
|
const text = tweet.entities.user_mentions && tweet.entities.user_mentions.length > 0 ? await replaceTwitterMentions(textReplaceURLs, tweet.entities.user_mentions) : textReplaceURLs;
|
||||||
const files: MiDriveFile[] = [];
|
const files: MiDriveFile[] = [];
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,14 @@ export const meta = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
deeplFreeMode: {
|
||||||
|
type: 'boolean',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
|
deeplFreeInstance: {
|
||||||
|
type: 'string',
|
||||||
|
optional: false, nullable: true,
|
||||||
|
},
|
||||||
defaultDarkTheme: {
|
defaultDarkTheme: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
optional: false, nullable: true,
|
optional: false, nullable: true,
|
||||||
|
@ -576,6 +584,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
||||||
deeplAuthKey: instance.deeplAuthKey,
|
deeplAuthKey: instance.deeplAuthKey,
|
||||||
deeplIsPro: instance.deeplIsPro,
|
deeplIsPro: instance.deeplIsPro,
|
||||||
|
deeplFreeMode: instance.deeplFreeMode,
|
||||||
|
deeplFreeInstance: instance.deeplFreeInstance,
|
||||||
enableIpLogging: instance.enableIpLogging,
|
enableIpLogging: instance.enableIpLogging,
|
||||||
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
||||||
enableVerifymailApi: instance.enableVerifymailApi,
|
enableVerifymailApi: instance.enableVerifymailApi,
|
||||||
|
|
|
@ -91,6 +91,8 @@ export const paramDef = {
|
||||||
summalyProxy: { type: 'string', nullable: true },
|
summalyProxy: { type: 'string', nullable: true },
|
||||||
deeplAuthKey: { type: 'string', nullable: true },
|
deeplAuthKey: { type: 'string', nullable: true },
|
||||||
deeplIsPro: { type: 'boolean' },
|
deeplIsPro: { type: 'boolean' },
|
||||||
|
deeplFreeMode: { type: 'boolean' },
|
||||||
|
deeplFreeInstance: { type: 'string', nullable: true },
|
||||||
enableEmail: { type: 'boolean' },
|
enableEmail: { type: 'boolean' },
|
||||||
email: { type: 'string', nullable: true },
|
email: { type: 'string', nullable: true },
|
||||||
smtpSecure: { type: 'boolean' },
|
smtpSecure: { type: 'boolean' },
|
||||||
|
@ -479,6 +481,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
set.deeplIsPro = ps.deeplIsPro;
|
set.deeplIsPro = ps.deeplIsPro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.deeplFreeMode !== undefined) {
|
||||||
|
set.deeplFreeMode = ps.deeplFreeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.deeplFreeInstance !== undefined) {
|
||||||
|
if (ps.deeplFreeInstance === '') {
|
||||||
|
set.deeplFreeInstance = null;
|
||||||
|
} else {
|
||||||
|
set.deeplFreeInstance = ps.deeplFreeInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ps.enableIpLogging !== undefined) {
|
if (ps.enableIpLogging !== undefined) {
|
||||||
set.enableIpLogging = ps.enableIpLogging;
|
set.enableIpLogging = ps.enableIpLogging;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import RE2 from 're2';
|
import RE2 from 're2';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import { JSDOM } from 'jsdom';
|
import { JSDOM } from 'jsdom';
|
||||||
|
|
|
@ -411,7 +411,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
enableEmail: instance.enableEmail,
|
enableEmail: instance.enableEmail,
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
enableServiceWorker: instance.enableServiceWorker,
|
||||||
|
|
||||||
translatorAvailable: instance.deeplAuthKey != null,
|
translatorAvailable: instance.deeplAuthKey != null || instance.deeplFreeMode && instance.deeplFreeInstance,
|
||||||
|
|
||||||
serverRules: instance.serverRules,
|
serverRules: instance.serverRules,
|
||||||
|
|
||||||
|
|
|
@ -81,19 +81,23 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
|
||||||
const instance = await this.metaService.fetch();
|
const instance = await this.metaService.fetch();
|
||||||
|
|
||||||
if (instance.deeplAuthKey == null) {
|
if (instance.deeplAuthKey == null && !instance.deeplFreeMode) {
|
||||||
return 204; // TODO: 良い感じのエラー返す
|
return 204; // TODO: 良い感じのエラー返す
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (instance.deeplFreeMode && !instance.deeplFreeInstance) {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
let targetLang = ps.targetLang;
|
let targetLang = ps.targetLang;
|
||||||
if (targetLang.includes('-')) targetLang = targetLang.split('-')[0];
|
if (targetLang.includes('-')) targetLang = targetLang.split('-')[0];
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('auth_key', instance.deeplAuthKey);
|
if (instance.deeplAuthKey) params.append('auth_key', instance.deeplAuthKey);
|
||||||
params.append('text', note.text);
|
params.append('text', note.text);
|
||||||
params.append('target_lang', targetLang);
|
params.append('target_lang', targetLang);
|
||||||
|
|
||||||
const endpoint = instance.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
const endpoint = instance.deeplFreeMode && instance.deeplFreeInstance ? instance.deeplFreeInstance : instance.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
||||||
|
|
||||||
const res = await this.httpRequestService.send(endpoint, {
|
const res = await this.httpRequestService.send(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -103,7 +107,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
},
|
},
|
||||||
body: params.toString(),
|
body: params.toString(),
|
||||||
});
|
});
|
||||||
|
if (instance.deeplAuthKey) {
|
||||||
const json = (await res.json()) as {
|
const json = (await res.json()) as {
|
||||||
translations: {
|
translations: {
|
||||||
detected_source_language: string;
|
detected_source_language: string;
|
||||||
|
@ -115,6 +119,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
sourceLang: json.translations[0].detected_source_language,
|
sourceLang: json.translations[0].detected_source_language,
|
||||||
text: json.translations[0].text,
|
text: json.translations[0].text,
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
const json = (await res.json()) as {
|
||||||
|
code: number,
|
||||||
|
message: string,
|
||||||
|
data: string,
|
||||||
|
source_lang: string,
|
||||||
|
target_lang: string,
|
||||||
|
alternatives: string[],
|
||||||
|
};
|
||||||
|
|
||||||
|
const languageNames = new Intl.DisplayNames(['en'], {
|
||||||
|
type: 'language',
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceLang: languageNames.of(json.source_lang),
|
||||||
|
text: json.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { Entity } from 'megalodon';
|
import { Entity } from 'megalodon';
|
||||||
import mfm from '@sharkey/sfm-js';
|
import mfm from '@transfem-org/sfm-js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { MfmService } from '@/core/MfmService.js';
|
import { MfmService } from '@/core/MfmService.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
|
@ -9,9 +9,9 @@ import type { MiUser } from '@/models/User.js';
|
||||||
import type { NoteEditRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
import type { NoteEditRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||||
import { GetterService } from '../GetterService.js';
|
|
||||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
import { GetterService } from '../GetterService.js';
|
||||||
|
|
||||||
export enum IdConvertType {
|
export enum IdConvertType {
|
||||||
MastodonId,
|
MastodonId,
|
||||||
|
@ -94,10 +94,10 @@ export class MastoConverters {
|
||||||
text_url: f.url,
|
text_url: f.url,
|
||||||
meta: {
|
meta: {
|
||||||
width: f.properties.width,
|
width: f.properties.width,
|
||||||
height: f.properties.height
|
height: f.properties.height,
|
||||||
},
|
},
|
||||||
description: f.comment ? f.comment : null,
|
description: f.comment ? f.comment : null,
|
||||||
blurhash: f.blurhash ? f.blurhash : null
|
blurhash: f.blurhash ? f.blurhash : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ export class MastoConverters {
|
||||||
sensitive: files.then(files => files.length > 0 ? files.some((f) => f.isSensitive) : false),
|
sensitive: files.then(files => files.length > 0 ? files.some((f) => f.isSensitive) : false),
|
||||||
spoiler_text: edit.cw ?? '',
|
spoiler_text: edit.cw ?? '',
|
||||||
poll: null,
|
poll: null,
|
||||||
media_attachments: files.then(files => files.length > 0 ? files.map((f) => this.encodeFile(f)) : [])
|
media_attachments: files.then(files => files.length > 0 ? files.map((f) => this.encodeFile(f)) : []),
|
||||||
};
|
};
|
||||||
lastDate = edit.updatedAt;
|
lastDate = edit.updatedAt;
|
||||||
history.push(awaitAll(item));
|
history.push(awaitAll(item));
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
|
|
||||||
import { CoreModule } from '@/core/CoreModule.js';
|
import { CoreModule } from '@/core/CoreModule.js';
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
|
|
||||||
import { parse } from '@sharkey/sfm-js';
|
import { parse } from '@transfem-org/sfm-js';
|
||||||
import { extractMentions } from '@/misc/extract-mentions.js';
|
import { extractMentions } from '@/misc/extract-mentions.js';
|
||||||
|
|
||||||
describe('Extract mentions', () => {
|
describe('Extract mentions', () => {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"@rollup/plugin-json": "6.1.0",
|
"@rollup/plugin-json": "6.1.0",
|
||||||
"@rollup/plugin-replace": "5.0.5",
|
"@rollup/plugin-replace": "5.0.5",
|
||||||
"@rollup/pluginutils": "5.1.0",
|
"@rollup/pluginutils": "5.1.0",
|
||||||
"@sharkey/sfm-js": "0.24.4",
|
"@transfem-org/sfm-js": "0.24.4",
|
||||||
"@syuilo/aiscript": "0.17.0",
|
"@syuilo/aiscript": "0.17.0",
|
||||||
"@phosphor-icons/web": "^2.0.3",
|
"@phosphor-icons/web": "^2.0.3",
|
||||||
"@twemoji/parser": "15.0.0",
|
"@twemoji/parser": "15.0.0",
|
||||||
|
|
|
@ -58,6 +58,21 @@ watch(() => props.lang, (to) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.codeBlockRoot :deep(.shiki) > code {
|
||||||
|
counter-reset: step;
|
||||||
|
counter-increment: step 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeBlockRoot :deep(.shiki) > code > .line::before {
|
||||||
|
content: counter(step);
|
||||||
|
counter-increment: step;
|
||||||
|
width: 1rem;
|
||||||
|
margin-right: 1.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: right;
|
||||||
|
color: rgba(115,138,148,.4)
|
||||||
|
}
|
||||||
|
|
||||||
.codeBlockRoot :deep(.shiki) {
|
.codeBlockRoot :deep(.shiki) {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin: .5em 0;
|
margin: .5em 0;
|
||||||
|
|
|
@ -204,6 +204,8 @@ watch(v, newValue => {
|
||||||
min-width: calc(100% - 24px);
|
min-width: calc(100% - 24px);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
// the +2.5 rem is because of the line numbers
|
||||||
|
padding-left: calc(12px + 2.5rem);
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
|
||||||
|
|
|
@ -178,7 +178,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkNoteSub from '@/components/MkNoteSub.vue';
|
import MkNoteSub from '@/components/MkNoteSub.vue';
|
||||||
import MkNoteHeader from '@/components/MkNoteHeader.vue';
|
import MkNoteHeader from '@/components/MkNoteHeader.vue';
|
||||||
|
@ -477,7 +477,7 @@ function renote(visibility: Visibility | 'local') {
|
||||||
renoted.value = true;
|
renoted.value = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (!appearNote.value.channel || appearNote.value.channel?.allowRenoteToExternal) {
|
} else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) {
|
||||||
const el = renoteButton.value as HTMLElement | null | undefined;
|
const el = renoteButton.value as HTMLElement | null | undefined;
|
||||||
if (el) {
|
if (el) {
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
|
|
|
@ -170,7 +170,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-if="!repliesLoaded" style="padding: 16px">
|
<div v-if="!repliesLoaded" style="padding: 16px">
|
||||||
<MkButton style="margin: 0 auto;" primary rounded @click="loadReplies">{{ i18n.ts.loadReplies }}</MkButton>
|
<MkButton style="margin: 0 auto;" primary rounded @click="loadReplies">{{ i18n.ts.loadReplies }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
<MkNoteSub v-for="note in replies" :key="note.id" :note="note" :class="$style.reply" :detail="true" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply" />
|
<MkNoteSub v-for="note in replies" :key="note.id" :note="note" :class="$style.reply" :detail="true" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab === 'renotes'" :class="$style.tab_renotes">
|
<div v-else-if="tab === 'renotes'" :class="$style.tab_renotes">
|
||||||
<MkPagination :pagination="renotesPagination" :disableAutoLoad="true">
|
<MkPagination :pagination="renotesPagination" :disableAutoLoad="true">
|
||||||
|
@ -221,7 +221,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, provide, ref, shallowRef, watch } from 'vue';
|
import { computed, inject, onMounted, provide, ref, shallowRef, watch } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkNoteSub from '@/components/MkNoteSub.vue';
|
import MkNoteSub from '@/components/MkNoteSub.vue';
|
||||||
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||||
|
@ -501,7 +501,7 @@ function renote(visibility: Visibility | 'local') {
|
||||||
os.toast(i18n.ts.renoted);
|
os.toast(i18n.ts.renoted);
|
||||||
renoted.value = true;
|
renoted.value = true;
|
||||||
});
|
});
|
||||||
} else if (!appearNote.value.channel || appearNote.value.channel?.allowRenoteToExternal) {
|
} else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) {
|
||||||
const el = renoteButton.value as HTMLElement | null | undefined;
|
const el = renoteButton.value as HTMLElement | null | undefined;
|
||||||
if (el) {
|
if (el) {
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
|
|
|
@ -102,7 +102,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, shallowRef, ref, computed } from 'vue';
|
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, shallowRef, ref, computed } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import insertTextAtCursor from 'insert-text-at-cursor';
|
import insertTextAtCursor from 'insert-text-at-cursor';
|
||||||
import { toASCII } from 'punycode/';
|
import { toASCII } from 'punycode/';
|
||||||
|
|
|
@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import MkMediaList from '@/components/MkMediaList.vue';
|
import MkMediaList from '@/components/MkMediaList.vue';
|
||||||
import MkPoll from '@/components/MkPoll.vue';
|
import MkPoll from '@/components/MkPoll.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
|
|
@ -180,7 +180,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
import { computed, inject, onMounted, ref, shallowRef, Ref, watch, provide } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import SkNoteSub from '@/components/SkNoteSub.vue';
|
import SkNoteSub from '@/components/SkNoteSub.vue';
|
||||||
import SkNoteHeader from '@/components/SkNoteHeader.vue';
|
import SkNoteHeader from '@/components/SkNoteHeader.vue';
|
||||||
|
@ -478,7 +478,7 @@ function renote(visibility: Visibility | 'local') {
|
||||||
renoted.value = true;
|
renoted.value = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (!appearNote.value.channel || appearNote.value.channel?.allowRenoteToExternal) {
|
} else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) {
|
||||||
const el = renoteButton.value as HTMLElement | null | undefined;
|
const el = renoteButton.value as HTMLElement | null | undefined;
|
||||||
if (el) {
|
if (el) {
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
|
|
|
@ -229,7 +229,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, onUnmounted, onUpdated, provide, ref, shallowRef, watch } from 'vue';
|
import { computed, inject, onMounted, onUnmounted, onUpdated, provide, ref, shallowRef, watch } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import SkNoteSub from '@/components/SkNoteSub.vue';
|
import SkNoteSub from '@/components/SkNoteSub.vue';
|
||||||
import SkNoteSimple from '@/components/SkNoteSimple.vue';
|
import SkNoteSimple from '@/components/SkNoteSimple.vue';
|
||||||
|
@ -510,7 +510,7 @@ function renote(visibility: Visibility | 'local') {
|
||||||
os.toast(i18n.ts.renoted);
|
os.toast(i18n.ts.renoted);
|
||||||
renoted.value = true;
|
renoted.value = true;
|
||||||
});
|
});
|
||||||
} else if (!appearNote.value.channel || appearNote.value.channel?.allowRenoteToExternal) {
|
} else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) {
|
||||||
const el = renoteButton.value as HTMLElement | null | undefined;
|
const el = renoteButton.value as HTMLElement | null | undefined;
|
||||||
if (el) {
|
if (el) {
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { inject, onMounted, ref, shallowRef, computed } from 'vue';
|
import { inject, onMounted, ref, shallowRef, computed } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
import MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||||
import MkMediaList from '@/components/MkMediaList.vue';
|
import MkMediaList from '@/components/MkMediaList.vue';
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { VNode, h, defineAsyncComponent, SetupContext } from 'vue';
|
import { VNode, h, defineAsyncComponent, SetupContext } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkUrl from '@/components/global/MkUrl.vue';
|
import MkUrl from '@/components/global/MkUrl.vue';
|
||||||
import MkTime from '@/components/global/MkTime.vue';
|
import MkTime from '@/components/global/MkTime.vue';
|
||||||
|
@ -52,7 +52,7 @@ type MfmEvents = {
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
||||||
const isNote = props.isNote ?? true;
|
const isNote = props.isNote ?? true;
|
||||||
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat ? props.author?.speakAsCat : false : false : false;
|
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat ? props.author.speakAsCat : false : false : false;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (props.text == null || props.text === '') return;
|
if (props.text == null || props.text === '') return;
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { TextBlock } from './block.type.js';
|
import { TextBlock } from './block.type.js';
|
||||||
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
|
import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm.js';
|
||||||
|
|
|
@ -19,6 +19,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkSwitch v-model="deeplIsPro">
|
<MkSwitch v-model="deeplIsPro">
|
||||||
<template #label>Pro account</template>
|
<template #label>Pro account</template>
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="deeplFreeMode">
|
||||||
|
<template #label>{{ i18n.ts.deeplFreeMode }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkInput v-if="deeplFreeMode" v-model="deeplFreeInstance" :placeholder="'example.com/translate'">
|
||||||
|
<template #prefix><i class="ph-globe-simple ph-bold ph-lg"></i></template>
|
||||||
|
<template #label>DeepLX-JS URL</template>
|
||||||
|
<template #caption>{{ i18n.ts.deeplFreeModeDescription }}</template>
|
||||||
|
</MkInput>
|
||||||
</div>
|
</div>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
|
@ -49,17 +57,23 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||||
|
|
||||||
const deeplAuthKey = ref<string>('');
|
const deeplAuthKey = ref<string>('');
|
||||||
const deeplIsPro = ref<boolean>(false);
|
const deeplIsPro = ref<boolean>(false);
|
||||||
|
const deeplFreeMode = ref<boolean>(false);
|
||||||
|
const deeplFreeInstance = ref<string>('');
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const meta = await misskeyApi('admin/meta');
|
const meta = await misskeyApi('admin/meta');
|
||||||
deeplAuthKey.value = meta.deeplAuthKey;
|
deeplAuthKey.value = meta.deeplAuthKey;
|
||||||
deeplIsPro.value = meta.deeplIsPro;
|
deeplIsPro.value = meta.deeplIsPro;
|
||||||
|
deeplFreeMode.value = meta.deeplFreeMode;
|
||||||
|
deeplFreeInstance.value = meta.deeplFreeInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
os.apiWithDialog('admin/update-meta', {
|
os.apiWithDialog('admin/update-meta', {
|
||||||
deeplAuthKey: deeplAuthKey.value,
|
deeplAuthKey: deeplAuthKey.value,
|
||||||
deeplIsPro: deeplIsPro.value,
|
deeplIsPro: deeplIsPro.value,
|
||||||
|
deeplFreeMode: deeplFreeMode.value,
|
||||||
|
deeplFreeInstance: deeplFreeInstance.value,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
fetchInstance();
|
fetchInstance();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
|
|
||||||
export function checkAnimationFromMfm(nodes: mfm.MfmNode[]): boolean {
|
export function checkAnimationFromMfm(nodes: mfm.MfmNode[]): boolean {
|
||||||
const animatedNodes = mfm.extract(nodes, (node) => {
|
const animatedNodes = mfm.extract(nodes, (node) => {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
// test is located in test/extract-mentions
|
// test is located in test/extract-mentions
|
||||||
|
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
|
|
||||||
export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] {
|
export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] {
|
||||||
// TODO: 重複を削除
|
// TODO: 重複を削除
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as mfm from '@sharkey/sfm-js';
|
import * as mfm from '@transfem-org/sfm-js';
|
||||||
import { unique } from '@/scripts/array.js';
|
import { unique } from '@/scripts/array.js';
|
||||||
|
|
||||||
// unique without hash
|
// unique without hash
|
||||||
|
|
|
@ -64,8 +64,12 @@ export async function parsePluginMeta(code: string): Promise<AiScriptPluginMeta>
|
||||||
try {
|
try {
|
||||||
ast = parser.parse(code);
|
ast = parser.parse(code);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (err instanceof Error) {
|
||||||
|
throw new Error(`Aiscript syntax error\n${(err as Error).message}`);
|
||||||
|
} else {
|
||||||
throw new Error('Aiscript syntax error');
|
throw new Error('Aiscript syntax error');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const meta = Interpreter.collectMetadata(ast);
|
const meta = Interpreter.collectMetadata(ast);
|
||||||
if (meta == null) {
|
if (meta == null) {
|
||||||
|
|
|
@ -85,6 +85,9 @@ type AdminAnnouncementsListResponse = operations['admin/announcements/list']['re
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminAnnouncementsUpdateRequest = operations['admin/announcements/update']['requestBody']['content']['application/json'];
|
type AdminAnnouncementsUpdateRequest = operations['admin/announcements/update']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminApproveUserRequest = operations['admin/approve-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminAvatarDecorationsCreateRequest = operations['admin/avatar-decorations/create']['requestBody']['content']['application/json'];
|
type AdminAvatarDecorationsCreateRequest = operations['admin/avatar-decorations/create']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -208,6 +211,9 @@ type AdminInviteListResponse = operations['admin/invite/list']['responses']['200
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminMetaResponse = operations['admin/meta']['responses']['200']['content']['application/json'];
|
type AdminMetaResponse = operations['admin/meta']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminNsfwUserRequest = operations['admin/nsfw-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminPromoCreateRequest = operations['admin/promo/create']['requestBody']['content']['application/json'];
|
type AdminPromoCreateRequest = operations['admin/promo/create']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -304,15 +310,24 @@ type AdminShowUsersRequest = operations['admin/show-users']['requestBody']['cont
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminShowUsersResponse = operations['admin/show-users']['responses']['200']['content']['application/json'];
|
type AdminShowUsersResponse = operations['admin/show-users']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminSilenceUserRequest = operations['admin/silence-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminSuspendUserRequest = operations['admin/suspend-user']['requestBody']['content']['application/json'];
|
type AdminSuspendUserRequest = operations['admin/suspend-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminUnnsfwUserRequest = operations['admin/unnsfw-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminUnsetUserAvatarRequest = operations['admin/unset-user-avatar']['requestBody']['content']['application/json'];
|
type AdminUnsetUserAvatarRequest = operations['admin/unset-user-avatar']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminUnsetUserBannerRequest = operations['admin/unset-user-banner']['requestBody']['content']['application/json'];
|
type AdminUnsetUserBannerRequest = operations['admin/unset-user-banner']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminUnsilenceUserRequest = operations['admin/unsilence-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminUnsuspendUserRequest = operations['admin/unsuspend-user']['requestBody']['content']['application/json'];
|
type AdminUnsuspendUserRequest = operations['admin/unsuspend-user']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -594,6 +609,13 @@ export type Channels = {
|
||||||
};
|
};
|
||||||
receives: null;
|
receives: null;
|
||||||
};
|
};
|
||||||
|
bubbleTimeline: {
|
||||||
|
params: null;
|
||||||
|
events: {
|
||||||
|
note: (payload: Note) => void;
|
||||||
|
};
|
||||||
|
receives: null;
|
||||||
|
};
|
||||||
userList: {
|
userList: {
|
||||||
params: {
|
params: {
|
||||||
listId: string;
|
listId: string;
|
||||||
|
@ -1165,7 +1187,12 @@ declare namespace entities {
|
||||||
AdminShowUserResponse,
|
AdminShowUserResponse,
|
||||||
AdminShowUsersRequest,
|
AdminShowUsersRequest,
|
||||||
AdminShowUsersResponse,
|
AdminShowUsersResponse,
|
||||||
|
AdminNsfwUserRequest,
|
||||||
|
AdminUnnsfwUserRequest,
|
||||||
|
AdminSilenceUserRequest,
|
||||||
|
AdminUnsilenceUserRequest,
|
||||||
AdminSuspendUserRequest,
|
AdminSuspendUserRequest,
|
||||||
|
AdminApproveUserRequest,
|
||||||
AdminUnsuspendUserRequest,
|
AdminUnsuspendUserRequest,
|
||||||
AdminUpdateMetaRequest,
|
AdminUpdateMetaRequest,
|
||||||
AdminDeleteAccountRequest,
|
AdminDeleteAccountRequest,
|
||||||
|
@ -1393,6 +1420,7 @@ declare namespace entities {
|
||||||
IGalleryPostsResponse,
|
IGalleryPostsResponse,
|
||||||
IImportBlockingRequest,
|
IImportBlockingRequest,
|
||||||
IImportFollowingRequest,
|
IImportFollowingRequest,
|
||||||
|
IImportNotesRequest,
|
||||||
IImportMutingRequest,
|
IImportMutingRequest,
|
||||||
IImportUserListsRequest,
|
IImportUserListsRequest,
|
||||||
IImportAntennasRequest,
|
IImportAntennasRequest,
|
||||||
|
@ -1410,6 +1438,7 @@ declare namespace entities {
|
||||||
IRegenerateTokenRequest,
|
IRegenerateTokenRequest,
|
||||||
IRegistryGetAllRequest,
|
IRegistryGetAllRequest,
|
||||||
IRegistryGetAllResponse,
|
IRegistryGetAllResponse,
|
||||||
|
IRegistryGetUnsecureRequest,
|
||||||
IRegistryGetDetailRequest,
|
IRegistryGetDetailRequest,
|
||||||
IRegistryGetDetailResponse,
|
IRegistryGetDetailResponse,
|
||||||
IRegistryGetRequest,
|
IRegistryGetRequest,
|
||||||
|
@ -1477,6 +1506,8 @@ declare namespace entities {
|
||||||
NotesFeaturedResponse,
|
NotesFeaturedResponse,
|
||||||
NotesGlobalTimelineRequest,
|
NotesGlobalTimelineRequest,
|
||||||
NotesGlobalTimelineResponse,
|
NotesGlobalTimelineResponse,
|
||||||
|
NotesBubbleTimelineRequest,
|
||||||
|
NotesBubbleTimelineResponse,
|
||||||
NotesHybridTimelineRequest,
|
NotesHybridTimelineRequest,
|
||||||
NotesHybridTimelineResponse,
|
NotesHybridTimelineResponse,
|
||||||
NotesLocalTimelineRequest,
|
NotesLocalTimelineRequest,
|
||||||
|
@ -1490,6 +1521,7 @@ declare namespace entities {
|
||||||
NotesReactionsResponse,
|
NotesReactionsResponse,
|
||||||
NotesReactionsCreateRequest,
|
NotesReactionsCreateRequest,
|
||||||
NotesReactionsDeleteRequest,
|
NotesReactionsDeleteRequest,
|
||||||
|
NotesLikeRequest,
|
||||||
NotesRenotesRequest,
|
NotesRenotesRequest,
|
||||||
NotesRenotesResponse,
|
NotesRenotesResponse,
|
||||||
NotesRepliesRequest,
|
NotesRepliesRequest,
|
||||||
|
@ -1511,6 +1543,10 @@ declare namespace entities {
|
||||||
NotesUnrenoteRequest,
|
NotesUnrenoteRequest,
|
||||||
NotesUserListTimelineRequest,
|
NotesUserListTimelineRequest,
|
||||||
NotesUserListTimelineResponse,
|
NotesUserListTimelineResponse,
|
||||||
|
NotesEditRequest,
|
||||||
|
NotesEditResponse,
|
||||||
|
NotesVersionsRequest,
|
||||||
|
NotesVersionsResponse,
|
||||||
NotificationsCreateRequest,
|
NotificationsCreateRequest,
|
||||||
PagePushRequest,
|
PagePushRequest,
|
||||||
PagesCreateRequest,
|
PagesCreateRequest,
|
||||||
|
@ -1619,6 +1655,7 @@ declare namespace entities {
|
||||||
FetchExternalResourcesRequest,
|
FetchExternalResourcesRequest,
|
||||||
FetchExternalResourcesResponse,
|
FetchExternalResourcesResponse,
|
||||||
RetentionResponse,
|
RetentionResponse,
|
||||||
|
SponsorsRequest,
|
||||||
BubbleGameRegisterRequest,
|
BubbleGameRegisterRequest,
|
||||||
BubbleGameRegisterResponse,
|
BubbleGameRegisterResponse,
|
||||||
BubbleGameRankingRequest,
|
BubbleGameRankingRequest,
|
||||||
|
@ -2016,6 +2053,9 @@ type IImportFollowingRequest = operations['i/import-following']['requestBody']['
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type IImportMutingRequest = operations['i/import-muting']['requestBody']['content']['application/json'];
|
type IImportMutingRequest = operations['i/import-muting']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type IImportNotesRequest = operations['i/import-notes']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type IImportUserListsRequest = operations['i/import-user-lists']['requestBody']['content']['application/json'];
|
type IImportUserListsRequest = operations['i/import-user-lists']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -2097,6 +2137,9 @@ type IRegistryGetRequest = operations['i/registry/get']['requestBody']['content'
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type IRegistryGetResponse = operations['i/registry/get']['responses']['200']['content']['application/json'];
|
type IRegistryGetResponse = operations['i/registry/get']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type IRegistryGetUnsecureRequest = operations['i/registry/get-unsecure']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type IRegistryKeysRequest = operations['i/registry/keys']['requestBody']['content']['application/json'];
|
type IRegistryKeysRequest = operations['i/registry/keys']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -2196,6 +2239,9 @@ type ModerationLog = {
|
||||||
} & ({
|
} & ({
|
||||||
type: 'updateServerSettings';
|
type: 'updateServerSettings';
|
||||||
info: ModerationLogPayloads['updateServerSettings'];
|
info: ModerationLogPayloads['updateServerSettings'];
|
||||||
|
} | {
|
||||||
|
type: 'approve';
|
||||||
|
info: ModerationLogPayloads['approve'];
|
||||||
} | {
|
} | {
|
||||||
type: 'suspend';
|
type: 'suspend';
|
||||||
info: ModerationLogPayloads['suspend'];
|
info: ModerationLogPayloads['suspend'];
|
||||||
|
@ -2307,7 +2353,7 @@ type ModerationLog = {
|
||||||
});
|
});
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
|
export const moderationLogTypes: readonly ["updateServerSettings", "suspend", "approve", "unsuspend", "updateUserNote", "addCustomEmoji", "updateCustomEmoji", "deleteCustomEmoji", "assignRole", "unassignRole", "createRole", "updateRole", "deleteRole", "clearQueue", "promoteQueue", "deleteDriveFile", "deleteNote", "createGlobalAnnouncement", "createUserAnnouncement", "updateGlobalAnnouncement", "updateUserAnnouncement", "deleteGlobalAnnouncement", "deleteUserAnnouncement", "resetPassword", "suspendRemoteInstance", "unsuspendRemoteInstance", "markSensitiveDriveFile", "unmarkSensitiveDriveFile", "resolveAbuseReport", "createInvitation", "createAd", "updateAd", "deleteAd", "createAvatarDecoration", "updateAvatarDecoration", "deleteAvatarDecoration", "unsetUserAvatar", "unsetUserBanner"];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type MuteCreateRequest = operations['mute/create']['requestBody']['content']['application/json'];
|
type MuteCreateRequest = operations['mute/create']['requestBody']['content']['application/json'];
|
||||||
|
@ -2342,6 +2388,12 @@ type NoteFavorite = components['schemas']['NoteFavorite'];
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NoteReaction = components['schemas']['NoteReaction'];
|
type NoteReaction = components['schemas']['NoteReaction'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesBubbleTimelineRequest = operations['notes/bubble-timeline']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesBubbleTimelineResponse = operations['notes/bubble-timeline']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesChildrenRequest = operations['notes/children']['requestBody']['content']['application/json'];
|
type NotesChildrenRequest = operations['notes/children']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -2369,6 +2421,12 @@ type NotesCreateResponse = operations['notes/create']['responses']['200']['conte
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesDeleteRequest = operations['notes/delete']['requestBody']['content']['application/json'];
|
type NotesDeleteRequest = operations['notes/delete']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesEditRequest = operations['notes/edit']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesEditResponse = operations['notes/edit']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesFavoritesCreateRequest = operations['notes/favorites/create']['requestBody']['content']['application/json'];
|
type NotesFavoritesCreateRequest = operations['notes/favorites/create']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -2393,6 +2451,9 @@ type NotesHybridTimelineRequest = operations['notes/hybrid-timeline']['requestBo
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesHybridTimelineResponse = operations['notes/hybrid-timeline']['responses']['200']['content']['application/json'];
|
type NotesHybridTimelineResponse = operations['notes/hybrid-timeline']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesLikeRequest = operations['notes/like']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesLocalTimelineRequest = operations['notes/local-timeline']['requestBody']['content']['application/json'];
|
type NotesLocalTimelineRequest = operations['notes/local-timeline']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -2495,6 +2556,12 @@ type NotesUserListTimelineRequest = operations['notes/user-list-timeline']['requ
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type NotesUserListTimelineResponse = operations['notes/user-list-timeline']['responses']['200']['content']['application/json'];
|
type NotesUserListTimelineResponse = operations['notes/user-list-timeline']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesVersionsRequest = operations['notes/versions']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type NotesVersionsResponse = operations['notes/versions']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const noteVisibilities: readonly ["public", "home", "followers", "specified"];
|
export const noteVisibilities: readonly ["public", "home", "followers", "specified"];
|
||||||
|
|
||||||
|
@ -2553,7 +2620,7 @@ type PagesUpdateRequest = operations['pages/update']['requestBody']['content']['
|
||||||
function parse(acct: string): Acct;
|
function parse(acct: string): Acct;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:channels", "write:channels", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "read:admin:show-users", "write:admin:suspend-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"];
|
export const permissions: readonly ["read:account", "write:account", "read:blocks", "write:blocks", "read:drive", "write:drive", "read:favorites", "write:favorites", "read:following", "write:following", "read:messaging", "write:messaging", "read:mutes", "write:mutes", "write:notes", "read:notifications", "write:notifications", "read:reactions", "write:reactions", "write:votes", "read:pages", "write:pages", "write:page-likes", "read:page-likes", "read:user-groups", "write:user-groups", "read:channels", "write:channels", "read:gallery", "write:gallery", "read:gallery-likes", "write:gallery-likes", "read:flash", "write:flash", "read:flash-likes", "write:flash-likes", "read:admin:abuse-user-reports", "write:admin:delete-account", "write:admin:delete-all-files-of-a-user", "read:admin:index-stats", "read:admin:table-stats", "read:admin:user-ips", "read:admin:meta", "write:admin:reset-password", "write:admin:resolve-abuse-user-report", "write:admin:send-email", "read:admin:server-info", "read:admin:show-moderation-log", "read:admin:show-user", "read:admin:show-users", "write:admin:suspend-user", "write:admin:approve-user", "write:admin:nsfw-user", "write:admin:unnsfw-user", "write:admin:silence-user", "write:admin:unsilence-user", "write:admin:unset-user-avatar", "write:admin:unset-user-banner", "write:admin:unsuspend-user", "write:admin:meta", "write:admin:user-note", "write:admin:roles", "read:admin:roles", "write:admin:relays", "read:admin:relays", "write:admin:invite-codes", "read:admin:invite-codes", "write:admin:announcements", "read:admin:announcements", "write:admin:avatar-decorations", "read:admin:avatar-decorations", "write:admin:federation", "write:admin:account", "read:admin:account", "write:admin:emoji", "read:admin:emoji", "write:admin:queue", "read:admin:queue", "write:admin:promo", "write:admin:drive", "read:admin:drive", "write:admin:ad", "read:admin:ad", "write:invite-codes", "read:invite-codes", "write:clip-favorite", "read:clip-favorite", "read:federation", "write:report-abuse"];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type PingResponse = operations['ping']['responses']['200']['content']['application/json'];
|
type PingResponse = operations['ping']['responses']['200']['content']['application/json'];
|
||||||
|
@ -2746,6 +2813,9 @@ type SignupResponse = MeDetailed & {
|
||||||
token: string;
|
token: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type SponsorsRequest = operations['sponsors']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type StatsResponse = operations['stats']['responses']['200']['content']['application/json'];
|
type StatsResponse = operations['stats']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* version: 2024.2.0-beta.6
|
* version: 2024.2.0-beta2
|
||||||
* generatedAt: 2024-01-24T07:32:10.455Z
|
* generatedAt: 2024-01-26T20:30:18.423Z
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SwitchCaseResponseType } from '../api.js';
|
import type { SwitchCaseResponseType } from '../api.js';
|
||||||
|
@ -691,6 +691,50 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *write:admin:nsfw-user*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/nsfw-user', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *write:admin:unnsfw-user*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/unnsfw-user', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *write:admin:silence-user*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/silence-user', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *write:admin:unsilence-user*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/unsilence-user', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No description provided.
|
* No description provided.
|
||||||
*
|
*
|
||||||
|
@ -702,6 +746,17 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *write:admin:approve-user*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/approve-user', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No description provided.
|
* No description provided.
|
||||||
*
|
*
|
||||||
|
@ -2514,6 +2569,17 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *read:account*
|
||||||
|
*/
|
||||||
|
request<E extends 'i/registry/get-unsecure', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No description provided.
|
* No description provided.
|
||||||
*
|
*
|
||||||
|
@ -2993,6 +3059,17 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *No*
|
||||||
|
*/
|
||||||
|
request<E extends 'notes/bubble-timeline', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No description provided.
|
* No description provided.
|
||||||
*
|
*
|
||||||
|
@ -4054,7 +4131,8 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/** No description provided.
|
/**
|
||||||
|
* No description provided.
|
||||||
*
|
*
|
||||||
* **Credential required**: *Yes* / **Permission**: *write:account*
|
* **Credential required**: *Yes* / **Permission**: *write:account*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* version: 2024.2.0-beta.6
|
* version: 2024.2.0-beta2
|
||||||
* generatedAt: 2024-01-24T07:32:10.453Z
|
* generatedAt: 2024-01-26T20:30:18.421Z
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* version: 2024.2.0-beta.6
|
* version: 2024.2.0-beta2
|
||||||
* generatedAt: 2024-01-24T07:32:10.452Z
|
* generatedAt: 2024-01-26T20:30:18.419Z
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { operations } from './types.js';
|
import { operations } from './types.js';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* version: 2024.2.0-beta.6
|
* version: 2024.2.0-beta2
|
||||||
* generatedAt: 2024-01-24T07:32:10.450Z
|
* generatedAt: 2024-01-26T20:30:18.418Z
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { components } from './types.js';
|
import { components } from './types.js';
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* version: 2024.2.0-beta.6
|
* version: 2024.2.0-beta2
|
||||||
* generatedAt: 2024-01-24T07:32:10.370Z
|
* generatedAt: 2024-01-26T20:30:18.319Z
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4784,6 +4784,8 @@ export type operations = {
|
||||||
backgroundImageUrl: string | null;
|
backgroundImageUrl: string | null;
|
||||||
deeplAuthKey: string | null;
|
deeplAuthKey: string | null;
|
||||||
deeplIsPro: boolean;
|
deeplIsPro: boolean;
|
||||||
|
deeplFreeMode: boolean;
|
||||||
|
deeplFreeInstance: string | null;
|
||||||
defaultDarkTheme: string | null;
|
defaultDarkTheme: string | null;
|
||||||
defaultLightTheme: string | null;
|
defaultLightTheme: string | null;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
|
@ -8795,6 +8797,8 @@ export type operations = {
|
||||||
summalyProxy?: string | null;
|
summalyProxy?: string | null;
|
||||||
deeplAuthKey?: string | null;
|
deeplAuthKey?: string | null;
|
||||||
deeplIsPro?: boolean;
|
deeplIsPro?: boolean;
|
||||||
|
deeplFreeMode?: boolean;
|
||||||
|
deeplFreeInstance?: string | null;
|
||||||
enableEmail?: boolean;
|
enableEmail?: boolean;
|
||||||
email?: string | null;
|
email?: string | null;
|
||||||
smtpSecure?: boolean;
|
smtpSecure?: boolean;
|
||||||
|
@ -14101,6 +14105,7 @@ export type operations = {
|
||||||
subscribing?: boolean | null;
|
subscribing?: boolean | null;
|
||||||
publishing?: boolean | null;
|
publishing?: boolean | null;
|
||||||
nsfw?: boolean | null;
|
nsfw?: boolean | null;
|
||||||
|
bubble?: boolean | null;
|
||||||
/** @default 30 */
|
/** @default 30 */
|
||||||
limit?: number;
|
limit?: number;
|
||||||
/** @default 0 */
|
/** @default 0 */
|
||||||
|
@ -26440,9 +26445,40 @@ export type operations = {
|
||||||
204: {
|
204: {
|
||||||
content: never;
|
content: never;
|
||||||
};
|
};
|
||||||
|
/** @description Client error */
|
||||||
|
400: {
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
/** bubble-game/register
|
/** @description Authentication error */
|
||||||
|
401: {
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Forbidden error */
|
||||||
|
403: {
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description I'm Ai */
|
||||||
|
418: {
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Internal server error */
|
||||||
|
500: {
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* bubble-game/register
|
||||||
* @description No description provided.
|
* @description No description provided.
|
||||||
*
|
*
|
||||||
* **Credential required**: *Yes* / **Permission**: *write:account*
|
* **Credential required**: *Yes* / **Permission**: *write:account*
|
||||||
|
|
|
@ -115,9 +115,6 @@ importers:
|
||||||
'@peertube/http-signature':
|
'@peertube/http-signature':
|
||||||
specifier: 1.7.0
|
specifier: 1.7.0
|
||||||
version: 1.7.0
|
version: 1.7.0
|
||||||
'@sharkey/sfm-js':
|
|
||||||
specifier: 0.24.4
|
|
||||||
version: 0.24.4
|
|
||||||
'@simplewebauthn/server':
|
'@simplewebauthn/server':
|
||||||
specifier: 9.0.0
|
specifier: 9.0.0
|
||||||
version: 9.0.0
|
version: 9.0.0
|
||||||
|
@ -133,6 +130,9 @@ importers:
|
||||||
'@swc/core':
|
'@swc/core':
|
||||||
specifier: 1.3.105
|
specifier: 1.3.105
|
||||||
version: 1.3.105
|
version: 1.3.105
|
||||||
|
'@transfem-org/sfm-js':
|
||||||
|
specifier: 0.24.4
|
||||||
|
version: 0.24.4
|
||||||
'@twemoji/parser':
|
'@twemoji/parser':
|
||||||
specifier: 15.0.0
|
specifier: 15.0.0
|
||||||
version: 15.0.0
|
version: 15.0.0
|
||||||
|
@ -696,12 +696,12 @@ importers:
|
||||||
'@rollup/pluginutils':
|
'@rollup/pluginutils':
|
||||||
specifier: 5.1.0
|
specifier: 5.1.0
|
||||||
version: 5.1.0(rollup@4.9.6)
|
version: 5.1.0(rollup@4.9.6)
|
||||||
'@sharkey/sfm-js':
|
|
||||||
specifier: 0.24.4
|
|
||||||
version: 0.24.4
|
|
||||||
'@syuilo/aiscript':
|
'@syuilo/aiscript':
|
||||||
specifier: 0.17.0
|
specifier: 0.17.0
|
||||||
version: 0.17.0
|
version: 0.17.0
|
||||||
|
'@transfem-org/sfm-js':
|
||||||
|
specifier: 0.24.4
|
||||||
|
version: 0.24.4
|
||||||
'@twemoji/parser':
|
'@twemoji/parser':
|
||||||
specifier: 15.0.0
|
specifier: 15.0.0
|
||||||
version: 15.0.0
|
version: 15.0.0
|
||||||
|
@ -5782,12 +5782,6 @@ packages:
|
||||||
string-argv: 0.3.1
|
string-argv: 0.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sharkey/sfm-js@0.24.4:
|
|
||||||
resolution: {integrity: sha512-m9reKRceS8kmFEPFlK2nhbN6mP9kE1I895WAc9OlFISMdT5L+IdvBW1NHv8dzjSPSTFZLeCfMHbys1oz+5uLuA==, tarball: https://git.joinsharkey.org/api/packages/Sharkey/npm/%40sharkey%2Fsfm-js/-/0.24.4/sfm-js-0.24.4.tgz}
|
|
||||||
dependencies:
|
|
||||||
'@twemoji/parser': 15.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@sideway/address@4.1.4:
|
/@sideway/address@4.1.4:
|
||||||
resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==}
|
resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -7513,6 +7507,12 @@ packages:
|
||||||
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
|
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@transfem-org/sfm-js@0.24.4:
|
||||||
|
resolution: {integrity: sha1-0wEXqL5UJseGFO4GGFRrES6NCDk=, tarball: https://activitypub.software/api/v4/projects/2/packages/npm/@transfem-org/sfm-js/-/@transfem-org/sfm-js-0.24.4.tgz}
|
||||||
|
dependencies:
|
||||||
|
'@twemoji/parser': 15.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@trysound/sax@0.2.0:
|
/@trysound/sax@0.2.0:
|
||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
Loading…
Reference in a new issue