diff --git a/packages/backend/src/core/WebhookTestService.ts b/packages/backend/src/core/WebhookTestService.ts index 0b1e8110e5..74a8b79a89 100644 --- a/packages/backend/src/core/WebhookTestService.ts +++ b/packages/backend/src/core/WebhookTestService.ts @@ -443,6 +443,8 @@ export class WebhookTestService { return { ...user, createdAt: this.idService.parse(user.id).date.toISOString(), + updatedAt: null, + lastFetchedAt: null, id: user.id, name: user.name, username: user.username, diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 638eaac16f..227814454d 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -546,6 +546,8 @@ export class UserEntityService implements OnModuleInit { avatarBlurhash: (user.avatarId == null ? null : user.avatarBlurhash), description: mastoapi ? mastoapi.description : profile ? profile.description : '', createdAt: this.idService.parse(user.id).date.toISOString(), + updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, + lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null, avatarDecorations: user.avatarDecorations.length > 0 ? this.avatarDecorationService.getAll().then(decorations => user.avatarDecorations.filter(ud => decorations.some(d => d.id === ud.id)).map(ud => ({ id: ud.id, angle: ud.angle || undefined, @@ -601,8 +603,6 @@ export class UserEntityService implements OnModuleInit { ? Promise.all(user.alsoKnownAs.map(uri => Promise.resolve(opts.userIdsByUri?.get(uri) ?? this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))) .then(xs => xs.length === 0 ? null : xs.filter(x => x != null)) : null, - updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, - lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null, bannerUrl: user.bannerId == null ? null : user.bannerUrl, bannerBlurhash: user.bannerId == null ? null : user.bannerBlurhash, backgroundUrl: user.backgroundId == null ? null : user.backgroundUrl, diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 23c8086fa6..4a2d5780d1 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -69,6 +69,16 @@ export const packedUserLiteSchema = { nullable: false, optional: false, format: 'date-time', }, + updatedAt: { + type: 'string', + nullable: true, optional: false, + format: 'date-time', + }, + lastFetchedAt: { + type: 'string', + nullable: true, optional: false, + format: 'date-time', + }, approved: { type: 'boolean', nullable: false, optional: false, @@ -304,16 +314,6 @@ export const packedUserDetailedNotMeOnlySchema = { nullable: false, optional: false, }, }, - updatedAt: { - type: 'string', - nullable: true, optional: false, - format: 'date-time', - }, - lastFetchedAt: { - type: 'string', - nullable: true, optional: false, - format: 'date-time', - }, bannerUrl: { type: 'string', format: 'url', diff --git a/packages/backend/src/server/api/endpoints/admin/roles/users.ts b/packages/backend/src/server/api/endpoints/admin/roles/users.ts index 198166bec2..0a62845087 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/users.ts @@ -35,7 +35,7 @@ export const meta = { properties: { id: { type: 'string', format: 'misskey:id' }, createdAt: { type: 'string', format: 'date-time' }, - user: { ref: 'UserDetailed' }, + user: { ref: 'User' }, expiresAt: { type: 'string', format: 'date-time', nullable: true }, }, required: ['id', 'createdAt', 'user'], @@ -50,6 +50,11 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: ['roleId'], } as const; @@ -90,12 +95,12 @@ export default class extends Endpoint { // eslint- .getMany(); const _users = assigns.map(({ user, userId }) => user ?? userId); - const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' }) + const _userMap = await this.userEntityService.packMany(_users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }) .then(users => new Map(users.map(u => [u.id, u]))); return await Promise.all(assigns.map(async assign => ({ id: assign.id, createdAt: this.idService.parse(assign.id).date.toISOString(), - user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }), + user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }), expiresAt: assign.expiresAt?.toISOString() ?? null, }))); }); diff --git a/packages/backend/src/server/api/endpoints/admin/show-users.ts b/packages/backend/src/server/api/endpoints/admin/show-users.ts index cc65ed2cf0..02117d4b6b 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-users.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-users.ts @@ -24,7 +24,7 @@ export const meta = { items: { type: 'object', nullable: false, optional: false, - ref: 'UserDetailed', + ref: 'User', }, }, } as const; @@ -44,6 +44,11 @@ export const paramDef = { default: null, description: 'The local host is represented with `null`.', }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: [], } as const; @@ -115,7 +120,7 @@ export default class extends Endpoint { // eslint- const users = await query.getMany(); - return await this.userEntityService.packMany(users, me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }); }); } } diff --git a/packages/backend/src/server/api/endpoints/hashtags/users.ts b/packages/backend/src/server/api/endpoints/hashtags/users.ts index 68c795de73..c43e750cf3 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/users.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/users.ts @@ -23,7 +23,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'User', }, }, @@ -43,6 +43,11 @@ export const paramDef = { state: { type: 'string', enum: ['all', 'alive'], default: 'all' }, origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'local' }, trending: { type: 'boolean', default: false }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: ['tag', 'sort'], } as const; @@ -96,7 +101,7 @@ export default class extends Endpoint { // eslint- .map(([u]) => u); } - return await this.userEntityService.packMany(users, me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }); }); } } diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts index 2e89d81404..ab13ca3497 100644 --- a/packages/backend/src/server/api/endpoints/pinned-users.ts +++ b/packages/backend/src/server/api/endpoints/pinned-users.ts @@ -23,7 +23,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'User', }, }, @@ -36,7 +36,13 @@ export const meta = { export const paramDef = { type: 'object', - properties: {}, + properties: { + detail: { + type: 'boolean', + nullable: false, + default: true, + }, + }, required: [], } as const; @@ -57,7 +63,7 @@ export default class extends Endpoint { // eslint- host: acct.host ?? IsNull(), }))); - return await this.userEntityService.packMany(users.filter(x => x != null), me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users.filter(x => x != null), me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }); }); } } diff --git a/packages/backend/src/server/api/endpoints/roles/users.ts b/packages/backend/src/server/api/endpoints/roles/users.ts index 774a6f889b..a9adac8b1c 100644 --- a/packages/backend/src/server/api/endpoints/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/roles/users.ts @@ -37,7 +37,7 @@ export const meta = { }, user: { type: 'object', - ref: 'UserDetailed', + ref: 'User', }, }, required: ['id', 'user'], @@ -58,6 +58,11 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: ['roleId'], } as const; @@ -99,11 +104,11 @@ export default class extends Endpoint { // eslint- .getMany(); const _users = assigns.map(({ user, userId }) => user ?? userId); - const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' }) + const _userMap = await this.userEntityService.packMany(_users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }) .then(users => new Map(users.map(u => [u.id, u]))); return await Promise.all(assigns.map(async assign => ({ id: assign.id, - user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }), + user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }), }))); }); } diff --git a/packages/backend/src/server/api/endpoints/users.ts b/packages/backend/src/server/api/endpoints/users.ts index defd38fe96..48942db002 100644 --- a/packages/backend/src/server/api/endpoints/users.ts +++ b/packages/backend/src/server/api/endpoints/users.ts @@ -24,7 +24,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'User', }, }, @@ -50,6 +50,11 @@ export const paramDef = { default: null, description: 'The local host is represented with `null`.', }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: [], } as const; @@ -111,7 +116,7 @@ export default class extends Endpoint { // eslint- .filter(([,p]) => p.canTrend) .map(([u]) => u); - return await this.userEntityService.packMany(users, me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }); }); } diff --git a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts index 99568cfa12..bb27bf32c5 100644 --- a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts +++ b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts @@ -30,7 +30,7 @@ export const meta = { user: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'User', }, weight: { type: 'number', @@ -60,6 +60,11 @@ export const paramDef = { properties: { userId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: ['userId'], } as const; @@ -127,10 +132,10 @@ export default class extends Endpoint { // eslint- const topRepliedUserIds = repliedUsersSorted.slice(0, ps.limit); // Make replies object (includes weights) - const _userMap = await this.userEntityService.packMany(topRepliedUserIds, me, { schema: 'UserDetailed' }) + const _userMap = await this.userEntityService.packMany(topRepliedUserIds, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }) .then(users => new Map(users.map(u => [u.id, u]))); const repliesObj = await Promise.all(topRepliedUserIds.map(async (userId) => ({ - user: _userMap.get(userId) ?? await this.userEntityService.pack(userId, me, { schema: 'UserDetailed' }), + user: _userMap.get(userId) ?? await this.userEntityService.pack(userId, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }), weight: repliedUsers[userId] / peak, }))); diff --git a/packages/backend/src/server/api/endpoints/users/recommendation.ts b/packages/backend/src/server/api/endpoints/users/recommendation.ts index 52dd2197b2..2585efdc11 100644 --- a/packages/backend/src/server/api/endpoints/users/recommendation.ts +++ b/packages/backend/src/server/api/endpoints/users/recommendation.ts @@ -26,7 +26,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'UserDetailed', + ref: 'User', }, }, @@ -42,6 +42,11 @@ export const paramDef = { properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, offset: { type: 'integer', default: 0 }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, required: [], } as const; @@ -83,7 +88,7 @@ export default class extends Endpoint { // eslint- const users = await query.limit(ps.limit).offset(ps.offset).getMany(); - return await this.userEntityService.packMany(users, me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }); }); } } diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 84eb661742..30b4719e09 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -30,13 +30,13 @@ export const meta = { oneOf: [ { type: 'object', - ref: 'UserDetailed', + ref: 'User', }, { type: 'array', items: { type: 'object', - ref: 'UserDetailed', + ref: 'User', }, }, ], @@ -79,6 +79,11 @@ export const paramDef = { nullable: true, description: 'The local host is represented with `null`.', }, + detail: { + type: 'boolean', + nullable: false, + default: true, + }, }, anyOf: [ { required: ['userId'] }, @@ -125,7 +130,7 @@ export default class extends Endpoint { // eslint- if (user != null) _users.push(user); } - const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' }) + const _userMap = await this.userEntityService.packMany(_users, me, { schema: ps.detail ? 'UserDetailed' : 'UserLite' }) .then(users => new Map(users.map(u => [u.id, u]))); return _users.map(u => _userMap.get(u.id)!); } else { @@ -156,7 +161,7 @@ export default class extends Endpoint { // eslint- } return await this.userEntityService.pack(user, me, { - schema: 'UserDetailed', + schema: ps.detail ? 'UserDetailed' : 'UserLite', }); } }); diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 94accf852e..a553353d2a 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -2067,6 +2067,7 @@ declare namespace entities { PagesUnlikeRequest, PagesUpdateRequest, PingResponse, + PinnedUsersRequest, PinnedUsersResponse, PromoReadRequest, RenoteMuteCreateRequest, @@ -3411,6 +3412,9 @@ export const permissions: readonly ["read:account", "write:account", "read:block // @public (undocumented) type PingResponse = operations['ping']['responses']['200']['content']['application/json']; +// @public (undocumented) +type PinnedUsersRequest = operations['pinned-users']['requestBody']['content']['application/json']; + // @public (undocumented) type PinnedUsersResponse = operations['pinned-users']['responses']['200']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index 5a40b74b8f..f08323d783 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -563,6 +563,7 @@ import type { PagesUnlikeRequest, PagesUpdateRequest, PingResponse, + PinnedUsersRequest, PinnedUsersResponse, PromoReadRequest, RenoteMuteCreateRequest, @@ -1044,7 +1045,7 @@ export type Endpoints = { 'pages/unlike': { req: PagesUnlikeRequest; res: EmptyResponse }; 'pages/update': { req: PagesUpdateRequest; res: EmptyResponse }; 'ping': { req: EmptyRequest; res: PingResponse }; - 'pinned-users': { req: EmptyRequest; res: PinnedUsersResponse }; + 'pinned-users': { req: PinnedUsersRequest; res: PinnedUsersResponse }; 'promo/read': { req: PromoReadRequest; res: EmptyResponse }; 'renote-mute/create': { req: RenoteMuteCreateRequest; res: EmptyResponse }; 'renote-mute/delete': { req: RenoteMuteDeleteRequest; res: EmptyResponse }; diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index 12f9b4c5ca..cf40793792 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -566,6 +566,7 @@ export type PagesShowResponse = operations['pages___show']['responses']['200'][' export type PagesUnlikeRequest = operations['pages___unlike']['requestBody']['content']['application/json']; export type PagesUpdateRequest = operations['pages___update']['requestBody']['content']['application/json']; export type PingResponse = operations['ping']['responses']['200']['content']['application/json']; +export type PinnedUsersRequest = operations['pinned-users']['requestBody']['content']['application/json']; export type PinnedUsersResponse = operations['pinned-users']['responses']['200']['content']['application/json']; export type PromoReadRequest = operations['promo___read']['requestBody']['content']['application/json']; export type RenoteMuteCreateRequest = operations['renote-mute___create']['requestBody']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 9d66000b47..c2a886a18c 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4254,6 +4254,10 @@ export type components = { host: string | null; /** Format: date-time */ createdAt: string; + /** Format: date-time */ + updatedAt: string | null; + /** Format: date-time */ + lastFetchedAt: string | null; approved: boolean; /** @example Hi masters, I am Ai! */ description: string | null; @@ -4320,10 +4324,6 @@ export type components = { /** Format: uri */ movedTo: string | null; alsoKnownAs: string[] | null; - /** Format: date-time */ - updatedAt: string | null; - /** Format: date-time */ - lastFetchedAt: string | null; /** Format: url */ bannerUrl: string | null; bannerBlurhash: string | null; @@ -10902,6 +10902,8 @@ export type operations = { untilId?: string; /** @default 10 */ limit?: number; + /** @default true */ + detail?: boolean; }; }; }; @@ -10914,7 +10916,7 @@ export type operations = { id: string; /** Format: date-time */ createdAt: string; - user: components['schemas']['UserDetailed']; + user: components['schemas']['User']; /** Format: date-time */ expiresAt: string | null; })[]; @@ -11410,6 +11412,8 @@ export type operations = { * @default null */ hostname?: string | null; + /** @default true */ + detail?: boolean; }; }; }; @@ -11417,7 +11421,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'][]; }; }; /** @description Client error */ @@ -21857,6 +21861,8 @@ export type operations = { origin?: 'combined' | 'local' | 'remote'; /** @default false */ trending?: boolean; + /** @default true */ + detail?: boolean; }; }; }; @@ -21864,7 +21870,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'][]; }; }; /** @description Client error */ @@ -29834,11 +29840,19 @@ export type operations = { * **Credential required**: *No* */ 'pinned-users': { + requestBody: { + content: { + 'application/json': { + /** @default true */ + detail?: boolean; + }; + }; + }; responses: { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'][]; }; }; /** @description Client error */ @@ -30966,6 +30980,8 @@ export type operations = { untilId?: string; /** @default 10 */ limit?: number; + /** @default true */ + detail?: boolean; }; }; }; @@ -30976,7 +30992,7 @@ export type operations = { 'application/json': { /** Format: misskey:id */ id: string; - user: components['schemas']['UserDetailed']; + user: components['schemas']['User']; }[]; }; }; @@ -31639,6 +31655,8 @@ export type operations = { * @default null */ hostname?: string | null; + /** @default true */ + detail?: boolean; }; }; }; @@ -31646,7 +31664,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'][]; }; }; /** @description Client error */ @@ -32162,6 +32180,8 @@ export type operations = { userId: string; /** @default 10 */ limit?: number; + /** @default true */ + detail?: boolean; }; }; }; @@ -32170,7 +32190,7 @@ export type operations = { 200: { content: { 'application/json': { - user: components['schemas']['UserDetailed']; + user: components['schemas']['User']; weight: number; }[]; }; @@ -33183,6 +33203,8 @@ export type operations = { limit?: number; /** @default 0 */ offset?: number; + /** @default true */ + detail?: boolean; }; }; }; @@ -33190,7 +33212,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'][]; }; }; /** @description Client error */ @@ -33525,6 +33547,8 @@ export type operations = { username?: string; /** @description The local host is represented with `null`. */ host?: string | null; + /** @default true */ + detail?: boolean; }; }; }; @@ -33532,7 +33556,7 @@ export type operations = { /** @description OK (with results) */ 200: { content: { - 'application/json': components['schemas']['UserDetailed'] | components['schemas']['UserDetailed'][]; + 'application/json': components['schemas']['User'] | components['schemas']['User'][]; }; }; /** @description Client error */