Compare commits
170 commits
Author | SHA1 | Date | |
---|---|---|---|
c454a44785 | |||
41250d997b | |||
a97d379c84 | |||
535e778033 | |||
726fdb9e93 | |||
ae3ce71bb2 | |||
106062fa23 | |||
42990fe6b6 | |||
dc787f7a76 | |||
83a6902997 | |||
1c5606ca72 | |||
02405287d1 | |||
bd9c084a3a | |||
cef5feaee2 | |||
fe16b16fc3 | |||
f4cc9e3d2e | |||
4d021f315f | |||
bad25a804c | |||
019199168e | |||
8122cb3a86 | |||
ab02fd3ec4 | |||
028e7c00ae | |||
27b6921d3c | |||
3ec19e0b00 | |||
8401117293 | |||
ced5638b80 | |||
b532ad8cd4 | |||
b818f2308d | |||
b697b2f651 | |||
0571b83978 | |||
b519ff1e10 | |||
601eb65cfb | |||
59f4bf2a74 | |||
a5a9540eac | |||
bb46030677 | |||
9530cb01b9 | |||
fd223a8538 | |||
4c52f3b286 | |||
edc38fc2c7 | |||
4a104af304 | |||
a1b243bbda | |||
6bd7a0d0aa | |||
80bd84932c | |||
7f28b7334c | |||
669cfb1e29 | |||
47fae30aba | |||
64bbfc2107 | |||
1e2178b717 | |||
b5852f6053 | |||
35b1f73b51 | |||
f651ca4b48 | |||
8bad11c559 | |||
aead5305a7 | |||
de9a5d515d | |||
7f51ace0ff | |||
586cfbe880 | |||
f7f8845801 | |||
93d111bfb6 | |||
1f64b7c9ea | |||
c4f434aa01 | |||
4001c974a6 | |||
2fc2f2d616 | |||
f81479ad05 | |||
6198313c49 | |||
90a22fe32f | |||
3918473e29 | |||
931cea75b6 | |||
68a2aa3efd | |||
dbeb1856ac | |||
07bbadbbdc | |||
78558eb666 | |||
bc15dde742 | |||
9135d2757e | |||
a1c96d9bcb | |||
94f25d9cdd | |||
e1b4a0438e | |||
93ea327660 | |||
9ce6f99cad | |||
d647df7f63 | |||
654c93b0ce | |||
8d36911f90 | |||
84835be483 | |||
35f90e94c9 | |||
5268a55996 | |||
53ad4b18e5 | |||
54b6b79559 | |||
b4cfa412b0 | |||
dfdfc8fab4 | |||
b14d3cdc32 | |||
82a17ea427 | |||
a57df6f2ca | |||
41c353e24d | |||
bca9c54923 | |||
ce5faa8ff5 | |||
0ef7a3db0f | |||
c264b01658 | |||
e07ed1b312 | |||
c0bd1b82ab | |||
d7fe783c46 | |||
1b6ac7888b | |||
86f4e206f4 | |||
e689dcdd73 | |||
810d065d21 | |||
8adf2701d2 | |||
11f41a6e8d | |||
8d1569567f | |||
23545bcbbb | |||
aea6950b46 | |||
d7d3f00488 | |||
307bc2a38e | |||
919af7b967 | |||
359f0b21b0 | |||
79f71acd42 | |||
89480d9029 | |||
0853b2fe42 | |||
13fe20d47e | |||
361ab296c7 | |||
e76c1d8956 | |||
0709ec5d82 | |||
f7a0213af9 | |||
9b27fffb0e | |||
c0cbbe6072 | |||
13fc093602 | |||
ca29fdc795 | |||
03a2501b45 | |||
69ba41bd8d | |||
5f2bbea6de | |||
49dc995f1e | |||
15ef1a082d | |||
cdfab72b35 | |||
37142d7495 | |||
b6d04f5d5b | |||
5e268f0611 | |||
2afa664864 | |||
64f4bb6a90 | |||
00cc846729 | |||
4f5d77391f | |||
ac99cdce8b | |||
3324f3fa15 | |||
56a1e436f3 | |||
ad6c5275ec | |||
0e08c56bc7 | |||
3e13bb4cd7 | |||
d3ecb02644 | |||
f3bc232419 | |||
00b1fd2ee3 | |||
44e819bf6a | |||
49e32ebf2b | |||
66447d13c1 | |||
5bb2d71231 | |||
32e489e536 | |||
fc10a9026c | |||
9699bac704 | |||
d328a8cefc | |||
34edf950ff | |||
7d8fa48d47 | |||
96e04738c0 | |||
e4c36bbd7a | |||
0ee1dab2bc | |||
47e3792105 | |||
0040aca841 | |||
41a822c34c | |||
55c217da73 | |||
ff85376306 | |||
ef15b9c0d3 | |||
abefddb90e | |||
3fcee7c4bd | |||
d18750cb97 | |||
6c53d1fdb7 | |||
e9355bf918 |
|
@ -210,6 +210,7 @@
|
|||
"eslint-plugin-import": "2.27.5",
|
||||
"execa": "6.1.0",
|
||||
"jest": "29.5.0",
|
||||
"jest-mock": "29.5.0"
|
||||
"jest-mock": "29.5.0",
|
||||
"schema-type": "github:misskey-dev/schema-type"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,83 +4,7 @@ import type { User } from '@/models/entities/User.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { NotificationService } from '@/core/NotificationService.js';
|
||||
|
||||
export const ACHIEVEMENT_TYPES = [
|
||||
'notes1',
|
||||
'notes10',
|
||||
'notes100',
|
||||
'notes500',
|
||||
'notes1000',
|
||||
'notes5000',
|
||||
'notes10000',
|
||||
'notes20000',
|
||||
'notes30000',
|
||||
'notes40000',
|
||||
'notes50000',
|
||||
'notes60000',
|
||||
'notes70000',
|
||||
'notes80000',
|
||||
'notes90000',
|
||||
'notes100000',
|
||||
'login3',
|
||||
'login7',
|
||||
'login15',
|
||||
'login30',
|
||||
'login60',
|
||||
'login100',
|
||||
'login200',
|
||||
'login300',
|
||||
'login400',
|
||||
'login500',
|
||||
'login600',
|
||||
'login700',
|
||||
'login800',
|
||||
'login900',
|
||||
'login1000',
|
||||
'passedSinceAccountCreated1',
|
||||
'passedSinceAccountCreated2',
|
||||
'passedSinceAccountCreated3',
|
||||
'loggedInOnBirthday',
|
||||
'loggedInOnNewYearsDay',
|
||||
'noteClipped1',
|
||||
'noteFavorited1',
|
||||
'myNoteFavorited1',
|
||||
'profileFilled',
|
||||
'markedAsCat',
|
||||
'following1',
|
||||
'following10',
|
||||
'following50',
|
||||
'following100',
|
||||
'following300',
|
||||
'followers1',
|
||||
'followers10',
|
||||
'followers50',
|
||||
'followers100',
|
||||
'followers300',
|
||||
'followers500',
|
||||
'followers1000',
|
||||
'collectAchievements30',
|
||||
'viewAchievements3min',
|
||||
'iLoveMisskey',
|
||||
'foundTreasure',
|
||||
'client30min',
|
||||
'client60min',
|
||||
'noteDeletedWithin1min',
|
||||
'postedAtLateNight',
|
||||
'postedAt0min0sec',
|
||||
'selfQuote',
|
||||
'htl20npm',
|
||||
'viewInstanceChart',
|
||||
'outputHelloWorldOnScratchpad',
|
||||
'open3windows',
|
||||
'driveFolderCircularReference',
|
||||
'reactWithoutRead',
|
||||
'clickedClickHere',
|
||||
'justPlainLucky',
|
||||
'setNameToSyuilo',
|
||||
'cookieClicked',
|
||||
'brainDiver',
|
||||
] as const;
|
||||
import { ACHIEVEMENT_TYPES } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class AchievementService {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { isUserRelated } from '@/misc/is-user-related.js';
|
|||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { PushNotificationService } from '@/core/PushNotificationService.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { MutingsRepository, NotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
|
|
|
@ -16,7 +16,7 @@ import type {
|
|||
UserListStreamTypes,
|
||||
RoleTimelineStreamTypes,
|
||||
} from '@/server/api/stream/types.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
|||
import { In } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Note } from '@/models/entities/Note.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
|
|
|
@ -3,7 +3,7 @@ import push from 'web-push';
|
|||
import * as Redis from 'ioredis';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { getNoteSummary } from '@/misc/get-note-summary.js';
|
||||
import type { SwSubscription, SwSubscriptionsRepository } from '@/models/index.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
|
|
|
@ -8,12 +8,12 @@ import { DI } from '@/di-symbols.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import type { RoleCondFormulaValue } from '@/models/entities/Role.js';
|
||||
import type { RoleCondFormulaValue } from 'misskey-js/built/schemas/role.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { StreamMessages } from '@/server/api/stream/types.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
export type RolePolicies = {
|
||||
|
|
|
@ -107,7 +107,10 @@ export class UserBlockingService implements OnModuleInit {
|
|||
if (this.userEntityService.isLocalUser(followee)) {
|
||||
this.userEntityService.pack(followee, followee, {
|
||||
detail: true,
|
||||
}).then(packed => this.globalEventService.publishMainStream(followee.id, 'meUpdated', packed));
|
||||
}).then(packed => {
|
||||
this.globalEventService.publishMainStream(followee.id, 'meUpdated', packed);
|
||||
return packed; // somehow this is needed by typescript
|
||||
});
|
||||
}
|
||||
|
||||
if (this.userEntityService.isLocalUser(follower) && !silent) {
|
||||
|
@ -122,6 +125,8 @@ export class UserBlockingService implements OnModuleInit {
|
|||
user: packed,
|
||||
});
|
||||
}
|
||||
|
||||
return packed; // somehow this is needed by typescript
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
|||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import InstanceChart from '@/core/chart/charts/instance.js';
|
||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||
import { WebhookService } from '@/core/WebhookService.js';
|
||||
|
@ -267,7 +267,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
this.userEntityService.pack(followee.id, follower, {
|
||||
detail: true,
|
||||
}).then(async packed => {
|
||||
this.globalEventService.publishMainStream(follower.id, 'follow', packed as Packed<'UserDetailedNotMe'>);
|
||||
this.globalEventService.publishMainStream(follower.id, 'follow', packed);
|
||||
|
||||
const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('follow'));
|
||||
for (const webhook of webhooks) {
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'activeUsers';
|
||||
|
||||
export const schema = {
|
||||
'readWrite': { intersection: ['read', 'write'] },
|
||||
'read': { uniqueIncrement: true },
|
||||
'write': { uniqueIncrement: true },
|
||||
'registeredWithinWeek': { uniqueIncrement: true },
|
||||
'registeredWithinMonth': { uniqueIncrement: true },
|
||||
'registeredWithinYear': { uniqueIncrement: true },
|
||||
'registeredOutsideWeek': { uniqueIncrement: true },
|
||||
'registeredOutsideMonth': { uniqueIncrement: true },
|
||||
'registeredOutsideYear': { uniqueIncrement: true },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'activeUsers' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'apRequest';
|
||||
|
||||
export const schema = {
|
||||
'deliverFailed': { },
|
||||
'deliverSucceeded': { },
|
||||
'inboxReceived': { },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'apRequest' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'drive';
|
||||
|
||||
export const schema = {
|
||||
'local.incCount': {},
|
||||
'local.incSize': {}, // in kilobyte
|
||||
'local.decCount': {},
|
||||
'local.decSize': {}, // in kilobyte
|
||||
'remote.incCount': {},
|
||||
'remote.incSize': {}, // in kilobyte
|
||||
'remote.decCount': {},
|
||||
'remote.decSize': {}, // in kilobyte
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'drive' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'federation';
|
||||
|
||||
export const schema = {
|
||||
'deliveredInstances': { uniqueIncrement: true, range: 'small' },
|
||||
'inboxInstances': { uniqueIncrement: true, range: 'small' },
|
||||
'stalled': { uniqueIncrement: true, range: 'small' },
|
||||
'sub': { accumulate: true, range: 'small' },
|
||||
'pub': { accumulate: true, range: 'small' },
|
||||
'pubsub': { accumulate: true, range: 'small' },
|
||||
'subActive': { accumulate: true, range: 'small' },
|
||||
'pubActive': { accumulate: true, range: 'small' },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'federation' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,32 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'instance';
|
||||
|
||||
export const schema = {
|
||||
'requests.failed': { range: 'small' },
|
||||
'requests.succeeded': { range: 'small' },
|
||||
'requests.received': { range: 'small' },
|
||||
'notes.total': { accumulate: true },
|
||||
'notes.inc': {},
|
||||
'notes.dec': {},
|
||||
'notes.diffs.normal': {},
|
||||
'notes.diffs.reply': {},
|
||||
'notes.diffs.renote': {},
|
||||
'notes.diffs.withFile': {},
|
||||
'users.total': { accumulate: true },
|
||||
'users.inc': { range: 'small' },
|
||||
'users.dec': { range: 'small' },
|
||||
'following.total': { accumulate: true },
|
||||
'following.inc': { range: 'small' },
|
||||
'following.dec': { range: 'small' },
|
||||
'followers.total': { accumulate: true },
|
||||
'followers.inc': { range: 'small' },
|
||||
'followers.dec': { range: 'small' },
|
||||
'drive.totalFiles': { accumulate: true },
|
||||
'drive.incFiles': {},
|
||||
'drive.decFiles': {},
|
||||
'drive.incUsage': {}, // in kilobyte
|
||||
'drive.decUsage': {}, // in kilobyte
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'instance' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'notes';
|
||||
|
||||
export const schema = {
|
||||
'local.total': { accumulate: true },
|
||||
'local.inc': {},
|
||||
'local.dec': {},
|
||||
'local.diffs.normal': {},
|
||||
'local.diffs.reply': {},
|
||||
'local.diffs.renote': {},
|
||||
'local.diffs.withFile': {},
|
||||
'remote.total': { accumulate: true },
|
||||
'remote.inc': {},
|
||||
'remote.dec': {},
|
||||
'remote.diffs.normal': {},
|
||||
'remote.diffs.reply': {},
|
||||
'remote.diffs.renote': {},
|
||||
'remote.diffs.withFile': {},
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'notes' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'perUserDrive';
|
||||
|
||||
export const schema = {
|
||||
'totalCount': { accumulate: true },
|
||||
'totalSize': { accumulate: true }, // in kilobyte
|
||||
'incCount': { range: 'small' },
|
||||
'incSize': {}, // in kilobyte
|
||||
'decCount': { range: 'small' },
|
||||
'decSize': {}, // in kilobyte
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'perUserDrive' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,20 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'perUserFollowing';
|
||||
|
||||
export const schema = {
|
||||
'local.followings.total': { accumulate: true },
|
||||
'local.followings.inc': { range: 'small' },
|
||||
'local.followings.dec': { range: 'small' },
|
||||
'local.followers.total': { accumulate: true },
|
||||
'local.followers.inc': { range: 'small' },
|
||||
'local.followers.dec': { range: 'small' },
|
||||
'remote.followings.total': { accumulate: true },
|
||||
'remote.followings.inc': { range: 'small' },
|
||||
'remote.followings.dec': { range: 'small' },
|
||||
'remote.followers.total': { accumulate: true },
|
||||
'remote.followers.inc': { range: 'small' },
|
||||
'remote.followers.dec': { range: 'small' },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'perUserFollowing' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'perUserNotes';
|
||||
|
||||
export const schema = {
|
||||
'total': { accumulate: true },
|
||||
'inc': { range: 'small' },
|
||||
'dec': { range: 'small' },
|
||||
'diffs.normal': { range: 'small' },
|
||||
'diffs.reply': { range: 'small' },
|
||||
'diffs.renote': { range: 'small' },
|
||||
'diffs.withFile': { range: 'small' },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'perUserNotes' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'perUserPv';
|
||||
|
||||
export const schema = {
|
||||
'upv.user': { uniqueIncrement: true, range: 'small' },
|
||||
'pv.user': { range: 'small' },
|
||||
'upv.visitor': { uniqueIncrement: true, range: 'small' },
|
||||
'pv.visitor': { range: 'small' },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'perUserPv' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
export const name = 'perUserReaction';
|
||||
|
||||
export const schema = {
|
||||
'local.count': { range: 'small' },
|
||||
'remote.count': { range: 'small' },
|
||||
} as const;
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'perUserReactions' as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'testGrouped';
|
||||
|
||||
export const schema = {
|
||||
'foo.total': { accumulate: true },
|
||||
'foo.inc': {},
|
||||
'foo.dec': {},
|
||||
} as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema, true);
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'testIntersection';
|
||||
|
||||
export const schema = {
|
||||
'a': { uniqueIncrement: true },
|
||||
'b': { uniqueIncrement: true },
|
||||
'aAndB': { intersection: ['a', 'b'] },
|
||||
} as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'testUnique';
|
||||
|
||||
export const schema = {
|
||||
'foo': { uniqueIncrement: true },
|
||||
} as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'test';
|
||||
|
||||
export const schema = {
|
||||
'foo.total': { accumulate: true },
|
||||
'foo.inc': {},
|
||||
'foo.dec': {},
|
||||
} as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
import Chart from '../../core.js';
|
||||
|
||||
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
|
||||
export const name = 'users';
|
||||
|
||||
export const schema = {
|
||||
'local.total': { accumulate: true },
|
||||
'local.inc': { range: 'small' },
|
||||
'local.dec': { range: 'small' },
|
||||
'remote.total': { accumulate: true },
|
||||
'remote.inc': { range: 'small' },
|
||||
'remote.dec': { range: 'small' },
|
||||
} as const;
|
||||
export const schema = chartsSchemas[name];
|
||||
|
||||
export const entity = Chart.schemaToEntity(name, schema);
|
||||
|
|
|
@ -10,22 +10,12 @@ import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/misc
|
|||
import type Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Repository, DataSource } from 'typeorm';
|
||||
import type { ChartSchema as Schema, ChartResult, Unflatten } from 'misskey-js/built/schemas';
|
||||
|
||||
const COLUMN_PREFIX = '___' as const;
|
||||
const UNIQUE_TEMP_COLUMN_PREFIX = 'unique_temp___' as const;
|
||||
const COLUMN_DELIMITER = '_' as const;
|
||||
|
||||
type Schema = Record<string, {
|
||||
uniqueIncrement?: boolean;
|
||||
|
||||
intersection?: string[] | ReadonlyArray<string>;
|
||||
|
||||
range?: 'big' | 'small' | 'medium';
|
||||
|
||||
// previousな値を引き継ぐかどうか
|
||||
accumulate?: boolean;
|
||||
}>;
|
||||
|
||||
type KeyToColumnName<T extends string> = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof COLUMN_DELIMITER}${KeyToColumnName<R2>}` : T;
|
||||
|
||||
type Columns<S extends Schema> = {
|
||||
|
@ -64,47 +54,6 @@ export type KVs<S extends Schema> = {
|
|||
[K in keyof S]: number;
|
||||
};
|
||||
|
||||
type ChartResult<T extends Schema> = {
|
||||
[P in keyof T]: number[];
|
||||
};
|
||||
|
||||
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
|
||||
|
||||
type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}`
|
||||
? { [_ in A]: UnflattenSingleton<B, V>; }
|
||||
: { [_ in K]: V; };
|
||||
|
||||
type Unflatten<T extends Record<string, any>> = UnionToIntersection<
|
||||
{
|
||||
[K in Extract<keyof T, string>]: UnflattenSingleton<K, T[K]>;
|
||||
}[Extract<keyof T, string>]
|
||||
>;
|
||||
|
||||
type ToJsonSchema<S> = {
|
||||
type: 'object';
|
||||
properties: {
|
||||
[K in keyof S]: S[K] extends number[] ? { type: 'array'; items: { type: 'number'; }; } : ToJsonSchema<S[K]>;
|
||||
},
|
||||
required: (keyof S)[];
|
||||
};
|
||||
|
||||
export function getJsonSchema<S extends Schema>(schema: S): ToJsonSchema<Unflatten<ChartResult<S>>> {
|
||||
const jsonSchema = {
|
||||
type: 'object',
|
||||
properties: {} as Record<string, unknown>,
|
||||
required: [],
|
||||
};
|
||||
|
||||
for (const k in schema) {
|
||||
jsonSchema.properties[k] = {
|
||||
type: 'array',
|
||||
items: { type: 'number' },
|
||||
};
|
||||
}
|
||||
|
||||
return jsonSchema as ToJsonSchema<Unflatten<ChartResult<S>>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 様々なチャートの管理を司るクラス
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@ import { awaitAll } from '@/misc/prelude/await-all.js';
|
|||
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class AbuseUserReportEntityService {
|
||||
|
@ -19,7 +20,7 @@ export class AbuseUserReportEntityService {
|
|||
@bindThis
|
||||
public async pack(
|
||||
src: AbuseUserReport['id'] | AbuseUserReport,
|
||||
) {
|
||||
): Promise<Packed<'AbuseUserReport'>> {
|
||||
const report = typeof src === 'object' ? src : await this.abuseUserReportsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
|
@ -46,7 +47,7 @@ export class AbuseUserReportEntityService {
|
|||
@bindThis
|
||||
public packMany(
|
||||
reports: any[],
|
||||
) {
|
||||
): Promise<Packed<'AbuseUserReport'>[]> {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { AntennasRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Antenna } from '@/models/entities/Antenna.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { AccessTokensRepository, AppsRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { App } from '@/models/entities/App.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -6,6 +6,7 @@ import type { AuthSession } from '@/models/entities/AuthSession.js';
|
|||
import type { User } from '@/models/entities/User.js';
|
||||
import { AppEntityService } from './AppEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class AuthSessionEntityService {
|
||||
|
@ -21,7 +22,7 @@ export class AuthSessionEntityService {
|
|||
public async pack(
|
||||
src: AuthSession['id'] | AuthSession,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'AuthSession'>> {
|
||||
const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
|
|
|
@ -2,11 +2,12 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { BlockingsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Blocking } from '@/models/entities/Blocking.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import type { Serialized } from 'schema-type';
|
||||
|
||||
@Injectable()
|
||||
export class BlockingEntityService {
|
||||
|
@ -39,7 +40,7 @@ export class BlockingEntityService {
|
|||
public packMany(
|
||||
blockings: any[],
|
||||
me: { id: User['id'] },
|
||||
) {
|
||||
): Promise<Packed<'Blocking'>[]> {
|
||||
return Promise.all(blockings.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { ChannelFavoritesRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, NoteUnreadsRepository, NotesRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Channel } from '@/models/entities/Channel.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { ClipFavoritesRepository, ClipsRepository, User } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Clip } from '@/models/entities/Clip.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
@ -47,7 +46,7 @@ export class ClipEntityService {
|
|||
public packMany(
|
||||
clips: Clip[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'Clip'>[]> {
|
||||
return Promise.all(clips.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { DataSource, In } from 'typeorm';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { NotesRepository, DriveFilesRepository } from '@/models/index.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
||||
|
@ -265,11 +265,11 @@ export class DriveFileEntityService {
|
|||
public async packManyByIdsMap(
|
||||
fileIds: DriveFile['id'][],
|
||||
options?: PackOptions,
|
||||
): Promise<Map<Packed<'DriveFile'>['id'], Packed<'DriveFile'> | null>> {
|
||||
): Promise<Map<Packed<'DriveFile'>>['id'], Serialized<Packed<'DriveFile'> | null>> {
|
||||
if (fileIds.length === 0) return new Map();
|
||||
const files = await this.driveFilesRepository.findBy({ id: In(fileIds) });
|
||||
const packedFiles = await this.packMany(files, options);
|
||||
const map = new Map<Packed<'DriveFile'>['id'], Packed<'DriveFile'> | null>(packedFiles.map(f => [f.id, f]));
|
||||
const map = new Map<Packed<'DriveFile'>>['id'], Serialized<Packed<'DriveFile'> | null>(packedFiles.map(f => [f.id, f]));
|
||||
for (const id of fileIds) {
|
||||
if (!map.has(id)) map.set(id, null);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { DriveFolder } from '@/models/entities/DriveFolder.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { EmojisRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Emoji } from '@/models/entities/Emoji.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { FlashsRepository, FlashLikesRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Flash } from '@/models/entities/Flash.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { FlashLikesRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { FlashLike } from '@/models/entities/FlashLike.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { FollowRequestsRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { FollowRequest } from '@/models/entities/FollowRequest.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { Packed } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class FollowRequestEntityService {
|
||||
|
@ -21,7 +21,7 @@ export class FollowRequestEntityService {
|
|||
public async pack(
|
||||
src: FollowRequest['id'] | FollowRequest,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'FollowRequest'>> {
|
||||
const request = typeof src === 'object' ? src : await this.followRequestsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { FollowingsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Following } from '@/models/entities/Following.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { GalleryLikesRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { GalleryLike } from '@/models/entities/GalleryLike.js';
|
||||
import { GalleryPostEntityService } from './GalleryPostEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { GalleryLikesRepository, GalleryPostsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { GalleryPost } from '@/models/entities/GalleryPost.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { HashtagsRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Hashtag } from '@/models/entities/Hashtag.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { InstancesRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Instance } from '@/models/entities/Instance.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -2,10 +2,10 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { ModerationLogsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { ModerationLog } from '@/models/entities/ModerationLog.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class ModerationLogEntityService {
|
||||
|
@ -20,7 +20,7 @@ export class ModerationLogEntityService {
|
|||
@bindThis
|
||||
public async pack(
|
||||
src: ModerationLog['id'] | ModerationLog,
|
||||
) {
|
||||
): Promise<Packed<'ModerationLog'>> {
|
||||
const log = typeof src === 'object' ? src : await this.moderationLogsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return await awaitAll({
|
||||
|
@ -38,8 +38,7 @@ export class ModerationLogEntityService {
|
|||
@bindThis
|
||||
public packMany(
|
||||
reports: any[],
|
||||
) {
|
||||
): Promise<Packed<'ModerationLog'>[]> {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { MutingsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Muting } from '@/models/entities/Muting.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { DataSource, In } from 'typeorm';
|
|||
import * as mfm from 'mfm-js';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { nyaize } from '@/misc/nyaize.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { NoteFavoritesRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { NoteFavorite } from '@/models/entities/NoteFavorite.js';
|
||||
import { NoteEntityService } from './NoteEntityService.js';
|
||||
|
@ -21,7 +21,7 @@ export class NoteFavoriteEntityService {
|
|||
public async pack(
|
||||
src: NoteFavorite['id'] | NoteFavorite,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'NoteFavorite'>> {
|
||||
const favorite = typeof src === 'object' ? src : await this.noteFavoritesRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { NoteReactionsRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { NoteReaction } from '@/models/entities/NoteReaction.js';
|
||||
import type { ReactionService } from '../ReactionService.js';
|
||||
|
|
|
@ -6,10 +6,10 @@ import type { AccessTokensRepository, FollowRequestsRepository, NoteReactionsRep
|
|||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Notification } from '@/models/entities/Notification.js';
|
||||
import type { Note } from '@/models/entities/Note.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import { notificationTypes } from '@/types.js';
|
||||
import { notificationTypes } from 'misskey-js';
|
||||
import type { OnModuleInit } from '@nestjs/common';
|
||||
import type { CustomEmojiService } from '../CustomEmojiService.js';
|
||||
import type { UserEntityService } from './UserEntityService.js';
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { DriveFilesRepository, PagesRepository, PageLikesRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { Page } from '@/models/entities/Page.js';
|
||||
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { PageLikesRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { PageLike } from '@/models/entities/PageLike.js';
|
||||
import { PageEntityService } from './PageEntityService.js';
|
||||
|
|
|
@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import type { RenoteMutingsRepository } from '@/models/index.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { User } from '@/models/entities/User.js';
|
||||
import type { RenoteMuting } from '@/models/entities/RenoteMuting.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
|
|
@ -8,6 +8,7 @@ import type { Role } from '@/models/entities/Role.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
@Injectable()
|
||||
export class RoleEntityService {
|
||||
|
@ -26,7 +27,7 @@ export class RoleEntityService {
|
|||
public async pack(
|
||||
src: Role['id'] | Role,
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
) {
|
||||
): Promise<Packed<'Role'>> {
|
||||
const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src });
|
||||
|
||||
const assignedCount = await this.roleAssignmentsRepository.createQueryBuilder('assign')
|
||||
|
@ -37,7 +38,7 @@ export class RoleEntityService {
|
|||
}))
|
||||
.getCount();
|
||||
|
||||
const policies = { ...role.policies };
|
||||
const policies: { [x: string]: Packed<'RolePolicy'> } = { ...role.policies };
|
||||
for (const [k, v] of Object.entries(DEFAULT_POLICIES)) {
|
||||
if (policies[k] == null) policies[k] = {
|
||||
useDefault: true,
|
||||
|
@ -72,8 +73,7 @@ export class RoleEntityService {
|
|||
public packMany(
|
||||
roles: any[],
|
||||
me: { id: User['id'] },
|
||||
) {
|
||||
): Promise<Packed<'Role'>[]> {
|
||||
return Promise.all(roles.map(x => this.pack(x, me)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { SigninsRepository } from '@/models/index.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Signin } from '@/models/entities/Signin.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
|
@ -19,8 +19,10 @@ export class SigninEntityService {
|
|||
@bindThis
|
||||
public async pack(
|
||||
src: Signin,
|
||||
) {
|
||||
return src;
|
||||
): Promise<Packed<'SignIn'>> {
|
||||
return {
|
||||
...src,
|
||||
createdAt: src.createdAt.toISOString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import _Ajv from 'ajv';
|
|||
import { ModuleRef } from '@nestjs/core';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { Promiseable } from '@/misc/prelude/await-all.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
|
||||
|
@ -28,7 +28,7 @@ type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends bo
|
|||
Detailed extends true ?
|
||||
ExpectsMe extends true ? Packed<'MeDetailed'> :
|
||||
ExpectsMe extends false ? Packed<'UserDetailedNotMe'> :
|
||||
Packed<'UserDetailed'> :
|
||||
(Packed<'MeDetailed'> | Packed<'UserDetailedNotMe'>) :
|
||||
Packed<'UserLite'>;
|
||||
|
||||
const Ajv = _Ajv.default;
|
||||
|
@ -291,7 +291,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
return `${this.config.url}/users/${userId}`;
|
||||
}
|
||||
|
||||
public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>(
|
||||
public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false, R = IsMeAndIsUserDetailed<ExpectsMe, D>>(
|
||||
src: User['id'] | User,
|
||||
me?: { id: User['id']; } | null | undefined,
|
||||
options?: {
|
||||
|
@ -299,7 +299,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
includeSecrets?: boolean,
|
||||
userProfile?: UserProfile,
|
||||
},
|
||||
): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
|
||||
): Promise<R> {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
includeSecrets: false,
|
||||
|
@ -499,19 +499,19 @@ export class UserEntityService implements OnModuleInit {
|
|||
isMuted: relation.isMuted,
|
||||
isRenoteMuted: relation.isRenoteMuted,
|
||||
} : {}),
|
||||
} as Promiseable<Packed<'User'>> as Promiseable<IsMeAndIsUserDetailed<ExpectsMe, D>>;
|
||||
} as Promiseable<R>;
|
||||
|
||||
return await awaitAll(packed);
|
||||
}
|
||||
|
||||
public packMany<D extends boolean = false>(
|
||||
public packMany<D extends boolean = false, R = IsUserDetailed<D>>(
|
||||
users: (User['id'] | User)[],
|
||||
me?: { id: User['id'] } | null | undefined,
|
||||
options?: {
|
||||
detail?: D,
|
||||
includeSecrets?: boolean,
|
||||
},
|
||||
): Promise<IsUserDetailed<D>[]> {
|
||||
return Promise.all(users.map(u => this.pack(u, me, options)));
|
||||
): Promise<R[]> {
|
||||
return Promise.all(users.map(u => this.pack<null, D, R>(u, me, options)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { UserListJoiningsRepository, UserListsRepository } from '@/models/index.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { } from '@/models/entities/Blocking.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
import type { UserList } from '@/models/entities/UserList.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
@ -39,4 +38,3 @@ export class UserListEntityService {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Packed } from './json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
/**
|
||||
* 投稿を表す文字列を取得します。
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Packed } from './json-schema.js';
|
||||
import type { Packed } from 'misskey-js';
|
||||
|
||||
export function isInstanceMuted(note: Packed<'Note'>, mutedInstances: Set<string>): boolean {
|
||||
if (mutedInstances.has(note.user.host ?? '')) return true;
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
import {
|
||||
packedUserLiteSchema,
|
||||
packedUserDetailedNotMeOnlySchema,
|
||||
packedMeDetailedOnlySchema,
|
||||
packedUserDetailedNotMeSchema,
|
||||
packedMeDetailedSchema,
|
||||
packedUserDetailedSchema,
|
||||
packedUserSchema,
|
||||
} from '@/models/json-schema/user.js';
|
||||
import { packedNoteSchema } from '@/models/json-schema/note.js';
|
||||
import { packedUserListSchema } from '@/models/json-schema/user-list.js';
|
||||
import { packedAppSchema } from '@/models/json-schema/app.js';
|
||||
import { packedNotificationSchema } from '@/models/json-schema/notification.js';
|
||||
import { packedDriveFileSchema } from '@/models/json-schema/drive-file.js';
|
||||
import { packedDriveFolderSchema } from '@/models/json-schema/drive-folder.js';
|
||||
import { packedFollowingSchema } from '@/models/json-schema/following.js';
|
||||
import { packedMutingSchema } from '@/models/json-schema/muting.js';
|
||||
import { packedRenoteMutingSchema } from '@/models/json-schema/renote-muting.js';
|
||||
import { packedBlockingSchema } from '@/models/json-schema/blocking.js';
|
||||
import { packedNoteReactionSchema } from '@/models/json-schema/note-reaction.js';
|
||||
import { packedHashtagSchema } from '@/models/json-schema/hashtag.js';
|
||||
import { packedPageSchema } from '@/models/json-schema/page.js';
|
||||
import { packedNoteFavoriteSchema } from '@/models/json-schema/note-favorite.js';
|
||||
import { packedChannelSchema } from '@/models/json-schema/channel.js';
|
||||
import { packedAntennaSchema } from '@/models/json-schema/antenna.js';
|
||||
import { packedClipSchema } from '@/models/json-schema/clip.js';
|
||||
import { packedFederationInstanceSchema } from '@/models/json-schema/federation-instance.js';
|
||||
import { packedQueueCountSchema } from '@/models/json-schema/queue.js';
|
||||
import { packedGalleryPostSchema } from '@/models/json-schema/gallery-post.js';
|
||||
import { packedEmojiDetailedSchema, packedEmojiSimpleSchema } from '@/models/json-schema/emoji.js';
|
||||
import { packedFlashSchema } from '@/models/json-schema/flash.js';
|
||||
|
||||
export const refs = {
|
||||
UserLite: packedUserLiteSchema,
|
||||
UserDetailedNotMeOnly: packedUserDetailedNotMeOnlySchema,
|
||||
MeDetailedOnly: packedMeDetailedOnlySchema,
|
||||
UserDetailedNotMe: packedUserDetailedNotMeSchema,
|
||||
MeDetailed: packedMeDetailedSchema,
|
||||
UserDetailed: packedUserDetailedSchema,
|
||||
User: packedUserSchema,
|
||||
|
||||
UserList: packedUserListSchema,
|
||||
App: packedAppSchema,
|
||||
Note: packedNoteSchema,
|
||||
NoteReaction: packedNoteReactionSchema,
|
||||
NoteFavorite: packedNoteFavoriteSchema,
|
||||
Notification: packedNotificationSchema,
|
||||
DriveFile: packedDriveFileSchema,
|
||||
DriveFolder: packedDriveFolderSchema,
|
||||
Following: packedFollowingSchema,
|
||||
Muting: packedMutingSchema,
|
||||
RenoteMuting: packedRenoteMutingSchema,
|
||||
Blocking: packedBlockingSchema,
|
||||
Hashtag: packedHashtagSchema,
|
||||
Page: packedPageSchema,
|
||||
Channel: packedChannelSchema,
|
||||
QueueCount: packedQueueCountSchema,
|
||||
Antenna: packedAntennaSchema,
|
||||
Clip: packedClipSchema,
|
||||
FederationInstance: packedFederationInstanceSchema,
|
||||
GalleryPost: packedGalleryPostSchema,
|
||||
EmojiSimple: packedEmojiSimpleSchema,
|
||||
EmojiDetailed: packedEmojiDetailedSchema,
|
||||
Flash: packedFlashSchema,
|
||||
};
|
||||
|
||||
export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;
|
||||
|
||||
type TypeStringef = 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'array' | 'object' | 'any';
|
||||
type StringDefToType<T extends TypeStringef> =
|
||||
T extends 'null' ? null :
|
||||
T extends 'boolean' ? boolean :
|
||||
T extends 'integer' ? number :
|
||||
T extends 'number' ? number :
|
||||
T extends 'string' ? string | Date :
|
||||
T extends 'array' ? ReadonlyArray<any> :
|
||||
T extends 'object' ? Record<string, any> :
|
||||
any;
|
||||
|
||||
// https://swagger.io/specification/?sbsearch=optional#schema-object
|
||||
type OfSchema = {
|
||||
readonly anyOf?: ReadonlyArray<Schema>;
|
||||
readonly oneOf?: ReadonlyArray<Schema>;
|
||||
readonly allOf?: ReadonlyArray<Schema>;
|
||||
}
|
||||
|
||||
export interface Schema extends OfSchema {
|
||||
readonly type?: TypeStringef;
|
||||
readonly nullable?: boolean;
|
||||
readonly optional?: boolean;
|
||||
readonly items?: Schema;
|
||||
readonly properties?: Obj;
|
||||
readonly required?: ReadonlyArray<Extract<keyof NonNullable<this['properties']>, string>>;
|
||||
readonly description?: string;
|
||||
readonly example?: any;
|
||||
readonly format?: string;
|
||||
readonly ref?: keyof typeof refs;
|
||||
readonly enum?: ReadonlyArray<string | null>;
|
||||
readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null;
|
||||
readonly maxLength?: number;
|
||||
readonly minLength?: number;
|
||||
readonly maximum?: number;
|
||||
readonly minimum?: number;
|
||||
readonly pattern?: string;
|
||||
}
|
||||
|
||||
type RequiredPropertyNames<s extends Obj> = {
|
||||
[K in keyof s]:
|
||||
// K is not optional
|
||||
s[K]['optional'] extends false ? K :
|
||||
// K has default value
|
||||
s[K]['default'] extends null | string | number | boolean | Record<string, unknown> ? K :
|
||||
never
|
||||
}[keyof s];
|
||||
|
||||
export type Obj = Record<string, Schema>;
|
||||
|
||||
// https://github.com/misskey-dev/misskey/issues/8535
|
||||
// To avoid excessive stack depth error,
|
||||
// deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it).
|
||||
export type ObjType<s extends Obj, RequiredProps extends ReadonlyArray<keyof s>> =
|
||||
UnionToIntersection<
|
||||
{ -readonly [R in RequiredPropertyNames<s>]-?: SchemaType<s[R]> } &
|
||||
{ -readonly [R in RequiredProps[number]]-?: SchemaType<s[R]> } &
|
||||
{ -readonly [P in keyof s]?: SchemaType<s[P]> }
|
||||
>;
|
||||
|
||||
type NullOrUndefined<p extends Schema, T> =
|
||||
| (p['nullable'] extends true ? null : never)
|
||||
| (p['optional'] extends true ? undefined : never)
|
||||
| T;
|
||||
|
||||
// https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
|
||||
// Get intersection from union
|
||||
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
||||
type PartialIntersection<T> = Partial<UnionToIntersection<T>>;
|
||||
|
||||
// https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552
|
||||
// To get union, we use `Foo extends any ? Hoge<Foo> : never`
|
||||
type UnionSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? SchemaType<X> : never;
|
||||
//type UnionObjectSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? ObjectSchemaType<X> : never;
|
||||
type UnionObjType<s extends Obj, a extends readonly any[], X extends ReadonlyArray<keyof s> = a[number]> = X extends any ? ObjType<s, X> : never;
|
||||
type ArrayUnion<T> = T extends any ? Array<T> : never;
|
||||
|
||||
type ObjectSchemaTypeDef<p extends Schema> =
|
||||
p['ref'] extends keyof typeof refs ? Packed<p['ref']> :
|
||||
p['properties'] extends NonNullable<Obj> ?
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? p['anyOf'][number]['required'] extends ReadonlyArray<keyof p['properties']> ?
|
||||
UnionObjType<p['properties'], NonNullable<p['anyOf'][number]['required']>> & ObjType<p['properties'], NonNullable<p['required']>>
|
||||
: never
|
||||
: ObjType<p['properties'], NonNullable<p['required']>>
|
||||
:
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? never : // see CONTRIBUTING.md
|
||||
p['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> :
|
||||
any
|
||||
|
||||
type ObjectSchemaType<p extends Schema> = NullOrUndefined<p, ObjectSchemaTypeDef<p>>;
|
||||
|
||||
export type SchemaTypeDef<p extends Schema> =
|
||||
p['type'] extends 'null' ? null :
|
||||
p['type'] extends 'integer' ? number :
|
||||
p['type'] extends 'number' ? number :
|
||||
p['type'] extends 'string' ? (
|
||||
p['enum'] extends readonly (string | null)[] ?
|
||||
p['enum'][number] :
|
||||
p['format'] extends 'date-time' ? string : // Dateにする??
|
||||
string
|
||||
) :
|
||||
p['type'] extends 'boolean' ? boolean :
|
||||
p['type'] extends 'object' ? ObjectSchemaTypeDef<p> :
|
||||
p['type'] extends 'array' ? (
|
||||
p['items'] extends OfSchema ? (
|
||||
p['items']['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<NonNullable<p['items']['anyOf']>>[] :
|
||||
p['items']['oneOf'] extends ReadonlyArray<Schema> ? ArrayUnion<UnionSchemaType<NonNullable<p['items']['oneOf']>>> :
|
||||
p['items']['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<NonNullable<p['items']['allOf']>>>[] :
|
||||
never
|
||||
) :
|
||||
p['items'] extends NonNullable<Schema> ? SchemaTypeDef<p['items']>[] :
|
||||
any[]
|
||||
) :
|
||||
p['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['anyOf']> & PartialIntersection<UnionSchemaType<p['anyOf']>> :
|
||||
p['oneOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['oneOf']> :
|
||||
any;
|
||||
|
||||
export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>;
|
|
@ -1,6 +1,6 @@
|
|||
import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { id } from '../id.js';
|
||||
import { mutedNoteReasons } from '../../types.js';
|
||||
import { mutedNoteReasons } from 'misskey-js';
|
||||
import { Note } from './Note.js';
|
||||
import { User } from './User.js';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm';
|
||||
import { id } from '../id.js';
|
||||
import { noteVisibilities } from '../../types.js';
|
||||
import { noteVisibilities } from 'misskey-js';
|
||||
import { User } from './User.js';
|
||||
import { Channel } from './Channel.js';
|
||||
import type { DriveFile } from './DriveFile.js';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { notificationTypes } from '@/types.js';
|
||||
import { ACHIEVEMENT_TYPES, notificationTypes } from 'misskey-js';
|
||||
import { User } from './User.js';
|
||||
import { Note } from './Note.js';
|
||||
import { FollowRequest } from './FollowRequest.js';
|
||||
|
@ -39,7 +39,7 @@ export type Notification = {
|
|||
|
||||
choice: number | null;
|
||||
|
||||
achievement: string | null;
|
||||
achievement: typeof ACHIEVEMENT_TYPES[number] | null;
|
||||
|
||||
/**
|
||||
* アプリ通知のbody
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
|
||||
import { id } from '../id.js';
|
||||
import { noteVisibilities } from '../../types.js';
|
||||
import { noteVisibilities } from 'misskey-js';
|
||||
import { Note } from './Note.js';
|
||||
import type { User } from './User.js';
|
||||
|
||||
|
|
|
@ -1,83 +1,6 @@
|
|||
import { Entity, Column, PrimaryColumn } from 'typeorm';
|
||||
import { id } from '../id.js';
|
||||
|
||||
type CondFormulaValueAnd = {
|
||||
type: 'and';
|
||||
values: RoleCondFormulaValue[];
|
||||
};
|
||||
|
||||
type CondFormulaValueOr = {
|
||||
type: 'or';
|
||||
values: RoleCondFormulaValue[];
|
||||
};
|
||||
|
||||
type CondFormulaValueNot = {
|
||||
type: 'not';
|
||||
value: RoleCondFormulaValue;
|
||||
};
|
||||
|
||||
type CondFormulaValueIsLocal = {
|
||||
type: 'isLocal';
|
||||
};
|
||||
|
||||
type CondFormulaValueIsRemote = {
|
||||
type: 'isRemote';
|
||||
};
|
||||
|
||||
type CondFormulaValueCreatedLessThan = {
|
||||
type: 'createdLessThan';
|
||||
sec: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueCreatedMoreThan = {
|
||||
type: 'createdMoreThan';
|
||||
sec: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueFollowersLessThanOrEq = {
|
||||
type: 'followersLessThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueFollowersMoreThanOrEq = {
|
||||
type: 'followersMoreThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueFollowingLessThanOrEq = {
|
||||
type: 'followingLessThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueFollowingMoreThanOrEq = {
|
||||
type: 'followingMoreThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueNotesLessThanOrEq = {
|
||||
type: 'notesLessThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
type CondFormulaValueNotesMoreThanOrEq = {
|
||||
type: 'notesMoreThanOrEq';
|
||||
value: number;
|
||||
};
|
||||
|
||||
export type RoleCondFormulaValue =
|
||||
CondFormulaValueAnd |
|
||||
CondFormulaValueOr |
|
||||
CondFormulaValueNot |
|
||||
CondFormulaValueIsLocal |
|
||||
CondFormulaValueIsRemote |
|
||||
CondFormulaValueCreatedLessThan |
|
||||
CondFormulaValueCreatedMoreThan |
|
||||
CondFormulaValueFollowersLessThanOrEq |
|
||||
CondFormulaValueFollowersMoreThanOrEq |
|
||||
CondFormulaValueFollowingLessThanOrEq |
|
||||
CondFormulaValueFollowingMoreThanOrEq |
|
||||
CondFormulaValueNotesLessThanOrEq |
|
||||
CondFormulaValueNotesMoreThanOrEq;
|
||||
import type { RoleCondFormulaValue } from 'misskey-js/built/schemas/role.js';
|
||||
|
||||
@Entity()
|
||||
export class Role {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
|
||||
import { obsoleteNotificationTypes, ffVisibility, notificationTypes } from '@/types.js';
|
||||
import { obsoleteNotificationTypes, ffVisibility, notificationTypes } from 'misskey-js';
|
||||
import { id } from '../id.js';
|
||||
import { User } from './User.js';
|
||||
import { Page } from './Page.js';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { notificationTypes } from '@/types.js';
|
||||
import { notificationTypes } from 'misskey-js';
|
||||
|
||||
export const packedNotificationSchema = {
|
||||
type: 'object',
|
||||
|
|
|
@ -19,7 +19,8 @@ import { ApiLoggerService } from './ApiLoggerService.js';
|
|||
import { AuthenticateService, AuthenticationError } from './AuthenticateService.js';
|
||||
import type { FastifyRequest, FastifyReply } from 'fastify';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
import type { IEndpointMeta, IEndpoint } from './endpoints.js';
|
||||
import type { IEndpointMeta } from 'misskey-js/built/endpoints.types.js';
|
||||
import { ExecutorWrapper } from './endpoint-base.js';
|
||||
|
||||
const pump = promisify(pipeline);
|
||||
|
||||
|
@ -88,7 +89,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
public handleRequest(
|
||||
endpoint: IEndpoint & { exec: any },
|
||||
endpoint: { name: string, meta: IEndpointMeta, exec: ExecutorWrapper },
|
||||
request: FastifyRequest<{ Body: Record<string, unknown> | undefined, Querystring: Record<string, unknown> }>,
|
||||
reply: FastifyReply,
|
||||
): void {
|
||||
|
@ -124,7 +125,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
public async handleMultipartRequest(
|
||||
endpoint: IEndpoint & { exec: any },
|
||||
endpoint: { name: string, meta: IEndpointMeta, exec: ExecutorWrapper },
|
||||
request: FastifyRequest<{ Body: Record<string, unknown>, Querystring: Record<string, unknown> }>,
|
||||
reply: FastifyReply,
|
||||
): Promise<void> {
|
||||
|
@ -219,7 +220,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
private async call(
|
||||
ep: IEndpoint & { exec: any },
|
||||
ep: { name: string, meta: IEndpointMeta, exec: ExecutorWrapper },
|
||||
user: LocalUser | null | undefined,
|
||||
token: AccessToken | null | undefined,
|
||||
data: any,
|
||||
|
@ -337,10 +338,13 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
// Cast non JSON input
|
||||
if ((ep.meta.requireFile || request.method === 'GET') && ep.params.properties) {
|
||||
for (const k of Object.keys(ep.params.properties)) {
|
||||
const param = ep.params.properties![k];
|
||||
if (['boolean', 'number', 'integer'].includes(param.type ?? '') && typeof data[k] === 'string') {
|
||||
if ((ep.meta.requireFile || request.method === 'GET') && ep.meta.defines[0]?.req?.properties) {
|
||||
for (const k of Object.keys(ep.meta.defines[0].req.properties)) {
|
||||
const param = ep.meta.defines[0].req.properties[k];
|
||||
if (typeof param === 'object' && (
|
||||
(typeof param.type === 'string' && ['boolean', 'number', 'integer'].includes(param.type ?? '')) ||
|
||||
(Array.isArray(param.type) && param.type.every(t => ['boolean', 'number', 'integer'].includes(t)))
|
||||
) && typeof data[k] === 'string') {
|
||||
try {
|
||||
data[k] = JSON.parse(data[k]);
|
||||
} catch (e) {
|
||||
|
|
|
@ -8,11 +8,12 @@ import type { UsersRepository, InstancesRepository, AccessTokensRepository } fro
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import endpoints from './endpoints.js';
|
||||
import { endpoints } from 'misskey-js/built/endpoints.js';
|
||||
import { ApiCallService } from './ApiCallService.js';
|
||||
import { SignupApiService } from './SignupApiService.js';
|
||||
import { SigninApiService } from './SigninApiService.js';
|
||||
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
|
||||
import { ExecutorWrapper } from './endpoint-base.js';
|
||||
|
||||
@Injectable()
|
||||
export class ApiServerService {
|
||||
|
@ -60,21 +61,20 @@ export class ApiServerService {
|
|||
done();
|
||||
});
|
||||
|
||||
for (const endpoint of endpoints) {
|
||||
for (const [name, meta] of Object.entries(endpoints)) {
|
||||
const ep = {
|
||||
name: endpoint.name,
|
||||
meta: endpoint.meta,
|
||||
params: endpoint.params,
|
||||
exec: this.moduleRef.get('ep:' + endpoint.name, { strict: false }).exec,
|
||||
name,
|
||||
meta,
|
||||
exec: this.moduleRef.get('ep:' + name, { strict: false }).exec as ExecutorWrapper,
|
||||
};
|
||||
|
||||
if (endpoint.meta.requireFile) {
|
||||
if (meta.requireFile) {
|
||||
fastify.all<{
|
||||
Params: { endpoint: string; },
|
||||
Body: Record<string, unknown>,
|
||||
Querystring: Record<string, unknown>,
|
||||
}>('/' + endpoint.name, async (request, reply) => {
|
||||
if (request.method === 'GET' && !endpoint.meta.allowGet) {
|
||||
}>('/' + name, async (request, reply) => {
|
||||
if (request.method === 'GET' && !meta.allowGet) {
|
||||
reply.code(405);
|
||||
reply.send();
|
||||
return;
|
||||
|
@ -89,8 +89,8 @@ export class ApiServerService {
|
|||
Params: { endpoint: string; },
|
||||
Body: Record<string, unknown>,
|
||||
Querystring: Record<string, unknown>,
|
||||
}>('/' + endpoint.name, { bodyLimit: 1024 * 1024 }, async (request, reply) => {
|
||||
if (request.method === 'GET' && !endpoint.meta.allowGet) {
|
||||
}>('/' + name, { bodyLimit: 1024 * 1024 }, async (request, reply) => {
|
||||
if (request.method === 'GET' && !meta.allowGet) {
|
||||
reply.code(405);
|
||||
reply.send();
|
||||
return;
|
||||
|
|
|
@ -5,7 +5,7 @@ import { DI } from '@/di-symbols.js';
|
|||
import type Logger from '@/logger.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { IEndpointMeta } from './endpoints.js';
|
||||
import type { IEndpointMeta } from 'misskey-js/built/endpoints.types.js';
|
||||
|
||||
@Injectable()
|
||||
export class RateLimiterService {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import * as fs from 'node:fs';
|
||||
import _Ajv from 'ajv';
|
||||
import type { Schema, SchemaType } from '@/misc/json-schema.js';
|
||||
import type { LocalUser } from '@/models/entities/User.js';
|
||||
import type { AccessToken } from '@/models/entities/AccessToken.js';
|
||||
import { ApiError } from './error.js';
|
||||
import type { IEndpointMeta } from './endpoints.js';
|
||||
import { endpoints, getEndpointSchema } from 'misskey-js/built/endpoints.js';
|
||||
import type { IEndpointMeta, ResponseOf, SchemaOrUndefined } from 'misskey-js/built/endpoints.types.js';
|
||||
import type { Endpoints } from 'misskey-js';
|
||||
import { WeakSerialized } from 'schema-type';
|
||||
|
||||
const Ajv = _Ajv.default;
|
||||
|
||||
|
@ -21,21 +23,42 @@ type File = {
|
|||
path: string;
|
||||
};
|
||||
|
||||
// TODO: paramsの型をT['params']のスキーマ定義から推論する
|
||||
type Executor<T extends IEndpointMeta, Ps extends Schema> =
|
||||
(params: SchemaType<Ps>, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record<string, string> | null) =>
|
||||
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
|
||||
export type Executor<T extends IEndpointMeta, P = SchemaOrUndefined<T['defines'][number]['req'], true>> =
|
||||
(
|
||||
params: P,
|
||||
user: LocalUser | (T['requireCredential'] extends true ? never : null),
|
||||
token: AccessToken | null,
|
||||
file?: File,
|
||||
cleanup?: () => any,
|
||||
ip?: string | null,
|
||||
headers?: Record<string, string> | null
|
||||
) => Promise<WeakSerialized<ResponseOf<T, P, true>>>;
|
||||
|
||||
export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
|
||||
public exec: (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => Promise<any>;
|
||||
// ExecutorWrapperの型はあえて緩くしておく
|
||||
export type ExecutorWrapper =
|
||||
(
|
||||
params: any,
|
||||
user: LocalUser | null,
|
||||
token: AccessToken | null,
|
||||
file?: File,
|
||||
ip?: string | null,
|
||||
headers?: Record<string, string> | null
|
||||
) => Promise<any>;
|
||||
|
||||
constructor(meta: T, paramDef: Ps, cb: Executor<T, Ps>) {
|
||||
const validate = ajv.compile(paramDef);
|
||||
export abstract class Endpoint<E extends keyof Endpoints, T extends IEndpointMeta = Endpoints[E]> {
|
||||
public readonly name: E;
|
||||
public readonly meta: Endpoints[E];
|
||||
public exec: ExecutorWrapper;
|
||||
|
||||
this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => {
|
||||
constructor(cb: Executor<T>) {
|
||||
this.meta = endpoints[this.name];
|
||||
const req = getEndpointSchema('req', this.name);
|
||||
const validate = req ? ajv.compile(req) : null;
|
||||
|
||||
this.exec = (params, user, token, file, ip, headers) => {
|
||||
let cleanup: undefined | (() => void) = undefined;
|
||||
|
||||
if (meta.requireFile) {
|
||||
if (this.meta.requireFile) {
|
||||
cleanup = () => {
|
||||
if (file) fs.unlink(file.path, () => {});
|
||||
};
|
||||
|
@ -47,7 +70,9 @@ export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
|
|||
}));
|
||||
}
|
||||
|
||||
if (validate) {
|
||||
const valid = validate(params);
|
||||
|
||||
if (!valid) {
|
||||
if (file) cleanup!();
|
||||
|
||||
|
@ -62,8 +87,12 @@ export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
|
|||
});
|
||||
return Promise.reject(err);
|
||||
}
|
||||
} else {
|
||||
// validateがnullである場合、paramsがnullや空オブジェクトであるべきではあるが、
|
||||
// 特にチェックはしない
|
||||
}
|
||||
|
||||
return cb(params as SchemaType<Ps>, user, token, file, cleanup, ip, headers);
|
||||
return cb(params as any, user as any, token, file, cleanup, ip, headers);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,793 +0,0 @@
|
|||
import type { Schema } from '@/misc/json-schema.js';
|
||||
import { RolePolicies } from '@/core/RoleService.js';
|
||||
|
||||
import * as ep___admin_meta from './endpoints/admin/meta.js';
|
||||
import * as ep___admin_abuseUserReports from './endpoints/admin/abuse-user-reports.js';
|
||||
import * as ep___admin_accounts_create from './endpoints/admin/accounts/create.js';
|
||||
import * as ep___admin_accounts_delete from './endpoints/admin/accounts/delete.js';
|
||||
import * as ep___admin_ad_create from './endpoints/admin/ad/create.js';
|
||||
import * as ep___admin_ad_delete from './endpoints/admin/ad/delete.js';
|
||||
import * as ep___admin_ad_list from './endpoints/admin/ad/list.js';
|
||||
import * as ep___admin_ad_update from './endpoints/admin/ad/update.js';
|
||||
import * as ep___admin_announcements_create from './endpoints/admin/announcements/create.js';
|
||||
import * as ep___admin_announcements_delete from './endpoints/admin/announcements/delete.js';
|
||||
import * as ep___admin_announcements_list from './endpoints/admin/announcements/list.js';
|
||||
import * as ep___admin_announcements_update from './endpoints/admin/announcements/update.js';
|
||||
import * as ep___admin_deleteAllFilesOfAUser from './endpoints/admin/delete-all-files-of-a-user.js';
|
||||
import * as ep___admin_drive_cleanRemoteFiles from './endpoints/admin/drive/clean-remote-files.js';
|
||||
import * as ep___admin_drive_cleanup from './endpoints/admin/drive/cleanup.js';
|
||||
import * as ep___admin_drive_files from './endpoints/admin/drive/files.js';
|
||||
import * as ep___admin_drive_showFile from './endpoints/admin/drive/show-file.js';
|
||||
import * as ep___admin_emoji_addAliasesBulk from './endpoints/admin/emoji/add-aliases-bulk.js';
|
||||
import * as ep___admin_emoji_add from './endpoints/admin/emoji/add.js';
|
||||
import * as ep___admin_emoji_copy from './endpoints/admin/emoji/copy.js';
|
||||
import * as ep___admin_emoji_deleteBulk from './endpoints/admin/emoji/delete-bulk.js';
|
||||
import * as ep___admin_emoji_delete from './endpoints/admin/emoji/delete.js';
|
||||
import * as ep___admin_emoji_importZip from './endpoints/admin/emoji/import-zip.js';
|
||||
import * as ep___admin_emoji_listRemote from './endpoints/admin/emoji/list-remote.js';
|
||||
import * as ep___admin_emoji_list from './endpoints/admin/emoji/list.js';
|
||||
import * as ep___admin_emoji_removeAliasesBulk from './endpoints/admin/emoji/remove-aliases-bulk.js';
|
||||
import * as ep___admin_emoji_setAliasesBulk from './endpoints/admin/emoji/set-aliases-bulk.js';
|
||||
import * as ep___admin_emoji_setCategoryBulk from './endpoints/admin/emoji/set-category-bulk.js';
|
||||
import * as ep___admin_emoji_setLicenseBulk from './endpoints/admin/emoji/set-license-bulk.js';
|
||||
import * as ep___admin_emoji_update from './endpoints/admin/emoji/update.js';
|
||||
import * as ep___admin_federation_deleteAllFiles from './endpoints/admin/federation/delete-all-files.js';
|
||||
import * as ep___admin_federation_refreshRemoteInstanceMetadata from './endpoints/admin/federation/refresh-remote-instance-metadata.js';
|
||||
import * as ep___admin_federation_removeAllFollowing from './endpoints/admin/federation/remove-all-following.js';
|
||||
import * as ep___admin_federation_updateInstance from './endpoints/admin/federation/update-instance.js';
|
||||
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
||||
import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js';
|
||||
import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js';
|
||||
import * as ep___invite from './endpoints/invite.js';
|
||||
import * as ep___admin_promo_create from './endpoints/admin/promo/create.js';
|
||||
import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js';
|
||||
import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js';
|
||||
import * as ep___admin_queue_inboxDelayed from './endpoints/admin/queue/inbox-delayed.js';
|
||||
import * as ep___admin_queue_promote from './endpoints/admin/queue/promote.js';
|
||||
import * as ep___admin_queue_stats from './endpoints/admin/queue/stats.js';
|
||||
import * as ep___admin_relays_add from './endpoints/admin/relays/add.js';
|
||||
import * as ep___admin_relays_list from './endpoints/admin/relays/list.js';
|
||||
import * as ep___admin_relays_remove from './endpoints/admin/relays/remove.js';
|
||||
import * as ep___admin_resetPassword from './endpoints/admin/reset-password.js';
|
||||
import * as ep___admin_resolveAbuseUserReport from './endpoints/admin/resolve-abuse-user-report.js';
|
||||
import * as ep___admin_sendEmail from './endpoints/admin/send-email.js';
|
||||
import * as ep___admin_serverInfo from './endpoints/admin/server-info.js';
|
||||
import * as ep___admin_showModerationLogs from './endpoints/admin/show-moderation-logs.js';
|
||||
import * as ep___admin_showUser from './endpoints/admin/show-user.js';
|
||||
import * as ep___admin_showUsers from './endpoints/admin/show-users.js';
|
||||
import * as ep___admin_suspendUser from './endpoints/admin/suspend-user.js';
|
||||
import * as ep___admin_unsuspendUser from './endpoints/admin/unsuspend-user.js';
|
||||
import * as ep___admin_updateMeta from './endpoints/admin/update-meta.js';
|
||||
import * as ep___admin_deleteAccount from './endpoints/admin/delete-account.js';
|
||||
import * as ep___admin_updateUserNote from './endpoints/admin/update-user-note.js';
|
||||
import * as ep___admin_roles_create from './endpoints/admin/roles/create.js';
|
||||
import * as ep___admin_roles_delete from './endpoints/admin/roles/delete.js';
|
||||
import * as ep___admin_roles_list from './endpoints/admin/roles/list.js';
|
||||
import * as ep___admin_roles_show from './endpoints/admin/roles/show.js';
|
||||
import * as ep___admin_roles_update from './endpoints/admin/roles/update.js';
|
||||
import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js';
|
||||
import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js';
|
||||
import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js';
|
||||
import * as ep___admin_roles_users from './endpoints/admin/roles/users.js';
|
||||
import * as ep___announcements from './endpoints/announcements.js';
|
||||
import * as ep___antennas_create from './endpoints/antennas/create.js';
|
||||
import * as ep___antennas_delete from './endpoints/antennas/delete.js';
|
||||
import * as ep___antennas_list from './endpoints/antennas/list.js';
|
||||
import * as ep___antennas_notes from './endpoints/antennas/notes.js';
|
||||
import * as ep___antennas_show from './endpoints/antennas/show.js';
|
||||
import * as ep___antennas_update from './endpoints/antennas/update.js';
|
||||
import * as ep___ap_get from './endpoints/ap/get.js';
|
||||
import * as ep___ap_show from './endpoints/ap/show.js';
|
||||
import * as ep___app_create from './endpoints/app/create.js';
|
||||
import * as ep___app_show from './endpoints/app/show.js';
|
||||
import * as ep___auth_accept from './endpoints/auth/accept.js';
|
||||
import * as ep___auth_session_generate from './endpoints/auth/session/generate.js';
|
||||
import * as ep___auth_session_show from './endpoints/auth/session/show.js';
|
||||
import * as ep___auth_session_userkey from './endpoints/auth/session/userkey.js';
|
||||
import * as ep___blocking_create from './endpoints/blocking/create.js';
|
||||
import * as ep___blocking_delete from './endpoints/blocking/delete.js';
|
||||
import * as ep___blocking_list from './endpoints/blocking/list.js';
|
||||
import * as ep___channels_create from './endpoints/channels/create.js';
|
||||
import * as ep___channels_featured from './endpoints/channels/featured.js';
|
||||
import * as ep___channels_follow from './endpoints/channels/follow.js';
|
||||
import * as ep___channels_followed from './endpoints/channels/followed.js';
|
||||
import * as ep___channels_owned from './endpoints/channels/owned.js';
|
||||
import * as ep___channels_show from './endpoints/channels/show.js';
|
||||
import * as ep___channels_timeline from './endpoints/channels/timeline.js';
|
||||
import * as ep___channels_unfollow from './endpoints/channels/unfollow.js';
|
||||
import * as ep___channels_update from './endpoints/channels/update.js';
|
||||
import * as ep___channels_favorite from './endpoints/channels/favorite.js';
|
||||
import * as ep___channels_unfavorite from './endpoints/channels/unfavorite.js';
|
||||
import * as ep___channels_myFavorites from './endpoints/channels/my-favorites.js';
|
||||
import * as ep___channels_search from './endpoints/channels/search.js';
|
||||
import * as ep___charts_activeUsers from './endpoints/charts/active-users.js';
|
||||
import * as ep___charts_apRequest from './endpoints/charts/ap-request.js';
|
||||
import * as ep___charts_drive from './endpoints/charts/drive.js';
|
||||
import * as ep___charts_federation from './endpoints/charts/federation.js';
|
||||
import * as ep___charts_instance from './endpoints/charts/instance.js';
|
||||
import * as ep___charts_notes from './endpoints/charts/notes.js';
|
||||
import * as ep___charts_user_drive from './endpoints/charts/user/drive.js';
|
||||
import * as ep___charts_user_following from './endpoints/charts/user/following.js';
|
||||
import * as ep___charts_user_notes from './endpoints/charts/user/notes.js';
|
||||
import * as ep___charts_user_pv from './endpoints/charts/user/pv.js';
|
||||
import * as ep___charts_user_reactions from './endpoints/charts/user/reactions.js';
|
||||
import * as ep___charts_users from './endpoints/charts/users.js';
|
||||
import * as ep___clips_addNote from './endpoints/clips/add-note.js';
|
||||
import * as ep___clips_removeNote from './endpoints/clips/remove-note.js';
|
||||
import * as ep___clips_create from './endpoints/clips/create.js';
|
||||
import * as ep___clips_delete from './endpoints/clips/delete.js';
|
||||
import * as ep___clips_list from './endpoints/clips/list.js';
|
||||
import * as ep___clips_notes from './endpoints/clips/notes.js';
|
||||
import * as ep___clips_show from './endpoints/clips/show.js';
|
||||
import * as ep___clips_update from './endpoints/clips/update.js';
|
||||
import * as ep___clips_favorite from './endpoints/clips/favorite.js';
|
||||
import * as ep___clips_unfavorite from './endpoints/clips/unfavorite.js';
|
||||
import * as ep___clips_myFavorites from './endpoints/clips/my-favorites.js';
|
||||
import * as ep___drive from './endpoints/drive.js';
|
||||
import * as ep___drive_files from './endpoints/drive/files.js';
|
||||
import * as ep___drive_files_attachedNotes from './endpoints/drive/files/attached-notes.js';
|
||||
import * as ep___drive_files_checkExistence from './endpoints/drive/files/check-existence.js';
|
||||
import * as ep___drive_files_create from './endpoints/drive/files/create.js';
|
||||
import * as ep___drive_files_delete from './endpoints/drive/files/delete.js';
|
||||
import * as ep___drive_files_findByHash from './endpoints/drive/files/find-by-hash.js';
|
||||
import * as ep___drive_files_find from './endpoints/drive/files/find.js';
|
||||
import * as ep___drive_files_show from './endpoints/drive/files/show.js';
|
||||
import * as ep___drive_files_update from './endpoints/drive/files/update.js';
|
||||
import * as ep___drive_files_uploadFromUrl from './endpoints/drive/files/upload-from-url.js';
|
||||
import * as ep___drive_folders from './endpoints/drive/folders.js';
|
||||
import * as ep___drive_folders_create from './endpoints/drive/folders/create.js';
|
||||
import * as ep___drive_folders_delete from './endpoints/drive/folders/delete.js';
|
||||
import * as ep___drive_folders_find from './endpoints/drive/folders/find.js';
|
||||
import * as ep___drive_folders_show from './endpoints/drive/folders/show.js';
|
||||
import * as ep___drive_folders_update from './endpoints/drive/folders/update.js';
|
||||
import * as ep___drive_stream from './endpoints/drive/stream.js';
|
||||
import * as ep___emailAddress_available from './endpoints/email-address/available.js';
|
||||
import * as ep___endpoint from './endpoints/endpoint.js';
|
||||
import * as ep___endpoints from './endpoints/endpoints.js';
|
||||
import * as ep___exportCustomEmojis from './endpoints/export-custom-emojis.js';
|
||||
import * as ep___federation_followers from './endpoints/federation/followers.js';
|
||||
import * as ep___federation_following from './endpoints/federation/following.js';
|
||||
import * as ep___federation_instances from './endpoints/federation/instances.js';
|
||||
import * as ep___federation_showInstance from './endpoints/federation/show-instance.js';
|
||||
import * as ep___federation_updateRemoteUser from './endpoints/federation/update-remote-user.js';
|
||||
import * as ep___federation_users from './endpoints/federation/users.js';
|
||||
import * as ep___federation_stats from './endpoints/federation/stats.js';
|
||||
import * as ep___following_create from './endpoints/following/create.js';
|
||||
import * as ep___following_delete from './endpoints/following/delete.js';
|
||||
import * as ep___following_invalidate from './endpoints/following/invalidate.js';
|
||||
import * as ep___following_requests_accept from './endpoints/following/requests/accept.js';
|
||||
import * as ep___following_requests_cancel from './endpoints/following/requests/cancel.js';
|
||||
import * as ep___following_requests_list from './endpoints/following/requests/list.js';
|
||||
import * as ep___following_requests_reject from './endpoints/following/requests/reject.js';
|
||||
import * as ep___gallery_featured from './endpoints/gallery/featured.js';
|
||||
import * as ep___gallery_popular from './endpoints/gallery/popular.js';
|
||||
import * as ep___gallery_posts from './endpoints/gallery/posts.js';
|
||||
import * as ep___gallery_posts_create from './endpoints/gallery/posts/create.js';
|
||||
import * as ep___gallery_posts_delete from './endpoints/gallery/posts/delete.js';
|
||||
import * as ep___gallery_posts_like from './endpoints/gallery/posts/like.js';
|
||||
import * as ep___gallery_posts_show from './endpoints/gallery/posts/show.js';
|
||||
import * as ep___gallery_posts_unlike from './endpoints/gallery/posts/unlike.js';
|
||||
import * as ep___gallery_posts_update from './endpoints/gallery/posts/update.js';
|
||||
import * as ep___getOnlineUsersCount from './endpoints/get-online-users-count.js';
|
||||
import * as ep___hashtags_list from './endpoints/hashtags/list.js';
|
||||
import * as ep___hashtags_search from './endpoints/hashtags/search.js';
|
||||
import * as ep___hashtags_show from './endpoints/hashtags/show.js';
|
||||
import * as ep___hashtags_trend from './endpoints/hashtags/trend.js';
|
||||
import * as ep___hashtags_users from './endpoints/hashtags/users.js';
|
||||
import * as ep___i from './endpoints/i.js';
|
||||
import * as ep___i_2fa_done from './endpoints/i/2fa/done.js';
|
||||
import * as ep___i_2fa_keyDone from './endpoints/i/2fa/key-done.js';
|
||||
import * as ep___i_2fa_passwordLess from './endpoints/i/2fa/password-less.js';
|
||||
import * as ep___i_2fa_registerKey from './endpoints/i/2fa/register-key.js';
|
||||
import * as ep___i_2fa_register from './endpoints/i/2fa/register.js';
|
||||
import * as ep___i_2fa_updateKey from './endpoints/i/2fa/update-key.js';
|
||||
import * as ep___i_2fa_removeKey from './endpoints/i/2fa/remove-key.js';
|
||||
import * as ep___i_2fa_unregister from './endpoints/i/2fa/unregister.js';
|
||||
import * as ep___i_apps from './endpoints/i/apps.js';
|
||||
import * as ep___i_authorizedApps from './endpoints/i/authorized-apps.js';
|
||||
import * as ep___i_claimAchievement from './endpoints/i/claim-achievement.js';
|
||||
import * as ep___i_changePassword from './endpoints/i/change-password.js';
|
||||
import * as ep___i_deleteAccount from './endpoints/i/delete-account.js';
|
||||
import * as ep___i_exportBlocking from './endpoints/i/export-blocking.js';
|
||||
import * as ep___i_exportFollowing from './endpoints/i/export-following.js';
|
||||
import * as ep___i_exportMute from './endpoints/i/export-mute.js';
|
||||
import * as ep___i_exportNotes from './endpoints/i/export-notes.js';
|
||||
import * as ep___i_exportFavorites from './endpoints/i/export-favorites.js';
|
||||
import * as ep___i_exportUserLists from './endpoints/i/export-user-lists.js';
|
||||
import * as ep___i_exportAntennas from './endpoints/i/export-antennas.js';
|
||||
import * as ep___i_favorites from './endpoints/i/favorites.js';
|
||||
import * as ep___i_gallery_likes from './endpoints/i/gallery/likes.js';
|
||||
import * as ep___i_gallery_posts from './endpoints/i/gallery/posts.js';
|
||||
import * as ep___i_getWordMutedNotesCount from './endpoints/i/get-word-muted-notes-count.js';
|
||||
import * as ep___i_importBlocking from './endpoints/i/import-blocking.js';
|
||||
import * as ep___i_importFollowing from './endpoints/i/import-following.js';
|
||||
import * as ep___i_importMuting from './endpoints/i/import-muting.js';
|
||||
import * as ep___i_importUserLists from './endpoints/i/import-user-lists.js';
|
||||
import * as ep___i_importAntennas from './endpoints/i/import-antennas.js';
|
||||
import * as ep___i_notifications from './endpoints/i/notifications.js';
|
||||
import * as ep___i_pageLikes from './endpoints/i/page-likes.js';
|
||||
import * as ep___i_pages from './endpoints/i/pages.js';
|
||||
import * as ep___i_pin from './endpoints/i/pin.js';
|
||||
import * as ep___i_readAllUnreadNotes from './endpoints/i/read-all-unread-notes.js';
|
||||
import * as ep___i_readAnnouncement from './endpoints/i/read-announcement.js';
|
||||
import * as ep___i_regenerateToken from './endpoints/i/regenerate-token.js';
|
||||
import * as ep___i_registry_getAll from './endpoints/i/registry/get-all.js';
|
||||
import * as ep___i_registry_getDetail from './endpoints/i/registry/get-detail.js';
|
||||
import * as ep___i_registry_get from './endpoints/i/registry/get.js';
|
||||
import * as ep___i_registry_keysWithType from './endpoints/i/registry/keys-with-type.js';
|
||||
import * as ep___i_registry_keys from './endpoints/i/registry/keys.js';
|
||||
import * as ep___i_registry_remove from './endpoints/i/registry/remove.js';
|
||||
import * as ep___i_registry_scopes from './endpoints/i/registry/scopes.js';
|
||||
import * as ep___i_registry_set from './endpoints/i/registry/set.js';
|
||||
import * as ep___i_revokeToken from './endpoints/i/revoke-token.js';
|
||||
import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
|
||||
import * as ep___i_unpin from './endpoints/i/unpin.js';
|
||||
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
|
||||
import * as ep___i_update from './endpoints/i/update.js';
|
||||
import * as ep___i_move from './endpoints/i/move.js';
|
||||
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
|
||||
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
|
||||
import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js';
|
||||
import * as ep___i_webhooks_update from './endpoints/i/webhooks/update.js';
|
||||
import * as ep___i_webhooks_delete from './endpoints/i/webhooks/delete.js';
|
||||
import * as ep___meta from './endpoints/meta.js';
|
||||
import * as ep___emojis from './endpoints/emojis.js';
|
||||
import * as ep___emoji from './endpoints/emoji.js';
|
||||
import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js';
|
||||
import * as ep___mute_create from './endpoints/mute/create.js';
|
||||
import * as ep___mute_delete from './endpoints/mute/delete.js';
|
||||
import * as ep___mute_list from './endpoints/mute/list.js';
|
||||
import * as ep___renoteMute_create from './endpoints/renote-mute/create.js';
|
||||
import * as ep___renoteMute_delete from './endpoints/renote-mute/delete.js';
|
||||
import * as ep___renoteMute_list from './endpoints/renote-mute/list.js';
|
||||
import * as ep___my_apps from './endpoints/my/apps.js';
|
||||
import * as ep___notes from './endpoints/notes.js';
|
||||
import * as ep___notes_children from './endpoints/notes/children.js';
|
||||
import * as ep___notes_clips from './endpoints/notes/clips.js';
|
||||
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
|
||||
import * as ep___notes_create from './endpoints/notes/create.js';
|
||||
import * as ep___notes_delete from './endpoints/notes/delete.js';
|
||||
import * as ep___notes_favorites_create from './endpoints/notes/favorites/create.js';
|
||||
import * as ep___notes_favorites_delete from './endpoints/notes/favorites/delete.js';
|
||||
import * as ep___notes_featured from './endpoints/notes/featured.js';
|
||||
import * as ep___notes_globalTimeline from './endpoints/notes/global-timeline.js';
|
||||
import * as ep___notes_hybridTimeline from './endpoints/notes/hybrid-timeline.js';
|
||||
import * as ep___notes_localTimeline from './endpoints/notes/local-timeline.js';
|
||||
import * as ep___notes_mentions from './endpoints/notes/mentions.js';
|
||||
import * as ep___notes_polls_recommendation from './endpoints/notes/polls/recommendation.js';
|
||||
import * as ep___notes_polls_vote from './endpoints/notes/polls/vote.js';
|
||||
import * as ep___notes_reactions from './endpoints/notes/reactions.js';
|
||||
import * as ep___notes_reactions_create from './endpoints/notes/reactions/create.js';
|
||||
import * as ep___notes_reactions_delete from './endpoints/notes/reactions/delete.js';
|
||||
import * as ep___notes_renotes from './endpoints/notes/renotes.js';
|
||||
import * as ep___notes_replies from './endpoints/notes/replies.js';
|
||||
import * as ep___notes_searchByTag from './endpoints/notes/search-by-tag.js';
|
||||
import * as ep___notes_search from './endpoints/notes/search.js';
|
||||
import * as ep___notes_show from './endpoints/notes/show.js';
|
||||
import * as ep___notes_state from './endpoints/notes/state.js';
|
||||
import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting/create.js';
|
||||
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
|
||||
import * as ep___notes_timeline from './endpoints/notes/timeline.js';
|
||||
import * as ep___notes_translate from './endpoints/notes/translate.js';
|
||||
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
|
||||
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
|
||||
import * as ep___notifications_create from './endpoints/notifications/create.js';
|
||||
import * as ep___notifications_markAllAsRead from './endpoints/notifications/mark-all-as-read.js';
|
||||
import * as ep___pagePush from './endpoints/page-push.js';
|
||||
import * as ep___pages_create from './endpoints/pages/create.js';
|
||||
import * as ep___pages_delete from './endpoints/pages/delete.js';
|
||||
import * as ep___pages_featured from './endpoints/pages/featured.js';
|
||||
import * as ep___pages_like from './endpoints/pages/like.js';
|
||||
import * as ep___pages_show from './endpoints/pages/show.js';
|
||||
import * as ep___pages_unlike from './endpoints/pages/unlike.js';
|
||||
import * as ep___pages_update from './endpoints/pages/update.js';
|
||||
import * as ep___flash_create from './endpoints/flash/create.js';
|
||||
import * as ep___flash_delete from './endpoints/flash/delete.js';
|
||||
import * as ep___flash_featured from './endpoints/flash/featured.js';
|
||||
import * as ep___flash_like from './endpoints/flash/like.js';
|
||||
import * as ep___flash_show from './endpoints/flash/show.js';
|
||||
import * as ep___flash_unlike from './endpoints/flash/unlike.js';
|
||||
import * as ep___flash_update from './endpoints/flash/update.js';
|
||||
import * as ep___flash_my from './endpoints/flash/my.js';
|
||||
import * as ep___flash_myLikes from './endpoints/flash/my-likes.js';
|
||||
import * as ep___ping from './endpoints/ping.js';
|
||||
import * as ep___pinnedUsers from './endpoints/pinned-users.js';
|
||||
import * as ep___promo_read from './endpoints/promo/read.js';
|
||||
import * as ep___roles_list from './endpoints/roles/list.js';
|
||||
import * as ep___roles_show from './endpoints/roles/show.js';
|
||||
import * as ep___roles_users from './endpoints/roles/users.js';
|
||||
import * as ep___roles_notes from './endpoints/roles/notes.js';
|
||||
import * as ep___requestResetPassword from './endpoints/request-reset-password.js';
|
||||
import * as ep___resetDb from './endpoints/reset-db.js';
|
||||
import * as ep___resetPassword from './endpoints/reset-password.js';
|
||||
import * as ep___serverInfo from './endpoints/server-info.js';
|
||||
import * as ep___stats from './endpoints/stats.js';
|
||||
import * as ep___sw_show_registration from './endpoints/sw/show-registration.js';
|
||||
import * as ep___sw_update_registration from './endpoints/sw/update-registration.js';
|
||||
import * as ep___sw_register from './endpoints/sw/register.js';
|
||||
import * as ep___sw_unregister from './endpoints/sw/unregister.js';
|
||||
import * as ep___test from './endpoints/test.js';
|
||||
import * as ep___username_available from './endpoints/username/available.js';
|
||||
import * as ep___users from './endpoints/users.js';
|
||||
import * as ep___users_clips from './endpoints/users/clips.js';
|
||||
import * as ep___users_followers from './endpoints/users/followers.js';
|
||||
import * as ep___users_following from './endpoints/users/following.js';
|
||||
import * as ep___users_gallery_posts from './endpoints/users/gallery/posts.js';
|
||||
import * as ep___users_getFrequentlyRepliedUsers from './endpoints/users/get-frequently-replied-users.js';
|
||||
import * as ep___users_lists_create from './endpoints/users/lists/create.js';
|
||||
import * as ep___users_lists_delete from './endpoints/users/lists/delete.js';
|
||||
import * as ep___users_lists_list from './endpoints/users/lists/list.js';
|
||||
import * as ep___users_lists_pull from './endpoints/users/lists/pull.js';
|
||||
import * as ep___users_lists_push from './endpoints/users/lists/push.js';
|
||||
import * as ep___users_lists_show from './endpoints/users/lists/show.js';
|
||||
import * as ep___users_lists_favorite from './endpoints/users/lists/favorite.js';
|
||||
import * as ep___users_lists_unfavorite from './endpoints/users/lists/unfavorite.js';
|
||||
import * as ep___users_lists_create_from_public from './endpoints/users/lists/create-from-public.js';
|
||||
import * as ep___users_lists_update from './endpoints/users/lists/update.js';
|
||||
import * as ep___users_notes from './endpoints/users/notes.js';
|
||||
import * as ep___users_pages from './endpoints/users/pages.js';
|
||||
import * as ep___users_reactions from './endpoints/users/reactions.js';
|
||||
import * as ep___users_recommendation from './endpoints/users/recommendation.js';
|
||||
import * as ep___users_relation from './endpoints/users/relation.js';
|
||||
import * as ep___users_reportAbuse from './endpoints/users/report-abuse.js';
|
||||
import * as ep___users_searchByUsernameAndHost from './endpoints/users/search-by-username-and-host.js';
|
||||
import * as ep___users_search from './endpoints/users/search.js';
|
||||
import * as ep___users_show from './endpoints/users/show.js';
|
||||
import * as ep___users_achievements from './endpoints/users/achievements.js';
|
||||
import * as ep___users_updateMemo from './endpoints/users/update-memo.js';
|
||||
import * as ep___fetchRss from './endpoints/fetch-rss.js';
|
||||
import * as ep___retention from './endpoints/retention.js';
|
||||
|
||||
const eps = [
|
||||
['admin/meta', ep___admin_meta],
|
||||
['admin/abuse-user-reports', ep___admin_abuseUserReports],
|
||||
['admin/accounts/create', ep___admin_accounts_create],
|
||||
['admin/accounts/delete', ep___admin_accounts_delete],
|
||||
['admin/ad/create', ep___admin_ad_create],
|
||||
['admin/ad/delete', ep___admin_ad_delete],
|
||||
['admin/ad/list', ep___admin_ad_list],
|
||||
['admin/ad/update', ep___admin_ad_update],
|
||||
['admin/announcements/create', ep___admin_announcements_create],
|
||||
['admin/announcements/delete', ep___admin_announcements_delete],
|
||||
['admin/announcements/list', ep___admin_announcements_list],
|
||||
['admin/announcements/update', ep___admin_announcements_update],
|
||||
['admin/delete-all-files-of-a-user', ep___admin_deleteAllFilesOfAUser],
|
||||
['admin/drive/clean-remote-files', ep___admin_drive_cleanRemoteFiles],
|
||||
['admin/drive/cleanup', ep___admin_drive_cleanup],
|
||||
['admin/drive/files', ep___admin_drive_files],
|
||||
['admin/drive/show-file', ep___admin_drive_showFile],
|
||||
['admin/emoji/add-aliases-bulk', ep___admin_emoji_addAliasesBulk],
|
||||
['admin/emoji/add', ep___admin_emoji_add],
|
||||
['admin/emoji/copy', ep___admin_emoji_copy],
|
||||
['admin/emoji/delete-bulk', ep___admin_emoji_deleteBulk],
|
||||
['admin/emoji/delete', ep___admin_emoji_delete],
|
||||
['admin/emoji/import-zip', ep___admin_emoji_importZip],
|
||||
['admin/emoji/list-remote', ep___admin_emoji_listRemote],
|
||||
['admin/emoji/list', ep___admin_emoji_list],
|
||||
['admin/emoji/remove-aliases-bulk', ep___admin_emoji_removeAliasesBulk],
|
||||
['admin/emoji/set-aliases-bulk', ep___admin_emoji_setAliasesBulk],
|
||||
['admin/emoji/set-category-bulk', ep___admin_emoji_setCategoryBulk],
|
||||
['admin/emoji/set-license-bulk', ep___admin_emoji_setLicenseBulk],
|
||||
['admin/emoji/update', ep___admin_emoji_update],
|
||||
['admin/federation/delete-all-files', ep___admin_federation_deleteAllFiles],
|
||||
['admin/federation/refresh-remote-instance-metadata', ep___admin_federation_refreshRemoteInstanceMetadata],
|
||||
['admin/federation/remove-all-following', ep___admin_federation_removeAllFollowing],
|
||||
['admin/federation/update-instance', ep___admin_federation_updateInstance],
|
||||
['admin/get-index-stats', ep___admin_getIndexStats],
|
||||
['admin/get-table-stats', ep___admin_getTableStats],
|
||||
['admin/get-user-ips', ep___admin_getUserIps],
|
||||
['invite', ep___invite],
|
||||
['admin/promo/create', ep___admin_promo_create],
|
||||
['admin/queue/clear', ep___admin_queue_clear],
|
||||
['admin/queue/deliver-delayed', ep___admin_queue_deliverDelayed],
|
||||
['admin/queue/inbox-delayed', ep___admin_queue_inboxDelayed],
|
||||
['admin/queue/promote', ep___admin_queue_promote],
|
||||
['admin/queue/stats', ep___admin_queue_stats],
|
||||
['admin/relays/add', ep___admin_relays_add],
|
||||
['admin/relays/list', ep___admin_relays_list],
|
||||
['admin/relays/remove', ep___admin_relays_remove],
|
||||
['admin/reset-password', ep___admin_resetPassword],
|
||||
['admin/resolve-abuse-user-report', ep___admin_resolveAbuseUserReport],
|
||||
['admin/send-email', ep___admin_sendEmail],
|
||||
['admin/server-info', ep___admin_serverInfo],
|
||||
['admin/show-moderation-logs', ep___admin_showModerationLogs],
|
||||
['admin/show-user', ep___admin_showUser],
|
||||
['admin/show-users', ep___admin_showUsers],
|
||||
['admin/suspend-user', ep___admin_suspendUser],
|
||||
['admin/unsuspend-user', ep___admin_unsuspendUser],
|
||||
['admin/update-meta', ep___admin_updateMeta],
|
||||
['admin/delete-account', ep___admin_deleteAccount],
|
||||
['admin/update-user-note', ep___admin_updateUserNote],
|
||||
['admin/roles/create', ep___admin_roles_create],
|
||||
['admin/roles/delete', ep___admin_roles_delete],
|
||||
['admin/roles/list', ep___admin_roles_list],
|
||||
['admin/roles/show', ep___admin_roles_show],
|
||||
['admin/roles/update', ep___admin_roles_update],
|
||||
['admin/roles/assign', ep___admin_roles_assign],
|
||||
['admin/roles/unassign', ep___admin_roles_unassign],
|
||||
['admin/roles/update-default-policies', ep___admin_roles_updateDefaultPolicies],
|
||||
['admin/roles/users', ep___admin_roles_users],
|
||||
['announcements', ep___announcements],
|
||||
['antennas/create', ep___antennas_create],
|
||||
['antennas/delete', ep___antennas_delete],
|
||||
['antennas/list', ep___antennas_list],
|
||||
['antennas/notes', ep___antennas_notes],
|
||||
['antennas/show', ep___antennas_show],
|
||||
['antennas/update', ep___antennas_update],
|
||||
['ap/get', ep___ap_get],
|
||||
['ap/show', ep___ap_show],
|
||||
['app/create', ep___app_create],
|
||||
['app/show', ep___app_show],
|
||||
['auth/accept', ep___auth_accept],
|
||||
['auth/session/generate', ep___auth_session_generate],
|
||||
['auth/session/show', ep___auth_session_show],
|
||||
['auth/session/userkey', ep___auth_session_userkey],
|
||||
['blocking/create', ep___blocking_create],
|
||||
['blocking/delete', ep___blocking_delete],
|
||||
['blocking/list', ep___blocking_list],
|
||||
['channels/create', ep___channels_create],
|
||||
['channels/featured', ep___channels_featured],
|
||||
['channels/follow', ep___channels_follow],
|
||||
['channels/followed', ep___channels_followed],
|
||||
['channels/owned', ep___channels_owned],
|
||||
['channels/show', ep___channels_show],
|
||||
['channels/timeline', ep___channels_timeline],
|
||||
['channels/unfollow', ep___channels_unfollow],
|
||||
['channels/update', ep___channels_update],
|
||||
['channels/favorite', ep___channels_favorite],
|
||||
['channels/unfavorite', ep___channels_unfavorite],
|
||||
['channels/my-favorites', ep___channels_myFavorites],
|
||||
['channels/search', ep___channels_search],
|
||||
['charts/active-users', ep___charts_activeUsers],
|
||||
['charts/ap-request', ep___charts_apRequest],
|
||||
['charts/drive', ep___charts_drive],
|
||||
['charts/federation', ep___charts_federation],
|
||||
['charts/instance', ep___charts_instance],
|
||||
['charts/notes', ep___charts_notes],
|
||||
['charts/user/drive', ep___charts_user_drive],
|
||||
['charts/user/following', ep___charts_user_following],
|
||||
['charts/user/notes', ep___charts_user_notes],
|
||||
['charts/user/pv', ep___charts_user_pv],
|
||||
['charts/user/reactions', ep___charts_user_reactions],
|
||||
['charts/users', ep___charts_users],
|
||||
['clips/add-note', ep___clips_addNote],
|
||||
['clips/remove-note', ep___clips_removeNote],
|
||||
['clips/create', ep___clips_create],
|
||||
['clips/delete', ep___clips_delete],
|
||||
['clips/list', ep___clips_list],
|
||||
['clips/notes', ep___clips_notes],
|
||||
['clips/show', ep___clips_show],
|
||||
['clips/update', ep___clips_update],
|
||||
['clips/favorite', ep___clips_favorite],
|
||||
['clips/unfavorite', ep___clips_unfavorite],
|
||||
['clips/my-favorites', ep___clips_myFavorites],
|
||||
['drive', ep___drive],
|
||||
['drive/files', ep___drive_files],
|
||||
['drive/files/attached-notes', ep___drive_files_attachedNotes],
|
||||
['drive/files/check-existence', ep___drive_files_checkExistence],
|
||||
['drive/files/create', ep___drive_files_create],
|
||||
['drive/files/delete', ep___drive_files_delete],
|
||||
['drive/files/find-by-hash', ep___drive_files_findByHash],
|
||||
['drive/files/find', ep___drive_files_find],
|
||||
['drive/files/show', ep___drive_files_show],
|
||||
['drive/files/update', ep___drive_files_update],
|
||||
['drive/files/upload-from-url', ep___drive_files_uploadFromUrl],
|
||||
['drive/folders', ep___drive_folders],
|
||||
['drive/folders/create', ep___drive_folders_create],
|
||||
['drive/folders/delete', ep___drive_folders_delete],
|
||||
['drive/folders/find', ep___drive_folders_find],
|
||||
['drive/folders/show', ep___drive_folders_show],
|
||||
['drive/folders/update', ep___drive_folders_update],
|
||||
['drive/stream', ep___drive_stream],
|
||||
['email-address/available', ep___emailAddress_available],
|
||||
['endpoint', ep___endpoint],
|
||||
['endpoints', ep___endpoints],
|
||||
['export-custom-emojis', ep___exportCustomEmojis],
|
||||
['federation/followers', ep___federation_followers],
|
||||
['federation/following', ep___federation_following],
|
||||
['federation/instances', ep___federation_instances],
|
||||
['federation/show-instance', ep___federation_showInstance],
|
||||
['federation/update-remote-user', ep___federation_updateRemoteUser],
|
||||
['federation/users', ep___federation_users],
|
||||
['federation/stats', ep___federation_stats],
|
||||
['following/create', ep___following_create],
|
||||
['following/delete', ep___following_delete],
|
||||
['following/invalidate', ep___following_invalidate],
|
||||
['following/requests/accept', ep___following_requests_accept],
|
||||
['following/requests/cancel', ep___following_requests_cancel],
|
||||
['following/requests/list', ep___following_requests_list],
|
||||
['following/requests/reject', ep___following_requests_reject],
|
||||
['gallery/featured', ep___gallery_featured],
|
||||
['gallery/popular', ep___gallery_popular],
|
||||
['gallery/posts', ep___gallery_posts],
|
||||
['gallery/posts/create', ep___gallery_posts_create],
|
||||
['gallery/posts/delete', ep___gallery_posts_delete],
|
||||
['gallery/posts/like', ep___gallery_posts_like],
|
||||
['gallery/posts/show', ep___gallery_posts_show],
|
||||
['gallery/posts/unlike', ep___gallery_posts_unlike],
|
||||
['gallery/posts/update', ep___gallery_posts_update],
|
||||
['get-online-users-count', ep___getOnlineUsersCount],
|
||||
['hashtags/list', ep___hashtags_list],
|
||||
['hashtags/search', ep___hashtags_search],
|
||||
['hashtags/show', ep___hashtags_show],
|
||||
['hashtags/trend', ep___hashtags_trend],
|
||||
['hashtags/users', ep___hashtags_users],
|
||||
['i', ep___i],
|
||||
['i/2fa/done', ep___i_2fa_done],
|
||||
['i/2fa/key-done', ep___i_2fa_keyDone],
|
||||
['i/2fa/password-less', ep___i_2fa_passwordLess],
|
||||
['i/2fa/register-key', ep___i_2fa_registerKey],
|
||||
['i/2fa/register', ep___i_2fa_register],
|
||||
['i/2fa/update-key', ep___i_2fa_updateKey],
|
||||
['i/2fa/remove-key', ep___i_2fa_removeKey],
|
||||
['i/2fa/unregister', ep___i_2fa_unregister],
|
||||
['i/apps', ep___i_apps],
|
||||
['i/authorized-apps', ep___i_authorizedApps],
|
||||
['i/claim-achievement', ep___i_claimAchievement],
|
||||
['i/change-password', ep___i_changePassword],
|
||||
['i/delete-account', ep___i_deleteAccount],
|
||||
['i/export-blocking', ep___i_exportBlocking],
|
||||
['i/export-following', ep___i_exportFollowing],
|
||||
['i/export-mute', ep___i_exportMute],
|
||||
['i/export-notes', ep___i_exportNotes],
|
||||
['i/export-favorites', ep___i_exportFavorites],
|
||||
['i/export-user-lists', ep___i_exportUserLists],
|
||||
['i/export-antennas', ep___i_exportAntennas],
|
||||
['i/favorites', ep___i_favorites],
|
||||
['i/gallery/likes', ep___i_gallery_likes],
|
||||
['i/gallery/posts', ep___i_gallery_posts],
|
||||
['i/get-word-muted-notes-count', ep___i_getWordMutedNotesCount],
|
||||
['i/import-blocking', ep___i_importBlocking],
|
||||
['i/import-following', ep___i_importFollowing],
|
||||
['i/import-muting', ep___i_importMuting],
|
||||
['i/import-user-lists', ep___i_importUserLists],
|
||||
['i/import-antennas', ep___i_importAntennas],
|
||||
['i/notifications', ep___i_notifications],
|
||||
['i/page-likes', ep___i_pageLikes],
|
||||
['i/pages', ep___i_pages],
|
||||
['i/pin', ep___i_pin],
|
||||
['i/read-all-unread-notes', ep___i_readAllUnreadNotes],
|
||||
['i/read-announcement', ep___i_readAnnouncement],
|
||||
['i/regenerate-token', ep___i_regenerateToken],
|
||||
['i/registry/get-all', ep___i_registry_getAll],
|
||||
['i/registry/get-detail', ep___i_registry_getDetail],
|
||||
['i/registry/get', ep___i_registry_get],
|
||||
['i/registry/keys-with-type', ep___i_registry_keysWithType],
|
||||
['i/registry/keys', ep___i_registry_keys],
|
||||
['i/registry/remove', ep___i_registry_remove],
|
||||
['i/registry/scopes', ep___i_registry_scopes],
|
||||
['i/registry/set', ep___i_registry_set],
|
||||
['i/revoke-token', ep___i_revokeToken],
|
||||
['i/signin-history', ep___i_signinHistory],
|
||||
['i/unpin', ep___i_unpin],
|
||||
['i/update-email', ep___i_updateEmail],
|
||||
['i/update', ep___i_update],
|
||||
['i/move', ep___i_move],
|
||||
['i/webhooks/create', ep___i_webhooks_create],
|
||||
['i/webhooks/list', ep___i_webhooks_list],
|
||||
['i/webhooks/show', ep___i_webhooks_show],
|
||||
['i/webhooks/update', ep___i_webhooks_update],
|
||||
['i/webhooks/delete', ep___i_webhooks_delete],
|
||||
['meta', ep___meta],
|
||||
['emojis', ep___emojis],
|
||||
['emoji', ep___emoji],
|
||||
['miauth/gen-token', ep___miauth_genToken],
|
||||
['mute/create', ep___mute_create],
|
||||
['mute/delete', ep___mute_delete],
|
||||
['mute/list', ep___mute_list],
|
||||
['renote-mute/create', ep___renoteMute_create],
|
||||
['renote-mute/delete', ep___renoteMute_delete],
|
||||
['renote-mute/list', ep___renoteMute_list],
|
||||
['my/apps', ep___my_apps],
|
||||
['notes', ep___notes],
|
||||
['notes/children', ep___notes_children],
|
||||
['notes/clips', ep___notes_clips],
|
||||
['notes/conversation', ep___notes_conversation],
|
||||
['notes/create', ep___notes_create],
|
||||
['notes/delete', ep___notes_delete],
|
||||
['notes/favorites/create', ep___notes_favorites_create],
|
||||
['notes/favorites/delete', ep___notes_favorites_delete],
|
||||
['notes/featured', ep___notes_featured],
|
||||
['notes/global-timeline', ep___notes_globalTimeline],
|
||||
['notes/hybrid-timeline', ep___notes_hybridTimeline],
|
||||
['notes/local-timeline', ep___notes_localTimeline],
|
||||
['notes/mentions', ep___notes_mentions],
|
||||
['notes/polls/recommendation', ep___notes_polls_recommendation],
|
||||
['notes/polls/vote', ep___notes_polls_vote],
|
||||
['notes/reactions', ep___notes_reactions],
|
||||
['notes/reactions/create', ep___notes_reactions_create],
|
||||
['notes/reactions/delete', ep___notes_reactions_delete],
|
||||
['notes/renotes', ep___notes_renotes],
|
||||
['notes/replies', ep___notes_replies],
|
||||
['notes/search-by-tag', ep___notes_searchByTag],
|
||||
['notes/search', ep___notes_search],
|
||||
['notes/show', ep___notes_show],
|
||||
['notes/state', ep___notes_state],
|
||||
['notes/thread-muting/create', ep___notes_threadMuting_create],
|
||||
['notes/thread-muting/delete', ep___notes_threadMuting_delete],
|
||||
['notes/timeline', ep___notes_timeline],
|
||||
['notes/translate', ep___notes_translate],
|
||||
['notes/unrenote', ep___notes_unrenote],
|
||||
['notes/user-list-timeline', ep___notes_userListTimeline],
|
||||
['notifications/create', ep___notifications_create],
|
||||
['notifications/mark-all-as-read', ep___notifications_markAllAsRead],
|
||||
['page-push', ep___pagePush],
|
||||
['pages/create', ep___pages_create],
|
||||
['pages/delete', ep___pages_delete],
|
||||
['pages/featured', ep___pages_featured],
|
||||
['pages/like', ep___pages_like],
|
||||
['pages/show', ep___pages_show],
|
||||
['pages/unlike', ep___pages_unlike],
|
||||
['pages/update', ep___pages_update],
|
||||
['flash/create', ep___flash_create],
|
||||
['flash/delete', ep___flash_delete],
|
||||
['flash/featured', ep___flash_featured],
|
||||
['flash/like', ep___flash_like],
|
||||
['flash/show', ep___flash_show],
|
||||
['flash/unlike', ep___flash_unlike],
|
||||
['flash/update', ep___flash_update],
|
||||
['flash/my', ep___flash_my],
|
||||
['flash/my-likes', ep___flash_myLikes],
|
||||
['ping', ep___ping],
|
||||
['pinned-users', ep___pinnedUsers],
|
||||
['promo/read', ep___promo_read],
|
||||
['roles/list', ep___roles_list],
|
||||
['roles/show', ep___roles_show],
|
||||
['roles/users', ep___roles_users],
|
||||
['roles/notes', ep___roles_notes],
|
||||
['request-reset-password', ep___requestResetPassword],
|
||||
['reset-db', ep___resetDb],
|
||||
['reset-password', ep___resetPassword],
|
||||
['server-info', ep___serverInfo],
|
||||
['stats', ep___stats],
|
||||
['sw/show-registration', ep___sw_show_registration],
|
||||
['sw/update-registration', ep___sw_update_registration],
|
||||
['sw/register', ep___sw_register],
|
||||
['sw/unregister', ep___sw_unregister],
|
||||
['test', ep___test],
|
||||
['username/available', ep___username_available],
|
||||
['users', ep___users],
|
||||
['users/clips', ep___users_clips],
|
||||
['users/followers', ep___users_followers],
|
||||
['users/following', ep___users_following],
|
||||
['users/gallery/posts', ep___users_gallery_posts],
|
||||
['users/get-frequently-replied-users', ep___users_getFrequentlyRepliedUsers],
|
||||
['users/lists/create', ep___users_lists_create],
|
||||
['users/lists/delete', ep___users_lists_delete],
|
||||
['users/lists/list', ep___users_lists_list],
|
||||
['users/lists/pull', ep___users_lists_pull],
|
||||
['users/lists/push', ep___users_lists_push],
|
||||
['users/lists/show', ep___users_lists_show],
|
||||
['users/lists/favorite', ep___users_lists_favorite],
|
||||
['users/lists/unfavorite', ep___users_lists_unfavorite],
|
||||
['users/lists/update', ep___users_lists_update],
|
||||
['users/lists/create-from-public', ep___users_lists_create_from_public],
|
||||
['users/notes', ep___users_notes],
|
||||
['users/pages', ep___users_pages],
|
||||
['users/reactions', ep___users_reactions],
|
||||
['users/recommendation', ep___users_recommendation],
|
||||
['users/relation', ep___users_relation],
|
||||
['users/report-abuse', ep___users_reportAbuse],
|
||||
['users/search-by-username-and-host', ep___users_searchByUsernameAndHost],
|
||||
['users/search', ep___users_search],
|
||||
['users/show', ep___users_show],
|
||||
['users/achievements', ep___users_achievements],
|
||||
['users/update-memo', ep___users_updateMemo],
|
||||
['fetch-rss', ep___fetchRss],
|
||||
['retention', ep___retention],
|
||||
];
|
||||
|
||||
export interface IEndpointMeta {
|
||||
readonly stability?: 'deprecated' | 'experimental' | 'stable';
|
||||
|
||||
readonly tags?: ReadonlyArray<string>;
|
||||
|
||||
readonly errors?: {
|
||||
readonly [key: string]: {
|
||||
readonly message: string;
|
||||
readonly code: string;
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
|
||||
readonly res?: Schema;
|
||||
|
||||
/**
|
||||
* このエンドポイントにリクエストするのにユーザー情報が必須か否か
|
||||
* 省略した場合は false として解釈されます。
|
||||
*/
|
||||
readonly requireCredential?: boolean;
|
||||
|
||||
/**
|
||||
* isModeratorなロールを必要とするか
|
||||
*/
|
||||
readonly requireModerator?: boolean;
|
||||
|
||||
/**
|
||||
* isAdministratorなロールを必要とするか
|
||||
*/
|
||||
readonly requireAdmin?: boolean;
|
||||
|
||||
readonly requireRolePolicy?: keyof RolePolicies;
|
||||
|
||||
/**
|
||||
* 引っ越し済みのユーザーによるリクエストを禁止するか
|
||||
* 省略した場合は false として解釈されます。
|
||||
*/
|
||||
readonly prohibitMoved?: boolean;
|
||||
|
||||
/**
|
||||
* エンドポイントのリミテーションに関するやつ
|
||||
* 省略した場合はリミテーションは無いものとして解釈されます。
|
||||
*/
|
||||
readonly limit?: {
|
||||
|
||||
/**
|
||||
* 複数のエンドポイントでリミットを共有したい場合に指定するキー
|
||||
*/
|
||||
readonly key?: string;
|
||||
|
||||
/**
|
||||
* リミットを適用する期間(ms)
|
||||
* このプロパティを設定する場合、max プロパティも設定する必要があります。
|
||||
*/
|
||||
readonly duration?: number;
|
||||
|
||||
/**
|
||||
* durationで指定した期間内にいくつまでリクエストできるのか
|
||||
* このプロパティを設定する場合、duration プロパティも設定する必要があります。
|
||||
*/
|
||||
readonly max?: number;
|
||||
|
||||
/**
|
||||
* 最低でもどれくらいの間隔を開けてリクエストしなければならないか(ms)
|
||||
*/
|
||||
readonly minInterval?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* ファイルの添付を必要とするか否か
|
||||
* 省略した場合は false として解釈されます。
|
||||
*/
|
||||
readonly requireFile?: boolean;
|
||||
|
||||
/**
|
||||
* サードパーティアプリからはリクエストすることができないか否か
|
||||
* 省略した場合は false として解釈されます。
|
||||
*/
|
||||
readonly secure?: boolean;
|
||||
|
||||
/**
|
||||
* エンドポイントの種類
|
||||
* パーミッションの実現に利用されます。
|
||||
*/
|
||||
readonly kind?: string;
|
||||
|
||||
readonly description?: string;
|
||||
|
||||
/**
|
||||
* GETでのリクエストを許容するか否か
|
||||
*/
|
||||
readonly allowGet?: boolean;
|
||||
|
||||
/**
|
||||
* 正常応答をキャッシュ (Cache-Control: public) する秒数
|
||||
*/
|
||||
readonly cacheSec?: number;
|
||||
}
|
||||
|
||||
export interface IEndpoint {
|
||||
name: string;
|
||||
meta: IEndpointMeta;
|
||||
params: Schema;
|
||||
}
|
||||
|
||||
const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => {
|
||||
return {
|
||||
name: name,
|
||||
get meta() { return ep.meta ?? {}; },
|
||||
get params() { return ep.paramDef; },
|
||||
};
|
||||
});
|
||||
|
||||
export default endpoints;
|
|
@ -5,91 +5,10 @@ import { QueryService } from '@/core/QueryService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEntityService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
nullable: false, optional: false,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
nullable: false, optional: false,
|
||||
format: 'date-time',
|
||||
},
|
||||
comment: {
|
||||
type: 'string',
|
||||
nullable: false, optional: false,
|
||||
},
|
||||
resolved: {
|
||||
type: 'boolean',
|
||||
nullable: false, optional: false,
|
||||
example: false,
|
||||
},
|
||||
reporterId: {
|
||||
type: 'string',
|
||||
nullable: false, optional: false,
|
||||
format: 'id',
|
||||
},
|
||||
targetUserId: {
|
||||
type: 'string',
|
||||
nullable: false, optional: false,
|
||||
format: 'id',
|
||||
},
|
||||
assigneeId: {
|
||||
type: 'string',
|
||||
nullable: true, optional: false,
|
||||
format: 'id',
|
||||
},
|
||||
reporter: {
|
||||
type: 'object',
|
||||
nullable: false, optional: false,
|
||||
ref: 'User',
|
||||
},
|
||||
targetUser: {
|
||||
type: 'object',
|
||||
nullable: false, optional: false,
|
||||
ref: 'User',
|
||||
},
|
||||
assignee: {
|
||||
type: 'object',
|
||||
nullable: true, optional: true,
|
||||
ref: 'User',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
state: { type: 'string', nullable: true, default: null },
|
||||
reporterOrigin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'combined' },
|
||||
targetUserOrigin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'combined' },
|
||||
forwarded: { type: 'boolean', default: false },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/abuse-user-reports'> {
|
||||
name = 'admin/abuse-user-reports' as const;
|
||||
constructor(
|
||||
@Inject(DI.abuseUserReportsRepository)
|
||||
private abuseUserReportsRepository: AbuseUserReportsRepository,
|
||||
|
@ -97,7 +16,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private abuseUserReportEntityService: AbuseUserReportEntityService,
|
||||
private queryService: QueryService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.abuseUserReportsRepository.createQueryBuilder('report'), ps.sinceId, ps.untilId);
|
||||
|
||||
switch (ps.state) {
|
||||
|
|
|
@ -7,34 +7,10 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
|||
import { localUsernameSchema, passwordSchema } from '@/models/entities/User.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
ref: 'User',
|
||||
properties: {
|
||||
token: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
username: localUsernameSchema,
|
||||
password: passwordSchema,
|
||||
},
|
||||
required: ['username', 'password'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/accounts/create'> {
|
||||
name = 'admin/accounts/create' as const;
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
@ -42,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private userEntityService: UserEntityService,
|
||||
private signupService: SignupService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, _me) => {
|
||||
super(async (ps, _me) => {
|
||||
const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null;
|
||||
const noUsers = (await this.usersRepository.countBy({
|
||||
host: IsNull(),
|
||||
|
@ -55,14 +31,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
ignorePreservedUsernames: true,
|
||||
});
|
||||
|
||||
const res = await this.userEntityService.pack(account, account, {
|
||||
const res = await this.userEntityService.pack<true, true>(account, account, {
|
||||
detail: true,
|
||||
includeSecrets: true,
|
||||
});
|
||||
|
||||
(res as any).token = secret;
|
||||
|
||||
return res;
|
||||
return { ...res, token: secret };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,24 +7,10 @@ import { UserSuspendService } from '@/core/UserSuspendService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireAdmin: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/accounts/delete'> {
|
||||
name = 'admin/accounts/delete' as const;
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
@ -34,7 +20,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private globalEventService: GlobalEventService,
|
||||
private userSuspendService: UserSuspendService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||
|
||||
if (user == null) {
|
||||
|
|
|
@ -4,38 +4,17 @@ import type { AdsRepository } from '@/models/index.js';
|
|||
import { IdService } from '@/core/IdService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', minLength: 1 },
|
||||
memo: { type: 'string' },
|
||||
place: { type: 'string' },
|
||||
priority: { type: 'string' },
|
||||
ratio: { type: 'integer' },
|
||||
expiresAt: { type: 'integer' },
|
||||
startsAt: { type: 'integer' },
|
||||
imageUrl: { type: 'string', minLength: 1 },
|
||||
},
|
||||
required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/ad/create'> {
|
||||
name = 'admin/ad/create' as const;
|
||||
constructor(
|
||||
@Inject(DI.adsRepository)
|
||||
private adsRepository: AdsRepository,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.adsRepository.insert({
|
||||
id: this.idService.genId(),
|
||||
createdAt: new Date(),
|
||||
|
|
|
@ -4,40 +4,18 @@ import type { AdsRepository } from '@/models/index.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAd: {
|
||||
message: 'No such ad.',
|
||||
code: 'NO_SUCH_AD',
|
||||
id: 'ccac9863-3a03-416e-b899-8a64041118b1',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/ad/delete'> {
|
||||
name = 'admin/ad/delete' as const;
|
||||
constructor(
|
||||
@Inject(DI.adsRepository)
|
||||
private adsRepository: AdsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const ad = await this.adsRepository.findOneBy({ id: ps.id });
|
||||
|
||||
if (ad == null) throw new ApiError(meta.errors.noSuchAd);
|
||||
if (ad == null) throw new ApiError(this.meta.errors.noSuchAd);
|
||||
|
||||
await this.adsRepository.delete(ad.id);
|
||||
});
|
||||
|
|
|
@ -23,14 +23,15 @@ export const paramDef = {
|
|||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/ad/list'> {
|
||||
name = 'admin/ad/list' as const;
|
||||
constructor(
|
||||
@Inject(DI.adsRepository)
|
||||
private adsRepository: AdsRepository,
|
||||
|
||||
private queryService: QueryService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId);
|
||||
const ads = await query.take(ps.limit).getMany();
|
||||
|
||||
|
|
|
@ -4,48 +4,18 @@ import type { AdsRepository } from '@/models/index.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAd: {
|
||||
message: 'No such ad.',
|
||||
code: 'NO_SUCH_AD',
|
||||
id: 'b7aa1727-1354-47bc-a182-3a9c3973d300',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'misskey:id' },
|
||||
memo: { type: 'string' },
|
||||
url: { type: 'string', minLength: 1 },
|
||||
imageUrl: { type: 'string', minLength: 1 },
|
||||
place: { type: 'string' },
|
||||
priority: { type: 'string' },
|
||||
ratio: { type: 'integer' },
|
||||
expiresAt: { type: 'integer' },
|
||||
startsAt: { type: 'integer' },
|
||||
},
|
||||
required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/ad/update'> {
|
||||
name = 'admin/ad/update' as const;
|
||||
constructor(
|
||||
@Inject(DI.adsRepository)
|
||||
private adsRepository: AdsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const ad = await this.adsRepository.findOneBy({ id: ps.id });
|
||||
|
||||
if (ad == null) throw new ApiError(meta.errors.noSuchAd);
|
||||
if (ad == null) throw new ApiError(this.meta.errors.noSuchAd);
|
||||
|
||||
await this.adsRepository.update(ad.id, {
|
||||
url: ps.url,
|
||||
|
|
|
@ -4,68 +4,17 @@ import type { AnnouncementsRepository } from '@/models/index.js';
|
|||
import { IdService } from '@/core/IdService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'date-time',
|
||||
},
|
||||
updatedAt: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
imageUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: { type: 'string', minLength: 1 },
|
||||
text: { type: 'string', minLength: 1 },
|
||||
imageUrl: { type: 'string', nullable: true, minLength: 1 },
|
||||
},
|
||||
required: ['title', 'text', 'imageUrl'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/announcements/create'> {
|
||||
name = 'admin/announcements/create' as const;
|
||||
constructor(
|
||||
@Inject(DI.announcementsRepository)
|
||||
private announcementsRepository: AnnouncementsRepository,
|
||||
|
||||
private idService: IdService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const announcement = await this.announcementsRepository.insert({
|
||||
id: this.idService.genId(),
|
||||
createdAt: new Date(),
|
||||
|
|
|
@ -4,40 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAnnouncement: {
|
||||
message: 'No such announcement.',
|
||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
||||
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/announcements/delete'> {
|
||||
name = 'admin/announcements/delete' as const;
|
||||
constructor(
|
||||
@Inject(DI.announcementsRepository)
|
||||
private announcementsRepository: AnnouncementsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const announcement = await this.announcementsRepository.findOneBy({ id: ps.id });
|
||||
|
||||
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
|
||||
if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement);
|
||||
|
||||
await this.announcementsRepository.delete(announcement.id);
|
||||
});
|
||||
|
|
|
@ -5,69 +5,10 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
|||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'date-time',
|
||||
},
|
||||
updatedAt: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
imageUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
reads: {
|
||||
type: 'number',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/announcements/list'> {
|
||||
name = 'admin/announcements/list' as const;
|
||||
constructor(
|
||||
@Inject(DI.announcementsRepository)
|
||||
private announcementsRepository: AnnouncementsRepository,
|
||||
|
@ -77,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
|
||||
private queryService: QueryService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
|
||||
|
||||
const announcements = await query.take(ps.limit).getMany();
|
||||
|
|
|
@ -4,43 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchAnnouncement: {
|
||||
message: 'No such announcement.',
|
||||
code: 'NO_SUCH_ANNOUNCEMENT',
|
||||
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'misskey:id' },
|
||||
title: { type: 'string', minLength: 1 },
|
||||
text: { type: 'string', minLength: 1 },
|
||||
imageUrl: { type: 'string', nullable: true, minLength: 0 },
|
||||
},
|
||||
required: ['id', 'title', 'text', 'imageUrl'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/announcements/update'> {
|
||||
name = 'admin/announcements/update' as const;
|
||||
constructor(
|
||||
@Inject(DI.announcementsRepository)
|
||||
private announcementsRepository: AnnouncementsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const announcement = await this.announcementsRepository.findOneBy({ id: ps.id });
|
||||
|
||||
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
|
||||
if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement);
|
||||
|
||||
await this.announcementsRepository.update(announcement.id, {
|
||||
updatedAt: new Date(),
|
||||
|
|
|
@ -4,34 +4,17 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
|||
import { DeleteAccountService } from '@/core/DeleteAccountService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireAdmin: true,
|
||||
|
||||
res: {
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/delete-account'> {
|
||||
name = 'admin/delete-account' as const;
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
private deleteAccountService: DeleteAccountService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps) => {
|
||||
super(async (ps) => {
|
||||
const user = await this.usersRepository.findOneByOrFail({ id: ps.userId });
|
||||
if (user.isDeleted) {
|
||||
return;
|
||||
|
|
|
@ -4,31 +4,17 @@ import type { DriveFilesRepository } from '@/models/index.js';
|
|||
import { DriveService } from '@/core/DriveService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireAdmin: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['userId'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/delete-all-files-of-a-user'> {
|
||||
name = 'admin/delete-all-files-of-a-user' as const;
|
||||
constructor(
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
||||
private driveService: DriveService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const files = await this.driveFilesRepository.findBy({
|
||||
userId: ps.userId,
|
||||
});
|
||||
|
|
|
@ -2,26 +2,14 @@ import { Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { QueueService } from '@/core/QueueService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/drive/clean-remote-files'> {
|
||||
name = 'admin/drive/clean-remote-files' as const;
|
||||
constructor(
|
||||
private queueService: QueueService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
this.queueService.createCleanRemoteFilesJob();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,29 +5,17 @@ import type { DriveFilesRepository } from '@/models/index.js';
|
|||
import { DriveService } from '@/core/DriveService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/drive/cleanup'> {
|
||||
name = 'admin/drive/cleanup' as const;
|
||||
constructor(
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
||||
private driveService: DriveService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const files = await this.driveFilesRepository.findBy({
|
||||
userId: IsNull(),
|
||||
});
|
||||
|
|
|
@ -5,45 +5,10 @@ import { QueryService } from '@/core/QueryService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
ref: 'DriveFile',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
userId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) },
|
||||
origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'local' },
|
||||
hostname: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
default: null,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/drive/files'> {
|
||||
name = 'admin/drive/files' as const;
|
||||
constructor(
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
@ -51,7 +16,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private driveFileEntityService: DriveFileEntityService,
|
||||
private queryService: QueryService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId);
|
||||
|
||||
if (ps.userId) {
|
||||
|
|
|
@ -5,152 +5,10 @@ import { DI } from '@/di-symbols.js';
|
|||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240',
|
||||
},
|
||||
},
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'date-time',
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
userHost: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
md5: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'md5',
|
||||
example: '15eca7fba0480996e2245f5185bf39f2',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
example: 'lenna.jpg',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
example: 'image/jpeg',
|
||||
},
|
||||
size: {
|
||||
type: 'number',
|
||||
optional: false, nullable: false,
|
||||
example: 51469,
|
||||
},
|
||||
comment: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
blurhash: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
properties: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
storedInternal: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: true,
|
||||
example: true,
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'url',
|
||||
},
|
||||
thumbnailUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'url',
|
||||
},
|
||||
webpublicUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'url',
|
||||
},
|
||||
accessKey: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
thumbnailAccessKey: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
webpublicAccessKey: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
uri: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
src: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
folderId: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
format: 'id',
|
||||
example: 'xxxxxxxxxx',
|
||||
},
|
||||
isSensitive: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
isLink: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
url: { type: 'string' },
|
||||
},
|
||||
anyOf: [
|
||||
{ required: ['fileId'] },
|
||||
{ required: ['url'] },
|
||||
],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/drive/show-file'> {
|
||||
name = 'admin/drive/show-file' as const;
|
||||
constructor(
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
@ -160,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const file = ps.fileId ? await this.driveFilesRepository.findOneBy({ id: ps.fileId }) : await this.driveFilesRepository.findOne({
|
||||
where: [{
|
||||
url: ps.url,
|
||||
|
@ -172,7 +30,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
});
|
||||
|
||||
if (file == null) {
|
||||
throw new ApiError(meta.errors.noSuchFile);
|
||||
throw new ApiError(this.meta.errors.noSuchFile);
|
||||
}
|
||||
|
||||
const owner = file.userId ? await this.usersRepository.findOneByOrFail({
|
||||
|
|
|
@ -2,33 +2,14 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ids: { type: 'array', items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
aliases: { type: 'array', items: {
|
||||
type: 'string',
|
||||
} },
|
||||
},
|
||||
required: ['ids', 'aliases'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/add-aliases-bulk'> {
|
||||
name = 'admin/emoji/add-aliases-bulk' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.addAliasesBulk(ps.ids, ps.aliases);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,49 +6,12 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
|||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: 'No such file.',
|
||||
code: 'NO_SUCH_FILE',
|
||||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
|
||||
fileId: { type: 'string', format: 'misskey:id' },
|
||||
category: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'Use `null` to reset the category.',
|
||||
},
|
||||
aliases: { type: 'array', items: {
|
||||
type: 'string',
|
||||
} },
|
||||
license: { type: 'string', nullable: true },
|
||||
isSensitive: { type: 'boolean' },
|
||||
localOnly: { type: 'boolean' },
|
||||
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
|
||||
type: 'string',
|
||||
} },
|
||||
},
|
||||
required: ['name', 'fileId'],
|
||||
} as const;
|
||||
|
||||
// TODO: ロジックをサービスに切り出す
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/add'> {
|
||||
name = 'admin/emoji/add' as const;
|
||||
constructor(
|
||||
@Inject(DI.driveFilesRepository)
|
||||
private driveFilesRepository: DriveFilesRepository,
|
||||
|
@ -57,9 +20,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
|
||||
private moderationLogService: ModerationLogService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
||||
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
if (driveFile == null) throw new ApiError(this.meta.errors.noSuchFile);
|
||||
|
||||
const emoji = await this.customEmojiService.add({
|
||||
driveFile,
|
||||
|
|
|
@ -10,46 +10,12 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
|
|||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
|
||||
errors: {
|
||||
noSuchEmoji: {
|
||||
message: 'No such emoji.',
|
||||
code: 'NO_SUCH_EMOJI',
|
||||
id: 'e2785b66-dca3-4087-9cac-b93c541cc425',
|
||||
},
|
||||
},
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
emojiId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['emojiId'],
|
||||
} as const;
|
||||
|
||||
// TODO: ロジックをサービスに切り出す
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/copy'> {
|
||||
name = 'admin/emoji/copy' as const;
|
||||
constructor(
|
||||
@Inject(DI.db)
|
||||
private db: DataSource,
|
||||
|
@ -62,11 +28,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private globalEventService: GlobalEventService,
|
||||
private driveService: DriveService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const emoji = await this.emojisRepository.findOneBy({ id: ps.emojiId });
|
||||
|
||||
if (emoji == null) {
|
||||
throw new ApiError(meta.errors.noSuchEmoji);
|
||||
throw new ApiError(this.meta.errors.noSuchEmoji);
|
||||
}
|
||||
|
||||
let driveFile: DriveFile;
|
||||
|
|
|
@ -3,29 +3,19 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
|||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ids: { type: 'array', items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
},
|
||||
required: ['ids'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/delete-bulk'> {
|
||||
name = 'admin/emoji/delete-bulk' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.deleteBulk(ps.ids);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,36 +2,14 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
|
||||
errors: {
|
||||
noSuchEmoji: {
|
||||
message: 'No such emoji.',
|
||||
code: 'NO_SUCH_EMOJI',
|
||||
id: 'be83669b-773a-44b7-b1f8-e5e5170ac3c2',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['id'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/delete'> {
|
||||
name = 'admin/emoji/delete' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.delete(ps.id);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,11 +18,12 @@ export const paramDef = {
|
|||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/import-zip'> {
|
||||
name = 'admin/emoji/import-zip' as const;
|
||||
constructor(
|
||||
private queueService: QueueService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
this.queueService.createImportCustomEmojisJob(me, ps.fileId);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,74 +7,10 @@ import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
},
|
||||
aliases: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
category: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
host: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
description: 'The local host is represented with `null`.',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
query: { type: 'string', nullable: true, default: null },
|
||||
host: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
default: null,
|
||||
description: 'Use `null` to represent the local host.',
|
||||
},
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/list-remote'> {
|
||||
name = 'admin/emoji/list-remote' as const;
|
||||
constructor(
|
||||
@Inject(DI.emojisRepository)
|
||||
private emojisRepository: EmojisRepository,
|
||||
|
@ -83,7 +19,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private queryService: QueryService,
|
||||
private emojiEntityService: EmojiEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId);
|
||||
|
||||
if (ps.host == null) {
|
||||
|
|
|
@ -7,68 +7,10 @@ import { DI } from '@/di-symbols.js';
|
|||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
|
||||
//import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
|
||||
res: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
},
|
||||
aliases: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
items: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
category: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
host: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
description: 'The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
query: { type: 'string', nullable: true, default: null },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/list'> {
|
||||
name = 'admin/emoji/list' as const;
|
||||
constructor(
|
||||
@Inject(DI.emojisRepository)
|
||||
private emojisRepository: EmojisRepository,
|
||||
|
@ -76,7 +18,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private emojiEntityService: EmojiEntityService,
|
||||
private queryService: QueryService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId)
|
||||
.andWhere('emoji.host IS NULL');
|
||||
|
||||
|
|
|
@ -24,11 +24,12 @@ export const paramDef = {
|
|||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/remove-aliases-bulk'> {
|
||||
name = 'admin/emoji/remove-aliases-bulk' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.removeAliasesBulk(ps.ids, ps.aliases);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,33 +2,14 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ids: { type: 'array', items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
aliases: { type: 'array', items: {
|
||||
type: 'string',
|
||||
} },
|
||||
},
|
||||
required: ['ids', 'aliases'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/set-aliases-bulk'> {
|
||||
name = 'admin/emoji/set-aliases-bulk' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.setAliasesBulk(ps.ids, ps.aliases);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,35 +2,14 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ids: { type: 'array', items: {
|
||||
type: 'string', format: 'misskey:id',
|
||||
} },
|
||||
category: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description: 'Use `null` to reset the category.',
|
||||
},
|
||||
},
|
||||
required: ['ids'],
|
||||
} as const;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
export default class extends Endpoint<'admin/emoji/set-category-bulk'> {
|
||||
name = 'admin/emoji/set-category-bulk' as const;
|
||||
constructor(
|
||||
private customEmojiService: CustomEmojiService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(async (ps, me) => {
|
||||
await this.customEmojiService.setCategoryBulk(ps.ids, ps.category ?? null);
|
||||
});
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue