mirror of
https://activitypub.software/TransFem-org/Sharkey
synced 2024-11-22 05:55:12 +00:00
feat: introduce aidx and make it default
Co-Authored-By: MeiMei <30769358+mei23@users.noreply.github.com>
This commit is contained in:
parent
54c6fb762a
commit
ca00a08e6e
12 changed files with 83 additions and 14 deletions
|
@ -114,6 +114,7 @@ redis:
|
||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
|
# aidx ... Millisecond accuracy
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
|
@ -121,7 +122,7 @@ redis:
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: 'aid'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
|
@ -125,6 +125,7 @@ redis:
|
||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
|
# aidx ... Millisecond accuracy
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
|
@ -132,7 +133,7 @@ redis:
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: 'aid'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
|
@ -114,6 +114,7 @@ redis:
|
||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
|
# aidx ... Millisecond accuracy
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
|
@ -121,7 +122,7 @@ redis:
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: 'aid'
|
id: 'aidx'
|
||||||
|
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
2
.github/misskey/test.yml
vendored
2
.github/misskey/test.yml
vendored
|
@ -12,4 +12,4 @@ db:
|
||||||
redis:
|
redis:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 56312
|
port: 56312
|
||||||
id: aid
|
id: aidx
|
||||||
|
|
|
@ -135,6 +135,7 @@ redis:
|
||||||
|
|
||||||
# Available methods:
|
# Available methods:
|
||||||
# aid ... Short, Millisecond accuracy
|
# aid ... Short, Millisecond accuracy
|
||||||
|
# aidx ... Millisecond accuracy
|
||||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||||
# ulid ... Millisecond accuracy
|
# ulid ... Millisecond accuracy
|
||||||
# objectid ... This is left for backward compatibility
|
# objectid ... This is left for backward compatibility
|
||||||
|
@ -142,7 +143,7 @@ redis:
|
||||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||||
# ID SETTINGS AFTER THAT!
|
# ID SETTINGS AFTER THAT!
|
||||||
|
|
||||||
id: "aid"
|
id: "aidx"
|
||||||
# ┌─────────────────────┐
|
# ┌─────────────────────┐
|
||||||
#───┘ Other configuration └─────────────────────────────────────
|
#───┘ Other configuration └─────────────────────────────────────
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"misskey-js": "workspace:*",
|
"misskey-js": "workspace:*",
|
||||||
"ms": "3.0.0-canary.1",
|
"ms": "3.0.0-canary.1",
|
||||||
|
"nanoid": "4.0.2",
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"nodemailer": "6.9.4",
|
"nodemailer": "6.9.4",
|
||||||
|
|
|
@ -8,6 +8,7 @@ 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 { genAidx, parseAidx } from '@/misc/id/aidx.js';
|
||||||
import { genMeid, parseMeid } from '@/misc/id/meid.js';
|
import { genMeid, parseMeid } from '@/misc/id/meid.js';
|
||||||
import { genMeidg, parseMeidg } from '@/misc/id/meidg.js';
|
import { genMeidg, parseMeidg } from '@/misc/id/meidg.js';
|
||||||
import { genObjectId, parseObjectId } from '@/misc/id/object-id.js';
|
import { genObjectId, parseObjectId } from '@/misc/id/object-id.js';
|
||||||
|
@ -31,6 +32,7 @@ export class IdService {
|
||||||
|
|
||||||
switch (this.method) {
|
switch (this.method) {
|
||||||
case 'aid': return genAid(date);
|
case 'aid': return genAid(date);
|
||||||
|
case 'aidx': return genAidx(date);
|
||||||
case 'meid': return genMeid(date);
|
case 'meid': return genMeid(date);
|
||||||
case 'meidg': return genMeidg(date);
|
case 'meidg': return genMeidg(date);
|
||||||
case 'ulid': return ulid(date.getTime());
|
case 'ulid': return ulid(date.getTime());
|
||||||
|
@ -43,6 +45,7 @@ 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);
|
||||||
|
case 'aidx': return parseAidx(id);
|
||||||
case 'objectid': return parseObjectId(id);
|
case 'objectid': return parseObjectId(id);
|
||||||
case 'meid': return parseMeid(id);
|
case 'meid': return parseMeid(id);
|
||||||
case 'meidg': return parseMeidg(id);
|
case 'meidg': return parseMeidg(id);
|
||||||
|
|
44
packages/backend/src/misc/id/aidx.ts
Normal file
44
packages/backend/src/misc/id/aidx.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
// AIDX
|
||||||
|
// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ4の[個体ID] + 長さ4の[カウンタ]
|
||||||
|
// (c) mei23
|
||||||
|
// https://misskey.m544.net/notes/71899acdcc9859ec5708ac24
|
||||||
|
|
||||||
|
import { customAlphabet } from 'nanoid';
|
||||||
|
|
||||||
|
export const aidxRegExp = /^[0-9a-z]{16}$/;
|
||||||
|
|
||||||
|
const TIME2000 = 946684800000;
|
||||||
|
const TIME_LENGTH = 8;
|
||||||
|
const NODE_LENGTH = 4;
|
||||||
|
const NOISE_LENGTH = 4;
|
||||||
|
|
||||||
|
const nodeId = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', NODE_LENGTH)();
|
||||||
|
let counter = 0;
|
||||||
|
|
||||||
|
function getTime(time: number): string {
|
||||||
|
time = time - TIME2000;
|
||||||
|
if (time < 0) time = 0;
|
||||||
|
|
||||||
|
return time.toString(36).padStart(TIME_LENGTH, '0').slice(-TIME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNoise(): string {
|
||||||
|
return counter.toString(36).padStart(NOISE_LENGTH, '0').slice(-NOISE_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function genAidx(date: Date): string {
|
||||||
|
const t = date.getTime();
|
||||||
|
if (isNaN(t)) throw new Error('Failed to create AIDX: Invalid Date');
|
||||||
|
counter++;
|
||||||
|
return getTime(t) + nodeId + getNoise();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseAidx(id: string): { date: Date; } {
|
||||||
|
const time = parseInt(id.slice(0, TIME_LENGTH), 36) + TIME2000;
|
||||||
|
return { date: new Date(time) };
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import { GlobalModule } from '@/GlobalModule.js';
|
||||||
import { AnnouncementService } from '@/core/AnnouncementService.js';
|
import { AnnouncementService } from '@/core/AnnouncementService.js';
|
||||||
import type { MiAnnouncement, AnnouncementsRepository, AnnouncementReadsRepository, UsersRepository, MiUser } from '@/models/index.js';
|
import type { MiAnnouncement, AnnouncementsRepository, AnnouncementReadsRepository, UsersRepository, MiUser } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { genAid } from '@/misc/id/aid.js';
|
import { genAidx } from '@/misc/id/aidx.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
|
@ -33,7 +33,7 @@ describe('AnnouncementService', () => {
|
||||||
function createUser(data: Partial<MiUser> = {}) {
|
function createUser(data: Partial<MiUser> = {}) {
|
||||||
const un = secureRndstr(16);
|
const un = secureRndstr(16);
|
||||||
return usersRepository.insert({
|
return usersRepository.insert({
|
||||||
id: genAid(new Date()),
|
id: genAidx(new Date()),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
username: un,
|
username: un,
|
||||||
usernameLower: un,
|
usernameLower: un,
|
||||||
|
@ -44,7 +44,7 @@ describe('AnnouncementService', () => {
|
||||||
|
|
||||||
function createAnnouncement(data: Partial<MiAnnouncement> = {}) {
|
function createAnnouncement(data: Partial<MiAnnouncement> = {}) {
|
||||||
return announcementsRepository.insert({
|
return announcementsRepository.insert({
|
||||||
id: genAid(new Date()),
|
id: genAidx(new Date()),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: null,
|
updatedAt: null,
|
||||||
title: 'Title',
|
title: 'Title',
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { RoleService } from '@/core/RoleService.js';
|
||||||
import type { MiRole, RolesRepository, RoleAssignmentsRepository, UsersRepository, MiUser } from '@/models/index.js';
|
import type { MiRole, RolesRepository, RoleAssignmentsRepository, UsersRepository, MiUser } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { genAid } from '@/misc/id/aid.js';
|
import { genAidx } from '@/misc/id/aidx.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
|
@ -37,7 +37,7 @@ describe('RoleService', () => {
|
||||||
function createUser(data: Partial<MiUser> = {}) {
|
function createUser(data: Partial<MiUser> = {}) {
|
||||||
const un = secureRndstr(16);
|
const un = secureRndstr(16);
|
||||||
return usersRepository.insert({
|
return usersRepository.insert({
|
||||||
id: genAid(new Date()),
|
id: genAidx(new Date()),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
username: un,
|
username: un,
|
||||||
usernameLower: un,
|
usernameLower: un,
|
||||||
|
@ -48,7 +48,7 @@ describe('RoleService', () => {
|
||||||
|
|
||||||
function createRole(data: Partial<MiRole> = {}) {
|
function createRole(data: Partial<MiRole> = {}) {
|
||||||
return rolesRepository.insert({
|
return rolesRepository.insert({
|
||||||
id: genAid(new Date()),
|
id: genAidx(new Date()),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
lastUsedAt: new Date(),
|
lastUsedAt: new Date(),
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
import { describe, test, expect } from '@jest/globals';
|
import { describe, test, expect } from '@jest/globals';
|
||||||
import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js';
|
import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js';
|
||||||
|
import { aidxRegExp, genAidx, parseAidx } from '@/misc/id/aidx.js';
|
||||||
import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js';
|
import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js';
|
||||||
import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js';
|
import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js';
|
||||||
import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js';
|
import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js';
|
||||||
|
@ -19,6 +20,13 @@ describe('misc:id', () => {
|
||||||
expect(parseAid(gotAid).date.getTime()).toBe(date.getTime());
|
expect(parseAid(gotAid).date.getTime()).toBe(date.getTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('aidx', () => {
|
||||||
|
const date = new Date();
|
||||||
|
const gotAidx = genAidx(date);
|
||||||
|
expect(gotAidx).toMatch(aidxRegExp);
|
||||||
|
expect(parseAidx(gotAidx).date.getTime()).toBe(date.getTime());
|
||||||
|
});
|
||||||
|
|
||||||
test('meid', () => {
|
test('meid', () => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const gotMeid = genMeid(date);
|
const gotMeid = genMeid(date);
|
||||||
|
|
|
@ -260,6 +260,9 @@ importers:
|
||||||
ms:
|
ms:
|
||||||
specifier: 3.0.0-canary.1
|
specifier: 3.0.0-canary.1
|
||||||
version: 3.0.0-canary.1
|
version: 3.0.0-canary.1
|
||||||
|
nanoid:
|
||||||
|
specifier: ^4.0.2
|
||||||
|
version: 4.0.2
|
||||||
nested-property:
|
nested-property:
|
||||||
specifier: 4.0.0
|
specifier: 4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
|
@ -6998,7 +7001,7 @@ packages:
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
vue-component-type-helpers: 1.8.8
|
vue-component-type-helpers: 1.8.10
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -16069,6 +16072,12 @@ packages:
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/nanoid@4.0.2:
|
||||||
|
resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==}
|
||||||
|
engines: {node: ^14 || ^16 || >=18}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/nanomatch@1.2.13:
|
/nanomatch@1.2.13:
|
||||||
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
|
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -21040,8 +21049,8 @@ packages:
|
||||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
/vue-component-type-helpers@1.8.8:
|
/vue-component-type-helpers@1.8.10:
|
||||||
resolution: {integrity: sha512-Ohv9HQY92nSbpReC6WhY0X4YkOszHzwUHaaN/lev5tHQLM1AEw+LrLeB2bIGIyKGDU7ZVrncXcv/oBny4rjbYg==}
|
resolution: {integrity: sha512-FJtmfw2Gn6eQ8kAVNEhw9nYIzWmVQJjdyQRtJXZ7tgXh/FoZhQnZ2KyxR+NuF9U4iZLBvSspeetIpnP9yxxyMw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vue-docgen-api@4.64.1(vue@3.3.4):
|
/vue-docgen-api@4.64.1(vue@3.3.4):
|
||||||
|
|
Loading…
Reference in a new issue