@herowcode/utils 1.2.2 → 1.3.0
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 +95 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/cjs/api/client.d.ts.map +1 -1
- package/dist/cjs/api/client.js +18 -9
- package/dist/cjs/api/client.js.map +1 -1
- package/dist/cjs/date/dayjs.js +0 -1
- package/dist/cjs/date/dayjs.js.map +1 -1
- package/dist/cjs/youtube/get-youtube-video-info.d.ts +26 -0
- package/dist/cjs/youtube/get-youtube-video-info.d.ts.map +1 -0
- package/dist/cjs/youtube/get-youtube-video-info.js +244 -0
- package/dist/cjs/youtube/get-youtube-video-info.js.map +1 -0
- package/dist/cjs/youtube/index.d.ts +1 -0
- package/dist/cjs/youtube/index.d.ts.map +1 -1
- package/dist/cjs/youtube/index.js +1 -0
- package/dist/cjs/youtube/index.js.map +1 -1
- package/dist/esm/api/client.js +18 -9
- package/dist/esm/date/dayjs.js +0 -1
- package/dist/esm/youtube/get-youtube-video-info.js +207 -0
- package/dist/esm/youtube/index.js +1 -0
- package/dist/youtube/get-youtube-video-info.d.ts +26 -0
- package/dist/youtube/get-youtube-video-info.d.ts.map +1 -0
- package/dist/youtube/index.d.ts +1 -0
- package/dist/youtube/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,15 @@ const embedUrl = generateYoutubeURL({
|
|
|
60
60
|
autoplay: true
|
|
61
61
|
}); // "https://www.youtube.com/embed/abc123?autoplay=1"
|
|
62
62
|
|
|
63
|
+
// Get detailed video information
|
|
64
|
+
const videoInfo = await getYoutubeVideoInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
|
65
|
+
if (videoInfo) {
|
|
66
|
+
console.log(videoInfo.title); // "Rick Astley - Never Gonna Give You Up"
|
|
67
|
+
console.log(videoInfo.viewCount); // 1500000000
|
|
68
|
+
console.log(videoInfo.lengthSeconds); // 213
|
|
69
|
+
console.log(videoInfo.isLive); // false
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
// API utilities
|
|
64
73
|
const client = apiClient({ baseURL: 'https://api.example.com' });
|
|
65
74
|
const result = await client.get('/users', { params: { page: 1 } });
|
|
@@ -552,6 +561,92 @@ Notes:
|
|
|
552
561
|
- Uses the browser Image load/error events to avoid CORS issues.
|
|
553
562
|
- Returns `null` when the video ID cannot be extracted or no thumbnails load.
|
|
554
563
|
|
|
564
|
+
#### `getYoutubeVideoInfo(videoUrl: string): Promise<TYouTubeVideoInfo | null>`
|
|
565
|
+
Fetches comprehensive metadata about a YouTube video using a cascade of fallback strategies. Returns detailed information including title, channel, thumbnails, view count, duration, and more.
|
|
566
|
+
|
|
567
|
+
**Features:**
|
|
568
|
+
- **Three-tier fallback strategy:** YouTube watch page → oEmbed API → NoEmbed service
|
|
569
|
+
- **Automatic caching:** Repeated requests for the same video use cached results
|
|
570
|
+
- **Robust parsing:** Handles various YouTube response formats including live streams, shorts, and standard videos
|
|
571
|
+
- **No API key required:** Uses public endpoints
|
|
572
|
+
|
|
573
|
+
**Return Type (`TYouTubeVideoInfo`):**
|
|
574
|
+
```typescript
|
|
575
|
+
{
|
|
576
|
+
id: string // Video ID
|
|
577
|
+
url: string // Full watch URL
|
|
578
|
+
title: string // Video title
|
|
579
|
+
channelTitle: string // Channel name
|
|
580
|
+
channelId?: string // Channel ID
|
|
581
|
+
channelUrl?: string // Channel URL
|
|
582
|
+
description?: string // Full description
|
|
583
|
+
shortDescription?: string // Short description
|
|
584
|
+
thumbnails: Array<{ // Available thumbnails
|
|
585
|
+
url: string
|
|
586
|
+
width?: number
|
|
587
|
+
height?: number
|
|
588
|
+
}>
|
|
589
|
+
thumbnail?: string // Best quality thumbnail URL
|
|
590
|
+
publishedAt?: string // Publication date (ISO 8601)
|
|
591
|
+
uploadedAt?: string // Upload date (ISO 8601)
|
|
592
|
+
keywords?: string[] // Video keywords/tags
|
|
593
|
+
viewCount?: number // View count
|
|
594
|
+
lengthSeconds?: number // Duration in seconds
|
|
595
|
+
isLive?: boolean // Live stream status
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
**Examples:**
|
|
600
|
+
```typescript
|
|
601
|
+
// Basic usage
|
|
602
|
+
const info = await getYoutubeVideoInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
|
603
|
+
if (info) {
|
|
604
|
+
console.log(info.title); // "Rick Astley - Never Gonna Give You Up"
|
|
605
|
+
console.log(info.channelTitle); // "Rick Astley"
|
|
606
|
+
console.log(info.viewCount); // 1500000000
|
|
607
|
+
console.log(info.lengthSeconds); // 213
|
|
608
|
+
console.log(info.thumbnail); // Best quality thumbnail URL
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Check if video is a live stream
|
|
612
|
+
const liveInfo = await getYoutubeVideoInfo('https://youtu.be/jfKfPfyJRdk');
|
|
613
|
+
if (liveInfo?.isLive) {
|
|
614
|
+
console.log('This is a live stream!');
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Handle various URL formats
|
|
618
|
+
const formats = [
|
|
619
|
+
'https://www.youtube.com/watch?v=abc123',
|
|
620
|
+
'https://youtu.be/abc123',
|
|
621
|
+
'https://www.youtube.com/embed/abc123',
|
|
622
|
+
'https://www.youtube.com/shorts/abc123'
|
|
623
|
+
];
|
|
624
|
+
// All return the same cached result
|
|
625
|
+
|
|
626
|
+
// Error handling
|
|
627
|
+
const invalid = await getYoutubeVideoInfo('https://example.com/not-youtube');
|
|
628
|
+
console.log(invalid); // null
|
|
629
|
+
|
|
630
|
+
const unavailable = await getYoutubeVideoInfo('https://youtube.com/watch?v=deleted');
|
|
631
|
+
console.log(unavailable); // null (video doesn't exist)
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**Fallback Strategy:**
|
|
635
|
+
1. **YouTube Watch Page:** Parses `ytInitialPlayerResponse` from HTML (most data available)
|
|
636
|
+
2. **YouTube oEmbed:** Uses official oEmbed endpoint (basic metadata)
|
|
637
|
+
3. **NoEmbed Service:** Third-party service as last resort (includes description)
|
|
638
|
+
|
|
639
|
+
**Caching:**
|
|
640
|
+
- Results are cached per video ID
|
|
641
|
+
- Different URL formats for the same video share the cache
|
|
642
|
+
- Failed requests are not cached (allows retry on next call)
|
|
643
|
+
|
|
644
|
+
**Notes:**
|
|
645
|
+
- Returns `null` for invalid URLs, unavailable videos, or when all sources fail
|
|
646
|
+
- Works in both browser and Node.js environments
|
|
647
|
+
- No rate limiting implemented (use responsibly)
|
|
648
|
+
- Cached data persists for the lifetime of the application
|
|
649
|
+
|
|
555
650
|
## Browser Support
|
|
556
651
|
|
|
557
652
|
This library supports all modern browsers and Node.js environments. It uses ES2018 features and requires:
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,UAAU,kBAAmB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACrE,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;QACtB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,UAAU,kBAAmB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACrE,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;QACtB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AA6GD,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qBAAqB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC7C,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAC9C,CAAA;AAiED,eAAO,MAAM,SAAS,GAAI,SAAS,eAAe;UAMxC,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;WAGrD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;UAGvD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;aAGnD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;YAKvD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;CAGjE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"AAEA,UAAU,kBAAmB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACrE,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;QACtB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"AAEA,UAAU,kBAAmB,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACrE,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;QACtB,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AA6GD,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qBAAqB,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC7C,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAC9C,CAAA;AAiED,eAAO,MAAM,SAAS,GAAI,SAAS,eAAe;UAMxC,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;WAGrD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;UAGvD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;aAGnD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;YAKvD,CAAC,iBAAiB,MAAM,YAAY,kBAAkB;CAGjE,CAAA"}
|
package/dist/cjs/api/client.js
CHANGED
|
@@ -28,7 +28,16 @@ async function beforeRequestHook(request, getAccessToken, getUserIP) {
|
|
|
28
28
|
if (userIP) {
|
|
29
29
|
headers.set("X-User-IP", userIP);
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
const cloned = request.clone();
|
|
34
|
+
const text = await cloned.text();
|
|
35
|
+
body = text === "" ? undefined : text;
|
|
36
|
+
}
|
|
37
|
+
catch (_a) {
|
|
38
|
+
body = undefined;
|
|
39
|
+
}
|
|
40
|
+
return new Request(request, { headers, body });
|
|
32
41
|
}
|
|
33
42
|
async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
34
43
|
const possibleSignInPaths = ["signin", "sign-in", "login"];
|
|
@@ -42,7 +51,7 @@ async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
|
42
51
|
responseBody = await clone.json();
|
|
43
52
|
responseBodyFor401 = responseBody;
|
|
44
53
|
}
|
|
45
|
-
catch (
|
|
54
|
+
catch (_b) {
|
|
46
55
|
responseBody = await clone.text();
|
|
47
56
|
}
|
|
48
57
|
}
|
|
@@ -51,27 +60,27 @@ async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
|
51
60
|
}
|
|
52
61
|
}
|
|
53
62
|
async function fetchWithRetry(input, init) {
|
|
54
|
-
var
|
|
63
|
+
var _b, _c, _d, _e;
|
|
55
64
|
const retryConfig = (init === null || init === void 0 ? void 0 : init.retry) || defaultRetryConfig;
|
|
56
65
|
const method = ((init === null || init === void 0 ? void 0 : init.method) || "GET").toLowerCase();
|
|
57
66
|
let attempt = 0;
|
|
58
67
|
while (true) {
|
|
59
68
|
attempt++;
|
|
60
69
|
const response = await fetch(input, init);
|
|
61
|
-
const shouldRetry = ((
|
|
62
|
-
((
|
|
63
|
-
attempt < ((
|
|
70
|
+
const shouldRetry = ((_b = retryConfig.statusCodes) === null || _b === void 0 ? void 0 : _b.includes(response.status)) &&
|
|
71
|
+
((_c = retryConfig.methods) === null || _c === void 0 ? void 0 : _c.includes(method)) &&
|
|
72
|
+
attempt < ((_d = retryConfig.limit) !== null && _d !== void 0 ? _d : 5);
|
|
64
73
|
if (!shouldRetry)
|
|
65
74
|
return response;
|
|
66
|
-
const backoff = Math.min(2 ** attempt * 100, (
|
|
75
|
+
const backoff = Math.min(2 ** attempt * 100, (_e = retryConfig.backoffLimit) !== null && _e !== void 0 ? _e : 3000);
|
|
67
76
|
await new Promise((resolve) => setTimeout(resolve, backoff));
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
async function api(config, endpoint, options = {}) {
|
|
71
|
-
var
|
|
80
|
+
var _b;
|
|
72
81
|
let url = endpoint.startsWith("http")
|
|
73
82
|
? endpoint
|
|
74
|
-
: `${(
|
|
83
|
+
: `${(_b = config.baseURL) === null || _b === void 0 ? void 0 : _b.replace(/\/$/, "")}/${endpoint.replace(/^\//, "")}`;
|
|
75
84
|
// Add query parameters if provided
|
|
76
85
|
if (options.params) {
|
|
77
86
|
const queryString = buildQueryString(options.params);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAatC,MAAM,kBAAkB,GAAG;IACzB,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,WAAW,EAAE,CAAC,GAAG,CAAC;IAClB,YAAY,EAAE,IAAI;CACnB,CAAA;AAED,SAAS,gBAAgB,CACvB,MAAoE;IAEpE,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAA;IAE1C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC9C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACzC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAA;IAC3C,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AAC7C,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,OAAgB,EAChB,cAA6C,EAC7C,SAA6C;IAE7C,MAAM,KAAK,GAAG,MAAM,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,EAAI,CAAA,CAAA;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAE5C,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,EAAI,CAAA,CAAA;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAClC,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/date/dayjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dayjs.js","sourceRoot":"","sources":["../../../src/date/dayjs.ts"],"names":[],"mappings":";;;;;;AA8GA,gDAKC;AAED,gDAKC;AAED,oDAMC;AAED,kDAeC;AAED,wDAIC;AAxJD,kDAAyB;AACzB,iFAAwD;AACxD,uFAA8D;AAC9D,mFAA0D;AAC1D,6EAAoD;AACpD,qEAA4C;AAC5C,2DAAkC;AAClC,2BAAwB;AACxB,2BAAwB;AACxB,2BAAwB;AACxB,8BAA2B;AAc3B,MAAM,mBAAmB,GAA6B;IACpD,MAAM,EAAE,OAAO;IACf,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;KAChB;CACF,CAAA;AAED,IAAI,gBAAgB,GAA6B;IAC/C,MAAM,EAAE,mBAAmB,CAAC,MAAM;IAClC,OAAO,EAAE,EAAE,GAAG,mBAAmB,CAAC,OAAO,EAAE;CAC5C,CAAA;AAED,SAAS,gBAAgB,CACvB,IAA8B,EAC9B,QAA2B;;IAE3B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE;SAC7B,CAAA;IACH,CAAC;IAED,MAAM,YAAY,GAAG,MAAA,QAAQ,CAAC,MAAM,mCAAI,IAAI,CAAC,MAAM,CAAA;IACnD,MAAM,aAAa,GAA+B,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IAErE,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAE7C,EAAE,CAAC;YACF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAEnC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC1C,
|
|
1
|
+
{"version":3,"file":"dayjs.js","sourceRoot":"","sources":["../../../src/date/dayjs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type TYtThumbnail = {
|
|
2
|
+
url: string;
|
|
3
|
+
width?: number;
|
|
4
|
+
height?: number;
|
|
5
|
+
};
|
|
6
|
+
export type TYouTubeVideoInfo = {
|
|
7
|
+
id: string;
|
|
8
|
+
url: string;
|
|
9
|
+
title: string;
|
|
10
|
+
channelTitle: string;
|
|
11
|
+
channelId?: string;
|
|
12
|
+
channelUrl?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
shortDescription?: string;
|
|
15
|
+
thumbnails: TYtThumbnail[];
|
|
16
|
+
thumbnail?: string;
|
|
17
|
+
publishedAt?: string;
|
|
18
|
+
uploadedAt?: string;
|
|
19
|
+
keywords?: string[];
|
|
20
|
+
viewCount?: number;
|
|
21
|
+
lengthSeconds?: number;
|
|
22
|
+
isLive?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function getYoutubeVideoInfo(videoUrl: string): Promise<TYouTubeVideoInfo | null>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=get-youtube-video-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-youtube-video-info.d.ts","sourceRoot":"","sources":["../../../src/youtube/get-youtube-video-info.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAoDD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,YAAY,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAID,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAiBnC"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getYoutubeVideoInfo = getYoutubeVideoInfo;
|
|
37
|
+
const videoInfoCache = new Map();
|
|
38
|
+
async function getYoutubeVideoInfo(videoUrl) {
|
|
39
|
+
const { extractYouTubeId } = await Promise.resolve().then(() => __importStar(require("./extract-youtube-video-id")));
|
|
40
|
+
const videoId = extractYouTubeId(videoUrl);
|
|
41
|
+
if (!videoId)
|
|
42
|
+
return null;
|
|
43
|
+
const cached = videoInfoCache.get(videoId);
|
|
44
|
+
if (cached)
|
|
45
|
+
return cached;
|
|
46
|
+
const fetchPromise = fetchYoutubeVideoInfo(videoId);
|
|
47
|
+
videoInfoCache.set(videoId, fetchPromise);
|
|
48
|
+
const info = await fetchPromise;
|
|
49
|
+
if (!info) {
|
|
50
|
+
videoInfoCache.delete(videoId);
|
|
51
|
+
}
|
|
52
|
+
return info;
|
|
53
|
+
}
|
|
54
|
+
async function fetchYoutubeVideoInfo(videoId) {
|
|
55
|
+
const watchUrl = `https://www.youtube.com/watch?v=${encodeURIComponent(videoId)}`;
|
|
56
|
+
const htmlInfo = await fetchFromWatchPage(videoId, watchUrl);
|
|
57
|
+
if (htmlInfo)
|
|
58
|
+
return htmlInfo;
|
|
59
|
+
const oEmbedInfo = await fetchFromOEmbed(videoId, watchUrl);
|
|
60
|
+
if (oEmbedInfo)
|
|
61
|
+
return oEmbedInfo;
|
|
62
|
+
const noEmbedInfo = await fetchFromNoEmbed(videoId, watchUrl);
|
|
63
|
+
if (noEmbedInfo)
|
|
64
|
+
return noEmbedInfo;
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
async function fetchFromWatchPage(videoId, watchUrl) {
|
|
68
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(watchUrl);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const html = await response.text();
|
|
75
|
+
const rawJson = extractJsonBlock(html, "ytInitialPlayerResponse");
|
|
76
|
+
if (!rawJson) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const data = JSON.parse(rawJson);
|
|
80
|
+
const details = data.videoDetails;
|
|
81
|
+
const microformat = (_a = data.microformat) === null || _a === void 0 ? void 0 : _a.playerMicroformatRenderer;
|
|
82
|
+
if (!details && !microformat) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const thumbnails = getThumbnails(details, microformat);
|
|
86
|
+
const bestThumbnail = selectBestThumbnail(thumbnails);
|
|
87
|
+
return {
|
|
88
|
+
id: (_b = details === null || details === void 0 ? void 0 : details.videoId) !== null && _b !== void 0 ? _b : videoId,
|
|
89
|
+
url: watchUrl,
|
|
90
|
+
title: (_d = (_c = details === null || details === void 0 ? void 0 : details.title) !== null && _c !== void 0 ? _c : extractText(microformat === null || microformat === void 0 ? void 0 : microformat.title)) !== null && _d !== void 0 ? _d : "",
|
|
91
|
+
channelTitle: (_f = (_e = details === null || details === void 0 ? void 0 : details.author) !== null && _e !== void 0 ? _e : microformat === null || microformat === void 0 ? void 0 : microformat.ownerChannelName) !== null && _f !== void 0 ? _f : "",
|
|
92
|
+
channelId: (_g = details === null || details === void 0 ? void 0 : details.channelId) !== null && _g !== void 0 ? _g : microformat === null || microformat === void 0 ? void 0 : microformat.externalChannelId,
|
|
93
|
+
channelUrl: microformat === null || microformat === void 0 ? void 0 : microformat.ownerProfileUrl,
|
|
94
|
+
description: (_h = extractText(microformat === null || microformat === void 0 ? void 0 : microformat.description)) !== null && _h !== void 0 ? _h : details === null || details === void 0 ? void 0 : details.shortDescription,
|
|
95
|
+
shortDescription: details === null || details === void 0 ? void 0 : details.shortDescription,
|
|
96
|
+
thumbnails,
|
|
97
|
+
thumbnail: bestThumbnail === null || bestThumbnail === void 0 ? void 0 : bestThumbnail.url,
|
|
98
|
+
publishedAt: (_j = microformat === null || microformat === void 0 ? void 0 : microformat.publishDate) !== null && _j !== void 0 ? _j : microformat === null || microformat === void 0 ? void 0 : microformat.uploadDate,
|
|
99
|
+
uploadedAt: microformat === null || microformat === void 0 ? void 0 : microformat.uploadDate,
|
|
100
|
+
keywords: details === null || details === void 0 ? void 0 : details.keywords,
|
|
101
|
+
viewCount: parseNumber(details === null || details === void 0 ? void 0 : details.viewCount),
|
|
102
|
+
lengthSeconds: parseNumber(details === null || details === void 0 ? void 0 : details.lengthSeconds),
|
|
103
|
+
isLive: (_k = details === null || details === void 0 ? void 0 : details.isLiveContent) !== null && _k !== void 0 ? _k : (_l = microformat === null || microformat === void 0 ? void 0 : microformat.liveBroadcastDetails) === null || _l === void 0 ? void 0 : _l.isLiveNow,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch (_m) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function fetchFromOEmbed(videoId, watchUrl) {
|
|
111
|
+
var _a;
|
|
112
|
+
try {
|
|
113
|
+
const oEmbedUrl = `https://www.youtube.com/oembed?url=${encodeURIComponent(watchUrl)}&format=json`;
|
|
114
|
+
const response = await fetch(oEmbedUrl);
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const data = (await response.json());
|
|
119
|
+
if (!(data === null || data === void 0 ? void 0 : data.title) || !(data === null || data === void 0 ? void 0 : data.author_name)) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const thumbnails = createThumbnailList(data.thumbnail_url, data.thumbnail_width, data.thumbnail_height);
|
|
123
|
+
return {
|
|
124
|
+
id: videoId,
|
|
125
|
+
url: watchUrl,
|
|
126
|
+
title: data.title,
|
|
127
|
+
channelTitle: data.author_name,
|
|
128
|
+
channelUrl: data.author_url,
|
|
129
|
+
thumbnails,
|
|
130
|
+
thumbnail: (_a = thumbnails[0]) === null || _a === void 0 ? void 0 : _a.url,
|
|
131
|
+
description: undefined,
|
|
132
|
+
shortDescription: undefined,
|
|
133
|
+
publishedAt: undefined,
|
|
134
|
+
uploadedAt: undefined,
|
|
135
|
+
keywords: undefined,
|
|
136
|
+
viewCount: undefined,
|
|
137
|
+
lengthSeconds: undefined,
|
|
138
|
+
isLive: undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (_b) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function fetchFromNoEmbed(videoId, watchUrl) {
|
|
146
|
+
var _a;
|
|
147
|
+
try {
|
|
148
|
+
const noEmbedUrl = `https://noembed.com/embed?url=${encodeURIComponent(watchUrl)}`;
|
|
149
|
+
const response = await fetch(noEmbedUrl);
|
|
150
|
+
if (!response.ok) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const data = (await response.json());
|
|
154
|
+
if (!(data === null || data === void 0 ? void 0 : data.title) || !(data === null || data === void 0 ? void 0 : data.author_name)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const thumbnails = createThumbnailList(data.thumbnail_url, data.thumbnail_width, data.thumbnail_height);
|
|
158
|
+
return {
|
|
159
|
+
id: videoId,
|
|
160
|
+
url: watchUrl,
|
|
161
|
+
title: data.title,
|
|
162
|
+
channelTitle: data.author_name,
|
|
163
|
+
channelUrl: data.author_url,
|
|
164
|
+
description: data.description,
|
|
165
|
+
shortDescription: data.description,
|
|
166
|
+
thumbnails,
|
|
167
|
+
thumbnail: (_a = thumbnails[0]) === null || _a === void 0 ? void 0 : _a.url,
|
|
168
|
+
publishedAt: data.upload_date,
|
|
169
|
+
uploadedAt: data.upload_date,
|
|
170
|
+
keywords: undefined,
|
|
171
|
+
viewCount: undefined,
|
|
172
|
+
lengthSeconds: undefined,
|
|
173
|
+
isLive: undefined,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch (_b) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function extractJsonBlock(html, marker) {
|
|
181
|
+
const markerIndex = html.indexOf(marker);
|
|
182
|
+
if (markerIndex === -1)
|
|
183
|
+
return null;
|
|
184
|
+
const jsonStart = html.indexOf("{", markerIndex);
|
|
185
|
+
if (jsonStart === -1)
|
|
186
|
+
return null;
|
|
187
|
+
let depth = 0;
|
|
188
|
+
for (let i = jsonStart; i < html.length; i++) {
|
|
189
|
+
const char = html[i];
|
|
190
|
+
if (char === "{") {
|
|
191
|
+
depth += 1;
|
|
192
|
+
}
|
|
193
|
+
else if (char === "}") {
|
|
194
|
+
depth -= 1;
|
|
195
|
+
}
|
|
196
|
+
if (depth === 0) {
|
|
197
|
+
return html.slice(jsonStart, i + 1);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
function getThumbnails(details, microformat) {
|
|
203
|
+
var _a, _b, _c, _d;
|
|
204
|
+
if ((_b = (_a = details === null || details === void 0 ? void 0 : details.thumbnail) === null || _a === void 0 ? void 0 : _a.thumbnails) === null || _b === void 0 ? void 0 : _b.length) {
|
|
205
|
+
return details.thumbnail.thumbnails;
|
|
206
|
+
}
|
|
207
|
+
return (_d = (_c = microformat === null || microformat === void 0 ? void 0 : microformat.thumbnail) === null || _c === void 0 ? void 0 : _c.thumbnails) !== null && _d !== void 0 ? _d : [];
|
|
208
|
+
}
|
|
209
|
+
function selectBestThumbnail(thumbnails) {
|
|
210
|
+
if (!thumbnails.length)
|
|
211
|
+
return undefined;
|
|
212
|
+
return thumbnails.reduce((best, current) => {
|
|
213
|
+
if (!best)
|
|
214
|
+
return current;
|
|
215
|
+
if (!best.width)
|
|
216
|
+
return current;
|
|
217
|
+
if (!current.width)
|
|
218
|
+
return best;
|
|
219
|
+
return current.width > best.width ? current : best;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function extractText(field) {
|
|
223
|
+
var _a;
|
|
224
|
+
if (!field)
|
|
225
|
+
return undefined;
|
|
226
|
+
if (field.simpleText)
|
|
227
|
+
return field.simpleText;
|
|
228
|
+
if ((_a = field.runs) === null || _a === void 0 ? void 0 : _a.length) {
|
|
229
|
+
return field.runs.map((run) => { var _a; return (_a = run.text) !== null && _a !== void 0 ? _a : ""; }).join("");
|
|
230
|
+
}
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
function parseNumber(value) {
|
|
234
|
+
if (value === undefined)
|
|
235
|
+
return undefined;
|
|
236
|
+
const parsed = Number(value);
|
|
237
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
238
|
+
}
|
|
239
|
+
function createThumbnailList(url, width, height) {
|
|
240
|
+
if (!url)
|
|
241
|
+
return [];
|
|
242
|
+
return [{ url, width, height }];
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=get-youtube-video-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-youtube-video-info.js","sourceRoot":"","sources":["../../../src/youtube/get-youtube-video-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./extract-youtube-video-id";
|
|
2
2
|
export * from "./generate-youtube-url";
|
|
3
3
|
export * from "./get-youtube-thumbnail";
|
|
4
|
+
export * from "./get-youtube-video-info";
|
|
4
5
|
export * from "./use-get-video-duration";
|
|
5
6
|
export * from "./validate-youtube-link";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/youtube/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/youtube/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA"}
|
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./extract-youtube-video-id"), exports);
|
|
18
18
|
__exportStar(require("./generate-youtube-url"), exports);
|
|
19
19
|
__exportStar(require("./get-youtube-thumbnail"), exports);
|
|
20
|
+
__exportStar(require("./get-youtube-video-info"), exports);
|
|
20
21
|
__exportStar(require("./use-get-video-duration"), exports);
|
|
21
22
|
__exportStar(require("./validate-youtube-link"), exports);
|
|
22
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/youtube/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA0C;AAC1C,yDAAsC;AACtC,0DAAuC;AACvC,2DAAwC;AACxC,0DAAuC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/youtube/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA0C;AAC1C,yDAAsC;AACtC,0DAAuC;AACvC,2DAAwC;AACxC,2DAAwC;AACxC,0DAAuC"}
|
package/dist/esm/api/client.js
CHANGED
|
@@ -25,7 +25,16 @@ async function beforeRequestHook(request, getAccessToken, getUserIP) {
|
|
|
25
25
|
if (userIP) {
|
|
26
26
|
headers.set("X-User-IP", userIP);
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
let body;
|
|
29
|
+
try {
|
|
30
|
+
const cloned = request.clone();
|
|
31
|
+
const text = await cloned.text();
|
|
32
|
+
body = text === "" ? undefined : text;
|
|
33
|
+
}
|
|
34
|
+
catch (_a) {
|
|
35
|
+
body = undefined;
|
|
36
|
+
}
|
|
37
|
+
return new Request(request, { headers, body });
|
|
29
38
|
}
|
|
30
39
|
async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
31
40
|
const possibleSignInPaths = ["signin", "sign-in", "login"];
|
|
@@ -39,7 +48,7 @@ async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
|
39
48
|
responseBody = await clone.json();
|
|
40
49
|
responseBodyFor401 = responseBody;
|
|
41
50
|
}
|
|
42
|
-
catch (
|
|
51
|
+
catch (_b) {
|
|
43
52
|
responseBody = await clone.text();
|
|
44
53
|
}
|
|
45
54
|
}
|
|
@@ -48,27 +57,27 @@ async function afterResponseHook(request, response, onSignoutUnauthorized) {
|
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
async function fetchWithRetry(input, init) {
|
|
51
|
-
var
|
|
60
|
+
var _b, _c, _d, _e;
|
|
52
61
|
const retryConfig = (init === null || init === void 0 ? void 0 : init.retry) || defaultRetryConfig;
|
|
53
62
|
const method = ((init === null || init === void 0 ? void 0 : init.method) || "GET").toLowerCase();
|
|
54
63
|
let attempt = 0;
|
|
55
64
|
while (true) {
|
|
56
65
|
attempt++;
|
|
57
66
|
const response = await fetch(input, init);
|
|
58
|
-
const shouldRetry = ((
|
|
59
|
-
((
|
|
60
|
-
attempt < ((
|
|
67
|
+
const shouldRetry = ((_b = retryConfig.statusCodes) === null || _b === void 0 ? void 0 : _b.includes(response.status)) &&
|
|
68
|
+
((_c = retryConfig.methods) === null || _c === void 0 ? void 0 : _c.includes(method)) &&
|
|
69
|
+
attempt < ((_d = retryConfig.limit) !== null && _d !== void 0 ? _d : 5);
|
|
61
70
|
if (!shouldRetry)
|
|
62
71
|
return response;
|
|
63
|
-
const backoff = Math.min(2 ** attempt * 100, (
|
|
72
|
+
const backoff = Math.min(2 ** attempt * 100, (_e = retryConfig.backoffLimit) !== null && _e !== void 0 ? _e : 3000);
|
|
64
73
|
await new Promise((resolve) => setTimeout(resolve, backoff));
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
76
|
async function api(config, endpoint, options = {}) {
|
|
68
|
-
var
|
|
77
|
+
var _b;
|
|
69
78
|
let url = endpoint.startsWith("http")
|
|
70
79
|
? endpoint
|
|
71
|
-
: `${(
|
|
80
|
+
: `${(_b = config.baseURL) === null || _b === void 0 ? void 0 : _b.replace(/\/$/, "")}/${endpoint.replace(/^\//, "")}`;
|
|
72
81
|
// Add query parameters if provided
|
|
73
82
|
if (options.params) {
|
|
74
83
|
const queryString = buildQueryString(options.params);
|
package/dist/esm/date/dayjs.js
CHANGED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
const videoInfoCache = new Map();
|
|
2
|
+
export async function getYoutubeVideoInfo(videoUrl) {
|
|
3
|
+
const { extractYouTubeId } = await import("./extract-youtube-video-id.js");
|
|
4
|
+
const videoId = extractYouTubeId(videoUrl);
|
|
5
|
+
if (!videoId)
|
|
6
|
+
return null;
|
|
7
|
+
const cached = videoInfoCache.get(videoId);
|
|
8
|
+
if (cached)
|
|
9
|
+
return cached;
|
|
10
|
+
const fetchPromise = fetchYoutubeVideoInfo(videoId);
|
|
11
|
+
videoInfoCache.set(videoId, fetchPromise);
|
|
12
|
+
const info = await fetchPromise;
|
|
13
|
+
if (!info) {
|
|
14
|
+
videoInfoCache.delete(videoId);
|
|
15
|
+
}
|
|
16
|
+
return info;
|
|
17
|
+
}
|
|
18
|
+
async function fetchYoutubeVideoInfo(videoId) {
|
|
19
|
+
const watchUrl = `https://www.youtube.com/watch?v=${encodeURIComponent(videoId)}`;
|
|
20
|
+
const htmlInfo = await fetchFromWatchPage(videoId, watchUrl);
|
|
21
|
+
if (htmlInfo)
|
|
22
|
+
return htmlInfo;
|
|
23
|
+
const oEmbedInfo = await fetchFromOEmbed(videoId, watchUrl);
|
|
24
|
+
if (oEmbedInfo)
|
|
25
|
+
return oEmbedInfo;
|
|
26
|
+
const noEmbedInfo = await fetchFromNoEmbed(videoId, watchUrl);
|
|
27
|
+
if (noEmbedInfo)
|
|
28
|
+
return noEmbedInfo;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
async function fetchFromWatchPage(videoId, watchUrl) {
|
|
32
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
33
|
+
try {
|
|
34
|
+
const response = await fetch(watchUrl);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const html = await response.text();
|
|
39
|
+
const rawJson = extractJsonBlock(html, "ytInitialPlayerResponse");
|
|
40
|
+
if (!rawJson) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const data = JSON.parse(rawJson);
|
|
44
|
+
const details = data.videoDetails;
|
|
45
|
+
const microformat = (_a = data.microformat) === null || _a === void 0 ? void 0 : _a.playerMicroformatRenderer;
|
|
46
|
+
if (!details && !microformat) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const thumbnails = getThumbnails(details, microformat);
|
|
50
|
+
const bestThumbnail = selectBestThumbnail(thumbnails);
|
|
51
|
+
return {
|
|
52
|
+
id: (_b = details === null || details === void 0 ? void 0 : details.videoId) !== null && _b !== void 0 ? _b : videoId,
|
|
53
|
+
url: watchUrl,
|
|
54
|
+
title: (_d = (_c = details === null || details === void 0 ? void 0 : details.title) !== null && _c !== void 0 ? _c : extractText(microformat === null || microformat === void 0 ? void 0 : microformat.title)) !== null && _d !== void 0 ? _d : "",
|
|
55
|
+
channelTitle: (_f = (_e = details === null || details === void 0 ? void 0 : details.author) !== null && _e !== void 0 ? _e : microformat === null || microformat === void 0 ? void 0 : microformat.ownerChannelName) !== null && _f !== void 0 ? _f : "",
|
|
56
|
+
channelId: (_g = details === null || details === void 0 ? void 0 : details.channelId) !== null && _g !== void 0 ? _g : microformat === null || microformat === void 0 ? void 0 : microformat.externalChannelId,
|
|
57
|
+
channelUrl: microformat === null || microformat === void 0 ? void 0 : microformat.ownerProfileUrl,
|
|
58
|
+
description: (_h = extractText(microformat === null || microformat === void 0 ? void 0 : microformat.description)) !== null && _h !== void 0 ? _h : details === null || details === void 0 ? void 0 : details.shortDescription,
|
|
59
|
+
shortDescription: details === null || details === void 0 ? void 0 : details.shortDescription,
|
|
60
|
+
thumbnails,
|
|
61
|
+
thumbnail: bestThumbnail === null || bestThumbnail === void 0 ? void 0 : bestThumbnail.url,
|
|
62
|
+
publishedAt: (_j = microformat === null || microformat === void 0 ? void 0 : microformat.publishDate) !== null && _j !== void 0 ? _j : microformat === null || microformat === void 0 ? void 0 : microformat.uploadDate,
|
|
63
|
+
uploadedAt: microformat === null || microformat === void 0 ? void 0 : microformat.uploadDate,
|
|
64
|
+
keywords: details === null || details === void 0 ? void 0 : details.keywords,
|
|
65
|
+
viewCount: parseNumber(details === null || details === void 0 ? void 0 : details.viewCount),
|
|
66
|
+
lengthSeconds: parseNumber(details === null || details === void 0 ? void 0 : details.lengthSeconds),
|
|
67
|
+
isLive: (_k = details === null || details === void 0 ? void 0 : details.isLiveContent) !== null && _k !== void 0 ? _k : (_l = microformat === null || microformat === void 0 ? void 0 : microformat.liveBroadcastDetails) === null || _l === void 0 ? void 0 : _l.isLiveNow,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (_m) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function fetchFromOEmbed(videoId, watchUrl) {
|
|
75
|
+
var _a;
|
|
76
|
+
try {
|
|
77
|
+
const oEmbedUrl = `https://www.youtube.com/oembed?url=${encodeURIComponent(watchUrl)}&format=json`;
|
|
78
|
+
const response = await fetch(oEmbedUrl);
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const data = (await response.json());
|
|
83
|
+
if (!(data === null || data === void 0 ? void 0 : data.title) || !(data === null || data === void 0 ? void 0 : data.author_name)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const thumbnails = createThumbnailList(data.thumbnail_url, data.thumbnail_width, data.thumbnail_height);
|
|
87
|
+
return {
|
|
88
|
+
id: videoId,
|
|
89
|
+
url: watchUrl,
|
|
90
|
+
title: data.title,
|
|
91
|
+
channelTitle: data.author_name,
|
|
92
|
+
channelUrl: data.author_url,
|
|
93
|
+
thumbnails,
|
|
94
|
+
thumbnail: (_a = thumbnails[0]) === null || _a === void 0 ? void 0 : _a.url,
|
|
95
|
+
description: undefined,
|
|
96
|
+
shortDescription: undefined,
|
|
97
|
+
publishedAt: undefined,
|
|
98
|
+
uploadedAt: undefined,
|
|
99
|
+
keywords: undefined,
|
|
100
|
+
viewCount: undefined,
|
|
101
|
+
lengthSeconds: undefined,
|
|
102
|
+
isLive: undefined,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (_b) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function fetchFromNoEmbed(videoId, watchUrl) {
|
|
110
|
+
var _a;
|
|
111
|
+
try {
|
|
112
|
+
const noEmbedUrl = `https://noembed.com/embed?url=${encodeURIComponent(watchUrl)}`;
|
|
113
|
+
const response = await fetch(noEmbedUrl);
|
|
114
|
+
if (!response.ok) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const data = (await response.json());
|
|
118
|
+
if (!(data === null || data === void 0 ? void 0 : data.title) || !(data === null || data === void 0 ? void 0 : data.author_name)) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const thumbnails = createThumbnailList(data.thumbnail_url, data.thumbnail_width, data.thumbnail_height);
|
|
122
|
+
return {
|
|
123
|
+
id: videoId,
|
|
124
|
+
url: watchUrl,
|
|
125
|
+
title: data.title,
|
|
126
|
+
channelTitle: data.author_name,
|
|
127
|
+
channelUrl: data.author_url,
|
|
128
|
+
description: data.description,
|
|
129
|
+
shortDescription: data.description,
|
|
130
|
+
thumbnails,
|
|
131
|
+
thumbnail: (_a = thumbnails[0]) === null || _a === void 0 ? void 0 : _a.url,
|
|
132
|
+
publishedAt: data.upload_date,
|
|
133
|
+
uploadedAt: data.upload_date,
|
|
134
|
+
keywords: undefined,
|
|
135
|
+
viewCount: undefined,
|
|
136
|
+
lengthSeconds: undefined,
|
|
137
|
+
isLive: undefined,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (_b) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function extractJsonBlock(html, marker) {
|
|
145
|
+
const markerIndex = html.indexOf(marker);
|
|
146
|
+
if (markerIndex === -1)
|
|
147
|
+
return null;
|
|
148
|
+
const jsonStart = html.indexOf("{", markerIndex);
|
|
149
|
+
if (jsonStart === -1)
|
|
150
|
+
return null;
|
|
151
|
+
let depth = 0;
|
|
152
|
+
for (let i = jsonStart; i < html.length; i++) {
|
|
153
|
+
const char = html[i];
|
|
154
|
+
if (char === "{") {
|
|
155
|
+
depth += 1;
|
|
156
|
+
}
|
|
157
|
+
else if (char === "}") {
|
|
158
|
+
depth -= 1;
|
|
159
|
+
}
|
|
160
|
+
if (depth === 0) {
|
|
161
|
+
return html.slice(jsonStart, i + 1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
function getThumbnails(details, microformat) {
|
|
167
|
+
var _a, _b, _c, _d;
|
|
168
|
+
if ((_b = (_a = details === null || details === void 0 ? void 0 : details.thumbnail) === null || _a === void 0 ? void 0 : _a.thumbnails) === null || _b === void 0 ? void 0 : _b.length) {
|
|
169
|
+
return details.thumbnail.thumbnails;
|
|
170
|
+
}
|
|
171
|
+
return (_d = (_c = microformat === null || microformat === void 0 ? void 0 : microformat.thumbnail) === null || _c === void 0 ? void 0 : _c.thumbnails) !== null && _d !== void 0 ? _d : [];
|
|
172
|
+
}
|
|
173
|
+
function selectBestThumbnail(thumbnails) {
|
|
174
|
+
if (!thumbnails.length)
|
|
175
|
+
return undefined;
|
|
176
|
+
return thumbnails.reduce((best, current) => {
|
|
177
|
+
if (!best)
|
|
178
|
+
return current;
|
|
179
|
+
if (!best.width)
|
|
180
|
+
return current;
|
|
181
|
+
if (!current.width)
|
|
182
|
+
return best;
|
|
183
|
+
return current.width > best.width ? current : best;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function extractText(field) {
|
|
187
|
+
var _a;
|
|
188
|
+
if (!field)
|
|
189
|
+
return undefined;
|
|
190
|
+
if (field.simpleText)
|
|
191
|
+
return field.simpleText;
|
|
192
|
+
if ((_a = field.runs) === null || _a === void 0 ? void 0 : _a.length) {
|
|
193
|
+
return field.runs.map((run) => { var _a; return (_a = run.text) !== null && _a !== void 0 ? _a : ""; }).join("");
|
|
194
|
+
}
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
function parseNumber(value) {
|
|
198
|
+
if (value === undefined)
|
|
199
|
+
return undefined;
|
|
200
|
+
const parsed = Number(value);
|
|
201
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
202
|
+
}
|
|
203
|
+
function createThumbnailList(url, width, height) {
|
|
204
|
+
if (!url)
|
|
205
|
+
return [];
|
|
206
|
+
return [{ url, width, height }];
|
|
207
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./extract-youtube-video-id.js";
|
|
2
2
|
export * from "./generate-youtube-url.js";
|
|
3
3
|
export * from "./get-youtube-thumbnail.js";
|
|
4
|
+
export * from "./get-youtube-video-info.js";
|
|
4
5
|
export * from "./use-get-video-duration.js";
|
|
5
6
|
export * from "./validate-youtube-link.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type TYtThumbnail = {
|
|
2
|
+
url: string;
|
|
3
|
+
width?: number;
|
|
4
|
+
height?: number;
|
|
5
|
+
};
|
|
6
|
+
export type TYouTubeVideoInfo = {
|
|
7
|
+
id: string;
|
|
8
|
+
url: string;
|
|
9
|
+
title: string;
|
|
10
|
+
channelTitle: string;
|
|
11
|
+
channelId?: string;
|
|
12
|
+
channelUrl?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
shortDescription?: string;
|
|
15
|
+
thumbnails: TYtThumbnail[];
|
|
16
|
+
thumbnail?: string;
|
|
17
|
+
publishedAt?: string;
|
|
18
|
+
uploadedAt?: string;
|
|
19
|
+
keywords?: string[];
|
|
20
|
+
viewCount?: number;
|
|
21
|
+
lengthSeconds?: number;
|
|
22
|
+
isLive?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function getYoutubeVideoInfo(videoUrl: string): Promise<TYouTubeVideoInfo | null>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=get-youtube-video-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-youtube-video-info.d.ts","sourceRoot":"","sources":["../../src/youtube/get-youtube-video-info.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAoDD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,YAAY,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAID,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAiBnC"}
|
package/dist/youtube/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./extract-youtube-video-id";
|
|
2
2
|
export * from "./generate-youtube-url";
|
|
3
3
|
export * from "./get-youtube-thumbnail";
|
|
4
|
+
export * from "./get-youtube-video-info";
|
|
4
5
|
export * from "./use-get-video-duration";
|
|
5
6
|
export * from "./validate-youtube-link";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/youtube/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/youtube/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA"}
|
package/package.json
CHANGED