youtubei 0.0.1-rc.24 → 0.0.1-rc.28

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.
@@ -9,7 +9,6 @@ export interface BaseVideoAttributes extends BaseAttributes {
9
9
  uploadDate: string;
10
10
  viewCount: number | null;
11
11
  likeCount: number | null;
12
- dislikeCount: number | null;
13
12
  isLiveContent: boolean;
14
13
  tags: string[];
15
14
  upNext: VideoCompact | PlaylistCompact | null;
@@ -32,8 +31,6 @@ export default class BaseVideo extends Base implements BaseVideoAttributes {
32
31
  viewCount: number | null;
33
32
  /** How many like does this video have, null if the like count hidden */
34
33
  likeCount: number | null;
35
- /** How many dislike does this video have, null if the dislike count is hidden */
36
- dislikeCount: number | null;
37
34
  /** Whether this video is a live content or not */
38
35
  isLiveContent: boolean;
39
36
  /** The tags of this video */
@@ -37,17 +37,17 @@ class BaseVideo extends _1.Base {
37
37
  this.isLiveContent = videoInfo.videoDetails.isLiveContent;
38
38
  this.thumbnails = new _1.Thumbnails().load(videoInfo.videoDetails.thumbnail.thumbnails);
39
39
  // Channel
40
- const { title, thumbnail } = videoInfo.owner.videoOwnerRenderer;
40
+ const { title, thumbnail, subscriberCountText } = videoInfo.owner.videoOwnerRenderer;
41
41
  this.channel = new _1.ChannelCompact({
42
42
  client: this.client,
43
43
  id: title.runs[0].navigationEndpoint.browseEndpoint.browseId,
44
44
  name: title.runs[0].text,
45
+ subscriberCount: subscriberCountText === null || subscriberCountText === void 0 ? void 0 : subscriberCountText.simpleText,
45
46
  thumbnails: new _1.Thumbnails().load(thumbnail.thumbnails),
46
47
  });
47
48
  // Like Count and Dislike Count
48
49
  const topLevelButtons = videoInfo.videoActions.menuRenderer.topLevelButtons;
49
50
  this.likeCount = common_1.stripToInt(BaseVideo.parseButtonRenderer(topLevelButtons[0]));
50
- this.dislikeCount = common_1.stripToInt(BaseVideo.parseButtonRenderer(topLevelButtons[1]));
51
51
  // Tags and description
52
52
  this.tags =
53
53
  ((_b = (_a = videoInfo.superTitleLink) === null || _a === void 0 ? void 0 : _a.runs) === null || _b === void 0 ? void 0 : _b.map((r) => r.text.trim()).filter((t) => t)) || [];
@@ -43,6 +43,8 @@ class Channel extends ChannelCompact_1.default {
43
43
  if (!shelfRenderer)
44
44
  continue;
45
45
  const { title, content, subtitle } = shelfRenderer;
46
+ if (!content.horizontalListRenderer)
47
+ continue;
46
48
  const items = content.horizontalListRenderer.items
47
49
  .map((i) => {
48
50
  if (i.gridVideoRenderer)
@@ -8,15 +8,15 @@ export declare namespace Client {
8
8
  type SearchOptions = {
9
9
  /** Search type, can be `"video"`, `"channel"`, `"playlist"`, or `"all"` */
10
10
  type: SearchType;
11
+ /** Raw search params to be passed on the request, ignores `type` value if this is provided */
12
+ params: string;
11
13
  };
12
14
  type ClientOptions = {
13
15
  cookie: string;
14
- /** 2-chars language code for localization */
15
- hl: string;
16
- /** 2-chars country code */
17
- gl: string;
18
16
  /** Optional options for http client */
19
- httpOptions: Partial<RequestOptions>;
17
+ requestOptions: Partial<RequestOptions>;
18
+ /** Optional options passed when sending a request to youtube (context.client) */
19
+ youtubeClientOptions: Record<string, unknown>;
20
20
  /** Use Node `https` module, set false to use `http` */
21
21
  https: boolean;
22
22
  };
@@ -25,8 +25,6 @@ export declare namespace Client {
25
25
  export default class Client {
26
26
  /** @hidden */
27
27
  http: HTTP;
28
- /** @hidden */
29
- options: Client.ClientOptions;
30
28
  constructor(options?: Partial<Client.ClientOptions>);
31
29
  /**
32
30
  * Searches for videos / playlists / channels
@@ -15,8 +15,8 @@ const _1 = require(".");
15
15
  /** Youtube Client */
16
16
  class Client {
17
17
  constructor(options = {}) {
18
- this.options = Object.assign({ hl: "en", gl: "US", cookie: "", https: true, httpOptions: {} }, options);
19
- this.http = new common_1.HTTP(this, options.httpOptions);
18
+ const fullOptions = Object.assign(Object.assign({ cookie: "", https: true, requestOptions: {} }, options), { youtubeClientOptions: Object.assign({ hl: "en", gl: "US" }, options.youtubeClientOptions) });
19
+ this.http = new common_1.HTTP(fullOptions);
20
20
  }
21
21
  /**
22
22
  * Searches for videos / playlists / channels
@@ -27,7 +27,7 @@ class Client {
27
27
  */
28
28
  search(query, searchOptions) {
29
29
  return __awaiter(this, void 0, void 0, function* () {
30
- const options = Object.assign({ type: "all" }, searchOptions);
30
+ const options = Object.assign({ type: "all", params: "" }, searchOptions);
31
31
  const result = new _1.SearchResult().load(this);
32
32
  yield result.init(query, options);
33
33
  return result;
@@ -30,14 +30,14 @@ class LiveVideo extends _1.BaseVideo {
30
30
  * @hidden
31
31
  */
32
32
  load(data) {
33
+ var _a;
33
34
  super.load(data);
34
35
  const videoInfo = _1.BaseVideo.parseRawData(data);
35
36
  this.watchingCount = +videoInfo.viewCount.videoViewCountRenderer.viewCount.runs
36
37
  .map((r) => r.text)
37
38
  .join(" ")
38
39
  .replace(/[^0-9]/g, "");
39
- this.chatContinuation =
40
- data[3].response.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer.continuations[0].reloadContinuationData.continuation;
40
+ this.chatContinuation = (_a = data[3].response.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer) === null || _a === void 0 ? void 0 : _a.continuations[0].reloadContinuationData.continuation;
41
41
  return this;
42
42
  }
43
43
  /**
@@ -65,6 +65,8 @@ class LiveVideo extends _1.BaseVideo {
65
65
  const response = yield this.client.http.post(constants_1.LIVE_CHAT_END_POINT, {
66
66
  data: { continuation: this.chatContinuation },
67
67
  });
68
+ if (!response.continuationContents)
69
+ return;
68
70
  this.parseChat(response.data);
69
71
  const timedContinuation = response.data.continuationContents.liveChatContinuation.continuations[0]
70
72
  .timedContinuationData;
@@ -27,12 +27,14 @@ class Playlist extends _1.Base {
27
27
  * @hidden
28
28
  */
29
29
  load(data) {
30
- var _a;
30
+ var _a, _b, _c;
31
31
  const sidebarRenderer = data.sidebar.playlistSidebarRenderer.items;
32
32
  const primaryRenderer = sidebarRenderer[0].playlistSidebarPrimaryInfoRenderer;
33
+ const metadata = data.metadata.playlistMetadataRenderer;
33
34
  // Basic information
34
- this.id = primaryRenderer.title.runs[0].navigationEndpoint.watchEndpoint.playlistId;
35
- this.title = primaryRenderer.title.runs[0].text;
35
+ this.id = (_a = Object.values(metadata)
36
+ .find((v) => v.includes("playlist?list="))) === null || _a === void 0 ? void 0 : _a.split("=")[1];
37
+ this.title = metadata.title;
36
38
  const { stats } = primaryRenderer;
37
39
  if (primaryRenderer.stats.length === 3) {
38
40
  this.videoCount = Playlist.parseSideBarInfo(stats[0], true);
@@ -43,13 +45,13 @@ class Playlist extends _1.Base {
43
45
  this.videoCount = Playlist.parseSideBarInfo(stats[0], true);
44
46
  this.lastUpdatedAt = Playlist.parseSideBarInfo(stats[1], false);
45
47
  }
46
- const playlistContents = data.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.content
48
+ const playlistContents = ((_b = data.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.content
47
49
  .sectionListRenderer.contents[0].itemSectionRenderer.contents[0]
48
- .playlistVideoListRenderer.contents;
50
+ .playlistVideoListRenderer) === null || _b === void 0 ? void 0 : _b.contents) || [];
49
51
  // Video Continuation Token
50
52
  this.continuation = common_1.getContinuationFromItems(playlistContents);
51
53
  // Channel
52
- const videoOwner = (_a = sidebarRenderer[1]) === null || _a === void 0 ? void 0 : _a.playlistSidebarSecondaryInfoRenderer.videoOwner;
54
+ const videoOwner = (_c = sidebarRenderer[1]) === null || _c === void 0 ? void 0 : _c.playlistSidebarSecondaryInfoRenderer.videoOwner;
53
55
  if (videoOwner) {
54
56
  const { title, thumbnail } = videoOwner.videoOwnerRenderer;
55
57
  this.channel = new _1.ChannelCompact({
@@ -66,7 +66,10 @@ let SearchResult = SearchResult_1 = class SearchResult extends Array {
66
66
  init(query, options) {
67
67
  return __awaiter(this, void 0, void 0, function* () {
68
68
  const response = yield this.client.http.post(`${constants_1.I_END_POINT}/search`, {
69
- data: { query, params: SearchResult_1.getSearchTypeParam(options.type) },
69
+ data: {
70
+ query,
71
+ params: options.params || SearchResult_1.getSearchTypeParam(options.type),
72
+ },
70
73
  });
71
74
  this.estimatedResults = +response.data.estimatedResults;
72
75
  if (this.estimatedResults > 0) {
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import https from "https";
3
3
  import { YoutubeRawData } from "./types";
4
- import { Client } from "../classes";
4
+ import { Client } from "../classes/Client";
5
5
  interface Options extends https.RequestOptions {
6
6
  params: Record<string, any>;
7
7
  data: any;
@@ -10,10 +10,9 @@ interface Options extends https.RequestOptions {
10
10
  export default class HTTP {
11
11
  private _httpClient;
12
12
  private _cookie;
13
- private _hl;
14
- private _gl;
15
- private _defaultOptions;
16
- constructor(client: Client, defaultOptions?: Partial<https.RequestOptions>);
13
+ private _defaultRequestOptions;
14
+ private _defaultClientOptions;
15
+ constructor({ cookie, requestOptions, youtubeClientOptions, https: useHttps, }: Client.ClientOptions);
17
16
  /** Send GET request to Youtube */
18
17
  get(path: string, options: Partial<Options>): Promise<YoutubeRawData>;
19
18
  /** Send POST request to Youtube */
@@ -19,13 +19,11 @@ const zlib_1 = __importDefault(require("zlib"));
19
19
  const querystring_1 = __importDefault(require("querystring"));
20
20
  const constants_1 = require("../constants");
21
21
  class HTTP {
22
- constructor(client, defaultOptions = {}) {
23
- const { hl, cookie, gl, https: useHttps } = client.options;
24
- this._httpClient = useHttps ? https_1.default : http_1.default;
22
+ constructor({ cookie, requestOptions, youtubeClientOptions, https: useHttps, }) {
25
23
  this._cookie = cookie;
26
- this._hl = hl;
27
- this._gl = gl;
28
- this._defaultOptions = defaultOptions;
24
+ this._defaultRequestOptions = requestOptions;
25
+ this._defaultClientOptions = youtubeClientOptions;
26
+ this._httpClient = useHttps ? https_1.default : http_1.default;
29
27
  }
30
28
  /** Send GET request to Youtube */
31
29
  get(path, options) {
@@ -38,12 +36,7 @@ class HTTP {
38
36
  post(path, options) {
39
37
  return __awaiter(this, void 0, void 0, function* () {
40
38
  options = Object.assign(Object.assign({ method: "POST", path }, options), { params: Object.assign({ key: constants_1.INNERTUBE_API_KEY }, options.params), data: Object.assign({ context: {
41
- client: {
42
- clientName: "WEB",
43
- clientVersion: constants_1.INNERTUBE_CLIENT_VERSION,
44
- hl: this._hl,
45
- gl: this._gl,
46
- },
39
+ client: Object.assign({ clientName: "WEB", clientVersion: constants_1.INNERTUBE_CLIENT_VERSION }, this._defaultClientOptions),
47
40
  } }, options.data) });
48
41
  return yield this.request(options);
49
42
  });
@@ -53,11 +46,10 @@ class HTTP {
53
46
  */
54
47
  request(partialOptions) {
55
48
  return new Promise((resolve, reject) => {
56
- const options = Object.assign(Object.assign(Object.assign({ hostname: constants_1.BASE_URL, port: 443 }, partialOptions), this._defaultOptions), { path: `${partialOptions.path}?${querystring_1.default.stringify(partialOptions.params)}`, headers: Object.assign({ "x-youtube-client-version": constants_1.INNERTUBE_CLIENT_VERSION, "x-youtube-client-name": "1", "content-type": "application/json", "accept-encoding": "gzip", cookie: this._cookie }, partialOptions.headers) });
49
+ const options = Object.assign(Object.assign(Object.assign({ hostname: constants_1.BASE_URL, port: 443 }, partialOptions), this._defaultRequestOptions), { path: `${partialOptions.path}?${querystring_1.default.stringify(partialOptions.params)}`, headers: Object.assign({ "x-youtube-client-version": constants_1.INNERTUBE_CLIENT_VERSION, "x-youtube-client-name": "1", "content-type": "application/json", "accept-encoding": "gzip", cookie: this._cookie }, partialOptions.headers) });
57
50
  let body = options.data || "";
58
- if (options.data) {
51
+ if (options.data)
59
52
  body = JSON.stringify(body);
60
- }
61
53
  const request = this._httpClient.request(options, (res) => {
62
54
  var _a, _b;
63
55
  if ((_a = res.headers["set-cookie"]) === null || _a === void 0 ? void 0 : _a.length)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youtubei",
3
- "version": "0.0.1-rc.24",
3
+ "version": "0.0.1-rc.28",
4
4
  "description": "Simple package to get information from youtube such as videos, playlists, channels, video information & comments, related videos, up next video, and more!",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,89 +0,0 @@
1
- import { YoutubeRawData } from "../common";
2
- import { Base, PlaylistCompact, Thumbnails, VideoCompact, BaseAttributes } from ".";
3
- /** @hidden */
4
- interface CompactChannelAttributes extends BaseAttributes {
5
- name: string;
6
- thumbnails?: Thumbnails;
7
- videoCount?: number;
8
- subscriberCount?: string;
9
- }
10
- /** Represents a Youtube Channel */
11
- export default class CompactChannel extends Base implements CompactChannelAttributes {
12
- /** The channel's name */
13
- name: string;
14
- /** Thumbnails of the Channel with different sizes */
15
- thumbnails?: Thumbnails;
16
- /** How many video does this channel have */
17
- videoCount?: number;
18
- /**
19
- * How many subscriber does this channel have,
20
- *
21
- * This is not the exact amount, but a literal string like `"1.95M subscribers"`
22
- */
23
- subscriberCount?: string;
24
- /** Loaded videos on the channel, fetched from `channel.nextVideos()` */
25
- videos: VideoCompact[];
26
- /** Loaded playlists on the channel, fetched from `channel.nextPlaylists()` */
27
- playlists: PlaylistCompact[];
28
- private _videoContinuation?;
29
- private _playlistContinuation?;
30
- /** @hidden */
31
- constructor(channel?: Partial<CompactChannelAttributes>);
32
- /** The URL of the channel page */
33
- get url(): string;
34
- /**
35
- * Load this instance with raw data from Youtube
36
- *
37
- * @hidden
38
- */
39
- load(data: YoutubeRawData): CompactChannel;
40
- /**
41
- * Load next 30 videos made by the channel, and push the loaded videos to {@link Channel.videos}
42
- *
43
- * @example
44
- * ```js
45
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
46
- * await channel.nextVideos();
47
- * console.log(channel.videos) // first 30 videos
48
- *
49
- * let newVideos = await channel.nextVideos();
50
- * console.log(newVideos) // 30 loaded videos
51
- * console.log(channel.videos) // first 60 videos
52
- *
53
- * await channel.nextVideos(0); // load the rest of the videos in the channel
54
- * ```
55
- *
56
- * @param count How many time to load the next videos, pass `0` to load all
57
- *
58
- * @return New loaded videos
59
- */
60
- nextVideos(count?: number): Promise<VideoCompact[]>;
61
- /**
62
- * Load next 30 playlists made by the channel, and push the loaded playlists to {@link Channel.playlists}
63
- *
64
- * @example
65
- * ```js
66
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
67
- * await channel.nextPlaylists();
68
- * console.log(channel.playlists) // first 30 playlists
69
- *
70
- * let newPlaylists = await channel.nextPlaylists();
71
- * console.log(newPlaylists) // 30 loaded playlists
72
- * console.log(channel.playlists) // first 60 playlists
73
- *
74
- * await channel.nextPlaylists(0); // load the rest of the playlists in the channel
75
- * ```
76
- *
77
- * @param count How many time to load the next playlists, pass `0` to load all
78
- *
79
- * @return New loaded playlists
80
- */
81
- nextPlaylists(count?: number): Promise<PlaylistCompact[]>;
82
- /** Get tab data from youtube */
83
- private getTabData;
84
- /** Parse tab data from request, tab name is ignored if it's a continuation data */
85
- private static parseTabData;
86
- /** Get continuation token from items (if exists) */
87
- private static getContinuationFromItems;
88
- }
89
- export {};
@@ -1,142 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const common_1 = require("../common");
13
- const _1 = require(".");
14
- const constants_1 = require("../constants");
15
- /** Represents a Youtube Channel */
16
- class CompactChannel extends _1.Base {
17
- /** @hidden */
18
- constructor(channel = {}) {
19
- super();
20
- this._videoContinuation = null;
21
- this._playlistContinuation = null;
22
- Object.assign(this, channel);
23
- this.videos = [];
24
- this.playlists = [];
25
- }
26
- /** The URL of the channel page */
27
- get url() {
28
- return `https://www.youtube.com/channel/${this.id}`;
29
- }
30
- /**
31
- * Load this instance with raw data from Youtube
32
- *
33
- * @hidden
34
- */
35
- load(data) {
36
- const { channelId, title, thumbnail, videoCountText, subscriberCountText } = data;
37
- this.id = channelId;
38
- this.name = title.simpleText;
39
- this.thumbnails = new _1.Thumbnails().load(thumbnail.thumbnails);
40
- this.videoCount = common_1.stripToInt(videoCountText === null || videoCountText === void 0 ? void 0 : videoCountText.runs[0].text) || 0;
41
- this.subscriberCount = subscriberCountText === null || subscriberCountText === void 0 ? void 0 : subscriberCountText.simpleText;
42
- this.videos = [];
43
- this.playlists = [];
44
- return this;
45
- }
46
- /**
47
- * Load next 30 videos made by the channel, and push the loaded videos to {@link Channel.videos}
48
- *
49
- * @example
50
- * ```js
51
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
52
- * await channel.nextVideos();
53
- * console.log(channel.videos) // first 30 videos
54
- *
55
- * let newVideos = await channel.nextVideos();
56
- * console.log(newVideos) // 30 loaded videos
57
- * console.log(channel.videos) // first 60 videos
58
- *
59
- * await channel.nextVideos(0); // load the rest of the videos in the channel
60
- * ```
61
- *
62
- * @param count How many time to load the next videos, pass `0` to load all
63
- *
64
- * @return New loaded videos
65
- */
66
- nextVideos(count = 1) {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- const newVideos = [];
69
- for (let i = 0; i < count || count == 0; i++) {
70
- if (this._videoContinuation === undefined)
71
- break;
72
- const items = yield this.getTabData("videos");
73
- this._videoContinuation = CompactChannel.getContinuationFromItems(items);
74
- newVideos.push(...items
75
- .filter((i) => i.gridVideoRenderer)
76
- .map((i) => new _1.VideoCompact({ client: this.client }).load(i.gridVideoRenderer)));
77
- }
78
- this.videos.push(...newVideos);
79
- return newVideos;
80
- });
81
- }
82
- /**
83
- * Load next 30 playlists made by the channel, and push the loaded playlists to {@link Channel.playlists}
84
- *
85
- * @example
86
- * ```js
87
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
88
- * await channel.nextPlaylists();
89
- * console.log(channel.playlists) // first 30 playlists
90
- *
91
- * let newPlaylists = await channel.nextPlaylists();
92
- * console.log(newPlaylists) // 30 loaded playlists
93
- * console.log(channel.playlists) // first 60 playlists
94
- *
95
- * await channel.nextPlaylists(0); // load the rest of the playlists in the channel
96
- * ```
97
- *
98
- * @param count How many time to load the next playlists, pass `0` to load all
99
- *
100
- * @return New loaded playlists
101
- */
102
- nextPlaylists(count = 1) {
103
- return __awaiter(this, void 0, void 0, function* () {
104
- const newPlaylists = [];
105
- for (let i = 0; i < count || count == 0; i++) {
106
- if (this._playlistContinuation === undefined)
107
- break;
108
- const items = yield this.getTabData("playlists");
109
- this._playlistContinuation = CompactChannel.getContinuationFromItems(items);
110
- newPlaylists.push(...items
111
- .filter((i) => i.gridPlaylistRenderer)
112
- .map((i) => new _1.PlaylistCompact({ client: this.client }).load(i.gridPlaylistRenderer)));
113
- }
114
- this.playlists.push(...newPlaylists);
115
- return newPlaylists;
116
- });
117
- }
118
- /** Get tab data from youtube */
119
- getTabData(name) {
120
- return __awaiter(this, void 0, void 0, function* () {
121
- const params = name === "videos" ? "EgZ2aWRlb3M%3D" : "EglwbGF5bGlzdHMgAQ%3D%3D";
122
- const continuation = name === "videos" ? this._videoContinuation : this._playlistContinuation;
123
- const response = yield this.client.http.post(`${constants_1.I_END_POINT}/browse`, {
124
- data: { browseId: this.id, params, continuation },
125
- });
126
- return CompactChannel.parseTabData(name, response.data);
127
- });
128
- }
129
- /** Parse tab data from request, tab name is ignored if it's a continuation data */
130
- static parseTabData(name, data) {
131
- var _a;
132
- const index = name === "videos" ? 1 : 2;
133
- return (((_a = data.contents) === null || _a === void 0 ? void 0 : _a.twoColumnBrowseResultsRenderer.tabs[index].tabRenderer.content.sectionListRenderer.contents[0].itemSectionRenderer.contents[0].gridRenderer.items) ||
134
- data.onResponseReceivedActions[0].appendContinuationItemsAction.continuationItems);
135
- }
136
- /** Get continuation token from items (if exists) */
137
- static getContinuationFromItems(items) {
138
- var _a;
139
- return (_a = items[items.length - 1].continuationItemRenderer) === null || _a === void 0 ? void 0 : _a.continuationEndpoint.continuationCommand.token;
140
- }
141
- }
142
- exports.default = CompactChannel;