summaryrefslogtreecommitdiff
path: root/src/misc
diff options
context:
space:
mode:
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/acct.ts11
-rw-r--r--src/misc/antenna-cache.ts36
-rw-r--r--src/misc/api-permissions.ts35
-rw-r--r--src/misc/app-lock.ts31
-rw-r--r--src/misc/before-shutdown.ts92
-rw-r--r--src/misc/cache.ts43
-rw-r--r--src/misc/cafy-id.ts32
-rw-r--r--src/misc/captcha.ts56
-rw-r--r--src/misc/check-hit-antenna.ts90
-rw-r--r--src/misc/check-word-mute.ts39
-rw-r--r--src/misc/content-disposition.ts6
-rw-r--r--src/misc/convert-host.ts26
-rw-r--r--src/misc/count-same-renotes.ts15
-rw-r--r--src/misc/create-temp.ts10
-rw-r--r--src/misc/detect-url-mime.ts15
-rw-r--r--src/misc/download-text-file.ts25
-rw-r--r--src/misc/download-url.ts87
-rw-r--r--src/misc/emoji-regex.ts3
-rw-r--r--src/misc/emojilist.ts7
-rw-r--r--src/misc/extract-custom-emojis-from-mfm.ts10
-rw-r--r--src/misc/extract-hashtags.ts9
-rw-r--r--src/misc/extract-mentions.ts11
-rw-r--r--src/misc/extract-url-from-mfm.ts19
-rw-r--r--src/misc/fetch-meta.ts35
-rw-r--r--src/misc/fetch-proxy-account.ts9
-rw-r--r--src/misc/fetch.ts141
-rw-r--r--src/misc/format-time-string.ts50
-rw-r--r--src/misc/gen-avatar.ts90
-rw-r--r--src/misc/gen-id.ts21
-rw-r--r--src/misc/gen-key-pair.ts36
-rw-r--r--src/misc/get-file-info.ts196
-rw-r--r--src/misc/get-note-summary.ts52
-rw-r--r--src/misc/get-reaction-emoji.ts16
-rw-r--r--src/misc/get-user-name.ts5
-rw-r--r--src/misc/hard-limits.ts14
-rw-r--r--src/misc/i18n.ts29
-rw-r--r--src/misc/id/aid.ts25
-rw-r--r--src/misc/id/meid.ts26
-rw-r--r--src/misc/id/meidg.ts28
-rw-r--r--src/misc/id/object-id.ts26
-rw-r--r--src/misc/identifiable-error.ts13
-rw-r--r--src/misc/is-blocker-user-related.ts15
-rw-r--r--src/misc/is-duplicate-key-value-error.ts3
-rw-r--r--src/misc/is-muted-user-related.ts15
-rw-r--r--src/misc/is-quote.ts5
-rw-r--r--src/misc/keypair-store.ts10
-rw-r--r--src/misc/license.ts19
-rw-r--r--src/misc/normalize-for-search.ts6
-rw-r--r--src/misc/nyaize.ts15
-rw-r--r--src/misc/populate-emojis.ts124
-rw-r--r--src/misc/reaction-lib.ts129
-rw-r--r--src/misc/safe-for-sql.ts3
-rw-r--r--src/misc/schema.ts107
-rw-r--r--src/misc/secure-rndstr.ts21
-rw-r--r--src/misc/show-machine-info.ts13
-rw-r--r--src/misc/simple-schema.ts15
-rw-r--r--src/misc/truncate.ts11
-rw-r--r--src/misc/twemoji-base.ts1
58 files changed, 0 insertions, 2032 deletions
diff --git a/src/misc/acct.ts b/src/misc/acct.ts
deleted file mode 100644
index 5106b1a09e..0000000000
--- a/src/misc/acct.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import * as Misskey from 'misskey-js';
-
-export const getAcct = (user: Misskey.Acct) => {
- return user.host == null ? user.username : `${user.username}@${user.host}`;
-};
-
-export const parseAcct = (acct: string): Misskey.Acct => {
- if (acct.startsWith('@')) acct = acct.substr(1);
- const split = acct.split('@', 2);
- return { username: split[0], host: split[1] || null };
-};
diff --git a/src/misc/antenna-cache.ts b/src/misc/antenna-cache.ts
deleted file mode 100644
index a23eeb45ec..0000000000
--- a/src/misc/antenna-cache.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Antennas } from '@/models/index';
-import { Antenna } from '@/models/entities/antenna';
-import { subsdcriber } from '../db/redis';
-
-let antennasFetched = false;
-let antennas: Antenna[] = [];
-
-export async function getAntennas() {
- if (!antennasFetched) {
- antennas = await Antennas.find();
- antennasFetched = true;
- }
-
- return antennas;
-}
-
-subsdcriber.on('message', async (_, data) => {
- const obj = JSON.parse(data);
-
- if (obj.channel === 'internal') {
- const { type, body } = obj.message;
- switch (type) {
- case 'antennaCreated':
- antennas.push(body);
- break;
- case 'antennaUpdated':
- antennas[antennas.findIndex(a => a.id === body.id)] = body;
- break;
- case 'antennaDeleted':
- antennas = antennas.filter(a => a.id !== body.id);
- break;
- default:
- break;
- }
- }
-});
diff --git a/src/misc/api-permissions.ts b/src/misc/api-permissions.ts
deleted file mode 100644
index 160cdf9fd6..0000000000
--- a/src/misc/api-permissions.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-export const kinds = [
- 'read:account',
- 'write:account',
- 'read:blocks',
- 'write:blocks',
- 'read:drive',
- 'write:drive',
- 'read:favorites',
- 'write:favorites',
- 'read:following',
- 'write:following',
- 'read:messaging',
- 'write:messaging',
- 'read:mutes',
- 'write:mutes',
- 'write:notes',
- 'read:notifications',
- 'write:notifications',
- 'read:reactions',
- 'write:reactions',
- 'write:votes',
- 'read:pages',
- 'write:pages',
- 'write:page-likes',
- 'read:page-likes',
- 'read:user-groups',
- 'write:user-groups',
- 'read:channels',
- 'write:channels',
- 'read:gallery',
- 'write:gallery',
- 'read:gallery-likes',
- 'write:gallery-likes',
-];
-// IF YOU ADD KINDS(PERMISSIONS), YOU MUST ADD TRANSLATIONS (under _permissions).
diff --git a/src/misc/app-lock.ts b/src/misc/app-lock.ts
deleted file mode 100644
index a32b600612..0000000000
--- a/src/misc/app-lock.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { redisClient } from '../db/redis';
-import { promisify } from 'util';
-import * as redisLock from 'redis-lock';
-
-/**
- * Retry delay (ms) for lock acquisition
- */
-const retryDelay = 100;
-
-const lock: (key: string, timeout?: number) => Promise<() => void>
- = redisClient
- ? promisify(redisLock(redisClient, retryDelay))
- : async () => () => { };
-
-/**
- * Get AP Object lock
- * @param uri AP object ID
- * @param timeout Lock timeout (ms), The timeout releases previous lock.
- * @returns Unlock function
- */
-export function getApLock(uri: string, timeout = 30 * 1000) {
- return lock(`ap-object:${uri}`, timeout);
-}
-
-export function getFetchInstanceMetadataLock(host: string, timeout = 30 * 1000) {
- return lock(`instance:${host}`, timeout);
-}
-
-export function getChartInsertLock(lockKey: string, timeout = 30 * 1000) {
- return lock(`chart-insert:${lockKey}`, timeout);
-}
diff --git a/src/misc/before-shutdown.ts b/src/misc/before-shutdown.ts
deleted file mode 100644
index 33abf5fb4d..0000000000
--- a/src/misc/before-shutdown.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-// https://gist.github.com/nfantone/1eaa803772025df69d07f4dbf5df7e58
-
-'use strict';
-
-/**
- * @callback BeforeShutdownListener
- * @param {string} [signalOrEvent] The exit signal or event name received on the process.
- */
-
-/**
- * System signals the app will listen to initiate shutdown.
- * @const {string[]}
- */
-const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM'];
-
-/**
- * Time in milliseconds to wait before forcing shutdown.
- * @const {number}
- */
-const SHUTDOWN_TIMEOUT = 15000;
-
-/**
- * A queue of listener callbacks to execute before shutting
- * down the process.
- * @type {BeforeShutdownListener[]}
- */
-const shutdownListeners = [];
-
-/**
- * Listen for signals and execute given `fn` function once.
- * @param {string[]} signals System signals to listen to.
- * @param {function(string)} fn Function to execute on shutdown.
- */
-const processOnce = (signals, fn) => {
- for (const sig of signals) {
- process.once(sig, fn);
- }
-};
-
-/**
- * Sets a forced shutdown mechanism that will exit the process after `timeout` milliseconds.
- * @param {number} timeout Time to wait before forcing shutdown (milliseconds)
- */
-const forceExitAfter = timeout => () => {
- setTimeout(() => {
- // Force shutdown after timeout
- console.warn(`Could not close resources gracefully after ${timeout}ms: forcing shutdown`);
- return process.exit(1);
- }, timeout).unref();
-};
-
-/**
- * Main process shutdown handler. Will invoke every previously registered async shutdown listener
- * in the queue and exit with a code of `0`. Any `Promise` rejections from any listener will
- * be logged out as a warning, but won't prevent other callbacks from executing.
- * @param {string} signalOrEvent The exit signal or event name received on the process.
- */
-async function shutdownHandler(signalOrEvent) {
- if (process.env.NODE_ENV === 'test') return process.exit(0);
-
- console.warn(`Shutting down: received [${signalOrEvent}] signal`);
-
- for (const listener of shutdownListeners) {
- try {
- await listener(signalOrEvent);
- } catch (err) {
- console.warn(`A shutdown handler failed before completing with: ${err.message || err}`);
- }
- }
-
- return process.exit(0);
-}
-
-/**
- * Registers a new shutdown listener to be invoked before exiting
- * the main process. Listener handlers are guaranteed to be called in the order
- * they were registered.
- * @param {BeforeShutdownListener} listener The shutdown listener to register.
- * @returns {BeforeShutdownListener} Echoes back the supplied `listener`.
- */
-export function beforeShutdown(listener) {
- shutdownListeners.push(listener);
- return listener;
-}
-
-// Register shutdown callback that kills the process after `SHUTDOWN_TIMEOUT` milliseconds
-// This prevents custom shutdown handlers from hanging the process indefinitely
-processOnce(SHUTDOWN_SIGNALS, forceExitAfter(SHUTDOWN_TIMEOUT));
-
-// Register process shutdown callback
-// Will listen to incoming signal events and execute all registered handlers in the stack
-processOnce(SHUTDOWN_SIGNALS, shutdownHandler);
diff --git a/src/misc/cache.ts b/src/misc/cache.ts
deleted file mode 100644
index 71fbbd8a4c..0000000000
--- a/src/misc/cache.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-export class Cache<T> {
- private cache: Map<string | null, { date: number; value: T; }>;
- private lifetime: number;
-
- constructor(lifetime: Cache<never>['lifetime']) {
- this.cache = new Map();
- this.lifetime = lifetime;
- }
-
- public set(key: string | null, value: T): void {
- this.cache.set(key, {
- date: Date.now(),
- value
- });
- }
-
- public get(key: string | null): T | undefined {
- const cached = this.cache.get(key);
- if (cached == null) return undefined;
- if ((Date.now() - cached.date) > this.lifetime) {
- this.cache.delete(key);
- return undefined;
- }
- return cached.value;
- }
-
- public delete(key: string | null) {
- this.cache.delete(key);
- }
-
- public async fetch(key: string | null, fetcher: () => Promise<T>): Promise<T> {
- const cachedValue = this.get(key);
- if (cachedValue !== undefined) {
- // Cache HIT
- return cachedValue;
- }
-
- // Cache MISS
- const value = await fetcher();
- this.set(key, value);
- return value;
- }
-}
diff --git a/src/misc/cafy-id.ts b/src/misc/cafy-id.ts
deleted file mode 100644
index 39886611e1..0000000000
--- a/src/misc/cafy-id.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { Context } from 'cafy';
-
-export class ID<Maybe = string> extends Context<string | (Maybe extends {} ? string : Maybe)> {
- public readonly name = 'ID';
-
- constructor(optional = false, nullable = false) {
- super(optional, nullable);
-
- this.push((v: any) => {
- if (typeof v !== 'string') {
- return new Error('must-be-an-id');
- }
- return true;
- });
- }
-
- public getType() {
- return super.getType('String');
- }
-
- public makeOptional(): ID<undefined> {
- return new ID(true, false);
- }
-
- public makeNullable(): ID<null> {
- return new ID(false, true);
- }
-
- public makeOptionalNullable(): ID<undefined | null> {
- return new ID(true, true);
- }
-}
diff --git a/src/misc/captcha.ts b/src/misc/captcha.ts
deleted file mode 100644
index f36943b589..0000000000
--- a/src/misc/captcha.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import fetch from 'node-fetch';
-import { URLSearchParams } from 'url';
-import { getAgentByUrl } from './fetch';
-import config from '@/config/index';
-
-export async function verifyRecaptcha(secret: string, response: string) {
- const result = await getCaptchaResponse('https://www.recaptcha.net/recaptcha/api/siteverify', secret, response).catch(e => {
- throw `recaptcha-request-failed: ${e}`;
- });
-
- if (result.success !== true) {
- const errorCodes = result['error-codes'] ? result['error-codes']?.join(', ') : '';
- throw `recaptcha-failed: ${errorCodes}`;
- }
-}
-
-export async function verifyHcaptcha(secret: string, response: string) {
- const result = await getCaptchaResponse('https://hcaptcha.com/siteverify', secret, response).catch(e => {
- throw `hcaptcha-request-failed: ${e}`;
- });
-
- if (result.success !== true) {
- const errorCodes = result['error-codes'] ? result['error-codes']?.join(', ') : '';
- throw `hcaptcha-failed: ${errorCodes}`;
- }
-}
-
-type CaptchaResponse = {
- success: boolean;
- 'error-codes'?: string[];
-};
-
-async function getCaptchaResponse(url: string, secret: string, response: string): Promise<CaptchaResponse> {
- const params = new URLSearchParams({
- secret,
- response
- });
-
- const res = await fetch(url, {
- method: 'POST',
- body: params,
- headers: {
- 'User-Agent': config.userAgent
- },
- timeout: 10 * 1000,
- agent: getAgentByUrl
- }).catch(e => {
- throw `${e.message || e}`;
- });
-
- if (!res.ok) {
- throw `${res.status}`;
- }
-
- return await res.json() as CaptchaResponse;
-}
diff --git a/src/misc/check-hit-antenna.ts b/src/misc/check-hit-antenna.ts
deleted file mode 100644
index 3789054b26..0000000000
--- a/src/misc/check-hit-antenna.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { Antenna } from '@/models/entities/antenna';
-import { Note } from '@/models/entities/note';
-import { User } from '@/models/entities/user';
-import { UserListJoinings, UserGroupJoinings } from '@/models/index';
-import { getFullApAccount } from './convert-host';
-import { parseAcct } from '@/misc/acct';
-import { Packed } from './schema';
-
-/**
- * noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい
- */
-export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> {
- if (note.visibility === 'specified') return false;
-
- if (note.visibility === 'followers') {
- if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false;
- if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false;
- }
-
- if (!antenna.withReplies && note.replyId != null) return false;
-
- if (antenna.src === 'home') {
- if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false;
- if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false;
- } else if (antenna.src === 'list') {
- const listUsers = (await UserListJoinings.find({
- userListId: antenna.userListId!
- })).map(x => x.userId);
-
- if (!listUsers.includes(note.userId)) return false;
- } else if (antenna.src === 'group') {
- const joining = await UserGroupJoinings.findOneOrFail(antenna.userGroupJoiningId!);
-
- const groupUsers = (await UserGroupJoinings.find({
- userGroupId: joining.userGroupId
- })).map(x => x.userId);
-
- if (!groupUsers.includes(note.userId)) return false;
- } else if (antenna.src === 'users') {
- const accts = antenna.users.map(x => {
- const { username, host } = parseAcct(x);
- return getFullApAccount(username, host).toLowerCase();
- });
- if (!accts.includes(getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false;
- }
-
- const keywords = antenna.keywords
- // Clean up
- .map(xs => xs.filter(x => x !== ''))
- .filter(xs => xs.length > 0);
-
- if (keywords.length > 0) {
- if (note.text == null) return false;
-
- const matched = keywords.some(and =>
- and.every(keyword =>
- antenna.caseSensitive
- ? note.text!.includes(keyword)
- : note.text!.toLowerCase().includes(keyword.toLowerCase())
- ));
-
- if (!matched) return false;
- }
-
- const excludeKeywords = antenna.excludeKeywords
- // Clean up
- .map(xs => xs.filter(x => x !== ''))
- .filter(xs => xs.length > 0);
-
- if (excludeKeywords.length > 0) {
- if (note.text == null) return false;
-
- const matched = excludeKeywords.some(and =>
- and.every(keyword =>
- antenna.caseSensitive
- ? note.text!.includes(keyword)
- : note.text!.toLowerCase().includes(keyword.toLowerCase())
- ));
-
- if (matched) return false;
- }
-
- if (antenna.withFile) {
- if (note.fileIds && note.fileIds.length === 0) return false;
- }
-
- // TODO: eval expression
-
- return true;
-}
diff --git a/src/misc/check-word-mute.ts b/src/misc/check-word-mute.ts
deleted file mode 100644
index e2e871dd2b..0000000000
--- a/src/misc/check-word-mute.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-const RE2 = require('re2');
-import { Note } from '@/models/entities/note';
-import { User } from '@/models/entities/user';
-
-type NoteLike = {
- userId: Note['userId'];
- text: Note['text'];
-};
-
-type UserLike = {
- id: User['id'];
-};
-
-export async function checkWordMute(note: NoteLike, me: UserLike | null | undefined, mutedWords: string[][]): Promise<boolean> {
- // 自分自身
- if (me && (note.userId === me.id)) return false;
-
- const words = mutedWords
- // Clean up
- .map(xs => xs.filter(x => x !== ''))
- .filter(xs => xs.length > 0);
-
- if (words.length > 0) {
- if (note.text == null) return false;
-
- const matched = words.some(and =>
- and.every(keyword => {
- const regexp = keyword.match(/^\/(.+)\/(.*)$/);
- if (regexp) {
- return new RE2(regexp[1], regexp[2]).test(note.text!);
- }
- return note.text!.includes(keyword);
- }));
-
- if (matched) return true;
- }
-
- return false;
-}
diff --git a/src/misc/content-disposition.ts b/src/misc/content-disposition.ts
deleted file mode 100644
index 9df7ed4688..0000000000
--- a/src/misc/content-disposition.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-const cd = require('content-disposition');
-
-export function contentDisposition(type: 'inline' | 'attachment', filename: string): string {
- const fallback = filename.replace(/[^\w.-]/g, '_');
- return cd(filename, { type, fallback });
-}
diff --git a/src/misc/convert-host.ts b/src/misc/convert-host.ts
deleted file mode 100644
index 6e9f6ed3e9..0000000000
--- a/src/misc/convert-host.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { URL } from 'url';
-import config from '@/config/index';
-import { toASCII } from 'punycode/';
-
-export function getFullApAccount(username: string, host: string | null) {
- return host ? `${username}@${toPuny(host)}` : `${username}@${toPuny(config.host)}`;
-}
-
-export function isSelfHost(host: string) {
- if (host == null) return true;
- return toPuny(config.host) === toPuny(host);
-}
-
-export function extractDbHost(uri: string) {
- const url = new URL(uri);
- return toPuny(url.hostname);
-}
-
-export function toPuny(host: string) {
- return toASCII(host.toLowerCase());
-}
-
-export function toPunyNullable(host: string | null | undefined): string | null {
- if (host == null) return null;
- return toASCII(host.toLowerCase());
-}
diff --git a/src/misc/count-same-renotes.ts b/src/misc/count-same-renotes.ts
deleted file mode 100644
index 6628761182..0000000000
--- a/src/misc/count-same-renotes.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Notes } from '@/models/index';
-
-export async function countSameRenotes(userId: string, renoteId: string, excludeNoteId: string | undefined): Promise<number> {
- // 指定したユーザーの指定したノートのリノートがいくつあるか数える
- const query = Notes.createQueryBuilder('note')
- .where('note.userId = :userId', { userId })
- .andWhere('note.renoteId = :renoteId', { renoteId });
-
- // 指定した投稿を除く
- if (excludeNoteId) {
- query.andWhere('note.id != :excludeNoteId', { excludeNoteId });
- }
-
- return await query.getCount();
-}
diff --git a/src/misc/create-temp.ts b/src/misc/create-temp.ts
deleted file mode 100644
index 04604cf7d0..0000000000
--- a/src/misc/create-temp.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as tmp from 'tmp';
-
-export function createTemp(): Promise<[string, any]> {
- return new Promise<[string, any]>((res, rej) => {
- tmp.file((e, path, fd, cleanup) => {
- if (e) return rej(e);
- res([path, cleanup]);
- });
- });
-}
diff --git a/src/misc/detect-url-mime.ts b/src/misc/detect-url-mime.ts
deleted file mode 100644
index 274c291737..0000000000
--- a/src/misc/detect-url-mime.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { createTemp } from './create-temp';
-import { downloadUrl } from './download-url';
-import { detectType } from './get-file-info';
-
-export async function detectUrlMime(url: string) {
- const [path, cleanup] = await createTemp();
-
- try {
- await downloadUrl(url, path);
- const { mime } = await detectType(path);
- return mime;
- } finally {
- cleanup();
- }
-}
diff --git a/src/misc/download-text-file.ts b/src/misc/download-text-file.ts
deleted file mode 100644
index e8e23cc120..0000000000
--- a/src/misc/download-text-file.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as fs from 'fs';
-import * as util from 'util';
-import Logger from '@/services/logger';
-import { createTemp } from './create-temp';
-import { downloadUrl } from './download-url';
-
-const logger = new Logger('download-text-file');
-
-export async function downloadTextFile(url: string): Promise<string> {
- // Create temp file
- const [path, cleanup] = await createTemp();
-
- logger.info(`Temp file is ${path}`);
-
- try {
- // write content at URL to temp file
- await downloadUrl(url, path);
-
- const text = await util.promisify(fs.readFile)(path, 'utf8');
-
- return text;
- } finally {
- cleanup();
- }
-}
diff --git a/src/misc/download-url.ts b/src/misc/download-url.ts
deleted file mode 100644
index c96b4fd1d6..0000000000
--- a/src/misc/download-url.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import * as fs from 'fs';
-import * as stream from 'stream';
-import * as util from 'util';
-import got, * as Got from 'got';
-import { httpAgent, httpsAgent, StatusError } from './fetch';
-import config from '@/config/index';
-import * as chalk from 'chalk';
-import Logger from '@/services/logger';
-import * as IPCIDR from 'ip-cidr';
-const PrivateIp = require('private-ip');
-
-const pipeline = util.promisify(stream.pipeline);
-
-export async function downloadUrl(url: string, path: string) {
- const logger = new Logger('download');
-
- logger.info(`Downloading ${chalk.cyan(url)} ...`);
-
- const timeout = 30 * 1000;
- const operationTimeout = 60 * 1000;
- const maxSize = config.maxFileSize || 262144000;
-
- const req = got.stream(url, {
- headers: {
- 'User-Agent': config.userAgent
- },
- timeout: {
- lookup: timeout,
- connect: timeout,
- secureConnect: timeout,
- socket: timeout, // read timeout
- response: timeout,
- send: timeout,
- request: operationTimeout, // whole operation timeout
- },
- agent: {
- http: httpAgent,
- https: httpsAgent,
- },
- http2: false, // default
- retry: 0,
- }).on('response', (res: Got.Response) => {
- if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) {
- if (isPrivateIp(res.ip)) {
- logger.warn(`Blocked address: ${res.ip}`);
- req.destroy();
- }
- }
-
- const contentLength = res.headers['content-length'];
- if (contentLength != null) {
- const size = Number(contentLength);
- if (size > maxSize) {
- logger.warn(`maxSize exceeded (${size} > ${maxSize}) on response`);
- req.destroy();
- }
- }
- }).on('downloadProgress', (progress: Got.Progress) => {
- if (progress.transferred > maxSize) {
- logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`);
- req.destroy();
- }
- });
-
- try {
- await pipeline(req, fs.createWriteStream(path));
- } catch (e) {
- if (e instanceof Got.HTTPError) {
- throw new StatusError(`${e.response.statusCode} ${e.response.statusMessage}`, e.response.statusCode, e.response.statusMessage);
- } else {
- throw e;
- }
- }
-
- logger.succ(`Download finished: ${chalk.cyan(url)}`);
-}
-
-function isPrivateIp(ip: string) {
- for (const net of config.allowedPrivateNetworks || []) {
- const cidr = new IPCIDR(net);
- if (cidr.contains(ip)) {
- return false;
- }
- }
-
- return PrivateIp(ip);
-}
diff --git a/src/misc/emoji-regex.ts b/src/misc/emoji-regex.ts
deleted file mode 100644
index 8b07fbd8f2..0000000000
--- a/src/misc/emoji-regex.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-const twemojiRegex = require('twemoji-parser/dist/lib/regex').default;
-
-export const emojiRegex = new RegExp(`(${twemojiRegex.source})`);
diff --git a/src/misc/emojilist.ts b/src/misc/emojilist.ts
deleted file mode 100644
index de7591f5a0..0000000000
--- a/src/misc/emojilist.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// initial converted from https://github.com/muan/emojilib/commit/242fe68be86ed6536843b83f7e32f376468b38fb
-export const emojilist = require('../emojilist.json') as {
- name: string;
- keywords: string[];
- char: string;
- category: 'people' | 'animals_and_nature' | 'food_and_drink' | 'activity' | 'travel_and_places' | 'objects' | 'symbols' | 'flags';
-}[];
diff --git a/src/misc/extract-custom-emojis-from-mfm.ts b/src/misc/extract-custom-emojis-from-mfm.ts
deleted file mode 100644
index b29ce281b3..0000000000
--- a/src/misc/extract-custom-emojis-from-mfm.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as mfm from 'mfm-js';
-import { unique } from '@/prelude/array';
-
-export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
- const emojiNodes = mfm.extract(nodes, (node) => {
- return (node.type === 'emojiCode' && node.props.name.length <= 100);
- });
-
- return unique(emojiNodes.map(x => x.props.name));
-}
diff --git a/src/misc/extract-hashtags.ts b/src/misc/extract-hashtags.ts
deleted file mode 100644
index b0a74df219..0000000000
--- a/src/misc/extract-hashtags.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as mfm from 'mfm-js';
-import { unique } from '@/prelude/array';
-
-export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
- const hashtagNodes = mfm.extract(nodes, (node) => node.type === 'hashtag');
- const hashtags = unique(hashtagNodes.map(x => x.props.hashtag));
-
- return hashtags;
-}
diff --git a/src/misc/extract-mentions.ts b/src/misc/extract-mentions.ts
deleted file mode 100644
index cc19b161a8..0000000000
--- a/src/misc/extract-mentions.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-// test is located in test/extract-mentions
-
-import * as mfm from 'mfm-js';
-
-export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] {
- // TODO: 重複を削除
- const mentionNodes = mfm.extract(nodes, (node) => node.type === 'mention');
- const mentions = mentionNodes.map(x => x.props);
-
- return mentions;
-}
diff --git a/src/misc/extract-url-from-mfm.ts b/src/misc/extract-url-from-mfm.ts
deleted file mode 100644
index e6d5d0104a..0000000000
--- a/src/misc/extract-url-from-mfm.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import * as mfm from 'mfm-js';
-import { unique } from '@/prelude/array';
-
-// unique without hash
-// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ]
-const removeHash = (x: string) => x.replace(/#[^#]*$/, '');
-
-export function extractUrlFromMfm(nodes: mfm.MfmNode[], respectSilentFlag = true): string[] {
- const urlNodes = mfm.extract(nodes, (node) => {
- return (node.type === 'url') || (node.type === 'link' && (!respectSilentFlag || !node.props.silent));
- });
- const urls: string[] = unique(urlNodes.map(x => x.props.url));
-
- return urls.reduce((array, url) => {
- const urlWithoutHash = removeHash(url);
- if (!array.map(x => removeHash(x)).includes(urlWithoutHash)) array.push(url);
- return array;
- }, [] as string[]);
-}
diff --git a/src/misc/fetch-meta.ts b/src/misc/fetch-meta.ts
deleted file mode 100644
index a0bcdd4d48..0000000000
--- a/src/misc/fetch-meta.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Meta } from '@/models/entities/meta';
-import { getConnection } from 'typeorm';
-
-let cache: Meta;
-
-export async function fetchMeta(noCache = false): Promise<Meta> {
- if (!noCache && cache) return cache;
-
- return await getConnection().transaction(async transactionalEntityManager => {
- // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
- const meta = await transactionalEntityManager.findOne(Meta, {
- order: {
- id: 'DESC'
- }
- });
-
- if (meta) {
- cache = meta;
- return meta;
- } else {
- const saved = await transactionalEntityManager.save(Meta, {
- id: 'x'
- }) as Meta;
-
- cache = saved;
- return saved;
- }
- });
-}
-
-setInterval(() => {
- fetchMeta(true).then(meta => {
- cache = meta;
- });
-}, 1000 * 10);
diff --git a/src/misc/fetch-proxy-account.ts b/src/misc/fetch-proxy-account.ts
deleted file mode 100644
index e0eedea4c8..0000000000
--- a/src/misc/fetch-proxy-account.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { fetchMeta } from './fetch-meta';
-import { ILocalUser } from '@/models/entities/user';
-import { Users } from '@/models/index';
-
-export async function fetchProxyAccount(): Promise<ILocalUser | null> {
- const meta = await fetchMeta();
- if (meta.proxyAccountId == null) return null;
- return await Users.findOneOrFail(meta.proxyAccountId) as ILocalUser;
-}
diff --git a/src/misc/fetch.ts b/src/misc/fetch.ts
deleted file mode 100644
index f4f16a27e2..0000000000
--- a/src/misc/fetch.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import * as http from 'http';
-import * as https from 'https';
-import CacheableLookup from 'cacheable-lookup';
-import fetch from 'node-fetch';
-import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
-import config from '@/config/index';
-import { URL } from 'url';
-
-export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: Record<string, string>) {
- const res = await getResponse({
- url,
- method: 'GET',
- headers: Object.assign({
- 'User-Agent': config.userAgent,
- Accept: accept
- }, headers || {}),
- timeout
- });
-
- return await res.json();
-}
-
-export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: Record<string, string>) {
- const res = await getResponse({
- url,
- method: 'GET',
- headers: Object.assign({
- 'User-Agent': config.userAgent,
- Accept: accept
- }, headers || {}),
- timeout
- });
-
- return await res.text();
-}
-
-export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
- const timeout = args?.timeout || 10 * 1000;
-
- const controller = new AbortController();
- setTimeout(() => {
- controller.abort();
- }, timeout * 6);
-
- const res = await fetch(args.url, {
- method: args.method,
- headers: args.headers,
- body: args.body,
- timeout,
- size: args?.size || 10 * 1024 * 1024,
- agent: getAgentByUrl,
- signal: controller.signal,
- });
-
- if (!res.ok) {
- throw new StatusError(`${res.status} ${res.statusText}`, res.status, res.statusText);
- }
-
- return res;
-}
-
-const cache = new CacheableLookup({
- maxTtl: 3600, // 1hours
- errorTtl: 30, // 30secs
- lookup: false, // nativeのdns.lookupにfallbackしない
-});
-
-/**
- * Get http non-proxy agent
- */
-const _http = new http.Agent({
- keepAlive: true,
- keepAliveMsecs: 30 * 1000,
- lookup: cache.lookup,
-} as http.AgentOptions);
-
-/**
- * Get https non-proxy agent
- */
-const _https = new https.Agent({
- keepAlive: true,
- keepAliveMsecs: 30 * 1000,
- lookup: cache.lookup,
-} as https.AgentOptions);
-
-const maxSockets = Math.max(256, config.deliverJobConcurrency || 128);
-
-/**
- * Get http proxy or non-proxy agent
- */
-export const httpAgent = config.proxy
- ? new HttpProxyAgent({
- keepAlive: true,
- keepAliveMsecs: 30 * 1000,
- maxSockets,
- maxFreeSockets: 256,
- scheduling: 'lifo',
- proxy: config.proxy
- })
- : _http;
-
-/**
- * Get https proxy or non-proxy agent
- */
-export const httpsAgent = config.proxy
- ? new HttpsProxyAgent({
- keepAlive: true,
- keepAliveMsecs: 30 * 1000,
- maxSockets,
- maxFreeSockets: 256,
- scheduling: 'lifo',
- proxy: config.proxy
- })
- : _https;
-
-/**
- * Get agent by URL
- * @param url URL
- * @param bypassProxy Allways bypass proxy
- */
-export function getAgentByUrl(url: URL, bypassProxy = false) {
- if (bypassProxy || (config.proxyBypassHosts || []).includes(url.hostname)) {
- return url.protocol == 'http:' ? _http : _https;
- } else {
- return url.protocol == 'http:' ? httpAgent : httpsAgent;
- }
-}
-
-export class StatusError extends Error {
- public statusCode: number;
- public statusMessage?: string;
- public isClientError: boolean;
-
- constructor(message: string, statusCode: number, statusMessage?: string) {
- super(message);
- this.name = 'StatusError';
- this.statusCode = statusCode;
- this.statusMessage = statusMessage;
- this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
- }
-}
diff --git a/src/misc/format-time-string.ts b/src/misc/format-time-string.ts
deleted file mode 100644
index bfb2c397ae..0000000000
--- a/src/misc/format-time-string.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-const defaultLocaleStringFormats: {[index: string]: string} = {
- 'weekday': 'narrow',
- 'era': 'narrow',
- 'year': 'numeric',
- 'month': 'numeric',
- 'day': 'numeric',
- 'hour': 'numeric',
- 'minute': 'numeric',
- 'second': 'numeric',
- 'timeZoneName': 'short'
-};
-
-function formatLocaleString(date: Date, format: string): string {
- return format.replace(/\{\{(\w+)(:(\w+))?\}\}/g, (match: string, kind: string, unused?, option?: string) => {
- if (['weekday', 'era', 'year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName'].includes(kind)) {
- return date.toLocaleString(window.navigator.language, {[kind]: option ? option : defaultLocaleStringFormats[kind]});
- } else {
- return match;
- }
- });
-}
-
-export function formatDateTimeString(date: Date, format: string): string {
- return format
- .replace(/yyyy/g, date.getFullYear().toString())
- .replace(/yy/g, date.getFullYear().toString().slice(-2))
- .replace(/MMMM/g, date.toLocaleString(window.navigator.language, { month: 'long'}))
- .replace(/MMM/g, date.toLocaleString(window.navigator.language, { month: 'short'}))
- .replace(/MM/g, (`0${date.getMonth() + 1}`).slice(-2))
- .replace(/M/g, (date.getMonth() + 1).toString())
- .replace(/dd/g, (`0${date.getDate()}`).slice(-2))
- .replace(/d/g, date.getDate().toString())
- .replace(/HH/g, (`0${date.getHours()}`).slice(-2))
- .replace(/H/g, date.getHours().toString())
- .replace(/hh/g, (`0${(date.getHours() % 12) || 12}`).slice(-2))
- .replace(/h/g, ((date.getHours() % 12) || 12).toString())
- .replace(/mm/g, (`0${date.getMinutes()}`).slice(-2))
- .replace(/m/g, date.getMinutes().toString())
- .replace(/ss/g, (`0${date.getSeconds()}`).slice(-2))
- .replace(/s/g, date.getSeconds().toString())
- .replace(/tt/g, date.getHours() >= 12 ? 'PM' : 'AM');
-}
-
-export function formatTimeString(date: Date, format: string): string {
- return format.replace(/\[(([^\[]|\[\])*)\]|(([yMdHhmst])\4{0,3})/g, (match: string, localeformat?: string, unused?, datetimeformat?: string) => {
- if (localeformat) return formatLocaleString(date, localeformat);
- if (datetimeformat) return formatDateTimeString(date, datetimeformat);
- return match;
- });
-}
diff --git a/src/misc/gen-avatar.ts b/src/misc/gen-avatar.ts
deleted file mode 100644
index f03ca9f96d..0000000000
--- a/src/misc/gen-avatar.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Random avatar generator
- */
-
-import * as p from 'pureimage';
-import * as gen from 'random-seed';
-import { WriteStream } from 'fs';
-
-const size = 256; // px
-const n = 5; // resolution
-const margin = (size / n);
-const colors = [
- '#e57373',
- '#F06292',
- '#BA68C8',
- '#9575CD',
- '#7986CB',
- '#64B5F6',
- '#4FC3F7',
- '#4DD0E1',
- '#4DB6AC',
- '#81C784',
- '#8BC34A',
- '#AFB42B',
- '#F57F17',
- '#FF5722',
- '#795548',
- '#455A64',
-];
-const bg = '#e9e9e9';
-
-const actualSize = size - (margin * 2);
-const cellSize = actualSize / n;
-const sideN = Math.floor(n / 2);
-
-/**
- * Generate buffer of random avatar by seed
- */
-export function genAvatar(seed: string, stream: WriteStream): Promise<void> {
- const rand = gen.create(seed);
- const canvas = p.make(size, size);
- const ctx = canvas.getContext('2d');
-
- ctx.fillStyle = bg;
- ctx.beginPath();
- ctx.fillRect(0, 0, size, size);
-
- ctx.fillStyle = colors[rand(colors.length)];
-
- // side bitmap (filled by false)
- const side: boolean[][] = new Array(sideN);
- for (let i = 0; i < side.length; i++) {
- side[i] = new Array(n).fill(false);
- }
-
- // 1*n (filled by false)
- const center: boolean[] = new Array(n).fill(false);
-
- // tslint:disable-next-line:prefer-for-of
- for (let x = 0; x < side.length; x++) {
- for (let y = 0; y < side[x].length; y++) {
- side[x][y] = rand(3) === 0;
- }
- }
-
- for (let i = 0; i < center.length; i++) {
- center[i] = rand(3) === 0;
- }
-
- // Draw
- for (let x = 0; x < n; x++) {
- for (let y = 0; y < n; y++) {
- const isXCenter = x === ((n - 1) / 2);
- if (isXCenter && !center[y]) continue;
-
- const isLeftSide = x < ((n - 1) / 2);
- if (isLeftSide && !side[x][y]) continue;
-
- const isRightSide = x > ((n - 1) / 2);
- if (isRightSide && !side[sideN - (x - sideN)][y]) continue;
-
- const actualX = margin + (cellSize * x);
- const actualY = margin + (cellSize * y);
- ctx.beginPath();
- ctx.fillRect(actualX, actualY, cellSize, cellSize);
- }
- }
-
- return p.encodePNGToStream(canvas, stream);
-}
diff --git a/src/misc/gen-id.ts b/src/misc/gen-id.ts
deleted file mode 100644
index b1b542dc4b..0000000000
--- a/src/misc/gen-id.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ulid } from 'ulid';
-import { genAid } from './id/aid';
-import { genMeid } from './id/meid';
-import { genMeidg } from './id/meidg';
-import { genObjectId } from './id/object-id';
-import config from '@/config/index';
-
-const metohd = config.id.toLowerCase();
-
-export function genId(date?: Date): string {
- if (!date || (date > new Date())) date = new Date();
-
- switch (metohd) {
- case 'aid': return genAid(date);
- case 'meid': return genMeid(date);
- case 'meidg': return genMeidg(date);
- case 'ulid': return ulid(date.getTime());
- case 'objectid': return genObjectId(date);
- default: throw new Error('unrecognized id generation method');
- }
-}
diff --git a/src/misc/gen-key-pair.ts b/src/misc/gen-key-pair.ts
deleted file mode 100644
index d4a8fa7534..0000000000
--- a/src/misc/gen-key-pair.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as crypto from 'crypto';
-import * as util from 'util';
-
-const generateKeyPair = util.promisify(crypto.generateKeyPair);
-
-export async function genRsaKeyPair(modulusLength = 2048) {
- return await generateKeyPair('rsa', {
- modulusLength,
- publicKeyEncoding: {
- type: 'spki',
- format: 'pem'
- },
- privateKeyEncoding: {
- type: 'pkcs8',
- format: 'pem',
- cipher: undefined,
- passphrase: undefined
- }
- });
-}
-
-export async function genEcKeyPair(namedCurve: 'prime256v1' | 'secp384r1' | 'secp521r1' | 'curve25519' = 'prime256v1') {
- return await generateKeyPair('ec', {
- namedCurve,
- publicKeyEncoding: {
- type: 'spki',
- format: 'pem'
- },
- privateKeyEncoding: {
- type: 'pkcs8',
- format: 'pem',
- cipher: undefined,
- passphrase: undefined
- }
- });
-}
diff --git a/src/misc/get-file-info.ts b/src/misc/get-file-info.ts
deleted file mode 100644
index 39ba541395..0000000000
--- a/src/misc/get-file-info.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-import * as fs from 'fs';
-import * as crypto from 'crypto';
-import * as stream from 'stream';
-import * as util from 'util';
-import * as fileType from 'file-type';
-import isSvg from 'is-svg';
-import * as probeImageSize from 'probe-image-size';
-import * as sharp from 'sharp';
-import { encode } from 'blurhash';
-
-const pipeline = util.promisify(stream.pipeline);
-
-export type FileInfo = {
- size: number;
- md5: string;
- type: {
- mime: string;
- ext: string | null;
- };
- width?: number;
- height?: number;
- blurhash?: string;
- warnings: string[];
-};
-
-const TYPE_OCTET_STREAM = {
- mime: 'application/octet-stream',
- ext: null
-};
-
-const TYPE_SVG = {
- mime: 'image/svg+xml',
- ext: 'svg'
-};
-
-/**
- * Get file information
- */
-export async function getFileInfo(path: string): Promise<FileInfo> {
- const warnings = [] as string[];
-
- const size = await getFileSize(path);
- const md5 = await calcHash(path);
-
- let type = await detectType(path);
-
- // image dimensions
- let width: number | undefined;
- let height: number | undefined;
-
- if (['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/webp', 'image/bmp', 'image/tiff', 'image/svg+xml', 'image/vnd.adobe.photoshop'].includes(type.mime)) {
- const imageSize = await detectImageSize(path).catch(e => {
- warnings.push(`detectImageSize failed: ${e}`);
- return undefined;
- });
-
- // うまく判定できない画像は octet-stream にする
- if (!imageSize) {
- warnings.push(`cannot detect image dimensions`);
- type = TYPE_OCTET_STREAM;
- } else if (imageSize.wUnits === 'px') {
- width = imageSize.width;
- height = imageSize.height;
-
- // 制限を超えている画像は octet-stream にする
- if (imageSize.width > 16383 || imageSize.height > 16383) {
- warnings.push(`image dimensions exceeds limits`);
- type = TYPE_OCTET_STREAM;
- }
- } else {
- warnings.push(`unsupported unit type: ${imageSize.wUnits}`);
- }
- }
-
- let blurhash: string | undefined;
-
- if (['image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/webp', 'image/svg+xml'].includes(type.mime)) {
- blurhash = await getBlurhash(path).catch(e => {
- warnings.push(`getBlurhash failed: ${e}`);
- return undefined;
- });
- }
-
- return {
- size,
- md5,
- type,
- width,
- height,
- blurhash,
- warnings,
- };
-}
-
-/**
- * Detect MIME Type and extension
- */
-export async function detectType(path: string) {
- // Check 0 byte
- const fileSize = await getFileSize(path);
- if (fileSize === 0) {
- return TYPE_OCTET_STREAM;
- }
-
- const type = await fileType.fromFile(path);
-
- if (type) {
- // XMLはSVGかもしれない
- if (type.mime === 'application/xml' && await checkSvg(path)) {
- return TYPE_SVG;
- }
-
- return {
- mime: type.mime,
- ext: type.ext
- };
- }
-
- // 種類が不明でもSVGかもしれない
- if (await checkSvg(path)) {
- return TYPE_SVG;
- }
-
- // それでも種類が不明なら application/octet-stream にする
- return TYPE_OCTET_STREAM;
-}
-
-/**
- * Check the file is SVG or not
- */
-export async function checkSvg(path: string) {
- try {
- const size = await getFileSize(path);
- if (size > 1 * 1024 * 1024) return false;
- return isSvg(fs.readFileSync(path));
- } catch {
- return false;
- }
-}
-
-/**
- * Get file size
- */
-export async function getFileSize(path: string): Promise<number> {
- const getStat = util.promisify(fs.stat);
- return (await getStat(path)).size;
-}
-
-/**
- * Calculate MD5 hash
- */
-async function calcHash(path: string): Promise<string> {
- const hash = crypto.createHash('md5').setEncoding('hex');
- await pipeline(fs.createReadStream(path), hash);
- return hash.read();
-}
-
-/**
- * Detect dimensions of image
- */
-async function detectImageSize(path: string): Promise<{
- width: number;
- height: number;
- wUnits: string;
- hUnits: string;
-}> {
- const readable = fs.createReadStream(path);
- const imageSize = await probeImageSize(readable);
- readable.destroy();
- return imageSize;
-}
-
-/**
- * Calculate average color of image
- */
-function getBlurhash(path: string): Promise<string> {
- return new Promise((resolve, reject) => {
- sharp(path)
- .raw()
- .ensureAlpha()
- .resize(64, 64, { fit: 'inside' })
- .toBuffer((err, buffer, { width, height }) => {
- if (err) return reject(err);
-
- let hash;
-
- try {
- hash = encode(new Uint8ClampedArray(buffer), width, height, 7, 7);
- } catch (e) {
- return reject(e);
- }
-
- resolve(hash);
- });
- });
-}
diff --git a/src/misc/get-note-summary.ts b/src/misc/get-note-summary.ts
deleted file mode 100644
index a1866fb209..0000000000
--- a/src/misc/get-note-summary.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 投稿を表す文字列を取得します。
- * @param {*} note (packされた)投稿
- */
-export const getNoteSummary = (note: any, locale: any): string => {
- if (note.deletedAt) {
- return `(${locale['deletedNote']})`;
- }
-
- if (note.isHidden) {
- return `(${locale['invisibleNote']})`;
- }
-
- let summary = '';
-
- // 本文
- if (note.cw != null) {
- summary += note.cw;
- } else {
- summary += note.text ? note.text : '';
- }
-
- // ファイルが添付されているとき
- if ((note.files || []).length != 0) {
- summary += ` (${locale['withNFiles'].replace('{n}', note.files.length)})`;
- }
-
- // 投票が添付されているとき
- if (note.poll) {
- summary += ` (${locale['poll']})`;
- }
-
- // 返信のとき
- if (note.replyId) {
- if (note.reply) {
- summary += `\n\nRE: ${getNoteSummary(note.reply, locale)}`;
- } else {
- summary += '\n\nRE: ...';
- }
- }
-
- // Renoteのとき
- if (note.renoteId) {
- if (note.renote) {
- summary += `\n\nRN: ${getNoteSummary(note.renote, locale)}`;
- } else {
- summary += '\n\nRN: ...';
- }
- }
-
- return summary.trim();
-};
diff --git a/src/misc/get-reaction-emoji.ts b/src/misc/get-reaction-emoji.ts
deleted file mode 100644
index c2e0b98582..0000000000
--- a/src/misc/get-reaction-emoji.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-export default function(reaction: string): string {
- switch (reaction) {
- case 'like': return '👍';
- case 'love': return '❤️';
- case 'laugh': return '😆';
- case 'hmm': return '🤔';
- case 'surprise': return '😮';
- case 'congrats': return '🎉';
- case 'angry': return '💢';
- case 'confused': return '😥';
- case 'rip': return '😇';
- case 'pudding': return '🍮';
- case 'star': return '⭐';
- default: return reaction;
- }
-}
diff --git a/src/misc/get-user-name.ts b/src/misc/get-user-name.ts
deleted file mode 100644
index 3545e986e8..0000000000
--- a/src/misc/get-user-name.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { User } from '@/models/entities/user';
-
-export default function(user: User): string {
- return user.name || user.username;
-}
diff --git a/src/misc/hard-limits.ts b/src/misc/hard-limits.ts
deleted file mode 100644
index 1039f7335a..0000000000
--- a/src/misc/hard-limits.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-
-// If you change DB_* values, you must also change the DB schema.
-
-/**
- * Maximum note text length that can be stored in DB.
- * Surrogate pairs count as one
- */
-export const DB_MAX_NOTE_TEXT_LENGTH = 8192;
-
-/**
- * Maximum image description length that can be stored in DB.
- * Surrogate pairs count as one
- */
-export const DB_MAX_IMAGE_COMMENT_LENGTH = 512;
diff --git a/src/misc/i18n.ts b/src/misc/i18n.ts
deleted file mode 100644
index 4fa398763a..0000000000
--- a/src/misc/i18n.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export class I18n<T extends Record<string, any>> {
- public locale: T;
-
- constructor(locale: T) {
- this.locale = locale;
-
- //#region BIND
- this.t = this.t.bind(this);
- //#endregion
- }
-
- // string にしているのは、ドット区切りでのパス指定を許可するため
- // なるべくこのメソッド使うよりもlocale直接参照の方がvueのキャッシュ効いてパフォーマンスが良いかも
- public t(key: string, args?: Record<string, any>): string {
- try {
- let str = key.split('.').reduce((o, i) => o[i], this.locale) as string;
-
- if (args) {
- for (const [k, v] of Object.entries(args)) {
- str = str.replace(`{${k}}`, v);
- }
- }
- return str;
- } catch (e) {
- console.warn(`missing localization '${key}'`);
- return key;
- }
- }
-}
diff --git a/src/misc/id/aid.ts b/src/misc/id/aid.ts
deleted file mode 100644
index 2bcde90bff..0000000000
--- a/src/misc/id/aid.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-// AID
-// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列]
-
-import * as crypto from 'crypto';
-
-const TIME2000 = 946684800000;
-let counter = crypto.randomBytes(2).readUInt16LE(0);
-
-function getTime(time: number) {
- time = time - TIME2000;
- if (time < 0) time = 0;
-
- return time.toString(36).padStart(8, '0');
-}
-
-function getNoise() {
- return counter.toString(36).padStart(2, '0').slice(-2);
-}
-
-export function genAid(date: Date): string {
- const t = date.getTime();
- if (isNaN(t)) throw 'Failed to create AID: Invalid Date';
- counter++;
- return getTime(t) + getNoise();
-}
diff --git a/src/misc/id/meid.ts b/src/misc/id/meid.ts
deleted file mode 100644
index 30bbdf1698..0000000000
--- a/src/misc/id/meid.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-const CHARS = '0123456789abcdef';
-
-function getTime(time: number) {
- if (time < 0) time = 0;
- if (time === 0) {
- return CHARS[0];
- }
-
- time += 0x800000000000;
-
- return time.toString(16).padStart(12, CHARS[0]);
-}
-
-function getRandom() {
- let str = '';
-
- for (let i = 0; i < 12; i++) {
- str += CHARS[Math.floor(Math.random() * CHARS.length)];
- }
-
- return str;
-}
-
-export function genMeid(date: Date): string {
- return getTime(date.getTime()) + getRandom();
-}
diff --git a/src/misc/id/meidg.ts b/src/misc/id/meidg.ts
deleted file mode 100644
index d4aaaea1ba..0000000000
--- a/src/misc/id/meidg.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-const CHARS = '0123456789abcdef';
-
-// 4bit Fixed hex value 'g'
-// 44bit UNIX Time ms in Hex
-// 48bit Random value in Hex
-
-function getTime(time: number) {
- if (time < 0) time = 0;
- if (time === 0) {
- return CHARS[0];
- }
-
- return time.toString(16).padStart(11, CHARS[0]);
-}
-
-function getRandom() {
- let str = '';
-
- for (let i = 0; i < 12; i++) {
- str += CHARS[Math.floor(Math.random() * CHARS.length)];
- }
-
- return str;
-}
-
-export function genMeidg(date: Date): string {
- return 'g' + getTime(date.getTime()) + getRandom();
-}
diff --git a/src/misc/id/object-id.ts b/src/misc/id/object-id.ts
deleted file mode 100644
index 392ea43301..0000000000
--- a/src/misc/id/object-id.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-const CHARS = '0123456789abcdef';
-
-function getTime(time: number) {
- if (time < 0) time = 0;
- if (time === 0) {
- return CHARS[0];
- }
-
- time = Math.floor(time / 1000);
-
- return time.toString(16).padStart(8, CHARS[0]);
-}
-
-function getRandom() {
- let str = '';
-
- for (let i = 0; i < 16; i++) {
- str += CHARS[Math.floor(Math.random() * CHARS.length)];
- }
-
- return str;
-}
-
-export function genObjectId(date: Date): string {
- return getTime(date.getTime()) + getRandom();
-}
diff --git a/src/misc/identifiable-error.ts b/src/misc/identifiable-error.ts
deleted file mode 100644
index 2d7c6bd0c6..0000000000
--- a/src/misc/identifiable-error.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * ID付きエラー
- */
-export class IdentifiableError extends Error {
- public message: string;
- public id: string;
-
- constructor(id: string, message?: string) {
- super(message);
- this.message = message || '';
- this.id = id;
- }
-}
diff --git a/src/misc/is-blocker-user-related.ts b/src/misc/is-blocker-user-related.ts
deleted file mode 100644
index 8c0ebfad9b..0000000000
--- a/src/misc/is-blocker-user-related.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function isBlockerUserRelated(note: any, blockerUserIds: Set<string>): boolean {
- if (blockerUserIds.has(note.userId)) {
- return true;
- }
-
- if (note.reply != null && blockerUserIds.has(note.reply.userId)) {
- return true;
- }
-
- if (note.renote != null && blockerUserIds.has(note.renote.userId)) {
- return true;
- }
-
- return false;
-}
diff --git a/src/misc/is-duplicate-key-value-error.ts b/src/misc/is-duplicate-key-value-error.ts
deleted file mode 100644
index 23d8ceb1b7..0000000000
--- a/src/misc/is-duplicate-key-value-error.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function isDuplicateKeyValueError(e: Error): boolean {
- return e.message.startsWith('duplicate key value');
-}
diff --git a/src/misc/is-muted-user-related.ts b/src/misc/is-muted-user-related.ts
deleted file mode 100644
index 2caa743f95..0000000000
--- a/src/misc/is-muted-user-related.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function isMutedUserRelated(note: any, mutedUserIds: Set<string>): boolean {
- if (mutedUserIds.has(note.userId)) {
- return true;
- }
-
- if (note.reply != null && mutedUserIds.has(note.reply.userId)) {
- return true;
- }
-
- if (note.renote != null && mutedUserIds.has(note.renote.userId)) {
- return true;
- }
-
- return false;
-}
diff --git a/src/misc/is-quote.ts b/src/misc/is-quote.ts
deleted file mode 100644
index 2b57f036a2..0000000000
--- a/src/misc/is-quote.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { Note } from '@/models/entities/note';
-
-export default function(note: Note): boolean {
- return note.renoteId != null && (note.text != null || note.hasPoll || (note.fileIds != null && note.fileIds.length > 0));
-}
diff --git a/src/misc/keypair-store.ts b/src/misc/keypair-store.ts
deleted file mode 100644
index c018013b7b..0000000000
--- a/src/misc/keypair-store.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { UserKeypairs } from '@/models/index';
-import { User } from '@/models/entities/user';
-import { UserKeypair } from '@/models/entities/user-keypair';
-import { Cache } from './cache';
-
-const cache = new Cache<UserKeypair>(Infinity);
-
-export async function getUserKeypair(userId: User['id']): Promise<UserKeypair> {
- return await cache.fetch(userId, () => UserKeypairs.findOneOrFail(userId));
-}
diff --git a/src/misc/license.ts b/src/misc/license.ts
deleted file mode 100644
index 8b12923ca1..0000000000
--- a/src/misc/license.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import * as fs from 'fs';
-import { fileURLToPath } from 'url';
-import { dirname } from 'path';
-
-//const _filename = fileURLToPath(import.meta.url);
-const _filename = __filename;
-const _dirname = dirname(_filename);
-
-const license = fs.readFileSync(_dirname + '/../../LICENSE', 'utf-8');
-
-const licenseHtml = license
- .replace(/\r\n/g, '\n')
- .replace(/(.)\n(.)/g, '$1 $2')
- .replace(/(^|\n)(.*?)($|\n)/g, '<p>$2</p>');
-
-export {
- license,
- licenseHtml
-};
diff --git a/src/misc/normalize-for-search.ts b/src/misc/normalize-for-search.ts
deleted file mode 100644
index 200540566e..0000000000
--- a/src/misc/normalize-for-search.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export function normalizeForSearch(tag: string): string {
- // ref.
- // - https://analytics-note.xyz/programming/unicode-normalization-forms/
- // - https://maku77.github.io/js/string/normalize.html
- return tag.normalize('NFKC').toLowerCase();
-}
diff --git a/src/misc/nyaize.ts b/src/misc/nyaize.ts
deleted file mode 100644
index 500d1db2cb..0000000000
--- a/src/misc/nyaize.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function nyaize(text: string): string {
- return text
- // ja-JP
- .replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ')
- // en-US
- .replace(/(?<=n)a/gi, x => x === 'A' ? 'YA' : 'ya')
- .replace(/(?<=morn)ing/gi, x => x === 'ING' ? 'YAN' : 'yan')
- .replace(/(?<=every)one/gi, x => x === 'ONE' ? 'NYAN' : 'nyan')
- // ko-KR
- .replace(/[나-낳]/g, match => String.fromCharCode(
- match.charCodeAt(0)! + '냐'.charCodeAt(0) - '나'.charCodeAt(0)
- ))
- .replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, '다냥')
- .replace(/(야(?=\?))|(야$)|(야(?= ))/gm, '냥');
-}
diff --git a/src/misc/populate-emojis.ts b/src/misc/populate-emojis.ts
deleted file mode 100644
index f0a8bde31e..0000000000
--- a/src/misc/populate-emojis.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { In } from 'typeorm';
-import { Emojis } from '@/models/index';
-import { Emoji } from '@/models/entities/emoji';
-import { Note } from '@/models/entities/note';
-import { Cache } from './cache';
-import { isSelfHost, toPunyNullable } from './convert-host';
-import { decodeReaction } from './reaction-lib';
-import config from '@/config/index';
-import { query } from '@/prelude/url';
-
-const cache = new Cache<Emoji | null>(1000 * 60 * 60 * 12);
-
-/**
- * 添付用絵文字情報
- */
-type PopulatedEmoji = {
- name: string;
- url: string;
-};
-
-function normalizeHost(src: string | undefined, noteUserHost: string | null): string | null {
- // クエリに使うホスト
- let host = src === '.' ? null // .はローカルホスト (ここがマッチするのはリアクションのみ)
- : src === undefined ? noteUserHost // ノートなどでホスト省略表記の場合はローカルホスト (ここがリアクションにマッチすることはない)
- : isSelfHost(src) ? null // 自ホスト指定
- : (src || noteUserHost); // 指定されたホスト || ノートなどの所有者のホスト (こっちがリアクションにマッチすることはない)
-
- host = toPunyNullable(host);
-
- return host;
-}
-
-function parseEmojiStr(emojiName: string, noteUserHost: string | null) {
- const match = emojiName.match(/^(\w+)(?:@([\w.-]+))?$/);
- if (!match) return { name: null, host: null };
-
- const name = match[1];
-
- // ホスト正規化
- const host = toPunyNullable(normalizeHost(match[2], noteUserHost));
-
- return { name, host };
-}
-
-/**
- * 添付用絵文字情報を解決する
- * @param emojiName ノートやユーザープロフィールに添付された、またはリアクションのカスタム絵文字名 (:は含めない, リアクションでローカルホストの場合は@.を付ける (これはdecodeReactionで可能))
- * @param noteUserHost ノートやユーザープロフィールの所有者のホスト
- * @returns 絵文字情報, nullは未マッチを意味する
- */
-export async function populateEmoji(emojiName: string, noteUserHost: string | null): Promise<PopulatedEmoji | null> {
- const { name, host } = parseEmojiStr(emojiName, noteUserHost);
- if (name == null) return null;
-
- const queryOrNull = async () => (await Emojis.findOne({
- name,
- host
- })) || null;
-
- const emoji = await cache.fetch(`${name} ${host}`, queryOrNull);
-
- if (emoji == null) return null;
-
- const isLocal = emoji.host == null;
- const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({url: emoji.url})}`;
-
- return {
- name: emojiName,
- url,
- };
-}
-
-/**
- * 複数の添付用絵文字情報を解決する (キャシュ付き, 存在しないものは結果から除外される)
- */
-export async function populateEmojis(emojiNames: string[], noteUserHost: string | null): Promise<PopulatedEmoji[]> {
- const emojis = await Promise.all(emojiNames.map(x => populateEmoji(x, noteUserHost)));
- return emojis.filter((x): x is PopulatedEmoji => x != null);
-}
-
-export function aggregateNoteEmojis(notes: Note[]) {
- let emojis: { name: string | null; host: string | null; }[] = [];
- for (const note of notes) {
- emojis = emojis.concat(note.emojis
- .map(e => parseEmojiStr(e, note.userHost)));
- if (note.renote) {
- emojis = emojis.concat(note.renote.emojis
- .map(e => parseEmojiStr(e, note.renote!.userHost)));
- if (note.renote.user) {
- emojis = emojis.concat(note.renote.user.emojis
- .map(e => parseEmojiStr(e, note.renote!.userHost)));
- }
- }
- const customReactions = Object.keys(note.reactions).map(x => decodeReaction(x)).filter(x => x.name != null) as typeof emojis;
- emojis = emojis.concat(customReactions);
- if (note.user) {
- emojis = emojis.concat(note.user.emojis
- .map(e => parseEmojiStr(e, note.userHost)));
- }
- }
- return emojis.filter(x => x.name != null) as { name: string; host: string | null; }[];
-}
-
-/**
- * 与えられた絵文字のリストをデータベースから取得し、キャッシュに追加します
- */
-export async function prefetchEmojis(emojis: { name: string; host: string | null; }[]): Promise<void> {
- const notCachedEmojis = emojis.filter(emoji => cache.get(`${emoji.name} ${emoji.host}`) == null);
- const emojisQuery: any[] = [];
- const hosts = new Set(notCachedEmojis.map(e => e.host));
- for (const host of hosts) {
- emojisQuery.push({
- name: In(notCachedEmojis.filter(e => e.host === host).map(e => e.name)),
- host: host
- });
- }
- const _emojis = emojisQuery.length > 0 ? await Emojis.find({
- where: emojisQuery,
- select: ['name', 'host', 'url']
- }) : [];
- for (const emoji of _emojis) {
- cache.set(`${emoji.name} ${emoji.host}`, emoji);
- }
-}
diff --git a/src/misc/reaction-lib.ts b/src/misc/reaction-lib.ts
deleted file mode 100644
index 46dedfa24b..0000000000
--- a/src/misc/reaction-lib.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import { emojiRegex } from './emoji-regex';
-import { fetchMeta } from './fetch-meta';
-import { Emojis } from '@/models/index';
-import { toPunyNullable } from './convert-host';
-
-const legacies: Record<string, string> = {
- 'like': '👍',
- 'love': '❤', // ここに記述する場合は異体字セレクタを入れない
- 'laugh': '😆',
- 'hmm': '🤔',
- 'surprise': '😮',
- 'congrats': '🎉',
- 'angry': '💢',
- 'confused': '😥',
- 'rip': '😇',
- 'pudding': '🍮',
- 'star': '⭐',
-};
-
-export async function getFallbackReaction(): Promise<string> {
- const meta = await fetchMeta();
- return meta.useStarForReactionFallback ? '⭐' : '👍';
-}
-
-export function convertLegacyReactions(reactions: Record<string, number>) {
- const _reactions = {} as Record<string, number>;
-
- for (const reaction of Object.keys(reactions)) {
- if (reactions[reaction] <= 0) continue;
-
- if (Object.keys(legacies).includes(reaction)) {
- if (_reactions[legacies[reaction]]) {
- _reactions[legacies[reaction]] += reactions[reaction];
- } else {
- _reactions[legacies[reaction]] = reactions[reaction];
- }
- } else {
- if (_reactions[reaction]) {
- _reactions[reaction] += reactions[reaction];
- } else {
- _reactions[reaction] = reactions[reaction];
- }
- }
- }
-
- const _reactions2 = {} as Record<string, number>;
-
- for (const reaction of Object.keys(_reactions)) {
- _reactions2[decodeReaction(reaction).reaction] = _reactions[reaction];
- }
-
- return _reactions2;
-}
-
-export async function toDbReaction(reaction?: string | null, reacterHost?: string | null): Promise<string> {
- if (reaction == null) return await getFallbackReaction();
-
- reacterHost = toPunyNullable(reacterHost);
-
- // 文字列タイプのリアクションを絵文字に変換
- if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
-
- // Unicode絵文字
- const match = emojiRegex.exec(reaction);
- if (match) {
- // 合字を含む1つの絵文字
- const unicode = match[0];
-
- // 異体字セレクタ除去
- return unicode.match('\u200d') ? unicode : unicode.replace(/\ufe0f/g, '');
- }
-
- const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);
- if (custom) {
- const name = custom[1];
- const emoji = await Emojis.findOne({
- host: reacterHost || null,
- name,
- });
-
- if (emoji) return reacterHost ? `:${name}@${reacterHost}:` : `:${name}:`;
- }
-
- return await getFallbackReaction();
-}
-
-type DecodedReaction = {
- /**
- * リアクション名 (Unicode Emoji or ':name@hostname' or ':name@.')
- */
- reaction: string;
-
- /**
- * name (カスタム絵文字の場合name, Emojiクエリに使う)
- */
- name?: string;
-
- /**
- * host (カスタム絵文字の場合host, Emojiクエリに使う)
- */
- host?: string | null;
-};
-
-export function decodeReaction(str: string): DecodedReaction {
- const custom = str.match(/^:([\w+-]+)(?:@([\w.-]+))?:$/);
-
- if (custom) {
- const name = custom[1];
- const host = custom[2] || null;
-
- return {
- reaction: `:${name}@${host || '.'}:`, // ローカル分は@以降を省略するのではなく.にする
- name,
- host
- };
- }
-
- return {
- reaction: str,
- name: undefined,
- host: undefined
- };
-}
-
-export function convertLegacyReaction(reaction: string): string {
- reaction = decodeReaction(reaction).reaction;
- if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
- return reaction;
-}
diff --git a/src/misc/safe-for-sql.ts b/src/misc/safe-for-sql.ts
deleted file mode 100644
index 02eb7f0a26..0000000000
--- a/src/misc/safe-for-sql.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function safeForSql(text: string): boolean {
- return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
-}
diff --git a/src/misc/schema.ts b/src/misc/schema.ts
deleted file mode 100644
index 4131875ef7..0000000000
--- a/src/misc/schema.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { SimpleObj, SimpleSchema } from './simple-schema';
-import { packedUserSchema } from '@/models/repositories/user';
-import { packedNoteSchema } from '@/models/repositories/note';
-import { packedUserListSchema } from '@/models/repositories/user-list';
-import { packedAppSchema } from '@/models/repositories/app';
-import { packedMessagingMessageSchema } from '@/models/repositories/messaging-message';
-import { packedNotificationSchema } from '@/models/repositories/notification';
-import { packedDriveFileSchema } from '@/models/repositories/drive-file';
-import { packedDriveFolderSchema } from '@/models/repositories/drive-folder';
-import { packedFollowingSchema } from '@/models/repositories/following';
-import { packedMutingSchema } from '@/models/repositories/muting';
-import { packedBlockingSchema } from '@/models/repositories/blocking';
-import { packedNoteReactionSchema } from '@/models/repositories/note-reaction';
-import { packedHashtagSchema } from '@/models/repositories/hashtag';
-import { packedPageSchema } from '@/models/repositories/page';
-import { packedUserGroupSchema } from '@/models/repositories/user-group';
-import { packedNoteFavoriteSchema } from '@/models/repositories/note-favorite';
-import { packedChannelSchema } from '@/models/repositories/channel';
-import { packedAntennaSchema } from '@/models/repositories/antenna';
-import { packedClipSchema } from '@/models/repositories/clip';
-import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance';
-import { packedQueueCountSchema } from '@/models/repositories/queue';
-import { packedGalleryPostSchema } from '@/models/repositories/gallery-post';
-import { packedEmojiSchema } from '@/models/repositories/emoji';
-import { packedReversiGameSchema } from '@/models/repositories/games/reversi/game';
-import { packedReversiMatchingSchema } from '@/models/repositories/games/reversi/matching';
-
-export const refs = {
- User: packedUserSchema,
- UserList: packedUserListSchema,
- UserGroup: packedUserGroupSchema,
- App: packedAppSchema,
- MessagingMessage: packedMessagingMessageSchema,
- Note: packedNoteSchema,
- NoteReaction: packedNoteReactionSchema,
- NoteFavorite: packedNoteFavoriteSchema,
- Notification: packedNotificationSchema,
- DriveFile: packedDriveFileSchema,
- DriveFolder: packedDriveFolderSchema,
- Following: packedFollowingSchema,
- Muting: packedMutingSchema,
- Blocking: packedBlockingSchema,
- Hashtag: packedHashtagSchema,
- Page: packedPageSchema,
- Channel: packedChannelSchema,
- QueueCount: packedQueueCountSchema,
- Antenna: packedAntennaSchema,
- Clip: packedClipSchema,
- FederationInstance: packedFederationInstanceSchema,
- GalleryPost: packedGalleryPostSchema,
- Emoji: packedEmojiSchema,
- ReversiGame: packedReversiGameSchema,
- ReversiMatching: packedReversiMatchingSchema,
-};
-
-export type Packed<x extends keyof typeof refs> = ObjType<(typeof refs[x])['properties']>;
-
-export interface Schema extends SimpleSchema {
- items?: Schema;
- properties?: Obj;
- ref?: keyof typeof refs;
-}
-
-type NonUndefinedPropertyNames<T extends Obj> = {
- [K in keyof T]: T[K]['optional'] extends true ? never : K
-}[keyof T];
-
-type UndefinedPropertyNames<T extends Obj> = {
- [K in keyof T]: T[K]['optional'] extends true ? K : never
-}[keyof T];
-
-type OnlyRequired<T extends Obj> = Pick<T, NonUndefinedPropertyNames<T>>;
-type OnlyOptional<T extends Obj> = Pick<T, UndefinedPropertyNames<T>>;
-
-export interface Obj extends SimpleObj { [key: string]: Schema; }
-
-export type ObjType<s extends Obj> =
- { [P in keyof OnlyOptional<s>]?: SchemaType<s[P]> } &
- { [P in keyof OnlyRequired<s>]: SchemaType<s[P]> };
-
-// https://qiita.com/hrsh7th@github/items/84e8968c3601009cdcf2
-type MyType<T extends Schema> = {
- 0: any;
- 1: SchemaType<T>;
-}[T extends Schema ? 1 : 0];
-
-type NullOrUndefined<p extends Schema, T> =
- p['nullable'] extends true
- ? p['optional'] extends true
- ? (T | null | undefined)
- : (T | null)
- : p['optional'] extends true
- ? (T | undefined)
- : T;
-
-export type SchemaType<p extends Schema> =
- p['type'] extends 'number' ? NullOrUndefined<p, number> :
- p['type'] extends 'string' ? NullOrUndefined<p, string> :
- p['type'] extends 'boolean' ? NullOrUndefined<p, boolean> :
- p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> :
- p['type'] extends 'object' ? (
- p['ref'] extends keyof typeof refs
- ? NullOrUndefined<p, Packed<p['ref']>>
- : NullOrUndefined<p, ObjType<NonNullable<p['properties']>>>
- ) :
- p['type'] extends 'any' ? NullOrUndefined<p, any> :
- any;
diff --git a/src/misc/secure-rndstr.ts b/src/misc/secure-rndstr.ts
deleted file mode 100644
index 76ee1225eb..0000000000
--- a/src/misc/secure-rndstr.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import * as crypto from 'crypto';
-
-const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz';
-const LU_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-export function secureRndstr(length = 32, useLU = true): string {
- const chars = useLU ? LU_CHARS : L_CHARS;
- const chars_len = chars.length;
-
- let str = '';
-
- for (let i = 0; i < length; i++) {
- let rand = Math.floor((crypto.randomBytes(1).readUInt8(0) / 0xFF) * chars_len);
- if (rand === chars_len) {
- rand = chars_len - 1;
- }
- str += chars.charAt(rand);
- }
-
- return str;
-}
diff --git a/src/misc/show-machine-info.ts b/src/misc/show-machine-info.ts
deleted file mode 100644
index 58747c1152..0000000000
--- a/src/misc/show-machine-info.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as os from 'os';
-import * as sysUtils from 'systeminformation';
-import Logger from '@/services/logger';
-
-export async function showMachineInfo(parentLogger: Logger) {
- const logger = parentLogger.createSubLogger('machine');
- logger.debug(`Hostname: ${os.hostname()}`);
- logger.debug(`Platform: ${process.platform} Arch: ${process.arch}`);
- const mem = await sysUtils.mem();
- const totalmem = (mem.total / 1024 / 1024 / 1024).toFixed(1);
- const availmem = (mem.available / 1024 / 1024 / 1024).toFixed(1);
- logger.debug(`CPU: ${os.cpus().length} core MEM: ${totalmem}GB (available: ${availmem}GB)`);
-}
diff --git a/src/misc/simple-schema.ts b/src/misc/simple-schema.ts
deleted file mode 100644
index abbb348e24..0000000000
--- a/src/misc/simple-schema.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export interface SimpleSchema {
- type: 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any';
- nullable: boolean;
- optional: boolean;
- items?: SimpleSchema;
- properties?: SimpleObj;
- description?: string;
- example?: any;
- format?: string;
- ref?: string;
- enum?: string[];
- default?: boolean | null;
-}
-
-export interface SimpleObj { [key: string]: SimpleSchema; }
diff --git a/src/misc/truncate.ts b/src/misc/truncate.ts
deleted file mode 100644
index cb120331a1..0000000000
--- a/src/misc/truncate.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { substring } from 'stringz';
-
-export function truncate(input: string, size: number): string;
-export function truncate(input: string | undefined, size: number): string | undefined;
-export function truncate(input: string | undefined, size: number): string | undefined {
- if (!input) {
- return input;
- } else {
- return substring(input, 0, size);
- }
-}
diff --git a/src/misc/twemoji-base.ts b/src/misc/twemoji-base.ts
deleted file mode 100644
index cd50311b15..0000000000
--- a/src/misc/twemoji-base.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const twemojiSvgBase = '/twemoji';