mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	fix(server): IdService.parseを全てのidタイプに対応させるように (#10533)
* wip fix-id
* ✌️
* fix import
			
			
This commit is contained in:
		
							parent
							
								
									7a33c5d2ee
								
							
						
					
					
						commit
						d76220cc80
					
				
					 7 changed files with 92 additions and 7 deletions
				
			
		| 
						 | 
					@ -3,10 +3,11 @@ import { ulid } from 'ulid';
 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import type { Config } from '@/config.js';
 | 
					import type { Config } from '@/config.js';
 | 
				
			||||||
import { genAid, parseAid } from '@/misc/id/aid.js';
 | 
					import { genAid, parseAid } from '@/misc/id/aid.js';
 | 
				
			||||||
import { genMeid } from '@/misc/id/meid.js';
 | 
					import { genMeid, parseMeid } from '@/misc/id/meid.js';
 | 
				
			||||||
import { genMeidg } from '@/misc/id/meidg.js';
 | 
					import { genMeidg, parseMeidg } from '@/misc/id/meidg.js';
 | 
				
			||||||
import { genObjectId } from '@/misc/id/object-id.js';
 | 
					import { genObjectId } from '@/misc/id/object-id.js';
 | 
				
			||||||
import { bindThis } from '@/decorators.js';
 | 
					import { bindThis } from '@/decorators.js';
 | 
				
			||||||
 | 
					import { parseUlid } from '@/misc/id/ulid.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable()
 | 
					@Injectable()
 | 
				
			||||||
export class IdService {
 | 
					export class IdService {
 | 
				
			||||||
| 
						 | 
					@ -37,11 +38,10 @@ export class IdService {
 | 
				
			||||||
	public parse(id: string): { date: Date; } {
 | 
						public parse(id: string): { date: Date; } {
 | 
				
			||||||
		switch (this.method) {
 | 
							switch (this.method) {
 | 
				
			||||||
			case 'aid': return parseAid(id);
 | 
								case 'aid': return parseAid(id);
 | 
				
			||||||
			// TODO
 | 
								case 'objectid':
 | 
				
			||||||
			//case 'meid':
 | 
								case 'meid': return parseMeid(id);
 | 
				
			||||||
			//case 'meidg':
 | 
								case 'meidg': return parseMeidg(id);
 | 
				
			||||||
			//case 'ulid':
 | 
								case 'ulid': return parseUlid(id);
 | 
				
			||||||
			//case 'objectid':
 | 
					 | 
				
			||||||
			default: throw new Error('unrecognized id generation method');
 | 
								default: throw new Error('unrecognized id generation method');
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as crypto from 'node:crypto';
 | 
					import * as crypto from 'node:crypto';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const aidRegExp = /^[0-9a-z]{10}$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TIME2000 = 946684800000;
 | 
					const TIME2000 = 946684800000;
 | 
				
			||||||
let counter = crypto.randomBytes(2).readUInt16LE(0);
 | 
					let counter = crypto.randomBytes(2).readUInt16LE(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,8 @@
 | 
				
			||||||
const CHARS = '0123456789abcdef';
 | 
					const CHARS = '0123456789abcdef';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// same as object-id
 | 
				
			||||||
 | 
					export const meidRegExp = /^[0-9a-f]{24}$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getTime(time: number) {
 | 
					function getTime(time: number) {
 | 
				
			||||||
	if (time < 0) time = 0;
 | 
						if (time < 0) time = 0;
 | 
				
			||||||
	if (time === 0) {
 | 
						if (time === 0) {
 | 
				
			||||||
| 
						 | 
					@ -24,3 +27,9 @@ function getRandom() {
 | 
				
			||||||
export function genMeid(date: Date): string {
 | 
					export function genMeid(date: Date): string {
 | 
				
			||||||
	return getTime(date.getTime()) + getRandom();
 | 
						return getTime(date.getTime()) + getRandom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseMeid(id: string): { date: Date; } {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							date: new Date(parseInt(id.slice(0, 12), 16) - 0x800000000000),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ const CHARS = '0123456789abcdef';
 | 
				
			||||||
//  4bit Fixed hex value 'g'
 | 
					//  4bit Fixed hex value 'g'
 | 
				
			||||||
// 44bit UNIX Time ms in Hex
 | 
					// 44bit UNIX Time ms in Hex
 | 
				
			||||||
// 48bit Random value in Hex
 | 
					// 48bit Random value in Hex
 | 
				
			||||||
 | 
					export const meidgRegExp = /^g[0-9a-f]{23}$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getTime(time: number) {
 | 
					function getTime(time: number) {
 | 
				
			||||||
	if (time < 0) time = 0;
 | 
						if (time < 0) time = 0;
 | 
				
			||||||
| 
						 | 
					@ -26,3 +27,9 @@ function getRandom() {
 | 
				
			||||||
export function genMeidg(date: Date): string {
 | 
					export function genMeidg(date: Date): string {
 | 
				
			||||||
	return 'g' + getTime(date.getTime()) + getRandom();
 | 
						return 'g' + getTime(date.getTime()) + getRandom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseMeidg(id: string): { date: Date; } {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							date: new Date(parseInt(id.slice(1, 12), 16)),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,8 @@
 | 
				
			||||||
const CHARS = '0123456789abcdef';
 | 
					const CHARS = '0123456789abcdef';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// same as meid
 | 
				
			||||||
 | 
					export const objectIdRegExp = /^[0-9a-f]{24}$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getTime(time: number) {
 | 
					function getTime(time: number) {
 | 
				
			||||||
	if (time < 0) time = 0;
 | 
						if (time < 0) time = 0;
 | 
				
			||||||
	if (time === 0) {
 | 
						if (time === 0) {
 | 
				
			||||||
| 
						 | 
					@ -24,3 +27,9 @@ function getRandom() {
 | 
				
			||||||
export function genObjectId(date: Date): string {
 | 
					export function genObjectId(date: Date): string {
 | 
				
			||||||
	return getTime(date.getTime()) + getRandom();
 | 
						return getTime(date.getTime()) + getRandom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseObjectId(id: string): { date: Date; } {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							date: new Date(parseInt(id.slice(0, 8), 16) * 1000),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								packages/backend/src/misc/id/ulid.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								packages/backend/src/misc/id/ulid.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					// Crockford's Base32
 | 
				
			||||||
 | 
					// https://github.com/ulid/spec#encoding
 | 
				
			||||||
 | 
					const CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ulidRegExp = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseUlid(id: string): { date: Date; } {
 | 
				
			||||||
 | 
					    const timestamp = id.slice(0, 10);
 | 
				
			||||||
 | 
					    let time = 0;
 | 
				
			||||||
 | 
					    for (let i = 0; i < 10; i++) {
 | 
				
			||||||
 | 
					        time = time * 32 + CHARS.indexOf(timestamp[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return { date: new Date(time) };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								packages/backend/test/unit/misc/id.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								packages/backend/test/unit/misc/id.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js';
 | 
				
			||||||
 | 
					import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js';
 | 
				
			||||||
 | 
					import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js';
 | 
				
			||||||
 | 
					import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js';
 | 
				
			||||||
 | 
					import { ulidRegExp, parseUlid } from '@/misc/id/ulid.js';
 | 
				
			||||||
 | 
					import { ulid } from 'ulid';
 | 
				
			||||||
 | 
					import { describe, test, expect } from '@jest/globals';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('misc:id', () => {
 | 
				
			||||||
 | 
					    test('aid', () => {
 | 
				
			||||||
 | 
					        const date = new Date();
 | 
				
			||||||
 | 
					        const gotAid = genAid(date);
 | 
				
			||||||
 | 
					        expect(gotAid).toMatch(aidRegExp);
 | 
				
			||||||
 | 
					        expect(parseAid(gotAid).date.getTime()).toBe(date.getTime());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('meid', () => {
 | 
				
			||||||
 | 
					        const date = new Date();
 | 
				
			||||||
 | 
					        const gotMeid = genMeid(date);
 | 
				
			||||||
 | 
					        expect(gotMeid).toMatch(meidRegExp);
 | 
				
			||||||
 | 
					        expect(parseMeid(gotMeid).date.getTime()).toBe(date.getTime());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('meidg', () => {
 | 
				
			||||||
 | 
					        const date = new Date();
 | 
				
			||||||
 | 
					        const gotMeidg = genMeidg(date);
 | 
				
			||||||
 | 
					        expect(gotMeidg).toMatch(meidgRegExp);
 | 
				
			||||||
 | 
					        expect(parseMeidg(gotMeidg).date.getTime()).toBe(date.getTime());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('objectid', () => {
 | 
				
			||||||
 | 
					        const date = new Date();
 | 
				
			||||||
 | 
					        const gotObjectId = genObjectId(date);
 | 
				
			||||||
 | 
					        expect(gotObjectId).toMatch(objectIdRegExp);
 | 
				
			||||||
 | 
					        expect(Math.floor(parseObjectId(gotObjectId).date.getTime() / 1000)).toBe(Math.floor(date.getTime() / 1000));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('ulid', () => {
 | 
				
			||||||
 | 
					        const date = new Date();
 | 
				
			||||||
 | 
					        const gotUlid = ulid(date.getTime());
 | 
				
			||||||
 | 
					        expect(gotUlid).toMatch(ulidRegExp);
 | 
				
			||||||
 | 
					        expect(parseUlid(gotUlid).date.getTime()).toBe(date.getTime());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue