move global services to "global" directory
This commit is contained in:
parent
00b216c83c
commit
a55649e89a
192 changed files with 223 additions and 223 deletions
|
|
@ -23,7 +23,7 @@ import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js';
|
|||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { IdService } from './IdService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import { RoleService } from '@/core/RoleService.js';
|
|||
import { AntennaService } from '@/core/AntennaService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { UserListService } from '@/core/UserListService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class AccountMoveService {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { NotificationService } from '@/core/NotificationService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { ACHIEVEMENT_TYPES } from '@/models/UserProfile.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
|
|||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class AnnouncementService {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import type { ApContextsRepository, ApFetchLogsRepository, ApInboxLogsRepository
|
|||
import type { Config } from '@/config.js';
|
||||
import { JsonValue } from '@/misc/json-value.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { IActivity, IObject } from './activitypub/type.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import { bindThis } from '@/decorators.js';
|
|||
import { MemorySingleCache } from '@/misc/cache.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/core/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/global/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class AvatarDecorationService implements OnApplicationShutdown {
|
||||
|
|
|
|||
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||
import * as Redis from 'ioredis';
|
||||
import {
|
||||
MemoryKVCache,
|
||||
MemorySingleCache,
|
||||
RedisKVCache,
|
||||
RedisSingleCache,
|
||||
type RedisKVCacheOpts,
|
||||
type RedisSingleCacheOpts,
|
||||
} from '@/misc/cache.js';
|
||||
import { QuantumKVCache, type QuantumKVOpts } from '@/misc/QuantumKVCache.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { TimeService, type TimerHandle } from '@/core/TimeService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
|
||||
// This is the one place that's *supposed* to new() up caches.
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
|
||||
export type ManagedMemoryKVCache<T> = Managed<MemoryKVCache<T>>;
|
||||
export type ManagedMemorySingleCache<T> = Managed<MemorySingleCache<T>>;
|
||||
export type ManagedRedisKVCache<T> = Managed<RedisKVCache<T>>;
|
||||
export type ManagedRedisSingleCache<T> = Managed<RedisSingleCache<T>>;
|
||||
export type ManagedQuantumKVCache<T> = Managed<QuantumKVCache<T>>;
|
||||
|
||||
export type Managed<T> = Omit<T, 'dispose' | 'onApplicationShutdown' | 'gc'>;
|
||||
export type Manager = { dispose(): void, clear(): void, gc(): void };
|
||||
|
||||
export const GC_INTERVAL = 1000 * 60 * 3; // 3m
|
||||
|
||||
/**
|
||||
* Creates and "manages" instances of any standard cache type.
|
||||
* Instances produced by this class are automatically tracked for disposal when the application shuts down.
|
||||
*/
|
||||
@Injectable()
|
||||
export class CacheManagementService implements OnApplicationShutdown {
|
||||
private readonly managedCaches = new Set<Manager>();
|
||||
private gcTimer?: TimerHandle | null;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.redis)
|
||||
private readonly redisClient: Redis.Redis,
|
||||
|
||||
private readonly timeService: TimeService,
|
||||
private readonly internalEventService: InternalEventService,
|
||||
) {}
|
||||
|
||||
private get cacheServices() {
|
||||
return {
|
||||
internalEventService: this.internalEventService,
|
||||
redisClient: this.redisClient,
|
||||
timeService: this.timeService,
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createMemoryKVCache<T>(lifetime: number): ManagedMemoryKVCache<T> {
|
||||
const cache = new MemoryKVCache<T>(lifetime, this.cacheServices);
|
||||
return this.manageCache(cache);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createMemorySingleCache<T>(lifetime: number): ManagedMemorySingleCache<T> {
|
||||
const cache = new MemorySingleCache<T>(lifetime, this.cacheServices);
|
||||
return this.manageCache(cache);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createRedisKVCache<T>(name: string, opts: RedisKVCacheOpts<T>): ManagedRedisKVCache<T> {
|
||||
const cache = new RedisKVCache<T>(name, this.cacheServices, opts);
|
||||
return this.manageCache(cache);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createRedisSingleCache<T>(name: string, opts: RedisSingleCacheOpts<T>): ManagedRedisSingleCache<T> {
|
||||
const cache = new RedisSingleCache<T>(name, this.cacheServices, opts);
|
||||
return this.manageCache(cache);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public createQuantumKVCache<T>(name: string, opts: QuantumKVOpts<T>): ManagedQuantumKVCache<T> {
|
||||
const cache = new QuantumKVCache<T>(name, this.cacheServices, opts);
|
||||
return this.manageCache(cache);
|
||||
}
|
||||
|
||||
protected manageCache<T extends Manager>(cache: T): Managed<T> {
|
||||
this.managedCaches.add(cache);
|
||||
this.startGcTimer();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public gc(): void {
|
||||
this.resetGcTimer(() => {
|
||||
// TODO callAll()
|
||||
for (const manager of this.managedCaches) {
|
||||
manager.gc();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public clear(): void {
|
||||
this.resetGcTimer(() => {
|
||||
for (const manager of this.managedCaches) {
|
||||
manager.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async dispose(): Promise<void> {
|
||||
this.stopGcTimer();
|
||||
for (const manager of this.managedCaches) {
|
||||
manager.dispose();
|
||||
}
|
||||
this.managedCaches.clear();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async onApplicationShutdown(): Promise<void> {
|
||||
await this.dispose();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private startGcTimer() {
|
||||
// Only start it once, and don't *re* start since this gets called repeatedly.
|
||||
this.gcTimer ??= this.timeService.startTimer(this.gc, GC_INTERVAL, { repeated: true });
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private stopGcTimer() {
|
||||
// Only stop it once, then clear the value so it can be restarted later.
|
||||
if (this.gcTimer != null) {
|
||||
this.timeService.stopTimer(this.gcTimer);
|
||||
this.gcTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private resetGcTimer(onBlank?: () => void): void {
|
||||
this.stopGcTimer();
|
||||
|
||||
try {
|
||||
if (onBlank) {
|
||||
onBlank();
|
||||
}
|
||||
} finally {
|
||||
this.startGcTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,13 +13,13 @@ import { isLocalUser, isRemoteUser } from '@/models/User.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { InternalEventTypes } from '@/core/GlobalEventService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import {
|
||||
CacheManagementService,
|
||||
type ManagedMemoryKVCache,
|
||||
type ManagedQuantumKVCache,
|
||||
} from '@/core/CacheManagementService.js';
|
||||
} from '@/global/CacheManagementService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
export interface FollowStats {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { IdService } from '@/core/IdService.js';
|
|||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { MiLocalUser } from '@/models/User.js';
|
||||
import { InternalEventService } from './InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
|
||||
@Injectable()
|
||||
export class ChannelFollowingService {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
|||
import { emojiRegex } from '@/misc/emoji-regex.js';
|
||||
import { NotificationService } from '@/core/NotificationService.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
const MAX_ROOM_MEMBERS = 30;
|
||||
const MAX_REACTIONS_PER_MESSAGE = 100;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js
|
|||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { MiLocalUser } from '@/models/User.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class ClipService {
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ import type { Serialized } from '@/types.js';
|
|||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { DriveService } from '@/core/DriveService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/core/CacheManagementService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/global/CacheManagementService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { isRetryableSymbol } from '@/misc/is-retryable-error.js';
|
||||
import { KeyNotFoundError } from '@/misc/QuantumKVCache.js';
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import nodePath from 'node:path';
|
||||
import nodeFs from 'node:fs';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { type ManagedMemoryKVCache, CacheManagementService } from '@/core/CacheManagementService.js';
|
||||
|
||||
/**
|
||||
* Provides structured, mockable access to runtime/environment details.
|
||||
*/
|
||||
@Injectable()
|
||||
export class EnvService {
|
||||
protected readonly dependencyVersionCache: ManagedMemoryKVCache<string | null>;
|
||||
|
||||
constructor(cacheManagementService: CacheManagementService) {
|
||||
this.dependencyVersionCache = cacheManagementService.createMemoryKVCache<string | null>(Infinity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment variables of the process.
|
||||
* Can be modified, but modifications are not reflected to the operating system environment.
|
||||
*/
|
||||
public get env(): Partial<Record<string, string>> {
|
||||
return process.env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the installed version of a given dependency, or null if not installed.
|
||||
*/
|
||||
@bindThis
|
||||
public async getDependencyVersion(dependency: string): Promise<string | null> {
|
||||
return await this.dependencyVersionCache.fetch(dependency, async () => {
|
||||
const packageJsonPath = nodePath.join(import.meta.dirname, '../../package.json');
|
||||
const packageJsonText = nodeFs.readFileSync(packageJsonPath, 'utf8');
|
||||
|
||||
// No "dependencies" section -> infer not installed.
|
||||
const packageJson = JSON.parse(packageJsonText) as { dependencies?: Partial<Record<string, string>> };
|
||||
if (packageJson.dependencies == null) return null;
|
||||
|
||||
// Not listed -> not installed.
|
||||
const version = packageJson.dependencies['mfm-js'];
|
||||
if (version == null) return null;
|
||||
|
||||
// Just in case some other value is there
|
||||
return String(version);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import * as Redis from 'ioredis';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
export type FanoutTimelineName = (
|
||||
// home timeline
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { MiGalleryPost, MiNote, MiUser } from '@/models/_.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
const GLOBAL_NOTES_RANKING_WINDOW = 1000 * 60 * 60 * 24 * 3; // 3日ごと
|
||||
export const GALLERY_POSTS_RANKING_WINDOW = 1000 * 60 * 60 * 24 * 3; // 3日ごと
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ import type { InternalEventTypes } from '@/core/GlobalEventService.js';
|
|||
import { IdService } from '@/core/IdService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/core/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/global/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { diffArraysSimple } from '@/misc/diff-arrays.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { LoggerService } from '@/core/LoggerService.js';
|
|||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||
import type { CheerioAPI } from 'cheerio/slim';
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import type { Config } from '@/config.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Serialized } from '@/types.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||
import type Emitter from 'strict-event-emitter-types';
|
||||
import type { EventEmitter } from 'events';
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import type { HashtagsRepository, MiMeta } from '@/models/_.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { FeaturedService } from '@/core/FeaturedService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class HashtagService {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/val
|
|||
import type { IObject, IObjectWithId } from '@/core/activitypub/type.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { Response } from 'node-fetch';
|
||||
import type { Socket } from 'node:net';
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { ulid } from 'ulid';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { genAid, isSafeAidT, parseAid, parseAidFull } from '@/misc/id/aid.js';
|
||||
import { genAidx, isSafeAidxT, parseAidx, parseAidxFull } from '@/misc/id/aidx.js';
|
||||
import { genMeid, isSafeMeidT, parseMeid, parseMeidFull } from '@/misc/id/meid.js';
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { IsNull, MoreThan } from 'typeorm';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/core/CacheManagementService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/global/CacheManagementService.js';
|
||||
import NotesChart from '@/core/chart/charts/notes.js';
|
||||
import UsersChart from '@/core/chart/charts/users.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
export interface InstanceStats {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||
import Redis from 'ioredis';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { GlobalEvents, InternalEventTypes } from '@/core/GlobalEventService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
||||
export type Listener<K extends keyof InternalEventTypes> = (value: InternalEventTypes[K], key: K, isLocal: boolean) => void | Promise<void>;
|
||||
|
||||
export interface ListenerProps {
|
||||
ignoreLocal?: boolean,
|
||||
ignoreRemote?: boolean,
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class InternalEventService implements OnApplicationShutdown {
|
||||
private readonly listeners = new Map<keyof InternalEventTypes, Map<Listener<keyof InternalEventTypes>, ListenerProps>>();
|
||||
|
||||
constructor(
|
||||
@Inject(DI.redisForSub)
|
||||
private readonly redisForSub: Redis.Redis,
|
||||
|
||||
@Inject(DI.redis)
|
||||
private readonly redisForPub: Redis.Redis,
|
||||
|
||||
@Inject(DI.config)
|
||||
private readonly config: Pick<Config, 'host'>,
|
||||
) {
|
||||
this.redisForSub.on('message', this.onMessage);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public on<K extends keyof InternalEventTypes>(type: K, listener: Listener<K>, props?: ListenerProps): void {
|
||||
let set = this.listeners.get(type);
|
||||
if (!set) {
|
||||
set = new Map();
|
||||
this.listeners.set(type, set);
|
||||
}
|
||||
|
||||
// Functionally, this is just a set with metadata on the values.
|
||||
set.set(listener as Listener<keyof InternalEventTypes>, props ?? {});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public off<K extends keyof InternalEventTypes>(type: K, listener: Listener<K>): void {
|
||||
this.listeners.get(type)?.delete(listener as Listener<keyof InternalEventTypes>);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async emit<K extends keyof InternalEventTypes>(type: K, value: InternalEventTypes[K]): Promise<void> {
|
||||
await this.emitInternal(type, value, true);
|
||||
await this.redisForPub.publish(this.config.host, JSON.stringify({
|
||||
channel: 'internal',
|
||||
message: { type: type, body: value },
|
||||
}));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async emitInternal<K extends keyof InternalEventTypes>(type: K, value: InternalEventTypes[K], isLocal: boolean): Promise<void> {
|
||||
const listeners = this.listeners.get(type);
|
||||
if (!listeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
for (const [listener, props] of listeners) {
|
||||
if ((isLocal && !props.ignoreLocal) || (!isLocal && !props.ignoreRemote)) {
|
||||
const promise = Promise.resolve(listener(value, type, isLocal));
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async onMessage(_: string, data: string): Promise<void> {
|
||||
const obj = JSON.parse(data);
|
||||
|
||||
if (obj.channel === 'internal') {
|
||||
const { type, body } = obj.message as GlobalEvents['internal']['payload'];
|
||||
if (!isLocalInternalEvent(body) || body._pid !== process.pid) {
|
||||
await this.emitInternal(type, body as InternalEventTypes[keyof InternalEventTypes], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public dispose(): void {
|
||||
this.redisForSub.off('message', this.onMessage);
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public onApplicationShutdown(): void {
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
interface LocalInternalEvent {
|
||||
_pid: number;
|
||||
}
|
||||
|
||||
function isLocalInternalEvent(body: object): body is LocalInternalEvent {
|
||||
return '_pid' in body && typeof(body._pid) === 'number';
|
||||
}
|
||||
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Logger from '@/logger.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { KEYWORD } from 'color-convert/conversions.js';
|
||||
import { envOption } from '@/env.js';
|
||||
import { envOption } from '@/env.js'; // TODO move to envService
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { FeaturedService } from '@/core/FeaturedService.js';
|
||||
import { TimeService, type TimerHandle } from '@/core/TimeService.js';
|
||||
import { TimeService, type TimerHandle } from '@/global/TimeService.js';
|
||||
import { MiInstance } from '@/models/Instance.js';
|
||||
import { diffArrays } from '@/misc/diff-arrays.js';
|
||||
import type { MetasRepository } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import { IdentifiableError } from '@/misc/identifiable-error.js';
|
|||
import { LatestNoteService } from '@/core/LatestNoteService.js';
|
||||
import { CollapsedQueue } from '@/misc/collapsed-queue.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { NoteVisibilityService } from '@/core/NoteVisibilityService.js';
|
||||
import { isPureRenote } from '@/misc/is-renote.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { isQuote, isRenote } from '@/misc/is-renote.js';
|
|||
import { LatestNoteService } from '@/core/LatestNoteService.js';
|
||||
import { ApLogService } from '@/core/ApLogService.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ import { IdentifiableError } from '@/misc/identifiable-error.js';
|
|||
import { LatestNoteService } from '@/core/LatestNoteService.js';
|
||||
import { CollapsedQueue } from '@/misc/collapsed-queue.js';
|
||||
import { NoteCreateService } from '@/core/NoteCreateService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { NoteVisibilityService } from '@/core/NoteVisibilityService.js';
|
||||
import { isPureRenote } from '@/misc/is-renote.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import type { Config } from '@/config.js';
|
|||
import { UserListService } from '@/core/UserListService.js';
|
||||
import { FilterUnionByProperty, groupedNotificationTypes, obsoleteNotificationTypes } from '@/types.js';
|
||||
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService implements OnApplicationShutdown {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import type { Packed } from '@/misc/json-schema.js';
|
|||
import { getNoteSummary } from '@/misc/get-note-summary.js';
|
||||
import type { MiMeta, MiSwSubscription, SwSubscriptionsRepository } from '@/models/_.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/core/CacheManagementService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/global/CacheManagementService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
// Defined also packages/sw/types.ts#L13
|
||||
type PushNotificationsTypes = {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
|
||||
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { SystemWebhookPayload } from '@/core/SystemWebhookService.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { type UserWebhookPayload } from './UserWebhookService.js';
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
|
|||
import { PER_NOTE_REACTION_USER_PAIR_CACHE_MAX } from '@/const.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { NoteVisibilityService } from '@/core/NoteVisibilityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { DataSource } from 'typeorm';
|
||||
|
||||
const FALLBACK = '\u2764';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as Redis from 'ioredis';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { MiUser, NotesRepository } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import { IdService } from '@/core/IdService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class RegistryApiService {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import { deepClone } from '@/misc/clone.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
import { CacheManagementService, ManagedMemorySingleCache } from '@/core/CacheManagementService.js';
|
||||
import { CacheManagementService, ManagedMemorySingleCache } from '@/global/CacheManagementService.js';
|
||||
|
||||
@Injectable()
|
||||
export class RelayService {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { ILink, WebfingerService } from '@/core/WebfingerService.js';
|
|||
import { RemoteLoggerService } from '@/core/RemoteLoggerService.js';
|
||||
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
|
||||
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { NotificationService } from '@/core/NotificationService.js';
|
||||
import { Serialized } from '@/types.js';
|
||||
import { ReversiGameEntityService } from './entities/ReversiGameEntityService.js';
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
|
|||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import type { NotificationService } from '@/core/NotificationService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import {
|
||||
CacheManagementService,
|
||||
type ManagedMemorySingleCache,
|
||||
type ManagedMemoryKVCache,
|
||||
} from '@/core/CacheManagementService.js';
|
||||
} from '@/global/CacheManagementService.js';
|
||||
import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
|
||||
import { getCallerId } from '@/misc/attach-caller-id.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type { MiMeta } from '@/models/Meta.js';
|
|||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import type { InternalEventTypes } from '@/core/GlobalEventService.js';
|
||||
import type { DeleteObjectCommandInput, PutObjectCommandInput } from '@aws-sdk/client-s3';
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { UtilityService } from '@/core/UtilityService.js';
|
|||
import { UserService } from '@/core/UserService.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class SignupService {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import type { MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { CacheManagementService, type ManagedRedisKVCache } from '@/core/CacheManagementService.js';
|
||||
import { CacheManagementService, type ManagedRedisKVCache } from '@/global/CacheManagementService.js';
|
||||
|
||||
export interface Sponsor {
|
||||
MemberId: number;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ import { bindThis } from '@/decorators.js';
|
|||
import { generateNativeUserToken } from '@/misc/token.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
|
||||
import { CacheManagementService, type ManagedMemoryKVCache } from '@/core/CacheManagementService.js';
|
||||
import { CacheManagementService, type ManagedMemoryKVCache } from '@/global/CacheManagementService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
export const SYSTEM_ACCOUNT_TYPES = ['actor', 'relay', 'proxy'] as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ import Logger from '@/logger.js';
|
|||
import { Packed } from '@/misc/json-schema.js';
|
||||
import { AbuseReportResolveType } from '@/models/AbuseUserReport.js';
|
||||
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/core/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/global/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
export type AbuseReportPayload = {
|
||||
|
|
|
|||
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
||||
const timerTokenSymbol = Symbol('timerToken');
|
||||
|
||||
/**
|
||||
* Provides abstractions to access the current time.
|
||||
* Exists for unit testing purposes, so that tests can "simulate" any given time for consistency.
|
||||
*/
|
||||
@Injectable()
|
||||
export abstract class TimeService<TTimer extends Timer = Timer> implements OnApplicationShutdown {
|
||||
protected readonly timers = new Map<symbol, TTimer>();
|
||||
|
||||
protected constructor() {}
|
||||
|
||||
/**
|
||||
* Returns the current time, in milliseconds since the Unix epoch.
|
||||
*/
|
||||
public abstract get now(): number;
|
||||
|
||||
/**
|
||||
* Returns a new Date instance representing the current time.
|
||||
*/
|
||||
public get date(): Date {
|
||||
return new Date(this.now);
|
||||
}
|
||||
|
||||
public startTimer(callback: () => void, delay: number, opts?: TimerOpts): TimerHandle;
|
||||
public startTimer<T>(callback: (value: T) => void, delay: number, opts: TimerOpts | undefined, value: T): TimerHandle;
|
||||
@bindThis
|
||||
public startTimer<T = undefined>(callback: (value: T) => void, delay: number, opts?: TimerOpts, value?: T): TimerHandle {
|
||||
const timerId = Symbol();
|
||||
const repeating = opts?.repeated ?? false;
|
||||
|
||||
const timer = this.startNativeTimer(timerId, repeating, () => {
|
||||
callback(value as T); // overloads ensure it can't be null
|
||||
}, delay);
|
||||
this.timers.set(timerId, timer);
|
||||
|
||||
return timerId;
|
||||
}
|
||||
|
||||
public startPromiseTimer(delay: number): PromiseTimerHandle;
|
||||
public startPromiseTimer<T>(delay: number, value: T, opts?: PromiseTimerOpts): PromiseTimerHandle<T>;
|
||||
@bindThis
|
||||
public startPromiseTimer<T = undefined>(delay: number, value?: T, opts?: PromiseTimerOpts): PromiseTimerHandle<T> {
|
||||
const timerId = Symbol();
|
||||
const abortController = new AbortController();
|
||||
const abortSignal = opts?.signal ? AbortSignal.any([abortController.signal, opts.signal]) : abortController.signal;
|
||||
|
||||
const handlePromise = new Promise<T>((resolve, reject) => {
|
||||
// Connect AbortSignal
|
||||
abortSignal.throwIfAborted();
|
||||
abortSignal.addEventListener('abort', () => reject(abortSignal.reason));
|
||||
|
||||
// Start the underlying timer
|
||||
this.startTimer<T>(resolve, delay, undefined, value as T); // overloads ensure it can't be null
|
||||
});
|
||||
|
||||
// Make sure we dispose the real handle if promise rejects!
|
||||
handlePromise.catch(() => {
|
||||
this.stopTimer(timerId);
|
||||
});
|
||||
|
||||
// Populate and return the handle.
|
||||
return Object.assign(handlePromise, {
|
||||
[timerTokenSymbol]: timerId,
|
||||
|
||||
abort: (reason: Error) => {
|
||||
abortController.abort(reason);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract startNativeTimer(timerId: symbol, repeating: boolean, callback: () => void, delay: number): TTimer;
|
||||
|
||||
/**
|
||||
* Clears a registered timeout or interval.
|
||||
* Returns true if the registration exists and was still active, false otherwise.
|
||||
* Safe to call with invalid or expired IDs.
|
||||
*/
|
||||
@bindThis
|
||||
public stopTimer(handle: TimerHandle | PromiseTimerHandle): boolean {
|
||||
const id = typeof(handle) === 'object' ? handle[timerTokenSymbol] : handle;
|
||||
const reg = this.timers.get(id);
|
||||
if (!reg) return false;
|
||||
|
||||
this.stopNativeTimer(reg);
|
||||
this.timers.delete(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract stopNativeTimer(reg: TTimer): void;
|
||||
|
||||
/**
|
||||
* Cleanup all handles and references.
|
||||
* Safe to call multiple times.
|
||||
*
|
||||
* **Must be called before shutting down the app!**
|
||||
*/
|
||||
@bindThis
|
||||
public dispose(): void {
|
||||
for (const reg of this.timers.values()) {
|
||||
this.stopNativeTimer(reg);
|
||||
}
|
||||
this.timers.clear();
|
||||
}
|
||||
|
||||
@bindThis
|
||||
onApplicationShutdown(): void {
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export interface Timer {
|
||||
timerId: symbol;
|
||||
repeating: boolean;
|
||||
delay: number;
|
||||
callback: () => void;
|
||||
}
|
||||
|
||||
export interface TimerOpts {
|
||||
repeated?: boolean;
|
||||
}
|
||||
|
||||
export type TimerHandle = symbol;
|
||||
|
||||
export interface PromiseTimerOpts {
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
export interface PromiseTimerHandle<T = void> extends PromiseLike<T> {
|
||||
readonly [timerTokenSymbol]: symbol;
|
||||
abort(error?: Error): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of TimeService, uses Date.now() as time source and setTimeout/setInterval for timers.
|
||||
*/
|
||||
@Injectable()
|
||||
export class NativeTimeService extends TimeService<NativeTimer> implements OnApplicationShutdown {
|
||||
public get now(): number {
|
||||
// This is the one place that actually *should* have it
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected startNativeTimer(timerId: symbol, repeating: boolean, callback: () => void, delay: number): NativeTimer {
|
||||
// Wrap the caller's callback to make sure we clean up the registration.
|
||||
const wrappedCallback = () => {
|
||||
this.timers.delete(timerId);
|
||||
callback();
|
||||
};
|
||||
|
||||
const timeout = repeating
|
||||
? global.setInterval(wrappedCallback, delay)
|
||||
: global.setTimeout(wrappedCallback, delay);
|
||||
|
||||
return { callback, timerId, repeating, delay, timeout };
|
||||
}
|
||||
|
||||
protected stopNativeTimer(reg: NativeTimer): void {
|
||||
if (reg.repeating) {
|
||||
global.clearInterval(reg.timeout);
|
||||
} else {
|
||||
global.clearTimeout(reg.timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface NativeTimer extends Timer {
|
||||
timeout: NodeJS.Timeout;
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import { CollapsedQueue } from '@/misc/collapsed-queue.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { MiNote } from '@/models/Note.js';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
type UpdateInstanceJob = {
|
||||
latestRequestReceivedAt: Date,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { AccountMoveService } from '@/core/AccountMoveService.js';
|
|||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import type { ThinUser } from '@/queue/types.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import type Logger from '../logger.js';
|
||||
|
||||
type Local = MiLocalUser | {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import type { UserKeypairsRepository } from '@/models/_.js';
|
|||
import type { MiUserKeypair } from '@/models/UserKeypair.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/core/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/global/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import type { InternalEventTypes } from '@/core/GlobalEventService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { QueueService } from '@/core/QueueService.js';
|
||||
import type { RoleService } from '@/core/RoleService.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { Packed } from '@/misc/json-schema.js';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { LoggerService } from '@/core/LoggerService.js';
|
|||
import type Logger from '@/logger.js';
|
||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
|
||||
@Injectable()
|
||||
export class UserSuspendService {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import { bindThis } from '@/decorators.js';
|
|||
import type { InternalEventTypes } from '@/core/GlobalEventService.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { QueueService } from '@/core/QueueService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/core/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/core/InternalEventService.js';
|
||||
import { CacheManagementService, type ManagedMemorySingleCache } from '@/global/CacheManagementService.js';
|
||||
import { InternalEventService } from '@/global/InternalEventService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
export type UserWebhookPayload<T extends WebhookEventTypes> =
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import type { MiMeta, SoftwareSuspension } from '@/models/Meta.js';
|
||||
import type { MiInstance } from '@/models/Instance.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { EnvService } from '@/core/EnvService.js';
|
||||
import { EnvService } from '@/global/EnvService.js';
|
||||
|
||||
@Injectable()
|
||||
export class UtilityService {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { MiUser } from '@/models/_.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import Logger from '@/logger.js';
|
||||
import type {
|
||||
AuthenticationResponseJSON,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
|||
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
|
||||
import { QueueService } from '@/core/QueueService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
|
||||
|
||||
const oneDayMillis = 24 * 60 * 60 * 1000;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataServic
|
|||
import { UpdateInstanceQueue } from '@/core/UpdateInstanceQueue.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { NoteVisibilityService } from '@/core/NoteVisibilityService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { getApHrefNullable, getApId, getApIds, getApType, getNullableApId, isAccept, isActor, isAdd, isAnnounce, isApObject, isBlock, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isDislike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost, isActivity, IObjectWithId } from './type.js';
|
||||
import { ApNoteService } from './models/ApNoteService.js';
|
||||
import { ApLoggerService } from './ApLoggerService.js';
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import { UtilityService } from '@/core/UtilityService.js';
|
|||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { isPureRenote, isQuote, isRenote } from '@/misc/is-renote.js';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { JsonLdService } from './JsonLdService.js';
|
||||
import { ApMfmService } from './ApMfmService.js';
|
||||
import { CONTEXT } from './misc/contexts.js';
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { UserKeypairService } from '@/core/UserKeypairService.js';
|
|||
import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js';
|
||||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import Logger from '@/logger.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { StatusError } from '@/misc/status-error.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { CONTEXT, PRELOADED_CONTEXTS } from './misc/contexts.js';
|
||||
import { validateContentTypeSetAsJsonLD } from './misc/validator.js';
|
||||
import type { ContextDefinition, JsonLdDocument } from 'jsonld';
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import { extractMediaFromHtml } from '@/core/activitypub/misc/extract-media-from
|
|||
import { extractMediaFromMfm } from '@/core/activitypub/misc/extract-media-from-mfm.js';
|
||||
import { getContentByType } from '@/core/activitypub/misc/get-content-by-type.js';
|
||||
import { CustomEmojiService, encodeEmojiKey, isValidEmojiName } from '@/core/CustomEmojiService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { getOneApId, getApId, validPost, isEmoji, getApType, isApObject, isDocument, IApDocument, isLink } from '../type.js';
|
||||
import { ApLoggerService } from '../ApLoggerService.js';
|
||||
import { ApMfmService } from '../ApMfmService.js';
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { isRemoteUser, isLocalUser } from '@/models/User.js';
|
|||
import { MiUser } from '@/models/User.js';
|
||||
import { truncate } from '@/misc/truncate.js';
|
||||
import type { CacheService } from '@/core/CacheService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/core/CacheManagementService.js';
|
||||
import { CacheManagementService, type ManagedQuantumKVCache } from '@/global/CacheManagementService.js';
|
||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||
import type Logger from '@/logger.js';
|
||||
|
|
@ -41,7 +41,7 @@ import type { AccountMoveService } from '@/core/AccountMoveService.js';
|
|||
import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { verifyFieldLinks } from '@/misc/verify-field-link.js';
|
||||
import { isRetryableError } from '@/misc/is-retryable-error.js';
|
||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Injectable } from '@nestjs/common';
|
|||
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { ChartLoggerService } from '@/core/chart/ChartLoggerService.js';
|
||||
import { TimeService, type TimerHandle } from '@/core/TimeService.js';
|
||||
import { TimeService, type TimerHandle } from '@/global/TimeService.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||
import FederationChart from './charts/federation.js';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import type { MiUser } from '@/models/User.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import Chart from '../core.js';
|
||||
import { ChartLoggerService } from '../ChartLoggerService.js';
|
||||
import { name, schema } from './entities/active-users.js';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import Chart from '../core.js';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Injectable, Inject } from '@nestjs/common';
|
|||
import { DataSource } from 'typeorm';
|
||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import Chart from '../core.js';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Injectable, Inject } from '@nestjs/common';
|
|||
import { DataSource } from 'typeorm';
|
||||
import type { FollowingsRepository, InstancesRepository, MiMeta } from '@/models/_.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import Chart from '../core.js';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { DriveFilesRepository, FollowingsRepository, UsersRepository, Notes
|
|||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Not, IsNull, DataSource } from 'typeorm';
|
|||
import type { NotesRepository } from '@/models/_.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import Chart from '../core.js';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { DataSource } from 'typeorm';
|
|||
import type { DriveFilesRepository } from '@/models/_.js';
|
||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Not, IsNull, DataSource } from 'typeorm';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import type { FollowingsRepository } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { DataSource } from 'typeorm';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { NotesRepository } from '@/models/_.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Injectable, Inject } from '@nestjs/common';
|
|||
import { DataSource } from 'typeorm';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import Chart from '../core.js';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { DataSource } from 'typeorm';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { AppLockService } from '@/core/AppLockService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import Chart from '../core.js';
|
||||
import { name, schema } from './entities/test.js';
|
||||
import type { KVs } from '../core.js';
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Injectable, Inject } from '@nestjs/common';
|
|||
import { Not, IsNull, Like, DataSource } from 'typeorm';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { AppLockService } from '@/core/AppLockService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { SystemAccountService } from '@/core/SystemAccountService.js';
|
|||
import type { Config } from '@/config.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class MetaEntityService {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { DebounceLoader } from '@/misc/loader.js';
|
|||
import type { IdService } from '@/core/IdService.js';
|
||||
import type { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { NoteVisibilityService } from '@/core/NoteVisibilityService.js';
|
||||
import type { NoteVisibilityData } from '@/core/NoteVisibilityService.js';
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { bindThis } from '@/decorators.js';
|
|||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { Packed } from '@/misc/json-schema.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
|
||||
@Injectable()
|
||||
export class RoleEntityService {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import type { RolePolicies, RoleService } from '@/core/RoleService.js';
|
|||
import type { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
||||
import type { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import type { IdService } from '@/core/IdService.js';
|
||||
import { TimeService } from '@/core/TimeService.js';
|
||||
import { TimeService } from '@/global/TimeService.js';
|
||||
import type { AnnouncementService } from '@/core/AnnouncementService.js';
|
||||
import type { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
import type { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue