Fixed 267U.pre2

This commit is contained in:
2026-07-26 18:25:37 +09:00
parent 50bfaeafdf
commit 317d00a284
1286 changed files with 80222 additions and 1 deletions
@@ -0,0 +1,49 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
},
aliases: {
type: "array",
items: {
type: "string"
}
}
},
required: [
"ids",
"aliases"
]
};
export default define(meta, paramDef, async (ps)=>{
const emojis = await Emojis.findBy({
id: In(ps.ids)
});
for (const emoji of emojis){
await Emojis.update(emoji.id, {
updatedAt: new Date(),
aliases: [
...new Set(emoji.aliases.concat(ps.aliases))
]
});
}
await db.queryResultCache.remove([
"meta_emojis"
]);
});
@@ -0,0 +1,70 @@
import define from "../../../define.js";
import { Emojis, DriveFiles } from "../../../../../models/index.js";
import { genId } from "../../../../../misc/gen-id.js";
import { insertModerationLog } from "../../../../../services/insert-moderation-log.js";
import { ApiError } from "../../../error.js";
import rndstr from "rndstr";
import { publishBroadcastStream } from "../../../../../services/stream.js";
import { db } from "../../../../../db/postgre.js";
import { getEmojiSize } from "../../../../../misc/emoji-meta.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
errors: {
noSuchFile: {
message: "No such file.",
code: "MO_SUCH_FILE",
id: "fc46b5a4-6b92-4c33-ac66-b806659bb5cf"
}
}
};
export const paramDef = {
type: "object",
properties: {
fileId: {
type: "string",
format: "misskey:id"
}
},
required: [
"fileId"
]
};
export default define(meta, paramDef, async (ps, me)=>{
const file = await DriveFiles.findOneBy({
id: ps.fileId
});
if (file == null) throw new ApiError(meta.errors.noSuchFile);
const name = file.name.split(".")[0].match(/^[a-z0-9_]+$/) ? file.name.split(".")[0] : `_${rndstr("a-z0-9", 8)}_`;
const size = await getEmojiSize(file.url);
const emoji = await Emojis.insert({
id: genId(),
updatedAt: new Date(),
name: name,
category: null,
host: null,
aliases: [],
originalUrl: file.url,
publicUrl: file.webpublicUrl ?? file.url,
type: file.webpublicType ?? file.type,
license: null,
glyph: file.type === "image/svg+xml",
width: size.width || null,
height: size.height || null
}).then((x)=>Emojis.findOneByOrFail(x.identifiers[0]));
await db.queryResultCache.remove([
"meta_emojis"
]);
publishBroadcastStream("emojiAdded", {
emoji: await Emojis.pack(emoji.id)
});
insertModerationLog(me, "addEmoji", {
emojiId: emoji.id
});
return {
id: emoji.id
};
});
@@ -0,0 +1,90 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { genId } from "../../../../../misc/gen-id.js";
import { ApiError } from "../../../error.js";
import { uploadFromUrl } from "../../../../../services/drive/upload-from-url.js";
import { publishBroadcastStream } from "../../../../../services/stream.js";
import { db } from "../../../../../db/postgre.js";
import { getEmojiSize } from "../../../../../misc/emoji-meta.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
errors: {
noSuchEmoji: {
message: "No such emoji.",
code: "NO_SUCH_EMOJI",
id: "e2785b66-dca3-4087-9cac-b93c541cc425"
}
},
res: {
type: "object",
optional: false,
nullable: false,
properties: {
id: {
type: "string",
optional: false,
nullable: false,
format: "id"
}
}
}
};
export const paramDef = {
type: "object",
properties: {
emojiId: {
type: "string",
format: "misskey:id"
}
},
required: [
"emojiId"
]
};
export default define(meta, paramDef, async (ps, me)=>{
const emoji = await Emojis.findOneBy({
id: ps.emojiId
});
if (emoji == null) {
throw new ApiError(meta.errors.noSuchEmoji);
}
let driveFile;
try {
// Create file
driveFile = await uploadFromUrl({
url: emoji.originalUrl,
user: null,
force: true
});
} catch (e) {
throw new ApiError();
}
const size = await getEmojiSize(driveFile.url);
const copied = await Emojis.insert({
id: genId(),
updatedAt: new Date(),
name: emoji.name,
host: null,
aliases: [],
originalUrl: driveFile.url,
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
type: driveFile.webpublicType ?? driveFile.type,
license: emoji.license,
glyph: emoji.glyph,
width: size.width || null,
height: size.height || null
}).then((x)=>Emojis.findOneByOrFail(x.identifiers[0]));
await db.queryResultCache.remove([
"meta_emojis"
]);
publishBroadcastStream("emojiAdded", {
emoji: await Emojis.pack(copied.id)
});
return {
id: copied.id
};
});
@@ -0,0 +1,41 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { insertModerationLog } from "../../../../../services/insert-moderation-log.js";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
}
},
required: [
"ids"
]
};
export default define(meta, paramDef, async (ps, me)=>{
const emojis = await Emojis.findBy({
id: In(ps.ids)
});
for (const emoji of emojis){
await Emojis.delete(emoji.id);
await db.queryResultCache.remove([
"meta_emojis"
]);
insertModerationLog(me, "deleteEmoji", {
emoji: emoji
});
}
});
@@ -0,0 +1,44 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { insertModerationLog } from "../../../../../services/insert-moderation-log.js";
import { ApiError } from "../../../error.js";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
errors: {
noSuchEmoji: {
message: "No such emoji.",
code: "NO_SUCH_EMOJI",
id: "be83669b-773a-44b7-b1f8-e5e5170ac3c2"
}
}
};
export const paramDef = {
type: "object",
properties: {
id: {
type: "string",
format: "misskey:id"
}
},
required: [
"id"
]
};
export default define(meta, paramDef, async (ps, me)=>{
const emoji = await Emojis.findOneBy({
id: ps.id
});
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
await Emojis.delete(emoji.id);
await db.queryResultCache.remove([
"meta_emojis"
]);
insertModerationLog(me, "deleteEmoji", {
emoji: emoji
});
});
@@ -0,0 +1,22 @@
import define from "../../../define.js";
import { createImportCustomEmojisJob } from "../../../../../queue/index.js";
export const meta = {
secure: true,
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
fileId: {
type: "string",
format: "misskey:id"
}
},
required: [
"fileId"
]
};
export default define(meta, paramDef, async (ps, user)=>{
createImportCustomEmojisJob(user, ps.fileId);
});
@@ -0,0 +1,134 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { toPuny } from "../../../../../misc/convert-host.js";
import { makePaginationQuery } from "../../../common/make-pagination-query.js";
import { sqlLikeEscape } from "../../../../../misc/sql-like-escape.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
res: {
type: "array",
optional: false,
nullable: false,
items: {
type: "object",
optional: false,
nullable: false,
properties: {
id: {
type: "string",
optional: false,
nullable: false,
format: "id"
},
aliases: {
type: "array",
optional: false,
nullable: false,
items: {
type: "string",
optional: false,
nullable: false
}
},
name: {
type: "string",
optional: false,
nullable: false
},
category: {
type: "string",
optional: false,
nullable: true
},
host: {
type: "string",
optional: false,
nullable: true,
description: "The local host is represented with `null`."
},
url: {
type: "string",
optional: false,
nullable: false
},
license: {
type: "string",
optional: false,
nullable: true
},
glyph: {
type: "boolean",
optional: false,
nullable: false
},
glyphUrl: {
type: "string",
optional: false,
nullable: true
},
width: {
type: "number",
optional: false,
nullable: true
},
height: {
type: "number",
optional: false,
nullable: true
}
}
}
}
};
export const paramDef = {
type: "object",
properties: {
query: {
type: "string",
nullable: true,
default: null
},
host: {
type: "string",
nullable: true,
default: null,
description: "Use `null` to represent the local host."
},
limit: {
type: "integer",
minimum: 1,
maximum: 100,
default: 10
},
sinceId: {
type: "string",
format: "misskey:id"
},
untilId: {
type: "string",
format: "misskey:id"
}
},
required: []
};
export default define(meta, paramDef, async (ps)=>{
const q = makePaginationQuery(Emojis.createQueryBuilder("emoji"), ps.sinceId, ps.untilId);
if (ps.host == null) {
q.andWhere("emoji.host IS NOT NULL");
} else {
q.andWhere("emoji.host = :host", {
host: toPuny(ps.host)
});
}
if (ps.query) {
q.andWhere("emoji.name like :query", {
query: `%${sqlLikeEscape(ps.query)}%`
});
}
const emojis = await q.orderBy("emoji.id", "DESC").take(ps.limit).getMany();
return Emojis.packMany(emojis);
});
@@ -0,0 +1,123 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { makePaginationQuery } from "../../../common/make-pagination-query.js";
//import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
res: {
type: "array",
optional: false,
nullable: false,
items: {
type: "object",
optional: false,
nullable: false,
properties: {
id: {
type: "string",
optional: false,
nullable: false,
format: "id"
},
aliases: {
type: "array",
optional: false,
nullable: false,
items: {
type: "string",
optional: false,
nullable: false
}
},
name: {
type: "string",
optional: false,
nullable: false
},
category: {
type: "string",
optional: false,
nullable: true
},
host: {
type: "null",
optional: false,
description: "The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files."
},
url: {
type: "string",
optional: false,
nullable: false
},
license: {
type: "string",
optional: false,
nullable: true
},
glyph: {
type: "boolean",
optional: false,
nullable: false
},
glyphUrl: {
type: "string",
optional: false,
nullable: true
},
width: {
type: "number",
optional: false,
nullable: true
},
height: {
type: "number",
optional: false,
nullable: true
}
}
}
}
};
export const paramDef = {
type: "object",
properties: {
query: {
type: "string",
nullable: true,
default: null
},
limit: {
type: "integer",
minimum: 1,
maximum: 100,
default: 10
},
sinceId: {
type: "string",
format: "misskey:id"
},
untilId: {
type: "string",
format: "misskey:id"
}
},
required: []
};
export default define(meta, paramDef, async (ps)=>{
const q = makePaginationQuery(Emojis.createQueryBuilder("emoji"), ps.sinceId, ps.untilId).andWhere("emoji.host IS NULL");
let emojis;
if (ps.query) {
//q.andWhere('emoji.name ILIKE :q', { q: `%${sqlLikeEscape(ps.query)}%` });
//const emojis = await q.take(ps.limit).getMany();
emojis = await q.getMany();
emojis = emojis.filter((emoji)=>emoji.name.includes(ps.query) || emoji.aliases.some((a)=>a.includes(ps.query)) || emoji.category?.includes(ps.query));
emojis.splice(ps.limit + 1);
} else {
emojis = await q.take(ps.limit).getMany();
}
return Emojis.packMany(emojis);
});
@@ -0,0 +1,47 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
},
aliases: {
type: "array",
items: {
type: "string"
}
}
},
required: [
"ids",
"aliases"
]
};
export default define(meta, paramDef, async (ps)=>{
const emojis = await Emojis.findBy({
id: In(ps.ids)
});
for (const emoji of emojis){
await Emojis.update(emoji.id, {
updatedAt: new Date(),
aliases: emoji.aliases.filter((x)=>!ps.aliases.includes(x))
});
}
await db.queryResultCache.remove([
"meta_emojis"
]);
});
@@ -0,0 +1,44 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
},
aliases: {
type: "array",
items: {
type: "string"
}
}
},
required: [
"ids",
"aliases"
]
};
export default define(meta, paramDef, async (ps)=>{
await Emojis.update({
id: In(ps.ids)
}, {
updatedAt: new Date(),
aliases: ps.aliases
});
await db.queryResultCache.remove([
"meta_emojis"
]);
});
@@ -0,0 +1,42 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
},
category: {
type: "string",
nullable: true,
description: "Use `null` to reset the category."
}
},
required: [
"ids"
]
};
export default define(meta, paramDef, async (ps)=>{
await Emojis.update({
id: In(ps.ids)
}, {
updatedAt: new Date(),
category: ps.category
});
await db.queryResultCache.remove([
"meta_emojis"
]);
});
@@ -0,0 +1,42 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { In } from "typeorm";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true
};
export const paramDef = {
type: "object",
properties: {
ids: {
type: "array",
items: {
type: "string",
format: "misskey:id"
}
},
license: {
type: "string",
nullable: true,
description: "Use `null` to reset the license."
}
},
required: [
"ids"
]
};
export default define(meta, paramDef, async (ps)=>{
await Emojis.update({
id: In(ps.ids)
}, {
updatedAt: new Date(),
license: ps.license
});
await db.queryResultCache.remove([
"meta_emojis"
]);
});
@@ -0,0 +1,72 @@
import define from "../../../define.js";
import { Emojis } from "../../../../../models/index.js";
import { ApiError } from "../../../error.js";
import { db } from "../../../../../db/postgre.js";
export const meta = {
tags: [
"admin"
],
requireCredential: true,
requireModerator: true,
errors: {
noSuchEmoji: {
message: "No such emoji.",
code: "NO_SUCH_EMOJI",
id: "684dec9d-a8c2-4364-9aa8-456c49cb1dc8"
}
}
};
export const paramDef = {
type: "object",
properties: {
id: {
type: "string",
format: "misskey:id"
},
name: {
type: "string"
},
category: {
type: "string",
nullable: true,
description: "Use `null` to reset the category."
},
aliases: {
type: "array",
items: {
type: "string"
}
},
license: {
type: "string",
nullable: true
},
glyph: {
type: "boolean"
}
},
required: [
"id",
"name",
"aliases"
]
};
export default define(meta, paramDef, async (ps)=>{
const emoji = await Emojis.findOneBy({
id: ps.id
});
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
await Emojis.update(emoji.id, {
updatedAt: new Date(),
name: ps.name,
category: ps.category,
aliases: ps.aliases,
license: ps.license,
...typeof ps.glyph === "boolean" ? {
glyph: ps.glyph
} : {}
});
await db.queryResultCache.remove([
"meta_emojis"
]);
});