This commit is contained in:
tamaina 2023-06-04 17:37:00 +00:00
parent 47fae30aba
commit 669cfb1e29
6 changed files with 165 additions and 155 deletions

View File

@ -8,49 +8,10 @@ import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import { ApiError } from '../../error.js';
export const meta = {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
limit: {
duration: ms('1hour'),
max: 10,
},
res: {
type: 'object',
optional: false, nullable: false,
ref: 'Channel',
},
errors: {
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 128 },
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
bannerId: { type: 'string', format: 'misskey:id', nullable: true },
color: { type: 'string', minLength: 1, maxLength: 16 },
},
required: ['name'],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'channels/create'> {
name = 'channels/create' as const;
constructor( constructor(
@Inject(DI.driveFilesRepository) @Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository, private driveFilesRepository: DriveFilesRepository,
@ -61,7 +22,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private idService: IdService, private idService: IdService,
private channelEntityService: ChannelEntityService, private channelEntityService: ChannelEntityService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
let banner = null; let banner = null;
if (ps.bannerId != null) { if (ps.bannerId != null) {
banner = await this.driveFilesRepository.findOneBy({ banner = await this.driveFilesRepository.findOneBy({
@ -70,7 +31,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
if (banner == null) { if (banner == null) {
throw new ApiError(meta.errors.noSuchFile); throw new ApiError(this.meta.errors.noSuchFile);
} }
} }

View File

@ -5,35 +5,10 @@ import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import { ApiError } from '../../error.js';
export const meta = {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
errors: {
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: '4938f5f3-6167-4c04-9149-6607b7542861',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
channelId: { type: 'string', format: 'misskey:id' },
},
required: ['channelId'],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'channels/favorite'> {
name = 'channels/favorite' as const;
constructor( constructor(
@Inject(DI.channelsRepository) @Inject(DI.channelsRepository)
private channelsRepository: ChannelsRepository, private channelsRepository: ChannelsRepository,
@ -43,13 +18,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private idService: IdService, private idService: IdService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const channel = await this.channelsRepository.findOneBy({ const channel = await this.channelsRepository.findOneBy({
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) {
throw new ApiError(meta.errors.noSuchChannel); throw new ApiError(this.meta.errors.noSuchChannel);
} }
await this.channelFavoritesRepository.insert({ await this.channelFavoritesRepository.insert({

View File

@ -4,38 +4,17 @@ import type { ChannelsRepository } from '@/models/index.js';
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['channels'],
requireCredential: false,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Channel',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'channels/featured'> {
name = 'channels/featured' as const;
constructor( constructor(
@Inject(DI.channelsRepository) @Inject(DI.channelsRepository)
private channelsRepository: ChannelsRepository, private channelsRepository: ChannelsRepository,
private channelEntityService: ChannelEntityService, private channelEntityService: ChannelEntityService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const query = this.channelsRepository.createQueryBuilder('channel') const query = this.channelsRepository.createQueryBuilder('channel')
.where('channel.lastNotedAt IS NOT NULL') .where('channel.lastNotedAt IS NOT NULL')
.andWhere('channel.isArchived = FALSE') .andWhere('channel.isArchived = FALSE')

View File

@ -6,35 +6,10 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '../../error.js'; import { ApiError } from '../../error.js';
export const meta = {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
errors: {
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
channelId: { type: 'string', format: 'misskey:id' },
},
required: ['channelId'],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'channels/follow'> {
name = 'channels/follow' as const;
constructor( constructor(
@Inject(DI.channelsRepository) @Inject(DI.channelsRepository)
private channelsRepository: ChannelsRepository, private channelsRepository: ChannelsRepository,
@ -44,13 +19,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private idService: IdService, private idService: IdService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const channel = await this.channelsRepository.findOneBy({ const channel = await this.channelsRepository.findOneBy({
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) {
throw new ApiError(meta.errors.noSuchChannel); throw new ApiError(this.meta.errors.noSuchChannel);
} }
await this.channelFollowingsRepository.insert({ await this.channelFollowingsRepository.insert({

View File

@ -5,37 +5,10 @@ import { QueryService } from '@/core/QueryService.js';
import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['channels', 'account'],
requireCredential: true,
kind: 'read:channels',
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Channel',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'channels/followed'> {
name = 'channels/followed' as const;
constructor( constructor(
@Inject(DI.channelFollowingsRepository) @Inject(DI.channelFollowingsRepository)
private channelFollowingsRepository: ChannelFollowingsRepository, private channelFollowingsRepository: ChannelFollowingsRepository,
@ -43,7 +16,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private channelEntityService: ChannelEntityService, private channelEntityService: ChannelEntityService,
private queryService: QueryService, private queryService: QueryService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.channelFollowingsRepository.createQueryBuilder(), ps.sinceId, ps.untilId) const query = this.queryService.makePaginationQuery(this.channelFollowingsRepository.createQueryBuilder(), ps.sinceId, ps.untilId)
.andWhere({ followerId: me.id }); .andWhere({ followerId: me.id });

View File

@ -2593,6 +2593,153 @@ export const endpoints = {
}], }],
}, },
//#endregion //#endregion
//#region channels
'channels/create': {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
limit: {
duration: ms('1hour'),
max: 10,
},
errors: {
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050',
},
},
defines: [{
req: {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 128 },
description: {
oneOf: [
{ type: 'string', minLength: 1, maxLength: 2048 },
{ type: 'null' },
],
},
bannerId: {
oneOf: [
{ type: 'string', format: 'misskey:id' },
{ type: 'null' },
],
},
color: { type: 'string', minLength: 1, maxLength: 16 },
},
required: ['name'],
},
res: {
$ref: 'https://misskey-hub.net/api/schemas/Channel',
}
}],
},
'channels/favorite': {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
errors: {
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: '4938f5f3-6167-4c04-9149-6607b7542861',
},
},
defines: [{
req: {
type: 'object',
properties: {
channelId: { type: 'string', format: 'misskey:id' },
},
required: ['channelId'],
},
res: undefined,
}]
},
'channels/featured': {
tags: ['channels'],
requireCredential: false,
defines: [{
req: undefined,
res: {
type: 'array',
items: {
$ref: 'https://misskey-hub.net/api/schemas/Channel',
},
},
}],
},
'channels/follow': {
tags: ['channels'],
requireCredential: true,
prohibitMoved: true,
kind: 'write:channels',
errors: {
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
},
},
defines: [{
req: {
type: 'object',
properties: {
channelId: { type: 'string', format: 'misskey:id' },
},
required: ['channelId'],
},
res: undefined,
}],
},
'channels/followed': {
tags: ['channels', 'account'],
requireCredential: true,
kind: 'read:channels',
defines: [{
req: {
type: 'object',
properties: {
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 },
},
required: [],
},
res: {
type: 'array',
items: {
$ref: 'https://misskey-hub.net/api/schemas/Channel',
},
},
}],
},
//#endregion
} as const satisfies { [x: string]: IEndpointMeta; }; } as const satisfies { [x: string]: IEndpointMeta; };
/** /**