perf(backend): cache local custom emojis
This commit is contained in:
		@@ -4,7 +4,7 @@ import type { NotesRepository, UsersRepository } from '@/models/index.js';
 | 
			
		||||
import type { Config } from '@/config.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 | 
			
		||||
import { MemoryCache } from '@/misc/cache.js';
 | 
			
		||||
import { MemorySingleCache } from '@/misc/cache.js';
 | 
			
		||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import NotesChart from '@/core/chart/charts/notes.js';
 | 
			
		||||
@@ -118,7 +118,7 @@ export class NodeinfoServerService {
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		const cache = new MemoryCache<Awaited<ReturnType<typeof nodeinfo2>>>(1000 * 60 * 10);
 | 
			
		||||
		const cache = new MemorySingleCache<Awaited<ReturnType<typeof nodeinfo2>>>(1000 * 60 * 10);
 | 
			
		||||
 | 
			
		||||
		fastify.get(nodeinfo2_1path, async (request, reply) => {
 | 
			
		||||
			const base = await cache.fetch(() => nodeinfo2());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, In } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -26,38 +22,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['ids', 'aliases'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const emojis = await this.emojisRepository.findBy({
 | 
			
		||||
				id: In(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			for (const emoji of emojis) {
 | 
			
		||||
				await this.emojisRepository.update(emoji.id, {
 | 
			
		||||
					updatedAt: new Date(),
 | 
			
		||||
					aliases: [...new Set(emoji.aliases.concat(ps.aliases))],
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiUpdated', {
 | 
			
		||||
				emojis: await this.emojiEntityService.packDetailedMany(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.addAliasesBulk(ps.ids, ps.aliases);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -90,8 +90,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
				license: emoji.license,
 | 
			
		||||
			}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiAdded', {
 | 
			
		||||
				emoji: await this.emojiEntityService.packDetailed(copied.id),
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, In } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -24,38 +19,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['ids'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private moderationLogService: ModerationLogService,
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const emojis = await this.emojisRepository.findBy({
 | 
			
		||||
				id: In(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			for (const emoji of emojis) {
 | 
			
		||||
				await this.emojisRepository.delete(emoji.id);
 | 
			
		||||
				await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
				this.moderationLogService.insertModerationLog(me, 'deleteEmoji', {
 | 
			
		||||
					emoji: emoji,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiDeleted', {
 | 
			
		||||
				emojis: await this.emojiEntityService.packDetailedMany(emojis),
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.deleteBulk(ps.ids);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { ApiError } from '../../../error.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -31,38 +25,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['id'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private moderationLogService: ModerationLogService,
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const emoji = await this.emojisRepository.findOneBy({ id: ps.id });
 | 
			
		||||
 | 
			
		||||
			if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
 | 
			
		||||
 | 
			
		||||
			await this.emojisRepository.delete(emoji.id);
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiDeleted', {
 | 
			
		||||
				emojis: [await this.emojiEntityService.packDetailed(emoji)],
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.moderationLogService.insertModerationLog(me, 'deleteEmoji', {
 | 
			
		||||
				emoji: emoji,
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.delete(ps.id);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, In } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -26,38 +22,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['ids', 'aliases'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const emojis = await this.emojisRepository.findBy({
 | 
			
		||||
				id: In(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			for (const emoji of emojis) {
 | 
			
		||||
				await this.emojisRepository.update(emoji.id, {
 | 
			
		||||
					updatedAt: new Date(),
 | 
			
		||||
					aliases: emoji.aliases.filter(x => !ps.aliases.includes(x)),
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
		
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiUpdated', {
 | 
			
		||||
				emojis: await this.emojiEntityService.packDetailedMany(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.removeAliasesBulk(ps.ids, ps.aliases);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, In } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -26,34 +22,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['ids', 'aliases'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			await this.emojisRepository.update({
 | 
			
		||||
				id: In(ps.ids),
 | 
			
		||||
			}, {
 | 
			
		||||
				updatedAt: new Date(),
 | 
			
		||||
				aliases: ps.aliases,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiUpdated', {
 | 
			
		||||
				emojis: await this.emojiEntityService.packDetailedMany(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.setAliasesBulk(ps.ids, ps.aliases);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, In } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
@@ -28,34 +24,14 @@ export const paramDef = {
 | 
			
		||||
	required: ['ids'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			await this.emojisRepository.update({
 | 
			
		||||
				id: In(ps.ids),
 | 
			
		||||
			}, {
 | 
			
		||||
				updatedAt: new Date(),
 | 
			
		||||
				category: ps.category,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			this.globalEventService.publishBroadcastStream('emojiUpdated', {
 | 
			
		||||
				emojis: await this.emojiEntityService.packDetailedMany(ps.ids),
 | 
			
		||||
			});
 | 
			
		||||
			await this.customEmojiService.setCategoryBulk(ps.ids, ps.category ?? null);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DataSource, IsNull } from 'typeorm';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { EmojisRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
import { ApiError } from '../../../error.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
@@ -45,51 +41,19 @@ export const paramDef = {
 | 
			
		||||
	required: ['id', 'name', 'aliases'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.emojisRepository)
 | 
			
		||||
		private emojisRepository: EmojisRepository,
 | 
			
		||||
 | 
			
		||||
		private emojiEntityService: EmojiEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const emoji = await this.emojisRepository.findOneBy({ id: ps.id });
 | 
			
		||||
			const sameNameEmoji = await this.emojisRepository.findOneBy({ name: ps.name, host: IsNull() });
 | 
			
		||||
			if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
 | 
			
		||||
			if (sameNameEmoji != null && sameNameEmoji.id !== ps.id) throw new ApiError(meta.errors.sameNameEmojiExists);
 | 
			
		||||
			await this.emojisRepository.update(emoji.id, {
 | 
			
		||||
				updatedAt: new Date(),
 | 
			
		||||
			await this.customEmojiService.update(ps.id, {
 | 
			
		||||
				name: ps.name,
 | 
			
		||||
				category: ps.category,
 | 
			
		||||
				category: ps.category ?? null,
 | 
			
		||||
				aliases: ps.aliases,
 | 
			
		||||
				license: ps.license,
 | 
			
		||||
				license: ps.license ?? null,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			await this.db.queryResultCache?.remove(['meta_emojis']);
 | 
			
		||||
 | 
			
		||||
			const updated = await this.emojiEntityService.packDetailed(emoji.id);
 | 
			
		||||
 | 
			
		||||
			if (emoji.name === ps.name) {
 | 
			
		||||
				this.globalEventService.publishBroadcastStream('emojiUpdated', {
 | 
			
		||||
					emojis: [updated],
 | 
			
		||||
				});
 | 
			
		||||
			} else {
 | 
			
		||||
				this.globalEventService.publishBroadcastStream('emojiDeleted', {
 | 
			
		||||
					emojis: [await this.emojiEntityService.packDetailed(emoji)],
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				this.globalEventService.publishBroadcastStream('emojiAdded', {
 | 
			
		||||
					emoji: updated,
 | 
			
		||||
				});	
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,10 +58,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
					category: 'ASC',
 | 
			
		||||
					name: 'ASC',
 | 
			
		||||
				},
 | 
			
		||||
				cache: {
 | 
			
		||||
					id: 'meta_emojis',
 | 
			
		||||
					milliseconds: 3600000,	// 1 hour
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			return {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user