server: fix lints

This commit is contained in:
Johann150 2023-01-03 03:51:38 +01:00
parent 8bc366fde0
commit 0c8a3cfeec
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
66 changed files with 84 additions and 101 deletions

View file

@ -8,10 +8,7 @@ import { SECOND } from '@/const.js';
*/
const retryDelay = 100;
const lock: (key: string, timeout?: number) => Promise<() => void>
= redisClient
? promisify(redisLock(redisClient, retryDelay))
: async () => () => { };
const lock: (key: string, timeout?: number) => Promise<() => void> = promisify(redisLock(redisClient, retryDelay));
/**
* Get AP Object lock

View file

@ -3,7 +3,7 @@ import { db } from '@/db/postgre.js';
import { Meta } from '@/models/entities/meta.js';
import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js';
let cache: Meta;
let cache: Meta | undefined;
/**
* Performs the primitive database operation to set the server configuration

View file

@ -1,5 +1,11 @@
import { Note } from '@/models/entities/note.js';
export function isPureRenote(note: Note): note is Note & { renoteId: string, text: null, fileIds: null | never[], hasPoll: false } {
return note.renoteId != null && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !note.hasPoll;
return note.renoteId != null
&& note.text == null
&& (
note.fileIds == null
|| note.fileIds.length === 0
)
&& !note.hasPoll;
}

View file

@ -32,12 +32,4 @@ export class Announcement {
length: 1024, nullable: true,
})
public imageUrl: string | null;
constructor(data: Partial<Announcement>) {
if (data == null) return;
for (const [k, v] of Object.entries(data)) {
(this as any)[k] = v;
}
}
}

View file

@ -35,12 +35,4 @@ export class AttestationChallenge {
default: false,
})
public registrationChallenge: boolean;
constructor(data: Partial<AttestationChallenge>) {
if (data == null) return;
for (const [k, v] of Object.entries(data)) {
(this as any)[k] = v;
}
}
}

View file

@ -2,7 +2,6 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typ
import { noteNotificationTypes } from 'foundkey-js';
import { id } from '../id.js';
import { User } from './user.js';
import { Note } from './note.js';
@Entity()
@Index(['userId', 'threadId'], { unique: true })

View file

@ -56,7 +56,7 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don
name: emojiInfo.name,
});
const driveFile = await addFile({ user: null, path: emojiPath, name: record.fileName, force: true });
const emoji = await Emojis.insert({
await Emojis.insert({
id: genId(),
updatedAt: new Date(),
name: emojiInfo.name,
@ -66,13 +66,13 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don
originalUrl: driveFile.url,
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
type: driveFile.webpublicType ?? driveFile.type,
}).then(x => Emojis.findOneByOrFail(x.identifiers[0]));
});
}
await db.queryResultCache!.remove(['meta_emojis']);
cleanup();
logger.succ('Imported');
done();
});

View file

@ -2,7 +2,7 @@ import Bull from 'bull';
import { In, LessThan } from 'typeorm';
import { AttestationChallenges, AuthSessions, Mutings, Notifications, PasswordResetRequests, Signins } from '@/models/index.js';
import { publishUserEvent } from '@/services/stream.js';
import { MINUTE, DAY, MONTH } from '@/const.js';
import { MINUTE, MONTH } from '@/const.js';
import { queueLogger } from '@/queue/logger.js';
const logger = queueLogger.createSubLogger('check-expired');

View file

@ -4,7 +4,7 @@ import { extractDbHost } from '@/misc/convert-host.js';
import { StatusError } from '@/misc/fetch.js';
import { Resolver } from '@/remote/activitypub/resolver.js';
import { createNote, fetchNote } from '@/remote/activitypub/models/note.js';
import { getApId, IObject, ICreate } from '@/remote/activitypub/type.js';
import { getApId, IObject } from '@/remote/activitypub/type.js';
/**
* 稿

View file

@ -1,4 +1,3 @@
import { URL } from 'node:url';
import promiseLimit from 'promise-limit';
import config from '@/config/index.js';
@ -40,7 +39,6 @@ const summaryLength = 2048;
* @param uri Fetch target URI
*/
function validateActor(x: IObject): IActor {
if (x == null) {
throw new Error('invalid Actor: object is null');
}
@ -100,7 +98,7 @@ function validateActor(x: IObject): IActor {
*
* If the target Person is registered in FoundKey, it is returned.
*/
export async function fetchPerson(uri: string, resolver: Resolver): Promise<CacheableUser | null> {
export async function fetchPerson(uri: string): Promise<CacheableUser | null> {
if (typeof uri !== 'string') throw new Error('uri is not string');
const cached = uriPersonCache.get(uri);
@ -384,7 +382,7 @@ export async function resolvePerson(uri: string, resolver: Resolver): Promise<Ca
if (typeof uri !== 'string') throw new Error('uri is not string');
//#region このサーバーに既に登録されていたらそれを返す
const exist = await fetchPerson(uri, resolver);
const exist = await fetchPerson(uri);
if (exist) {
return exist;

View file

@ -20,10 +20,10 @@ export async function extractPollFromQuestion(source: string | IObject, resolver
}
const choices = question[multiple ? 'anyOf' : 'oneOf']!
.map((x, i) => x.name!);
.map(x => x.name!);
const votes = question[multiple ? 'anyOf' : 'oneOf']!
.map((x, i) => x.replies && x.replies.totalItems || x._misskey_votes || 0);
.map(x => x.replies && x.replies.totalItems || x._misskey_votes || 0);
return {
choices,

View file

@ -16,4 +16,4 @@ export async function perform(actor: CacheableRemoteUser, activity: IObject, res
});
}
}
};
}

View file

@ -30,14 +30,15 @@ export async function request(user: { id: User['id'] }, url: string, object: any
// don't allow redirects on the inbox
redirect: 'error',
});
};
}
/**
* Get AP object with http-signature
* @param user http-signature user
* @param url URL to fetch
*/
export async function signedGet(url: string, user: { id: User['id'] }): Promise<any> {
export async function signedGet(_url: string, user: { id: User['id'] }): Promise<any> {
let url = _url;
const keypair = await getUserKeypair(user.id);
for (let redirects = 0; redirects < 3; redirects++) {

View file

@ -23,20 +23,20 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const user = await Users.findOneBy({ id: ps.userId });
if (user == null) {
throw new ApiError('NO_SUCH_USER');
} else if (user.isAdmin) {
throw new ApiError('IS_ADMIN');
} else if(user.isModerator) {
} else if (user.isModerator) {
throw new ApiError('IS_MODERATOR');
}
if (Users.isLocalUser(user)) {
// 物理削除する前にDelete activityを送信する
await doPostSuspend(user).catch(e => {});
await doPostSuspend(user).catch(() => {});
createDeleteAccountJob(user, {
soft: false,

View file

@ -20,7 +20,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const announcement = await Announcements.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');

View file

@ -84,6 +84,6 @@ export default define(meta, paramDef, async (ps) => {
title: announcement.title,
text: announcement.text,
imageUrl: announcement.imageUrl,
reads: reads.get(announcement)!,
reads: reads.get(announcement),
}));
});

View file

@ -23,7 +23,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const announcement = await Announcements.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');

View file

@ -18,7 +18,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const files = await DriveFiles.findBy({
userId: ps.userId,
});

View file

@ -15,6 +15,6 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async () => {
createCleanRemoteFilesJob();
});

View file

@ -39,7 +39,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const query = makePaginationQuery(DriveFiles.createQueryBuilder('file'), ps.sinceId, ps.untilId);
if (ps.userId) {

View file

@ -163,7 +163,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const file = ps.fileId ? await DriveFiles.findOneBy({ id: ps.fileId }) : await DriveFiles.findOne({
where: [{
url: ps.url,

View file

@ -37,7 +37,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const emoji = await Emojis.findOneBy({ id: ps.emojiId });
if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');

View file

@ -18,7 +18,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const files = await DriveFiles.findBy({
userHost: ps.host,
});

View file

@ -22,7 +22,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const instance = await Instances.findOneBy({ host: toPuny(ps.host) });
if (instance == null) {

View file

@ -18,7 +18,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const followings = await Followings.findBy({
followerHost: ps.host,
});

View file

@ -256,7 +256,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async () => {
const instance = await fetchMeta(true);
return {

View file

@ -39,7 +39,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps) => {
export default define(meta, paramDef, async () => {
const jobs = await deliverQueue.getJobs(['delayed']);
const res = [] as [string, number][];

View file

@ -39,7 +39,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps) => {
export default define(meta, paramDef, async () => {
const jobs = await inboxQueue.getJobs(['delayed']);
const res = [] as [string, number][];

View file

@ -38,7 +38,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps) => {
export default define(meta, paramDef, async () => {
const deliverJobCounts = await deliverQueue.getJobCounts();
const inboxJobCounts = await inboxQueue.getJobCounts();
const dbJobCounts = await dbQueue.getJobCounts();

View file

@ -49,7 +49,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
try {
if (new URL(ps.inbox).protocol !== 'https:') throw new ApiError('INVALID_URL', 'https only');
} catch (e) {

View file

@ -46,6 +46,6 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async () => {
return await listRelay();
});

View file

@ -17,6 +17,6 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
return await removeRelay(ps.inbox);
});

View file

@ -50,9 +50,9 @@ export default define(meta, paramDef, async (ps, me) => {
}
(async () => {
await doPostSuspend(user).catch(e => {});
await unFollowAll(user).catch(e => {});
await readAllNotify(user).catch(e => {});
await doPostSuspend(user).catch(() => {});
await unFollowAll(user).catch(() => {});
await readAllNotify(user).catch(() => {});
})();
});

View file

@ -6,7 +6,7 @@ import { extractDbHost } from '@/misc/convert-host.js';
import { Users, Notes } from '@/models/index.js';
import { Note } from '@/models/entities/note.js';
import { CacheableLocalUser, User } from '@/models/entities/user.js';
import { isActor, isPost, getApId } from '@/remote/activitypub/type.js';
import { isActor, isPost } from '@/remote/activitypub/type.js';
import { SchemaType } from '@/misc/schema.js';
import { HOUR } from '@/const.js';
import { shouldBlockInstance } from '@/misc/should-block-instance.js';

View file

@ -27,7 +27,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
const result = await AuthSessions.delete({
token: ps.token,
});

View file

@ -36,7 +36,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const query = Instances.createQueryBuilder('instance');
switch (ps.sort) {

View file

@ -26,7 +26,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const instance = await Instances
.findOneBy({ host: toPuny(ps.host) });

View file

@ -30,7 +30,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const query = Hashtags.createQueryBuilder('tag');
if (ps.attachedToUserOnly) query.andWhere('tag.attachedUsersCount != 0');

View file

@ -26,7 +26,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) });
if (hashtag == null) throw new ApiError('NO_SUCH_HASHTAG');

View file

@ -1,7 +1,7 @@
import * as speakeasy from 'speakeasy';
import { UserProfiles } from '@/models/index.js';
import define from '../../../define.js';
import { ApiError } from '@/server/api/error.js';
import define from '../../../define.js';
export const meta = {
requireCredential: true,

View file

@ -1,8 +1,8 @@
import { comparePassword } from '@/misc/password.js';
import { publishInternalEvent, publishMainStream, publishUserEvent } from '@/services/stream.js';
import { Users, UserProfiles } from '@/models/index.js';
import generateUserToken from '../../common/generate-native-user-token.js';
import { ApiError } from '@/server/api/error.js';
import generateUserToken from '../../common/generate-native-user-token.js';
import define from '../../define.js';
export const meta = {

View file

@ -51,7 +51,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
// check note visibility
const note = await getNote(ps.noteId, user).catch(err => {
await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err;
});

View file

@ -3,7 +3,6 @@ import fetch from 'node-fetch';
import config from '@/config/index.js';
import { getAgentByUrl } from '@/misc/fetch.js';
import { fetchMeta } from '@/misc/fetch-meta.js';
import { Notes } from '@/models/index.js';
import { TranslationService } from '@/models/entities/meta.js';
import { ApiError } from '../../error.js';
import { getNote } from '../../common/getters.js';

View file

@ -17,7 +17,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async () => {
if (process.env.NODE_ENV !== 'test') throw new ApiError('ACCESS_DENIED');
await resetDb();

View file

@ -28,7 +28,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
const req = await PasswordResetRequests.findOneBy({
token: ps.token,
});

View file

@ -30,7 +30,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
const query = makePaginationQuery(Clips.createQueryBuilder('clip'), ps.sinceId, ps.untilId)
.andWhere('clip.userId = :userId', { userId: ps.userId })
.andWhere('clip.isPublic = true');

View file

@ -30,7 +30,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
export default define(meta, paramDef, async (ps) => {
const query = makePaginationQuery(Pages.createQueryBuilder('page'), ps.sinceId, ps.untilId)
.andWhere('page.userId = :userId', { userId: ps.userId })
.andWhere('page.visibility = \'public\'');

View file

@ -110,7 +110,7 @@ export const paramDef = {
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => {
export default define(meta, paramDef, async (ps) => {
const user = await Users.findOneBy({ id: ps.userId });
if (user == null) {
throw new ApiError('NO_SUCH_USER');

View file

@ -10,15 +10,16 @@ export class ApiError extends Error {
code: keyof errors = 'INTERNAL_ERROR',
info?: any | null,
) {
let _info = info, _code = code;
if (!(code in errors)) {
info = `Unknown error "${code}" occurred.`;
code = 'INTERNAL_ERROR';
_code = 'INTERNAL_ERROR';
_info = `Unknown error "${code}" occurred.`;
}
const { message, httpStatusCode } = errors[code];
const { message, httpStatusCode } = errors[_code];
super(message);
this.code = code;
this.info = info;
this.code = _code;
this.info = _info;
this.message = message;
this.httpStatusCode = httpStatusCode;
}

View file

@ -4,7 +4,8 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
const res: any = schema;
if (schema.type === 'object' && schema.properties) {
res.required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
res.required = Object.entries(schema.properties)
.flatMap(([k, v]) => v.optional ? [] : [k]);
for (const k of Object.keys(schema.properties)) {
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);

View file

@ -11,7 +11,7 @@ export default async (ctx: Koa.Context) => {
try {
const pendingUser = await UserPendings.findOneByOrFail({ code });
const { account, secret } = await signup({
const { account } = await signup({
username: pendingUser.username,
passwordHash: pendingUser.password,
});

View file

@ -5,7 +5,7 @@ export default class extends Channel {
public static shouldShare = true;
public static requireCredential = true;
public async init(params: any) {
public async init() {
// Subscribe admin stream
this.subscriber.on(`adminStream:${this.user!.id}`, data => {
this.send(data);

View file

@ -5,7 +5,7 @@ export default class extends Channel {
public static shouldShare = true;
public static requireCredential = true;
public async init(params: any) {
public async init() {
// Subscribe drive stream
this.subscriber.on(`driveStream:${this.user!.id}`, data => {
this.send(data);

View file

@ -17,7 +17,7 @@ export default class extends Channel {
this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
}
public async init(params: any) {
public async init() {
const meta = await fetchMeta();
if (meta.disableGlobalTimeline) {
if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;

View file

@ -16,7 +16,7 @@ export default class extends Channel {
this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
}
public async init(params: any) {
public async init() {
// Subscribe events
this.subscriber.on('notesStream', this.onNote);
}

View file

@ -17,7 +17,7 @@ export default class extends Channel {
this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
}
public async init(params: any) {
public async init() {
const meta = await fetchMeta();
if (meta.disableLocalTimeline && !this.user!.isAdmin && !this.user!.isModerator) return;

View file

@ -16,7 +16,7 @@ export default class extends Channel {
this.onNote = this.withPackedNote(this.onPackedNote.bind(this));
}
public async init(params: any) {
public async init() {
const meta = await fetchMeta();
if (meta.disableLocalTimeline) {
if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;

View file

@ -6,7 +6,7 @@ export default class extends Channel {
public static shouldShare = true;
public static requireCredential = true;
public async init(params: any) {
public async init() {
// Subscribe main stream channel
this.subscriber.on(`mainStream:${this.user!.id}`, async data => {
switch (data.type) {

View file

@ -5,7 +5,7 @@ export default class extends Channel {
public static shouldShare = true;
public static requireCredential = true;
public async init(params: any) {
public async init() {
// Subscribe messaging index stream
this.subscriber.on(`messagingIndexStream:${this.user!.id}`, data => {
this.send(data);

View file

@ -14,7 +14,7 @@ export default class extends Channel {
this.onMessage = this.onMessage.bind(this);
}
public async init(params: any) {
public async init() {
ev.addListener('queueStats', this.onStats);
}

View file

@ -14,7 +14,7 @@ export default class extends Channel {
this.onMessage = this.onMessage.bind(this);
}
public async init(params: any) {
public async init() {
ev.addListener('serverStats', this.onStats);
}

View file

@ -485,9 +485,6 @@ router.get('/_info_card_', async ctx => {
});
});
const override = (source: string, target: string, depth = 0) =>
[, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/');
router.get('/flush', async ctx => {
await ctx.render('flush');
});

View file

@ -13,7 +13,7 @@ export default class PerUserReactionsChart extends Chart<typeof schema> {
super(name, schema, true);
}
protected async tickMajor(group: string): Promise<Partial<KVs<typeof schema>>> {
protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
return {};
}

View file

@ -1,6 +1,6 @@
import { publishMainStream } from '@/services/stream.js';
import { pushNotification } from '@/services/push-notification.js';
import { Notifications, Mutings, UserProfiles, Users } from '@/models/index.js';
import { Notifications, Mutings, UserProfiles } from '@/models/index.js';
import { genId } from '@/misc/gen-id.js';
import { User } from '@/models/entities/user.js';
import { Notification } from '@/models/entities/notification.js';

View file

@ -656,7 +656,7 @@ async function createMentionedEvents(mentionedUsers: MinimumUser[], note: Note,
}
}
function saveReply(reply: Note, note: Note): void {
function saveReply(reply: Note): void {
Notes.increment({ id: reply.id }, 'repliesCount', 1);
}

View file

@ -1,4 +1,4 @@
import { Brackets, FindOptionsWhere, In, IsNull, Not } from 'typeorm';
import { FindOptionsWhere, In, IsNull, Not } from 'typeorm';
import { publishNoteStream } from '@/services/stream.js';
import renderDelete from '@/remote/activitypub/renderer/delete.js';
import renderAnnounce from '@/remote/activitypub/renderer/announce.js';
@ -106,7 +106,7 @@ async function findCascadingNotes(note: Note): Promise<Note[]> {
await Promise.all(replies.map(reply => {
// only add unique notes
if (cascadingNotes.find((x) => x.id == reply.id) != null) return;
if (cascadingNotes.find((x) => x.id === reply.id) != null) return;
cascadingNotes.push(reply);
return recursive(reply.id);