Skip to content

Commit bb42817

Browse files
feat: elysia youtube poc with api-key docs and simplified typed client
1 parent 9aabc10 commit bb42817

File tree

24 files changed

+563
-198
lines changed

24 files changed

+563
-198
lines changed

app/api/[...slug]/route.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { NextRequest } from "next/server";
2+
import { elysiaApi } from "@/lib/api/elysia/app";
3+
4+
async function handle(request: NextRequest): Promise<Response> {
5+
return elysiaApi.handle(request);
6+
}
7+
8+
export const GET = handle;
9+
export const POST = handle;
10+
export const PUT = handle;
11+
export const PATCH = handle;
12+
export const DELETE = handle;
13+
export const HEAD = handle;
14+
export const OPTIONS = handle;
15+
16+
export const dynamic = "force-dynamic";
17+
export const fetchCache = "force-no-store";
18+
export const revalidate = 0;

app/api/agent-templates/favorites/route.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

app/api/youtube/channel-info/route.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.

components/Agents/useAgentToggleFavorite.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
import { useUserProvider } from "@/providers/UserProvder";
21
import { useQueryClient } from "@tanstack/react-query";
32
import { toast } from "sonner";
43
import type { ToggleFavoriteRequest } from "@/types/AgentTemplates";
54

65
export function useAgentToggleFavorite() {
7-
const { userData } = useUserProvider();
86
const queryClient = useQueryClient();
97

108
const handleToggleFavorite = async (
119
templateId: string,
1210
nextFavourite: boolean
1311
) => {
14-
if (!userData?.id || !templateId) return;
12+
if (!templateId) return;
1513

1614
try {
1715
const body: ToggleFavoriteRequest = {
1816
templateId,
19-
userId: userData.id,
2017
isFavourite: nextFavourite,
2118
};
2219
const res = await fetch("/api/agent-templates/favorites", {

components/ArtistSetting/StandaloneYoutubeComponent/ChannelInfo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Youtube } from "lucide-react";
66
const ChannelInfo = ({ dense, artistAccountId }: { dense?: boolean; artistAccountId: string }) => {
77
const { data, isLoading } = useYoutubeChannel(artistAccountId);
88

9-
const channel = data?.channels?.[0];
9+
const channel = data?.[0];
1010

1111
return (
1212
<div className="flex flex-col gap-1 cursor-pointer">

components/YouTube/ChatInputYoutubeButtonPopover/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const ChatInputYoutubeButtonPopover = ({ children, artistAccountId }: { children
1414
const { data: channelInfo, isLoading: isChannelInfoLoading } = useYoutubeChannel(artistAccountId);
1515
const isMobile = useIsMobile();
1616
const [isOpen, setIsOpen] = useState(false);
17-
const channel = channelInfo?.channels?.[0];
17+
const channel = channelInfo?.[0];
1818

1919
if (youtubeStatus?.status === "invalid" || isLoading || isChannelInfoLoading) {
2020
return children;

hooks/useYouTubeLoginSuccess.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ export function useYouTubeLoginSuccess() {
4545
hasCheckedOAuth.current = true;
4646

4747
if (selectedArtist?.account_id) {
48-
fetchYouTubeChannel(selectedArtist.account_id).then((youtubeChannel) => {
49-
if (youtubeChannel.success) {
48+
const checkYouTubeConnection = async () => {
49+
try {
50+
await fetchYouTubeChannel(selectedArtist.account_id);
51+
5052
const successMessage = {
5153
id: generateUUID(),
5254
role: "user" as const,
@@ -59,8 +61,12 @@ export function useYouTubeLoginSuccess() {
5961
} as UIMessage;
6062

6163
append(successMessage);
64+
} catch {
65+
// Ignore auth/check errors here; normal flow continues.
6266
}
63-
});
67+
};
68+
69+
void checkYouTubeConnection();
6470
}
6571
}, [messages, append, selectedArtist?.account_id]);
6672
}

hooks/useYoutubeChannel.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import fetchYouTubeChannel from "@/lib/youtube/fetchYouTubeChannel";
2-
import { YouTubeChannelResponse } from "@/types/youtube";
31
import { useQuery } from "@tanstack/react-query";
2+
import fetchYouTubeChannel from "@/lib/youtube/fetchYouTubeChannel";
43

54
const useYoutubeChannel = (artistAccountId: string) => {
6-
return useQuery<YouTubeChannelResponse>({
5+
return useQuery({
76
queryKey: ["youtube-channel-info", artistAccountId],
87
queryFn: () => fetchYouTubeChannel(artistAccountId),
98
enabled: !!artistAccountId, // Only run query if artistAccountId is provided

hooks/useYoutubeStatus.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ const useYoutubeStatus = (artistAccountId?: string) => {
1313
status: (() => {
1414
if (error) return "error";
1515
if (isLoading) return "invalid";
16-
if (channelResponse) {
17-
return channelResponse.tokenStatus === "valid"
18-
? "valid"
19-
: "invalid";
16+
if (Array.isArray(channelResponse) && channelResponse.length > 0) {
17+
return "valid";
2018
}
2119
return "invalid";
2220
})(),
@@ -27,7 +25,7 @@ const useYoutubeStatus = (artistAccountId?: string) => {
2725
return {
2826
data,
2927
isLoading,
30-
error: null,
28+
error: error ?? null,
3129
} as YoutubeStatus;
3230
};
3331

lib/api/elysia/app.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Elysia } from "elysia";
2+
import { openapi } from "@elysiajs/openapi";
3+
import { authPlugin } from "@/lib/api/elysia/plugins/auth";
4+
import { elysiaRoutes } from "@/lib/api/elysia/routes";
5+
6+
export const elysiaApi = new Elysia({ prefix: "/api" })
7+
.use(
8+
openapi({
9+
path: "/openapi",
10+
specPath: "/openapi/json",
11+
provider: "scalar",
12+
documentation: {
13+
info: {
14+
title: "Recoupable Chat API (Elysia POC)",
15+
version: "0.1.0",
16+
},
17+
components: {
18+
securitySchemes: {
19+
apiKeyAuth: {
20+
type: "apiKey",
21+
in: "header",
22+
name: "x-api-key",
23+
},
24+
},
25+
},
26+
},
27+
}),
28+
)
29+
.use(authPlugin)
30+
.use(elysiaRoutes);
31+
32+
export type ElysiaApi = typeof elysiaApi;

0 commit comments

Comments
 (0)