Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

better-youtube-api

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

better-youtube-api - npm Package Compare versions

Comparing version 2.1.5 to 2.1.6

out/services/generic-service.js

244

out/index.js

@@ -17,4 +17,4 @@ "use strict";

const util_1 = require("./util");
const caching_1 = require("./util/caching");
const oauth_1 = require("./oauth");
const services_1 = require("./services");
__export(require("./entities"));

@@ -38,3 +38,3 @@ /**

if (options.cacheCheckInterval > 0) {
setInterval(caching_1.Cache.checkTTLs, options.cacheCheckInterval * 1000);
setInterval(util_1.Cache.checkTTLs, options.cacheCheckInterval * 1000);
}

@@ -47,3 +47,3 @@ }

this._token = val;
this.tokenType = val.startsWith('ya29') ? 'oauth' : 'key';
this._tokenType = val.startsWith('ya29') ? 'oauth' : 'key';
}

@@ -54,3 +54,3 @@ _cache(id, value) {

}
caching_1.Cache.set(id, value, this._cacheTTL > 0 ? this._cacheTTL * 1000 + new Date().getTime() : 0);
util_1.Cache.set(id, value, this._cacheTTL > 0 ? this._cacheTTL * 1000 + new Date().getTime() : 0);
}

@@ -65,3 +65,3 @@ /**

search(types, searchTerm, maxResults = 10, pageToken) {
return this._search(types, searchTerm, maxResults, pageToken);
return services_1.SearchService.search(this, types, searchTerm, maxResults, pageToken);
}

@@ -101,4 +101,4 @@ /**

return __awaiter(this, void 0, void 0, function* () {
const id = yield this.getId(videoResolvable, 'video');
return this.getItemById(entities_1.Video, id);
const id = yield services_1.GenericService.getId(this, videoResolvable, 'video');
return services_1.GenericService.getItemById(this, entities_1.Video, id);
});

@@ -112,4 +112,4 @@ }

return __awaiter(this, void 0, void 0, function* () {
const id = yield this.getId(channelResolvable, 'channel');
return this.getItemById(entities_1.Channel, id);
const id = yield services_1.GenericService.getId(this, channelResolvable, 'channel');
return services_1.GenericService.getItemById(this, entities_1.Channel, id);
});

@@ -123,4 +123,4 @@ }

return __awaiter(this, void 0, void 0, function* () {
const id = yield this.getId(playlistResolvable, 'playlist');
return this.getItemById(entities_1.Playlist, id);
const id = yield services_1.GenericService.getId(this, playlistResolvable, 'playlist');
return services_1.GenericService.getItemById(this, entities_1.Playlist, id);
});

@@ -133,3 +133,3 @@ }

getComment(commentId) {
return this.getItemById(entities_1.YTComment, commentId);
return services_1.GenericService.getItemById(this, entities_1.YTComment, commentId);
}

@@ -147,3 +147,3 @@ /**

}
return this.getItemById(entities_1.Video, id.video);
return services_1.GenericService.getItemById(this, entities_1.Video, id.video);
}

@@ -161,3 +161,3 @@ /**

}
return this.getItemById(entities_1.Channel, id.channel);
return services_1.GenericService.getItemById(this, entities_1.Channel, id.channel);
}

@@ -175,3 +175,3 @@ /**

}
return this.getItemById(entities_1.Playlist, id.playlist);
return services_1.GenericService.getItemById(this, entities_1.Playlist, id.playlist);
}

@@ -185,4 +185,4 @@ /**

return __awaiter(this, void 0, void 0, function* () {
const playlistId = yield this.getId(playlistResolvable, 'playlist');
return this.getPaginatedItems('playlistItems', playlistId, maxResults);
const playlistId = yield services_1.GenericService.getId(this, playlistResolvable, 'playlist');
return services_1.GenericService.getPaginatedItems(this, 'playlistItems', playlistId, maxResults);
});

@@ -197,4 +197,4 @@ }

return __awaiter(this, void 0, void 0, function* () {
const videoId = yield this.getId(videoResolvable, 'video');
return this.getPaginatedItems('commentThreads:video', videoId, maxResults);
const videoId = yield services_1.GenericService.getId(this, videoResolvable, 'video');
return services_1.GenericService.getPaginatedItems(this, 'commentThreads:video', videoId, maxResults);
});

@@ -209,4 +209,4 @@ }

return __awaiter(this, void 0, void 0, function* () {
const channelId = yield this.getId(channelResolvable, 'channel');
return this.getPaginatedItems('commentThreads:channel', channelId, maxResults);
const channelId = yield services_1.GenericService.getId(this, channelResolvable, 'channel');
return services_1.GenericService.getPaginatedItems(this, 'commentThreads:channel', channelId, maxResults);
});

@@ -221,4 +221,4 @@ }

return __awaiter(this, void 0, void 0, function* () {
const channelId = yield this.getId(channelResolvable, 'channel');
return this.getPaginatedItems('playlists:channel', channelId, maxResults);
const channelId = yield services_1.GenericService.getId(this, channelResolvable, 'channel');
return services_1.GenericService.getPaginatedItems(this, 'playlists:channel', channelId, maxResults);
});

@@ -232,200 +232,4 @@ }

getCommentReplies(commentId, maxResults = -1) {
return this.getPaginatedItems('comments', commentId, maxResults);
return services_1.GenericService.getPaginatedItems(this, 'comments', commentId, maxResults);
}
/* istanbul ignore next */
_search(types, searchTerm, maxResults = 10, pageToken) {
return __awaiter(this, void 0, void 0, function* () {
const type = types.map(t => t.endpoint.substring(0, t.endpoint.length - 1)).join(',');
const cached = caching_1.Cache.get(`search://${type}/"${searchTerm}"/${maxResults}/"${pageToken}"`);
if (this._shouldCache && cached) {
return cached;
}
if (maxResults < 1 || maxResults > 50) {
return Promise.reject('Max results must be greater than 0 and less than or equal to 50');
}
const fields = 'prevPageToken,nextPageToken,items(kind,id,snippet(title,description,thumbnails,publishedAt,channelId))';
const data = {
q: encodeURIComponent(searchTerm),
fields: encodeURIComponent(fields),
maxResults,
part: 'snippet',
type
};
if (pageToken) {
data.pageToken = pageToken;
}
const results = yield util_1.request.api('search', data, this.token, this.tokenType);
const items = [];
results.items.forEach(item => {
if (item.id.videoId) {
items.push(new entities_1.Video(this, item));
}
else if (item.id.channelId) {
items.push(new entities_1.Channel(this, item));
}
else if (item.id.playlistId) {
items.push(new entities_1.Playlist(this, item));
}
});
const toReturn = { results: items, prevPageToken: results.prevPageToken, nextPageToken: results.nextPageToken };
if (this._shouldCache && this._cacheSearches) {
this._cache(`search://${type}/"${searchTerm}"/${maxResults}/"${pageToken}"`, toReturn);
}
return toReturn;
});
}
/* istanbul ignore next */
getItemById(type, id) {
return __awaiter(this, void 0, void 0, function* () {
if (!([entities_1.Video, entities_1.Channel, entities_1.Playlist, entities_1.YTComment].includes(type))) {
return Promise.reject('Type must be a video, channel, playlist, or comment.');
}
const cached = caching_1.Cache.get(`get://${type.endpoint}/${id}`);
if (this._shouldCache && cached) {
return cached;
}
const result = yield util_1.request.api(type.endpoint, {
id,
fields: encodeURIComponent(type.fields),
part: type.part
}, this.token, this.tokenType);
if (result.items.length === 0) {
return Promise.reject('Item not found');
}
let endResult = new type(this, result.items[0], result.items[0].snippet.channelId ? 'channel' : 'video');
if (this._shouldCache) {
this._cache(`get://${type.endpoint}/${id}`, endResult);
}
return endResult;
});
}
/* istanbul ignore next */
getPaginatedItems(endpoint, id, maxResults = -1) {
return __awaiter(this, void 0, void 0, function* () {
const cached = caching_1.Cache.get(`get://${endpoint}/${id}/${maxResults}`);
if (this._shouldCache && cached) {
return cached;
}
let items = [];
const full = maxResults <= 0;
const options = {
part: 'snippet',
maxResults: 0
};
let max;
let clazz;
let commentType;
if (endpoint === 'playlistItems') {
max = 50;
clazz = entities_1.Video;
options.playlistId = id;
}
else if (endpoint.startsWith('commentThreads')) {
max = 100;
clazz = entities_1.YTComment;
const [, type] = endpoint.split(':');
commentType = type ? type : 'video';
endpoint = 'commentThreads';
options[`${type}Id`] = id;
options.part += ',replies';
options.textFormat = 'plainText';
}
else if (endpoint === 'comments') {
max = 100;
clazz = entities_1.YTComment;
options.parentId = id;
}
else if (endpoint === 'playlists:channel') {
max = 50;
clazz = entities_1.Playlist;
endpoint = 'playlists';
options.part += ',contentDetails,player';
options.channelId = id;
}
else {
return Promise.reject('Unknown item type ' + endpoint);
}
if (maxResults > max) {
return Promise.reject(`Max results must be ${max} or below for ${endpoint}`);
}
options.maxResults = full ? max : maxResults;
let results;
let pages = null;
let shouldReturn = !full;
for (let i = 1; i < pages ? pages : 3; i++) {
results = yield util_1.request.api(endpoint, options, this.token, this.tokenType).catch(() => {
return Promise.reject('Items not found');
});
if (results.items.length === 0) {
return Promise.reject('Items not found');
}
if (!pages) {
pages = results.pageInfo.totalResults / results.pageInfo.resultsPerPage;
if (pages <= 1) {
shouldReturn = true;
}
pages = Math.floor(pages);
}
results.items.forEach(item => {
let comment;
if (item.snippet.topLevelComment) {
comment = new entities_1.YTComment(this, item.snippet.topLevelComment, commentType);
items.push(comment);
}
else {
items.push(new clazz(this, item, commentType));
}
if (item.replies) {
item.replies.comments.forEach(reply => {
const created = new entities_1.YTComment(this, reply, commentType);
comment.replies.push(created);
});
}
});
if (results.nextPageToken && !shouldReturn) {
options.pageToken = results.nextPageToken;
}
else {
return items;
}
}
if (this._shouldCache) {
this._cache(`get://${endpoint}/${id}/${maxResults}`, items);
}
return items;
});
}
/* istanbul ignore next */
getId(input, type) {
return __awaiter(this, void 0, void 0, function* () {
let id = null;
if (input.includes('youtube.com') || input.includes('youtu.be')) {
const idFromUrl = util_1.parseUrl(input)[type];
// Custom channel URLs don't work that well
if (type === 'channel' && idFromUrl && !idFromUrl.startsWith('UC')) {
id = yield util_1.request.api('search', { q: idFromUrl, type, part: 'id' }, this.token, this.tokenType).then(r => r.items[0] ? r.items[0].id.channelId : undefined);
}
id = idFromUrl;
}
if (id !== null && id !== undefined && id !== '') {
return id;
}
if (type === 'channel' && (!input.startsWith('UC') || input.includes(' '))) {
id = yield util_1.request.api('search', { q: input, type, part: 'id', maxResults: 1 }, this.token, this.tokenType).then(r => r.items[0] ? r.items[0].id.channelId : undefined);
}
else if (type === 'playlist' && input.includes(' ')) {
id = yield util_1.request.api('search', { q: input, type, part: 'id', maxResults: 1 }, this.token, this.tokenType).then(r => r.items[0] ? r.items[0].id.playlistId : undefined);
}
else if (type === 'video' && (input.length < 11 || input.includes(' '))) {
id = yield util_1.request.api('search', { q: input, type, part: 'id', maxResults: 1 }, this.token, this.tokenType).then(r => r.items[0] ? r.items[0].id.videoId : undefined);
}
else {
id = input;
}
if (id === null || id === undefined || id === '') {
return Promise.reject('Item not found');
}
return id;
});
}
}

@@ -432,0 +236,0 @@ exports.YouTube = YouTube;

@@ -26,3 +26,3 @@ "use strict";

checkTokenAndThrow() {
if (this.youtube.tokenType !== 'oauth') {
if (this.youtube._tokenType !== 'oauth') {
throw new Error('Token is not an oauth token');

@@ -29,0 +29,0 @@ }

@@ -8,3 +8,4 @@ "use strict";

__export(require("./request"));
__export(require("./caching"));
//# sourceMappingURL=index.js.map
{
"name": "better-youtube-api",
"version": "2.1.5",
"version": "2.1.6",
"description": "A very easy to use promise-based Youtube Data v3 API.",

@@ -5,0 +5,0 @@ "main": "out/index.js",

@@ -62,1 +62,8 @@ # Better YouTube API

Note: This wrapper does not implement every feature of the YouTube API. With a single developer working on it, there just isn't time for everything to be implemented. Some of the objectively most-important features have been added. The limits imposed by the wrapper are not imposed by YouTube.
# Development
## Before committing:
* Run TSLint.
* Run `npm run coverage` to check if you've added enough tests. It should display 100% statement, line, and branch coverage.
* Run `yarn test` or `npm run test` and make sure that every test passes.

@@ -9,8 +9,8 @@ import { Video, Channel, Playlist, YTComment } from './entities';

export declare class YouTube {
private _shouldCache;
private _cacheSearches;
private _cacheTTL;
_shouldCache: boolean;
_cacheSearches: boolean;
_cacheTTL: number;
_tokenType: 'key' | 'oauth';
private _token;
token: string;
tokenType: 'key' | 'oauth';
/**

@@ -141,6 +141,2 @@ * Methods requiring an OAuth token

getCommentReplies(commentId: string, maxResults?: number): Promise<YTComment[]>;
private _search;
private getItemById;
private getPaginatedItems;
private getId;
}

@@ -147,0 +143,0 @@ declare type YouTubeOptions = {

export * from './util';
export * from './request';
export * from './caching';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc