diff --git a/packages/backend/src/core/entities/RoleEntityService.ts b/packages/backend/src/core/entities/RoleEntityService.ts index 54818782d..fde9f7d08 100644 --- a/packages/backend/src/core/entities/RoleEntityService.ts +++ b/packages/backend/src/core/entities/RoleEntityService.ts @@ -8,6 +8,8 @@ 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 { Packed } from 'misskey-js'; +import { Serialized } from 'schema-type'; @Injectable() export class RoleEntityService { @@ -26,7 +28,7 @@ export class RoleEntityService { public async pack( src: Role['id'] | Role, me?: { id: User['id'] } | null | undefined, - ) { + ): Promise>> { const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src }); const assignedCount = await this.roleAssignmentsRepository.createQueryBuilder('assign') @@ -37,7 +39,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 +74,7 @@ export class RoleEntityService { public packMany( roles: any[], me: { id: User['id'] }, - ) { + ): Promise>[]> { return Promise.all(roles.map(x => this.pack(x, me))); } } - diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts index 4f8a2fa6e..1224d8499 100644 --- a/packages/misskey-js/src/entities.ts +++ b/packages/misskey-js/src/entities.ts @@ -39,6 +39,10 @@ export type Channel = Packed<'Channel'>; export type Following = Packed<'Following'>; export type Blocking = Packed<'Blocking'>; export type Relay = Packed<'Relay'>; +export type Role = Packed<'Role'>; +export type RoleAssign = Packed<'RoleAssign'>; +export type RolePolicy = Packed<'RolePolicy'>; +export type RoleCondFormula = Packed<'RoleCondFormula'>; export type LiteInstanceMetadata = { maintainerName: string | null; diff --git a/packages/misskey-js/src/schemas.ts b/packages/misskey-js/src/schemas.ts index 5891b91ae..f284ce59f 100644 --- a/packages/misskey-js/src/schemas.ts +++ b/packages/misskey-js/src/schemas.ts @@ -36,7 +36,12 @@ import { packedFlashSchema } from './schemas/flash.js'; import { packedAdSchema } from './schemas/ad.js'; import { packedAnnouncementSchema } from './schemas/announcement.js'; import { packedRelaySchema } from './schemas/relay.js'; -import { packedRoleAssignSchema } from './schemas/role.js'; +import { + packedRoleSchema, + packedRoleAssignSchema, + packedRolePolicySchema, + packedRoleCondFormulaSchema, +} from './schemas/role.js'; import { Error, ApiError } from './schemas/error.js'; import type { JSONSchema7, JSONSchema7Definition, GetDef, GetRefs, GetKeys, UnionToArray } from 'schema-type'; @@ -78,8 +83,10 @@ export const refs = { Ad: packedAdSchema, Announcement: packedAnnouncementSchema, Relay: packedRelaySchema, - + Role: packedRoleSchema, RoleAssign: packedRoleAssignSchema, + RolePolicy: packedRolePolicySchema, + RoleCondFormula: packedRoleCondFormulaSchema, Error: Error, ApiError: ApiError, diff --git a/packages/misskey-js/src/schemas/role.ts b/packages/misskey-js/src/schemas/role.ts index f9a6279fd..9e64cf3bf 100644 --- a/packages/misskey-js/src/schemas/role.ts +++ b/packages/misskey-js/src/schemas/role.ts @@ -14,31 +14,81 @@ export const packedRoleSchema = { type: 'string', format: 'date-time', }, - name: { - type: 'string', - }, - description: { - type: 'string', - }, - color: { - type: ['string', 'null'], - }, - iconUrl: { - type: ['string', 'null'], - }, - target: { - enum: [ - 'manual', - 'conditional', - ], - } + name: { + type: 'string', + }, + description: { + type: 'string', + }, + color: { + type: ['string', 'null'], + }, + iconUrl: { + type: ['string', 'null'], + }, + target: { + enum: [ + 'manual', + 'conditional', + ], + }, + condFormula: { + type: 'object', + // 循環参照なので難しい + //$ref: 'https://misskey-hub.net/api/schemas/RoleCondFormula', + }, + isPublic: { + type: 'boolean', + }, + isAdministrator: { + type: 'boolean', + }, + isModerator: { + type: 'boolean', + }, + isExplorable: { + type: 'boolean', + }, + asBadge: { + type: 'boolean', + }, + canEditMembersByModerator: { + type: 'boolean', + }, + displayOrder: { + type: 'number', + }, + policies: { + type: 'object', + additionalProperties: { + $ref: 'https://misskey-hub.net/api/schemas/RolePolicy', + }, + }, + usersCount: { + type: 'number', + }, }, required: [ 'id', 'createdAt', - 'updatedAt', + 'updatedAt', + 'name', + 'description', + 'color', + 'iconUrl', + 'target', + 'condFormula', + 'isPublic', + 'isAdministrator', + 'isModerator', + 'isExplorable', + 'asBadge', + 'canEditMembersByModerator', + 'displayOrder', + 'policies', + 'usersCount', ], -} +} as const satisfies JSONSchema7Definition; export const packedRoleAssignSchema = { $id: 'https://misskey-hub.net/api/schemas/RoleAssign', @@ -50,20 +100,184 @@ export const packedRoleAssignSchema = { type: 'string', format: 'date-time', }, - user: { $ref: 'https://misskey-hub.net/api/schemas/UserDetailed' }, - expiresAt: { - oneOf: [{ - type: 'string', - format: 'date-time', - }, { - type: 'null', - }], - }, + user: { $ref: 'https://misskey-hub.net/api/schemas/UserDetailed' }, + expiresAt: { + oneOf: [{ + type: 'string', + format: 'date-time', + }, { + type: 'null', + }], + }, }, required: [ 'id', 'createdAt', - 'user', - 'expiresAt', + 'user', + 'expiresAt', ], } as const satisfies JSONSchema7Definition; + +export const packedRolePolicySchema = { + $id: 'https://misskey-hub.net/api/schemas/RolePolicy', + + type: 'object', + properties: { + useDefault: { type: 'boolean' }, + priority: { type: 'number' }, + value: { additionalProperties: true }, + }, + required: [ + 'useDefault', + 'priority', + 'value', + ], +} as const satisfies JSONSchema7Definition; + +export const packedRoleCondFormulaSchema = { + $id: 'https://misskey-hub.net/api/schemas/RoleCondFormula', + + oneOf: [ + { $ref: '#/$defs/and' }, + { $ref: '#/$defs/or' }, + { $ref: '#/$defs/not' }, + { $ref: '#/$defs/isLocal' }, + { $ref: '#/$defs/isRemote' }, + { $ref: '#/$defs/createdLessThan' }, + { $ref: '#/$defs/createdMoreThan' }, + { $ref: '#/$defs/createdLessThanOrEq' }, + { $ref: '#/$defs/createdMoreThanOrEq' }, + { $ref: '#/$defs/followersLessThanOrEq' }, + { $ref: '#/$defs/followersMoreThanOrEq' }, + { $ref: '#/$defs/followingLessThanOrEq' }, + { $ref: '#/$defs/followingMoreThanOrEq' }, + { $ref: '#/$defs/notesLessThanOrEq' }, + { $ref: '#/$defs/notesMoreThanOrEq' }, + ], + $defs: { + and: { + type: 'object', + properties: { + type: { const: 'and' }, + values: { + type: 'array', + items: { $ref: '#' }, + }, + }, + required: ['type', 'values'], + }, + or: { + type: 'object', + properties: { + type: { const: 'or' }, + values: { + type: 'array', + items: { $ref: '#' }, + }, + }, + required: ['type', 'values'], + }, + not: { + type: 'object', + properties: { + type: { const: 'not' }, + value: { $ref: '#' }, + }, + required: ['type', 'value'], + }, + isLocal: { + type: 'object', + properties: { + type: { const: 'isLocal' }, + }, + required: ['type'], + }, + isRemote: { + type: 'object', + properties: { + type: { const: 'isRemote' }, + }, + required: ['type'], + }, + createdLessThan: { + type: 'object', + properties: { + type: { const: 'createdLessThan' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + createdMoreThan: { + type: 'object', + properties: { + type: { const: 'createdMoreThan' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + createdLessThanOrEq: { + type: 'object', + properties: { + type: { const: 'createdLessThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + createdMoreThanOrEq: { + type: 'object', + properties: { + type: { const: 'createdMoreThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + followersLessThanOrEq: { + type: 'object', + properties: { + type: { const: 'followersLessThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + followersMoreThanOrEq: { + type: 'object', + properties: { + type: { const: 'followersMoreThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + followingLessThanOrEq: { + type: 'object', + properties: { + type: { const: 'followingLessThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + followingMoreThanOrEq: { + type: 'object', + properties: { + type: { const: 'followingMoreThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + notesLessThanOrEq: { + type: 'object', + properties: { + type: { const: 'notesLessThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + notesMoreThanOrEq: { + type: 'object', + properties: { + type: { const: 'notesMoreThanOrEq' }, + value: { type: 'number' }, + }, + required: ['type', 'value'], + }, + } +} as const satisfies JSONSchema7Definition; diff --git a/packages/misskey-js/test-d/schemas.ts b/packages/misskey-js/test-d/schemas.ts index 0ba22fd92..658d57caf 100644 --- a/packages/misskey-js/test-d/schemas.ts +++ b/packages/misskey-js/test-d/schemas.ts @@ -100,9 +100,12 @@ describe('schemas', () => { test('relay', () => { type Relay = Packed<'Relay'>; }); - test('role': () => { - + test('role', () => { + type Role = Packed<'Role'>; + type CF = Role['condFormula']; type RoleAssign = Packed<'RoleAssign'>; + type RolePolicy = Packed<'RolePolicy'>; + type RoleCondFormula = Packed<'RoleCondFormula'>; }); test('error', () => { type Error = Packed<'Error'>; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0033267f3..ecfc1a1ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -626,7 +626,7 @@ importers: version: 29.5.0 schema-type: specifier: github:misskey-dev/schema-type - version: github.com/misskey-dev/schema-type/ecfe907fb71f89eb0e41ed4449246ccd8366a260(typescript@5.0.4) + version: github.com/misskey-dev/schema-type/04addbe29c488e9e749bb9fe09812407da132e11(typescript@5.0.4) packages/frontend: dependencies: @@ -1026,7 +1026,7 @@ importers: version: 4.4.0 schema-type: specifier: github:misskey-dev/schema-type - version: github.com/misskey-dev/schema-type/ecfe907fb71f89eb0e41ed4449246ccd8366a260(typescript@5.0.4) + version: github.com/misskey-dev/schema-type/04addbe29c488e9e749bb9fe09812407da132e11(typescript@5.0.4) ts-essentials: specifier: ^9.3.2 version: 9.3.2(typescript@5.0.4) @@ -20518,9 +20518,9 @@ packages: version: 0.0.0 dev: false - github.com/misskey-dev/schema-type/ecfe907fb71f89eb0e41ed4449246ccd8366a260(typescript@5.0.4): - resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/ecfe907fb71f89eb0e41ed4449246ccd8366a260} - id: github.com/misskey-dev/schema-type/ecfe907fb71f89eb0e41ed4449246ccd8366a260 + github.com/misskey-dev/schema-type/04addbe29c488e9e749bb9fe09812407da132e11(typescript@5.0.4): + resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/04addbe29c488e9e749bb9fe09812407da132e11} + id: github.com/misskey-dev/schema-type/04addbe29c488e9e749bb9fe09812407da132e11 name: schema-type version: 1.0.0 dependencies: