Skip to content

Commit

Permalink
Merge pull request #533 from neet/channel
Browse files Browse the repository at this point in the history
chore: Add channel
  • Loading branch information
neet authored Nov 23, 2022
2 parents a311c92 + b68e420 commit cff170f
Show file tree
Hide file tree
Showing 112 changed files with 1,419 additions and 632 deletions.
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"sqltag",
"storyshots",
"tailwindcss",
"Twicasting",
"unfetch",
"unmount",
"unoptimized",
Expand Down
2 changes: 1 addition & 1 deletion packages/@neet/vschedule-api-spec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
},
"devDependencies": {
"@asteasolutions/zod-to-openapi": "^3.0.0",
"@asteasolutions/zod-to-openapi": "^3.1.0",
"@neet/eslint-plugin-vschedule": "workspace:^",
"@neet/tsconfig-vschedule": "workspace:^",
"@types/eslint": "^8.4.10",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { z } from 'zod';

import { registry } from '../../api';

export const PathChannelId = registry.registerParameter(
'PathChannelId',
z.string().openapi({ param: { name: 'channelId', in: 'path' } }),
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from 'zod';

import { registry } from '../../api';
import { Channel } from './Channel';
import { MediaAttachment } from './MediaAttachment';

export const Actor = registry.register(
Expand All @@ -14,5 +15,6 @@ export const Actor = registry.register(
avatar: MediaAttachment.optional(),
twitterUsername: z.string().nullable(),
youtubeChannelId: z.string().nullable(),
channels: z.array(Channel),
}),
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { z } from 'zod';

import { registry } from '../../api';

export const BaseChannel = registry.register(
'BaseChannel',
z.object({
id: z.string(),
name: z.string(),
description: z.string().nullish(),
}),
);

export const YoutubeChannel = registry.register(
'YoutubeChannel',
BaseChannel.extend({
type: z.literal('youtube'),
url: z.string().url(),
}),
);

export const TwitchChannel = registry.register(
'TwitchChannel',
BaseChannel.extend({
type: z.literal('twitch'),
url: z.string().url(),
}),
);

export const TwicastingChannel = registry.register(
'TwicastingChannel',
BaseChannel.extend({
type: z.literal('twicasting'),
url: z.string().url(),
}),
);

export const Channel = registry.register(
'Channel',
z.discriminatedUnion('type', [
YoutubeChannel,
TwitchChannel,
TwicastingChannel,
]),
);
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ export const Stream = registry.register(
url: z.string().url(),
description: z.string().nullable(),
thumbnail: MediaAttachment.optional(),
channelId: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
startedAt: z.date(),
endedAt: z.date().nullable(),
duration: z.string().nullable(),
owner: Performer,
casts: z.array(Performer),
participants: z.array(Performer),
}),
);
21 changes: 21 additions & 0 deletions packages/@neet/vschedule-api-spec/src/paths/rest/v1/channels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { z } from 'zod';

import { registry } from '../../../api';
import { PathChannelId } from '../../../components/parameters/PathChannelId';

registry.registerPath({
method: 'post',
path: '/rest/v1/channels/{channelId}/subscribe',
operationId: 'subscribeToChannel',
summary: 'チャンネルを購読',
request: {
params: z.object({
channelId: PathChannelId,
}),
},
responses: {
200: {
description: '成功時のレスポンスです',
},
},
});
20 changes: 0 additions & 20 deletions packages/@neet/vschedule-api-spec/src/paths/rest/v1/performers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,3 @@ registry.registerPath({
},
},
});

registry.registerPath({
method: 'post',
path: '/rest/v1/performers/{performerId}/subscribe',
operationId: 'subscribeToPerformer',
summary: 'パフォーマーを購読',
request: {
params: z.object({
performerId: PathPerformerId,
}),
},
responses: {
200: {
description: '成功時のレスポンスです',
// content: {
// 'application/json': { schema: Performer },
// },
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export const YoutubeAtomFeed = z.union([
export const YoutubeWebsubVerification = z.object({
'hub.topic': z.string().url(),
'hub.challenge': z.string(),
'hub.mode': z.union([z.literal('subscribe'), z.literal('unsubscribe')]),
// 'hub.mode': z.union([z.literal('subscribe'), z.literal('unsubscribe')]),
'hub.mode': z.string(),
'hub.lease_seconds': z.number().int(),
'hub.verify_token': z.string(),
});
Expand Down
6 changes: 3 additions & 3 deletions packages/@neet/vschedule-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"class-validator": "^0.13.2",
"color": "^4.2.3",
"cors": "^2.8.5",
"cosmiconfig": "^7.1.0",
"cosmiconfig": "^8.0.0",
"cosmiconfig-toml-loader": "^1.0.0",
"dayjs": "^1.11.6",
"express": "^4.18.2",
Expand All @@ -39,7 +39,7 @@
"mkdirp": "^1.0.4",
"nanoid": "^3.3.4",
"node-fetch": "^2.6.7",
"openapi2aspida": "^0.19.0",
"openapi2aspida": "^0.20.0",
"passport": "^0.6.0",
"passport-local": "^1.0.0",
"plaiceholder": "^2.5.0",
Expand All @@ -58,7 +58,7 @@
"devDependencies": {
"@neet/eslint-plugin-vschedule": "workspace:^",
"@neet/tsconfig-vschedule": "workspace:^",
"@quramy/jest-prisma-node": "^1.1.2",
"@quramy/jest-prisma-node": "^1.2.0",
"@swc/core": "^1.3.19",
"@swc/jest": "^0.2.23",
"@types/bcryptjs": "^2.4.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Warnings:
- Added the required column `channel_id` to the `streams` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE `streams` ADD COLUMN `channel_id` VARCHAR(191) NOT NULL;

-- CreateTable
CREATE TABLE `channels` (
`id` VARCHAR(21) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`status` VARCHAR(191) NOT NULL,
`description` TEXT NULL,
`performer_id` VARCHAR(191) NULL,
`organization_id` VARCHAR(191) NULL,

INDEX `channels_performer_id_organization_id_idx`(`performer_id`, `organization_id`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `youtube_channels` (
`id` VARCHAR(21) NOT NULL,
`youtubeChannelId` VARCHAR(191) NOT NULL,

UNIQUE INDEX `youtube_channels_youtubeChannelId_key`(`youtubeChannelId`),
INDEX `youtube_channels_youtubeChannelId_idx`(`youtubeChannelId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- AddForeignKey
ALTER TABLE `streams` ADD CONSTRAINT `streams_channel_id_fkey` FOREIGN KEY (`channel_id`) REFERENCES `channels`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `channels` ADD CONSTRAINT `channels_performer_id_fkey` FOREIGN KEY (`performer_id`) REFERENCES `performers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `channels` ADD CONSTRAINT `channels_organization_id_fkey` FOREIGN KEY (`organization_id`) REFERENCES `organizations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `youtube_channels` ADD CONSTRAINT `youtube_channels_id_fkey` FOREIGN KEY (`id`) REFERENCES `channels`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
38 changes: 35 additions & 3 deletions packages/@neet/vschedule-api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ model Stream {
startedAt DateTime @map("started_at")
endedAt DateTime? @map("ended_at")
channelId String @map("channel_id")
channel Channel @relation(fields: [channelId], references: [id])
ownerId String @map("owner_id")
owner Performer @relation(fields: [ownerId], references: [id])
Expand Down Expand Up @@ -75,7 +78,8 @@ model Performer {
createdAt DateTime @map("created_at")
updatedAt DateTime @map("updated_at")
streams Stream[]
streams Stream[]
channels Channel[]
@@index([organizationId])
@@index([youtubeChannelId])
Expand All @@ -98,14 +102,42 @@ model Organization {
performers Performer[]
createdAt DateTime @map("created_at")
updatedAt DateTime @map("updated_at")
createdAt DateTime @map("created_at")
updatedAt DateTime @map("updated_at")
channels Channel[]
@@index([youtubeChannelId])
@@index([twitterUsername])
@@map("organizations")
}

model Channel {
id String @id @db.VarChar(21)
name String
status String
description String? @db.Text
performerId String? @map("performer_id")
performer Performer? @relation(fields: [performerId], references: [id])
organizationId String? @map("organization_id")
organization Organization? @relation(fields: [organizationId], references: [id])
youtubeChannel YoutubeChannel?
streams Stream[]
@@index([performerId, organizationId])
@@map("channels")
}

model YoutubeChannel {
id String @id @db.VarChar(21)
youtubeChannelId String @unique
channel Channel @relation(fields: [id], references: [id])
@@index([youtubeChannelId])
@@map("youtube_channels")
}

model Token {
id String @id @unique @db.VarChar(64)
createdAt DateTime @map("created_at")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { inject, injectable } from 'inversify';
import { JsonController, OnUndefined, Param, Post } from 'routing-controllers';

import { RequestChannelSubscription } from '../../../../app/channel/request-channel-subscription';

@injectable()
@JsonController('/rest/v1/channels')
export class ChannelController {
constructor(
@inject(RequestChannelSubscription)
private readonly requestChannelSubscription: RequestChannelSubscription,
) {}

@Post('/:channelId/subscribe')
@OnUndefined(202)
async subscribe(@Param('channelId') channelId: string): Promise<void> {
await this.requestChannelSubscription.invoke({ channelId });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @file Automatically generated by barrelsby.
*/

export * from './channels';
export * from './media';
export * from './organizations';
export * from './performers';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import { inject, injectable } from 'inversify';
import {
Authorized,
Get,
JsonController,
OnUndefined,
Param,
Params,
Post,
} from 'routing-controllers';
import { Get, JsonController, Param, Params } from 'routing-controllers';

import {
ListPerformers,
ShowPerformer,
SubscribeToPerformer,
} from '../../../../app';
import { ListPerformers, ShowPerformer } from '../../../../app';
import { Methods } from '../../../generated/rest/v1/performers';
import { RestPresenter } from '../../../mappers';

Expand All @@ -27,9 +15,6 @@ export class PerformersController {
@inject(ListPerformers)
private readonly _listPerformers: ListPerformers,

@inject(SubscribeToPerformer)
private readonly _subscribeToPerformer: SubscribeToPerformer,

@inject(RestPresenter)
private readonly _presenter: RestPresenter,
) {}
Expand All @@ -46,16 +31,6 @@ export class PerformersController {
return this._presenter.presentPerformer(performer);
}

@Post('/:performerId/subscribe')
@Authorized()
@OnUndefined(202)
public async subscribe(@Param('performerId') performerId: string) {
await this._subscribeToPerformer.invoke({
performerId,
});
// return this.statusCode(202);
}

@Get('/')
async list(
@Params() params: Methods['get']['query'] = {},
Expand Down
Loading

1 comment on commit cff170f

@vercel
Copy link

@vercel vercel bot commented on cff170f Nov 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.