mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	Cache meta
This commit is contained in:
		
							parent
							
								
									8a55bdd89d
								
							
						
					
					
						commit
						5aa5896b22
					
				
					 34 changed files with 62 additions and 55 deletions
				
			
		| 
						 | 
					@ -1,7 +1,11 @@
 | 
				
			||||||
import { Meta } from '../models/entities/meta';
 | 
					import { Meta } from '../models/entities/meta';
 | 
				
			||||||
import { getConnection } from 'typeorm';
 | 
					import { getConnection } from 'typeorm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async function(): Promise<Meta> {
 | 
					let cache: Meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function fetchMeta(noCache = false): Promise<Meta> {
 | 
				
			||||||
 | 
						if (!noCache && cache) return cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return await getConnection().transaction(async transactionalEntityManager => {
 | 
						return await getConnection().transaction(async transactionalEntityManager => {
 | 
				
			||||||
		// バグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
 | 
							// バグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
 | 
				
			||||||
		const meta = await transactionalEntityManager.findOne(Meta, {
 | 
							const meta = await transactionalEntityManager.findOne(Meta, {
 | 
				
			||||||
| 
						 | 
					@ -11,11 +15,21 @@ export default async function(): Promise<Meta> {
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (meta) {
 | 
							if (meta) {
 | 
				
			||||||
 | 
								cache = meta;
 | 
				
			||||||
			return meta;
 | 
								return meta;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return await transactionalEntityManager.save(Meta, {
 | 
								const saved = await transactionalEntityManager.save(Meta, {
 | 
				
			||||||
				id: 'x'
 | 
									id: 'x'
 | 
				
			||||||
			}) as Meta;
 | 
								}) as Meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								cache = saved;
 | 
				
			||||||
 | 
								return saved;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setInterval(() => {
 | 
				
			||||||
 | 
						fetchMeta(true).then(meta => {
 | 
				
			||||||
 | 
							cache = meta;
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}, 5000);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
import fetchMeta from './fetch-meta';
 | 
					import { fetchMeta } from './fetch-meta';
 | 
				
			||||||
import { ILocalUser } from '../models/entities/user';
 | 
					import { ILocalUser } from '../models/entities/user';
 | 
				
			||||||
import { Users } from '../models';
 | 
					import { Users } from '../models';
 | 
				
			||||||
import { ensure } from '../prelude/ensure';
 | 
					import { ensure } from '../prelude/ensure';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
import { emojiRegex } from './emoji-regex';
 | 
					import { emojiRegex } from './emoji-regex';
 | 
				
			||||||
import fetchMeta from './fetch-meta';
 | 
					import { fetchMeta } from './fetch-meta';
 | 
				
			||||||
import { Emojis } from '../models';
 | 
					import { Emojis } from '../models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const basic10: Record<string, string> = {
 | 
					const basic10: Record<string, string> = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ export async function awaitAll<T>(obj: T): Promise<AwaitAll<T>> {
 | 
				
			||||||
	const values = Object.values(obj);
 | 
						const values = Object.values(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const resolvedValues = await Promise.all(values.map(value =>
 | 
						const resolvedValues = await Promise.all(values.map(value =>
 | 
				
			||||||
		(value || !value.constructor || value.constructor.name !== 'Object')
 | 
							(!value || !value.constructor || value.constructor.name !== 'Object')
 | 
				
			||||||
			? value
 | 
								? value
 | 
				
			||||||
			: awaitAll(value)
 | 
								: awaitAll(value)
 | 
				
			||||||
	));
 | 
						));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-ins
 | 
				
			||||||
import { Instances, Users, UserPublickeys } from '../../models';
 | 
					import { Instances, Users, UserPublickeys } from '../../models';
 | 
				
			||||||
import { instanceChart } from '../../services/chart';
 | 
					import { instanceChart } from '../../services/chart';
 | 
				
			||||||
import { UserPublickey } from '../../models/entities/user-publickey';
 | 
					import { UserPublickey } from '../../models/entities/user-publickey';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
import { toPuny } from '../../misc/convert-host';
 | 
					import { toPuny } from '../../misc/convert-host';
 | 
				
			||||||
import { validActor } from '../../remote/activitypub/type';
 | 
					import { validActor } from '../../remote/activitypub/type';
 | 
				
			||||||
import { ensure } from '../../prelude/ensure';
 | 
					import { ensure } from '../../prelude/ensure';
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,6 @@ export default async (job: Bull.Job): Promise<void> => {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ブロックしてたら中断
 | 
						// ブロックしてたら中断
 | 
				
			||||||
	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 | 
					 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta();
 | 
				
			||||||
	if (meta.blockedHosts.includes(host)) {
 | 
						if (meta.blockedHosts.includes(host)) {
 | 
				
			||||||
		logger.info(`Blocked request: ${host}`);
 | 
							logger.info(`Blocked request: ${host}`);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ import { fetchNote, resolveNote } from '../../models/note';
 | 
				
			||||||
import { resolvePerson } from '../../models/person';
 | 
					import { resolvePerson } from '../../models/person';
 | 
				
			||||||
import { apLogger } from '../../logger';
 | 
					import { apLogger } from '../../logger';
 | 
				
			||||||
import { extractDbHost } from '../../../../misc/convert-host';
 | 
					import { extractDbHost } from '../../../../misc/convert-host';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const logger = apLogger;
 | 
					const logger = apLogger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,6 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// アナウンス先をブロックしてたら中断
 | 
						// アナウンス先をブロックしてたら中断
 | 
				
			||||||
	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 | 
					 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta();
 | 
				
			||||||
	if (meta.blockedHosts.includes(extractDbHost(uri))) return;
 | 
						if (meta.blockedHosts.includes(extractDbHost(uri))) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import uploadFromUrl from '../../../services/drive/upload-from-url';
 | 
					import uploadFromUrl from '../../../services/drive/upload-from-url';
 | 
				
			||||||
import { IRemoteUser } from '../../../models/entities/user';
 | 
					import { IRemoteUser } from '../../../models/entities/user';
 | 
				
			||||||
import Resolver from '../resolver';
 | 
					import Resolver from '../resolver';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { apLogger } from '../logger';
 | 
					import { apLogger } from '../logger';
 | 
				
			||||||
import { DriveFile } from '../../../models/entities/drive-file';
 | 
					import { DriveFile } from '../../../models/entities/drive-file';
 | 
				
			||||||
import { DriveFiles } from '../../../models';
 | 
					import { DriveFiles } from '../../../models';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ import { Note } from '../../../models/entities/note';
 | 
				
			||||||
import { IObject, INote } from '../type';
 | 
					import { IObject, INote } from '../type';
 | 
				
			||||||
import { Emoji } from '../../../models/entities/emoji';
 | 
					import { Emoji } from '../../../models/entities/emoji';
 | 
				
			||||||
import { genId } from '../../../misc/gen-id';
 | 
					import { genId } from '../../../misc/gen-id';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { ensure } from '../../../prelude/ensure';
 | 
					import { ensure } from '../../../prelude/ensure';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const logger = apLogger;
 | 
					const logger = apLogger;
 | 
				
			||||||
| 
						 | 
					@ -233,7 +233,6 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
 | 
				
			||||||
	if (uri == null) throw new Error('missing uri');
 | 
						if (uri == null) throw new Error('missing uri');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ブロックしてたら中断
 | 
						// ブロックしてたら中断
 | 
				
			||||||
	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 | 
					 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta();
 | 
				
			||||||
	if (meta.blockedHosts.includes(extractDbHost(uri))) throw { statusCode: 451 };
 | 
						if (meta.blockedHosts.includes(extractDbHost(uri))) throw { statusCode: 451 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import { ILocalUser } from '../../models/entities/user';
 | 
				
			||||||
import { publishApLogStream } from '../../services/stream';
 | 
					import { publishApLogStream } from '../../services/stream';
 | 
				
			||||||
import { apLogger } from './logger';
 | 
					import { apLogger } from './logger';
 | 
				
			||||||
import { UserKeypairs } from '../../models';
 | 
					import { UserKeypairs } from '../../models';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
import { toPuny } from '../../misc/convert-host';
 | 
					import { toPuny } from '../../misc/convert-host';
 | 
				
			||||||
import { ensure } from '../../prelude/ensure';
 | 
					import { ensure } from '../../prelude/ensure';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,6 @@ export default async (user: ILocalUser, url: string, object: any) => {
 | 
				
			||||||
	const { protocol, host, hostname, port, pathname, search } = new URL(url);
 | 
						const { protocol, host, hostname, port, pathname, search } = new URL(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ブロックしてたら中断
 | 
						// ブロックしてたら中断
 | 
				
			||||||
	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 | 
					 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta();
 | 
				
			||||||
	if (meta.blockedHosts.includes(toPuny(host))) return;
 | 
						if (meta.blockedHosts.includes(toPuny(host))) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ import { extractDbHost } from '../../../../misc/convert-host';
 | 
				
			||||||
import { Users, Notes } from '../../../../models';
 | 
					import { Users, Notes } from '../../../../models';
 | 
				
			||||||
import { Note } from '../../../../models/entities/note';
 | 
					import { Note } from '../../../../models/entities/note';
 | 
				
			||||||
import { User } from '../../../../models/entities/user';
 | 
					import { User } from '../../../../models/entities/user';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { validActor } from '../../../../remote/activitypub/type';
 | 
					import { validActor } from '../../../../remote/activitypub/type';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const meta = {
 | 
					export const meta = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
import define from '../define';
 | 
					import define from '../define';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { DriveFiles } from '../../../models';
 | 
					import { DriveFiles } from '../../../models';
 | 
				
			||||||
import { types, bool } from '../../../misc/schema';
 | 
					import { types, bool } from '../../../misc/schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async (ps, user) => {
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Calculate drive usage
 | 
						// Calculate drive usage
 | 
				
			||||||
	const usage = await DriveFiles.clacDriveUsageOf(user);
 | 
						const usage = await DriveFiles.clacDriveUsageOf(user);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import { Instances } from '../../../../models';
 | 
					import { Instances } from '../../../../models';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const meta = {
 | 
					export const meta = {
 | 
				
			||||||
	tags: ['federation'],
 | 
						tags: ['federation'],
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ export default define(meta, async (ps, me) => {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (typeof ps.blocked === 'boolean') {
 | 
						if (typeof ps.blocked === 'boolean') {
 | 
				
			||||||
		const meta = await fetchMeta();
 | 
							const meta = await fetchMeta(true);
 | 
				
			||||||
		if (ps.blocked) {
 | 
							if (ps.blocked) {
 | 
				
			||||||
			query.andWhere('instance.host IN (:...blocks)', { blocks: meta.blockedHosts });
 | 
								query.andWhere('instance.host IN (:...blocks)', { blocks: meta.blockedHosts });
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
import { Note } from '../../../../models/entities/note';
 | 
					import { Note } from '../../../../models/entities/note';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async () => {
 | 
					export default define(meta, async () => {
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
	const hiddenTags = instance.hiddenTags.map(t => t.toLowerCase());
 | 
						const hiddenTags = instance.hiddenTags.map(t => t.toLowerCase());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const tagNotes = await Notes.createQueryBuilder('note')
 | 
						const tagNotes = await Notes.createQueryBuilder('note')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import $ from 'cafy';
 | 
				
			||||||
import { publishMainStream } from '../../../../services/stream';
 | 
					import { publishMainStream } from '../../../../services/stream';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import * as nodemailer from 'nodemailer';
 | 
					import * as nodemailer from 'nodemailer';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import rndstr from 'rndstr';
 | 
					import rndstr from 'rndstr';
 | 
				
			||||||
import config from '../../../../config';
 | 
					import config from '../../../../config';
 | 
				
			||||||
import * as ms from 'ms';
 | 
					import * as ms from 'ms';
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ export default define(meta, async (ps, user) => {
 | 
				
			||||||
			emailVerifyCode: code
 | 
								emailVerifyCode: code
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const meta = await fetchMeta();
 | 
							const meta = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const enableAuth = meta.smtpUser != null && meta.smtpUser !== '';
 | 
							const enableAuth = meta.smtpUser != null && meta.smtpUser !== '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import $ from 'cafy';
 | 
				
			||||||
import * as os from 'os';
 | 
					import * as os from 'os';
 | 
				
			||||||
import config from '../../../config';
 | 
					import config from '../../../config';
 | 
				
			||||||
import define from '../define';
 | 
					import define from '../define';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import * as pkg from '../../../../package.json';
 | 
					import * as pkg from '../../../../package.json';
 | 
				
			||||||
import { Emojis } from '../../../models';
 | 
					import { Emojis } from '../../../models';
 | 
				
			||||||
import { types, bool } from '../../../misc/schema';
 | 
					import { types, bool } from '../../../misc/schema';
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async (ps, me) => {
 | 
					export default define(meta, async (ps, me) => {
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const emojis = await Emojis.find({ host: null });
 | 
						const emojis = await Emojis.find({ host: null });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ import * as ms from 'ms';
 | 
				
			||||||
import { length } from 'stringz';
 | 
					import { length } from 'stringz';
 | 
				
			||||||
import create from '../../../../services/note/create';
 | 
					import create from '../../../../services/note/create';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { ApiError } from '../../error';
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
import { ID } from '../../../../misc/cafy-id';
 | 
					import { ID } from '../../../../misc/cafy-id';
 | 
				
			||||||
import { User } from '../../../../models/entities/user';
 | 
					import { User } from '../../../../models/entities/user';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import { ID } from '../../../../misc/cafy-id';
 | 
					import { ID } from '../../../../misc/cafy-id';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { ApiError } from '../../error';
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
import { makePaginationQuery } from '../../common/make-pagination-query';
 | 
					import { makePaginationQuery } from '../../common/make-pagination-query';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,6 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async (ps, user) => {
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
	// TODO どっかにキャッシュ
 | 
					 | 
				
			||||||
	const m = await fetchMeta();
 | 
						const m = await fetchMeta();
 | 
				
			||||||
	if (m.disableGlobalTimeline) {
 | 
						if (m.disableGlobalTimeline) {
 | 
				
			||||||
		if (user == null || (!user.isAdmin && !user.isModerator)) {
 | 
							if (user == null || (!user.isAdmin && !user.isModerator)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import { ID } from '../../../../misc/cafy-id';
 | 
					import { ID } from '../../../../misc/cafy-id';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { ApiError } from '../../error';
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
import { makePaginationQuery } from '../../common/make-pagination-query';
 | 
					import { makePaginationQuery } from '../../common/make-pagination-query';
 | 
				
			||||||
import { Followings, Notes } from '../../../../models';
 | 
					import { Followings, Notes } from '../../../../models';
 | 
				
			||||||
| 
						 | 
					@ -109,7 +109,6 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async (ps, user) => {
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
	// TODO どっかにキャッシュ
 | 
					 | 
				
			||||||
	const m = await fetchMeta();
 | 
						const m = await fetchMeta();
 | 
				
			||||||
	if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
 | 
						if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
 | 
				
			||||||
		throw new ApiError(meta.errors.stlDisabled);
 | 
							throw new ApiError(meta.errors.stlDisabled);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import { ID } from '../../../../misc/cafy-id';
 | 
					import { ID } from '../../../../misc/cafy-id';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { ApiError } from '../../error';
 | 
					import { ApiError } from '../../error';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
import { generateMuteQuery } from '../../common/generate-mute-query';
 | 
					import { generateMuteQuery } from '../../common/generate-mute-query';
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,6 @@ export const meta = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default define(meta, async (ps, user) => {
 | 
					export default define(meta, async (ps, user) => {
 | 
				
			||||||
	// TODO どっかにキャッシュ
 | 
					 | 
				
			||||||
	const m = await fetchMeta();
 | 
						const m = await fetchMeta();
 | 
				
			||||||
	if (m.disableLocalTimeline) {
 | 
						if (m.disableLocalTimeline) {
 | 
				
			||||||
		if (user == null || (!user.isAdmin && !user.isModerator)) {
 | 
							if (user == null || (!user.isAdmin && !user.isModerator)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import define from '../../define';
 | 
					import define from '../../define';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { genId } from '../../../../misc/gen-id';
 | 
					import { genId } from '../../../../misc/gen-id';
 | 
				
			||||||
import { SwSubscriptions } from '../../../../models';
 | 
					import { SwSubscriptions } from '../../../../models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ export default define(meta, async (ps, user) => {
 | 
				
			||||||
		publickey: ps.publickey,
 | 
							publickey: ps.publickey,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (exist != null) {
 | 
						if (exist != null) {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs';
 | 
				
			||||||
import { generateKeyPair } from 'crypto';
 | 
					import { generateKeyPair } from 'crypto';
 | 
				
			||||||
import generateUserToken from '../common/generate-native-user-token';
 | 
					import generateUserToken from '../common/generate-native-user-token';
 | 
				
			||||||
import config from '../../../config';
 | 
					import config from '../../../config';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import * as recaptcha from 'recaptcha-promise';
 | 
					import * as recaptcha from 'recaptcha-promise';
 | 
				
			||||||
import { Users, RegistrationTickets } from '../../../models';
 | 
					import { Users, RegistrationTickets } from '../../../models';
 | 
				
			||||||
import { genId } from '../../../misc/gen-id';
 | 
					import { genId } from '../../../misc/gen-id';
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ import { getConnection } from 'typeorm';
 | 
				
			||||||
export default async (ctx: Koa.BaseContext) => {
 | 
					export default async (ctx: Koa.BaseContext) => {
 | 
				
			||||||
	const body = ctx.request.body as any;
 | 
						const body = ctx.request.body as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify recaptcha
 | 
						// Verify recaptcha
 | 
				
			||||||
	// ただしテスト時はこの機構は障害となるため無効にする
 | 
						// ただしテスト時はこの機構は障害となるため無効にする
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
 | 
				
			||||||
import redis from '../../../db/redis';
 | 
					import redis from '../../../db/redis';
 | 
				
			||||||
import * as uuid from 'uuid';
 | 
					import * as uuid from 'uuid';
 | 
				
			||||||
import signin from '../common/signin';
 | 
					import signin from '../common/signin';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { Users, UserProfiles } from '../../../models';
 | 
					import { Users, UserProfiles } from '../../../models';
 | 
				
			||||||
import { ILocalUser } from '../../../models/entities/user';
 | 
					import { ILocalUser } from '../../../models/entities/user';
 | 
				
			||||||
import { ensure } from '../../../prelude/ensure';
 | 
					import { ensure } from '../../../prelude/ensure';
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ router.get('/disconnect/discord', async ctx => {
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getOAuth2() {
 | 
					async function getOAuth2() {
 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (meta.enableDiscordIntegration) {
 | 
						if (meta.enableDiscordIntegration) {
 | 
				
			||||||
		return new OAuth2(
 | 
							return new OAuth2(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
 | 
				
			||||||
import redis from '../../../db/redis';
 | 
					import redis from '../../../db/redis';
 | 
				
			||||||
import * as uuid from 'uuid';
 | 
					import * as uuid from 'uuid';
 | 
				
			||||||
import signin from '../common/signin';
 | 
					import signin from '../common/signin';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { Users, UserProfiles } from '../../../models';
 | 
					import { Users, UserProfiles } from '../../../models';
 | 
				
			||||||
import { ILocalUser } from '../../../models/entities/user';
 | 
					import { ILocalUser } from '../../../models/entities/user';
 | 
				
			||||||
import { ensure } from '../../../prelude/ensure';
 | 
					import { ensure } from '../../../prelude/ensure';
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ router.get('/disconnect/github', async ctx => {
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getOath2() {
 | 
					async function getOath2() {
 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (meta.enableGithubIntegration && meta.githubClientId && meta.githubClientSecret) {
 | 
						if (meta.enableGithubIntegration && meta.githubClientId && meta.githubClientSecret) {
 | 
				
			||||||
		return new OAuth2(
 | 
							return new OAuth2(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ import redis from '../../../db/redis';
 | 
				
			||||||
import { publishMainStream } from '../../../services/stream';
 | 
					import { publishMainStream } from '../../../services/stream';
 | 
				
			||||||
import config from '../../../config';
 | 
					import config from '../../../config';
 | 
				
			||||||
import signin from '../common/signin';
 | 
					import signin from '../common/signin';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { Users, UserProfiles } from '../../../models';
 | 
					import { Users, UserProfiles } from '../../../models';
 | 
				
			||||||
import { ILocalUser } from '../../../models/entities/user';
 | 
					import { ILocalUser } from '../../../models/entities/user';
 | 
				
			||||||
import { ensure } from '../../../prelude/ensure';
 | 
					import { ensure } from '../../../prelude/ensure';
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ router.get('/disconnect/twitter', async ctx => {
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getTwAuth() {
 | 
					async function getTwAuth() {
 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (meta.enableTwitterIntegration && meta.twitterConsumerKey && meta.twitterConsumerSecret) {
 | 
						if (meta.enableTwitterIntegration && meta.twitterConsumerKey && meta.twitterConsumerSecret) {
 | 
				
			||||||
		return autwh({
 | 
							return autwh({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import autobind from 'autobind-decorator';
 | 
					import autobind from 'autobind-decorator';
 | 
				
			||||||
import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
					import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
				
			||||||
import Channel from '../channel';
 | 
					import Channel from '../channel';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
import { PackedNote } from '../../../../models/repositories/note';
 | 
					import { PackedNote } from '../../../../models/repositories/note';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import autobind from 'autobind-decorator';
 | 
					import autobind from 'autobind-decorator';
 | 
				
			||||||
import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
					import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
				
			||||||
import Channel from '../channel';
 | 
					import Channel from '../channel';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
import { PackedNote } from '../../../../models/repositories/note';
 | 
					import { PackedNote } from '../../../../models/repositories/note';
 | 
				
			||||||
import { PackedUser } from '../../../../models/repositories/user';
 | 
					import { PackedUser } from '../../../../models/repositories/user';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import autobind from 'autobind-decorator';
 | 
					import autobind from 'autobind-decorator';
 | 
				
			||||||
import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
					import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 | 
				
			||||||
import Channel from '../channel';
 | 
					import Channel from '../channel';
 | 
				
			||||||
import fetchMeta from '../../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../../misc/fetch-meta';
 | 
				
			||||||
import { Notes } from '../../../../models';
 | 
					import { Notes } from '../../../../models';
 | 
				
			||||||
import { PackedNote } from '../../../../models/repositories/note';
 | 
					import { PackedNote } from '../../../../models/repositories/note';
 | 
				
			||||||
import { PackedUser } from '../../../../models/repositories/user';
 | 
					import { PackedUser } from '../../../../models/repositories/user';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import * as Router from 'koa-router';
 | 
					import * as Router from 'koa-router';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
import fetchMeta from '../misc/fetch-meta';
 | 
					import { fetchMeta } from '../misc/fetch-meta';
 | 
				
			||||||
// import User from '../models/user';
 | 
					// import User from '../models/user';
 | 
				
			||||||
import { name as softwareName, version, repository } from '../../package.json';
 | 
					import { name as softwareName, version, repository } from '../../package.json';
 | 
				
			||||||
// import Note from '../models/note';
 | 
					// import Note from '../models/note';
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ const nodeinfo2 = async () => {
 | 
				
			||||||
		// localPosts,
 | 
							// localPosts,
 | 
				
			||||||
		// localComments
 | 
							// localComments
 | 
				
			||||||
	] = await Promise.all([
 | 
						] = await Promise.all([
 | 
				
			||||||
		fetchMeta(),
 | 
							fetchMeta(true),
 | 
				
			||||||
		// User.count({ host: null }),
 | 
							// User.count({ host: null }),
 | 
				
			||||||
		// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 15552000000) } }),
 | 
							// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 15552000000) } }),
 | 
				
			||||||
		// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 2592000000) } }),
 | 
							// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 2592000000) } }),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ import * as views from 'koa-views';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import docs from './docs';
 | 
					import docs from './docs';
 | 
				
			||||||
import packFeed from './feed';
 | 
					import packFeed from './feed';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
import * as pkg from '../../../package.json';
 | 
					import * as pkg from '../../../package.json';
 | 
				
			||||||
import { genOpenapiSpec } from '../api/openapi/gen-spec';
 | 
					import { genOpenapiSpec } from '../api/openapi/gen-spec';
 | 
				
			||||||
import config from '../../config';
 | 
					import config from '../../config';
 | 
				
			||||||
| 
						 | 
					@ -206,7 +206,7 @@ router.get('/notes/:note', async ctx => {
 | 
				
			||||||
//#endregion
 | 
					//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get('/info', async ctx => {
 | 
					router.get('/info', async ctx => {
 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta(true);
 | 
				
			||||||
	const emojis = await Emojis.find({
 | 
						const emojis = await Emojis.find({
 | 
				
			||||||
		where: { host: null }
 | 
							where: { host: null }
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
import * as Koa from 'koa';
 | 
					import * as Koa from 'koa';
 | 
				
			||||||
import * as manifest from '../../client/assets/manifest.json';
 | 
					import * as manifest from '../../client/assets/manifest.json';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = async (ctx: Koa.BaseContext) => {
 | 
					module.exports = async (ctx: Koa.BaseContext) => {
 | 
				
			||||||
	const json = JSON.parse(JSON.stringify(manifest));
 | 
						const json = JSON.parse(JSON.stringify(manifest));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const instance = await fetchMeta();
 | 
						const instance = await fetchMeta(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	json.short_name = instance.name || 'Misskey';
 | 
						json.short_name = instance.name || 'Misskey';
 | 
				
			||||||
	json.name = instance.name || 'Misskey';
 | 
						json.name = instance.name || 'Misskey';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import * as Koa from 'koa';
 | 
					import * as Koa from 'koa';
 | 
				
			||||||
import * as request from 'request-promise-native';
 | 
					import * as request from 'request-promise-native';
 | 
				
			||||||
import summaly from 'summaly';
 | 
					import summaly from 'summaly';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
import Logger from '../../services/logger';
 | 
					import Logger from '../../services/logger';
 | 
				
			||||||
import config from '../../config';
 | 
					import config from '../../config';
 | 
				
			||||||
import { query } from '../../prelude/url';
 | 
					import { query } from '../../prelude/url';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ import * as sharp from 'sharp';
 | 
				
			||||||
import { publishMainStream, publishDriveStream } from '../stream';
 | 
					import { publishMainStream, publishDriveStream } from '../stream';
 | 
				
			||||||
import delFile from './delete-file';
 | 
					import delFile from './delete-file';
 | 
				
			||||||
import config from '../../config';
 | 
					import config from '../../config';
 | 
				
			||||||
import fetchMeta from '../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../misc/fetch-meta';
 | 
				
			||||||
import { GenerateVideoThumbnail } from './generate-video-thumbnail';
 | 
					import { GenerateVideoThumbnail } from './generate-video-thumbnail';
 | 
				
			||||||
import { driveLogger } from './logger';
 | 
					import { driveLogger } from './logger';
 | 
				
			||||||
import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
 | 
					import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ import { deliver } from '../../../queue';
 | 
				
			||||||
import { renderActivity } from '../../../remote/activitypub/renderer';
 | 
					import { renderActivity } from '../../../remote/activitypub/renderer';
 | 
				
			||||||
import { IdentifiableError } from '../../../misc/identifiable-error';
 | 
					import { IdentifiableError } from '../../../misc/identifiable-error';
 | 
				
			||||||
import { toDbReaction } from '../../../misc/reaction-lib';
 | 
					import { toDbReaction } from '../../../misc/reaction-lib';
 | 
				
			||||||
import fetchMeta from '../../../misc/fetch-meta';
 | 
					import { fetchMeta } from '../../../misc/fetch-meta';
 | 
				
			||||||
import { User } from '../../../models/entities/user';
 | 
					import { User } from '../../../models/entities/user';
 | 
				
			||||||
import { Note } from '../../../models/entities/note';
 | 
					import { Note } from '../../../models/entities/note';
 | 
				
			||||||
import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
 | 
					import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import * as push from 'web-push';
 | 
					import * as push from 'web-push';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
import { SwSubscriptions } from '../models';
 | 
					import { SwSubscriptions } from '../models';
 | 
				
			||||||
import fetchMeta from '../misc/fetch-meta';
 | 
					import { fetchMeta } from '../misc/fetch-meta';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async function(userId: string, type: string, body?: any) {
 | 
					export default async function(userId: string, type: string, body?: any) {
 | 
				
			||||||
	const meta = await fetchMeta();
 | 
						const meta = await fetchMeta();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue