stophy 0.1.1 → 0.2.1
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 +25 -18
- package/dist/index.cjs +180 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +253 -195
- package/dist/index.d.ts +253 -195
- package/dist/index.js +180 -85
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ type ErrorResponse = {
|
|
|
8
8
|
/**
|
|
9
9
|
* Machine-readable error code.
|
|
10
10
|
*/
|
|
11
|
-
code?:
|
|
11
|
+
code?: "UNAUTHORIZED" | "INSUFFICIENT_CREDITS" | "BAD_REQUEST" | "INVALID_INPUT" | "NOT_FOUND" | "CONCURRENCY_LIMITED" | "UPSTREAM_UNAVAILABLE" | "INTERNAL_ERROR";
|
|
12
12
|
/**
|
|
13
13
|
* Human-readable error message.
|
|
14
14
|
*/
|
|
@@ -45,37 +45,37 @@ type TranscriptResult = {
|
|
|
45
45
|
};
|
|
46
46
|
type VideoDetails = {
|
|
47
47
|
id: string;
|
|
48
|
-
type
|
|
48
|
+
type: "video";
|
|
49
49
|
videoUrl: string;
|
|
50
50
|
title: string | null;
|
|
51
|
-
author
|
|
52
|
-
authorId
|
|
53
|
-
category
|
|
54
|
-
description
|
|
55
|
-
durationSec
|
|
56
|
-
durationText
|
|
57
|
-
isLive
|
|
58
|
-
likeCount
|
|
59
|
-
likeCountText
|
|
60
|
-
publishedAt
|
|
61
|
-
tags
|
|
62
|
-
viewCount
|
|
63
|
-
viewCountText
|
|
51
|
+
author: string | null;
|
|
52
|
+
authorId: string | null;
|
|
53
|
+
category: string | null;
|
|
54
|
+
description: string | null;
|
|
55
|
+
durationSec: number | null;
|
|
56
|
+
durationText: string | null;
|
|
57
|
+
isLive: boolean;
|
|
58
|
+
likeCount: number | null;
|
|
59
|
+
likeCountText: string | null;
|
|
60
|
+
publishedAt: string | null;
|
|
61
|
+
tags: Array<string>;
|
|
62
|
+
viewCount: number | null;
|
|
63
|
+
viewCountText: string | null;
|
|
64
64
|
thumbnails: Array<Thumbnail>;
|
|
65
65
|
};
|
|
66
66
|
type RelatedVideo = {
|
|
67
67
|
id: string;
|
|
68
|
-
type
|
|
68
|
+
type: "video";
|
|
69
69
|
videoUrl: string;
|
|
70
|
-
title
|
|
71
|
-
author
|
|
72
|
-
authorId
|
|
73
|
-
durationSec
|
|
74
|
-
durationText
|
|
75
|
-
publishedAt
|
|
76
|
-
publishedAtText
|
|
77
|
-
viewCount
|
|
78
|
-
viewCountText
|
|
70
|
+
title: string | null;
|
|
71
|
+
author: string | null;
|
|
72
|
+
authorId: string | null;
|
|
73
|
+
durationSec: number | null;
|
|
74
|
+
durationText: string | null;
|
|
75
|
+
publishedAt: string | null;
|
|
76
|
+
publishedAtText: string | null;
|
|
77
|
+
viewCount: number | null;
|
|
78
|
+
viewCountText: string | null;
|
|
79
79
|
thumbnails: Array<Thumbnail>;
|
|
80
80
|
};
|
|
81
81
|
type VideoDetailsData = {
|
|
@@ -87,21 +87,29 @@ type Comment = {
|
|
|
87
87
|
text: string | null;
|
|
88
88
|
author: string | null;
|
|
89
89
|
authorId: string | null;
|
|
90
|
-
authorThumbnail
|
|
90
|
+
authorThumbnail: string | null;
|
|
91
91
|
hasChannelOwnerReplied: boolean;
|
|
92
92
|
isChannelOwner: boolean;
|
|
93
93
|
isHearted: boolean;
|
|
94
94
|
isPinned: boolean;
|
|
95
95
|
isVerified: boolean;
|
|
96
|
-
publishedAt
|
|
97
|
-
publishedAtText
|
|
98
|
-
likeCount
|
|
99
|
-
likeCountText
|
|
100
|
-
replyCount
|
|
101
|
-
replyCountText
|
|
102
|
-
repliesToken
|
|
96
|
+
publishedAt: string | null;
|
|
97
|
+
publishedAtText: string | null;
|
|
98
|
+
likeCount: number | null;
|
|
99
|
+
likeCountText: string | null;
|
|
100
|
+
replyCount: number | null;
|
|
101
|
+
replyCountText: string | null;
|
|
102
|
+
repliesToken: string | null;
|
|
103
103
|
};
|
|
104
104
|
type CommentsData = {
|
|
105
|
+
/**
|
|
106
|
+
* Present for top-level comment requests.
|
|
107
|
+
*/
|
|
108
|
+
videoId?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Resolved sort order for top-level comment requests.
|
|
111
|
+
*/
|
|
112
|
+
sortBy?: "any" | "latest" | "top";
|
|
105
113
|
items: Array<Comment>;
|
|
106
114
|
continuationToken: string | null;
|
|
107
115
|
empty?: EmptyState;
|
|
@@ -109,20 +117,20 @@ type CommentsData = {
|
|
|
109
117
|
type LiveChatMessage = {
|
|
110
118
|
id: string;
|
|
111
119
|
text: string;
|
|
112
|
-
author
|
|
113
|
-
authorId
|
|
114
|
-
timestampUsec
|
|
120
|
+
author: string | null;
|
|
121
|
+
authorId: string | null;
|
|
122
|
+
timestampUsec: string | null;
|
|
115
123
|
isOwner: boolean;
|
|
116
124
|
isModerator: boolean;
|
|
117
125
|
isVerified: boolean;
|
|
118
|
-
superChatAmount
|
|
119
|
-
superChatCurrency
|
|
126
|
+
superChatAmount: string | null;
|
|
127
|
+
superChatCurrency: string | null;
|
|
120
128
|
};
|
|
121
129
|
type LiveChatData = {
|
|
122
|
-
status:
|
|
130
|
+
status: "live" | "upcoming" | "replay" | "chat_disabled" | "not_live";
|
|
123
131
|
isLive: boolean;
|
|
124
|
-
concurrentViewers
|
|
125
|
-
pollIntervalMs
|
|
132
|
+
concurrentViewers: number | null;
|
|
133
|
+
pollIntervalMs: number | null;
|
|
126
134
|
messages: Array<LiveChatMessage>;
|
|
127
135
|
continuationToken: string | null;
|
|
128
136
|
};
|
|
@@ -131,75 +139,76 @@ type LiveChatData = {
|
|
|
131
139
|
*/
|
|
132
140
|
type VideoData = VideoDetailsData | TranscriptResult | CommentsData | LiveChatData;
|
|
133
141
|
type SearchVideo = {
|
|
134
|
-
type:
|
|
142
|
+
type: "video";
|
|
135
143
|
id: string;
|
|
136
144
|
videoUrl: string;
|
|
137
145
|
title: string;
|
|
138
|
-
author
|
|
139
|
-
authorId
|
|
140
|
-
description
|
|
141
|
-
duration
|
|
142
|
-
durationSec
|
|
143
|
-
durationText
|
|
144
|
-
isLive
|
|
145
|
-
isUpcoming
|
|
146
|
-
isVerified
|
|
147
|
-
viewCount
|
|
148
|
-
viewCountText
|
|
149
|
-
publishedAt
|
|
150
|
-
publishedAtText
|
|
146
|
+
author: string | null;
|
|
147
|
+
authorId: string | null;
|
|
148
|
+
description: string | null;
|
|
149
|
+
duration: string | null;
|
|
150
|
+
durationSec: number | null;
|
|
151
|
+
durationText: string | null;
|
|
152
|
+
isLive: boolean;
|
|
153
|
+
isUpcoming: boolean;
|
|
154
|
+
isVerified: boolean;
|
|
155
|
+
viewCount: number | null;
|
|
156
|
+
viewCountText: string | null;
|
|
157
|
+
publishedAt: string | null;
|
|
158
|
+
publishedAtText: string | null;
|
|
151
159
|
thumbnails: Array<Thumbnail>;
|
|
152
160
|
};
|
|
153
161
|
type SearchShort = {
|
|
154
|
-
type:
|
|
162
|
+
type: "short";
|
|
155
163
|
id: string;
|
|
156
164
|
shortUrl: string;
|
|
157
165
|
title: string;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
description?: string | null;
|
|
161
|
-
duration?: string | null;
|
|
162
|
-
durationSec?: number | null;
|
|
163
|
-
durationText?: string | null;
|
|
164
|
-
viewCount?: number | null;
|
|
165
|
-
viewCountText?: string | null;
|
|
166
|
-
publishedAt?: string | null;
|
|
167
|
-
publishedAtText?: string | null;
|
|
166
|
+
viewCount: number | null;
|
|
167
|
+
viewCountText: string | null;
|
|
168
168
|
thumbnails: Array<Thumbnail>;
|
|
169
169
|
};
|
|
170
170
|
type SearchPlaylist = {
|
|
171
|
-
type:
|
|
171
|
+
type: "playlist";
|
|
172
172
|
id: string;
|
|
173
173
|
playlistUrl: string;
|
|
174
174
|
title: string;
|
|
175
|
-
author
|
|
176
|
-
authorId
|
|
177
|
-
videoCount
|
|
178
|
-
videoCountText
|
|
175
|
+
author: string | null;
|
|
176
|
+
authorId: string | null;
|
|
177
|
+
videoCount: number | null;
|
|
178
|
+
videoCountText: string | null;
|
|
179
179
|
thumbnails: Array<Thumbnail>;
|
|
180
180
|
};
|
|
181
181
|
type SearchChannel = {
|
|
182
|
-
type:
|
|
182
|
+
type: "channel";
|
|
183
183
|
id: string;
|
|
184
184
|
channelUrl: string;
|
|
185
185
|
name: string;
|
|
186
|
-
handle
|
|
187
|
-
description
|
|
188
|
-
subscriberCount
|
|
189
|
-
subscriberCountText
|
|
190
|
-
isVerified
|
|
186
|
+
handle: string | null;
|
|
187
|
+
description: string | null;
|
|
188
|
+
subscriberCount: number | null;
|
|
189
|
+
subscriberCountText: string | null;
|
|
190
|
+
isVerified: boolean;
|
|
191
191
|
thumbnails: Array<Thumbnail>;
|
|
192
192
|
};
|
|
193
193
|
type SearchItem = ({
|
|
194
|
-
type?:
|
|
194
|
+
type?: "video";
|
|
195
195
|
} & SearchVideo) | ({
|
|
196
|
-
type?:
|
|
196
|
+
type?: "short";
|
|
197
197
|
} & SearchShort) | ({
|
|
198
|
-
type?:
|
|
198
|
+
type?: "playlist";
|
|
199
199
|
} & SearchPlaylist) | ({
|
|
200
|
-
type?:
|
|
200
|
+
type?: "channel";
|
|
201
201
|
} & SearchChannel);
|
|
202
|
+
type SearchQuery = {
|
|
203
|
+
q: string;
|
|
204
|
+
type?: "video" | "short" | "channel" | "playlist" | "movie";
|
|
205
|
+
sortBy?: "relevance" | "popularity" | "date" | "rating";
|
|
206
|
+
uploadDate?: "today" | "week" | "month" | "year";
|
|
207
|
+
duration?: "short" | "medium" | "long";
|
|
208
|
+
features?: Array<string>;
|
|
209
|
+
};
|
|
202
210
|
type SearchData = {
|
|
211
|
+
query: SearchQuery;
|
|
203
212
|
items: Array<SearchItem>;
|
|
204
213
|
continuationToken: string | null;
|
|
205
214
|
estimatedResults?: number;
|
|
@@ -214,11 +223,11 @@ type ChannelProfile = {
|
|
|
214
223
|
name: string | null;
|
|
215
224
|
handle: string | null;
|
|
216
225
|
channelUrl: string | null;
|
|
217
|
-
description
|
|
218
|
-
subscriberCount
|
|
219
|
-
subscriberCountText
|
|
220
|
-
videoCount
|
|
221
|
-
videoCountText
|
|
226
|
+
description: string | null;
|
|
227
|
+
subscriberCount: number | null;
|
|
228
|
+
subscriberCountText: string | null;
|
|
229
|
+
videoCount: number | null;
|
|
230
|
+
videoCountText: string | null;
|
|
222
231
|
viewCount?: number | null;
|
|
223
232
|
viewCountText?: string | null;
|
|
224
233
|
isVerified: boolean;
|
|
@@ -228,59 +237,90 @@ type ChannelProfile = {
|
|
|
228
237
|
banners: Array<Thumbnail>;
|
|
229
238
|
links?: Array<ChannelLink> | null;
|
|
230
239
|
};
|
|
231
|
-
type
|
|
240
|
+
type ChannelVideo = {
|
|
232
241
|
id: string;
|
|
233
|
-
type
|
|
234
|
-
title
|
|
235
|
-
videoUrl
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
type: "video";
|
|
243
|
+
title: string | null;
|
|
244
|
+
videoUrl: string;
|
|
245
|
+
author: string | null;
|
|
246
|
+
authorId: string | null;
|
|
247
|
+
duration: string | null;
|
|
248
|
+
durationSec: number | null;
|
|
249
|
+
durationText: string | null;
|
|
250
|
+
isLive: boolean;
|
|
251
|
+
isUpcoming: boolean;
|
|
252
|
+
upcomingAt: string | null;
|
|
253
|
+
viewCount: number | null;
|
|
254
|
+
viewCountText: string | null;
|
|
255
|
+
publishedAt: string | null;
|
|
256
|
+
publishedAtText: string | null;
|
|
257
|
+
thumbnails: Array<Thumbnail>;
|
|
258
|
+
};
|
|
259
|
+
type ChannelShort = {
|
|
260
|
+
id: string;
|
|
261
|
+
type: "short";
|
|
262
|
+
shortUrl: string;
|
|
263
|
+
title: string | null;
|
|
264
|
+
author: string | null;
|
|
265
|
+
authorId: string | null;
|
|
266
|
+
viewCount: number | null;
|
|
267
|
+
viewCountText: string | null;
|
|
268
|
+
thumbnails: Array<Thumbnail>;
|
|
269
|
+
};
|
|
270
|
+
type ChannelPlaylist = {
|
|
271
|
+
id: string;
|
|
272
|
+
type: "playlist";
|
|
273
|
+
playlistUrl: string;
|
|
274
|
+
title: string | null;
|
|
275
|
+
author: string | null;
|
|
276
|
+
authorId: string | null;
|
|
277
|
+
videoCount: string | null;
|
|
246
278
|
thumbnails: Array<Thumbnail>;
|
|
247
279
|
};
|
|
280
|
+
type ContentItem = ({
|
|
281
|
+
type?: "video";
|
|
282
|
+
} & ChannelVideo) | ({
|
|
283
|
+
type?: "short";
|
|
284
|
+
} & ChannelShort) | ({
|
|
285
|
+
type?: "playlist";
|
|
286
|
+
} & ChannelPlaylist);
|
|
248
287
|
type ChannelData = {
|
|
249
288
|
channel: ChannelProfile | null;
|
|
250
|
-
tab
|
|
289
|
+
tab: "video" | "short" | "playlist" | "about";
|
|
251
290
|
items?: Array<ContentItem>;
|
|
252
291
|
continuationToken?: string | null;
|
|
253
292
|
empty?: EmptyState;
|
|
254
293
|
};
|
|
255
294
|
type PlaylistMeta = {
|
|
256
295
|
id: string;
|
|
257
|
-
type
|
|
296
|
+
type: "playlist";
|
|
258
297
|
playlistUrl: string;
|
|
259
|
-
title
|
|
260
|
-
author
|
|
261
|
-
authorId
|
|
262
|
-
description
|
|
263
|
-
videoCount
|
|
298
|
+
title: string | null;
|
|
299
|
+
author: string | null;
|
|
300
|
+
authorId: string | null;
|
|
301
|
+
description: string | null;
|
|
302
|
+
videoCount: string | null;
|
|
264
303
|
thumbnails: Array<Thumbnail>;
|
|
265
304
|
};
|
|
266
305
|
type PlaylistItem = {
|
|
267
306
|
id: string;
|
|
268
|
-
type
|
|
307
|
+
type: "video";
|
|
269
308
|
videoUrl: string;
|
|
270
|
-
title
|
|
271
|
-
author
|
|
272
|
-
authorId
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
309
|
+
title: string | null;
|
|
310
|
+
author: string | null;
|
|
311
|
+
authorId: string | null;
|
|
312
|
+
duration: string | null;
|
|
313
|
+
durationSec: number | null;
|
|
314
|
+
durationText: string | null;
|
|
315
|
+
index: number | null;
|
|
316
|
+
isLive: boolean;
|
|
317
|
+
isPlayable: boolean;
|
|
318
|
+
isUpcoming: boolean;
|
|
319
|
+
upcomingAt: string | null;
|
|
320
|
+
viewCount: number | null;
|
|
321
|
+
viewCountText: string | null;
|
|
322
|
+
publishedAt: string | null;
|
|
323
|
+
publishedAtText: string | null;
|
|
284
324
|
thumbnails: Array<Thumbnail>;
|
|
285
325
|
};
|
|
286
326
|
type PlaylistData = {
|
|
@@ -332,27 +372,33 @@ type GetVideoData = {
|
|
|
332
372
|
/**
|
|
333
373
|
* The type of data to retrieve.
|
|
334
374
|
*/
|
|
335
|
-
type:
|
|
375
|
+
type: "details" | "transcript" | "comments" | "livechat";
|
|
336
376
|
/**
|
|
337
|
-
* Full YouTube video URL.
|
|
377
|
+
* Full YouTube video URL.
|
|
338
378
|
*/
|
|
339
379
|
videoUrl: string;
|
|
340
380
|
/**
|
|
341
381
|
* Comment sort order. Only applies when type is comments.
|
|
342
382
|
*/
|
|
343
|
-
sortBy?:
|
|
383
|
+
sortBy?: "latest" | "top";
|
|
344
384
|
/**
|
|
345
385
|
* Live chat mode. Only applies when type is livechat: 'top' = Top chat (moderated, default), 'live' = all messages. Applied on the first call; later polls keep the chosen mode.
|
|
346
386
|
*/
|
|
347
|
-
chatType?:
|
|
387
|
+
chatType?: "top" | "live";
|
|
348
388
|
/**
|
|
349
|
-
*
|
|
389
|
+
* For comments, pass a previous comments response token. For livechat, pass the previous livechat token to poll for new messages.
|
|
350
390
|
*/
|
|
351
391
|
continuationToken?: string;
|
|
392
|
+
} | {
|
|
393
|
+
type: "replies";
|
|
394
|
+
/**
|
|
395
|
+
* The repliesToken from a top-level comment.
|
|
396
|
+
*/
|
|
397
|
+
continuationToken: string;
|
|
352
398
|
};
|
|
353
399
|
path?: never;
|
|
354
400
|
query?: never;
|
|
355
|
-
url:
|
|
401
|
+
url: "/v1/video";
|
|
356
402
|
};
|
|
357
403
|
type GetVideoErrors = {
|
|
358
404
|
/**
|
|
@@ -367,6 +413,10 @@ type GetVideoErrors = {
|
|
|
367
413
|
* Insufficient credits
|
|
368
414
|
*/
|
|
369
415
|
402: ErrorResponse;
|
|
416
|
+
/**
|
|
417
|
+
* Video or captions not found
|
|
418
|
+
*/
|
|
419
|
+
404: ErrorResponse;
|
|
370
420
|
/**
|
|
371
421
|
* Rate limited
|
|
372
422
|
*/
|
|
@@ -375,6 +425,10 @@ type GetVideoErrors = {
|
|
|
375
425
|
* Internal error
|
|
376
426
|
*/
|
|
377
427
|
500: ErrorResponse;
|
|
428
|
+
/**
|
|
429
|
+
* Upstream video data temporarily unavailable
|
|
430
|
+
*/
|
|
431
|
+
503: ErrorResponse;
|
|
378
432
|
};
|
|
379
433
|
type GetVideoError = GetVideoErrors[keyof GetVideoErrors];
|
|
380
434
|
type GetVideoResponses = {
|
|
@@ -385,7 +439,7 @@ type GetVideoResponses = {
|
|
|
385
439
|
success: true;
|
|
386
440
|
requestId: string;
|
|
387
441
|
data: VideoData;
|
|
388
|
-
cacheState:
|
|
442
|
+
cacheState: "hit" | "miss";
|
|
389
443
|
creditsUsed: number;
|
|
390
444
|
creditsRemaining: number;
|
|
391
445
|
};
|
|
@@ -400,23 +454,23 @@ type SearchVideosData = {
|
|
|
400
454
|
/**
|
|
401
455
|
* Filter by content type.
|
|
402
456
|
*/
|
|
403
|
-
type?:
|
|
457
|
+
type?: "video" | "short" | "channel" | "playlist" | "movie";
|
|
404
458
|
/**
|
|
405
459
|
* Sort order. Defaults to relevance.
|
|
406
460
|
*/
|
|
407
|
-
sortBy?:
|
|
461
|
+
sortBy?: "relevance" | "popularity" | "date" | "rating";
|
|
408
462
|
/**
|
|
409
463
|
* Filter by upload date.
|
|
410
464
|
*/
|
|
411
|
-
uploadDate?:
|
|
465
|
+
uploadDate?: "today" | "week" | "month" | "year";
|
|
412
466
|
/**
|
|
413
467
|
* Duration filter. Not applicable when type is short.
|
|
414
468
|
*/
|
|
415
|
-
duration?:
|
|
469
|
+
duration?: "short" | "medium" | "long";
|
|
416
470
|
/**
|
|
417
471
|
* Filter by video features.
|
|
418
472
|
*/
|
|
419
|
-
features?: Array<
|
|
473
|
+
features?: Array<"live" | "4k" | "hd" | "subtitles" | "creativeCommons" | "360" | "vr180" | "3d" | "hdr" | "location" | "purchased">;
|
|
420
474
|
/**
|
|
421
475
|
* Token from a previous response to fetch the next page.
|
|
422
476
|
*/
|
|
@@ -424,7 +478,7 @@ type SearchVideosData = {
|
|
|
424
478
|
};
|
|
425
479
|
path?: never;
|
|
426
480
|
query?: never;
|
|
427
|
-
url:
|
|
481
|
+
url: "/v1/search";
|
|
428
482
|
};
|
|
429
483
|
type SearchVideosErrors = {
|
|
430
484
|
/**
|
|
@@ -457,7 +511,7 @@ type SearchVideosResponses = {
|
|
|
457
511
|
success: true;
|
|
458
512
|
requestId: string;
|
|
459
513
|
data: SearchData;
|
|
460
|
-
cacheState:
|
|
514
|
+
cacheState: "hit" | "miss";
|
|
461
515
|
creditsUsed: number;
|
|
462
516
|
creditsRemaining: number;
|
|
463
517
|
};
|
|
@@ -472,7 +526,7 @@ type GetChannelData = {
|
|
|
472
526
|
/**
|
|
473
527
|
* Content tab to fetch. Defaults to video.
|
|
474
528
|
*/
|
|
475
|
-
tab?:
|
|
529
|
+
tab?: "video" | "short" | "playlist" | "about";
|
|
476
530
|
/**
|
|
477
531
|
* Token from a previous response to fetch the next page.
|
|
478
532
|
*/
|
|
@@ -480,11 +534,11 @@ type GetChannelData = {
|
|
|
480
534
|
/**
|
|
481
535
|
* Sort order for the selected tab.
|
|
482
536
|
*/
|
|
483
|
-
sortBy?:
|
|
537
|
+
sortBy?: "latest" | "popular" | "oldest";
|
|
484
538
|
};
|
|
485
539
|
path?: never;
|
|
486
540
|
query?: never;
|
|
487
|
-
url:
|
|
541
|
+
url: "/v1/channel";
|
|
488
542
|
};
|
|
489
543
|
type GetChannelErrors = {
|
|
490
544
|
/**
|
|
@@ -517,7 +571,7 @@ type GetChannelResponses = {
|
|
|
517
571
|
success: true;
|
|
518
572
|
requestId: string;
|
|
519
573
|
data: ChannelData;
|
|
520
|
-
cacheState:
|
|
574
|
+
cacheState: "hit" | "miss";
|
|
521
575
|
creditsUsed: number;
|
|
522
576
|
creditsRemaining: number;
|
|
523
577
|
};
|
|
@@ -536,7 +590,7 @@ type GetPlaylistData = {
|
|
|
536
590
|
};
|
|
537
591
|
path?: never;
|
|
538
592
|
query?: never;
|
|
539
|
-
url:
|
|
593
|
+
url: "/v1/playlist";
|
|
540
594
|
};
|
|
541
595
|
type GetPlaylistErrors = {
|
|
542
596
|
/**
|
|
@@ -569,7 +623,7 @@ type GetPlaylistResponses = {
|
|
|
569
623
|
success: true;
|
|
570
624
|
requestId: string;
|
|
571
625
|
data: PlaylistData;
|
|
572
|
-
cacheState:
|
|
626
|
+
cacheState: "hit" | "miss";
|
|
573
627
|
creditsUsed: number;
|
|
574
628
|
creditsRemaining: number;
|
|
575
629
|
};
|
|
@@ -592,7 +646,7 @@ type GetSuggestionsData = {
|
|
|
592
646
|
*/
|
|
593
647
|
gl?: string;
|
|
594
648
|
};
|
|
595
|
-
url:
|
|
649
|
+
url: "/v1/suggest";
|
|
596
650
|
};
|
|
597
651
|
type GetSuggestionsErrors = {
|
|
598
652
|
/**
|
|
@@ -621,7 +675,7 @@ type GetSuggestionsResponses = {
|
|
|
621
675
|
success: true;
|
|
622
676
|
requestId: string;
|
|
623
677
|
data: SuggestData;
|
|
624
|
-
cacheState:
|
|
678
|
+
cacheState: "hit" | "miss";
|
|
625
679
|
creditsUsed: number;
|
|
626
680
|
creditsRemaining: number;
|
|
627
681
|
};
|
|
@@ -631,7 +685,7 @@ type GetCreditsData = {
|
|
|
631
685
|
body?: never;
|
|
632
686
|
path?: never;
|
|
633
687
|
query?: never;
|
|
634
|
-
url:
|
|
688
|
+
url: "/v1/credits";
|
|
635
689
|
};
|
|
636
690
|
type GetCreditsErrors = {
|
|
637
691
|
/**
|
|
@@ -658,7 +712,7 @@ type GetLogsData = {
|
|
|
658
712
|
/**
|
|
659
713
|
* Time window: 'today', the last 7 days, or the last 30 days.
|
|
660
714
|
*/
|
|
661
|
-
days?:
|
|
715
|
+
days?: "today" | "7" | "30";
|
|
662
716
|
/**
|
|
663
717
|
* Filter logs to a single endpoint, e.g. /video.
|
|
664
718
|
*/
|
|
@@ -668,7 +722,7 @@ type GetLogsData = {
|
|
|
668
722
|
*/
|
|
669
723
|
page?: number;
|
|
670
724
|
};
|
|
671
|
-
url:
|
|
725
|
+
url: "/v1/logs";
|
|
672
726
|
};
|
|
673
727
|
type GetLogsErrors = {
|
|
674
728
|
/**
|
|
@@ -695,13 +749,13 @@ type GetUsageData = {
|
|
|
695
749
|
/**
|
|
696
750
|
* Time window: 'today', the last 7 days, or the last 30 days.
|
|
697
751
|
*/
|
|
698
|
-
days?:
|
|
752
|
+
days?: "today" | "7" | "30";
|
|
699
753
|
/**
|
|
700
754
|
* Timezone offset in minutes used to bucket activity into days. Defaults to UTC.
|
|
701
755
|
*/
|
|
702
756
|
tz?: string;
|
|
703
757
|
};
|
|
704
|
-
url:
|
|
758
|
+
url: "/v1/usage";
|
|
705
759
|
};
|
|
706
760
|
type GetUsageErrors = {
|
|
707
761
|
/**
|
|
@@ -722,57 +776,45 @@ type GetUsageResponses = {
|
|
|
722
776
|
};
|
|
723
777
|
type GetUsageResponse = GetUsageResponses[keyof GetUsageResponses];
|
|
724
778
|
type ClientOptions = {
|
|
725
|
-
baseUrl:
|
|
779
|
+
baseUrl: "https://api.stophy.dev" | (string & {});
|
|
726
780
|
};
|
|
727
781
|
|
|
728
|
-
|
|
729
|
-
type
|
|
730
|
-
|
|
782
|
+
type ChannelBody = GetChannelData["body"];
|
|
783
|
+
type ChannelOptions = Omit<ChannelBody, "channelUrl">;
|
|
784
|
+
|
|
785
|
+
type PlaylistBody = GetPlaylistData["body"];
|
|
786
|
+
type PlaylistOptions = Omit<PlaylistBody, "playlistUrl">;
|
|
787
|
+
|
|
788
|
+
type SearchBody = SearchVideosData["body"];
|
|
789
|
+
type SearchOptions = Omit<SearchBody, "q">;
|
|
790
|
+
|
|
791
|
+
type SuggestQuery = GetSuggestionsData["query"];
|
|
792
|
+
type SuggestOptions = Omit<SuggestQuery, "q">;
|
|
793
|
+
|
|
794
|
+
type VideoResponseFor<T> = Omit<GetVideoResponse, "data"> & {
|
|
795
|
+
data: T;
|
|
731
796
|
};
|
|
797
|
+
type VideoUrlBody = Extract<GetVideoData["body"], {
|
|
798
|
+
videoUrl: string;
|
|
799
|
+
}>;
|
|
800
|
+
type CommentsOptions = Pick<VideoUrlBody, "sortBy" | "continuationToken">;
|
|
801
|
+
type LiveChatOptions = Pick<VideoUrlBody, "chatType" | "continuationToken">;
|
|
732
802
|
|
|
733
803
|
interface StophyOptions {
|
|
734
|
-
/**
|
|
735
|
-
apiKey
|
|
736
|
-
/** Defaults to `https://api.stophy.dev`. */
|
|
804
|
+
/** Defaults to `STOPHY_API_KEY`. */
|
|
805
|
+
apiKey?: string;
|
|
806
|
+
/** Defaults to `STOPHY_BASE_URL` or `https://api.stophy.dev`. */
|
|
737
807
|
baseUrl?: string;
|
|
738
|
-
/** Bring your own `fetch` (handy for tests or non-global runtimes). */
|
|
739
808
|
fetch?: typeof globalThis.fetch;
|
|
740
|
-
/** Sent with every request. */
|
|
741
809
|
headers?: Record<string, string>;
|
|
742
|
-
/**
|
|
743
|
-
* Retry attempts for transient failures (network errors and
|
|
744
|
-
* 429/500/502/503/504). Set to `0` to disable. Defaults to `2`.
|
|
745
|
-
*/
|
|
746
810
|
maxRetries?: number;
|
|
747
|
-
/** Base delay for backoff, in ms. Defaults to `500`. */
|
|
748
811
|
retryInitialDelayMs?: number;
|
|
749
812
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
readonly code?: ErrorResponse["code"];
|
|
753
|
-
readonly status: number;
|
|
754
|
-
readonly requestId?: string;
|
|
755
|
-
readonly details?: unknown;
|
|
756
|
-
constructor(message: string, opts: {
|
|
757
|
-
status: number;
|
|
758
|
-
code?: ErrorResponse["code"];
|
|
759
|
-
requestId?: string;
|
|
760
|
-
details?: unknown;
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Stophy API client — YouTube context API for AI agents.
|
|
765
|
-
*
|
|
766
|
-
* ```ts
|
|
767
|
-
* const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY! });
|
|
768
|
-
* const { data } = await stophy.video({ type: "transcript", videoUrl });
|
|
769
|
-
* ```
|
|
770
|
-
*/
|
|
813
|
+
type StophyClientInput = StophyOptions | string;
|
|
814
|
+
/** Typed client for the Stophy API. */
|
|
771
815
|
declare class Stophy {
|
|
772
|
-
/** The underlying fetch client, if you need lower-level access. */
|
|
773
816
|
readonly client: Client;
|
|
774
|
-
constructor(
|
|
775
|
-
/** Video details, transcript, comments, replies, or live chat — pick with `type`. */
|
|
817
|
+
constructor(input?: StophyClientInput);
|
|
776
818
|
video(body: GetVideoData["body"] & {
|
|
777
819
|
type: "details";
|
|
778
820
|
}): Promise<VideoResponseFor<VideoDetailsData>>;
|
|
@@ -786,20 +828,36 @@ declare class Stophy {
|
|
|
786
828
|
type: "livechat";
|
|
787
829
|
}): Promise<VideoResponseFor<LiveChatData>>;
|
|
788
830
|
video(body: GetVideoData["body"]): Promise<GetVideoResponse>;
|
|
789
|
-
|
|
831
|
+
videoDetails(videoUrl: string): Promise<VideoResponseFor<VideoDetailsData>>;
|
|
832
|
+
transcript(videoUrl: string): Promise<VideoResponseFor<TranscriptResult>>;
|
|
833
|
+
comments(videoUrl: string, options?: CommentsOptions): Promise<VideoResponseFor<CommentsData>>;
|
|
834
|
+
replies(continuationToken: string): Promise<VideoResponseFor<CommentsData>>;
|
|
835
|
+
liveChat(videoUrl: string, options?: LiveChatOptions): Promise<VideoResponseFor<LiveChatData>>;
|
|
790
836
|
search(body: SearchVideosData["body"]): Promise<SearchVideosResponse>;
|
|
791
|
-
|
|
837
|
+
search(query: string, options?: SearchOptions): Promise<SearchVideosResponse>;
|
|
792
838
|
channel(body: GetChannelData["body"]): Promise<GetChannelResponse>;
|
|
793
|
-
|
|
839
|
+
channel(channelUrl: string, options?: ChannelOptions): Promise<GetChannelResponse>;
|
|
794
840
|
playlist(body: GetPlaylistData["body"]): Promise<GetPlaylistResponse>;
|
|
795
|
-
|
|
841
|
+
playlist(playlistUrl: string, options?: PlaylistOptions): Promise<GetPlaylistResponse>;
|
|
796
842
|
suggest(query: GetSuggestionsData["query"]): Promise<GetSuggestionsResponse>;
|
|
797
|
-
|
|
843
|
+
suggest(query: string, options?: SuggestOptions): Promise<GetSuggestionsResponse>;
|
|
798
844
|
credits(): Promise<GetCreditsResponse>;
|
|
799
|
-
/** Recent API request logs. */
|
|
800
845
|
logs(query?: GetLogsData["query"]): Promise<GetLogsResponse>;
|
|
801
|
-
/** Daily credit and request counts. */
|
|
802
846
|
usage(query?: GetUsageData["query"]): Promise<GetUsageResponse>;
|
|
803
847
|
}
|
|
804
848
|
|
|
805
|
-
|
|
849
|
+
/** Thrown when the Stophy API responds with a non-success status. */
|
|
850
|
+
declare class StophyError extends Error {
|
|
851
|
+
readonly code?: ErrorResponse["code"];
|
|
852
|
+
readonly status: number;
|
|
853
|
+
readonly requestId?: string;
|
|
854
|
+
readonly details?: unknown;
|
|
855
|
+
constructor(message: string, options: {
|
|
856
|
+
status: number;
|
|
857
|
+
code?: ErrorResponse["code"];
|
|
858
|
+
requestId?: string;
|
|
859
|
+
details?: unknown;
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
export { type ChannelData, type ChannelLink, type ChannelOptions, type ChannelPlaylist, type ChannelProfile, type ChannelShort, type ChannelVideo, type ClientOptions, type Comment, type CommentsData, type CommentsOptions, type ContentItem, type CreditsData, type EmptyState, type ErrorResponse, type GetChannelData, type GetChannelError, type GetChannelErrors, type GetChannelResponse, type GetChannelResponses, type GetCreditsData, type GetCreditsError, type GetCreditsErrors, type GetCreditsResponse, type GetCreditsResponses, type GetLogsData, type GetLogsError, type GetLogsErrors, type GetLogsResponse, type GetLogsResponses, type GetPlaylistData, type GetPlaylistError, type GetPlaylistErrors, type GetPlaylistResponse, type GetPlaylistResponses, type GetSuggestionsData, type GetSuggestionsError, type GetSuggestionsErrors, type GetSuggestionsResponse, type GetSuggestionsResponses, type GetUsageData, type GetUsageError, type GetUsageErrors, type GetUsageResponse, type GetUsageResponses, type GetVideoData, type GetVideoError, type GetVideoErrors, type GetVideoResponse, type GetVideoResponses, type LiveChatData, type LiveChatMessage, type LiveChatOptions, type LogEntry, type LogsData, type PlaylistData, type PlaylistItem, type PlaylistMeta, type PlaylistOptions, type RelatedVideo, type SearchChannel, type SearchData, type SearchItem, type SearchOptions, type SearchPlaylist, type SearchQuery, type SearchShort, type SearchVideo, type SearchVideosData, type SearchVideosError, type SearchVideosErrors, type SearchVideosResponse, type SearchVideosResponses, Stophy, type StophyClientInput, StophyError, type StophyOptions, type SuggestData, type SuggestOptions, type Thumbnail, type TranscriptLanguage, type TranscriptResult, type TranscriptSegment, type UsageData, type UsageItem, type VideoData, type VideoDetails, type VideoDetailsData, Stophy as default };
|