ytsearcher
Advanced tools
Comparing version 1.0.3 to 1.1.0
{ | ||
"env": { | ||
"node": true, | ||
"es6": true | ||
}, | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"ecmaVersion": 2017, | ||
"sourceType": "module" | ||
}, | ||
"rules": { | ||
"indent": [ | ||
"error", | ||
"tab" | ||
], | ||
"linebreak-style": [ | ||
"error", | ||
"unix" | ||
], | ||
"quotes": [ | ||
"error", | ||
"double" | ||
], | ||
"semi": [ | ||
"error", | ||
"always" | ||
], | ||
"strict": 1, | ||
"indent": 0, | ||
"quotes": 0, | ||
"no-undef": 1, | ||
"no-console": 0, | ||
"no-mixed-spaces-and-tabs": 1, | ||
"no-unused-vars": 1, | ||
"semi": 1 | ||
} | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"ecmaVersion": 2017 | ||
}, | ||
"env": { | ||
"es6": true, | ||
"node": true | ||
}, | ||
"overrides": [ | ||
{ "files": ["*.browser.js"], "env": { "browser": true } } | ||
], | ||
"rules": { | ||
"no-await-in-loop": "warn", | ||
"no-compare-neg-zero": "error", | ||
"no-extra-parens": ["warn", "all", { | ||
"nestedBinaryExpressions": false | ||
}], | ||
"no-template-curly-in-string": "error", | ||
"no-unsafe-negation": "error", | ||
"valid-jsdoc": ["error", { | ||
"requireReturn": false, | ||
"requireReturnDescription": false, | ||
"prefer": { | ||
"return": "return", | ||
"arg": "param" | ||
}, | ||
"preferType": { | ||
"String": "string", | ||
"Number": "number", | ||
"Boolean": "boolean", | ||
"Symbol": "symbol", | ||
"object": "Object", | ||
"function": "Function", | ||
"array": "Array", | ||
"date": "Date", | ||
"error": "Error", | ||
"null": "void" | ||
} | ||
}], | ||
"accessor-pairs": "warn", | ||
"array-callback-return": "error", | ||
"complexity": "warn", | ||
"consistent-return": "error", | ||
"curly": ["error", "multi-line", "consistent"], | ||
"dot-location": ["error", "property"], | ||
"dot-notation": "error", | ||
"eqeqeq": "error", | ||
"no-empty-function": "error", | ||
"no-floating-decimal": "error", | ||
"no-implied-eval": "error", | ||
"no-invalid-this": "error", | ||
"no-lone-blocks": "error", | ||
"no-multi-spaces": "error", | ||
"no-new-func": "error", | ||
"no-new-wrappers": "error", | ||
"no-new": "error", | ||
"no-octal-escape": "error", | ||
"no-return-assign": "error", | ||
"no-return-await": "error", | ||
"no-self-compare": "error", | ||
"no-sequences": "error", | ||
"no-throw-literal": "error", | ||
"no-unmodified-loop-condition": "error", | ||
"no-unused-expressions": "error", | ||
"no-useless-call": "error", | ||
"no-useless-concat": "error", | ||
"no-useless-escape": "error", | ||
"no-useless-return": "error", | ||
"no-void": "error", | ||
"no-warning-comments": "warn", | ||
"prefer-promise-reject-errors": "error", | ||
"require-await": "warn", | ||
"wrap-iife": "error", | ||
"yoda": "error", | ||
"no-label-var": "error", | ||
"no-shadow": "error", | ||
"no-undef-init": "error", | ||
"callback-return": "error", | ||
"handle-callback-err": "error", | ||
"no-mixed-requires": "error", | ||
"no-new-require": "error", | ||
"no-path-concat": "error", | ||
"array-bracket-spacing": "error", | ||
"block-spacing": "error", | ||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }], | ||
"comma-dangle": ["error", "always-multiline"], | ||
"comma-spacing": "error", | ||
"comma-style": "error", | ||
"computed-property-spacing": "error", | ||
"consistent-this": ["error", "$this"], | ||
"eol-last": "error", | ||
"func-names": "error", | ||
"func-name-matching": "error", | ||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }], | ||
"indent": ["error", 2, { "SwitchCase": 1 }], | ||
"key-spacing": "error", | ||
"keyword-spacing": "error", | ||
"max-depth": "error", | ||
"max-len": ["error", 140, 2], | ||
"max-nested-callbacks": ["error", { "max": 4 }], | ||
"max-statements-per-line": ["error", { "max": 2 }], | ||
"new-cap": "off", | ||
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 3 }], | ||
"no-array-constructor": "error", | ||
"no-lonely-if": "error", | ||
"no-mixed-operators": "error", | ||
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], | ||
"no-new-object": "error", | ||
"no-spaced-func": "error", | ||
"no-trailing-spaces": "error", | ||
"no-unneeded-ternary": "error", | ||
"no-whitespace-before-property": "error", | ||
"nonblock-statement-body-position": "error", | ||
"object-curly-spacing": ["error", "always"], | ||
"operator-assignment": "error", | ||
"operator-linebreak": ["error", "after"], | ||
"padded-blocks": ["error", "never"], | ||
"quote-props": ["error", "as-needed"], | ||
"quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], | ||
"semi-spacing": "error", | ||
"semi": "error", | ||
"space-before-blocks": "error", | ||
"space-before-function-paren": ["error", "never"], | ||
"space-in-parens": "error", | ||
"space-infix-ops": "error", | ||
"space-unary-ops": "error", | ||
"template-tag-spacing": "error", | ||
"unicode-bom": "error", | ||
"arrow-body-style": "error", | ||
"arrow-parens": ["error", "as-needed"], | ||
"arrow-spacing": "error", | ||
"no-duplicate-imports": "error", | ||
"no-useless-computed-key": "error", | ||
"no-useless-constructor": "error", | ||
"prefer-arrow-callback": "error", | ||
"prefer-numeric-literals": "error", | ||
"prefer-rest-params": "error", | ||
"prefer-spread": "error", | ||
"prefer-template": "error", | ||
"rest-spread-spacing": "error", | ||
"template-curly-spacing": "error", | ||
"yield-star-spacing": "error" | ||
} | ||
} |
@@ -5,6 +5,6 @@ 'use strict'; | ||
exports.validOptions = [].concat(...[ | ||
[ //required: | ||
[ //required: | ||
'part', | ||
], | ||
[ //filters: | ||
[ //filters: | ||
'forContentOwner', | ||
@@ -15,3 +15,3 @@ 'forDeveloper', | ||
], | ||
[ //optional: | ||
[ //optional: | ||
'channelId', | ||
@@ -44,5 +44,5 @@ 'channelType', | ||
'videoType', | ||
] | ||
], | ||
]); | ||
exports.apiurl = 'https://www.googleapis.com/youtube/v3/search?'; |
@@ -7,3 +7,2 @@ 'use strict'; | ||
//////////////////////////////////// | ||
const _keystore = new WeakMap(); | ||
@@ -14,8 +13,7 @@ | ||
/////////////////////// | ||
const querystring = require( 'querystring' ); | ||
const needle = require( 'needle' ); | ||
const Constants = require ( '../deps/Constants'); | ||
const querystring = require('querystring'); | ||
const { get } = require('snekfetch'); | ||
const Constants = require('../deps/Constants'); | ||
const { YTSearchPage } = require('./YTSearchPage'); | ||
const { determineType } = require('../deps/determineType'); | ||
/** | ||
@@ -28,2 +26,3 @@ * validOptions | ||
const validOptions = Constants.validOptions; | ||
/** | ||
@@ -48,3 +47,2 @@ * apiurl | ||
const YTSearch = class YTSearch { | ||
/** | ||
@@ -54,12 +52,8 @@ * constructor - Creates a search object with a given query (but does not perform the actual search). | ||
* @param {string} query - The Search query | ||
* @return {YTSearch} - The YTSearch object | ||
*/ | ||
constructor ( query ) { | ||
Object.defineProperty( this, 'query', { | ||
value: query, | ||
} ); | ||
Object.defineProperty( this, 'timestamp', { | ||
value: Date.now(), | ||
} ); | ||
constructor(query) { | ||
Object.defineProperties(this, { | ||
query: { value: query }, | ||
timestamp: { value: Date.now() }, | ||
}); | ||
} | ||
@@ -78,9 +72,8 @@ | ||
*/ | ||
search ( options, { key: apikey } ) { | ||
search(options, { key: apikey }) { | ||
return new Promise((res, rej) => { | ||
this.options = Object.assign({}, options); | ||
return new Promise( (res, rej) => { | ||
this.options = Object.assign( {}, options ); | ||
if(!apikey&&!_keystore.get(this)) rej('No token'); | ||
const theKey = apikey||_keystore.get(this); | ||
if (!apikey && !_keystore.get(this)) rej(new Error('No token')); | ||
const theKey = apikey || _keystore.get(this); | ||
_keystore.set(this, theKey); | ||
@@ -93,25 +86,19 @@ | ||
q: this.query, | ||
regionCode: this.options.regionCode||'US', | ||
type: ( () => { | ||
switch(!0){ | ||
case this.options.type == 'all' : return 'video,channel,playlist'; | ||
case typeof this.options.type == 'string' : return this.options.type; | ||
case !0 : return 'video'; | ||
} | ||
} )() | ||
regionCode: this.options.regionCode || 'US', | ||
type: determineType(this.options.type), | ||
}; | ||
for(const option of Object.keys(this.options)) | ||
if (~validOptions.indexOf(option)) searchParams[option] = options[option]; | ||
for (const option of Object.keys(this.options)) { | ||
if (validOptions.includes(option)) searchParams[option] = options[option]; | ||
} | ||
const queryUrl = `${apiurl}${querystring.stringify(searchParams)}`; | ||
needle.get( queryUrl, (error, response) => { | ||
if(error) rej(error); | ||
if(response.statusCode!=200) rej(`Error code: ${response.statusCode}`); | ||
get(queryUrl).then(response => { | ||
if (response.statusCode !== 200) return rej(new Error(`Error code: ${response.statusCode}`)); | ||
const body = response.body; | ||
if(body.error) rej(body.error.message); | ||
if (body.error) return rej(new Error(body.error.message)); | ||
this.totalResults = body.pageInfo?body.pageInfo.totalResults:null; | ||
this.pages = this.totalResults&&body.pageInfo.resultsPerPage?~~(this.totalResults/body.pageInfo.resultsPerPage)+1:null; | ||
this.totalResults = body.pageInfo ? body.pageInfo.totalResults : null; | ||
this.pages = this.totalResults && body.pageInfo.resultsPerPage ? ~~(this.totalResults / body.pageInfo.resultsPerPage) + 1 : null; | ||
@@ -124,5 +111,5 @@ this.nextPageToken = body.nextPageToken; | ||
res ( this ); | ||
} ); | ||
} ); | ||
return res(this); | ||
}).catch(error => rej(error)); | ||
}); | ||
} | ||
@@ -139,10 +126,10 @@ | ||
*/ | ||
nextPage ( newOptions = this.options ) { | ||
nextPage(newOptions = this.options) { | ||
newOptions = Object.assign({}, newOptions, this.options); | ||
return new Promise( async (res, rej) => { | ||
if(!this.nextPageToken) res(null); | ||
return new Promise(async(res, rej) => { | ||
if (!this.nextPageToken) res(null); | ||
try{ | ||
res( await this.search(Object.assign(newOptions, {pageToken: this.nextPageToken})) ); | ||
}catch(err){ | ||
try { | ||
res(await this.search(Object.assign(newOptions, { pageToken: this.nextPageToken }))); | ||
} catch (err) { | ||
rej(err); | ||
@@ -162,10 +149,10 @@ } | ||
*/ | ||
prevPage ( newOptions = {} ) { | ||
prevPage(newOptions = {}) { | ||
newOptions = Object.assign({}, newOptions, this.options); | ||
return new Promise( async (res, rej) => { | ||
if(!this.prevPageToken) res(null); | ||
return new Promise(async(res, rej) => { | ||
if (!this.prevPageToken) res(null); | ||
try{ | ||
res( await this.search(Object.assign(newOptions, {pageToken: this.prevPageToken})) ); | ||
}catch(err){ | ||
try { | ||
res(await this.search(Object.assign(newOptions, { pageToken: this.prevPageToken }))); | ||
} catch (err) { | ||
rej(err); | ||
@@ -172,0 +159,0 @@ } |
@@ -25,3 +25,2 @@ 'use strict'; | ||
const YTSearcher = class YTSearcher { | ||
/** | ||
@@ -33,16 +32,17 @@ * constructor - Creates a YouTube Searcher object | ||
* @param {Object=} [defaultoptions] - Optional default options to be used in every search. | ||
* @return {YTSearcher} The Searcher object | ||
*/ | ||
constructor ( apiKey, defaultoptions ) { | ||
constructor(apiKey, defaultoptions = {}) { | ||
let keyObj = false; | ||
if ( typeof apiKey === 'object' && apiKey != null ) { | ||
if( !apiKey.hasOwnProperty('key') ) | ||
throw new SyntaxError( ['Invalid Key','The object you provide to create a YTSearcher must contain a property called key'].join('|') ); | ||
if (typeof apiKey === 'object' && apiKey !== null && apiKey !== undefined) { | ||
if (!apiKey.hasOwnProperty('key')) { | ||
throw new SyntaxError(['Invalid Key', | ||
'The object you provide to create a YTSearcher must contain a property called key'].join('|')); | ||
} | ||
if( apiKey.hasOwnProperty('revealkey') ) | ||
Object.defineProperty( this, _protectkey, { | ||
value: typeof apiKey.revealkey ==='boolean'? (!apiKey.revealkey):true, | ||
} ); | ||
if (apiKey.hasOwnProperty('revealkey')) { | ||
Object.defineProperty(this, _protectkey, { | ||
value: typeof apiKey.revealkey === 'boolean' ? !apiKey.revealkey : true, | ||
}); | ||
} | ||
@@ -52,14 +52,14 @@ keyObj = true; | ||
_key.set(this,keyObj?apiKey.key:apiKey); | ||
_key.set(this, keyObj ? apiKey.key : apiKey); | ||
this.defaultoptions = defaultoptions||{}; | ||
this.defaultoptions = defaultoptions; | ||
} | ||
set key (newKey) { | ||
set key(newKey) { | ||
_key.set(this, newKey); | ||
} | ||
get key () { | ||
return this[_protectkey]?undefined:_key.get(this); | ||
get key() { | ||
return this[_protectkey] ? undefined : _key.get(this); | ||
} | ||
@@ -77,5 +77,5 @@ | ||
*/ | ||
search ( query, options ) { | ||
return new YTSearch( query ) | ||
.search( Object.assign({}, this.defaultoptions||{}, options||{}), { key: _key.get(this) } ); | ||
search(query, options) { | ||
return new YTSearch(query) | ||
.search(Object.assign({}, this.defaultoptions || {}, options || {}), { key: _key.get(this) }); | ||
} | ||
@@ -82,0 +82,0 @@ }; |
@@ -19,30 +19,29 @@ 'use strict'; | ||
* @param {Array} items - A list of youtube#searchResult | ||
* @return {YTSearchPage} - A YTSearchPage of results | ||
*/ | ||
constructor ( items ) { | ||
constructor(items) { | ||
super(0); | ||
if(!items) return; | ||
for ( let item of items ) { | ||
if (!items) return; | ||
for (const item of items) { | ||
const currentEntry = {}; | ||
( () => { | ||
(() => { | ||
currentEntry.kind = item.id.kind; | ||
switch (item.id.kind) { | ||
case 'youtube#channel':{ | ||
currentEntry.url = 'https://www.youtube.com/channel/' + item.id.channelId; | ||
case 'youtube#channel': { | ||
currentEntry.url = `https://www.youtube.com/channel/${item.id.channelId}`; | ||
currentEntry.id = item.id.channelId; | ||
return;} | ||
case 'youtube#playlist':{ | ||
currentEntry.url = 'https://www.youtube.com/playlist?list=' + item.id.playlistId; | ||
return; } | ||
case 'youtube#playlist': { | ||
currentEntry.url = `https://www.youtube.com/playlist?list=${item.id.playlistId}`; | ||
currentEntry.id = item.id.playlistId; | ||
return;} | ||
case 'youtube#video':{ | ||
currentEntry.url = 'https://www.youtube.com/watch?v=' + item.id.videoId; | ||
return; } | ||
case 'youtube#video': { | ||
currentEntry.url = `https://www.youtube.com/watch?v=${item.id.videoId}`; | ||
currentEntry.id = item.id.videoId; | ||
return;} | ||
} | ||
} | ||
} )(); | ||
})(); | ||
const snip = item.snippet; | ||
Object.assign( currentEntry, { | ||
Object.assign(currentEntry, { | ||
publishedAt: new Date(snip.publishedAt), | ||
@@ -55,3 +54,3 @@ channelId: snip.channelId, | ||
liveBroadcastContent: snip.liveBroadcastContent, | ||
} ); | ||
}); | ||
@@ -70,3 +69,3 @@ this.push(currentEntry); | ||
*/ | ||
first () { | ||
first() { | ||
return this[0] || null; | ||
@@ -83,4 +82,4 @@ } | ||
*/ | ||
last () { | ||
return this[this.length-1] || null; | ||
last() { | ||
return this[this.length - 1] || null; | ||
} | ||
@@ -87,0 +86,0 @@ }; |
{ | ||
"name": "ytsearcher", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "A nodejs package that provides an easy-to-use promise-based system of getting youtube search results", | ||
@@ -11,2 +11,3 @@ "main": "index.js", | ||
"scripts": { | ||
"gen-doc": "jsdoc -r --verbose -d ./docs -c ./conf.json -R ./README.md .;", | ||
"test": "node index.js" | ||
@@ -19,4 +20,7 @@ }, | ||
"keywords": [ | ||
"Promise-Based", | ||
"YouTube", | ||
"Searcher" | ||
"Searcher", | ||
"ytsearcher", | ||
"Pagination" | ||
], | ||
@@ -30,5 +34,5 @@ "author": "William Zhou", | ||
"dependencies": { | ||
"needle": "^1.6.0", | ||
"querystring": "^0.2.0" | ||
"querystring": "^0.2.0", | ||
"snekfetch": "^4.0.2" | ||
} | ||
} |
@@ -0,1 +1,14 @@ | ||
<div align="center"> | ||
<br /> | ||
<p> | ||
<a href="https://www.npmjs.com/package/ytsearcher"><img src="https://img.shields.io/npm/v/ytsearcher.svg" alt="NPM version" /></a> | ||
<a href="https://www.npmjs.com/package/ytsearcher"><img src="https://img.shields.io/npm/dt/ytsearcher.svg" alt="NPM downloads" /></a> | ||
<a href="https://david-dm.org/wzhouwzhou/ytsearcher"><img src="https://img.shields.io/david/wzhouwzhou/ytsearcher.svg" alt="Dependencies" /></a> | ||
<a href="https://paypal.me/wzhouwzhou"><img src="https://img.shields.io/badge/donate-paypal-009cde.svg" alt="Paypal" /></a> | ||
</p> | ||
<p> | ||
<a href="https://nodei.co/npm/ytsearcher/"><img src="https://nodei.co/npm/ytsearcher.png?stars=true&downloads=true"></a> | ||
</p> | ||
</div> | ||
# YTSearcher | ||
@@ -19,6 +32,6 @@ ## A nodejs package that provides an easy-to-use promise-based system of getting youtube search results. | ||
const searcher2 = new YTSearcher( { | ||
const searcher2 = new YTSearcher({ | ||
key: apiKey, | ||
revealkey: true, | ||
} ); | ||
}); | ||
@@ -73,11 +86,14 @@ **To Perform Searches** | ||
**For async methods:** | ||
**For async functions:** | ||
(async () => { | ||
const APIKEY = "12345"; // replace me | ||
const QUERY = "Anthing you want"; // replace me too | ||
const QUERY = "Anything you want"; // replace me too | ||
const { YTSearcher } = require( 'ytsearcher' ); | ||
const ytsearcher = new YTSearcher( APIKEY ); | ||
const { YTSearcher } = require('ytsearcher'); | ||
const ytsearcher = new YTSearcher(APIKEY); | ||
const searchResult = await ytsearcher.search( QUERY, { type: 'video' } ); | ||
// Type can be 'all', 'video', 'channel', 'playlist', or comma separated combination such as 'video,channel' | ||
const searchResult = await ytsearcher.search(QUERY, { type: 'video' }); | ||
@@ -90,17 +106,19 @@ const secondPage = await searchResult.nextPage(); | ||
console.log( videoEntry.url ); | ||
console.log(videoEntry.url); | ||
**For completely non-async methods:** | ||
})(); | ||
**For completely non-async functions:** | ||
const APIKEY = "12345"; // replace me | ||
const QUERY = "Anything you want"; // replace me too | ||
const { YTSearcher } = require( 'ytsearcher' ); | ||
const ytsearcher = new YTSearcher( APIKEY ); | ||
const { YTSearcher } = require('ytsearcher'); | ||
const ytsearcher = new YTSearcher(APIKEY); | ||
ytsearcher.search( QUERY, { type: 'video' } ) | ||
.then( searchResult => { | ||
ytsearcher.search(QUERY, { type: 'video' }) | ||
.then(searchResult => { | ||
searchResult.nextPage() | ||
.then( secondPage => { | ||
.then(secondPage => { | ||
// secondPage is same object as searchResult | ||
@@ -111,3 +129,3 @@ | ||
console.log( videoEntry.url ); | ||
console.log(videoEntry.url); | ||
}); | ||
@@ -114,0 +132,0 @@ }); |
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
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1111318
50
1103
135
+ Addedsnekfetch@^4.0.2
+ Addedsnekfetch@4.0.4(transitive)
- Removedneedle@^1.6.0
- Removeddebug@2.6.9(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedms@2.0.0(transitive)
- Removedneedle@1.6.0(transitive)
- Removedsafer-buffer@2.1.2(transitive)