wip
This commit is contained in:
		| @@ -66,6 +66,8 @@ import { FeaturedService } from './FeaturedService.js'; | ||||
| import { FanoutTimelineService } from './FanoutTimelineService.js'; | ||||
| import { ChannelFollowingService } from './ChannelFollowingService.js'; | ||||
| import { RegistryApiService } from './RegistryApiService.js'; | ||||
| import { ReversiService } from './ReversiService.js'; | ||||
|  | ||||
| import { ChartLoggerService } from './chart/ChartLoggerService.js'; | ||||
| import FederationChart from './chart/charts/federation.js'; | ||||
| import NotesChart from './chart/charts/notes.js'; | ||||
| @@ -80,6 +82,7 @@ import PerUserFollowingChart from './chart/charts/per-user-following.js'; | ||||
| import PerUserDriveChart from './chart/charts/per-user-drive.js'; | ||||
| import ApRequestChart from './chart/charts/ap-request.js'; | ||||
| import { ChartManagementService } from './chart/ChartManagementService.js'; | ||||
|  | ||||
| import { AbuseUserReportEntityService } from './entities/AbuseUserReportEntityService.js'; | ||||
| import { AntennaEntityService } from './entities/AntennaEntityService.js'; | ||||
| import { AppEntityService } from './entities/AppEntityService.js'; | ||||
| @@ -112,6 +115,9 @@ import { UserListEntityService } from './entities/UserListEntityService.js'; | ||||
| import { FlashEntityService } from './entities/FlashEntityService.js'; | ||||
| import { FlashLikeEntityService } from './entities/FlashLikeEntityService.js'; | ||||
| import { RoleEntityService } from './entities/RoleEntityService.js'; | ||||
| import { ReversiGameEntityService } from './entities/ReversiGameEntityService.js'; | ||||
| import { ReversiMatchingEntityService } from './entities/ReversiMatchingEntityService.js'; | ||||
|  | ||||
| import { ApAudienceService } from './activitypub/ApAudienceService.js'; | ||||
| import { ApDbResolverService } from './activitypub/ApDbResolverService.js'; | ||||
| import { ApDeliverManagerService } from './activitypub/ApDeliverManagerService.js'; | ||||
| @@ -199,6 +205,7 @@ const $FanoutTimelineService: Provider = { provide: 'FanoutTimelineService', use | ||||
| const $FanoutTimelineEndpointService: Provider = { provide: 'FanoutTimelineEndpointService', useExisting: FanoutTimelineEndpointService }; | ||||
| const $ChannelFollowingService: Provider = { provide: 'ChannelFollowingService', useExisting: ChannelFollowingService }; | ||||
| const $RegistryApiService: Provider = { provide: 'RegistryApiService', useExisting: RegistryApiService }; | ||||
| const $ReversiService: Provider = { provide: 'ReversiService', useExisting: ReversiService }; | ||||
|  | ||||
| const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService }; | ||||
| const $FederationChart: Provider = { provide: 'FederationChart', useExisting: FederationChart }; | ||||
| @@ -247,6 +254,8 @@ const $UserListEntityService: Provider = { provide: 'UserListEntityService', use | ||||
| const $FlashEntityService: Provider = { provide: 'FlashEntityService', useExisting: FlashEntityService }; | ||||
| const $FlashLikeEntityService: Provider = { provide: 'FlashLikeEntityService', useExisting: FlashLikeEntityService }; | ||||
| const $RoleEntityService: Provider = { provide: 'RoleEntityService', useExisting: RoleEntityService }; | ||||
| const $ReversiGameEntityService: Provider = { provide: 'ReversiGameEntityService', useExisting: ReversiGameEntityService }; | ||||
| const $ReversiMatchingEntityService: Provider = { provide: 'ReversiMatchingEntityService', useExisting: ReversiMatchingEntityService }; | ||||
|  | ||||
| const $ApAudienceService: Provider = { provide: 'ApAudienceService', useExisting: ApAudienceService }; | ||||
| const $ApDbResolverService: Provider = { provide: 'ApDbResolverService', useExisting: ApDbResolverService }; | ||||
| @@ -336,6 +345,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		FanoutTimelineEndpointService, | ||||
| 		ChannelFollowingService, | ||||
| 		RegistryApiService, | ||||
| 		ReversiService, | ||||
|  | ||||
| 		ChartLoggerService, | ||||
| 		FederationChart, | ||||
| 		NotesChart, | ||||
| @@ -350,6 +361,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		PerUserDriveChart, | ||||
| 		ApRequestChart, | ||||
| 		ChartManagementService, | ||||
|  | ||||
| 		AbuseUserReportEntityService, | ||||
| 		AntennaEntityService, | ||||
| 		AppEntityService, | ||||
| @@ -382,6 +394,9 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		FlashEntityService, | ||||
| 		FlashLikeEntityService, | ||||
| 		RoleEntityService, | ||||
| 		ReversiGameEntityService, | ||||
| 		ReversiMatchingEntityService, | ||||
|  | ||||
| 		ApAudienceService, | ||||
| 		ApDbResolverService, | ||||
| 		ApDeliverManagerService, | ||||
| @@ -466,6 +481,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$FanoutTimelineEndpointService, | ||||
| 		$ChannelFollowingService, | ||||
| 		$RegistryApiService, | ||||
| 		$ReversiService, | ||||
|  | ||||
| 		$ChartLoggerService, | ||||
| 		$FederationChart, | ||||
| 		$NotesChart, | ||||
| @@ -480,6 +497,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$PerUserDriveChart, | ||||
| 		$ApRequestChart, | ||||
| 		$ChartManagementService, | ||||
|  | ||||
| 		$AbuseUserReportEntityService, | ||||
| 		$AntennaEntityService, | ||||
| 		$AppEntityService, | ||||
| @@ -512,6 +530,9 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$FlashEntityService, | ||||
| 		$FlashLikeEntityService, | ||||
| 		$RoleEntityService, | ||||
| 		$ReversiGameEntityService, | ||||
| 		$ReversiMatchingEntityService, | ||||
|  | ||||
| 		$ApAudienceService, | ||||
| 		$ApDbResolverService, | ||||
| 		$ApDeliverManagerService, | ||||
| @@ -597,6 +618,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		FanoutTimelineEndpointService, | ||||
| 		ChannelFollowingService, | ||||
| 		RegistryApiService, | ||||
| 		ReversiService, | ||||
|  | ||||
| 		FederationChart, | ||||
| 		NotesChart, | ||||
| 		UsersChart, | ||||
| @@ -610,6 +633,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		PerUserDriveChart, | ||||
| 		ApRequestChart, | ||||
| 		ChartManagementService, | ||||
|  | ||||
| 		AbuseUserReportEntityService, | ||||
| 		AntennaEntityService, | ||||
| 		AppEntityService, | ||||
| @@ -642,6 +666,9 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		FlashEntityService, | ||||
| 		FlashLikeEntityService, | ||||
| 		RoleEntityService, | ||||
| 		ReversiGameEntityService, | ||||
| 		ReversiMatchingEntityService, | ||||
|  | ||||
| 		ApAudienceService, | ||||
| 		ApDbResolverService, | ||||
| 		ApDeliverManagerService, | ||||
| @@ -726,6 +753,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$FanoutTimelineEndpointService, | ||||
| 		$ChannelFollowingService, | ||||
| 		$RegistryApiService, | ||||
| 		$ReversiService, | ||||
|  | ||||
| 		$FederationChart, | ||||
| 		$NotesChart, | ||||
| 		$UsersChart, | ||||
| @@ -739,6 +768,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$PerUserDriveChart, | ||||
| 		$ApRequestChart, | ||||
| 		$ChartManagementService, | ||||
|  | ||||
| 		$AbuseUserReportEntityService, | ||||
| 		$AntennaEntityService, | ||||
| 		$AppEntityService, | ||||
| @@ -771,6 +801,9 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||
| 		$FlashEntityService, | ||||
| 		$FlashLikeEntityService, | ||||
| 		$RoleEntityService, | ||||
| 		$ReversiGameEntityService, | ||||
| 		$ReversiMatchingEntityService, | ||||
|  | ||||
| 		$ApAudienceService, | ||||
| 		$ApDbResolverService, | ||||
| 		$ApDeliverManagerService, | ||||
|   | ||||
							
								
								
									
										126
									
								
								packages/backend/src/core/ReversiService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								packages/backend/src/core/ReversiService.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| import { Inject, Injectable } from '@nestjs/common'; | ||||
| import * as Redis from 'ioredis'; | ||||
| import { In } from 'typeorm'; | ||||
| import { ModuleRef } from '@nestjs/core'; | ||||
| import type { | ||||
| 	MiReversiGame, | ||||
| 	MiRole, | ||||
| 	MiRoleAssignment, | ||||
| 	RoleAssignmentsRepository, | ||||
| 	RolesRepository, | ||||
| 	UsersRepository, | ||||
| } from '@/models/_.js'; | ||||
| import { MemoryKVCache, MemorySingleCache } from '@/misc/cache.js'; | ||||
| import type { MiUser } from '@/models/User.js'; | ||||
| 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/Role.js'; | ||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||
| import type { GlobalEvents } from '@/core/GlobalEventService.js'; | ||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||
| import { IdService } from '@/core/IdService.js'; | ||||
| import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||
| import type { Packed } from '@/misc/json-schema.js'; | ||||
| import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; | ||||
| import { NotificationService } from '@/core/NotificationService.js'; | ||||
| import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ReversiService implements OnApplicationShutdown, OnModuleInit { | ||||
| 	private notificationService: NotificationService; | ||||
|  | ||||
| 	constructor( | ||||
| 		private moduleRef: ModuleRef, | ||||
|  | ||||
| 		@Inject(DI.redis) | ||||
| 		private redisClient: Redis.Redis, | ||||
|  | ||||
| 		@Inject(DI.redisForTimelines) | ||||
| 		private redisForTimelines: Redis.Redis, | ||||
|  | ||||
| 		@Inject(DI.redisForSub) | ||||
| 		private redisForSub: Redis.Redis, | ||||
|  | ||||
| 		@Inject(DI.usersRepository) | ||||
| 		private usersRepository: UsersRepository, | ||||
|  | ||||
| 		@Inject(DI.rolesRepository) | ||||
| 		private rolesRepository: RolesRepository, | ||||
|  | ||||
| 		@Inject(DI.roleAssignmentsRepository) | ||||
| 		private roleAssignmentsRepository: RoleAssignmentsRepository, | ||||
|  | ||||
| 		private metaService: MetaService, | ||||
| 		private cacheService: CacheService, | ||||
| 		private userEntityService: UserEntityService, | ||||
| 		private globalEventService: GlobalEventService, | ||||
| 		private idService: IdService, | ||||
| 		private moderationLogService: ModerationLogService, | ||||
| 		private fanoutTimelineService: FanoutTimelineService, | ||||
| 	) { | ||||
| 	} | ||||
|  | ||||
| 	async onModuleInit() { | ||||
| 		this.notificationService = this.moduleRef.get(NotificationService.name); | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async getModerators(includeAdmins = true): Promise<MiUser[]> { | ||||
| 		const ids = await this.getModeratorIds(includeAdmins); | ||||
| 		const users = ids.length > 0 ? await this.usersRepository.findBy({ | ||||
| 			id: In(ids), | ||||
| 		}) : []; | ||||
| 		return users; | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async create(values: Partial<MiRole>, moderator?: MiUser): Promise<MiRole> { | ||||
| 		const date = new Date(); | ||||
| 		const created = await this.rolesRepository.insert({ | ||||
| 			id: this.idService.gen(date.getTime()), | ||||
| 			updatedAt: date, | ||||
| 			lastUsedAt: date, | ||||
| 			name: values.name, | ||||
| 			description: values.description, | ||||
| 			color: values.color, | ||||
| 			iconUrl: values.iconUrl, | ||||
| 			target: values.target, | ||||
| 			condFormula: values.condFormula, | ||||
| 			isPublic: values.isPublic, | ||||
| 			isAdministrator: values.isAdministrator, | ||||
| 			isModerator: values.isModerator, | ||||
| 			isExplorable: values.isExplorable, | ||||
| 			asBadge: values.asBadge, | ||||
| 			canEditMembersByModerator: values.canEditMembersByModerator, | ||||
| 			displayOrder: values.displayOrder, | ||||
| 			policies: values.policies, | ||||
| 		}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0])); | ||||
|  | ||||
| 		this.globalEventService.publishInternalEvent('roleCreated', created); | ||||
|  | ||||
| 		if (moderator) { | ||||
| 			this.moderationLogService.log(moderator, 'createRole', { | ||||
| 				roleId: created.id, | ||||
| 				role: created, | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		return created; | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public dispose(): void { | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public onApplicationShutdown(signal?: string | undefined): void { | ||||
| 		this.dispose(); | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| import { Inject, Injectable } from '@nestjs/common'; | ||||
| import { DI } from '@/di-symbols.js'; | ||||
| import type { ReversiGamesRepository } from '@/models/_.js'; | ||||
| import { awaitAll } from '@/misc/prelude/await-all.js'; | ||||
| import type { Packed } from '@/misc/json-schema.js'; | ||||
| import type { } from '@/models/Blocking.js'; | ||||
| import type { MiUser } from '@/models/User.js'; | ||||
| import type { MiReversiGame } from '@/models/ReversiGame.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import { IdService } from '@/core/IdService.js'; | ||||
| import { UserEntityService } from './UserEntityService.js'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ReversiGameEntityService { | ||||
| 	constructor( | ||||
| 		@Inject(DI.reversiGamesRepository) | ||||
| 		private reversiGamesRepository: ReversiGamesRepository, | ||||
|  | ||||
| 		private userEntityService: UserEntityService, | ||||
| 		private idService: IdService, | ||||
| 	) { | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async pack( | ||||
| 		src: MiReversiGame['id'] | MiReversiGame, | ||||
| 		me?: { id: MiUser['id'] } | null | undefined, | ||||
| 		options?: { | ||||
| 			detail?: boolean; | ||||
| 			skipHide?: boolean; | ||||
| 		}, | ||||
| 	): Promise<Packed<'ReversiGame'>> { | ||||
| 		const game = typeof src === 'object' ? src : await this.reversiGamesRepository.findOneByOrFail({ id: src }); | ||||
|  | ||||
| 		return await awaitAll({ | ||||
| 			id: game.id, | ||||
| 			createdAt: this.idService.parse(game.id).date.toISOString(), | ||||
| 			startedAt: game.startedAt && game.startedAt.toISOString(), | ||||
| 			isStarted: game.isStarted, | ||||
| 			isEnded: game.isEnded, | ||||
| 			form1: game.form1, | ||||
| 			form2: game.form2, | ||||
| 			user1Accepted: game.user1Accepted, | ||||
| 			user2Accepted: game.user2Accepted, | ||||
| 			user1Id: game.user1Id, | ||||
| 			user2Id: game.user2Id, | ||||
| 			user1: this.userEntityService.pack(game.user1Id, me), | ||||
| 			user2: this.userEntityService.pack(game.user2Id, me), | ||||
| 			winnerId: game.winnerId, | ||||
| 			winner: game.winnerId ? this.userEntityService.pack(game.winnerId, me) : null, | ||||
| 			surrendered: game.surrendered, | ||||
| 			black: game.black, | ||||
| 			bw: game.bw, | ||||
| 			isLlotheo: game.isLlotheo, | ||||
| 			canPutEverywhere: game.canPutEverywhere, | ||||
| 			loopedBoard: game.loopedBoard, | ||||
| 			...(options?.detail ? { | ||||
| 				logs: game.logs.map(log => ({ | ||||
| 					at: log.at.toISOString(), | ||||
| 					color: log.color, | ||||
| 					pos: log.pos, | ||||
| 				})), | ||||
| 				map: game.map, | ||||
| 			} : {}), | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public packMany( | ||||
| 		xs: MiReversiGame[], | ||||
| 		me?: { id: MiUser['id'] } | null | undefined, | ||||
| 	) { | ||||
| 		return Promise.all(xs.map(x => this.pack(x, me))); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,57 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| import { Inject, Injectable } from '@nestjs/common'; | ||||
| import { DI } from '@/di-symbols.js'; | ||||
| import type { MiReversiMatching, ReversiMatchingsRepository } from '@/models/_.js'; | ||||
| import { awaitAll } from '@/misc/prelude/await-all.js'; | ||||
| import type { Packed } from '@/misc/json-schema.js'; | ||||
| import type { } from '@/models/Blocking.js'; | ||||
| import type { MiUser } from '@/models/User.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import { IdService } from '@/core/IdService.js'; | ||||
| import { UserEntityService } from './UserEntityService.js'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ReversiMatchingEntityService { | ||||
| 	constructor( | ||||
| 		@Inject(DI.reversiMatchingsRepository) | ||||
| 		private reversiMatchingsRepository: ReversiMatchingsRepository, | ||||
|  | ||||
| 		private userEntityService: UserEntityService, | ||||
| 		private idService: IdService, | ||||
| 	) { | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public async pack( | ||||
| 		src: MiReversiMatching['id'] | MiReversiMatching, | ||||
| 		me?: { id: MiUser['id'] } | null | undefined, | ||||
| 	): Promise<Packed<'ReversiMatching'>> { | ||||
| 		const matching = typeof src === 'object' ? src : await this.reversiMatchingsRepository.findOneByOrFail({ id: src }); | ||||
|  | ||||
| 		return await awaitAll({ | ||||
| 			id: matching.id, | ||||
| 			createdAt: this.idService.parse(matching.id).date.toISOString(), | ||||
| 			parentId: matching.parentId, | ||||
| 			parent: this.userEntityService.pack(matching.parentId, me, { | ||||
| 				detail: true, | ||||
| 			}), | ||||
| 			childId: matching.childId, | ||||
| 			child: this.userEntityService.pack(matching.childId, me, { | ||||
| 				detail: true, | ||||
| 			}), | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	@bindThis | ||||
| 	public packMany( | ||||
| 		xs: MiReversiMatching[], | ||||
| 		me?: { id: MiUser['id'] } | null | undefined, | ||||
| 	) { | ||||
| 		return Promise.all(xs.map(x => this.pack(x, me))); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -39,6 +39,8 @@ import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js'; | ||||
| import { packedSigninSchema } from '@/models/json-schema/signin.js'; | ||||
| import { packedRoleLiteSchema, packedRoleSchema } from '@/models/json-schema/role.js'; | ||||
| import { packedAdSchema } from '@/models/json-schema/ad.js'; | ||||
| import { packedReversiGameSchema } from '@/models/json-schema/reversi-game.js'; | ||||
| import { packedReversiMatchingSchema } from '@/models/json-schema/reversi-matching.js'; | ||||
|  | ||||
| export const refs = { | ||||
| 	UserLite: packedUserLiteSchema, | ||||
| @@ -78,6 +80,8 @@ export const refs = { | ||||
| 	Signin: packedSigninSchema, | ||||
| 	RoleLite: packedRoleLiteSchema, | ||||
| 	Role: packedRoleSchema, | ||||
| 	ReversiGame: packedReversiGameSchema, | ||||
| 	ReversiMatching: packedReversiMatchingSchema, | ||||
| }; | ||||
|  | ||||
| export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>; | ||||
|   | ||||
							
								
								
									
										135
									
								
								packages/backend/src/models/json-schema/reversi-game.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								packages/backend/src/models/json-schema/reversi-game.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| export const packedReversiGameSchema = { | ||||
| 	type: 'object', | ||||
| 	properties: { | ||||
| 		id: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		createdAt: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'date-time', | ||||
| 		}, | ||||
| 		startedAt: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: true, | ||||
| 			format: 'date-time', | ||||
| 		}, | ||||
| 		isStarted: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		isEnded: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		form1: { | ||||
| 			type: 'any', | ||||
| 			optional: false, nullable: true, | ||||
| 		}, | ||||
| 		form2: { | ||||
| 			type: 'any', | ||||
| 			optional: false, nullable: true, | ||||
| 		}, | ||||
| 		user1Accepted: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		user2Accepted: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		user1Id: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		user2Id: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		user1: { | ||||
| 			type: 'object', | ||||
| 			optional: false, nullable: false, | ||||
| 			ref: 'User', | ||||
| 		}, | ||||
| 		user2: { | ||||
| 			type: 'object', | ||||
| 			optional: false, nullable: false, | ||||
| 			ref: 'User', | ||||
| 		}, | ||||
| 		winnerId: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: true, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		winner: { | ||||
| 			type: 'object', | ||||
| 			optional: false, nullable: true, | ||||
| 			ref: 'User', | ||||
| 		}, | ||||
| 		surrendered: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: true, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		black: { | ||||
| 			type: 'number', | ||||
| 			optional: false, nullable: true, | ||||
| 		}, | ||||
| 		bw: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		isLlotheo: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		canPutEverywhere: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		loopedBoard: { | ||||
| 			type: 'boolean', | ||||
| 			optional: false, nullable: false, | ||||
| 		}, | ||||
| 		logs: { | ||||
| 			type: 'array', | ||||
| 			optional: true, nullable: false, | ||||
| 			items: { | ||||
| 				type: 'object', | ||||
| 				optional: true, nullable: false, | ||||
| 				properties: { | ||||
| 					at: { | ||||
| 						type: 'string', | ||||
| 						optional: false, nullable: false, | ||||
| 						format: 'date-time', | ||||
| 					}, | ||||
| 					color: { | ||||
| 						type: 'boolean', | ||||
| 						optional: false, nullable: false, | ||||
| 					}, | ||||
| 					pos: { | ||||
| 						type: 'number', | ||||
| 						optional: false, nullable: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		map: { | ||||
| 			type: 'array', | ||||
| 			optional: true, nullable: false, | ||||
| 			items: { | ||||
| 				type: 'string', | ||||
| 				optional: false, nullable: false, | ||||
| 			}, | ||||
| 		}, | ||||
| 	}, | ||||
| } as const; | ||||
							
								
								
									
										40
									
								
								packages/backend/src/models/json-schema/reversi-matching.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								packages/backend/src/models/json-schema/reversi-matching.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| export const packedReversiMatchingSchema = { | ||||
| 	type: 'object', | ||||
| 	properties: { | ||||
| 		id: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		createdAt: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'date-time', | ||||
| 		}, | ||||
| 		parentId: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		parent: { | ||||
| 			type: 'object', | ||||
| 			optional: false, nullable: true, | ||||
| 			ref: 'User', | ||||
| 		}, | ||||
| 		childId: { | ||||
| 			type: 'string', | ||||
| 			optional: false, nullable: false, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		child: { | ||||
| 			type: 'object', | ||||
| 			optional: false, nullable: false, | ||||
| 			ref: 'User', | ||||
| 		}, | ||||
| 	}, | ||||
| } as const; | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo