@opentabs-dev/opentabs-plugin-twitch 0.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -0
- package/dist/adapter.iife.js +15103 -0
- package/dist/adapter.iife.js.map +7 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/get-channel-emotes.d.ts +10 -0
- package/dist/tools/get-channel-emotes.d.ts.map +1 -0
- package/dist/tools/get-channel-emotes.js +38 -0
- package/dist/tools/get-channel-emotes.js.map +1 -0
- package/dist/tools/get-current-user.d.ts +18 -0
- package/dist/tools/get-current-user.d.ts.map +1 -0
- package/dist/tools/get-current-user.js +27 -0
- package/dist/tools/get-current-user.js.map +1 -0
- package/dist/tools/get-game-clips.d.ts +31 -0
- package/dist/tools/get-game-clips.d.ts.map +1 -0
- package/dist/tools/get-game-clips.js +44 -0
- package/dist/tools/get-game-clips.js.map +1 -0
- package/dist/tools/get-game.d.ts +15 -0
- package/dist/tools/get-game.d.ts.map +1 -0
- package/dist/tools/get-game.js +32 -0
- package/dist/tools/get-game.js.map +1 -0
- package/dist/tools/get-stream.d.ts +24 -0
- package/dist/tools/get-stream.d.ts.map +1 -0
- package/dist/tools/get-stream.js +36 -0
- package/dist/tools/get-stream.js.map +1 -0
- package/dist/tools/get-streams-by-game.d.ts +25 -0
- package/dist/tools/get-streams-by-game.d.ts.map +1 -0
- package/dist/tools/get-streams-by-game.js +44 -0
- package/dist/tools/get-streams-by-game.js.map +1 -0
- package/dist/tools/get-top-games.d.ts +14 -0
- package/dist/tools/get-top-games.d.ts.map +1 -0
- package/dist/tools/get-top-games.js +30 -0
- package/dist/tools/get-top-games.js.map +1 -0
- package/dist/tools/get-top-streams.d.ts +23 -0
- package/dist/tools/get-top-streams.d.ts.map +1 -0
- package/dist/tools/get-top-streams.js +34 -0
- package/dist/tools/get-top-streams.js.map +1 -0
- package/dist/tools/get-user-clips.d.ts +31 -0
- package/dist/tools/get-user-clips.d.ts.map +1 -0
- package/dist/tools/get-user-clips.js +44 -0
- package/dist/tools/get-user-clips.js.map +1 -0
- package/dist/tools/get-user-profile.d.ts +20 -0
- package/dist/tools/get-user-profile.d.ts.map +1 -0
- package/dist/tools/get-user-profile.js +31 -0
- package/dist/tools/get-user-profile.js.map +1 -0
- package/dist/tools/get-user-videos.d.ts +30 -0
- package/dist/tools/get-user-videos.d.ts.map +1 -0
- package/dist/tools/get-user-videos.js +58 -0
- package/dist/tools/get-user-videos.js.map +1 -0
- package/dist/tools/get-video.d.ts +23 -0
- package/dist/tools/get-video.d.ts.map +1 -0
- package/dist/tools/get-video.js +50 -0
- package/dist/tools/get-video.js.map +1 -0
- package/dist/tools/schemas.d.ts +153 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +160 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/search-categories.d.ts +14 -0
- package/dist/tools/search-categories.d.ts.map +1 -0
- package/dist/tools/search-categories.js +29 -0
- package/dist/tools/search-categories.js.map +1 -0
- package/dist/tools/search-channels.d.ts +31 -0
- package/dist/tools/search-channels.d.ts.map +1 -0
- package/dist/tools/search-channels.js +56 -0
- package/dist/tools/search-channels.js.map +1 -0
- package/dist/tools.json +1492 -0
- package/dist/twitch-api.d.ts +6 -0
- package/dist/twitch-api.d.ts.map +1 -0
- package/dist/twitch-api.js +90 -0
- package/dist/twitch-api.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const getUserClips: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
|
|
3
|
+
login: z.ZodString;
|
|
4
|
+
period: z.ZodOptional<z.ZodEnum<{
|
|
5
|
+
LAST_DAY: "LAST_DAY";
|
|
6
|
+
LAST_WEEK: "LAST_WEEK";
|
|
7
|
+
LAST_MONTH: "LAST_MONTH";
|
|
8
|
+
ALL_TIME: "ALL_TIME";
|
|
9
|
+
}>>;
|
|
10
|
+
first: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
clips: z.ZodArray<z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
slug: z.ZodString;
|
|
15
|
+
title: z.ZodString;
|
|
16
|
+
viewCount: z.ZodNumber;
|
|
17
|
+
createdAt: z.ZodString;
|
|
18
|
+
thumbnailURL: z.ZodString;
|
|
19
|
+
durationSeconds: z.ZodNumber;
|
|
20
|
+
broadcaster: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
login: z.ZodString;
|
|
23
|
+
displayName: z.ZodString;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
game: z.ZodObject<{
|
|
26
|
+
id: z.ZodString;
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
//# sourceMappingURL=get-user-clips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-clips.d.ts","sourceRoot":"","sources":["../../src/tools/get-user-clips.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAwCvB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { defineTool, ToolError } from '@opentabs-dev/plugin-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { gql } from '../twitch-api.js';
|
|
4
|
+
import { clipSchema, mapClip } from './schemas.js';
|
|
5
|
+
export const getUserClips = defineTool({
|
|
6
|
+
name: 'get_user_clips',
|
|
7
|
+
displayName: 'Get User Clips',
|
|
8
|
+
description: 'Get clips from a Twitch channel sorted by view count. Provide the broadcaster login name and optionally filter by time period.',
|
|
9
|
+
summary: 'Get clips from a Twitch channel',
|
|
10
|
+
icon: 'clapperboard',
|
|
11
|
+
group: 'Clips',
|
|
12
|
+
input: z.object({
|
|
13
|
+
login: z.string().describe('Broadcaster login name (e.g., "shroud")'),
|
|
14
|
+
period: z
|
|
15
|
+
.enum(['LAST_DAY', 'LAST_WEEK', 'LAST_MONTH', 'ALL_TIME'])
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Time period filter (default ALL_TIME)'),
|
|
18
|
+
first: z.number().int().min(1).max(25).optional().describe('Number of clips to return (default 10, max 25)'),
|
|
19
|
+
}),
|
|
20
|
+
output: z.object({ clips: z.array(clipSchema) }),
|
|
21
|
+
handle: async (params) => {
|
|
22
|
+
const first = params.first ?? 10;
|
|
23
|
+
const period = params.period ?? 'ALL_TIME';
|
|
24
|
+
const data = await gql(`{
|
|
25
|
+
user(login: "${params.login}") {
|
|
26
|
+
clips(first: ${first}, criteria: { period: ${period} }) {
|
|
27
|
+
edges {
|
|
28
|
+
node {
|
|
29
|
+
id slug title viewCount createdAt thumbnailURL durationSeconds
|
|
30
|
+
broadcaster { id login displayName }
|
|
31
|
+
game { id name }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}`);
|
|
37
|
+
if (!data.user)
|
|
38
|
+
throw ToolError.notFound(`User "${params.login}" not found`);
|
|
39
|
+
return {
|
|
40
|
+
clips: (data.user.clips?.edges ?? []).map(e => mapClip(e.node)),
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=get-user-clips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-clips.js","sourceRoot":"","sources":["../../src/tools/get-user-clips.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGnD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,gBAAgB;IAC7B,WAAW,EACT,gIAAgI;IAClI,OAAO,EAAE,iCAAiC;IAC1C,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACrE,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;aACzD,QAAQ,EAAE;aACV,QAAQ,CAAC,uCAAuC,CAAC;QACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;KAC7G,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;IAChD,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,GAAG,CAEnB;qBACc,MAAM,CAAC,KAAK;uBACV,KAAK,yBAAyB,MAAM;;;;;;;;;;MAUrD,CAAC,CAAC;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,SAAS,MAAM,CAAC,KAAK,aAAa,CAAC,CAAC;QAC7E,OAAO;YACL,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAChE,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const getUserProfile: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
|
|
3
|
+
login: z.ZodString;
|
|
4
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
5
|
+
user: z.ZodObject<{
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
login: z.ZodString;
|
|
8
|
+
displayName: z.ZodString;
|
|
9
|
+
profileImageURL: z.ZodString;
|
|
10
|
+
description: z.ZodString;
|
|
11
|
+
createdAt: z.ZodString;
|
|
12
|
+
hasPrime: z.ZodBoolean;
|
|
13
|
+
roles: z.ZodObject<{
|
|
14
|
+
isPartner: z.ZodBoolean;
|
|
15
|
+
isAffiliate: z.ZodBoolean;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
followerCount: z.ZodNumber;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
}, z.core.$strip>>;
|
|
20
|
+
//# sourceMappingURL=get-user-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-profile.d.ts","sourceRoot":"","sources":["../../src/tools/get-user-profile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;kBAyBzB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineTool, ToolError } from '@opentabs-dev/plugin-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { gql } from '../twitch-api.js';
|
|
4
|
+
import { userSchema, mapUser } from './schemas.js';
|
|
5
|
+
export const getUserProfile = defineTool({
|
|
6
|
+
name: 'get_user_profile',
|
|
7
|
+
displayName: 'Get User Profile',
|
|
8
|
+
description: 'Get a Twitch user profile by their login name. Returns display name, bio, follower count, partner/affiliate status, profile image, and account creation date.',
|
|
9
|
+
summary: 'Get a Twitch user profile by login name',
|
|
10
|
+
icon: 'user',
|
|
11
|
+
group: 'Users',
|
|
12
|
+
input: z.object({
|
|
13
|
+
login: z.string().describe('Twitch login name (e.g., "shroud", "ninja")'),
|
|
14
|
+
}),
|
|
15
|
+
output: z.object({ user: userSchema }),
|
|
16
|
+
handle: async (params) => {
|
|
17
|
+
const data = await gql(`{
|
|
18
|
+
user(login: "${params.login.replace(/"/g, '\\"')}") {
|
|
19
|
+
id login displayName description
|
|
20
|
+
profileImageURL(width: 300)
|
|
21
|
+
createdAt
|
|
22
|
+
roles { isPartner isAffiliate }
|
|
23
|
+
followers { totalCount }
|
|
24
|
+
}
|
|
25
|
+
}`);
|
|
26
|
+
if (!data.user)
|
|
27
|
+
throw ToolError.notFound(`User "${params.login}" not found`);
|
|
28
|
+
return { user: mapUser(data.user) };
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=get-user-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-profile.js","sourceRoot":"","sources":["../../src/tools/get-user-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGnD,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;IACvC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,kBAAkB;IAC/B,WAAW,EACT,+JAA+J;IACjK,OAAO,EAAE,yCAAyC;IAClD,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;KAC1E,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACtC,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,IAAI,GAAG,MAAM,GAAG,CAA2B;qBAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;;;;;;;MAOhD,CAAC,CAAC;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,SAAS,MAAM,CAAC,KAAK,aAAa,CAAC,CAAC;QAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const getUserVideos: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
|
|
3
|
+
login: z.ZodString;
|
|
4
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
5
|
+
ARCHIVE: "ARCHIVE";
|
|
6
|
+
HIGHLIGHT: "HIGHLIGHT";
|
|
7
|
+
UPLOAD: "UPLOAD";
|
|
8
|
+
PAST_PREMIERE: "PAST_PREMIERE";
|
|
9
|
+
}>>;
|
|
10
|
+
sort: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
TIME: "TIME";
|
|
12
|
+
VIEWS: "VIEWS";
|
|
13
|
+
}>>;
|
|
14
|
+
first: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
16
|
+
videos: z.ZodArray<z.ZodObject<{
|
|
17
|
+
id: z.ZodString;
|
|
18
|
+
title: z.ZodString;
|
|
19
|
+
viewCount: z.ZodNumber;
|
|
20
|
+
publishedAt: z.ZodString;
|
|
21
|
+
lengthSeconds: z.ZodNumber;
|
|
22
|
+
game: z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
name: z.ZodString;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
thumbnailURL: z.ZodString;
|
|
27
|
+
}, z.core.$strip>>;
|
|
28
|
+
totalCount: z.ZodNumber;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
//# sourceMappingURL=get-user-videos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-videos.d.ts","sourceRoot":"","sources":["../../src/tools/get-user-videos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyDxB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { defineTool, ToolError } from '@opentabs-dev/plugin-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { gql } from '../twitch-api.js';
|
|
4
|
+
import { videoSchema, mapVideo } from './schemas.js';
|
|
5
|
+
export const getUserVideos = defineTool({
|
|
6
|
+
name: 'get_user_videos',
|
|
7
|
+
displayName: 'Get User Videos',
|
|
8
|
+
description: 'Get videos (VODs, highlights, uploads) from a Twitch channel. Optionally filter by video type and sort order.',
|
|
9
|
+
summary: 'Get videos from a Twitch channel',
|
|
10
|
+
icon: 'video',
|
|
11
|
+
group: 'Videos',
|
|
12
|
+
input: z.object({
|
|
13
|
+
login: z.string().describe('Broadcaster login name (e.g., "shroud")'),
|
|
14
|
+
type: z
|
|
15
|
+
.enum(['ARCHIVE', 'HIGHLIGHT', 'UPLOAD', 'PAST_PREMIERE'])
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Video type filter (default: all types)'),
|
|
18
|
+
sort: z.enum(['TIME', 'VIEWS']).optional().describe('Sort order (default TIME — most recent first)'),
|
|
19
|
+
first: z.number().int().min(1).max(25).optional().describe('Number of videos to return (default 10, max 25)'),
|
|
20
|
+
}),
|
|
21
|
+
output: z.object({
|
|
22
|
+
videos: z.array(videoSchema),
|
|
23
|
+
totalCount: z.number().describe('Total number of videos available'),
|
|
24
|
+
}),
|
|
25
|
+
handle: async (params) => {
|
|
26
|
+
const first = params.first ?? 10;
|
|
27
|
+
const sort = params.sort ?? 'TIME';
|
|
28
|
+
const typeArg = params.type ? `, type: ${params.type}` : '';
|
|
29
|
+
const data = await gql(`{
|
|
30
|
+
user(login: "${params.login}") {
|
|
31
|
+
videos(first: ${first}, sort: ${sort}${typeArg}) {
|
|
32
|
+
totalCount
|
|
33
|
+
edges {
|
|
34
|
+
node {
|
|
35
|
+
id title viewCount publishedAt lengthSeconds
|
|
36
|
+
game { id name }
|
|
37
|
+
thumbnailURLs(width: 320, height: 180)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}`);
|
|
43
|
+
if (!data.user)
|
|
44
|
+
throw ToolError.notFound(`User "${params.login}" not found`);
|
|
45
|
+
const edges = data.user.videos?.edges ?? [];
|
|
46
|
+
return {
|
|
47
|
+
videos: edges.map(e => {
|
|
48
|
+
const node = e.node;
|
|
49
|
+
return mapVideo({
|
|
50
|
+
...node,
|
|
51
|
+
thumbnailURL: node.thumbnailURLs?.[0] ?? '',
|
|
52
|
+
});
|
|
53
|
+
}),
|
|
54
|
+
totalCount: data.user.videos?.totalCount ?? 0,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=get-user-videos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-user-videos.js","sourceRoot":"","sources":["../../src/tools/get-user-videos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;IACtC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,iBAAiB;IAC9B,WAAW,EACT,+GAA+G;IACjH,OAAO,EAAE,kCAAkC;IAC3C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACrE,IAAI,EAAE,CAAC;aACJ,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;aACzD,QAAQ,EAAE;aACV,QAAQ,CAAC,wCAAwC,CAAC;QACrD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACpG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;KAC9G,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KACpE,CAAC;IACF,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,GAAG,CAEnB;qBACc,MAAM,CAAC,KAAK;wBACT,KAAK,WAAW,IAAI,GAAG,OAAO;;;;;;;;;;;MAWhD,CAAC,CAAC;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,SAAS,MAAM,CAAC,KAAK,aAAa,CAAC,CAAC;QAI7E,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBACpB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAoB,CAAC;gBACpC,OAAO,QAAQ,CAAC;oBACd,GAAG,IAAI;oBACP,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;iBAC5C,CAAC,CAAC;YACL,CAAC,CAAC;YACF,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC;SAC9C,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const getVideo: import("@opentabs-dev/plugin-sdk").ToolDefinition<z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
5
|
+
video: z.ZodObject<{
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
title: z.ZodString;
|
|
8
|
+
viewCount: z.ZodNumber;
|
|
9
|
+
publishedAt: z.ZodString;
|
|
10
|
+
lengthSeconds: z.ZodNumber;
|
|
11
|
+
game: z.ZodObject<{
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
thumbnailURL: z.ZodString;
|
|
16
|
+
broadcaster: z.ZodObject<{
|
|
17
|
+
id: z.ZodString;
|
|
18
|
+
login: z.ZodString;
|
|
19
|
+
displayName: z.ZodString;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
//# sourceMappingURL=get-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-video.d.ts","sourceRoot":"","sources":["../../src/tools/get-video.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;kBAgDnB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { defineTool, ToolError } from '@opentabs-dev/plugin-sdk';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { gql } from '../twitch-api.js';
|
|
4
|
+
import { videoSchema, mapVideo } from './schemas.js';
|
|
5
|
+
export const getVideo = defineTool({
|
|
6
|
+
name: 'get_video',
|
|
7
|
+
displayName: 'Get Video',
|
|
8
|
+
description: 'Get details about a specific Twitch video by its ID. Returns title, view count, duration, game, and broadcaster info.',
|
|
9
|
+
summary: 'Get details about a specific video',
|
|
10
|
+
icon: 'video',
|
|
11
|
+
group: 'Videos',
|
|
12
|
+
input: z.object({
|
|
13
|
+
id: z.string().describe('Video ID (e.g., "2717949378")'),
|
|
14
|
+
}),
|
|
15
|
+
output: z.object({
|
|
16
|
+
video: videoSchema.extend({
|
|
17
|
+
broadcaster: z
|
|
18
|
+
.object({
|
|
19
|
+
id: z.string().describe('Broadcaster user ID'),
|
|
20
|
+
login: z.string().describe('Broadcaster login name'),
|
|
21
|
+
displayName: z.string().describe('Broadcaster display name'),
|
|
22
|
+
})
|
|
23
|
+
.describe('Video broadcaster'),
|
|
24
|
+
}),
|
|
25
|
+
}),
|
|
26
|
+
handle: async (params) => {
|
|
27
|
+
const data = await gql(`{
|
|
28
|
+
video(id: "${params.id}") {
|
|
29
|
+
id title viewCount publishedAt lengthSeconds
|
|
30
|
+
game { id name }
|
|
31
|
+
thumbnailURLs(width: 320, height: 180)
|
|
32
|
+
owner { id login displayName }
|
|
33
|
+
}
|
|
34
|
+
}`);
|
|
35
|
+
if (!data.video)
|
|
36
|
+
throw ToolError.notFound(`Video "${params.id}" not found`);
|
|
37
|
+
const v = data.video;
|
|
38
|
+
return {
|
|
39
|
+
video: {
|
|
40
|
+
...mapVideo({ ...v, thumbnailURL: v.thumbnailURLs?.[0] ?? '' }),
|
|
41
|
+
broadcaster: {
|
|
42
|
+
id: v.owner?.id ?? '',
|
|
43
|
+
login: v.owner?.login ?? '',
|
|
44
|
+
displayName: v.owner?.displayName ?? '',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=get-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-video.js","sourceRoot":"","sources":["../../src/tools/get-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,WAAW;IACxB,WAAW,EACT,uHAAuH;IACzH,OAAO,EAAE,oCAAoC;IAC7C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;KACzD,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;YACxB,WAAW,EAAE,CAAC;iBACX,MAAM,CAAC;gBACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;gBAC9C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;gBACpD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;aAC7D,CAAC;iBACD,QAAQ,CAAC,mBAAmB,CAAC;SACjC,CAAC;KACH,CAAC;IACF,MAAM,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QAKrB,MAAM,IAAI,GAAG,MAAM,GAAG,CAA4C;mBACnD,MAAM,CAAC,EAAE;;;;;;MAMtB,CAAC,CAAC;QACJ,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,UAAU,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC;QAC5E,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACrB,OAAO;YACL,KAAK,EAAE;gBACL,GAAG,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC/D,WAAW,EAAE;oBACX,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE;oBACrB,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;oBAC3B,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE;iBACxC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const userSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
login: z.ZodString;
|
|
5
|
+
displayName: z.ZodString;
|
|
6
|
+
profileImageURL: z.ZodString;
|
|
7
|
+
description: z.ZodString;
|
|
8
|
+
createdAt: z.ZodString;
|
|
9
|
+
hasPrime: z.ZodBoolean;
|
|
10
|
+
roles: z.ZodObject<{
|
|
11
|
+
isPartner: z.ZodBoolean;
|
|
12
|
+
isAffiliate: z.ZodBoolean;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
followerCount: z.ZodNumber;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type User = z.infer<typeof userSchema>;
|
|
17
|
+
export interface RawUser {
|
|
18
|
+
id?: string;
|
|
19
|
+
login?: string;
|
|
20
|
+
displayName?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
profileImageURL?: string;
|
|
23
|
+
createdAt?: string;
|
|
24
|
+
hasPrime?: boolean;
|
|
25
|
+
roles?: {
|
|
26
|
+
isPartner?: boolean;
|
|
27
|
+
isAffiliate?: boolean;
|
|
28
|
+
};
|
|
29
|
+
followers?: {
|
|
30
|
+
totalCount?: number;
|
|
31
|
+
};
|
|
32
|
+
followerCount?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function mapUser(raw: RawUser): User;
|
|
35
|
+
export declare const streamSchema: z.ZodObject<{
|
|
36
|
+
id: z.ZodString;
|
|
37
|
+
title: z.ZodString;
|
|
38
|
+
viewersCount: z.ZodNumber;
|
|
39
|
+
type: z.ZodString;
|
|
40
|
+
createdAt: z.ZodString;
|
|
41
|
+
broadcaster: z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
login: z.ZodString;
|
|
44
|
+
displayName: z.ZodString;
|
|
45
|
+
profileImageURL: z.ZodString;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
game: z.ZodObject<{
|
|
48
|
+
id: z.ZodString;
|
|
49
|
+
name: z.ZodString;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type Stream = z.infer<typeof streamSchema>;
|
|
53
|
+
export interface RawStream {
|
|
54
|
+
id?: string;
|
|
55
|
+
title?: string;
|
|
56
|
+
viewersCount?: number;
|
|
57
|
+
type?: string;
|
|
58
|
+
createdAt?: string;
|
|
59
|
+
broadcaster?: {
|
|
60
|
+
id?: string;
|
|
61
|
+
login?: string;
|
|
62
|
+
displayName?: string;
|
|
63
|
+
profileImageURL?: string;
|
|
64
|
+
};
|
|
65
|
+
game?: {
|
|
66
|
+
id?: string;
|
|
67
|
+
name?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export declare function mapStream(raw: RawStream): Stream;
|
|
71
|
+
export declare const gameSchema: z.ZodObject<{
|
|
72
|
+
id: z.ZodString;
|
|
73
|
+
name: z.ZodString;
|
|
74
|
+
displayName: z.ZodString;
|
|
75
|
+
viewersCount: z.ZodNumber;
|
|
76
|
+
broadcastersCount: z.ZodNumber;
|
|
77
|
+
boxArtURL: z.ZodString;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
export type Game = z.infer<typeof gameSchema>;
|
|
80
|
+
export interface RawGame {
|
|
81
|
+
id?: string;
|
|
82
|
+
name?: string;
|
|
83
|
+
displayName?: string;
|
|
84
|
+
viewersCount?: number;
|
|
85
|
+
broadcastersCount?: number;
|
|
86
|
+
boxArtURL?: string;
|
|
87
|
+
}
|
|
88
|
+
export declare function mapGame(raw: RawGame): Game;
|
|
89
|
+
export declare const clipSchema: z.ZodObject<{
|
|
90
|
+
id: z.ZodString;
|
|
91
|
+
slug: z.ZodString;
|
|
92
|
+
title: z.ZodString;
|
|
93
|
+
viewCount: z.ZodNumber;
|
|
94
|
+
createdAt: z.ZodString;
|
|
95
|
+
thumbnailURL: z.ZodString;
|
|
96
|
+
durationSeconds: z.ZodNumber;
|
|
97
|
+
broadcaster: z.ZodObject<{
|
|
98
|
+
id: z.ZodString;
|
|
99
|
+
login: z.ZodString;
|
|
100
|
+
displayName: z.ZodString;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
game: z.ZodObject<{
|
|
103
|
+
id: z.ZodString;
|
|
104
|
+
name: z.ZodString;
|
|
105
|
+
}, z.core.$strip>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
export type Clip = z.infer<typeof clipSchema>;
|
|
108
|
+
export interface RawClip {
|
|
109
|
+
id?: string;
|
|
110
|
+
slug?: string;
|
|
111
|
+
title?: string;
|
|
112
|
+
viewCount?: number;
|
|
113
|
+
createdAt?: string;
|
|
114
|
+
thumbnailURL?: string;
|
|
115
|
+
durationSeconds?: number;
|
|
116
|
+
broadcaster?: {
|
|
117
|
+
id?: string;
|
|
118
|
+
login?: string;
|
|
119
|
+
displayName?: string;
|
|
120
|
+
};
|
|
121
|
+
game?: {
|
|
122
|
+
id?: string;
|
|
123
|
+
name?: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export declare function mapClip(raw: RawClip): Clip;
|
|
127
|
+
export declare const videoSchema: z.ZodObject<{
|
|
128
|
+
id: z.ZodString;
|
|
129
|
+
title: z.ZodString;
|
|
130
|
+
viewCount: z.ZodNumber;
|
|
131
|
+
publishedAt: z.ZodString;
|
|
132
|
+
lengthSeconds: z.ZodNumber;
|
|
133
|
+
game: z.ZodObject<{
|
|
134
|
+
id: z.ZodString;
|
|
135
|
+
name: z.ZodString;
|
|
136
|
+
}, z.core.$strip>;
|
|
137
|
+
thumbnailURL: z.ZodString;
|
|
138
|
+
}, z.core.$strip>;
|
|
139
|
+
export type Video = z.infer<typeof videoSchema>;
|
|
140
|
+
export interface RawVideo {
|
|
141
|
+
id?: string;
|
|
142
|
+
title?: string;
|
|
143
|
+
viewCount?: number;
|
|
144
|
+
publishedAt?: string;
|
|
145
|
+
lengthSeconds?: number;
|
|
146
|
+
game?: {
|
|
147
|
+
id?: string;
|
|
148
|
+
name?: string;
|
|
149
|
+
};
|
|
150
|
+
thumbnailURL?: string;
|
|
151
|
+
}
|
|
152
|
+
export declare function mapVideo(raw: RawVideo): Video;
|
|
153
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Shared fragments
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const userRefSchema = z.object({
|
|
6
|
+
id: z.string().describe('Twitch user ID'),
|
|
7
|
+
login: z.string().describe('Twitch login name (lowercase, URL-safe)'),
|
|
8
|
+
displayName: z.string().describe('User display name'),
|
|
9
|
+
profileImageURL: z.string().describe("URL of the user's profile image"),
|
|
10
|
+
});
|
|
11
|
+
const gameRefSchema = z.object({
|
|
12
|
+
id: z.string().describe('Game/category ID'),
|
|
13
|
+
name: z.string().describe('Game/category name'),
|
|
14
|
+
});
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// User
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const userRolesSchema = z.object({
|
|
19
|
+
isPartner: z.boolean().describe('Whether the user is a Twitch Partner'),
|
|
20
|
+
isAffiliate: z.boolean().describe('Whether the user is a Twitch Affiliate'),
|
|
21
|
+
});
|
|
22
|
+
export const userSchema = userRefSchema.extend({
|
|
23
|
+
description: z.string().describe('User bio / channel description'),
|
|
24
|
+
createdAt: z.string().describe('ISO 8601 timestamp of account creation'),
|
|
25
|
+
hasPrime: z.boolean().describe('Whether the user has Twitch Prime'),
|
|
26
|
+
roles: userRolesSchema.describe('Partner and Affiliate status'),
|
|
27
|
+
followerCount: z.number().describe('Total number of followers'),
|
|
28
|
+
});
|
|
29
|
+
export function mapUser(raw) {
|
|
30
|
+
return {
|
|
31
|
+
id: raw.id ?? '',
|
|
32
|
+
login: raw.login ?? '',
|
|
33
|
+
displayName: raw.displayName ?? '',
|
|
34
|
+
description: raw.description ?? '',
|
|
35
|
+
profileImageURL: raw.profileImageURL ?? '',
|
|
36
|
+
createdAt: raw.createdAt ?? '',
|
|
37
|
+
hasPrime: raw.hasPrime ?? false,
|
|
38
|
+
roles: {
|
|
39
|
+
isPartner: raw.roles?.isPartner ?? false,
|
|
40
|
+
isAffiliate: raw.roles?.isAffiliate ?? false,
|
|
41
|
+
},
|
|
42
|
+
followerCount: raw.followers?.totalCount ?? raw.followerCount ?? 0,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Stream
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
export const streamSchema = z.object({
|
|
49
|
+
id: z.string().describe('Stream ID'),
|
|
50
|
+
title: z.string().describe('Stream title'),
|
|
51
|
+
viewersCount: z.number().describe('Current number of viewers'),
|
|
52
|
+
type: z.string().describe('Stream type (e.g. "live")'),
|
|
53
|
+
createdAt: z.string().describe('ISO 8601 timestamp when the stream started'),
|
|
54
|
+
broadcaster: userRefSchema.describe('Broadcaster info'),
|
|
55
|
+
game: gameRefSchema.describe('Game/category being streamed'),
|
|
56
|
+
});
|
|
57
|
+
export function mapStream(raw) {
|
|
58
|
+
return {
|
|
59
|
+
id: raw.id ?? '',
|
|
60
|
+
title: raw.title ?? '',
|
|
61
|
+
viewersCount: raw.viewersCount ?? 0,
|
|
62
|
+
type: raw.type ?? '',
|
|
63
|
+
createdAt: raw.createdAt ?? '',
|
|
64
|
+
broadcaster: {
|
|
65
|
+
id: raw.broadcaster?.id ?? '',
|
|
66
|
+
login: raw.broadcaster?.login ?? '',
|
|
67
|
+
displayName: raw.broadcaster?.displayName ?? '',
|
|
68
|
+
profileImageURL: raw.broadcaster?.profileImageURL ?? '',
|
|
69
|
+
},
|
|
70
|
+
game: {
|
|
71
|
+
id: raw.game?.id ?? '',
|
|
72
|
+
name: raw.game?.name ?? '',
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Game
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
export const gameSchema = gameRefSchema.extend({
|
|
80
|
+
displayName: z.string().describe('Localized display name for the game'),
|
|
81
|
+
viewersCount: z.number().describe('Total viewers across all streams'),
|
|
82
|
+
broadcastersCount: z.number().describe('Number of channels currently streaming this game'),
|
|
83
|
+
boxArtURL: z.string().describe('URL of the game box art image'),
|
|
84
|
+
});
|
|
85
|
+
export function mapGame(raw) {
|
|
86
|
+
return {
|
|
87
|
+
id: raw.id ?? '',
|
|
88
|
+
name: raw.name ?? '',
|
|
89
|
+
displayName: raw.displayName ?? raw.name ?? '',
|
|
90
|
+
viewersCount: raw.viewersCount ?? 0,
|
|
91
|
+
broadcastersCount: raw.broadcastersCount ?? 0,
|
|
92
|
+
boxArtURL: raw.boxArtURL ?? '',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Clip
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
const broadcasterRefSchema = z.object({
|
|
99
|
+
id: z.string().describe('Broadcaster user ID'),
|
|
100
|
+
login: z.string().describe('Broadcaster login name'),
|
|
101
|
+
displayName: z.string().describe('Broadcaster display name'),
|
|
102
|
+
});
|
|
103
|
+
export const clipSchema = z.object({
|
|
104
|
+
id: z.string().describe('Clip ID'),
|
|
105
|
+
slug: z.string().describe('URL-safe slug for the clip'),
|
|
106
|
+
title: z.string().describe('Clip title'),
|
|
107
|
+
viewCount: z.number().describe('Total number of views'),
|
|
108
|
+
createdAt: z.string().describe('ISO 8601 timestamp when the clip was created'),
|
|
109
|
+
thumbnailURL: z.string().describe('URL of the clip thumbnail image'),
|
|
110
|
+
durationSeconds: z.number().describe('Clip duration in seconds'),
|
|
111
|
+
broadcaster: broadcasterRefSchema.describe('Broadcaster who was clipped'),
|
|
112
|
+
game: gameRefSchema.describe('Game/category at the time of the clip'),
|
|
113
|
+
});
|
|
114
|
+
export function mapClip(raw) {
|
|
115
|
+
return {
|
|
116
|
+
id: raw.id ?? '',
|
|
117
|
+
slug: raw.slug ?? '',
|
|
118
|
+
title: raw.title ?? '',
|
|
119
|
+
viewCount: raw.viewCount ?? 0,
|
|
120
|
+
createdAt: raw.createdAt ?? '',
|
|
121
|
+
thumbnailURL: raw.thumbnailURL ?? '',
|
|
122
|
+
durationSeconds: raw.durationSeconds ?? 0,
|
|
123
|
+
broadcaster: {
|
|
124
|
+
id: raw.broadcaster?.id ?? '',
|
|
125
|
+
login: raw.broadcaster?.login ?? '',
|
|
126
|
+
displayName: raw.broadcaster?.displayName ?? '',
|
|
127
|
+
},
|
|
128
|
+
game: {
|
|
129
|
+
id: raw.game?.id ?? '',
|
|
130
|
+
name: raw.game?.name ?? '',
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Video
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
export const videoSchema = z.object({
|
|
138
|
+
id: z.string().describe('Video ID'),
|
|
139
|
+
title: z.string().describe('Video title'),
|
|
140
|
+
viewCount: z.number().describe('Total number of views'),
|
|
141
|
+
publishedAt: z.string().describe('ISO 8601 timestamp when the video was published'),
|
|
142
|
+
lengthSeconds: z.number().describe('Video duration in seconds'),
|
|
143
|
+
game: gameRefSchema.describe('Game/category associated with the video'),
|
|
144
|
+
thumbnailURL: z.string().describe('URL of the video thumbnail image'),
|
|
145
|
+
});
|
|
146
|
+
export function mapVideo(raw) {
|
|
147
|
+
return {
|
|
148
|
+
id: raw.id ?? '',
|
|
149
|
+
title: raw.title ?? '',
|
|
150
|
+
viewCount: raw.viewCount ?? 0,
|
|
151
|
+
publishedAt: raw.publishedAt ?? '',
|
|
152
|
+
lengthSeconds: raw.lengthSeconds ?? 0,
|
|
153
|
+
game: {
|
|
154
|
+
id: raw.game?.id ?? '',
|
|
155
|
+
name: raw.game?.name ?? '',
|
|
156
|
+
},
|
|
157
|
+
thumbnailURL: raw.thumbnailURL ?? '',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=schemas.js.map
|