Removed out all note packing
ci/woodpecker/tag/ociImageTag Pipeline was successful Details

This commit is contained in:
Natty 2023-12-28 00:31:05 +01:00
parent f4d03a4f48
commit c443079db0
Signed by: natty
GPG Key ID: BF6CB659ADEE60EC
55 changed files with 427 additions and 1391 deletions

View File

@ -92,7 +92,7 @@
"qs": "6.11.2",
"random-seed": "0.3.0",
"ratelimiter": "3.4.1",
"re2": "1.19.0",
"re2": "1.20.9",
"redis-lock": "0.1.4",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",

View File

@ -1,15 +1,10 @@
import type { Antenna } from "@/models/entities/antenna.js";
import type { Note } from "@/models/entities/note.js";
import type { User } from "@/models/entities/user.js";
import {
UserListJoinings,
UserGroupJoinings,
Blockings,
} from "@/models/index.js";
import { getFullApAccount } from "./convert-host.js";
import type {Antenna} from "@/models/entities/antenna.js";
import type {Note} from "@/models/entities/note.js";
import type {User} from "@/models/entities/user.js";
import {Blockings, UserGroupJoinings, UserListJoinings,} from "@/models/index.js";
import {getFullApAccount} from "./convert-host.js";
import * as Acct from "@/misc/acct.js";
import type { Packed } from "./schema.js";
import { Cache } from "./cache.js";
import {Cache} from "./cache.js";
const blockingCache = new Cache<User["id"][]>(1000 * 60 * 5);
@ -20,7 +15,7 @@ const blockingCache = new Cache<User["id"][]>(1000 * 60 * 5);
*/
export async function checkHitAntenna(
antenna: Antenna,
note: Note | Packed<"Note">,
note: Note,
noteUser: { id: User["id"]; username: string; host: string | null },
noteUserFollowers?: User["id"][],
antennaUserFollowing?: User["id"][],

View File

@ -29,4 +29,4 @@ export function genId(date?: Date): string {
const cuid = createId();
return `${time36}${cuid}`;
}
}

View File

@ -1,14 +1,10 @@
import type { Packed } from "./schema.js";
import {Note} from "@/models/entities/note";
/**
* 稿
* @param {*} note (packされた)稿
*/
export const getNoteSummary = (note: Packed<"Note">): string => {
if (note.deletedAt) {
return "❌";
}
export const getNoteSummary = (note: Note): string => {
let summary = "";
// 本文
@ -19,13 +15,13 @@ export const getNoteSummary = (note: Packed<"Note">): string => {
}
// ファイルが添付されているとき
if ((note.files || []).length !== 0) {
const len = note.files?.length;
if ((note.fileIds || []).length !== 0) {
const len = note.fileIds?.length;
summary += ` 📎${len !== 1 ? ` (${len})` : ""}`;
}
// 投票が添付されているとき
if (note.poll) {
if (note.fileIds) {
summary += " 📊";
}

View File

@ -1,7 +1,8 @@
import type { Packed } from "./schema.js";
import type {Packed} from "./schema.js";
import {Note} from "@/models/entities/note";
export function isInstanceMuted(
note: Packed<"Note">,
note: Note,
mutedInstances: Set<string>,
): boolean {
if (mutedInstances.has(note?.user?.host ?? "")) return true;

View File

@ -1,4 +1,6 @@
export function isUserRelated(note: any, ids: Set<string>): boolean {
import {Note} from "@/models/entities/note";
export function isUserRelated(note: Note, ids: Set<string>): boolean {
if (ids.has(note.userId)) return true; // note author is muted
if (note.mentions?.some((user: string) => ids.has(user))) return true; // any of mentioned users are muted
if (note.reply && isUserRelated(note.reply, ids)) return true; // also check reply target

View File

@ -7,7 +7,6 @@ import {
packedUserLiteSchema,
packedUserSchema,
} from "@/models/schema/user.js";
import {packedNoteSchema} from "@/models/schema/note.js";
import {packedUserListSchema} from "@/models/schema/user-list.js";
import {packedAppSchema} from "@/models/schema/app.js";
import {packedNotificationSchema} from "@/models/schema/notification.js";
@ -42,7 +41,6 @@ export const refs = {
UserList: packedUserListSchema,
UserGroup: packedUserGroupSchema,
App: packedAppSchema,
Note: packedNoteSchema,
NoteEdit: packedNoteEdit,
NoteReaction: packedNoteReactionSchema,
NoteFavorite: packedNoteFavoriteSchema,

View File

@ -1,7 +1,7 @@
import { db } from "@/db/postgre.js";
import { NoteFavorite } from "@/models/entities/note-favorite.js";
import { Notes } from "../index.js";
import type { User } from "@/models/entities/user.js";
import {db} from "@/db/postgre.js";
import {NoteFavorite} from "@/models/entities/note-favorite.js";
import type {User} from "@/models/entities/user.js";
import {getNote} from "@/server/api/common/getters.js";
export const NoteFavoriteRepository = db.getRepository(NoteFavorite).extend({
async pack(
@ -16,7 +16,7 @@ export const NoteFavoriteRepository = db.getRepository(NoteFavorite).extend({
createdAt: favorite.createdAt.toISOString(),
noteId: favorite.noteId,
// may throw error
note: await Notes.pack(favorite.note || favorite.noteId, me),
note: await getNote(favorite.noteId, me ?? null),
};
},

View File

@ -1,9 +1,10 @@
import { db } from "@/db/postgre.js";
import { NoteReaction } from "@/models/entities/note-reaction.js";
import { Notes, Users } from "../index.js";
import type { Packed } from "@/misc/schema.js";
import { convertLegacyReaction } from "@/misc/reaction-lib.js";
import type { User } from "@/models/entities/user.js";
import {db} from "@/db/postgre.js";
import {NoteReaction} from "@/models/entities/note-reaction.js";
import {Users} from "../index.js";
import type {Packed} from "@/misc/schema.js";
import {convertLegacyReaction} from "@/misc/reaction-lib.js";
import type {User} from "@/models/entities/user.js";
import {getNote} from "@/server/api/common/getters.js";
export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
async pack(
@ -31,7 +32,7 @@ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
...(opts.withNote
? {
// may throw error
note: await Notes.pack(reaction.note ?? reaction.noteId, me),
note: getNote(reaction.noteId, me),
}
: {}),
};
@ -41,7 +42,7 @@ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
src: NoteReaction[],
me?: { id: User["id"] } | null | undefined,
options?: {
withNote: booleam;
withNote: boolean;
},
): Promise<Packed<"NoteReaction">[]> {
const reactions = await Promise.allSettled(

View File

@ -1,16 +1,9 @@
import {In} from "typeorm";
import * as mfm from "mfm-js";
import {Note} from "@/models/entities/note.js";
import type {User} from "@/models/entities/user.js";
import {DriveFiles, Followings, NoteReactions, Notes, Polls, PollVotes, Users,} from "../index.js";
import type {Packed} from "@/misc/schema.js";
import {nyaize} from "@/misc/nyaize.js";
import {awaitAll} from "@/prelude/await-all.js";
import {convertLegacyReaction, convertLegacyReactions, decodeReaction,} from "@/misc/reaction-lib.js";
import {Followings, NoteReactions, Polls, PollVotes, Users,} from "../index.js";
import {convertLegacyReaction,} from "@/misc/reaction-lib.js";
import type {NoteReaction} from "@/models/entities/note-reaction.js";
import {aggregateNoteEmojis, populateEmojis, prefetchEmojis,} from "@/misc/populate-emojis.js";
import {db} from "@/db/postgre.js";
import {IdentifiableError} from "@/misc/identifiable-error.js";
export async function populatePoll(note: Note, meId: User["id"] | null) {
const poll = await Polls.findOneByOrFail({ noteId: note.id });
@ -132,179 +125,4 @@ export const NoteRepository = db.getRepository(Note).extend({
return true;
},
async pack(
src: Note["id"] | Note,
me?: { id: User["id"] } | null | undefined,
options?: {
detail?: boolean;
_hint_?: {
myReactions: Map<Note["id"], NoteReaction | null>;
};
},
): Promise<Packed<"Note">> {
const opts = Object.assign(
{
detail: true,
},
options,
);
const meId = me ? me.id : null;
const note =
typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
const host = note.userHost;
if (!(await this.isVisibleForMe(note, meId))) {
throw new IdentifiableError(
"9725d0ce-ba28-4dde-95a7-2cbb2c15de24",
"No such note.",
);
}
let text = note.text;
if (note.name && (note.url ?? note.uri)) {
text = `${note.name}\n${(note.text || "").trim()}\n\n${
note.url ?? note.uri
}`;
}
const reactionEmojiNames = Object.keys(note.reactions)
.filter((x) => x?.startsWith(":"))
.map((x) => decodeReaction(x).reaction)
.map((x) => x.replace(/:/g, ""));
const userRenoteExists = meId ? (Notes.createQueryBuilder("note")
.andWhere("note.renoteId = :renoteId", { renoteId: note.id })
.andWhere("note.userId = :userId", { userId: meId })
.getExists()) : (async () => false)();
const noteEmoji = await populateEmojis(
note.emojis.concat(reactionEmojiNames),
host,
);
const reactionEmoji = await populateEmojis(reactionEmojiNames, host);
const packed: Packed<"Note"> = await awaitAll({
id: note.id,
createdAt: note.createdAt.toISOString(),
userId: note.userId,
user: Users.pack(note.user ?? note.userId, me, {
detail: false,
}),
text: text,
cw: note.cw,
visibility: note.visibility,
localOnly: note.localOnly || undefined,
visibleUserIds:
note.visibility === "specified" ? note.visibleUserIds : undefined,
renoteCount: note.renoteCount,
repliesCount: note.repliesCount,
reactions: convertLegacyReactions(note.reactions),
reactionEmojis: reactionEmoji,
emojis: noteEmoji,
tags: note.tags.length > 0 ? note.tags : undefined,
fileIds: note.fileIds,
files: DriveFiles.packMany(note.fileIds),
replyId: note.replyId,
renoteId: note.renoteId,
mentions: note.mentions.length > 0 ? note.mentions : undefined,
uri: note.uri || undefined,
url: note.url || undefined,
updatedAt: note.updatedAt?.toISOString() || undefined,
hasRenotedBefore: userRenoteExists,
poll: note.hasPoll ? populatePoll(note, meId) : undefined,
...(meId
? {
myReaction: populateMyReaction(note, meId, options?._hint_),
}
: {}),
...(opts.detail
? {
reply: note.replyId
? this.pack(note.reply || note.replyId, me, {
detail: false,
_hint_: options?._hint_,
})
: undefined,
renote: note.renoteId
? this.pack(note.renote || note.renoteId, me, {
detail: true,
_hint_: options?._hint_,
})
: undefined,
}
: {}),
});
if (packed.user.isCat && packed.user.speakAsCat && packed.text) {
const tokens = packed.text ? mfm.parse(packed.text) : [];
function nyaizeNode(node: mfm.MfmNode) {
if (node.type === "quote") return;
if (node.type === "text") node.props.text = nyaize(node.props.text);
if (node.children) {
for (const child of node.children) {
nyaizeNode(child);
}
}
}
for (const node of tokens) nyaizeNode(node);
packed.text = mfm.toString(tokens);
}
return packed;
},
async packMany(
notes: Note[],
me?: { id: User["id"] } | null | undefined,
options?: {
detail?: boolean;
},
) {
if (notes.length === 0) return [];
const meId = me ? me.id : null;
const myReactionsMap = new Map<Note["id"], NoteReaction | null>();
if (meId) {
const renoteIds = notes
.filter((n) => n.renoteId != null)
.map((n) => n.renoteId!);
const targets = [...notes.map((n) => n.id), ...renoteIds];
const myReactions = await NoteReactions.findBy({
userId: meId,
noteId: In(targets),
});
for (const target of targets) {
myReactionsMap.set(
target,
myReactions.find((reaction) => reaction.noteId === target) || null,
);
}
}
await prefetchEmojis(aggregateNoteEmojis(notes));
const promises = await Promise.allSettled(
notes.map((n) =>
this.pack(n, me, {
...options,
_hint_: {
myReactions: myReactionsMap,
},
}),
),
);
// filter out rejected promises, only keep fulfilled values
return promises.flatMap((result) =>
result.status === "fulfilled" ? [result.value] : [],
);
},
});

View File

@ -1,20 +1,14 @@
import { In, Repository } from "typeorm";
import { Notification } from "@/models/entities/notification.js";
import { awaitAll } from "@/prelude/await-all.js";
import type { Packed } from "@/misc/schema.js";
import type { Note } from "@/models/entities/note.js";
import type { NoteReaction } from "@/models/entities/note-reaction.js";
import type { User } from "@/models/entities/user.js";
import { aggregateNoteEmojis, prefetchEmojis } from "@/misc/populate-emojis.js";
import { notificationTypes } from "@/types.js";
import { db } from "@/db/postgre.js";
import {
Users,
Notes,
UserGroupInvitations,
AccessTokens,
NoteReactions,
} from "../index.js";
import {In} from "typeorm";
import {Notification} from "@/models/entities/notification.js";
import {awaitAll} from "@/prelude/await-all.js";
import type {Packed} from "@/misc/schema.js";
import type {Note} from "@/models/entities/note.js";
import type {NoteReaction} from "@/models/entities/note-reaction.js";
import type {User} from "@/models/entities/user.js";
import {aggregateNoteEmojis, prefetchEmojis} from "@/misc/populate-emojis.js";
import {db} from "@/db/postgre.js";
import {AccessTokens, NoteReactions, UserGroupInvitations, Users,} from "../index.js";
import {getNote} from "@/server/api/common/getters.js";
export const NotificationRepository = db.getRepository(Notification).extend({
async pack(
@ -44,88 +38,42 @@ export const NotificationRepository = db.getRepository(Notification).extend({
: null,
...(notification.type === "mention"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
}
: {}),
...(notification.type === "reply"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
}
: {}),
...(notification.type === "renote"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifierId }).then(async (n) => {
n.renote = await getNote(n.renoteId!, { id: notification.notifieeId });
return n;
}),
}
: {}),
...(notification.type === "quote"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
}
: {}),
...(notification.type === "reaction"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
reaction: notification.reaction,
}
: {}),
...(notification.type === "pollVote"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
choice: notification.choice,
}
: {}),
...(notification.type === "pollEnded"
? {
note: Notes.pack(
notification.note || notification.noteId!,
{ id: notification.notifieeId },
{
detail: true,
_hint_: options._hintForEachNotes_,
},
),
note: getNote(notification.noteId!, { id: notification.notifieeId }),
}
: {}),
...(notification.type === "groupInvited"

View File

@ -25,7 +25,6 @@ import {
FollowRequests,
Instances,
Mutings,
Notes,
NoteUnreads,
Notifications,
Pages,
@ -276,22 +275,6 @@ export const UserRepository = db.getRepository(User).extend({
: "offline";
},
async getAvatarUrl(user: User): Promise<string> {
if (user.avatar) {
return (
DriveFiles.getPublicUrl(user.avatar, true) ||
this.getIdenticonUrl(user.id)
);
} else if (user.avatarId) {
const avatar = await DriveFiles.findOneByOrFail({ id: user.avatarId });
return (
DriveFiles.getPublicUrl(avatar, true) || this.getIdenticonUrl(user.id)
);
} else {
return this.getIdenticonUrl(user.id);
}
},
getAvatarUrlSync(user: User): string {
if (user.avatar) {
return (
@ -330,17 +313,9 @@ export const UserRepository = db.getRepository(User).extend({
if (typeof src === "object") {
user = src;
if (src.avatar === undefined && src.avatarId)
src.avatar = (await DriveFiles.findOneBy({ id: src.avatarId })) ?? null;
if (src.banner === undefined && src.bannerId)
src.banner = (await DriveFiles.findOneBy({ id: src.bannerId })) ?? null;
} else {
user = await this.findOneOrFail({
where: { id: src },
relations: {
avatar: true,
banner: true,
},
where: { id: src }
});
}
@ -391,9 +366,6 @@ export const UserRepository = db.getRepository(User).extend({
name: user.name,
username: user.username,
host: user.host,
avatarUrl: this.getAvatarUrlSync(user),
avatarBlurhash: user.avatar?.blurhash || null,
avatarColor: null, // 後方互換性のため
isAdmin: user.isAdmin || falsy,
isModerator: user.isModerator || falsy,
isBot: user.isBot || falsy,
@ -436,11 +408,6 @@ export const UserRepository = db.getRepository(User).extend({
lastFetchedAt: user.lastFetchedAt
? user.lastFetchedAt.toISOString()
: null,
bannerUrl: user.banner
? DriveFiles.getPublicUrl(user.banner, false)
: null,
bannerBlurhash: user.banner?.blurhash || null,
bannerColor: null, // 後方互換性のため
isLocked: user.isLocked,
isSilenced: user.isSilenced || falsy,
isSuspended: user.isSuspended || falsy,
@ -453,13 +420,6 @@ export const UserRepository = db.getRepository(User).extend({
followingCount: followingCount || 0,
notesCount: user.notesCount,
pinnedNoteIds: pins.map((pin) => pin.noteId),
pinnedNotes: Notes.packMany(
pins.map((pin) => pin.note!),
me,
{
detail: true,
},
),
pinnedPageId: profile!.pinnedPageId,
pinnedPage: profile!.pinnedPageId
? Pages.pack(profile!.pinnedPageId, me)

View File

@ -27,23 +27,6 @@ export const packedUserLiteSchema = {
example: "misskey.example.com",
description: "The local host is represented with `null`.",
},
avatarUrl: {
type: "string",
format: "url",
nullable: true,
optional: false,
},
avatarBlurhash: {
type: "any",
nullable: true,
optional: false,
},
avatarColor: {
type: "any",
nullable: true,
optional: false,
default: null,
},
isAdmin: {
type: "boolean",
nullable: false,
@ -149,23 +132,6 @@ export const packedUserDetailedNotMeOnlySchema = {
optional: false,
format: "date-time",
},
bannerUrl: {
type: "string",
format: "url",
nullable: true,
optional: false,
},
bannerBlurhash: {
type: "any",
nullable: true,
optional: false,
},
bannerColor: {
type: "any",
nullable: true,
optional: false,
default: null,
},
isLocked: {
type: "boolean",
nullable: false,
@ -254,17 +220,6 @@ export const packedUserDetailedNotMeOnlySchema = {
format: "id",
},
},
pinnedNotes: {
type: "array",
nullable: false,
optional: false,
items: {
type: "object",
nullable: false,
optional: false,
ref: "Note",
},
},
pinnedPageId: {
type: "string",
nullable: true,

View File

@ -222,7 +222,6 @@ import * as ep___renote_mute_create from "./endpoints/renote-mute/create.js";
import * as ep___renote_mute_delete from "./endpoints/renote-mute/delete.js";
import * as ep___renote_mute_list from "./endpoints/renote-mute/list.js";
import * as ep___my_apps from "./endpoints/my/apps.js";
import * as ep___notes from "./endpoints/notes.js";
import * as ep___notes_children from "./endpoints/notes/children.js";
import * as ep___notes_clips from "./endpoints/notes/clips.js";
import * as ep___notes_conversation from "./endpoints/notes/conversation.js";
@ -237,7 +236,6 @@ import * as ep___notes_hybridTimeline from "./endpoints/notes/hybrid-timeline.js
import * as ep___notes_localTimeline from "./endpoints/notes/local-timeline.js";
import * as ep___notes_recommendedTimeline from "./endpoints/notes/recommended-timeline.js";
import * as ep___notes_mentions from "./endpoints/notes/mentions.js";
import * as ep___notes_polls_recommendation from "./endpoints/notes/polls/recommendation.js";
import * as ep___notes_polls_vote from "./endpoints/notes/polls/vote.js";
import * as ep___notes_reactions from "./endpoints/notes/reactions.js";
import * as ep___notes_reactions_create from "./endpoints/notes/reactions/create.js";
@ -246,7 +244,6 @@ import * as ep___notes_renotes from "./endpoints/notes/renotes.js";
import * as ep___notes_replies from "./endpoints/notes/replies.js";
import * as ep___notes_searchByTag from "./endpoints/notes/search-by-tag.js";
import * as ep___notes_search from "./endpoints/notes/search.js";
import * as ep___notes_show from "./endpoints/notes/show.js";
import * as ep___notes_state from "./endpoints/notes/state.js";
import * as ep___notes_threadMuting_create from "./endpoints/notes/thread-muting/create.js";
import * as ep___notes_threadMuting_delete from "./endpoints/notes/thread-muting/delete.js";
@ -555,7 +552,6 @@ const eps = [
["mute/delete", ep___mute_delete],
["mute/list", ep___mute_list],
["my/apps", ep___my_apps],
["notes", ep___notes],
["notes/children", ep___notes_children],
["notes/clips", ep___notes_clips],
["notes/conversation", ep___notes_conversation],
@ -570,7 +566,6 @@ const eps = [
["notes/local-timeline", ep___notes_localTimeline],
["notes/recommended-timeline", ep___notes_recommendedTimeline],
["notes/mentions", ep___notes_mentions],
["notes/polls/recommendation", ep___notes_polls_recommendation],
["notes/polls/vote", ep___notes_polls_vote],
["notes/reactions", ep___notes_reactions],
["notes/reactions/create", ep___notes_reactions_create],
@ -579,7 +574,6 @@ const eps = [
["notes/replies", ep___notes_replies],
["notes/search-by-tag", ep___notes_searchByTag],
["notes/search", ep___notes_search],
["notes/show", ep___notes_show],
["notes/state", ep___notes_state],
["notes/thread-muting/create", ep___notes_threadMuting_create],
["notes/thread-muting/delete", ep___notes_threadMuting_delete],

View File

@ -1,11 +1,11 @@
import define from "../../define.js";
import readNote from "@/services/note/read.js";
import { Antennas, Notes, AntennaNotes } from "@/models/index.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { ApiError } from "../../error.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {AntennaNotes, Antennas, Notes} from "@/models/index.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {ApiError} from "../../error.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["antennas", "account", "notes"],
@ -70,17 +70,6 @@ export default define(meta, paramDef, async (ps, user) => {
"antennaNote",
"antennaNote.noteId = note.id",
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.andWhere("antennaNote.antennaId = :antennaId", { antennaId: antenna.id })
.andWhere("note.visibility != 'home'");
@ -94,5 +83,5 @@ export default define(meta, paramDef, async (ps, user) => {
readNote(user.id, notes);
}
return await Notes.packMany(notes, user);
return notes;
});

View File

@ -1,20 +1,20 @@
import define from "../../define.js";
import { createPerson } from "@/remote/activitypub/models/person.js";
import { createNote } from "@/remote/activitypub/models/note.js";
import {createPerson} from "@/remote/activitypub/models/person.js";
import {createNote} from "@/remote/activitypub/models/note.js";
import DbResolver from "@/remote/activitypub/db-resolver.js";
import Resolver from "@/remote/activitypub/resolver.js";
import { ApiError } from "../../error.js";
import { extractDbHost } from "@/misc/convert-host.js";
import { Users, Notes } from "@/models/index.js";
import type { Note } from "@/models/entities/note.js";
import type { CacheableLocalUser, User } from "@/models/entities/user.js";
import { isActor, isPost, getApId } from "@/remote/activitypub/type.js";
import type { SchemaType } from "@/misc/schema.js";
import { HOUR } from "@/const.js";
import { shouldBlockInstance } from "@/misc/should-block-instance.js";
import { updateQuestion } from "@/remote/activitypub/models/question.js";
import { populatePoll } from "@/models/repositories/note.js";
import { redisClient } from "@/db/redis.js";
import {ApiError} from "../../error.js";
import {extractDbHost} from "@/misc/convert-host.js";
import {Notes, Users} from "@/models/index.js";
import type {Note} from "@/models/entities/note.js";
import type {CacheableLocalUser, User} from "@/models/entities/user.js";
import {getApId, isActor, isPost} from "@/remote/activitypub/type.js";
import type {SchemaType} from "@/misc/schema.js";
import {HOUR} from "@/const.js";
import {shouldBlockInstance} from "@/misc/should-block-instance.js";
import {updateQuestion} from "@/remote/activitypub/models/question.js";
import {populatePoll} from "@/models/repositories/note.js";
import {redisClient} from "@/db/redis.js";
export const meta = {
tags: ["federation"],
@ -161,11 +161,12 @@ async function mergePack(
};
} else if (note != null) {
try {
const object = await Notes.pack(note, me, { detail: true });
if (!await Notes.isVisibleForMe(note, me?.id ?? null))
return null;
return {
type: "Note",
object,
note,
};
} catch (e) {
return null;

View File

@ -1,10 +1,10 @@
import define from "../../define.js";
import { ClipNotes, Clips, Notes } from "@/models/index.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { ApiError } from "../../error.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {ClipNotes, Clips, Notes} from "@/models/index.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {ApiError} from "../../error.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["account", "notes", "clips"],
@ -69,26 +69,11 @@ export default define(meta, paramDef, async (ps, user) => {
"clipNote",
"clipNote.noteId = note.id",
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.andWhere("clipNote.clipId = :clipId", { clipId: clip.id });
if (user) {
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
generateBlockedUserQuery(query, user);
}
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
generateBlockedUserQuery(query, user);
const notes = await query.take(ps.limit).getMany();
return await Notes.packMany(notes, user);
return await query.take(ps.limit).getMany();
});

View File

@ -1,6 +1,7 @@
import define from "../../../define.js";
import { ApiError } from "../../../error.js";
import { DriveFiles, Notes } from "@/models/index.js";
import {ApiError} from "../../../error.js";
import {DriveFiles, Notes} from "@/models/index.js";
import {generateVisibilityQuery} from "@/server/api/common/generate-visibility-query.js";
export const meta = {
tags: ["drive", "notes"],
@ -51,11 +52,10 @@ export default define(meta, paramDef, async (ps, user) => {
throw new ApiError(meta.errors.noSuchFile);
}
const notes = await Notes.createQueryBuilder("note")
.where(":file = ANY(note.fileIds)", { file: file.id })
.getMany();
const notes = Notes.createQueryBuilder("note")
.where(":file = ANY(note.fileIds)", { file: file.id });
return await Notes.packMany(notes, user, {
detail: true,
});
generateVisibilityQuery(notes, user);
return await notes.getMany();
});

View File

@ -1,16 +1,10 @@
import { Brackets } from "typeorm";
import {
Notifications,
Followings,
Mutings,
Users,
UserProfiles,
} from "@/models/index.js";
import { notificationTypes } from "@/types.js";
import {Brackets} from "typeorm";
import {Followings, Mutings, Notifications, UserProfiles, Users,} from "@/models/index.js";
import {notificationTypes} from "@/types.js";
import read from "@/services/note/read.js";
import { readNotification } from "../../common/read-notification.js";
import {readNotification} from "../../common/read-notification.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
export const meta = {
tags: ["account", "notifications"],
@ -97,19 +91,11 @@ export default define(meta, paramDef, async (ps, user) => {
.andWhere("notification.notifieeId = :meId", { meId: user.id })
.leftJoinAndSelect("notification.notifier", "notifier")
.leftJoinAndSelect("notification.note", "note")
.leftJoinAndSelect("notifier.avatar", "notifierAvatar")
.leftJoinAndSelect("notifier.banner", "notifierBanner")
.leftJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.leftJoinAndSelect("renote.user", "renoteUser");
// muted users
query.andWhere(

View File

@ -1,91 +0,0 @@
import { Notes } from "@/models/index.js";
import define from "../define.js";
import { makePaginationQuery } from "../common/make-pagination-query.js";
export const meta = {
tags: ["notes"],
requireCredentialPrivateMode: true,
res: {
type: "array",
optional: false,
nullable: false,
items: {
type: "object",
optional: false,
nullable: false,
ref: "Note",
},
},
} as const;
export const paramDef = {
type: "object",
properties: {
local: { type: "boolean", default: false },
reply: { type: "boolean" },
renote: { type: "boolean" },
withFiles: { type: "boolean" },
poll: { type: "boolean" },
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
sinceId: { type: "string", format: "misskey:id" },
untilId: { type: "string", format: "misskey:id" },
},
required: [],
} as const;
export default define(meta, paramDef, async (ps) => {
const query = makePaginationQuery(
Notes.createQueryBuilder("note"),
ps.sinceId,
ps.untilId,
)
.andWhere("note.visibility = 'public'")
.andWhere("note.localOnly = FALSE")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
if (ps.local) {
query.andWhere("note.userHost IS NULL");
}
if (ps.reply !== undefined) {
query.andWhere(
ps.reply ? "note.replyId IS NOT NULL" : "note.replyId IS NULL",
);
}
if (ps.renote !== undefined) {
query.andWhere(
ps.renote ? "note.renoteId IS NOT NULL" : "note.renoteId IS NULL",
);
}
if (ps.withFiles !== undefined) {
query.andWhere(
ps.withFiles ? "note.fileIds != '{}'" : "note.fileIds = '{}'",
);
}
if (ps.poll !== undefined) {
query.andWhere(ps.poll ? "note.hasPoll = TRUE" : "note.hasPoll = FALSE");
}
// TODO
//if (bot != undefined) {
// query.isBot = bot;
//}
const notes = await query.take(ps.limit).getMany();
return await Notes.packMany(notes);
});

View File

@ -1,10 +1,9 @@
import { Brackets } from "typeorm";
import { Notes } from "@/models/index.js";
import {Notes} from "@/models/index.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["notes"],
@ -46,9 +45,7 @@ export default define(meta, paramDef, async (ps, user) => {
"note.id IN (SELECT id FROM note_replies(:noteId, :depth, :limit))",
{ noteId: ps.noteId, depth: ps.depth, limit: ps.limit },
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner");
.innerJoinAndSelect("note.user", "user");
generateVisibilityQuery(query, user);
if (user) {
@ -56,7 +53,5 @@ export default define(meta, paramDef, async (ps, user) => {
generateBlockedUserQuery(query, user);
}
const notes = await query.getMany();
return await Notes.packMany(notes, user, { detail: false });
return await query.getMany();
});

View File

@ -1,8 +1,7 @@
import type { Note } from "@/models/entities/note.js";
import { Notes } from "@/models/index.js";
import type {Note} from "@/models/entities/note.js";
import define from "../../define.js";
import { ApiError } from "../../error.js";
import { getNote } from "../../common/getters.js";
import {ApiError} from "../../error.js";
import {getNote} from "../../common/getters.js";
export const meta = {
tags: ["notes"],
@ -77,5 +76,5 @@ export default define(meta, paramDef, async (ps, user) => {
await get(note.replyId);
}
return await Notes.packMany(conversation, user);
return conversation;
});

View File

@ -1,7 +1,7 @@
import {In} from "typeorm";
import create from "@/services/note/create.js";
import type {User} from "@/models/entities/user.js";
import {Blockings, DriveFiles, Notes, Users,} from "@/models/index.js";
import {Blockings, DriveFiles, Users,} from "@/models/index.js";
import type {DriveFile} from "@/models/entities/drive-file.js";
import type {Note} from "@/models/entities/note.js";
import {HOUR, MAX_NOTE_TEXT_LENGTH} from "@/const.js";
@ -284,6 +284,6 @@ export default define(meta, paramDef, async (ps, user) => {
});
return {
createdNote: await Notes.pack(note, user),
createdNote: note,
};
});

View File

@ -624,11 +624,11 @@ export default define(meta, paramDef, async (ps, user) => {
// GO!
dm.execute();
})();
})().then();
}
return {
createdNote: await Notes.pack(note, user),
createdNote: note,
};
});

View File

@ -1,7 +1,7 @@
import { Notes } from "@/models/index.js";
import {Notes} from "@/models/index.js";
import define from "../../define.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["notes"],
@ -45,18 +45,7 @@ export default define(meta, paramDef, async (ps, user) => {
.addSelect("note.score")
.andWhere("note.score > 0")
.andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) })
.andWhere("note.visibility = 'public'")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("note.visibility = 'public'");
switch (ps.origin) {
case "local":
@ -78,5 +67,5 @@ export default define(meta, paramDef, async (ps, user) => {
notes = notes.slice(ps.offset, ps.offset + ps.limit);
return await Notes.packMany(notes, user);
return notes;
});

View File

@ -78,18 +78,7 @@ export default define(meta, paramDef, async (ps, user) => {
ps.sinceDate,
ps.untilDate,
)
.andWhere("note.visibility = 'public'")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("note.visibility = 'public'");
generateRepliesQuery(query, ps.withReplies, user);
if (user) {
@ -111,25 +100,5 @@ export default define(meta, paramDef, async (ps, user) => {
}
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
} catch (error) {
throw new ApiError(meta.errors.queryError);
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -94,17 +94,6 @@ export default define(meta, paramDef, async (ps, user) => {
).orWhere("(note.visibility = 'public') AND (note.userHost IS NULL)");
}),
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.setParameters(followingQuery.getParameters());
generateRepliesQuery(query, ps.withReplies, user);
@ -167,25 +156,5 @@ export default define(meta, paramDef, async (ps, user) => {
activeUsersChart.read(user);
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
} catch (error) {
throw new ApiError(meta.errors.queryError);
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -87,18 +87,7 @@ export default define(meta, paramDef, async (ps, user) => {
ps.sinceDate,
ps.untilDate,
)
.andWhere("(note.visibility = 'public') AND (note.userHost IS NULL)")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("(note.visibility = 'public') AND (note.userHost IS NULL)");
generateRepliesQuery(query, ps.withReplies, user);
generateVisibilityQuery(query, user);
@ -140,25 +129,5 @@ export default define(meta, paramDef, async (ps, user) => {
}
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
} catch (error) {
throw new ApiError(meta.errors.queryError);
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,12 +1,11 @@
import { Brackets } from "typeorm";
import read from "@/services/note/read.js";
import { Notes, Followings } from "@/models/index.js";
import {Brackets} from "typeorm";
import {Followings, Notes} from "@/models/index.js";
import define from "../../define.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import { generateMutedNoteThreadQuery } from "../../common/generate-muted-note-thread-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
import {generateMutedNoteThreadQuery} from "../../common/generate-muted-note-thread-query.js";
export const meta = {
tags: ["notes"],
@ -54,18 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
`'{"${user.id}"}' <@ note.visibleUserIds`,
);
}),
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
);
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
@ -86,23 +74,5 @@ export default define(meta, paramDef, async (ps, user) => {
query.setParameters(followingQuery.getParameters());
}
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
read(user.id, found);
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,85 +0,0 @@
import { Brackets, In } from "typeorm";
import { Polls, Mutings, Notes, PollVotes } from "@/models/index.js";
import define from "../../../define.js";
export const meta = {
tags: ["notes"],
requireCredential: true,
res: {
type: "array",
optional: false,
nullable: false,
items: {
type: "object",
optional: false,
nullable: false,
ref: "Note",
},
},
} as const;
export const paramDef = {
type: "object",
properties: {
limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
offset: { type: "integer", default: 0 },
},
required: [],
} as const;
export default define(meta, paramDef, async (ps, user) => {
const query = Polls.createQueryBuilder("poll")
.where("poll.userHost IS NULL")
.andWhere("poll.userId != :meId", { meId: user.id })
.andWhere("poll.noteVisibility = 'public'")
.andWhere(
new Brackets((qb) => {
qb.where("poll.expiresAt IS NULL").orWhere("poll.expiresAt > :now", {
now: new Date(),
});
}),
);
//#region exclude arleady voted polls
const votedQuery = PollVotes.createQueryBuilder("vote")
.select("vote.noteId")
.where("vote.userId = :meId", { meId: user.id });
query.andWhere(`poll.noteId NOT IN (${votedQuery.getQuery()})`);
query.setParameters(votedQuery.getParameters());
//#endregion
//#region mute
const mutingQuery = Mutings.createQueryBuilder("muting")
.select("muting.muteeId")
.where("muting.muterId = :muterId", { muterId: user.id });
query.andWhere(`poll.userId NOT IN (${mutingQuery.getQuery()})`);
query.setParameters(mutingQuery.getParameters());
//#endregion
const polls = await query
.orderBy("poll.noteId", "DESC")
.take(ps.limit)
.skip(ps.offset)
.getMany();
if (polls.length === 0) return [];
const notes = await Notes.find({
where: {
id: In(polls.map((poll) => poll.noteId)),
},
order: {
createdAt: "DESC",
},
});
return await Notes.packMany(notes, user, {
detail: true,
});
});

View File

@ -1,10 +1,9 @@
import type { FindOptionsWhere } from "typeorm";
import { DeepPartial } from "typeorm";
import { NoteReactions } from "@/models/index.js";
import type { NoteReaction } from "@/models/entities/note-reaction.js";
import type {FindOptionsWhere} from "typeorm";
import {NoteReactions} from "@/models/index.js";
import type {NoteReaction} from "@/models/entities/note-reaction.js";
import define from "../../define.js";
import { ApiError } from "../../error.js";
import { getNote } from "../../common/getters.js";
import {ApiError} from "../../error.js";
import {getNote} from "../../common/getters.js";
export const meta = {
tags: ["notes", "reactions"],
@ -78,7 +77,7 @@ export default define(meta, paramDef, async (ps, user) => {
order: {
id: -1,
},
relations: ["user", "user.avatar", "user.banner", "note"],
relations: ["user", "note"],
});
return await NoteReactions.packMany(reactions, user);

View File

@ -90,18 +90,7 @@ export default define(meta, paramDef, async (ps, user) => {
.andWhere(
`(note.userHost = ANY ('{"${m.recommendedInstances.join('","')}"}'))`,
)
.andWhere("(note.visibility = 'public')")
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("(note.visibility = 'public')");
generateRepliesQuery(query, ps.withReplies, user);
generateVisibilityQuery(query, user);
@ -143,25 +132,5 @@ export default define(meta, paramDef, async (ps, user) => {
}
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
} catch (error) {
throw new ApiError(meta.errors.queryError);
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,11 +1,11 @@
import { Notes } from "@/models/index.js";
import {Notes} from "@/models/index.js";
import define from "../../define.js";
import { getNote } from "../../common/getters.js";
import { ApiError } from "../../error.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {getNote} from "../../common/getters.js";
import {ApiError} from "../../error.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["notes"],
@ -65,37 +65,9 @@ export default define(meta, paramDef, async (ps, user) => {
query.andWhere("user.id = :userId", { userId: ps.userId });
}
query
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
generateVisibilityQuery(query, user);
if (user) generateMutedUserQuery(query, user);
if (user) generateBlockedUserQuery(query, user);
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,9 +1,9 @@
import { Notes } from "@/models/index.js";
import {Notes} from "@/models/index.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["notes"],
@ -41,38 +41,11 @@ export default define(meta, paramDef, async (ps, user) => {
ps.sinceId,
ps.untilId,
)
.andWhere("note.replyId = :replyId", { replyId: ps.noteId })
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("note.replyId = :replyId", { replyId: ps.noteId });
generateVisibilityQuery(query, user);
if (user) generateMutedUserQuery(query, user);
if (user) generateBlockedUserQuery(query, user);
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,12 +1,12 @@
import { Brackets } from "typeorm";
import { Notes } from "@/models/index.js";
import { safeForSql } from "@/misc/safe-for-sql.js";
import { normalizeForSearch } from "@/misc/normalize-for-search.js";
import {Brackets} from "typeorm";
import {Notes} from "@/models/index.js";
import {safeForSql} from "@/misc/safe-for-sql.js";
import {normalizeForSearch} from "@/misc/normalize-for-search.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["notes", "hashtags"],
@ -74,18 +74,7 @@ export default define(meta, paramDef, async (ps, me) => {
Notes.createQueryBuilder("note"),
ps.sinceId,
ps.untilId,
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
);
generateVisibilityQuery(query, me);
if (me) generateMutedUserQuery(query, me);
@ -145,21 +134,5 @@ export default define(meta, paramDef, async (ps, me) => {
}
}
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, me)));
skip += take;
if (notes.length < take) break;
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,16 +1,16 @@
import { In } from "typeorm";
import { Notes } from "@/models/index.js";
import { Note } from "@/models/entities/note.js";
import {In} from "typeorm";
import {Notes} from "@/models/index.js";
import {Note} from "@/models/entities/note.js";
import config from "@/config/index.js";
import es from "@/db/elasticsearch.js";
import sonic from "@/db/sonic.js";
import meilisearch, { MeilisearchNote } from "@/db/meilisearch.js";
import meilisearch, {MeilisearchNote} from "@/db/meilisearch.js";
import define from "../../define.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
import {sqlLikeEscape} from "@/misc/sql-like-escape.js";
export const meta = {
tags: ["notes"],
@ -79,18 +79,7 @@ export default define(meta, paramDef, async (ps, me) => {
}
query
.andWhere("note.text ILIKE :q", { q: `%${sqlLikeEscape(ps.query)}%` })
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.andWhere("note.text ILIKE :q", { q: `%${sqlLikeEscape(ps.query)}%` });
generateVisibilityQuery(query, me);
if (me) generateMutedUserQuery(query, me);
@ -98,7 +87,7 @@ export default define(meta, paramDef, async (ps, me) => {
const notes: Note[] = await query.take(ps.limit).getMany();
return await Notes.packMany(notes, me);
return notes;
} else if (sonic) {
let start = 0;
const chunkSize = 100;
@ -162,7 +151,7 @@ export default define(meta, paramDef, async (ps, me) => {
});
// The notes are checked for visibility and muted/blocked users when packed
found.push(...(await Notes.packMany(notes, me)));
found.push(...notes);
start += chunkSize;
}
@ -192,9 +181,6 @@ export default define(meta, paramDef, async (ps, me) => {
if (ps.userId && key.userId !== ps.userId) {
return false;
}
if (ps.channelId && key.channelId !== ps.channelId) {
return false;
}
if (ps.sinceId && key.id <= ps.sinceId) {
return false;
}
@ -226,7 +212,7 @@ export default define(meta, paramDef, async (ps, me) => {
});
// The notes are checked for visibility and muted/blocked users when packed
found.push(...(await Notes.packMany(notes, me)));
found.push(...notes);
start += chunkSize;
}
@ -315,6 +301,6 @@ export default define(meta, paramDef, async (ps, me) => {
},
});
return await Notes.packMany(notes, me);
return notes;
}
});

View File

@ -1,51 +0,0 @@
import { Notes } from "@/models/index.js";
import define from "../../define.js";
import { getNote } from "../../common/getters.js";
import { ApiError } from "../../error.js";
export const meta = {
tags: ["notes"],
requireCredential: false,
requireCredentialPrivateMode: true,
res: {
type: "object",
optional: false,
nullable: false,
ref: "Note",
},
errors: {
noSuchNote: {
message: "No such note.",
code: "NO_SUCH_NOTE",
id: "24fcbfc6-2e37-42b6-8388-c29b3861a08d",
},
},
} as const;
export const paramDef = {
type: "object",
properties: {
noteId: { type: "string", format: "misskey:id" },
},
required: ["noteId"],
} as const;
export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch((err) => {
if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
throw new ApiError(meta.errors.noSuchNote);
throw err;
});
return await Notes.pack(note, user, {
// FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774)
detail: true,
}).catch((err) => {
if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
throw new ApiError(meta.errors.noSuchNote);
throw err;
});
});

View File

@ -90,17 +90,6 @@ export default define(meta, paramDef, async (ps, user) => {
qb.orWhere(`note.userId IN (${followingQuery.getQuery()})`);
}),
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.setParameters(followingQuery.getParameters());
generateRepliesQuery(query, ps.withReplies, user);
@ -171,7 +160,7 @@ export default define(meta, paramDef, async (ps, user) => {
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
found.push(...notes);
skip += take;
if (notes.length < take) break;
}

View File

@ -1,10 +1,10 @@
import { Brackets } from "typeorm";
import { UserLists, UserListJoinings, Notes } from "@/models/index.js";
import { activeUsersChart } from "@/services/chart/index.js";
import {Brackets} from "typeorm";
import {Notes, UserListJoinings, UserLists} from "@/models/index.js";
import {activeUsersChart} from "@/services/chart/index.js";
import define from "../../define.js";
import { ApiError } from "../../error.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import {ApiError} from "../../error.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
export const meta = {
tags: ["notes", "lists"],
@ -80,16 +80,6 @@ export default define(meta, paramDef, async (ps, user) => {
"userListJoining.userId = note.userId",
)
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
.andWhere("userListJoining.userListId = :userListId", {
userListId: list.id,
});
@ -149,25 +139,5 @@ export default define(meta, paramDef, async (ps, user) => {
}
});
// We fetch more than requested because some may be filtered out, and if there's less than
// requested, the pagination stops.
const found = [];
const take = Math.floor(ps.limit * 1.5);
let skip = 0;
try {
while (found.length < ps.limit) {
const notes = await query.take(take).skip(skip).getMany();
found.push(...(await Notes.packMany(notes, user)));
skip += take;
if (notes.length < take) break;
}
} catch (error) {
throw new ApiError(meta.errors.queryError);
}
if (found.length > ps.limit) {
found.length = ps.limit;
}
return found;
return await query.take(ps.limit).getMany();
});

View File

@ -1,12 +1,12 @@
import { Brackets } from "typeorm";
import { Notes } from "@/models/index.js";
import {Brackets} from "typeorm";
import {Notes} from "@/models/index.js";
import define from "../../define.js";
import { ApiError } from "../../error.js";
import { getUser } from "../../common/getters.js";
import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {ApiError} from "../../error.js";
import {getUser} from "../../common/getters.js";
import {makePaginationQuery} from "../../common/make-pagination-query.js";
import {generateVisibilityQuery} from "../../common/generate-visibility-query.js";
import {generateMutedUserQuery} from "../../common/generate-muted-user-query.js";
import {generateBlockedUserQuery} from "../../common/generate-block-query.js";
export const meta = {
tags: ["users", "notes"],
@ -75,17 +75,7 @@ export default define(meta, paramDef, async (ps, me) => {
ps.untilDate,
)
.andWhere("note.userId = :userId", { userId: user.id })
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")
.leftJoinAndSelect("note.reply", "reply")
.leftJoinAndSelect("note.renote", "renote")
.leftJoinAndSelect("reply.user", "replyUser")
.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
.leftJoinAndSelect("renote.user", "renoteUser")
.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
.innerJoinAndSelect("note.user", "user");
generateVisibilityQuery(query, me);
if (me) {
@ -138,7 +128,5 @@ export default define(meta, paramDef, async (ps, me) => {
//#endregion
const timeline = await query.take(ps.limit).getMany();
return await Notes.packMany(timeline, me);
return await query.take(ps.limit).getMany();
});

View File

@ -1,8 +1,4 @@
import type Connection from ".";
import type {Note} from "@/models/entities/note.js";
import {Notes} from "@/models/index.js";
import type {Packed} from "@/misc/schema.js";
import {IdentifiableError} from "@/misc/identifiable-error.js";
/**
* Stream channel
@ -63,34 +59,4 @@ export default abstract class Channel {
public dispose?(): void;
public onMessage?(type: string, body: any): void;
protected withPackedNote(
callback: (noteMessage: { type: "note", body: Packed<"Note"> }) => void,
): (noteMessage: { type: "note", body: Note }) => void {
return async ({body: note}) => {
try {
// because `note` was previously JSON.stringify'ed, the fields that
// were objects before are now strings and have to be restored or
// removed from the object
note.createdAt = new Date(note.createdAt);
note.reply = undefined;
note.renote = undefined;
note.user = undefined;
const packed = await Notes.pack(note, this.user, { detail: true });
callback({ type: "note", body: packed });
} catch (err) {
if (
err instanceof IdentifiableError &&
err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24"
) {
// skip: note not visible to user
return;
} else {
throw err;
}
}
};
}
}

View File

@ -1,13 +1,12 @@
import Channel from "../channel.js";
import { Notes } from "@/models/index.js";
import { isUserRelated } from "@/misc/is-user-related.js";
import type { StreamMessages } from "../types.js";
import { IdentifiableError } from "@/misc/identifiable-error.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import type {StreamMessages} from "../types.js";
import {IdentifiableError} from "@/misc/identifiable-error.js";
export default class extends Channel {
public readonly chName = "antenna";
public static shouldShare = false;
public static requireCredential = false;
public readonly chName = "antenna";
private antennaId: string;
constructor(id: string, connection: Channel["connection"]) {
@ -22,12 +21,15 @@ export default class extends Channel {
this.subscriber.on(`antennaStream:${this.antennaId}`, this.onEvent);
}
public dispose() {
// Unsubscribe events
this.subscriber.off(`antennaStream:${this.antennaId}`, this.onEvent);
}
private async onEvent(data: StreamMessages["antenna"]["payload"]) {
if (data.type === "note") {
try {
const note = await Notes.pack(data.body.id, this.user, {
detail: true,
});
const note = data.body;
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
if (isUserRelated(note, this.muting)) return;
@ -37,9 +39,7 @@ export default class extends Channel {
if (note.renote && !note.text && this.renoteMuting.has(note.userId))
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
} catch (e) {
if (
e instanceof IdentifiableError &&
@ -55,9 +55,4 @@ export default class extends Channel {
this.send(data.type, data.body);
}
}
public dispose() {
// Unsubscribe events
this.subscriber.off(`antennaStream:${this.antennaId}`, this.onEvent);
}
}

View File

@ -3,7 +3,7 @@ import {fetchMeta} from "@/misc/fetch-meta.js";
import {getWordHardMute} from "@/misc/check-word-mute.js";
import {isInstanceMuted} from "@/misc/is-instance-muted.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = true;
@ -13,7 +13,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -34,7 +34,7 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({body: note}: { type: "note", body: Packed<"Note"> }) {
private async onNote({body: note}: { type: "note", body: Note }) {
if (note.visibility !== "public") return;
// 関係ない返信は除外
@ -76,8 +76,6 @@ export default class extends Channel {
)
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -1,7 +1,7 @@
import Channel from "../channel.js";
import {normalizeForSearch} from "@/misc/normalize-for-search.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = false;
@ -11,7 +11,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -28,7 +28,7 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({body: note}: {type: "note", body: Packed<"Note">}) {
private async onNote({body: note}: {type: "note", body: Note}) {
if (note.visibility === "hidden") return;
const noteTags = note.tags
? note.tags.map((t: string) => t.toLowerCase())
@ -45,8 +45,6 @@ export default class extends Channel {
if (note.renote && !note.text && this.renoteMuting.has(note.userId)) return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -2,7 +2,7 @@ import Channel from "../channel.js";
import {getWordHardMute} from "@/misc/check-word-mute.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import {isInstanceMuted} from "@/misc/is-instance-muted.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = true;
@ -12,7 +12,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -27,7 +27,7 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({ body: note }: { type: "note", body: Packed<"Note"> }) {
private async onNote({ body: note }: { type: "note", body: Note }) {
if (note.visibility === "hidden") return;
// Filter away notes that are not authored by the user or any of the followed users
@ -73,8 +73,6 @@ export default class extends Channel {
)
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -3,7 +3,7 @@ import {fetchMeta} from "@/misc/fetch-meta.js";
import {getWordHardMute} from "@/misc/check-word-mute.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import {isInstanceMuted} from "@/misc/is-instance-muted.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = true;
@ -13,7 +13,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -36,7 +36,7 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({ body: note }: { type: "note", "body": Packed<"Note"> }) {
private async onNote({ body: note }: { type: "note", "body": Note }) {
if (note.visibility === "hidden")
return;
@ -48,7 +48,7 @@ export default class extends Channel {
!(
this.user!.id === note.userId ||
this.following.has(note.userId) ||
(note.user.host == null && note.visibility === "public")
(note.userHost == null && note.visibility === "public")
)
)
return;
@ -92,8 +92,6 @@ export default class extends Channel {
)
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -2,7 +2,7 @@ import Channel from "../channel.js";
import {fetchMeta} from "@/misc/fetch-meta.js";
import {getWordHardMute} from "@/misc/check-word-mute.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = true;
@ -12,7 +12,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -33,8 +33,8 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({ body: note }: { type: "note", body: Packed<"Note"> }) {
if (note.user.host !== null) return;
private async onNote({ body: note }: { type: "note", body: Note }) {
if (note.userHost !== null) return;
if (note.visibility !== "public") return;
// 関係ない返信は除外
@ -67,8 +67,6 @@ export default class extends Channel {
)
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -3,7 +3,7 @@ import {fetchMeta} from "@/misc/fetch-meta.js";
import {getWordHardMute} from "@/misc/check-word-mute.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import {isInstanceMuted} from "@/misc/is-instance-muted.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = true;
@ -13,7 +13,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -36,7 +36,7 @@ export default class extends Channel {
this.subscriber.off("notesStream", this.onNote);
}
private async onNote({ body: note }: { type: "note", body: Packed<"Note"> }) {
private async onNote({ body: note }: { type: "note", body: Note }) {
if (note.visibility === "hidden") return;
// チャンネルの投稿ではなく、自分自身の投稿 または
// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
@ -45,8 +45,8 @@ export default class extends Channel {
const meta = await fetchMeta();
if (
!(
note.user.host != null &&
meta.recommendedInstances.includes(note.user.host) &&
note.userHost != null &&
meta.recommendedInstances.includes(note.userHost) &&
note.visibility === "public"
)
)
@ -91,8 +91,6 @@ export default class extends Channel {
)
return;
this.connection.cacheNote(note);
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -2,7 +2,7 @@ import Channel from "../channel.js";
import {UserListJoinings, UserLists} from "@/models/index.js";
import type {User} from "@/models/entities/user.js";
import {isUserRelated} from "@/misc/is-user-related.js";
import type {Packed} from "@/misc/schema.js";
import {Note} from "@/models/entities/note";
export default class extends Channel {
public static shouldShare = false;
@ -15,7 +15,7 @@ export default class extends Channel {
constructor(id: string, connection: Channel["connection"]) {
super(id, connection);
this.updateListUsers = this.updateListUsers.bind(this);
this.onNote = this.withPackedNote(this.onNote.bind(this));
this.onNote = this.onNote.bind(this);
}
public async init(params: any) {
@ -56,7 +56,7 @@ export default class extends Channel {
this.listUsers = users.map((x) => x.userId);
}
private async onNote({ body: note }: { type: "note", body: Packed<"Note"> }) {
private async onNote({ body: note }: { type: "note", body: Note }) {
if (note.visibility === "hidden") return;
if (!this.listUsers.includes(note.userId)) return;
@ -67,6 +67,6 @@ export default class extends Channel {
if (note.renote && !note.text && this.renoteMuting.has(note.userId)) return;
this.send("note", note);
this.send("note", note.id);
}
}

View File

@ -4,7 +4,6 @@ import type {User} from "@/models/entities/user.js";
import {Blockings, Followings, Mutings, RenoteMutings, UserProfiles,} from "@/models/index.js";
import type {AccessToken} from "@/models/entities/access-token.js";
import type {UserProfile} from "@/models/entities/user-profile.js";
import type {Packed} from "@/misc/schema.js";
import {readNotification} from "../common/read-notification.js";
import channels from "./channels/index.js";
import type Channel from "./channel.js";
@ -25,7 +24,6 @@ export default class Connection {
private wsConnection: websocket.connection;
private channels: Channel[] = [];
private subscribingNotes: Map<string, number> = new Map();
private cachedNotes: Packed<"Note">[] = [];
private host: string;
private accessToken: string;
private currentSubscribe: string[][] = [];
@ -76,25 +74,6 @@ export default class Connection {
}
}
public cacheNote(note: Packed<"Note">) {
const add = (note: Packed<"Note">) => {
const existIndex = this.cachedNotes.findIndex((n) => n.id === note.id);
if (existIndex > -1) {
this.cachedNotes[existIndex] = note;
return;
}
this.cachedNotes.unshift(note);
if (this.cachedNotes.length > 32) {
this.cachedNotes.splice(32);
}
};
add(note);
if (note.reply) add(note.reply);
if (note.renote) add(note.renote);
}
/**
*
*/

View File

@ -64,9 +64,9 @@ export interface UserStreamTypes {
export interface MainStreamTypes {
notification: Packed<"Notification">;
mention: Packed<"Note">;
reply: Packed<"Note">;
renote: Packed<"Note">;
mention: Note;
reply: Note;
renote: Note;
follow: Packed<"UserDetailedNotMe">;
followed: Packed<"User">;
unfollow: Packed<"User">;

View File

@ -54,6 +54,7 @@ import {getActiveWebhooks} from "@/misc/webhook-cache.js";
import {shouldSilenceInstance} from "@/misc/should-block-instance.js";
import meilisearch from "../../db/meilisearch.js";
import {redisClient} from "@/db/redis.js";
import {getNote} from "@/server/api/common/getters.js";
const mutedWordsCache = new Cache<
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
@ -466,10 +467,12 @@ export default async (
webhooks.filter((x) => x.userId === user.id && x.on.includes("note")),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "note", {
note: await Notes.pack(note, user),
});
if (await Notes.isVisibleForMe(note, user.id)) {
for (const webhook of webhooks) {
webhookDeliver(webhook, "note", {
note,
});
}
}
const nm = new NotificationManager(user, note);
@ -492,19 +495,21 @@ export default async (
if (!threadMuted) {
nm.push(data.reply.userId, "reply");
const packedReply = await Notes.pack(note, {
id: data.reply.userId,
});
publishMainStream(data.reply.userId, "reply", packedReply);
if (data.reply.userId) {
getNote(note.id, { id: data.reply.userId }).then(async (reply) => {
publishMainStream(data.reply!.userId, "reply", reply);
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === data.reply!.userId && x.on.includes("reply"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "reply", {
note: packedReply,
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === data.reply!.userId && x.on.includes("reply"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "reply", {
note: reply,
});
}
});
}
}
}
}
@ -531,18 +536,18 @@ export default async (
// Publish event
if (user.id !== data.renote.userId && data.renote.userHost === null) {
const packedRenote = await Notes.pack(note, {
id: data.renote.userId,
});
publishMainStream(data.renote.userId, "renote", packedRenote);
if (data.renote.userId) {
getNote(note.id, { id: data.renote.userId }).then(async (renote) => {
publishMainStream(data.renote!.userId, "renote", renote);
const renote = data.renote;
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === renote.userId && x.on.includes("renote"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "renote", {
note: packedRenote,
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === renote.renoteUserId && x.on.includes("renote"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "renote", {
note: renote,
});
}
});
}
}
@ -585,7 +590,7 @@ export default async (
}
dm.execute();
})();
})().then();
}
//#endregion
}
@ -823,20 +828,19 @@ async function createMentionedEvents(
// note with "specified" visibility might not be visible to mentioned users
try {
const detailPackedNote = await Notes.pack(note, u, {
detail: true,
});
await getNote(note.id, { id: u.id }).then(async (note) => {
publishMainStream(u.id, "mention", note);
publishMainStream(u.id, "mention", detailPackedNote);
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === u.id && x.on.includes("mention"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "mention", {
note,
});
}
})
const webhooks = (await getActiveWebhooks()).filter(
(x) => x.userId === u.id && x.on.includes("mention"),
);
for (const webhook of webhooks) {
webhookDeliver(webhook, "mention", {
note: detailPackedNote,
});
}
} catch (err) {
if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") continue;
throw err;

View File

@ -6,14 +6,13 @@ import {In} from "typeorm";
import {checkHitAntenna} from "@/misc/check-hit-antenna.js";
import {getAntennas} from "@/misc/antenna-cache.js";
import {readNotificationByQuery} from "@/server/api/common/read-notification.js";
import type {Packed} from "@/misc/schema.js";
/**
* Mark notes as read
*/
export default async function (
userId: User["id"],
notes: (Note | Packed<"Note">)[],
notes: Note[],
info?: {
following: Set<User["id"]>;
},
@ -32,9 +31,9 @@ export default async function (
);
const myAntennas = (await getAntennas()).filter((a) => a.userId === userId);
const readMentions: (Note | Packed<"Note">)[] = [];
const readSpecifiedNotes: (Note | Packed<"Note">)[] = [];
const readAntennaNotes: (Note | Packed<"Note">)[] = [];
const readMentions: Note[] = [];
const readSpecifiedNotes: Note[] = [];
const readAntennaNotes: Note[] = [];
for (const note of notes) {
if (note.mentions?.includes(userId)) {

View File

@ -1,9 +1,9 @@
import push from "web-push";
import config from "@/config/index.js";
import { SwSubscriptions } from "@/models/index.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import type { Packed } from "@/misc/schema.js";
import { getNoteSummary } from "@/misc/get-note-summary.js";
import {SwSubscriptions} from "@/models/index.js";
import {fetchMeta} from "@/misc/fetch-meta.js";
import type {Packed} from "@/misc/schema.js";
import {getNoteSummary} from "@/misc/get-note-summary.js";
// Defined also packages/sw/types.ts#L14-L21
type pushNotificationsTypes = {
@ -22,7 +22,7 @@ function truncateNotification(notification: Packed<"Notification">): any {
// textをgetNoteSummaryしたものに置き換える
text: getNoteSummary(
notification.type === "renote"
? (notification.note.renote as Packed<"Note">)
? (notification.note.renote)
: notification.note,
),

View File

@ -280,8 +280,8 @@ importers:
specifier: 3.4.1
version: 3.4.1
re2:
specifier: 1.19.0
version: 1.19.0
specifier: 1.20.9
version: 1.20.9
redis-lock:
specifier: 0.1.4
version: 0.1.4
@ -1146,6 +1146,19 @@ packages:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
/@npmcli/agent@2.2.0:
resolution: {integrity: sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q==}
engines: {node: ^16.14.0 || >=18.0.0}
dependencies:
agent-base: 7.1.0
http-proxy-agent: 7.0.0
https-proxy-agent: 7.0.2
lru-cache: 10.1.0
socks-proxy-agent: 8.0.2
transitivePeerDependencies:
- supports-color
dev: false
/@npmcli/fs@3.1.0:
resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@ -2069,6 +2082,11 @@ packages:
/abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
/abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dev: false
/abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@ -2129,13 +2147,11 @@ packages:
- supports-color
dev: false
/agentkeepalive@4.3.0:
resolution: {integrity: sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==}
engines: {node: '>= 8.0.0'}
/agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
dependencies:
debug: 4.3.4
depd: 2.0.0
humanize-ms: 1.2.1
transitivePeerDependencies:
- supports-color
dev: false
@ -2264,14 +2280,6 @@ packages:
readable-stream: 3.6.2
dev: false
/are-we-there-yet@3.0.1:
resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
dev: false
/arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@ -2582,16 +2590,16 @@ packages:
engines: {node: '>= 0.8'}
dev: false
/cacache@17.1.3:
resolution: {integrity: sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
/cacache@18.0.1:
resolution: {integrity: sha512-g4Uf2CFZPaxtJKre6qr4zqLDOOPU7bNVhWjlNhvzc51xaTOx2noMOLhfFkTAqwtrAZAKQUuDfyjitzilpA8WsQ==}
engines: {node: ^16.14.0 || >=18.0.0}
dependencies:
'@npmcli/fs': 3.1.0
fs-minipass: 3.0.2
glob: 10.2.7
lru-cache: 7.18.3
minipass: 5.0.0
minipass-collect: 1.0.2
glob: 10.3.10
lru-cache: 10.1.0
minipass: 7.0.4
minipass-collect: 2.0.1
minipass-flush: 1.0.5
minipass-pipeline: 1.2.4
p-map: 4.0.0
@ -4089,20 +4097,6 @@ packages:
wide-align: 1.1.5
dev: false
/gauge@4.0.4:
resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
dev: false
/generic-pool@3.9.0:
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
engines: {node: '>= 4'}
@ -4180,16 +4174,16 @@ packages:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
dev: true
/glob@10.2.7:
resolution: {integrity: sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==}
/glob@10.3.10:
resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
dependencies:
foreground-child: 3.1.1
jackspeak: 2.2.1
jackspeak: 2.3.6
minimatch: 9.0.1
minipass: 5.0.0
path-scurry: 1.9.2
path-scurry: 1.10.1
dev: false
/glob@7.2.3:
@ -4386,6 +4380,16 @@ packages:
- supports-color
dev: false
/http-proxy-agent@7.0.0:
resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/http2-wrapper@1.0.3:
resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
engines: {node: '>=10.19.0'}
@ -4419,6 +4423,16 @@ packages:
- supports-color
dev: false
/https-proxy-agent@7.0.2:
resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
@ -4429,12 +4443,6 @@ packages:
engines: {node: '>=12.20.0'}
dev: true
/humanize-ms@1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
dependencies:
ms: 2.1.3
dev: false
/humanize-number@0.0.2:
resolution: {integrity: sha512-un3ZAcNQGI7RzaWGZzQDH47HETM4Wrj6z6E4TId8Yeq9w5ZKUVB1nrT2jwFheTUjEmqcgTjXDc959jum+ai1kQ==}
dev: false
@ -4504,8 +4512,8 @@ packages:
/ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
/install-artifact-from-github@1.3.3:
resolution: {integrity: sha512-x79SL0d8WOi1ZjXSTUqqs0GPQZ92YArJAN9O46wgU9wdH2U9ecyyhB9YGDbPe2OLV4ptmt6AZYRQZ2GydQZosQ==}
/install-artifact-from-github@1.3.5:
resolution: {integrity: sha512-gZHC7f/cJgXz7MXlHFBxPVMsvIbev1OQN1uKQYKVJDydGNm9oYf9JstbU4Atnh/eSvk41WtEovoRm+8IF686xg==}
hasBin: true
dev: false
@ -4709,8 +4717,13 @@ packages:
/isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
/jackspeak@2.2.1:
resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==}
/isexe@3.1.1:
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
engines: {node: '>=16'}
dev: false
/jackspeak@2.3.6:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
dependencies:
'@isaacs/cliui': 8.0.2
@ -5274,6 +5287,11 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/lru-cache@10.1.0:
resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==}
engines: {node: 14 || >=16.14}
dev: false
/lru-cache@4.1.5:
resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
dependencies:
@ -5292,11 +5310,6 @@ packages:
dependencies:
yallist: 4.0.0
/lru-cache@7.18.3:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
engines: {node: '>=12'}
dev: false
/lru-cache@9.1.2:
resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==}
engines: {node: 14 || >=16.14}
@ -5321,24 +5334,20 @@ packages:
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
/make-fetch-happen@11.1.1:
resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
/make-fetch-happen@13.0.0:
resolution: {integrity: sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==}
engines: {node: ^16.14.0 || >=18.0.0}
dependencies:
agentkeepalive: 4.3.0
cacache: 17.1.3
'@npmcli/agent': 2.2.0
cacache: 18.0.1
http-cache-semantics: 4.1.1
http-proxy-agent: 5.0.0
https-proxy-agent: 5.0.1
is-lambda: 1.0.1
lru-cache: 7.18.3
minipass: 5.0.0
minipass: 7.0.4
minipass-fetch: 3.0.3
minipass-flush: 1.0.5
minipass-pipeline: 1.2.4
negotiator: 0.6.3
promise-retry: 2.0.1
socks-proxy-agent: 7.0.0
ssri: 10.0.4
transitivePeerDependencies:
- supports-color
@ -5448,11 +5457,11 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
/minipass-collect@1.0.2:
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
engines: {node: '>= 8'}
/minipass-collect@2.0.1:
resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
minipass: 3.3.6
minipass: 7.0.4
dev: false
/minipass-fetch@3.0.3:
@ -5499,6 +5508,11 @@ packages:
engines: {node: '>=8'}
dev: false
/minipass@7.0.4:
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
engines: {node: '>=16 || 14 >=14.17'}
dev: false
/minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
@ -5588,8 +5602,8 @@ packages:
object-assign: 4.1.1
thenify-all: 1.6.0
/nan@2.17.0:
resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==}
/nan@2.18.0:
resolution: {integrity: sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==}
dev: false
/nanoid@3.3.6:
@ -5689,22 +5703,21 @@ packages:
hasBin: true
dev: false
/node-gyp@9.4.0:
resolution: {integrity: sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==}
engines: {node: ^12.13 || ^14.13 || >=16}
/node-gyp@10.0.1:
resolution: {integrity: sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==}
engines: {node: ^16.14.0 || >=18.0.0}
hasBin: true
dependencies:
env-paths: 2.2.1
exponential-backoff: 3.1.1
glob: 7.2.3
glob: 10.3.10
graceful-fs: 4.2.11
make-fetch-happen: 11.1.1
nopt: 6.0.0
npmlog: 6.0.2
rimraf: 3.0.2
make-fetch-happen: 13.0.0
nopt: 7.2.0
proc-log: 3.0.0
semver: 7.5.1
tar: 6.1.15
which: 2.0.2
which: 4.0.0
transitivePeerDependencies:
- supports-color
dev: false
@ -5736,6 +5749,14 @@ packages:
dependencies:
abbrev: 1.1.1
/nopt@7.2.0:
resolution: {integrity: sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
hasBin: true
dependencies:
abbrev: 2.0.0
dev: false
/normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@ -5780,16 +5801,6 @@ packages:
set-blocking: 2.0.0
dev: false
/npmlog@6.0.2:
resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
are-we-there-yet: 3.0.1
console-control-strings: 1.1.0
gauge: 4.0.4
set-blocking: 2.0.0
dev: false
/nwsapi@2.2.5:
resolution: {integrity: sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==}
dev: false
@ -6011,8 +6022,8 @@ packages:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: false
/path-scurry@1.9.2:
resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==}
/path-scurry@1.10.1:
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
lru-cache: 9.1.2
@ -6214,6 +6225,11 @@ packages:
- supports-color
dev: false
/proc-log@3.0.0:
resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
dev: false
/process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: false
@ -6363,13 +6379,13 @@ packages:
setimmediate: 1.0.5
dev: false
/re2@1.19.0:
resolution: {integrity: sha512-y0LcLZgBF3L7mDtNfbghb7dCmChYQO2QsUGklNueAJUH+HAZO8UZUubgNsf6OxRTAQpeE4KMPR7vcpK3+Q+GiA==}
/re2@1.20.9:
resolution: {integrity: sha512-ZYcPTFr5ha2xq3WQjBDTF9CWPSDK1z28MLh5UFRxc//7X8BNQ3A7yR7ITnP0jO346661ertdKVFqw1qoL3FMEQ==}
requiresBuild: true
dependencies:
install-artifact-from-github: 1.3.3
nan: 2.17.0
node-gyp: 9.4.0
install-artifact-from-github: 1.3.5
nan: 2.18.0
node-gyp: 10.0.1
transitivePeerDependencies:
- supports-color
dev: false
@ -6764,11 +6780,11 @@ packages:
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
dev: false
/socks-proxy-agent@7.0.0:
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
engines: {node: '>= 10'}
/socks-proxy-agent@8.0.2:
resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==}
engines: {node: '>= 14'}
dependencies:
agent-base: 6.0.2
agent-base: 7.1.0
debug: 4.3.4
socks: 2.7.1
transitivePeerDependencies:
@ -7787,6 +7803,14 @@ packages:
dependencies:
isexe: 2.0.0
/which@4.0.0:
resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
engines: {node: ^16.13.0 || >=18.0.0}
hasBin: true
dependencies:
isexe: 3.1.1
dev: false
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies: