wip
This commit is contained in:
parent
47fae30aba
commit
669cfb1e29
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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 });
|
||||||
|
|
||||||
|
|
|
@ -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; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue