mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
fix(api): 🐛 Fix favourited attribute not being correct on serialized API notes
This commit is contained in:
parent
5fcbcd0f07
commit
3c3814a3c1
|
|
@ -38,9 +38,7 @@ import type { Application } from "./Application";
|
||||||
import { attachmentFromLysand } from "./Attachment";
|
import { attachmentFromLysand } from "./Attachment";
|
||||||
import { type EmojiWithInstance, fetchEmoji } from "./Emoji";
|
import { type EmojiWithInstance, fetchEmoji } from "./Emoji";
|
||||||
import { objectToInboxRequest } from "./Federation";
|
import { objectToInboxRequest } from "./Federation";
|
||||||
import type { Like } from "./Like";
|
|
||||||
import {
|
import {
|
||||||
type UserType,
|
|
||||||
type UserWithInstance,
|
type UserWithInstance,
|
||||||
type UserWithRelations,
|
type UserWithRelations,
|
||||||
resolveWebFinger,
|
resolveWebFinger,
|
||||||
|
|
@ -57,7 +55,6 @@ export type StatusWithRelations = Status & {
|
||||||
attachments: InferSelectModel<typeof Attachments>[];
|
attachments: InferSelectModel<typeof Attachments>[];
|
||||||
reblog: StatusWithoutRecursiveRelations | null;
|
reblog: StatusWithoutRecursiveRelations | null;
|
||||||
emojis: EmojiWithInstance[];
|
emojis: EmojiWithInstance[];
|
||||||
likes: Like[];
|
|
||||||
reply: Status | null;
|
reply: Status | null;
|
||||||
quote: Status | null;
|
quote: Status | null;
|
||||||
application: Application | null;
|
application: Application | null;
|
||||||
|
|
@ -71,21 +68,6 @@ export type StatusWithoutRecursiveRelations = Omit<
|
||||||
"reply" | "quote" | "reblog"
|
"reply" | "quote" | "reblog"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export const noteExtras = {
|
|
||||||
reblogCount:
|
|
||||||
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."reblogId" = "Notes".id)`.as(
|
|
||||||
"reblog_count",
|
|
||||||
),
|
|
||||||
likeCount:
|
|
||||||
sql`(SELECT COUNT(*) FROM "Likes" WHERE "Likes"."likedId" = "Notes".id)`.as(
|
|
||||||
"like_count",
|
|
||||||
),
|
|
||||||
replyCount:
|
|
||||||
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."replyId" = "Notes".id)`.as(
|
|
||||||
"reply_count",
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper against the Status object to make it easier to work with
|
* Wrapper against the Status object to make it easier to work with
|
||||||
* @param query
|
* @param query
|
||||||
|
|
@ -98,10 +80,7 @@ export const findManyNotes = async (
|
||||||
...query,
|
...query,
|
||||||
with: {
|
with: {
|
||||||
...query?.with,
|
...query?.with,
|
||||||
attachments: {
|
attachments: true,
|
||||||
where: (attachment, { eq }) =>
|
|
||||||
eq(attachment.noteId, sql`"Notes"."id"`),
|
|
||||||
},
|
|
||||||
emojis: {
|
emojis: {
|
||||||
with: {
|
with: {
|
||||||
emoji: {
|
emoji: {
|
||||||
|
|
@ -158,14 +137,36 @@ export const findManyNotes = async (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extras: {
|
extras: {
|
||||||
...noteExtras,
|
reblogCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."reblogId" = "Notes_reblog".id)`.as(
|
||||||
|
"reblog_count",
|
||||||
|
),
|
||||||
|
likeCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Likes" WHERE "Likes"."likedId" = "Notes_reblog".id)`.as(
|
||||||
|
"like_count",
|
||||||
|
),
|
||||||
|
replyCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."replyId" = "Notes_reblog".id)`.as(
|
||||||
|
"reply_count",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
reply: true,
|
reply: true,
|
||||||
quote: true,
|
quote: true,
|
||||||
},
|
},
|
||||||
extras: {
|
extras: {
|
||||||
...noteExtras,
|
reblogCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."reblogId" = "Notes".id)`.as(
|
||||||
|
"reblog_count",
|
||||||
|
),
|
||||||
|
likeCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Likes" WHERE "Likes"."likedId" = "Notes".id)`.as(
|
||||||
|
"like_count",
|
||||||
|
),
|
||||||
|
replyCount:
|
||||||
|
sql`(SELECT COUNT(*) FROM "Notes" WHERE "Notes"."replyId" = "Notes".id)`.as(
|
||||||
|
"reply_count",
|
||||||
|
),
|
||||||
...query?.extras,
|
...query?.extras,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -196,113 +197,6 @@ export const findManyNotes = async (
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findFirstNote = async (
|
|
||||||
query: Parameters<typeof db.query.Notes.findFirst>[0],
|
|
||||||
): Promise<StatusWithRelations | null> => {
|
|
||||||
const output = await db.query.Notes.findFirst({
|
|
||||||
...query,
|
|
||||||
with: {
|
|
||||||
...query?.with,
|
|
||||||
attachments: {
|
|
||||||
where: (attachment, { eq }) =>
|
|
||||||
eq(attachment.noteId, sql`"Notes"."id"`),
|
|
||||||
},
|
|
||||||
emojis: {
|
|
||||||
with: {
|
|
||||||
emoji: {
|
|
||||||
with: {
|
|
||||||
instance: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
author: {
|
|
||||||
with: {
|
|
||||||
...userRelations,
|
|
||||||
},
|
|
||||||
extras: userExtrasTemplate("Notes_author"),
|
|
||||||
},
|
|
||||||
mentions: {
|
|
||||||
with: {
|
|
||||||
user: {
|
|
||||||
with: {
|
|
||||||
instance: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
reblog: {
|
|
||||||
with: {
|
|
||||||
attachments: true,
|
|
||||||
emojis: {
|
|
||||||
with: {
|
|
||||||
emoji: {
|
|
||||||
with: {
|
|
||||||
instance: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
likes: true,
|
|
||||||
application: true,
|
|
||||||
mentions: {
|
|
||||||
with: {
|
|
||||||
user: {
|
|
||||||
with: userRelations,
|
|
||||||
extras: userExtrasTemplate(
|
|
||||||
"Notes_reblog_mentions_user",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
author: {
|
|
||||||
with: {
|
|
||||||
...userRelations,
|
|
||||||
},
|
|
||||||
extras: userExtrasTemplate("Notes_reblog_author"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extras: {
|
|
||||||
...noteExtras,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
reply: true,
|
|
||||||
quote: true,
|
|
||||||
},
|
|
||||||
extras: {
|
|
||||||
...noteExtras,
|
|
||||||
...query?.extras,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!output) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...output,
|
|
||||||
author: transformOutputToUserWithRelations(output.author),
|
|
||||||
mentions: output.mentions.map((mention) => ({
|
|
||||||
...mention.user,
|
|
||||||
endpoints: mention.user.endpoints,
|
|
||||||
})),
|
|
||||||
emojis: (output.emojis ?? []).map((emoji) => emoji.emoji),
|
|
||||||
reblog: output.reblog && {
|
|
||||||
...output.reblog,
|
|
||||||
author: transformOutputToUserWithRelations(output.reblog.author),
|
|
||||||
mentions: output.reblog.mentions.map((mention) => ({
|
|
||||||
...mention.user,
|
|
||||||
endpoints: mention.user.endpoints,
|
|
||||||
})),
|
|
||||||
emojis: (output.reblog.emojis ?? []).map((emoji) => emoji.emoji),
|
|
||||||
reblogCount: Number(output.reblog.reblogCount),
|
|
||||||
likeCount: Number(output.reblog.likeCount),
|
|
||||||
replyCount: Number(output.reblog.replyCount),
|
|
||||||
},
|
|
||||||
reblogCount: Number(output.reblogCount),
|
|
||||||
likeCount: Number(output.likeCount),
|
|
||||||
replyCount: Number(output.replyCount),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const resolveNote = async (
|
export const resolveNote = async (
|
||||||
uri?: string,
|
uri?: string,
|
||||||
providedNote?: Lysand.Note,
|
providedNote?: Lysand.Note,
|
||||||
|
|
|
||||||
280
package.json
280
package.json
|
|
@ -1,143 +1,143 @@
|
||||||
{
|
{
|
||||||
"name": "lysand",
|
"name": "lysand",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"description": "A project to build a federated social network",
|
"description": "A project to build a federated social network",
|
||||||
"author": {
|
"author": {
|
||||||
"email": "contact@cpluspatch.com",
|
"email": "contact@cpluspatch.com",
|
||||||
"name": "CPlusPatch",
|
"name": "CPlusPatch",
|
||||||
"url": "https://cpluspatch.com"
|
"url": "https://cpluspatch.com"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/lysand-org/lysand/issues"
|
"url": "https://github.com/lysand-org/lysand/issues"
|
||||||
},
|
},
|
||||||
"icon": "https://github.com/lysand-org/lysand",
|
"icon": "https://github.com/lysand-org/lysand",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"keywords": ["federated", "activitypub", "bun"],
|
"keywords": ["federated", "activitypub", "bun"],
|
||||||
"workspaces": ["packages/*"],
|
"workspaces": ["packages/*"],
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
{
|
{
|
||||||
"email": "contact@cpluspatch.com",
|
"email": "contact@cpluspatch.com",
|
||||||
"name": "CPlusPatch",
|
"name": "CPlusPatch",
|
||||||
"url": "https://cpluspatch.com"
|
"url": "https://cpluspatch.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/lysand-org/lysand.git"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "bun run --hot index.ts",
|
||||||
|
"start": "NODE_ENV=production bun run dist/index.js --prod",
|
||||||
|
"lint": "bunx @biomejs/biome check .",
|
||||||
|
"build": "bun run build.ts",
|
||||||
|
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs,glitch,glitch-dev --exclude-ext sql,log,pem",
|
||||||
|
"wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-",
|
||||||
|
"cli": "bun run cli/index.ts",
|
||||||
|
"prune": "ts-prune | grep -v server/ | grep -v dist/ | grep -v '(used in module)'"
|
||||||
|
},
|
||||||
|
"trustedDependencies": [
|
||||||
|
"@biomejs/biome",
|
||||||
|
"@fortawesome/fontawesome-common-types",
|
||||||
|
"@fortawesome/free-regular-svg-icons",
|
||||||
|
"@fortawesome/free-solid-svg-icons",
|
||||||
|
"es5-ext",
|
||||||
|
"esbuild",
|
||||||
|
"json-editor-vue",
|
||||||
|
"msgpackr-extract",
|
||||||
|
"nuxt-app",
|
||||||
|
"sharp",
|
||||||
|
"vue-demi"
|
||||||
|
],
|
||||||
|
"oclif": {
|
||||||
|
"bin": "cli",
|
||||||
|
"dirname": "cli",
|
||||||
|
"commands": {
|
||||||
|
"strategy": "explicit",
|
||||||
|
"target": "./cli/index",
|
||||||
|
"identifier": "commands"
|
||||||
|
},
|
||||||
|
"additionalHelpFlags": ["-h"],
|
||||||
|
"additionalVersionFlags": ["-v"],
|
||||||
|
"plugins": [],
|
||||||
|
"description": "CLI to interface with the Lysand project",
|
||||||
|
"topicSeparator": " ",
|
||||||
|
"topics": {
|
||||||
|
"user": {
|
||||||
|
"description": "Manage users"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"theme": "./cli/theme.json",
|
||||||
|
"flexibleTaxonomy": true
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "^1.7.0",
|
||||||
|
"@types/cli-progress": "^3.11.5",
|
||||||
|
"@types/cli-table": "^0.3.4",
|
||||||
|
"@types/html-to-text": "^9.0.4",
|
||||||
|
"@types/ioredis": "^5.0.0",
|
||||||
|
"@types/jsonld": "^1.5.13",
|
||||||
|
"@types/markdown-it-container": "^2.0.10",
|
||||||
|
"@types/mime-types": "^2.1.4",
|
||||||
|
"@types/pg": "^8.11.5",
|
||||||
|
"@types/qs": "^6.9.15",
|
||||||
|
"bun-types": "latest",
|
||||||
|
"drizzle-kit": "^0.20.14",
|
||||||
|
"oclif": "^4.10.4",
|
||||||
|
"ts-prune": "^0.10.3",
|
||||||
|
"typescript": "latest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@inquirer/confirm": "^3.1.6",
|
||||||
|
"@inquirer/input": "^2.1.6",
|
||||||
|
"@oclif/core": "^3.26.6",
|
||||||
|
"cli-progress": "^3.12.0",
|
||||||
|
"ora": "^8.0.1",
|
||||||
|
"table": "^6.8.2",
|
||||||
|
"uqr": "^0.1.2",
|
||||||
|
"@hackmd/markdown-it-task-lists": "^2.1.4",
|
||||||
|
"@hono/zod-validator": "^0.2.1",
|
||||||
|
"@json2csv/plainjs": "^7.0.6",
|
||||||
|
"@tufjs/canonical-json": "^2.0.0",
|
||||||
|
"blurhash": "^2.0.5",
|
||||||
|
"bullmq": "^5.7.1",
|
||||||
|
"chalk": "^5.3.0",
|
||||||
|
"cli-parser": "workspace:*",
|
||||||
|
"cli-table": "^0.3.11",
|
||||||
|
"config-manager": "workspace:*",
|
||||||
|
"drizzle-orm": "^0.30.7",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"hono": "^4.3.2",
|
||||||
|
"html-to-text": "^9.0.5",
|
||||||
|
"ioredis": "^5.3.2",
|
||||||
|
"ip-matching": "^2.1.2",
|
||||||
|
"iso-639-1": "^3.1.0",
|
||||||
|
"jose": "^5.2.4",
|
||||||
|
"linkify-html": "^4.1.3",
|
||||||
|
"linkify-string": "^4.1.3",
|
||||||
|
"linkifyjs": "^4.1.3",
|
||||||
|
"log-manager": "workspace:*",
|
||||||
|
"magic-regexp": "^0.8.0",
|
||||||
|
"markdown-it": "^14.1.0",
|
||||||
|
"markdown-it-anchor": "^8.6.7",
|
||||||
|
"markdown-it-container": "^4.0.0",
|
||||||
|
"markdown-it-toc-done-right": "^4.2.0",
|
||||||
|
"media-manager": "workspace:*",
|
||||||
|
"meilisearch": "^0.39.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"oauth4webapi": "^2.4.0",
|
||||||
|
"pg": "^8.11.5",
|
||||||
|
"qs": "^6.12.1",
|
||||||
|
"sharp": "^0.33.3",
|
||||||
|
"string-comparison": "^1.3.0",
|
||||||
|
"stringify-entities": "^4.0.4",
|
||||||
|
"xss": "^1.0.15",
|
||||||
|
"zod": "^3.22.4",
|
||||||
|
"zod-validation-error": "^3.2.0"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/lysand-org/lysand.git"
|
|
||||||
},
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "bun run --hot index.ts",
|
|
||||||
"start": "NODE_ENV=production bun run dist/index.js --prod",
|
|
||||||
"lint": "bunx @biomejs/biome check .",
|
|
||||||
"build": "bun run build.ts",
|
|
||||||
"cloc": "cloc . --exclude-dir node_modules,dist,.output,.nuxt,meta,logs,glitch,glitch-dev --exclude-ext sql,log,pem",
|
|
||||||
"wc": "find server database *.ts docs packages types utils drizzle tests -type f -print0 | wc -m --files0-from=-",
|
|
||||||
"cli": "bun run cli/index.ts",
|
|
||||||
"prune": "ts-prune | grep -v server/ | grep -v dist/ | grep -v '(used in module)'"
|
|
||||||
},
|
|
||||||
"trustedDependencies": [
|
|
||||||
"@biomejs/biome",
|
|
||||||
"@fortawesome/fontawesome-common-types",
|
|
||||||
"@fortawesome/free-regular-svg-icons",
|
|
||||||
"@fortawesome/free-solid-svg-icons",
|
|
||||||
"es5-ext",
|
|
||||||
"esbuild",
|
|
||||||
"json-editor-vue",
|
|
||||||
"msgpackr-extract",
|
|
||||||
"nuxt-app",
|
|
||||||
"sharp",
|
|
||||||
"vue-demi"
|
|
||||||
],
|
|
||||||
"oclif": {
|
|
||||||
"bin": "cli",
|
|
||||||
"dirname": "cli",
|
|
||||||
"commands": {
|
|
||||||
"strategy": "explicit",
|
|
||||||
"target": "./cli/index",
|
|
||||||
"identifier": "commands"
|
|
||||||
},
|
|
||||||
"additionalHelpFlags": ["-h"],
|
|
||||||
"additionalVersionFlags": ["-v"],
|
|
||||||
"plugins": [],
|
|
||||||
"description": "CLI to interface with the Lysand project",
|
|
||||||
"topicSeparator": " ",
|
|
||||||
"topics": {
|
|
||||||
"user": {
|
|
||||||
"description": "Manage users"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"theme": "./cli/theme.json",
|
|
||||||
"flexibleTaxonomy": true
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@biomejs/biome": "^1.7.0",
|
|
||||||
"@types/cli-progress": "^3.11.5",
|
|
||||||
"@types/cli-table": "^0.3.4",
|
|
||||||
"@types/html-to-text": "^9.0.4",
|
|
||||||
"@types/ioredis": "^5.0.0",
|
|
||||||
"@types/jsonld": "^1.5.13",
|
|
||||||
"@types/markdown-it-container": "^2.0.10",
|
|
||||||
"@types/mime-types": "^2.1.4",
|
|
||||||
"@types/pg": "^8.11.5",
|
|
||||||
"@types/qs": "^6.9.15",
|
|
||||||
"bun-types": "latest",
|
|
||||||
"drizzle-kit": "^0.20.14",
|
|
||||||
"oclif": "^4.10.4",
|
|
||||||
"ts-prune": "^0.10.3",
|
|
||||||
"typescript": "latest"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "^5.3.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/confirm": "^3.1.6",
|
|
||||||
"@inquirer/input": "^2.1.6",
|
|
||||||
"@oclif/core": "^3.26.6",
|
|
||||||
"cli-progress": "^3.12.0",
|
|
||||||
"ora": "^8.0.1",
|
|
||||||
"table": "^6.8.2",
|
|
||||||
"uqr": "^0.1.2",
|
|
||||||
"@hackmd/markdown-it-task-lists": "^2.1.4",
|
|
||||||
"@hono/zod-validator": "^0.2.1",
|
|
||||||
"@json2csv/plainjs": "^7.0.6",
|
|
||||||
"@tufjs/canonical-json": "^2.0.0",
|
|
||||||
"blurhash": "^2.0.5",
|
|
||||||
"bullmq": "^5.7.1",
|
|
||||||
"chalk": "^5.3.0",
|
|
||||||
"cli-parser": "workspace:*",
|
|
||||||
"cli-table": "^0.3.11",
|
|
||||||
"config-manager": "workspace:*",
|
|
||||||
"drizzle-orm": "^0.30.7",
|
|
||||||
"extract-zip": "^2.0.1",
|
|
||||||
"hono": "^4.3.2",
|
|
||||||
"html-to-text": "^9.0.5",
|
|
||||||
"ioredis": "^5.3.2",
|
|
||||||
"ip-matching": "^2.1.2",
|
|
||||||
"iso-639-1": "^3.1.0",
|
|
||||||
"jose": "^5.2.4",
|
|
||||||
"linkify-html": "^4.1.3",
|
|
||||||
"linkify-string": "^4.1.3",
|
|
||||||
"linkifyjs": "^4.1.3",
|
|
||||||
"log-manager": "workspace:*",
|
|
||||||
"magic-regexp": "^0.8.0",
|
|
||||||
"markdown-it": "^14.1.0",
|
|
||||||
"markdown-it-anchor": "^8.6.7",
|
|
||||||
"markdown-it-container": "^4.0.0",
|
|
||||||
"markdown-it-toc-done-right": "^4.2.0",
|
|
||||||
"media-manager": "workspace:*",
|
|
||||||
"meilisearch": "^0.39.0",
|
|
||||||
"mime-types": "^2.1.35",
|
|
||||||
"oauth4webapi": "^2.4.0",
|
|
||||||
"pg": "^8.11.5",
|
|
||||||
"qs": "^6.12.1",
|
|
||||||
"sharp": "^0.33.3",
|
|
||||||
"string-comparison": "^1.3.0",
|
|
||||||
"stringify-entities": "^4.0.4",
|
|
||||||
"xss": "^1.0.15",
|
|
||||||
"zod": "^3.22.4",
|
|
||||||
"zod-validation-error": "^3.2.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import {
|
||||||
type Status,
|
type Status,
|
||||||
type StatusWithRelations,
|
type StatusWithRelations,
|
||||||
contentToHtml,
|
contentToHtml,
|
||||||
findFirstNote,
|
|
||||||
findManyNotes,
|
findManyNotes,
|
||||||
} from "~database/entities/Status";
|
} from "~database/entities/Status";
|
||||||
import { db } from "~drizzle/db";
|
import { db } from "~drizzle/db";
|
||||||
|
|
@ -69,13 +68,14 @@ export class Note {
|
||||||
sql: SQL<unknown> | undefined,
|
sql: SQL<unknown> | undefined,
|
||||||
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
orderBy: SQL<unknown> | undefined = desc(Notes.id),
|
||||||
) {
|
) {
|
||||||
const found = await findFirstNote({
|
const found = await findManyNotes({
|
||||||
where: sql,
|
where: sql,
|
||||||
orderBy,
|
orderBy,
|
||||||
|
limit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!found) return null;
|
if (!found[0]) return null;
|
||||||
return new Note(found);
|
return new Note(found[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async manyFromSql(
|
static async manyFromSql(
|
||||||
|
|
@ -413,35 +413,47 @@ export class Note {
|
||||||
|
|
||||||
async toAPI(userFetching?: User | null): Promise<APIStatus> {
|
async toAPI(userFetching?: User | null): Promise<APIStatus> {
|
||||||
const data = this.getStatus();
|
const data = this.getStatus();
|
||||||
const wasPinnedByUser = userFetching
|
|
||||||
? !!(await db.query.UserToPinnedNotes.findFirst({
|
|
||||||
where: (relation, { and, eq }) =>
|
|
||||||
and(
|
|
||||||
eq(relation.noteId, data.id),
|
|
||||||
eq(relation.userId, userFetching?.id),
|
|
||||||
),
|
|
||||||
}))
|
|
||||||
: false;
|
|
||||||
|
|
||||||
const wasRebloggedByUser = userFetching
|
const [pinnedByUser, rebloggedByUser, mutedByUser, likedByUser] = (
|
||||||
? !!(await Note.fromSql(
|
await Promise.all([
|
||||||
and(
|
userFetching
|
||||||
eq(Notes.authorId, userFetching?.id),
|
? db.query.UserToPinnedNotes.findFirst({
|
||||||
eq(Notes.reblogId, data.id),
|
where: (relation, { and, eq }) =>
|
||||||
),
|
and(
|
||||||
))
|
eq(relation.noteId, data.id),
|
||||||
: false;
|
eq(relation.userId, userFetching?.id),
|
||||||
|
),
|
||||||
const wasMutedByUser = userFetching
|
})
|
||||||
? !!(await db.query.Relationships.findFirst({
|
: false,
|
||||||
where: (relationship, { and, eq }) =>
|
userFetching
|
||||||
and(
|
? Note.fromSql(
|
||||||
eq(relationship.ownerId, userFetching.id),
|
and(
|
||||||
eq(relationship.subjectId, data.authorId),
|
eq(Notes.authorId, userFetching?.id),
|
||||||
eq(relationship.muting, true),
|
eq(Notes.reblogId, data.id),
|
||||||
),
|
),
|
||||||
}))
|
)
|
||||||
: false;
|
: false,
|
||||||
|
userFetching
|
||||||
|
? db.query.Relationships.findFirst({
|
||||||
|
where: (relationship, { and, eq }) =>
|
||||||
|
and(
|
||||||
|
eq(relationship.ownerId, userFetching.id),
|
||||||
|
eq(relationship.subjectId, data.authorId),
|
||||||
|
eq(relationship.muting, true),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
: false,
|
||||||
|
userFetching
|
||||||
|
? db.query.Likes.findFirst({
|
||||||
|
where: (like, { and, eq }) =>
|
||||||
|
and(
|
||||||
|
eq(like.likedId, data.id),
|
||||||
|
eq(like.likerId, userFetching.id),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
: false,
|
||||||
|
])
|
||||||
|
).map((r) => !!r);
|
||||||
|
|
||||||
// Convert mentions of local users from @username@host to @username
|
// Convert mentions of local users from @username@host to @username
|
||||||
const mentionedLocalUsers = data.mentions.filter(
|
const mentionedLocalUsers = data.mentions.filter(
|
||||||
|
|
@ -476,10 +488,7 @@ export class Note {
|
||||||
card: null,
|
card: null,
|
||||||
content: replacedContent,
|
content: replacedContent,
|
||||||
emojis: data.emojis.map((emoji) => emojiToAPI(emoji)),
|
emojis: data.emojis.map((emoji) => emojiToAPI(emoji)),
|
||||||
// FIXME: data.likes is always empty
|
favourited: likedByUser,
|
||||||
favourited: !!(data.likes ?? []).find(
|
|
||||||
(like) => like.likerId === userFetching?.id,
|
|
||||||
),
|
|
||||||
favourites_count: data.likeCount,
|
favourites_count: data.likeCount,
|
||||||
media_attachments: (data.attachments ?? []).map(
|
media_attachments: (data.attachments ?? []).map(
|
||||||
(a) => attachmentToAPI(a) as APIAttachment,
|
(a) => attachmentToAPI(a) as APIAttachment,
|
||||||
|
|
@ -495,8 +504,8 @@ export class Note {
|
||||||
username: mention.username,
|
username: mention.username,
|
||||||
})),
|
})),
|
||||||
language: null,
|
language: null,
|
||||||
muted: wasMutedByUser,
|
muted: mutedByUser,
|
||||||
pinned: wasPinnedByUser,
|
pinned: pinnedByUser,
|
||||||
// TODO: Add polls
|
// TODO: Add polls
|
||||||
poll: null,
|
poll: null,
|
||||||
reblog: data.reblog
|
reblog: data.reblog
|
||||||
|
|
@ -504,7 +513,7 @@ export class Note {
|
||||||
data.reblog as StatusWithRelations,
|
data.reblog as StatusWithRelations,
|
||||||
).toAPI(userFetching)
|
).toAPI(userFetching)
|
||||||
: null,
|
: null,
|
||||||
reblogged: wasRebloggedByUser,
|
reblogged: rebloggedByUser,
|
||||||
reblogs_count: data.reblogCount,
|
reblogs_count: data.reblogCount,
|
||||||
replies_count: data.replyCount,
|
replies_count: data.replyCount,
|
||||||
sensitive: data.sensitive,
|
sensitive: data.sensitive,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue