refactor: move misc/acct.ts to native-utils

This commit is contained in:
naskya 2024-01-13 20:56:10 +09:00
parent 821b85f0e0
commit 7c93e1a91a
Signed by: naskya
GPG key ID: 712D413B3A9FED5C
17 changed files with 75 additions and 47 deletions

View file

@ -266,6 +266,8 @@ if (!nativeBinding) {
}
const {
stringToAcct,
acctToString,
nativeRandomStr,
IdConvertType,
convertId,
@ -274,6 +276,8 @@ const {
nativeInitIdGenerator,
} = nativeBinding;
module.exports.stringToAcct = stringToAcct;
module.exports.acctToString = acctToString;
module.exports.nativeRandomStr = nativeRandomStr;
module.exports.IdConvertType = IdConvertType;
module.exports.convertId = convertId;

View file

@ -32,7 +32,7 @@ tokio = { version = "1.35.1", features = ["full"] }
utoipa = "4.1.0"
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.14.1", default-features = false, features = ["napi6", "tokio_rt"], optional = true }
napi = { version = "2.14.1", default-features = false, features = ["napi9", "tokio_rt"], optional = true }
napi-derive = { version = "2.14.5", optional = true }
basen = "0.1.0"

View file

@ -0,0 +1,36 @@
use napi_derive::napi;
#[derive(Clone, Eq, PartialEq, Debug)]
#[napi(object)]
pub struct Acct {
pub username: String,
pub host: Option<String>,
}
#[napi]
pub fn string_to_acct(acct: String) -> Acct {
let split: Vec<&str> = if let Some(stripped) = acct.strip_prefix('@') {
stripped
} else {
&acct
}
.split('@')
.collect();
Acct {
username: split[0].to_string(),
host: if split.len() == 1 {
None
} else {
Some(split[1].to_string())
},
}
}
#[napi]
pub fn acct_to_string(acct: Acct) -> String {
match acct.host {
Some(host) => format!("{}@{}", acct.username, host),
None => acct.username,
}
}

View file

@ -1,2 +1,3 @@
pub mod acct;
pub mod id;
pub mod random;

View file

@ -1,14 +0,0 @@
export type Acct = {
username: string;
host: string | null;
};
export function parse(acct: string): Acct {
if (acct.startsWith("@")) acct = acct.slice(1);
const split = acct.split("@", 2);
return { username: split[0], host: split[1] || null };
}
export function toString(acct: Acct): string {
return acct.host == null ? acct.username : `${acct.username}@${acct.host}`;
}

View file

@ -3,7 +3,7 @@ import type { Note } from "@/models/entities/note.js";
import type { User } from "@/models/entities/user.js";
import { Blockings, Followings, UserProfiles } from "@/models/index.js";
import { getFullApAccount } from "@/misc/convert-host.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import type { Packed } from "@/misc/schema.js";
import { Cache } from "@/misc/cache.js";
import { getWordHardMute } from "@/misc/check-word-mute.js";
@ -25,8 +25,8 @@ export async function checkHitAntenna(
if (antenna.src === "users") {
const accts = antenna.users.map((x) => {
const { username, host } = Acct.parse(x);
return getFullApAccount(username, host).toLowerCase();
const { username, host } = stringToAcct(x);
return getFullApAccount(username, host ?? null).toLowerCase();
});
if (
!accts.includes(

View file

@ -1,7 +1,7 @@
import type Bull from "bull";
import { queueLogger } from "../../logger.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { resolveUser } from "@/remote/resolve-user.js";
import { downloadTextFile } from "@/misc/download-text-file.js";
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
@ -41,7 +41,7 @@ export async function importBlocking(
try {
const acct = line.split(",")[0].trim();
const { username, host } = Acct.parse(acct);
const { username, host } = stringToAcct(acct);
let target = isSelfHost(host!)
? await Users.findOneBy({

View file

@ -1,7 +1,7 @@
import { IsNull } from "typeorm";
import follow from "@/services/following/create.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { resolveUser } from "@/remote/resolve-user.js";
import { downloadTextFile } from "@/misc/download-text-file.js";
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
@ -39,7 +39,7 @@ export async function importFollowing(
if (file.type.endsWith("json")) {
for (const acct of JSON.parse(csv)) {
try {
const { username, host } = Acct.parse(acct);
const { username, host } = stringToAcct(acct);
let target = isSelfHost(host!)
? await Users.findOneBy({
@ -77,7 +77,7 @@ export async function importFollowing(
try {
const acct = line.split(",")[0].trim();
const { username, host } = Acct.parse(acct);
const { username, host } = stringToAcct(acct);
let target = isSelfHost(host!)
? await Users.findOneBy({

View file

@ -1,7 +1,7 @@
import type Bull from "bull";
import { queueLogger } from "../../logger.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { resolveUser } from "@/remote/resolve-user.js";
import { downloadTextFile } from "@/misc/download-text-file.js";
import { isSelfHost, toPuny } from "@/misc/convert-host.js";
@ -42,7 +42,7 @@ export async function importMuting(
try {
const acct = line.split(",")[0].trim();
const { username, host } = Acct.parse(acct);
const { username, host } = stringToAcct(acct);
let target = isSelfHost(host!)
? await Users.findOneBy({

View file

@ -1,7 +1,7 @@
import type Bull from "bull";
import { queueLogger } from "../../logger.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { resolveUser } from "@/remote/resolve-user.js";
import { pushUserToUserList } from "@/services/user-list/push.js";
import { downloadTextFile } from "@/misc/download-text-file.js";
@ -47,7 +47,7 @@ export async function importUserLists(
try {
const listName = line.split(",")[0].trim();
const { username, host } = Acct.parse(line.split(",")[1].trim());
const { username, host } = stringToAcct(line.split(",")[1].trim());
let list = await UserLists.findOneBy({
userId: user.id,

View file

@ -8,7 +8,7 @@ import { DAY } from "@/const.js";
import { apiLogger } from "@/server/api/logger.js";
import define from "@/server/api/define.js";
import { ApiError } from "@/server/api/error.js";
import { parse } from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
export const meta = {
tags: ["users"],
@ -71,9 +71,9 @@ export default define(meta, paramDef, async (ps, user) => {
for (const line of ps.alsoKnownAs) {
if (!line) throw new ApiError(meta.errors.noSuchUser);
const { username, host } = parse(line);
const { username, host } = stringToAcct(line);
const aka = await resolveUser(username, host).catch((e) => {
const aka = await resolveUser(username, host ?? null).catch((e) => {
apiLogger.warn(`failed to resolve remote user: ${e}`);
throw new ApiError(meta.errors.noSuchUser);
});

View file

@ -12,7 +12,7 @@ import { getUser } from "@/server/api/common/getters.js";
import { Followings, Users } from "@/models/index.js";
import config from "@/config/index.js";
import { publishMainStream } from "@/services/stream.js";
import { parse } from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
export const meta = {
tags: ["users"],
@ -89,10 +89,10 @@ export default define(meta, paramDef, async (ps, user) => {
if (!ps.moveToAccount) throw new ApiError(meta.errors.noSuchMoveTarget);
if (user.movedToUri) throw new ApiError(meta.errors.alreadyMoved);
const { username, host } = parse(ps.moveToAccount);
const { username, host } = stringToAcct(ps.moveToAccount);
if (!host) throw new ApiError(meta.errors.notRemote);
const moveTo: User = await resolveUser(username, host).catch((e) => {
const moveTo: User = await resolveUser(username, host ?? null).catch((e) => {
apiLogger.warn(`failed to resolve remote user: ${e}`);
throw new ApiError(meta.errors.noSuchMoveTarget);
});

View file

@ -1,7 +1,7 @@
import { IsNull } from "typeorm";
import { Users } from "@/models/index.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import type { User } from "@/models/entities/user.js";
import define from "@/server/api/define.js";
@ -35,7 +35,7 @@ export default define(meta, paramDef, async (ps, me) => {
const users = await Promise.all(
meta.pinnedUsers
.map((acct) => Acct.parse(acct))
.map((acct) => stringToAcct(acct))
.map((acct) =>
Users.findOneBy({
usernameLower: acct.username.toLowerCase(),

View file

@ -19,7 +19,7 @@ import { Users } from "@/models/index.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import { genIdenticon } from "@/misc/gen-identicon.js";
import { createTemp } from "@/misc/create-temp.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { envOption } from "@/env.js";
import megalodon, { MegalodonInterface } from "megalodon";
import activityPub from "./activitypub.js";
@ -107,7 +107,7 @@ router.use(nodeinfo.routes());
router.use(wellKnown.routes());
router.get("/avatar/@:acct", async (ctx) => {
const { username, host } = Acct.parse(ctx.params.acct);
const { username, host } = stringToAcct(ctx.params.acct);
const user = await Users.findOne({
where: {
usernameLower: username.toLowerCase(),

View file

@ -28,7 +28,7 @@ import {
Emojis,
GalleryPosts,
} from "@/models/index.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import { getNoteSummary } from "@/misc/get-note-summary.js";
import { queues } from "@/queue/queues.js";
import { genOpenapiSpec } from "../api/openapi/gen-spec.js";
@ -328,7 +328,7 @@ const getFeed = async (
if (meta.privateMode) {
return;
}
const { username, host } = Acct.parse(acct);
const { username, host } = stringToAcct(acct);
const user = await Users.findOneBy({
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),
@ -459,7 +459,7 @@ const jsonFeed: Router.Middleware = async (ctx) => {
const userPage: Router.Middleware = async (ctx, next) => {
const userParam = ctx.params.user;
const subParam = ctx.params.sub;
const { username, host } = Acct.parse(userParam);
const { username, host } = stringToAcct(userParam);
const user = await Users.findOneBy({
usernameLower: username.toLowerCase(),
@ -578,7 +578,7 @@ router.get("/posts/:note", async (ctx, next) => {
// Page
router.get("/@:user/pages/:page", async (ctx, next) => {
const { username, host } = Acct.parse(ctx.params.user);
const { username, host } = stringToAcct(ctx.params.user);
const user = await Users.findOneBy({
usernameLower: username.toLowerCase(),
host: host ?? IsNull(),

View file

@ -1,7 +1,8 @@
import Router from "@koa/router";
import config from "@/config/index.js";
import * as Acct from "@/misc/acct.js";
import { stringToAcct } from "native-utils/built/index.js";
import type { Acct } from "native-utils/built/index.js";
import { links } from "./nodeinfo.js";
import { escapeAttribute, escapeValue } from "@/prelude/xml.js";
import { Users } from "@/models/index.js";
@ -110,7 +111,7 @@ router.get(webFingerPath, async (ctx) => {
resource.startsWith(`${config.url.toLowerCase()}/users/`)
? fromId(resource.split("/").pop()!)
: fromAcct(
Acct.parse(
stringToAcct(
resource.startsWith(`${config.url.toLowerCase()}/@`)
? resource.split("/").pop()!
: resource.startsWith("acct:")
@ -119,7 +120,7 @@ router.get(webFingerPath, async (ctx) => {
),
);
const fromAcct = (acct: Acct.Acct): FindOptionsWhere<User> | number =>
const fromAcct = (acct: Acct): FindOptionsWhere<User> | number =>
!acct.host || acct.host === config.host.toLowerCase()
? {
usernameLower: acct.username,

View file

@ -2,7 +2,7 @@
import type { User } from "@/models/entities/user.js";
// import { sendEmail } from "./send-email.js";
// import { I18n } from "@/misc/i18n.js";
// import * as Acct from "@/misc/acct.js";
// import { acctToString } from "native-utils/built/index.js";
// TODO
//const locales = await import('../../../../locales/index.js');
@ -15,7 +15,7 @@ async function follow(userId: User["id"], follower: User) {
const locale = locales[userProfile.lang || 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${acctToString(follower)})`, `${follower.name} (@${acctToString(follower)})`);
*/
}
@ -26,7 +26,7 @@ async function receiveFollowRequest(userId: User["id"], follower: User) {
const locale = locales[userProfile.lang || 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${acctToString(follower)})`, `${follower.name} (@${acctToString(follower)})`);
*/
}