diff --git a/packages/backend/src/core/IdService.ts b/packages/backend/src/core/IdService.ts index 223a8de678..d30093d1db 100644 --- a/packages/backend/src/core/IdService.ts +++ b/packages/backend/src/core/IdService.ts @@ -3,40 +3,84 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Inject, Injectable } from '@nestjs/common'; -import { ulid } from 'ulid'; +import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.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'; -import { genMeidg, isSafeMeidgT, parseMeidg, parseMeidgFull } from '@/misc/id/meidg.js'; -import { genObjectId, isSafeObjectIdT, parseObjectId, parseObjectIdFull } from '@/misc/id/object-id.js'; import { bindThis } from '@/decorators.js'; -import { parseUlid, parseUlidFull } from '@/misc/id/ulid.js'; @Injectable() -export class IdService { +export class IdService implements OnModuleInit { private method: string; + private safeTFn: (t: number) => boolean; + private genFn: (time: number) => string; + private parseFn: (id: string) => { date: Date; }; + private parseFullFn: (id: string) => { date: number; additional: bigint; }; constructor( @Inject(DI.config) private config: Config, ) { - this.method = config.id.toLowerCase(); + this.method = this.config.id.toLowerCase(); + } + + async onModuleInit() { + switch (this.method) { + case 'aid': { + const aidModule = await import('@/misc/id/aid.js'); + this.safeTFn = aidModule.isSafeAidT; + this.genFn = aidModule.genAid; + this.parseFn = aidModule.parseAid; + this.parseFullFn = aidModule.parseAidFull; + break; + } + case 'aidx': { + const aidxModule = await import('@/misc/id/aidx.js'); + this.safeTFn = aidxModule.isSafeAidxT; + this.genFn = aidxModule.genAidx; + this.parseFn = aidxModule.parseAidx; + this.parseFullFn = aidxModule.parseAidxFull; + break; + } + case 'meid': { + const meidModule = await import('@/misc/id/meid.js'); + this.safeTFn = meidModule.isSafeMeidT; + this.genFn = meidModule.genMeid; + this.parseFn = meidModule.parseMeid; + this.parseFullFn = meidModule.parseMeidFull; + break; + } + case 'meidg': { + const meidgModule = await import('@/misc/id/meidg.js'); + this.safeTFn = meidgModule.isSafeMeidgT; + this.genFn = meidgModule.genMeidg; + this.parseFn = meidgModule.parseMeidg; + this.parseFullFn = meidgModule.parseMeidgFull; + break; + } + case 'ulid': { + const ulidModule = await import('@/misc/id/ulid.js'); + const { ulid: genUlid } = await import('ulid'); + this.safeTFn = (t) => t > 0; + this.genFn = (time) => genUlid(time); + this.parseFn = ulidModule.parseUlid; + this.parseFullFn = ulidModule.parseUlidFull; + break; + } + case 'objectid': { + const objectIdModule = await import('@/misc/id/object-id.js'); + this.safeTFn = objectIdModule.isSafeObjectIdT; + this.genFn = objectIdModule.genObjectId; + this.parseFn = objectIdModule.parseObjectId; + this.parseFullFn = objectIdModule.parseObjectIdFull; + break; + } + default: throw new Error('unrecognized id generation method'); + } } @bindThis public isSafeT(t: number): boolean { - switch (this.method) { - case 'aid': return isSafeAidT(t); - case 'aidx': return isSafeAidxT(t); - case 'meid': return isSafeMeidT(t); - case 'meidg': return isSafeMeidgT(t); - case 'ulid': return t > 0; - case 'objectid': return isSafeObjectIdT(t); - default: throw new Error('unrecognized id generation method'); - } + return this.safeTFn(t); } /** @@ -46,42 +90,17 @@ export class IdService { @bindThis public gen(time?: number): string { const t = (!time || (time > Date.now())) ? Date.now() : time; - - switch (this.method) { - case 'aid': return genAid(t); - case 'aidx': return genAidx(t); - case 'meid': return genMeid(t); - case 'meidg': return genMeidg(t); - case 'ulid': return ulid(t); - case 'objectid': return genObjectId(t); - default: throw new Error('unrecognized id generation method'); - } + return this.genFn(t); } @bindThis public parse(id: string): { date: Date; } { - switch (this.method) { - case 'aid': return parseAid(id); - case 'aidx': return parseAidx(id); - case 'objectid': return parseObjectId(id); - case 'meid': return parseMeid(id); - case 'meidg': return parseMeidg(id); - case 'ulid': return parseUlid(id); - default: throw new Error('unrecognized id generation method'); - } + return this.parseFn(id); } // Note: additional is at most 64 bits @bindThis public parseFull(id: string): { date: number; additional: bigint; } { - switch (this.method) { - case 'aid': return parseAidFull(id); - case 'aidx': return parseAidxFull(id); - case 'objectid': return parseObjectIdFull(id); - case 'meid': return parseMeidFull(id); - case 'meidg': return parseMeidgFull(id); - case 'ulid': return parseUlidFull(id); - default: throw new Error('unrecognized id generation method'); - } + return this.parseFullFn(id); } }