From a98fb2cc65813bbdb01be1f42cf3896acad7197a Mon Sep 17 00:00:00 2001 From: ajay2507 Date: Tue, 28 Jan 2020 11:46:44 -0800 Subject: [PATCH 01/39] v2.7.7 --- package.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 28126e0..de263eb 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,15 @@ { "name": "ebay-node-api", - "version": "2.7.6", + "version": "2.7.7", "description": "Ebay node api client", "main": "./src/index.js", "homepage": "https://github.com/pajaydev/ebay-node-api", "scripts": { "lint": "eslint src/*.js", "test": "mocha && npm run lint", + "docs": "docsify init ./docs", + "serve-docs": "docsify serve docs", + "publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", "prepublish": "npm run test" }, "author": "Ajaykumar prathap", @@ -35,9 +38,11 @@ }, "devDependencies": { "chai": "^4.1.2", + "documentation": "^12.1.4", "eslint": "^5.8.0", + "gh-pages": "^2.2.0", "mocha": "^5.0.1", "nock": "^9.2.3", "sinon": "^4.4.5" } -} \ No newline at end of file +} From 81c562851c2ee3934394ea31a8e1d41e2adc76f1 Mon Sep 17 00:00:00 2001 From: ajay2507 Date: Fri, 8 May 2020 02:36:37 -0700 Subject: [PATCH 02/39] added include selector to user details --- demo/shopping.js | 2 +- docs/README.md | 2 +- package.json | 2 +- src/shopping.js | 6 +----- test/shopping.test.js | 14 +++++++++++++- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/demo/shopping.js b/demo/shopping.js index 5651bbf..af9db5b 100644 --- a/demo/shopping.js +++ b/demo/shopping.js @@ -16,7 +16,7 @@ ebay.getAllCategories('1234').then((data) => { // // Get User Profile // // https://developer.ebay.com/devzone/shopping/docs/callref/GetUserProfile.html -ebay.getUserDetails({ userId: 'ajaykumapratha_0', details: true }).then((data) => { +ebay.getUserDetails({ userId: 'ajaykumapratha_0', includeSelector: 'Details' }).then((data) => { console.log(data); }, (error) => { console.log(error); diff --git a/docs/README.md b/docs/README.md index af6b7ac..30d10e8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -322,7 +322,7 @@ ebay.getAllCategories('1234').then((data) => { Get User Profile ```javascript //https://developer.ebay.com/devzone/shopping/docs/callref/GetUserProfile.html -ebay.getUserDetails({ userId: 'ajaykumapratha_0', details: true }).then((data) => { +ebay.getUserDetails({ userId: 'ajaykumapratha_0', includeSelector: true }).then((data) => { console.log(data); }, (error) => { console.log(error); diff --git a/package.json b/package.json index 9ecbeac..22ea9f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ebay-node-api", - "version": "2.8.3", + "version": "2.8.4", "description": "Ebay node api client", "main": "./src/index.js", "homepage": "https://github.com/pajaydev/ebay-node-api", diff --git a/src/shopping.js b/src/shopping.js index ed016b8..8b788c7 100644 --- a/src/shopping.js +++ b/src/shopping.js @@ -6,7 +6,6 @@ const makeString = require('make-string'); const getAllCategories = function (categoryID) { const requestURL = `${urlObject.buildShoppingUrl(this.options, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; - console.log(requestURL); return getRequest(requestURL).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -16,8 +15,8 @@ const getAllCategories = function (categoryID) { const getUserDetails = function (input) { if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); if (!input.userId) throw new Error('invalid_request_error -> userId is null or invalid'); + input.includeSelector = input.includeSelector ? input.includeSelector : 'Details'; const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetUserProfile')}&${stringifyUrl(input)}`; - console.log(requestUrl); return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -30,7 +29,6 @@ const getItemStatus = function (itemIds) { 'ItemID': makeString(itemIds, { braces: 'false', quotes: 'no' }) }; const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetItemStatus')}&${stringifyUrl(paramsObj)}`; - console.log(requestUrl); return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -41,7 +39,6 @@ const getShippingCosts = function (input) { if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); if (!input.itemId) throw new Error('invalid_request_error -> Item id is null or invalid'); const url = `${urlObject.buildShoppingUrl(this.options, 'GetShippingCosts')}&${stringifyUrl(input)} `; - console.log(url); return getRequest(url).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -56,7 +53,6 @@ const getShippingCosts = function (input) { const getMultipleItems = function (options) { if (!options || !options.itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemId, { braces: 'false', quotes: 'no' }) })}`; - console.log(requestUrl); return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console diff --git a/test/shopping.test.js b/test/shopping.test.js index d55db4b..1dd96f9 100644 --- a/test/shopping.test.js +++ b/test/shopping.test.js @@ -49,13 +49,25 @@ describe('test shopping api', () => { clientID: 'ABCXXX123' }); nock('https://api.ebay.com') - .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test') + .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=Details') .reply(200, { getUserDetails: true }); ebay.getUserDetails({ userId: 'test' }).then((data) => { expect(data).to.deep.equal({ getUserDetails: true }); }); }); + it('test getUserDetails method with include selector', () => { + const ebay = new Ebay({ + clientID: 'ABCXXX123' + }); + nock('https://api.ebay.com') + .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=sample') + .reply(200, { getUserDetailsWithIncludeSelector: true }); + ebay.getUserDetails({ userId: 'test', includeSelector: 'sample' }).then((data) => { + expect(data).to.deep.equal({ getUserDetailsWithIncludeSelector: true }); + }); + }); + it('test getShippingCosts method', () => { const ebay = new Ebay({ clientID: 'ABCXXX123' From 1c64c5d09844332c54a7ad7cbe1a8e9f1d9fde25 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 18 May 2020 22:10:46 +0700 Subject: [PATCH 03/39] Set up base for new oauth --- package-lock.json | 13 +++ src/buildURL.js | 53 ----------- src/buy-api.js | 79 ++++++++++------- src/common-utils/index.js | 67 -------------- src/constants.js | 5 +- src/findingApi.js | 80 +++++++++-------- src/index.js | 180 ++++++++++++++++++++++++++++++++------ src/merchandising.js | 18 ++-- src/request.js | 45 +++++++--- src/shopping.js | 38 ++++---- src/taxonomy-api.js | 57 +++++++----- src/utils/URLQuery.js | 19 ++++ src/utils/buildURL.js | 31 +++++++ src/utils/general.js | 76 ++++++++++++++++ src/utils/index.js | 23 +++++ test/tester.js | 12 +++ 16 files changed, 522 insertions(+), 274 deletions(-) create mode 100644 package-lock.json delete mode 100644 src/buildURL.js delete mode 100644 src/common-utils/index.js create mode 100644 src/utils/URLQuery.js create mode 100644 src/utils/buildURL.js create mode 100644 src/utils/general.js create mode 100644 src/utils/index.js create mode 100644 test/tester.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7b3ddb1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "ebay-node-api", + "version": "2.8.4", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "make-string": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/make-string/-/make-string-1.0.3.tgz", + "integrity": "sha512-qpC9vH1GPDr1VEAIL1jicyoR77SjSuFPE5QYm/lKEFA/br21jKpAehGVZ11i23ai7UhfFGpJ1Hukw6EPi81Rvg==" + } + } +} diff --git a/src/buildURL.js b/src/buildURL.js deleted file mode 100644 index 7d424b5..0000000 --- a/src/buildURL.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -/** - * This method is used to build the url based on - * the type of request. - */ - -const buildURL = { - - /** - * Builds the findings(search) URL. - * - * @param {Object} options - * @param {String} data - * @return {String} build url - * @private - */ - buildSearchUrl(options) { - let baseUrl = `https://${options.baseSvcUrl}/services/search/FindingService/v1?`; - baseUrl += 'SECURITY-APPNAME=' + options.clientID; - baseUrl += '&OPERATION-NAME=' + options.operationName; - baseUrl += '&SERVICE-VERSION=1.0.0&RESPONSE-DATA-FORMAT=JSON'; - baseUrl += options.param ? '&' + options.param + '=' + options.name : ''; - baseUrl += options.additionalParam ? '&' + options.additionalParam : ''; - baseUrl += options.sortOrder ? '&sortOrder=' + options.sortOrder : ''; - baseUrl += '&outputSelector(0)=SellerInfo'; - baseUrl += '&outputSelector(1)=PictureURLLarge'; - baseUrl += options.limit ? '&paginationInput.entriesPerPage=' + options.limit : ''; - baseUrl += options.globalID ? '&GLOBAL-ID=' + options.globalID : ''; - baseUrl += options.pageNumber ? '&paginationInput.pageNumber=' + options.pageNumber : ''; - return baseUrl; - }, - - /** - * Builds the Shopping(open api) URL. - * - * @param {Object} options - * @return {String} url - * @private - */ - buildShoppingUrl(options, operationName) { - let baseUrl = `https://${options.baseUrl}/Shopping?`; - baseUrl += `appid=${options.clientID}`; - baseUrl += `&callname=${operationName}`; - baseUrl += `&version=967&siteid=${options.siteId || 0}&responseencoding=JSON`; - baseUrl += options.includeSelector ? '&IncludeSelector=' + options.includeSelector : ''; - return baseUrl; - } - -}; - -module.exports = buildURL; - diff --git a/src/buy-api.js b/src/buy-api.js index 9758c39..acfe2f3 100644 --- a/src/buy-api.js +++ b/src/buy-api.js @@ -1,30 +1,39 @@ 'use strict'; const fs = require('fs'); const makeString = require('make-string'); +const qs = require('querystring'); const { makeRequest } = require('./request'); -const { encodeURLQuery, base64Encode } = require('./common-utils'); +const { base64Encode, encodeURLQuery } = require('./utils') -const getItem = function (itemId) { +const getItemById = itemId => { if (!itemId) throw new Error('Item Id is required'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; + if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); + const auth = 'Bearer ' + this.appAccessToken; const id = encodeURIComponent(itemId); - this.options.contentType = 'application/json'; - return makeRequest(this.options, `/buy/browse/v1/item/${id}`, 'GET', auth).then((result) => { - return JSON.parse(result); + let config = { + contentType: 'application/json' + }; + return new Promise((resolve, reject) => { + makeRequest(this, config, `/buy/browse/v1/item/${id}`, 'GET', auth).then((result) => { + return resolve(JSON.parse(result)); + }).then((error) => { + return reject(error); + }); }); }; -const getItemByLegacyId = function (legacyOptions) { +const getItemByLegacyId = legacyOptions => { if (!legacyOptions) throw new Error('Error Required input to get Items By LegacyID'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); + if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); if (!legacyOptions.legacyItemId) throw new Error('Error Legacy Item Id is required'); - const auth = 'Bearer ' + this.options.access_token; + const auth = 'Bearer ' + this.appAccessToken; let param = 'legacy_item_id=' + legacyOptions.legacyItemId; param += legacyOptions.legacyVariationSku ? '&legacy_variation_sku=' + legacyOptions.legacyVariationSku : ''; - this.options.contentType = 'application/json'; + let config = { + contentType: 'application/json' + }; return new Promise((resolve, reject) => { - makeRequest(this.options, `/buy/browse/v1/item/get_item_by_legacy_id?${param}`, 'GET', auth).then((result) => { + makeRequest(this, config, `/buy/browse/v1/item/get_item_by_legacy_id?${param}`, 'GET', auth).then((result) => { return resolve(JSON.parse(result)); }).then((error) => { return reject(error); @@ -32,14 +41,16 @@ const getItemByLegacyId = function (legacyOptions) { }); }; -const getItemByItemGroup = function (itemGroupId) { +const getItemByItemGroup = itemGroupId => { if (typeof itemGroupId === 'object') throw new Error('Expecting String or number (Item group id)'); if (!itemGroupId) throw new Error('Error Item Group ID is required'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - this.options.contentType = 'application/json'; + if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); + const auth = 'Bearer ' + this.appAccessToken; + let config = { + contentType: 'application/json' + }; return new Promise((resolve, reject) => { - makeRequest(this.options, `/buy/browse/v1/item/get_items_by_item_group?item_group_id=${itemGroupId}`, 'GET', auth).then((result) => { + makeRequest(this, config, `/buy/browse/v1/item/get_items_by_item_group?item_group_id=${itemGroupId}`, 'GET', auth).then((result) => { resolve(result); }).then((error) => { reject(error); @@ -47,11 +58,11 @@ const getItemByItemGroup = function (itemGroupId) { }); }; -const searchItems = function (searchConfig) { - if (!searchConfig) throw new Error('Error --> Missing or invalid input parameter to search'); +const searchItems = searchConfig => { + if (!searchConfig) throw new Error('Missing or invalid input parameter to search'); if (!searchConfig.keyword && !searchConfig.categoryId && !searchConfig.gtin) throw new Error('Error --> Keyword or category id is required in query param'); - if (!this.options.access_token) throw new Error('Error -->Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; + if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); + const auth = 'Bearer ' + this.appAccessToken; let queryParam = searchConfig.keyword ? 'q=' + encodeURIComponent(searchConfig.keyword) : ''; queryParam = queryParam + (searchConfig.gtin ? '>in=' + searchConfig.gtin : ''); queryParam = queryParam + (searchConfig.categoryId ? '&category_ids=' + searchConfig.categoryId : ''); @@ -61,9 +72,11 @@ const searchItems = function (searchConfig) { if (searchConfig.fieldgroups !== undefined) queryParam = queryParam + '&fieldgroups=' + searchConfig.fieldgroups; if (searchConfig.filter !== undefined) queryParam = queryParam + '&filter=' + encodeURLQuery(makeString(searchConfig.filter, { quotes: 'no', braces: 'false' })); queryParam = queryParam + (searchConfig.aspect_filter ? '&aspect_filter=' + encodeURLQuery(makeString(searchConfig.aspect_filter, { quotes: 'no', braces: 'false' })) : ''); - this.options.contentType = 'application/json'; + let config = { + contentType: 'application/json' + }; return new Promise((resolve, reject) => { - makeRequest(this.options, `/buy/browse/v1/item_summary/search?${(queryParam)}`, 'GET', auth).then((result) => { + makeRequest(this, config, `/buy/browse/v1/item_summary/search?${(queryParam)}`, 'GET', auth).then((result) => { resolve(result); }).then((error) => { reject(error); @@ -71,17 +84,19 @@ const searchItems = function (searchConfig) { }); }; -const searchByImage = function (searchConfig) { - if (!searchConfig) throw new Error('INVALID_REQUEST_PARMS --> Missing or invalid input parameter to search by image'); - if (!this.options.access_token) throw new Error('INVALID_AUTH_TOKEN --> Missing Access token, Generate access token'); - if (!searchConfig.imgPath && !searchConfig.base64Image) throw new Error('REQUIRED_PARAMS --> imgPath or base64Image is required'); - const auth = 'Bearer ' + this.options.access_token; +const searchByImage = searchConfig => { + if (!searchConfig) throw new Error('Missing or invalid input parameter to search by image'); + if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); + if (!searchConfig.imgPath && !searchConfig.base64Image) throw new Error('imgPath or base64Image is required'); + const auth = 'Bearer ' + this.appAccessToken; const encodeImage = searchConfig.imgPath ? base64Encode(fs.readFileSync(searchConfig.imgPath)) : searchConfig.base64Image; - this.options.data = JSON.stringify({ image: encodeImage }); - this.options.contentType = 'application/json'; + let config = qs.stringify({ + data: { image: encodeImage }, + contentType: "application/json", + }); const queryString = makeString(searchConfig, { quotes: 'no', braces: 'false', seperator: '&', assignment: '=' }); return new Promise((resolve, reject) => { - makeRequest(this.options, `/buy/browse/v1/item_summary/search_by_image?${queryString}`, 'POST', auth).then((result) => { + makeRequest(this, config, `/buy/browse/v1/item_summary/search_by_image?${queryString}`, 'POST', auth).then((result) => { resolve(result); }).then((error) => { reject(error); @@ -90,7 +105,7 @@ const searchByImage = function (searchConfig) { }; module.exports = { - getItem, + getItemById, getItemByLegacyId, getItemByItemGroup, searchItems, diff --git a/src/common-utils/index.js b/src/common-utils/index.js deleted file mode 100644 index 27f3be7..0000000 --- a/src/common-utils/index.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; -const { makeRequest } = require('../request'); - -const base64Encode = (encodeData) => { - const buff = Buffer.from(encodeData);; - return buff.toString('base64'); -} - -module.exports = { - setAccessToken: function (token) { - this.options.access_token = token; - }, - getAccessToken: function () { - if (!this.options.clientID) throw new Error('Missing Client ID'); - if (!this.options.clientSecret) throw new Error('Missing Client Secret or Cert Id'); - if (!this.options.body) throw new Error('Missing Body, required Grant type'); - const encodedStr = base64Encode(this.options.clientID + ':' + this.options.clientSecret); - const self = this; - const auth = 'Basic ' + encodedStr; - this.options.contentType = 'application/x-www-form-urlencoded'; - return makeRequest(this.options, '/identity/v1/oauth2/token', 'POST', auth).then((result) => { - const resultJSON = JSON.parse(result); - self.setAccessToken(resultJSON.access_token); - return resultJSON; - }); - }, - setSiteId: function (siteId) { - this.options.siteId = siteId; - }, - setHeaders(self, headerObj) { - self.headers = Object.assign({}, self.headers, headerObj); - }, - upperCase(data) { - if (!isString(data)) data = data.toString(); - return data.toUpperCase(); - }, - - // Returns if a value is a string - isString(value) { - return typeof value === 'string' || value instanceof String; - }, - - // Returns if object is empty or not - isEmptyObj(obj) { - for (let key in obj) { - if (obj.hasOwnProperty(key)) { - return false; - } - } - return true; - }, - - encodeURLQuery(url) { - return encodeURIComponent(url).replace(/'/g, '%27').replace(/"/g, '%22'); - }, - - // parses the object and converts it into query params. - parseObj(options, url = '') { - if (options) { - for (let key in options) { - url = `${url}&${key}=${options[key]}` - } - } - return url; - }, - base64Encode -}; \ No newline at end of file diff --git a/src/constants.js b/src/constants.js index 81ded07..8b64deb 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,9 +1,12 @@ 'use strict'; module.exports = { + PROD_OAUTHENVIRONMENT_WEBENDPOINT: 'https://auth.ebay.com/oauth2/authorize', + SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT: 'https://auth.sandbox.ebay.com/oauth2/authorize', PROD_BASE_URL: 'api.ebay.com', SANDBOX_BASE_URL: 'api.sandbox.ebay.com', BASE_SVC_URL: 'svcs.ebay.com', BASE_SANDBX_SVC_URL: 'svcs.sandbox.ebay.com', - MERCH_SRVC_NAME: 'MerchandisingService' + MERCH_SRVC_NAME: 'MerchandisingService', + CLIENT_CRED_SCOPE: 'https://api.ebay.com/oauth/api_scope' }; diff --git a/src/findingApi.js b/src/findingApi.js index ea4f66e..830a794 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -1,35 +1,39 @@ 'use strict'; -const urlObject = require('./buildURL'); +const { buildSearchUrl } = require('./utils') const { getRequest } = require('./request'); const FIND_ITEMS_BY_KEYWORD = 'findItemsByKeywords'; const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; const FIND_COMPLETED_ITEMS = 'findCompletedItems'; const FIND_ITEMS_ADV = 'findItemsAdvanced'; -const findItemsByKeywords = function (options) { +const findItemsByKeywords = options => { if (!options) { - throw new Error('INVALID_REQUEST_PARMS --> Keyword is missing, Keyword is required'); + throw new Error('Keyword param is required'); } - this.options.operationName = FIND_ITEMS_BY_KEYWORD; - this.options.param = 'keywords'; + let config = { + operationName: FIND_ITEMS_BY_KEYWORD, + param: 'keywords' + }; // support only keyword string. - if (!options.keywords) options = { keywords: options }; - options.keywords = encodeURIComponent(options.keywords); - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); + if (!options.keywords) config = { keywords: options }; + config.keywords = encodeURIComponent(options.keywords); + config.additionalParam = constructAdditionalParams(options); + const url = buildSearchUrl(config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; }, console.error // eslint-disable-line no-console ); }; -const findItemsByCategory = function (categoryID) { - if (!categoryID) throw new Error('INVALID_REQUEST_PARMS --> Category ID is null or invalid'); - this.options.name = categoryID; - this.options.operationName = FIND_ITEMS_BY_CATEGORY; - this.options.param = 'categoryId'; - const url = urlObject.buildSearchUrl(this.options); +const findItemsByCategory = categoryID => { + if (!categoryID) throw new Error('Category ID is required'); + let config = { + name: categoryID, + operationName: FIND_ITEMS_BY_CATEGORY, + param: 'categoryId' + } + const url = buildSearchUrl(config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByCategoryResponse; }, console.error // eslint-disable-line no-console @@ -41,15 +45,16 @@ const findItemsByCategory = function (categoryID) { * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. * @param {Object} options */ -const findCompletedItems = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> Keyword or category ID are required.'); - if (!options.keywords && !options.categoryId) throw new Error('Keyword or category ID are required.'); +const findCompletedItems = options => { + if (!options || options.keywords || options.categoryId) throw new Error('Keyword or category ID is required'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } - this.options.operationName = FIND_COMPLETED_ITEMS; - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: FIND_COMPLETED_ITEMS, + additionalParam: constructAdditionalParams(options), + } + const url = buildSearchUrl(config); return getRequest(url).then((data) => { return JSON.parse(data).findCompletedItemsResponse; @@ -63,24 +68,27 @@ const findCompletedItems = function (options) { * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. * @param {Object} options */ -const findItemsAdvanced = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> check here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); +const findItemsAdvanced = options => { + if (!options) throw new Error('Options param is required\nCheck here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } - this.options.operationName = FIND_ITEMS_ADV; - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: FIND_ITEMS_ADV, + additionalParam: constructAdditionalParams(options), + } + const url = buildSearchUrl(config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsAdvancedResponse; }, console.error // eslint-disable-line no-console ); }; - const getVersion = function () { - this.options.operationName = 'getVersion'; - const url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: 'getVersion', + } + const url = buildSearchUrl(config); return getRequest(url).then((data) => { return JSON.parse(data).getVersionResponse[0]; }, console.error // eslint-disable-line no-console @@ -91,13 +99,15 @@ const getVersion = function () { * Searches for items on eBay using specific eBay product values. * @param {Object} options */ -const findItemsByProduct = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> Please enter the Valid input.'); - if (!options.productId) throw new Error('INVALID_REQUEST_PARMS --> Product ID is required.'); +const findItemsByProduct = options => { + if (!options) throw new Error('Options param is required'); + if (!options.productId) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; - this.options.operationName = 'findItemsByProduct'; - this.options.additionalParam = constructAdditionalParams(options); - let url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: 'findItemsByProduct', + additionalParam: constructAdditionalParams(options) + } + let url = buildSearchUrl(config); url = `${url}&productId.@type=${type}`; return getRequest(url).then((data) => { return JSON.parse(data).findItemsByProductResponse; diff --git a/src/index.js b/src/index.js index bab315e..e6d9361 100644 --- a/src/index.js +++ b/src/index.js @@ -1,57 +1,183 @@ 'use strict'; + +const qs = require('querystring'); const ebayBuyApi = require('./buy-api'); const shoppingApi = require('./shopping'); const { getDefaultCategoryTreeId, getCategoryTree, getCategorySubtree, getCategorySuggestions, - getItemAspectsForCategory } = require('./taxonomy-api'); + getItemAspectsForCategory +} = require('./taxonomy-api'); const ebayFindingApi = require('./findingApi'); -const { setAccessToken, - getAccessToken, - setHeaders, - getHeaders -} = require('./common-utils'); const { getSimilarItems, getMostWatchedItems } = require('./merchandising'); -const { PROD_BASE_URL, SANDBOX_BASE_URL, BASE_SANDBX_SVC_URL, BASE_SVC_URL } = require('./constants'); +const { getSiteId, base64Encode } = require('./utils'); +const { postRequest } = require('./request'); +const { PROD_OAUTHENVIRONMENT_WEBENDPOINT, + SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT, + PROD_BASE_URL, SANDBOX_BASE_URL, + BASE_SANDBX_SVC_URL, + BASE_SVC_URL, CLIENT_CRED_SCOPE +} = require('./constants'); const PROD_ENV = 'PROD'; const SANDBOX_ENV = 'SANDBOX'; - /** * Creates a eBay instance. * - * @param {Object} options configuration options - * @param {String} options.clientID Client Id/App id - * @param {String} options.env Environment, defaults to PROD + * @param {Object} options configuration options - required + * @param {String} options.clientID eBay Client/App ID - required + * @param {String} options.clientSecret eBay Secret/Cert Id - required + * @param {String} options.redirectUri redirect URI after user gives consent - required for authorization code flow * @param {String} options.headers HTTP request headers + * @param {String} options.environment eBay API Environment, defaults to PROD (Production) + * @param {String} options.countryCode eBay specific country site, defaults to EBAY-US * @constructor * @public */ function Ebay(options) { if (!options) throw new Error('Options is missing, please provide the input'); - if (!options.clientID) throw Error('Client ID is Missing\ncheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); + if (!options.clientID || !options.clientSecret) throw Error('Client ID/Secret Id is Missing\nCheck documentation to get them http://developer.ebay.com/DevZone/account/'); if (!(this instanceof Ebay)) return new Ebay(options); - if (!options.env) options.env = PROD_ENV; - options.baseUrl = PROD_BASE_URL; - options.baseSvcUrl = BASE_SVC_URL; - // handle sandbox env. - if (options.env === SANDBOX_ENV) { - options.baseUrl = SANDBOX_BASE_URL; - options.baseSvcUrl = BASE_SANDBX_SVC_URL; + if (options.environment === SANDBOX_ENV) { + this.baseUrl = SANDBOX_BASE_URL; + this.baseSvcUrl = BASE_SANDBX_SVC_URL; + this.oauthEndpoint = SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT; + } else { + this.baseUrl = PROD_BASE_URL; + this.baseSvcUrl = BASE_SVC_URL; + this.oauthEndpoint = PROD_OAUTHENVIRONMENT_WEBENDPOINT; + } + // Assign the credentials + this.credentials = { + clientID: options.clientID, + clientSecret: options.clientSecret + }; + // Set the headers + this.headers = options.headers; + this.globalID = options.countryCode || 'EBAY-US'; + this.siteId = getSiteId(this.globalID); +} + +/** +* Generates an application access token for client credentials grant flow +* +* @param scopes array of scopes for the access token +* @return accessToken object +*/ +const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { + if (!this.credentials) throw new Error('Credentials are required'); + this.grantType = 'client_credentials'; + this.scope = Array.isArray(scopes) ? scopes.join('%20') : scopes; + const data = qs.stringify({ + grant_type: this.grantType, + scope: this.scope + }); + const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const auth = `Basic ${encodedStr}`; + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); +} + +/** + * Generates user consent authorization url + * + * @param scopes array of scopes for the access token + * @param state custom state value + * @return userConsentUrl +*/ +const getUserAuthorizationUrl = (scopes, state = None) => { + if (!scopes) throw new Error('Scopes parameter is required'); + if (!this.credentials) throw new Error('Credentials are required'); + if (!this.credentials.redirectUri) throw new Error('redirect_uri is required for redirection after sign in\nkindly check here https://developer.ebay.com/api-docs/static/oauth-redirect-uri.html'); + let scopesParam = Array.isArray(scopes) ? scopes.join('%20') : scopes; + let queryParam = `client_id=${this.credentials.clientId}`; + queryParam = `${queryParam}&redirect_uri=${this.credentials.redirectUri}`; + queryParam = `${queryParam}&response_type=code`; + queryParam = `${queryParam}&scope=${scopesParam}`; + queryParam = state ? `${queryParam}&state=${state}` : queryParam; + return `${this.oauthEndpoint}?${queryParam}`; +} + +/** + * Generates a User access token given auth code + * + * @param environment Environment (production/sandbox). + * @param code code generated from browser using the method generateUserAuthorizationUrl. + * @return accessToken object. +*/ +const getAccessTokenByCode = code => { + if (!code) throw new Error('Authorization code is required'); + if (!this.credentials) throw new Error('Credentials are required'); + const data = qs.stringify({ + code: code, + grant_type: 'authorization_code', + redirect_uri: this.credentials.redirectUri + }); + const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const auth = `Basic ${encodedStr}`; + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); +} + +/** + * Use a refresh token to update a User access token (Updating the expired access token) + * + * @param refreshToken refresh token, defaults to pre-assigned refresh token + * @param scopes array of scopes for the access token + * @return accessToken object +*/ +const getAccessTokenByRefresh = (refreshToken = None, scopes) => { + refreshToken = refreshToken ? refreshToken : this.refreshToken; + if (!scopes) throw new Error('Scopes parameter is required'); + if (!this.credentials) throw new Error('Credentials are required'); + let scopesParam = Array.isArray(scopes) ? scopes.join('%20') : scopes; + if (!token) { + throw new Error('Refresh token is required, to generate refresh token use exchangeCodeForAccessToken method'); // eslint-disable-line max-len } - this.options = options; - setHeaders(this, options.headers); - this.options.globalID = options.countryCode || 'EBAY-US'; - this.options.siteId = options.siteId || '0'; + const data = qs.stringify({ + refresh_token: refreshToken, + grant_type: 'refresh_token', + scope: scopesParam + }); + const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const auth = `Basic ${encodedStr}`; + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); } +/** + * Assign user access token and refresh token returned from authorization grant workflow (i.e getAccessTokenByCode) + * + * @param accessToken User Access token + * @param refreshToken Refresh token +*/ +const setUserAccessTokens = (accessToken, refreshToken) => { + this.refreshToken = refreshToken; + this.userAccessToken = accessToken; +} + +/** + * Assign application access token returned from client credentials workflow (i.e getApplicationToken) + * + * @param accessToken User Access token +*/ +const setAppAccessToken = accessToken => { + this.appAccessToken = accessToken; +} + +const getRefreshToken = () => this.refreshToken; +const getUserAccessToken = () => this.userAccessToken; +const getAppAccessToken = () => this.appAccessToken; + Ebay.prototype = { - setAccessToken, - getAccessToken, - setHeaders, - getHeaders, + getApplicationToken, + getUserAuthorizationUrl, + getAccessTokenByCode, + getAccessTokenByRefresh, + setAppAccessToken, + setUserAccessTokens, + getRefreshToken, + getUserAccessToken, + getAppAccessToken, getDefaultCategoryTreeId, getCategoryTree, getCategorySubtree, diff --git a/src/merchandising.js b/src/merchandising.js index 80c2be6..3bde698 100644 --- a/src/merchandising.js +++ b/src/merchandising.js @@ -1,7 +1,7 @@ 'use strict'; const { getRequest } = require('./request'); -const { parseObj } = require('./common-utils/index'); +const { urlParseObj } = require('./utils'); const { MERCH_SRVC_NAME } = require('./constants'); //https://developer.ebay.com/devzone/merchandising/docs/CallRef/getMostWatchedItems.html#Samples @@ -11,10 +11,10 @@ const { MERCH_SRVC_NAME } = require('./constants'); * Add interest and excitement for buyers by showing them what other people are watching. * @param {String} categoryId (optional) */ -const getMostWatchedItems = function (merchOptions) { - if (!this.options.clientID) throw new Error('Missing App id or client id'); - const url = parseObj(merchOptions); - return getRequest(`http://${this.options.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getMostWatchedItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.options.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { +const getMostWatchedItems = merchOptions => { + if (!this.credentials.clientID) throw new Error('Missing App id or client id'); + const url = urlParseObj(merchOptions); + return getRequest(`http://${this.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getMostWatchedItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.credentials.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { return JSON.parse(result); }).catch((error) => { console.log(error); // eslint-disable-line no-console @@ -27,10 +27,10 @@ const getMostWatchedItems = function (merchOptions) { * Gets similar Items based on the Item id provided. * @param {String} categoryId (optional) */ -const getSimilarItems = function (merchOptions) { - if (!this.options.clientID) throw new Error('Missing App id or client id'); - const url = parseObj(merchOptions); - return getRequest(`http://${this.options.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getSimilarItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.options.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { +const getSimilarItems = merchOptions => { + if (!this.credentials.clientID) throw new Error('Missing App id or client id'); + const url = urlParseObj(merchOptions); + return getRequest(`http://${this.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getSimilarItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.credentials.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { return JSON.parse(result); }).catch((error) => { console.log(error); // eslint-disable-line no-console diff --git a/src/request.js b/src/request.js index 6ced6a7..9d1b2bf 100644 --- a/src/request.js +++ b/src/request.js @@ -25,20 +25,20 @@ const getRequest = (url) => { })); }; -const makeRequest = function postRequest(self, endpoint, methodName, token) { +const makeRequest = (self, customOptions, endpoint, methodName, token) => { let dataString = ''; - if (self.data) { - dataString = self.data; + if (customOptions.data) { + dataString = customOptions.data; } else { - methodName === 'POST' ? dataString = qs.stringify(self.body) : ''; + methodName === 'POST' ? dataString = qs.stringify(customOptions.body) : ''; } const options = { 'hostname': self.baseUrl, 'path': endpoint, - 'method': methodName || 'GET', + 'method': methodName, 'headers': { - 'content-type': self.contentType ? self.contentType : 'application/json', + 'content-type': customOptions.contentType, 'authorization': token, 'cache-control': 'no-cache', ...self.headers @@ -67,10 +67,35 @@ const makeRequest = function postRequest(self, endpoint, methodName, token) { })); }; +const postRequest = (self, contentType, data, endpoint, authToken) => { + return new Promise((resolve, reject) => { + const req = https.request({ + hostname: self.baseUrl, + path: endpoint, + method: 'POST', + headers: { + 'Content-Type': contentType, + 'authorization': authToken, + ...self.headers + }, + }); + req.on('response', (response) => { + let body = ''; + response.setEncoding('utf8'); + response.on('data', (chunk) => body += chunk); // eslint-disable-line + response.on('end', () => { + if (body.error) { + reject(body); + } + resolve(body); + }); + }); -const base64Encode = (encodeData) => { - const buff = Buffer.from(encodeData); - return buff.toString('base64'); + req.on('error', (error) => { + reject(error); + }); + req.end(data); + }); }; -module.exports = { getRequest, makeRequest, base64Encode }; +module.exports = { getRequest, postRequest, makeRequest }; diff --git a/src/shopping.js b/src/shopping.js index 8b788c7..790cc69 100644 --- a/src/shopping.js +++ b/src/shopping.js @@ -1,44 +1,44 @@ 'use strict'; const { getRequest } = require('./request'); -const urlObject = require('./buildURL'); +const { buildShoppingUrl } = require('./utils'); const makeString = require('make-string'); -const getAllCategories = function (categoryID) { - const requestURL = `${urlObject.buildShoppingUrl(this.options, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; +const getAllCategories = categoryID => { + const requestURL = `${buildShoppingUrl(this, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; return getRequest(requestURL).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console ); }; -const getUserDetails = function (input) { - if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); - if (!input.userId) throw new Error('invalid_request_error -> userId is null or invalid'); +const getUserDetails = input => { + if (!input || typeof input !== 'object') throw new Error('Input param is required'); + if (!input.userId) throw new Error('userId is required'); input.includeSelector = input.includeSelector ? input.includeSelector : 'Details'; - const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetUserProfile')}&${stringifyUrl(input)}`; + const requestUrl = `${buildShoppingUrl(this, 'GetUserProfile')}&${stringifyUrl(input)}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console ); }; -const getItemStatus = function (itemIds) { - if (!itemIds) throw new Error('invalid_request_error -> Item ID is null or invalid'); +const getItemStatus = itemIds => { + if (!itemIds) throw new Error('Item ID param is required'); const paramsObj = { 'ItemID': makeString(itemIds, { braces: 'false', quotes: 'no' }) }; - const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetItemStatus')}&${stringifyUrl(paramsObj)}`; + const requestUrl = `${buildShoppingUrl(this, 'GetItemStatus')}&${stringifyUrl(paramsObj)}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console ); }; -const getShippingCosts = function (input) { - if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); - if (!input.itemId) throw new Error('invalid_request_error -> Item id is null or invalid'); - const url = `${urlObject.buildShoppingUrl(this.options, 'GetShippingCosts')}&${stringifyUrl(input)} `; +const getShippingCosts = input => { + if (!input || typeof input !== 'object') throw new Error('iInput param is required'); + if (!input.itemId) throw new Error('Item ID param is required'); + const url = `${buildShoppingUrl(this, 'GetShippingCosts')}&${stringifyUrl(input)} `; return getRequest(url).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -50,9 +50,9 @@ const getShippingCosts = function (input) { * Retrieves publicly visible details about for one or more listings on eBay. * @param {Object} options (required) */ -const getMultipleItems = function (options) { - if (!options || !options.itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); - const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemId, { braces: 'false', quotes: 'no' }) })}`; +const getMultipleItems = options => { + if (!options || !options.itemId) throw new Error('Item ID param is required'); + const requestUrl = `${buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemId, { braces: 'false', quotes: 'no' }) })}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -65,9 +65,9 @@ const getMultipleItems = function (options) { * Retrieves publicly visible details about one listing on eBay. * @param {String} itemId (required) */ -const getSingleItem = function (itemId) { +const getSingleItem = itemId => { if (!itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); - const requestUrl = `${urlObject.buildShoppingUrl(this.options, 'GetSingleItem')}&${stringifyUrl({ 'ItemID': itemId })} `; + const requestUrl = `${buildShoppingUrl(this, 'GetSingleItem')}&${stringifyUrl({ 'ItemID': itemId })} `; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console diff --git a/src/taxonomy-api.js b/src/taxonomy-api.js index b36857f..9367e98 100644 --- a/src/taxonomy-api.js +++ b/src/taxonomy-api.js @@ -1,6 +1,6 @@ 'use strict'; const { makeRequest } = require('./request'); -const { upperCase } = require('./common-utils'); +const { upperCase } = require('./utils'); /** * @method getDefaultCategoryTreeId {Function} @@ -8,12 +8,15 @@ const { upperCase } = require('./common-utils'); */ const DEFAULT_CATEGORY_TREE = 'EBAY_US'; -const getDefaultCategoryTreeId = function (marketPlaceId) { +const getDefaultCategoryTreeId = marketPlaceId => { if (!marketPlaceId) marketPlaceId = DEFAULT_CATEGORY_TREE; marketPlaceId = upperCase(marketPlaceId); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - return makeRequest(this.options, `/commerce/taxonomy/v1_beta/get_default_category_tree_id?marketplace_id=${marketPlaceId}`, 'GET', auth).then((result) => { + if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); + let config = { + contentType: 'application/json' + }; + const auth = 'Bearer ' + this.appAccessToken; + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/get_default_category_tree_id?marketplace_id=${marketPlaceId}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; @@ -23,11 +26,14 @@ const getDefaultCategoryTreeId = function (marketPlaceId) { * @param {Integer} categoryTreeId = default = 0 */ -const getCategoryTree = function (categoryTreeId) { +const getCategoryTree = categoryTreeId => { if (!categoryTreeId) categoryTreeId = 0; - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - return makeRequest(this.options, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}`, 'GET', auth).then((result) => { + if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); + let config = { + contentType: 'application/json' + }; + const auth = 'Bearer ' + this.appAccessToken; + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; @@ -38,12 +44,15 @@ const getCategoryTree = function (categoryTreeId) { * @param {String} categoryTreeId = The unique identifier of the eBay category tree from which a category subtree is being requested. */ -const getCategorySubtree = function (categoryTreeId, categoryId) { +const getCategorySubtree = (categoryTreeId, categoryId) => { if (!categoryTreeId) categoryTreeId = 0; if (!categoryId) throw new Error('Missing Categor id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySubtree#h2-samples'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - return makeRequest(this.options, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_subtree?category_id=${categoryId}`, 'GET', auth).then((result) => { + if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); + let config = { + contentType: 'application/json' + }; + const auth = 'Bearer ' + this.appAccessToken; + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_subtree?category_id=${categoryId}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; @@ -54,12 +63,15 @@ const getCategorySubtree = function (categoryTreeId, categoryId) { * @param {String} keyword = input string to get CategorySuggestions. */ -const getCategorySuggestions = function (categoryTreeId, keyword) { +const getCategorySuggestions = (categoryTreeId, keyword) => { if (!categoryTreeId) categoryTreeId = 0; if (!keyword) throw new Error('Missing keyword \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySuggestions'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - return makeRequest(this.options, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_suggestions?q=${keyword}`, 'GET', auth).then((result) => { + if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); + let config = { + contentType: 'application/json' + }; + const auth = 'Bearer ' + this.appAccessToken; + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_suggestions?q=${keyword}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; @@ -69,12 +81,15 @@ const getCategorySuggestions = function (categoryTreeId, keyword) { * @param {String} categoryId = identifier of the category at the top of the subtree. * @param {String} keyword = input string to get CategorySuggestions. */ -const getItemAspectsForCategory = function (categoryTreeId, categoryId) { +const getItemAspectsForCategory = (categoryTreeId, categoryId) => { if (!categoryTreeId) categoryTreeId = 0; if (!categoryId) throw new Error('Missing Category id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getItemAspectsForCategory#h2-samples'); - if (!this.options.access_token) throw new Error('Missing Access token, Generate access token'); - const auth = 'Bearer ' + this.options.access_token; - return makeRequest(this.options, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_item_aspects_for_category?category_id=${categoryId}`, 'GET', auth).then((result) => { + if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); + let config = { + contentType: 'application/json' + }; + const auth = 'Bearer ' + this.appAccessToken; + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_item_aspects_for_category?category_id=${categoryId}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; diff --git a/src/utils/URLQuery.js b/src/utils/URLQuery.js new file mode 100644 index 0000000..a093aac --- /dev/null +++ b/src/utils/URLQuery.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = { + encodeURLQuery: url => { + return encodeURIComponent(url) + .replace(/'/g, '%27') + .replace(/"/g, '%22'); + }, + + // parses the object and converts it into query params. + urlParseObj: (options, url = '') => { + if (options) { + for (let key in options) { + url = `${url}&${key}=${options[key]}`; + } + } + return url; + } +} \ No newline at end of file diff --git a/src/utils/buildURL.js b/src/utils/buildURL.js new file mode 100644 index 0000000..fc3c95b --- /dev/null +++ b/src/utils/buildURL.js @@ -0,0 +1,31 @@ +'use strict'; + +/** + * Methods used to build the url based on + * the type of request. + */ +module.exports = { + buildSearchUrl: (self, options) => { + let url = `https://${self.baseSvcUrl}/services/search/FindingService/v1?`; + url += 'SECURITY-APPNAME=' + self.credentials.clientID; + url += '&OPERATION-NAME=' + options.operationName; + url += '&SERVICE-VERSION=1.0.0&RESPONSE-DATA-FORMAT=JSON'; + url += options.param ? '&' + options.param + '=' + options.name : ''; + url += options.additionalParam ? '&' + options.additionalParam : ''; + url += options.sortOrder ? '&sortOrder=' + options.sortOrder : ''; + url += '&outputSelector(0)=SellerInfo'; + url += '&outputSelector(1)=PictureURLLarge'; + url += options.limit ? '&paginationInput.entriesPerPage=' + options.limit : ''; + url += this.globalID ? '&GLOBAL-ID=' + self.globalID : ''; + url += options.pageNumber ? '&paginationInput.pageNumber=' + options.pageNumber : ''; + return url; + }, + buildShoppingUrl: (self, operationName) => { + let url = `https://${self.baseUrl}/Shopping?`; + url += `appid=${self.credentials.clientID}`; + url += `&callname=${operationName}`; + url += `&version=967&siteid=${self.siteId || 0}&responseencoding=JSON`; + return url; + } +}; + diff --git a/src/utils/general.js b/src/utils/general.js new file mode 100644 index 0000000..1a43911 --- /dev/null +++ b/src/utils/general.js @@ -0,0 +1,76 @@ +'use strict'; + +module.exports = { + base64Encode: data => { + const buff = Buffer.from(data); + return buff.toString('base64'); + }, + getSiteId: globalID => { + // Reference: https://developer.ebay.com/DevZone/merchandising/docs/Concepts/SiteIDToGlobalID.html + switch (globalID) { + case 'EBAY-US': + return 0; + case 'EBAY-ENCA': + return 2; + case 'EBAY-GB': + return 3; + case 'EBAY-AU': + return 15; + case 'EBAY-FRBE': + return 16; + case 'EBAY-FR': + return 23; + case 'EBAY-DE': + return 71; + case 'EBAY-MOTOR': + return 77; + case 'EBAY-IT': + return 100; + case 'EBAY-NLBE': + return 101; + case 'EBAY-NL': + return 123; + case 'EBAY-ES': + return 146; + case 'EBAY-CH': + return 186; + case 'EBAY-HK': + return 193; + case 'EBAY-IN': + return 201; + case 'EBAY-IE': + return 205; + case 'EBAY-MY': + return 207; + case 'EBAY-FRCA': + return 210; + case 'EBAY-PH': + return 211; + case 'EBAY-PL': + return 212; + case 'EBAY-SG': + return 216; + default: + return -1; + } + }, + upperCase: data => { + if (!isString(data)) data = data.toString(); + return data.toUpperCase(); + }, + + // Returns if a value is a string + isString: value => { + return typeof value === 'string' || value instanceof String; + }, + + // Returns if object is empty or not + isEmptyObj: obj => { + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + return false; + } + } + return true; + } +}; diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..6fea5cc --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,23 @@ +'use strict'; + +const { + base64Encode, + getSiteId, + upperCase, + isString, + isEmptyObj, +} = require('./general'); +const { buildSearchUrl, buildShoppingUrl } = require('./buildURL'); +const { urlParseObj, encodeURLQuery } = require('./URLQuery'); + +module.exports = { + base64Encode, + getSiteId, + upperCase, + isString, + isEmptyObj, + buildSearchUrl, + buildShoppingUrl, + urlParseObj, + encodeURLQuery +}; diff --git a/test/tester.js b/test/tester.js new file mode 100644 index 0000000..0258773 --- /dev/null +++ b/test/tester.js @@ -0,0 +1,12 @@ +let Ebay = require('../src/index'); + +let ebay = new Ebay({ + clientID: 'ChaseWal-test-SBX-1bcdef085-6a35b75b', + clientSecret: 'SBX-bcdef085d25c-9862-4747-ae5b-0d00', + environment: 'SANDBOX' +}); +ebay.getApplicationToken().then((data) => { + console.log(data); // data.access_token +}, (error) => { + console.log(error); +}); From ecd30c694f55dcaf2e9ccddf10d288ef99e5c643 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 18 May 2020 23:07:00 +0700 Subject: [PATCH 04/39] Remove misused arrow functions --- src/buy-api.js | 10 +++++----- src/findingApi.js | 12 ++++++------ src/index.js | 29 +++++++++++++++++------------ src/merchandising.js | 4 ++-- src/request.js | 16 ++++++++-------- src/shopping.js | 14 +++++++------- src/taxonomy-api.js | 8 ++++---- 7 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/buy-api.js b/src/buy-api.js index acfe2f3..488e3f2 100644 --- a/src/buy-api.js +++ b/src/buy-api.js @@ -5,7 +5,7 @@ const qs = require('querystring'); const { makeRequest } = require('./request'); const { base64Encode, encodeURLQuery } = require('./utils') -const getItemById = itemId => { +const getItemById = function (itemId) { if (!itemId) throw new Error('Item Id is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; @@ -22,7 +22,7 @@ const getItemById = itemId => { }); }; -const getItemByLegacyId = legacyOptions => { +const getItemByLegacyId = function (legacyOptions) { if (!legacyOptions) throw new Error('Error Required input to get Items By LegacyID'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); if (!legacyOptions.legacyItemId) throw new Error('Error Legacy Item Id is required'); @@ -41,7 +41,7 @@ const getItemByLegacyId = legacyOptions => { }); }; -const getItemByItemGroup = itemGroupId => { +const getItemByItemGroup = function (itemGroupId) { if (typeof itemGroupId === 'object') throw new Error('Expecting String or number (Item group id)'); if (!itemGroupId) throw new Error('Error Item Group ID is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); @@ -58,7 +58,7 @@ const getItemByItemGroup = itemGroupId => { }); }; -const searchItems = searchConfig => { +const searchItems = function (searchConfig) { if (!searchConfig) throw new Error('Missing or invalid input parameter to search'); if (!searchConfig.keyword && !searchConfig.categoryId && !searchConfig.gtin) throw new Error('Error --> Keyword or category id is required in query param'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); @@ -84,7 +84,7 @@ const searchItems = searchConfig => { }); }; -const searchByImage = searchConfig => { +const searchByImage = function (searchConfig) { if (!searchConfig) throw new Error('Missing or invalid input parameter to search by image'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); if (!searchConfig.imgPath && !searchConfig.base64Image) throw new Error('imgPath or base64Image is required'); diff --git a/src/findingApi.js b/src/findingApi.js index 830a794..d8bbced 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -7,7 +7,7 @@ const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; const FIND_COMPLETED_ITEMS = 'findCompletedItems'; const FIND_ITEMS_ADV = 'findItemsAdvanced'; -const findItemsByKeywords = options => { +const findItemsByKeywords = function (options) { if (!options) { throw new Error('Keyword param is required'); } @@ -26,7 +26,7 @@ const findItemsByKeywords = options => { ); }; -const findItemsByCategory = categoryID => { +const findItemsByCategory = function (categoryID) { if (!categoryID) throw new Error('Category ID is required'); let config = { name: categoryID, @@ -45,7 +45,7 @@ const findItemsByCategory = categoryID => { * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. * @param {Object} options */ -const findCompletedItems = options => { +const findCompletedItems = function (options) { if (!options || options.keywords || options.categoryId) throw new Error('Keyword or category ID is required'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); @@ -68,7 +68,7 @@ const findCompletedItems = options => { * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. * @param {Object} options */ -const findItemsAdvanced = options => { +const findItemsAdvanced = function (options) { if (!options) throw new Error('Options param is required\nCheck here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); @@ -99,7 +99,7 @@ const getVersion = function () { * Searches for items on eBay using specific eBay product values. * @param {Object} options */ -const findItemsByProduct = options => { +const findItemsByProduct = function (options) { if (!options) throw new Error('Options param is required'); if (!options.productId) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; @@ -122,7 +122,7 @@ const findItemsByProduct = options => { * output will be keywords=iphone&itemFilter(0).name=Condition&itemFilter(0).value=3000&itemFilter(1).name=FreeShippingOnly&itemFilter(1).value=true&itemFilter(2).name=SoldItemsOnly&itemFilter(2).value=true * @param {Object} options */ -const constructAdditionalParams = (options) => { +const constructAdditionalParams = function (options) { let params = ''; let count = 0; for (let key in options) { diff --git a/src/index.js b/src/index.js index e6d9361..e7531f7 100644 --- a/src/index.js +++ b/src/index.js @@ -68,11 +68,10 @@ function Ebay(options) { */ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { if (!this.credentials) throw new Error('Credentials are required'); - this.grantType = 'client_credentials'; - this.scope = Array.isArray(scopes) ? scopes.join('%20') : scopes; + scopes = Array.isArray(scopes) ? scopes.join('%20') : scopes; const data = qs.stringify({ - grant_type: this.grantType, - scope: this.scope + grant_type: 'client_credentials', + scope: scopes }); const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; @@ -86,7 +85,7 @@ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { * @param state custom state value * @return userConsentUrl */ -const getUserAuthorizationUrl = (scopes, state = None) => { +const getUserAuthorizationUrl = function (scopes, state = None) { if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); if (!this.credentials.redirectUri) throw new Error('redirect_uri is required for redirection after sign in\nkindly check here https://developer.ebay.com/api-docs/static/oauth-redirect-uri.html'); @@ -106,7 +105,7 @@ const getUserAuthorizationUrl = (scopes, state = None) => { * @param code code generated from browser using the method generateUserAuthorizationUrl. * @return accessToken object. */ -const getAccessTokenByCode = code => { +const getAccessTokenByCode = function (code) { if (!code) throw new Error('Authorization code is required'); if (!this.credentials) throw new Error('Credentials are required'); const data = qs.stringify({ @@ -126,7 +125,7 @@ const getAccessTokenByCode = code => { * @param scopes array of scopes for the access token * @return accessToken object */ -const getAccessTokenByRefresh = (refreshToken = None, scopes) => { +const getAccessTokenByRefresh = function (refreshToken = None, scopes) { refreshToken = refreshToken ? refreshToken : this.refreshToken; if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); @@ -150,7 +149,7 @@ const getAccessTokenByRefresh = (refreshToken = None, scopes) => { * @param accessToken User Access token * @param refreshToken Refresh token */ -const setUserAccessTokens = (accessToken, refreshToken) => { +const setUserAccessTokens = function (accessToken, refreshToken) { this.refreshToken = refreshToken; this.userAccessToken = accessToken; } @@ -160,13 +159,19 @@ const setUserAccessTokens = (accessToken, refreshToken) => { * * @param accessToken User Access token */ -const setAppAccessToken = accessToken => { +const setAppAccessToken = function (accessToken) { this.appAccessToken = accessToken; } -const getRefreshToken = () => this.refreshToken; -const getUserAccessToken = () => this.userAccessToken; -const getAppAccessToken = () => this.appAccessToken; +const getRefreshToken = function () { + return this.refreshToken; +} +const getUserAccessToken = function () { + return this.userAccessToken; +} +const getAppAccessToken = function () { + return this.appAccessToken; +} Ebay.prototype = { getApplicationToken, diff --git a/src/merchandising.js b/src/merchandising.js index 3bde698..0713412 100644 --- a/src/merchandising.js +++ b/src/merchandising.js @@ -11,7 +11,7 @@ const { MERCH_SRVC_NAME } = require('./constants'); * Add interest and excitement for buyers by showing them what other people are watching. * @param {String} categoryId (optional) */ -const getMostWatchedItems = merchOptions => { +const getMostWatchedItems = function (merchOptions) { if (!this.credentials.clientID) throw new Error('Missing App id or client id'); const url = urlParseObj(merchOptions); return getRequest(`http://${this.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getMostWatchedItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.credentials.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { @@ -27,7 +27,7 @@ const getMostWatchedItems = merchOptions => { * Gets similar Items based on the Item id provided. * @param {String} categoryId (optional) */ -const getSimilarItems = merchOptions => { +const getSimilarItems = function (merchOptions) { if (!this.credentials.clientID) throw new Error('Missing App id or client id'); const url = urlParseObj(merchOptions); return getRequest(`http://${this.baseSvcUrl}/${MERCH_SRVC_NAME}?OPERATION-NAME=getSimilarItems&SERVICE-NAME=${MERCH_SRVC_NAME}&SERVICE-VERSION=1.1.0&CONSUMER-ID=${this.credentials.clientID}&RESPONSE-DATA-FORMAT=JSON&REST-PAYLOAD${url}`).then((result) => { diff --git a/src/request.js b/src/request.js index 9d1b2bf..76c963a 100644 --- a/src/request.js +++ b/src/request.js @@ -29,8 +29,7 @@ const makeRequest = (self, customOptions, endpoint, methodName, token) => { let dataString = ''; if (customOptions.data) { dataString = customOptions.data; - } - else { + } else { methodName === 'POST' ? dataString = qs.stringify(customOptions.body) : ''; } const options = { @@ -69,7 +68,7 @@ const makeRequest = (self, customOptions, endpoint, methodName, token) => { const postRequest = (self, contentType, data, endpoint, authToken) => { return new Promise((resolve, reject) => { - const req = https.request({ + const req = httpRequest.request({ hostname: self.baseUrl, path: endpoint, method: 'POST', @@ -77,13 +76,13 @@ const postRequest = (self, contentType, data, endpoint, authToken) => { 'Content-Type': contentType, 'authorization': authToken, ...self.headers - }, + }, }); - req.on('response', (response) => { + req.on('response', (res) => { let body = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => body += chunk); // eslint-disable-line - response.on('end', () => { + res.setEncoding('utf8'); + res.on('data', (chunk) => body += chunk); // eslint-disable-line + res.on('end', () => { if (body.error) { reject(body); } @@ -95,6 +94,7 @@ const postRequest = (self, contentType, data, endpoint, authToken) => { reject(error); }); req.end(data); + console.log(req.body); }); }; diff --git a/src/shopping.js b/src/shopping.js index 790cc69..e678e0c 100644 --- a/src/shopping.js +++ b/src/shopping.js @@ -4,7 +4,7 @@ const { getRequest } = require('./request'); const { buildShoppingUrl } = require('./utils'); const makeString = require('make-string'); -const getAllCategories = categoryID => { +const getAllCategories = function (categoryID) { const requestURL = `${buildShoppingUrl(this, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; return getRequest(requestURL).then((data) => { return JSON.parse(data); @@ -12,7 +12,7 @@ const getAllCategories = categoryID => { ); }; -const getUserDetails = input => { +const getUserDetails = function (input) { if (!input || typeof input !== 'object') throw new Error('Input param is required'); if (!input.userId) throw new Error('userId is required'); input.includeSelector = input.includeSelector ? input.includeSelector : 'Details'; @@ -23,7 +23,7 @@ const getUserDetails = input => { ); }; -const getItemStatus = itemIds => { +const getItemStatus = function (itemIds) { if (!itemIds) throw new Error('Item ID param is required'); const paramsObj = { 'ItemID': makeString(itemIds, { braces: 'false', quotes: 'no' }) @@ -35,7 +35,7 @@ const getItemStatus = itemIds => { ); }; -const getShippingCosts = input => { +const getShippingCosts = function (input) { if (!input || typeof input !== 'object') throw new Error('iInput param is required'); if (!input.itemId) throw new Error('Item ID param is required'); const url = `${buildShoppingUrl(this, 'GetShippingCosts')}&${stringifyUrl(input)} `; @@ -50,7 +50,7 @@ const getShippingCosts = input => { * Retrieves publicly visible details about for one or more listings on eBay. * @param {Object} options (required) */ -const getMultipleItems = options => { +const getMultipleItems = function (options) { if (!options || !options.itemId) throw new Error('Item ID param is required'); const requestUrl = `${buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemId, { braces: 'false', quotes: 'no' }) })}`; return getRequest(requestUrl).then((data) => { @@ -65,7 +65,7 @@ const getMultipleItems = options => { * Retrieves publicly visible details about one listing on eBay. * @param {String} itemId (required) */ -const getSingleItem = itemId => { +const getSingleItem = function (itemId) { if (!itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); const requestUrl = `${buildShoppingUrl(this, 'GetSingleItem')}&${stringifyUrl({ 'ItemID': itemId })} `; return getRequest(requestUrl).then((data) => { @@ -74,7 +74,7 @@ const getSingleItem = itemId => { ); }; -const stringifyUrl = (obj) => { +const stringifyUrl = function (obj) { return makeString(obj, { braces: 'false', assignment: '=', quotes: 'no', seperator: '&' }); }; diff --git a/src/taxonomy-api.js b/src/taxonomy-api.js index 9367e98..e7cb412 100644 --- a/src/taxonomy-api.js +++ b/src/taxonomy-api.js @@ -26,7 +26,7 @@ const getDefaultCategoryTreeId = marketPlaceId => { * @param {Integer} categoryTreeId = default = 0 */ -const getCategoryTree = categoryTreeId => { +const getCategoryTree = function (categoryTreeId) { if (!categoryTreeId) categoryTreeId = 0; if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { @@ -44,7 +44,7 @@ const getCategoryTree = categoryTreeId => { * @param {String} categoryTreeId = The unique identifier of the eBay category tree from which a category subtree is being requested. */ -const getCategorySubtree = (categoryTreeId, categoryId) => { +const getCategorySubtree = function (categoryTreeId, categoryId) { if (!categoryTreeId) categoryTreeId = 0; if (!categoryId) throw new Error('Missing Categor id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySubtree#h2-samples'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); @@ -63,7 +63,7 @@ const getCategorySubtree = (categoryTreeId, categoryId) => { * @param {String} keyword = input string to get CategorySuggestions. */ -const getCategorySuggestions = (categoryTreeId, keyword) => { +const getCategorySuggestions = function (categoryTreeId, keyword) { if (!categoryTreeId) categoryTreeId = 0; if (!keyword) throw new Error('Missing keyword \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySuggestions'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); @@ -81,7 +81,7 @@ const getCategorySuggestions = (categoryTreeId, keyword) => { * @param {String} categoryId = identifier of the category at the top of the subtree. * @param {String} keyword = input string to get CategorySuggestions. */ -const getItemAspectsForCategory = (categoryTreeId, categoryId) => { +const getItemAspectsForCategory = function (categoryTreeId, categoryId) { if (!categoryTreeId) categoryTreeId = 0; if (!categoryId) throw new Error('Missing Category id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getItemAspectsForCategory#h2-samples'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); From 5e292b525ed4f0a0c601da0d8809d2f860f3606e Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Tue, 19 May 2020 00:44:32 +0700 Subject: [PATCH 05/39] Final touches for setting up oauth --- src/findingApi.js | 12 ++++++------ src/index.js | 37 ++++++++++++++++++++++--------------- src/request.js | 1 - test/tester.js | 12 ------------ 4 files changed, 28 insertions(+), 34 deletions(-) delete mode 100644 test/tester.js diff --git a/src/findingApi.js b/src/findingApi.js index d8bbced..2f18c9e 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -19,7 +19,7 @@ const findItemsByKeywords = function (options) { if (!options.keywords) config = { keywords: options }; config.keywords = encodeURIComponent(options.keywords); config.additionalParam = constructAdditionalParams(options); - const url = buildSearchUrl(config); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; }, console.error // eslint-disable-line no-console @@ -33,7 +33,7 @@ const findItemsByCategory = function (categoryID) { operationName: FIND_ITEMS_BY_CATEGORY, param: 'categoryId' } - const url = buildSearchUrl(config); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByCategoryResponse; }, console.error // eslint-disable-line no-console @@ -54,7 +54,7 @@ const findCompletedItems = function (options) { operationName: FIND_COMPLETED_ITEMS, additionalParam: constructAdditionalParams(options), } - const url = buildSearchUrl(config); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findCompletedItemsResponse; @@ -77,7 +77,7 @@ const findItemsAdvanced = function (options) { operationName: FIND_ITEMS_ADV, additionalParam: constructAdditionalParams(options), } - const url = buildSearchUrl(config); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsAdvancedResponse; }, console.error // eslint-disable-line no-console @@ -88,7 +88,7 @@ const getVersion = function () { let config = { operationName: 'getVersion', } - const url = buildSearchUrl(config); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).getVersionResponse[0]; }, console.error // eslint-disable-line no-console @@ -107,7 +107,7 @@ const findItemsByProduct = function (options) { operationName: 'findItemsByProduct', additionalParam: constructAdditionalParams(options) } - let url = buildSearchUrl(config); + let url = buildSearchUrl(this, config); url = `${url}&productId.@type=${type}`; return getRequest(url).then((data) => { return JSON.parse(data).findItemsByProductResponse; diff --git a/src/index.js b/src/index.js index e7531f7..633d87d 100644 --- a/src/index.js +++ b/src/index.js @@ -64,7 +64,7 @@ function Ebay(options) { * Generates an application access token for client credentials grant flow * * @param scopes array of scopes for the access token -* @return accessToken object +* @return appAccessToken object */ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { if (!this.credentials) throw new Error('Credentials are required'); @@ -73,9 +73,11 @@ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { grant_type: 'client_credentials', scope: scopes }); - const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; - return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { + return JSON.parse(result); + }); } /** @@ -103,7 +105,7 @@ const getUserAuthorizationUrl = function (scopes, state = None) { * * @param environment Environment (production/sandbox). * @param code code generated from browser using the method generateUserAuthorizationUrl. - * @return accessToken object. + * @return userAccessToken object. */ const getAccessTokenByCode = function (code) { if (!code) throw new Error('Authorization code is required'); @@ -115,7 +117,9 @@ const getAccessTokenByCode = function (code) { }); const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; - return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { + return JSON.parse(result); + });; } /** @@ -123,7 +127,7 @@ const getAccessTokenByCode = function (code) { * * @param refreshToken refresh token, defaults to pre-assigned refresh token * @param scopes array of scopes for the access token - * @return accessToken object + * @return userAccessToken object */ const getAccessTokenByRefresh = function (refreshToken = None, scopes) { refreshToken = refreshToken ? refreshToken : this.refreshToken; @@ -140,27 +144,30 @@ const getAccessTokenByRefresh = function (refreshToken = None, scopes) { }); const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; - return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth); + return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { + return JSON.parse(result); + }); } /** * Assign user access token and refresh token returned from authorization grant workflow (i.e getAccessTokenByCode) * - * @param accessToken User Access token - * @param refreshToken Refresh token + * @param userAccessToken userAccessToken obj returned from getAccessTokenByCode or getAccessTokenByRefresh */ -const setUserAccessTokens = function (accessToken, refreshToken) { - this.refreshToken = refreshToken; - this.userAccessToken = accessToken; +const setUserAccessTokens = function (userAccessToken) { + if (!userAccessToken.token_type == 'User Access Token') throw new Error('userAccessToken is either missing or invalid'); + this.refreshToken = userAccessToken.refresh_token; + this.userAccessToken = userAccessToken.access_token; } /** * Assign application access token returned from client credentials workflow (i.e getApplicationToken) * - * @param accessToken User Access token + * @param appAccessToken userAccessToken obj returned from getApplicationToken */ -const setAppAccessToken = function (accessToken) { - this.appAccessToken = accessToken; +const setAppAccessToken = function (appAccessToken) { + if (!appAccessToken.token_type == 'Application Access Token') throw new Error('appAccessToken is either missing or invalid'); + this.appAccessToken = appAccessToken.access_token; } const getRefreshToken = function () { diff --git a/src/request.js b/src/request.js index 76c963a..c791ce3 100644 --- a/src/request.js +++ b/src/request.js @@ -94,7 +94,6 @@ const postRequest = (self, contentType, data, endpoint, authToken) => { reject(error); }); req.end(data); - console.log(req.body); }); }; diff --git a/test/tester.js b/test/tester.js deleted file mode 100644 index 0258773..0000000 --- a/test/tester.js +++ /dev/null @@ -1,12 +0,0 @@ -let Ebay = require('../src/index'); - -let ebay = new Ebay({ - clientID: 'ChaseWal-test-SBX-1bcdef085-6a35b75b', - clientSecret: 'SBX-bcdef085d25c-9862-4747-ae5b-0d00', - environment: 'SANDBOX' -}); -ebay.getApplicationToken().then((data) => { - console.log(data); // data.access_token -}, (error) => { - console.log(error); -}); From c45c24f892cfed364261948aa030ca2ffc870e32 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Tue, 19 May 2020 18:09:48 +0700 Subject: [PATCH 06/39] General bug fixes --- package-lock.json | 725 ++++++++++++++++++++++++++++++++ package.json | 12 +- src/buy-api.js | 22 +- src/findingApi.js | 21 +- src/index.js | 18 +- src/merchandising.js | 4 +- src/shopping.js | 32 +- src/taxonomy-api.js | 40 +- src/utils/URLQuery.js | 3 +- src/utils/buildURL.js | 11 +- src/utils/general.js | 44 +- test/buildURL.test.js | 43 +- test/common.test.js | 8 +- test/findItemsByKeyword.test.js | 2 +- test/finding.test.js | 18 +- test/index.test.js | 30 +- test/shopping.test.js | 18 +- 17 files changed, 892 insertions(+), 159 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b3ddb1..7960e30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,10 +4,735 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@sinonjs/commons": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", + "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "clipboard": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "dev": true, + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "dev": true, + "optional": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "docsify": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.3.tgz", + "integrity": "sha512-o9AvGb4vZOlmorg/58Kj6tNdfBaoSQUJZSFC6fJsfLjGFt45kiXhA2UmALnnVk5sol0WgSzxZlcZw6tu1gVu4Q==", + "dev": true, + "requires": { + "marked": "^0.7.0", + "medium-zoom": "^1.0.5", + "opencollective-postinstall": "^2.0.2", + "prismjs": "^1.19.0", + "strip-indent": "^3.0.0", + "tinydate": "^1.0.0", + "tweezer.js": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "dev": true, + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "just-extend": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "dev": true + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + }, "make-string": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/make-string/-/make-string-1.0.3.tgz", "integrity": "sha512-qpC9vH1GPDr1VEAIL1jicyoR77SjSuFPE5QYm/lKEFA/br21jKpAehGVZ11i23ai7UhfFGpJ1Hukw6EPi81Rvg==" + }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "medium-zoom": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.5.tgz", + "integrity": "sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ==", + "dev": true + }, + "min-indent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", + "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nise": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", + "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^5.0.1", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + } + } + }, + "nock": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.6.1.tgz", + "integrity": "sha512-EDgl/WgNQ0C1BZZlASOQkQdE6tAWXJi8QQlugqzN64JJkvZ7ILijZuG24r4vCC7yOfnm6HKpne5AGExLGCeBWg==", + "dev": true, + "requires": { + "chai": "^4.1.2", + "debug": "^3.1.0", + "deep-equal": "^1.0.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.5", + "mkdirp": "^0.5.0", + "propagate": "^1.0.0", + "qs": "^6.5.1", + "semver": "^5.5.0" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "prismjs": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", + "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", + "dev": true, + "requires": { + "clipboard": "^2.0.0" + } + }, + "propagate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", + "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", + "dev": true + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "sinon": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true, + "optional": true + }, + "tinydate": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz", + "integrity": "sha512-3GwPk8VhDFnUZ2TrgkhXJs6hcMAIIw4x/xkz+ayK6dGoQmp2nUwKzBXK0WnMsqkh6vfUhpqQicQF3rbshfyJkg==", + "dev": true + }, + "tweezer.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", + "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true } } } diff --git a/package.json b/package.json index 22ea9f4..0a6c5b1 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,13 @@ "oauth-ebay": "^1.0.0" }, "devDependencies": { - "chai": "^4.1.2", - "docsify": "^4.10.2", + "chai": "^4.2.0", + "docsify": "^4.11.3", "documentation": "^12.1.4", "eslint": "^5.8.0", "gh-pages": "^2.2.0", - "mocha": "^5.0.1", - "nock": "^9.2.3", - "sinon": "^4.4.5" + "mocha": "^5.2.0", + "nock": "^9.6.1", + "sinon": "^4.5.0" } -} \ No newline at end of file +} diff --git a/src/buy-api.js b/src/buy-api.js index 488e3f2..815c4b2 100644 --- a/src/buy-api.js +++ b/src/buy-api.js @@ -5,11 +5,11 @@ const qs = require('querystring'); const { makeRequest } = require('./request'); const { base64Encode, encodeURLQuery } = require('./utils') -const getItemById = function (itemId) { - if (!itemId) throw new Error('Item Id is required'); +const getItemById = function (itemID) { + if (!itemID) throw new Error('Item ID is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; - const id = encodeURIComponent(itemId); + const id = encodeURIComponent(itemID); let config = { contentType: 'application/json' }; @@ -25,9 +25,9 @@ const getItemById = function (itemId) { const getItemByLegacyId = function (legacyOptions) { if (!legacyOptions) throw new Error('Error Required input to get Items By LegacyID'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); - if (!legacyOptions.legacyItemId) throw new Error('Error Legacy Item Id is required'); + if (!legacyOptions.legacyItemID) throw new Error('Error Legacy Item ID is required'); const auth = 'Bearer ' + this.appAccessToken; - let param = 'legacy_item_id=' + legacyOptions.legacyItemId; + let param = 'legacy_item_id=' + legacyOptions.legacyItemID; param += legacyOptions.legacyVariationSku ? '&legacy_variation_sku=' + legacyOptions.legacyVariationSku : ''; let config = { contentType: 'application/json' @@ -41,16 +41,16 @@ const getItemByLegacyId = function (legacyOptions) { }); }; -const getItemByItemGroup = function (itemGroupId) { - if (typeof itemGroupId === 'object') throw new Error('Expecting String or number (Item group id)'); - if (!itemGroupId) throw new Error('Error Item Group ID is required'); +const getItemByItemGroup = function (itemGroupID) { + if (typeof itemGroupID === 'object') throw new Error('Expecting String or number (Item group id)'); + if (!itemGroupID) throw new Error('Error Item Group ID is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; let config = { contentType: 'application/json' }; return new Promise((resolve, reject) => { - makeRequest(this, config, `/buy/browse/v1/item/get_items_by_item_group?item_group_id=${itemGroupId}`, 'GET', auth).then((result) => { + makeRequest(this, config, `/buy/browse/v1/item/get_items_by_item_group?item_group_id=${itemGroupID}`, 'GET', auth).then((result) => { resolve(result); }).then((error) => { reject(error); @@ -60,12 +60,12 @@ const getItemByItemGroup = function (itemGroupId) { const searchItems = function (searchConfig) { if (!searchConfig) throw new Error('Missing or invalid input parameter to search'); - if (!searchConfig.keyword && !searchConfig.categoryId && !searchConfig.gtin) throw new Error('Error --> Keyword or category id is required in query param'); + if (!searchConfig.keyword && !searchConfig.categoryID && !searchConfig.gtin) throw new Error('Error --> Keyword or category id is required in query param'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; let queryParam = searchConfig.keyword ? 'q=' + encodeURIComponent(searchConfig.keyword) : ''; queryParam = queryParam + (searchConfig.gtin ? '>in=' + searchConfig.gtin : ''); - queryParam = queryParam + (searchConfig.categoryId ? '&category_ids=' + searchConfig.categoryId : ''); + queryParam = queryParam + (searchConfig.categoryId ? '&category_ids=' + searchConfig.categoryID : ''); queryParam = queryParam + (searchConfig.limit ? '&limit=' + searchConfig.limit : ''); queryParam = queryParam + (searchConfig.offset ? '&offset=' + searchConfig.offset : ''); queryParam = queryParam + (searchConfig.sort ? '&sort=' + searchConfig.sort : ''); diff --git a/src/findingApi.js b/src/findingApi.js index 2f18c9e..521a82b 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -9,7 +9,7 @@ const FIND_ITEMS_ADV = 'findItemsAdvanced'; const findItemsByKeywords = function (options) { if (!options) { - throw new Error('Keyword param is required'); + throw new Error('Keyword is required'); } let config = { operationName: FIND_ITEMS_BY_KEYWORD, @@ -42,11 +42,11 @@ const findItemsByCategory = function (categoryID) { /** * searches for items whose listings are completed and are no longer available for - * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. + * sale by category (using categoryD), by keywords (using keywords), or a combination of the two. * @param {Object} options */ const findCompletedItems = function (options) { - if (!options || options.keywords || options.categoryId) throw new Error('Keyword or category ID is required'); + if (!options || options.keywords || options.categoryID) throw new Error('Keyword or category ID is required'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } @@ -65,11 +65,11 @@ const findCompletedItems = function (options) { /** * searches for items whose listings are completed and are no longer available for - * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. + * sale by category (using categoryID), by keywords (using keywords), or a combination of the two. * @param {Object} options */ const findItemsAdvanced = function (options) { - if (!options) throw new Error('Options param is required\nCheck here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); + if (!options) throw new Error('Options is required\nCheck here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } @@ -100,8 +100,8 @@ const getVersion = function () { * @param {Object} options */ const findItemsByProduct = function (options) { - if (!options) throw new Error('Options param is required'); - if (!options.productId) throw new Error('Product ID is required.'); + if (!options) throw new Error('Options is required'); + if (!options.productID) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; let config = { operationName: 'findItemsByProduct', @@ -130,13 +130,16 @@ const constructAdditionalParams = function (options) { if (key === 'entriesPerPage' || key === 'pageNumber') { params = `${params}paginationInput.${key}=${options[key]}&`; } - else if (key === 'keywords' || key === 'categoryId' || key === 'productId' || key === 'sortOrder') { + else if (key === 'keywords' || key === 'sortOrder') { params = `${params}${key}=${options[key]}&`; } + else if (key === 'categoryID' || key === 'productID') { + params = `${params}${key.replace(/ID$/, 'Id')}=${options[key]}&`; + } else if (key === 'affiliate') { const innerParams = options[key]; for (let innerKey in innerParams) { - params = `${params}${key}.${innerKey}=${innerParams[innerKey]}&`; + params = `${params}${key}.${innerKey.replace(/ID$/, 'Id')}=${innerParams[innerKey]}&`; } } else { diff --git a/src/index.js b/src/index.js index 633d87d..010d565 100644 --- a/src/index.js +++ b/src/index.js @@ -27,7 +27,7 @@ const SANDBOX_ENV = 'SANDBOX'; * * @param {Object} options configuration options - required * @param {String} options.clientID eBay Client/App ID - required - * @param {String} options.clientSecret eBay Secret/Cert Id - required + * @param {String} options.clientSecret eBay Secret/Cert ID - required for user access tokens * @param {String} options.redirectUri redirect URI after user gives consent - required for authorization code flow * @param {String} options.headers HTTP request headers * @param {String} options.environment eBay API Environment, defaults to PROD (Production) @@ -38,13 +38,15 @@ const SANDBOX_ENV = 'SANDBOX'; function Ebay(options) { if (!options) throw new Error('Options is missing, please provide the input'); - if (!options.clientID || !options.clientSecret) throw Error('Client ID/Secret Id is Missing\nCheck documentation to get them http://developer.ebay.com/DevZone/account/'); + if (!options.clientID) throw Error('Client ID is Missing\nCheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); if (!(this instanceof Ebay)) return new Ebay(options); if (options.environment === SANDBOX_ENV) { + this.environment = SANDBOX_ENV; this.baseUrl = SANDBOX_BASE_URL; this.baseSvcUrl = BASE_SANDBX_SVC_URL; this.oauthEndpoint = SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT; } else { + this.environment = PROD_ENV; this.baseUrl = PROD_BASE_URL; this.baseSvcUrl = BASE_SVC_URL; this.oauthEndpoint = PROD_OAUTHENVIRONMENT_WEBENDPOINT; @@ -57,7 +59,7 @@ function Ebay(options) { // Set the headers this.headers = options.headers; this.globalID = options.countryCode || 'EBAY-US'; - this.siteId = getSiteId(this.globalID); + this.siteID = getSiteId(this.globalID); } /** @@ -87,12 +89,12 @@ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { * @param state custom state value * @return userConsentUrl */ -const getUserAuthorizationUrl = function (scopes, state = None) { +const getUserAuthorizationUrl = function (scopes, state = null) { if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); if (!this.credentials.redirectUri) throw new Error('redirect_uri is required for redirection after sign in\nkindly check here https://developer.ebay.com/api-docs/static/oauth-redirect-uri.html'); let scopesParam = Array.isArray(scopes) ? scopes.join('%20') : scopes; - let queryParam = `client_id=${this.credentials.clientId}`; + let queryParam = `client_id=${this.credentials.clientID}`; queryParam = `${queryParam}&redirect_uri=${this.credentials.redirectUri}`; queryParam = `${queryParam}&response_type=code`; queryParam = `${queryParam}&scope=${scopesParam}`; @@ -115,7 +117,7 @@ const getAccessTokenByCode = function (code) { grant_type: 'authorization_code', redirect_uri: this.credentials.redirectUri }); - const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); @@ -129,7 +131,7 @@ const getAccessTokenByCode = function (code) { * @param scopes array of scopes for the access token * @return userAccessToken object */ -const getAccessTokenByRefresh = function (refreshToken = None, scopes) { +const getAccessTokenByRefresh = function (refreshToken = null, scopes) { refreshToken = refreshToken ? refreshToken : this.refreshToken; if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); @@ -142,7 +144,7 @@ const getAccessTokenByRefresh = function (refreshToken = None, scopes) { grant_type: 'refresh_token', scope: scopesParam }); - const encodedStr = base64Encode(`${this.credentials.clientId}:${this.credentials.clientSecret}`); + const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); diff --git a/src/merchandising.js b/src/merchandising.js index 0713412..ef78a9a 100644 --- a/src/merchandising.js +++ b/src/merchandising.js @@ -9,7 +9,7 @@ const { MERCH_SRVC_NAME } = require('./constants'); /** * @method getMostWatchedItems {Function} * Add interest and excitement for buyers by showing them what other people are watching. - * @param {String} categoryId (optional) + * @param {String} categoryID (optional) */ const getMostWatchedItems = function (merchOptions) { if (!this.credentials.clientID) throw new Error('Missing App id or client id'); @@ -25,7 +25,7 @@ const getMostWatchedItems = function (merchOptions) { /** * @method getSimilarItems {Function} * Gets similar Items based on the Item id provided. - * @param {String} categoryId (optional) + * @param {String} categoryID (optional) */ const getSimilarItems = function (merchOptions) { if (!this.credentials.clientID) throw new Error('Missing App id or client id'); diff --git a/src/shopping.js b/src/shopping.js index 8d3901c..a273435 100644 --- a/src/shopping.js +++ b/src/shopping.js @@ -5,7 +5,7 @@ const { buildShoppingUrl } = require('./utils'); const makeString = require('make-string'); const getAllCategories = function (categoryID) { - const requestURL = `${urlObject.buildShoppingUrl(this, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; + const requestURL = `${buildShoppingUrl(this, 'GetCategoryInfo')}&${stringifyUrl({ 'CategoryID': categoryID || -1 })}`; return getRequest(requestURL).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -13,22 +13,22 @@ const getAllCategories = function (categoryID) { }; const getUserDetails = function (input) { - if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); - if (!input.userId) throw new Error('invalid_request_error -> userId is null or invalid'); + if (!input || typeof input !== 'object') throw new Error('Invalid input'); + if (!input.userID) throw new Error('User ID is required'); input.includeSelector = input.includeSelector ? input.includeSelector : 'Details'; - const requestUrl = `${urlObject.buildShoppingUrl(this, 'GetUserProfile')}&${stringifyUrl(input)}`; + const requestUrl = `${buildShoppingUrl(this, 'GetUserProfile', input.includeSelector)}&${stringifyUrl(input)}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console ); }; -const getItemStatus = function (itemIds) { - if (!itemIds) throw new Error('Item ID param is required'); +const getItemStatus = function (itemIDs) { + if (!itemIDs) throw new Error('Item ID is required'); const paramsObj = { - 'ItemID': makeString(itemIds, { braces: 'false', quotes: 'no' }) + 'ItemID': makeString(itemIDs, { braces: 'false', quotes: 'no' }) }; - const requestUrl = `${urlObject.buildShoppingUrl(this, 'GetItemStatus')}&${stringifyUrl(paramsObj)}`; + const requestUrl = `${buildShoppingUrl(this, 'GetItemStatus')}&${stringifyUrl(paramsObj)}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -36,9 +36,9 @@ const getItemStatus = function (itemIds) { }; const getShippingCosts = function (input) { - if (!input || typeof input !== 'object') throw new Error('invalid_request_error -> Invalid input'); - if (!input.itemId) throw new Error('invalid_request_error -> Item id is null or invalid'); - const url = `${urlObject.buildShoppingUrl(this, 'GetShippingCosts')}&${stringifyUrl(input)} `; + if (!input || typeof input !== 'object') throw new Error('Invalid input'); + if (!input.itemID) throw new Error('Item ID is required'); + const url = `${buildShoppingUrl(this, 'GetShippingCosts')}&${stringifyUrl(input)} `; return getRequest(url).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -51,8 +51,8 @@ const getShippingCosts = function (input) { * @param {Object} options (required) */ const getMultipleItems = function (options) { - if (!options || !options.itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); - const requestUrl = `${urlObject.buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemId, { braces: 'false', quotes: 'no' }) })}`; + if (!options || !options.itemID) throw new Error('Item ID is required'); + const requestUrl = `${buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemID, { braces: 'false', quotes: 'no' }) })}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -65,9 +65,9 @@ const getMultipleItems = function (options) { * Retrieves publicly visible details about one listing on eBay. * @param {String} itemId (required) */ -const getSingleItem = function (itemId) { - if (!itemId) throw new Error('invalid_request_error -> Item ID is null or invalid'); - const requestUrl = `${buildShoppingUrl(this, 'GetSingleItem')}&${stringifyUrl({ 'ItemID': itemId })} `; +const getSingleItem = function (itemID) { + if (!itemID) throw new Error('Item ID is required'); + const requestUrl = `${buildShoppingUrl(this, 'GetSingleItem')}&${stringifyUrl({ 'ItemID': itemID })} `; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console diff --git a/src/taxonomy-api.js b/src/taxonomy-api.js index e7cb412..73bd710 100644 --- a/src/taxonomy-api.js +++ b/src/taxonomy-api.js @@ -3,7 +3,7 @@ const { makeRequest } = require('./request'); const { upperCase } = require('./utils'); /** - * @method getDefaultCategoryTreeId {Function} + * @method getDefaultcategoryTreeID {Function} * @param {String} marketPlaceId = default = EBAY_US */ @@ -23,73 +23,73 @@ const getDefaultCategoryTreeId = marketPlaceId => { /** * @method getCategoryTree {Function} - * @param {Integer} categoryTreeId = default = 0 + * @param {Integer} categoryTreeID = default = 0 */ -const getCategoryTree = function (categoryTreeId) { - if (!categoryTreeId) categoryTreeId = 0; +const getCategoryTree = function (categoryTreeID) { + if (!categoryTreeID) categoryTreeID = 0; if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { contentType: 'application/json' }; const auth = 'Bearer ' + this.appAccessToken; - return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}`, 'GET', auth).then((result) => { + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeID}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; /** * @method getCategorySubtree {Function} - * @param {String} categoryId = identifier of the category at the top of the subtree. - * @param {String} categoryTreeId = The unique identifier of the eBay category tree from which a category subtree is being requested. + * @param {String} categoryID = identifier of the category at the top of the subtree. + * @param {String} categoryTreeID = The unique identifier of the eBay category tree from which a category subtree is being requested. */ -const getCategorySubtree = function (categoryTreeId, categoryId) { - if (!categoryTreeId) categoryTreeId = 0; - if (!categoryId) throw new Error('Missing Categor id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySubtree#h2-samples'); +const getCategorySubtree = function (categoryTreeID, categoryID) { + if (!categoryTreeID) categoryTreeID = 0; + if (!categoryID) throw new Error('Missing Categor id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySubtree#h2-samples'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { contentType: 'application/json' }; const auth = 'Bearer ' + this.appAccessToken; - return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_subtree?category_id=${categoryId}`, 'GET', auth).then((result) => { + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeID}/get_category_subtree?category_id=${categoryID}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; /** * @method getCategorySuggestions {Function} - * @param {String} categoryTreeId = identifier of the category at the top of the subtree. + * @param {String} categoryTreeID = identifier of the category at the top of the subtree. * @param {String} keyword = input string to get CategorySuggestions. */ -const getCategorySuggestions = function (categoryTreeId, keyword) { - if (!categoryTreeId) categoryTreeId = 0; +const getCategorySuggestions = function (categoryTreeID, keyword) { + if (!categoryTreeID) categoryTreeID = 0; if (!keyword) throw new Error('Missing keyword \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategorySuggestions'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { contentType: 'application/json' }; const auth = 'Bearer ' + this.appAccessToken; - return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_category_suggestions?q=${keyword}`, 'GET', auth).then((result) => { + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeID}/get_category_suggestions?q=${keyword}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; /** * @method getItemAspectsForCategory {Function} - * @param {String} categoryId = identifier of the category at the top of the subtree. + * @param {String} categoryID = identifier of the category at the top of the subtree. * @param {String} keyword = input string to get CategorySuggestions. */ -const getItemAspectsForCategory = function (categoryTreeId, categoryId) { - if (!categoryTreeId) categoryTreeId = 0; - if (!categoryId) throw new Error('Missing Category id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getItemAspectsForCategory#h2-samples'); +const getItemAspectsForCategory = function (categoryTreeID, categoryID) { + if (!categoryTreeID) categoryTreeID = 0; + if (!categoryID) throw new Error('Missing Category id \n Refer documentation here https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getItemAspectsForCategory#h2-samples'); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { contentType: 'application/json' }; const auth = 'Bearer ' + this.appAccessToken; - return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeId}/get_item_aspects_for_category?category_id=${categoryId}`, 'GET', auth).then((result) => { + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/category_tree/${categoryTreeID}/get_item_aspects_for_category?category_id=${categoryID}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; diff --git a/src/utils/URLQuery.js b/src/utils/URLQuery.js index a093aac..dd5f8ec 100644 --- a/src/utils/URLQuery.js +++ b/src/utils/URLQuery.js @@ -11,7 +11,8 @@ module.exports = { urlParseObj: (options, url = '') => { if (options) { for (let key in options) { - url = `${url}&${key}=${options[key]}`; + // The regex turns keys like categoryID to categoryId for the param + url = `${url}&${key.replace(/ID$/, 'Id')}=${options[key]}`; } } return url; diff --git a/src/utils/buildURL.js b/src/utils/buildURL.js index fc3c95b..8590f2a 100644 --- a/src/utils/buildURL.js +++ b/src/utils/buildURL.js @@ -5,10 +5,10 @@ * the type of request. */ module.exports = { - buildSearchUrl: (self, options) => { + buildSearchUrl: (self, options, operationName) => { let url = `https://${self.baseSvcUrl}/services/search/FindingService/v1?`; url += 'SECURITY-APPNAME=' + self.credentials.clientID; - url += '&OPERATION-NAME=' + options.operationName; + url += '&OPERATION-NAME=' + operationName; url += '&SERVICE-VERSION=1.0.0&RESPONSE-DATA-FORMAT=JSON'; url += options.param ? '&' + options.param + '=' + options.name : ''; url += options.additionalParam ? '&' + options.additionalParam : ''; @@ -16,15 +16,16 @@ module.exports = { url += '&outputSelector(0)=SellerInfo'; url += '&outputSelector(1)=PictureURLLarge'; url += options.limit ? '&paginationInput.entriesPerPage=' + options.limit : ''; - url += this.globalID ? '&GLOBAL-ID=' + self.globalID : ''; + url += self.globalID ? '&GLOBAL-ID=' + self.globalID : ''; url += options.pageNumber ? '&paginationInput.pageNumber=' + options.pageNumber : ''; return url; }, - buildShoppingUrl: (self, operationName) => { + buildShoppingUrl: (self, operationName, includeSelector = null) => { let url = `https://${self.baseUrl}/Shopping?`; url += `appid=${self.credentials.clientID}`; url += `&callname=${operationName}`; - url += `&version=967&siteid=${self.siteId || 0}&responseencoding=JSON`; + url += `&version=967&siteid=${self.siteID || 0}&responseencoding=JSON`; + url += includeSelector ? '&IncludeSelector=' + includeSelector : ''; return url; } }; diff --git a/src/utils/general.js b/src/utils/general.js index 1a43911..2129713 100644 --- a/src/utils/general.js +++ b/src/utils/general.js @@ -9,49 +9,49 @@ module.exports = { // Reference: https://developer.ebay.com/DevZone/merchandising/docs/Concepts/SiteIDToGlobalID.html switch (globalID) { case 'EBAY-US': - return 0; + return '0'; case 'EBAY-ENCA': - return 2; + return '2'; case 'EBAY-GB': - return 3; + return '3'; case 'EBAY-AU': - return 15; + return '15'; case 'EBAY-FRBE': - return 16; + return '16'; case 'EBAY-FR': - return 23; + return '23'; case 'EBAY-DE': - return 71; + return '71'; case 'EBAY-MOTOR': - return 77; + return '77'; case 'EBAY-IT': - return 100; + return '100'; case 'EBAY-NLBE': - return 101; + return '101'; case 'EBAY-NL': - return 123; + return '123'; case 'EBAY-ES': - return 146; + return '146'; case 'EBAY-CH': - return 186; + return '186'; case 'EBAY-HK': - return 193; + return '193'; case 'EBAY-IN': - return 201; + return '201'; case 'EBAY-IE': - return 205; + return '205'; case 'EBAY-MY': - return 207; + return '207'; case 'EBAY-FRCA': - return 210; + return '210'; case 'EBAY-PH': - return 211; + return '211'; case 'EBAY-PL': - return 212; + return '212'; case 'EBAY-SG': - return 216; + return '216'; default: - return -1; + throw new Error('Invalid globalID'); } }, upperCase: data => { diff --git a/test/buildURL.test.js b/test/buildURL.test.js index 454294c..c0db624 100644 --- a/test/buildURL.test.js +++ b/test/buildURL.test.js @@ -1,7 +1,7 @@ let expect = require('chai').expect; let should = require('chai').should(); let eBay = require('../src/index'); -let buildURL = require('../src/buildURL'); +let { buildSearchUrl, buildShoppingUrl } = require('../src/utils'); describe('test building url methods', () => { @@ -10,36 +10,41 @@ describe('test building url methods', () => { let expectedSearchUrl = 'https://svcs.ebay.com/services/search/FindingService/v1?SECURITY-APPNAME=testID&OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&RESPONSE-DATA-FORMAT=JSON&keywords=iphone&outputSelector(0)=SellerInfo&outputSelector(1)=PictureURLLarge&paginationInput.entriesPerPage=6&GLOBAL-ID=EBAY-US'; let options = { name: 'iphone', - operationName: 'findItemsByKeywords', param: 'keywords', - clientID: 'testID', limit: 6, - globalID: 'EBAY-US', - baseSvcUrl: 'svcs.ebay.com' }; - expect(buildURL.buildSearchUrl(options, 'findItemsByKeywords')).to.be.equal(expectedSearchUrl); + self = { + baseSvcUrl: 'svcs.ebay.com', + credentials: { + clientID: 'testID' + }, + globalID: 'EBAY-US' + } + expect(buildSearchUrl(self, options, 'findItemsByKeywords')).to.be.equal(expectedSearchUrl); }); it('test Shopping url without selector', () => { let expectedSearchUrl = 'https://open.api.ebay.com/Shopping?appid=testID&callname=demoShoppingName&version=967&siteid=0&responseencoding=JSON'; - let options = { - name: 'iphone', - param: 'keywords', - clientID: 'testID', - baseUrl: 'open.api.ebay.com' + let self = { + credentials: { + clientID: 'testID' + }, + baseUrl: 'open.api.ebay.com', + siteID: 0 }; - expect(buildURL.buildShoppingUrl(options, 'demoShoppingName')).to.be.equal(expectedSearchUrl); + expect(buildShoppingUrl(self, 'demoShoppingName')).to.be.equal(expectedSearchUrl); }); it('test Shopping url including selector', () => { let expectedSearchUrl = 'https://open.api.ebay.com/Shopping?appid=testID&callname=demoShoppingName&version=967&siteid=0&responseencoding=JSON&IncludeSelector=true'; - let options = { - name: 'iphone', - param: 'keywords', - clientID: 'testID', - includeSelector: true, - baseUrl: 'open.api.ebay.com' + + let self = { + credentials: { + clientID: 'testID' + }, + baseUrl: 'open.api.ebay.com', + siteID: 0 }; - expect(buildURL.buildShoppingUrl(options, 'demoShoppingName')).to.be.equal(expectedSearchUrl); + expect(buildShoppingUrl(self, 'demoShoppingName', true)).to.be.equal(expectedSearchUrl); }); }); diff --git a/test/common.test.js b/test/common.test.js index 1e37949..7c08e2b 100644 --- a/test/common.test.js +++ b/test/common.test.js @@ -1,7 +1,7 @@ 'use strict'; const expect = require('chai').expect; const should = require('chai').should(); -const { parseObj } = require('../src/common-utils/index'); +const { urlParseObj } = require('../src/utils'); describe('test common util methods', () => { it('test parse object to query params', () => { @@ -12,8 +12,8 @@ describe('test common util methods', () => { sortOrder: 'PricePlusShippingLowest' }; const emptyOptions = {}; - expect(parseObj(options)).to.be.equal(expectedParam); - expect(parseObj(emptyOptions)).to.be.equal(''); - expect(parseObj(options, 'userName=ebay')).to.be.equal(`userName=ebay${expectedParam}`); + expect(urlParseObj(options)).to.be.equal(expectedParam); + expect(urlParseObj(emptyOptions)).to.be.equal(''); + expect(urlParseObj(options, 'userName=ebay')).to.be.equal(`userName=ebay${expectedParam}`); }); }); diff --git a/test/findItemsByKeyword.test.js b/test/findItemsByKeyword.test.js index ed095d6..89df334 100644 --- a/test/findItemsByKeyword.test.js +++ b/test/findItemsByKeyword.test.js @@ -25,6 +25,6 @@ describe('Test find items by keyword method', () => { let ebay = new Ebay({ clientID: 'ClientId' }); - expect(() => { ebay.findItemsByKeywords(); }).to.throw('Keyword is missing, Keyword is required'); + expect(() => { ebay.findItemsByKeywords(); }).to.throw('Keyword is required'); }); }); diff --git a/test/finding.test.js b/test/finding.test.js index 7b57c81..bc7fd3e 100644 --- a/test/finding.test.js +++ b/test/finding.test.js @@ -13,14 +13,14 @@ describe('test ebay finding Api', () => { let ebay = new Ebay({ clientID: 'ClientId' }); - expect(() => { ebay.findItemsByCategory(); }).to.throw('Category ID is null or invalid'); + expect(() => { ebay.findItemsByCategory(); }).to.throw('Category ID is required'); }); it('test findCompletedItemswith required params', () => { let ebay = new Ebay({ clientID: 'ClientId' }); - expect(() => { ebay.findCompletedItems(''); }).to.throw('Keyword or category ID are required.'); + expect(() => { ebay.findCompletedItems(''); }).to.throw('Keyword or category ID is required'); }); }); @@ -29,7 +29,7 @@ describe('test ebay finding Api', () => { let expectedParam = 'keywords=iphone&categoryId=111&sortOrder=PricePlusShippingLowest'; const options = { keywords: 'iphone', - categoryId: '111', + categoryID: '111', sortOrder: 'PricePlusShippingLowest' }; const emptyOptions = {}; @@ -42,17 +42,17 @@ describe('test ebay finding Api', () => { let expectedParam = 'keywords=iphone&categoryId=111&sortOrder=PricePlusShippingLowest'; const options = { keywords: 'iphone', - categoryId: '111', + categoryID: '111', sortOrder: 'PricePlusShippingLowest', affiliate: { - trackingId: 1234567899, - networkId: 123 + trackingID: 1234567899, + networkID: 123 } }; const optionsWithNoAffiliate = { keywords: 'iphone', - categoryId: '111', + categoryID: '111', sortOrder: 'PricePlusShippingLowest' }; const emptyOptions = {}; @@ -66,14 +66,14 @@ describe('test ebay finding Api', () => { let expectedPaginationParam = 'keywords=iphone&categoryId=111&sortOrder=PricePlusShippingLowest&itemFilter(0).name=Condition&itemFilter(0).value=3000&itemFilter(1).name=SoldItemsOnly&itemFilter(1).value=true&paginationInput.entriesPerPage=2'; const options = { keywords: 'iphone', - categoryId: '111', + categoryID: '111', sortOrder: 'PricePlusShippingLowest', Condition: 3000, SoldItemsOnly: true }; const optionsWithPagination = { keywords: 'iphone', - categoryId: '111', + categoryID: '111', sortOrder: 'PricePlusShippingLowest', Condition: 3000, SoldItemsOnly: true, diff --git a/test/index.test.js b/test/index.test.js index bffd415..dc9e0c8 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -11,13 +11,13 @@ describe('check all the options provided is valid or not - Ebay Constructor ', ( it('should have client ID', () => { let ebayApi = new Ebay({ clientID: '12345' }); - ebayApi.options.should.have.property('clientID'); + ebayApi.credentials.should.have.property('clientID'); }); it('should not have client ID', () => { expect(() => { new Ebay({}); - }).to.throw('Client ID is Missing\ncheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); + }).to.throw('Client ID is Missing\nCheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); }); it('check instance of Ebay', () => { @@ -29,26 +29,22 @@ describe('check all the options provided is valid or not - Ebay Constructor ', ( const ebay = new Ebay({ clientID: 'ClientId' }); - const expected = { - clientID: 'ClientId', - env: 'PROD', - baseUrl: 'api.ebay.com', - baseSvcUrl: 'svcs.ebay.com', - globalID: 'EBAY-US', - siteId: '0' - }; - expect(ebay.options).to.deep.equal(expected); + expect(ebay.credentials.clientID).to.equal('ClientId'); + expect(ebay.baseUrl).to.equal('api.ebay.com'); + expect(ebay.baseSvcUrl).to.equal('svcs.ebay.com'); + expect(ebay.globalID).to.equal('EBAY-US'); + expect(ebay.siteID).to.equal('0'); + expect(ebay.environment).to.equal('PROD'); }); it('test site id, env and country code', () => { const ebay = new Ebay({ clientID: 'ClientId', - siteId: 3, - env: 'SANDBOX', - countryCode: 'EBAY_UK' + environment: 'SANDBOX', + countryCode: 'EBAY-GB' }); - expect(ebay.options.siteId).to.equals(3); - expect(ebay.options.env).to.equals('SANDBOX'); - expect(ebay.options.globalID).to.equals('EBAY_UK'); + expect(ebay.siteID).to.equals('3'); + expect(ebay.environment).to.equals('SANDBOX'); + expect(ebay.globalID).to.equals('EBAY-GB'); }); }); diff --git a/test/shopping.test.js b/test/shopping.test.js index 1dd96f9..f14c75f 100644 --- a/test/shopping.test.js +++ b/test/shopping.test.js @@ -10,13 +10,13 @@ describe('test shopping api', () => { let ebay = new Ebay({ clientID: 'ClientId' }); - expect(() => { ebay.getSingleItem(); }).to.throw('invalid_request_error -> Item ID is null or invalid'); - expect(() => { ebay.getMultipleItems(); }).to.throw('invalid_request_error -> Item ID is null or invalid'); - expect(() => { ebay.getMultipleItems([]); }).to.throw('invalid_request_error -> Item ID is null or invalid'); - expect(() => { ebay.getShippingCosts(); }).to.throw('invalid_request_error -> Invalid input'); - expect(() => { ebay.getUserDetails(); }).to.throw('invalid_request_error -> Invalid input'); + expect(() => { ebay.getSingleItem(); }).to.throw('Item ID is required'); + expect(() => { ebay.getMultipleItems(); }).to.throw('Item ID is required'); + expect(() => { ebay.getMultipleItems([]); }).to.throw('Item ID is required'); + expect(() => { ebay.getShippingCosts(); }).to.throw('Invalid input'); + expect(() => { ebay.getUserDetails(); }).to.throw('Invalid input'); expect(() => { ebay.getAllCategories(); }).to.be.not.throw; - expect(() => { ebay.getItemStatus(); }).to.throw('invalid_request_error -> Item ID is null or invalid'); + expect(() => { ebay.getItemStatus(); }).to.throw('Item ID is required'); }); }); describe('test shopping api calls', () => { @@ -39,7 +39,7 @@ describe('test shopping api', () => { nock('https://api.ebay.com') .get('/Shopping?appid=ABCXXX123&callname=GetMultipleItems&version=967&siteid=0&responseencoding=JSON&itemId=12345,4567') .reply(200, { getMultipleItems: true }); - ebay.getMultipleItems({ itemId: ['12345', '4567'] }).then((data) => { + ebay.getMultipleItems({ itemID: ['12345', '4567'] }).then((data) => { expect(data).to.deep.equal({ getMultipleItems: true }); }); }); @@ -51,7 +51,7 @@ describe('test shopping api', () => { nock('https://api.ebay.com') .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=Details') .reply(200, { getUserDetails: true }); - ebay.getUserDetails({ userId: 'test' }).then((data) => { + ebay.getUserDetails({ userID: 'test' }).then((data) => { expect(data).to.deep.equal({ getUserDetails: true }); }); }); @@ -63,7 +63,7 @@ describe('test shopping api', () => { nock('https://api.ebay.com') .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=sample') .reply(200, { getUserDetailsWithIncludeSelector: true }); - ebay.getUserDetails({ userId: 'test', includeSelector: 'sample' }).then((data) => { + ebay.getUserDetails({ userID: 'test', includeSelector: 'sample' }).then((data) => { expect(data).to.deep.equal({ getUserDetailsWithIncludeSelector: true }); }); }); From 2b5a2a197ac3d5592f6ab3091d4b21d60d566923 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Tue, 19 May 2020 18:13:20 +0700 Subject: [PATCH 07/39] Delete package-lock.json --- package-lock.json | 738 ---------------------------------------------- 1 file changed, 738 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 7960e30..0000000 --- a/package-lock.json +++ /dev/null @@ -1,738 +0,0 @@ -{ - "name": "ebay-node-api", - "version": "2.8.4", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@sinonjs/commons": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", - "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", - "dev": true, - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, - "optional": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "docsify": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.3.tgz", - "integrity": "sha512-o9AvGb4vZOlmorg/58Kj6tNdfBaoSQUJZSFC6fJsfLjGFt45kiXhA2UmALnnVk5sol0WgSzxZlcZw6tu1gVu4Q==", - "dev": true, - "requires": { - "marked": "^0.7.0", - "medium-zoom": "^1.0.5", - "opencollective-postinstall": "^2.0.2", - "prismjs": "^1.19.0", - "strip-indent": "^3.0.0", - "tinydate": "^1.0.0", - "tweezer.js": "^1.4.0" - } - }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - }, - "make-string": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/make-string/-/make-string-1.0.3.tgz", - "integrity": "sha512-qpC9vH1GPDr1VEAIL1jicyoR77SjSuFPE5QYm/lKEFA/br21jKpAehGVZ11i23ai7UhfFGpJ1Hukw6EPi81Rvg==" - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "medium-zoom": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.5.tgz", - "integrity": "sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ==", - "dev": true - }, - "min-indent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", - "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^5.0.1", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - } - } - }, - "nock": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-9.6.1.tgz", - "integrity": "sha512-EDgl/WgNQ0C1BZZlASOQkQdE6tAWXJi8QQlugqzN64JJkvZ7ILijZuG24r4vCC7yOfnm6HKpne5AGExLGCeBWg==", - "dev": true, - "requires": { - "chai": "^4.1.2", - "debug": "^3.1.0", - "deep-equal": "^1.0.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.5", - "mkdirp": "^0.5.0", - "propagate": "^1.0.0", - "qs": "^6.5.1", - "semver": "^5.5.0" - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "prismjs": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", - "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", - "dev": true, - "requires": { - "clipboard": "^2.0.0" - } - }, - "propagate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", - "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", - "dev": true - }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "sinon": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", - "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, - "tinydate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz", - "integrity": "sha512-3GwPk8VhDFnUZ2TrgkhXJs6hcMAIIw4x/xkz+ayK6dGoQmp2nUwKzBXK0WnMsqkh6vfUhpqQicQF3rbshfyJkg==", - "dev": true - }, - "tweezer.js": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", - "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - } - } -} From e55bc324e35e362426581196c2e2cf33ec24504c Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 16:21:39 +0700 Subject: [PATCH 08/39] Update with 2.8.5 changes from original repo --- src/findingApi.js | 55 +++++++++++++------------------------------ src/index.js | 24 +++++++------------ src/utils/URLQuery.js | 38 +++++++++++++++++++++++++++++- src/utils/index.js | 5 ++-- 4 files changed, 65 insertions(+), 57 deletions(-) diff --git a/src/findingApi.js b/src/findingApi.js index 521a82b..536d913 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -1,11 +1,13 @@ 'use strict'; -const { buildSearchUrl } = require('./utils') +const { buildSearchUrl, constructAdditionalParams } = require('./utils') const { getRequest } = require('./request'); const FIND_ITEMS_BY_KEYWORD = 'findItemsByKeywords'; const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; const FIND_COMPLETED_ITEMS = 'findCompletedItems'; +const FIND_ITEMS_PROD = 'findItemsByProduct'; const FIND_ITEMS_ADV = 'findItemsAdvanced'; +const FIND_EBAY_STORE = 'findItemsInEbayStores'; const findItemsByKeywords = function (options) { if (!options) { @@ -104,7 +106,7 @@ const findItemsByProduct = function (options) { if (!options.productID) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; let config = { - operationName: 'findItemsByProduct', + operationName: FIND_ITEMS_PROD, additionalParam: constructAdditionalParams(options) } let url = buildSearchUrl(this, config); @@ -116,50 +118,27 @@ const findItemsByProduct = function (options) { ); }; - -/** - * Constructs query param based on some logic to support filter and aspect_filter params. - * output will be keywords=iphone&itemFilter(0).name=Condition&itemFilter(0).value=3000&itemFilter(1).name=FreeShippingOnly&itemFilter(1).value=true&itemFilter(2).name=SoldItemsOnly&itemFilter(2).value=true - * @param {Object} options - */ -const constructAdditionalParams = function (options) { - let params = ''; - let count = 0; - for (let key in options) { - if (options.hasOwnProperty(key)) { - if (key === 'entriesPerPage' || key === 'pageNumber') { - params = `${params}paginationInput.${key}=${options[key]}&`; - } - else if (key === 'keywords' || key === 'sortOrder') { - params = `${params}${key}=${options[key]}&`; - } - else if (key === 'categoryID' || key === 'productID') { - params = `${params}${key.replace(/ID$/, 'Id')}=${options[key]}&`; - } - else if (key === 'affiliate') { - const innerParams = options[key]; - for (let innerKey in innerParams) { - params = `${params}${key}.${innerKey.replace(/ID$/, 'Id')}=${innerParams[innerKey]}&`; - } - } - else { - params = `${params}itemFilter(${count}).name=${key}& - itemFilter(${count}).value=${options[key]}&`; - count += 1; - } - } +const findItemsIneBayStores = function (options) { + if (!options) throw new Error('Options is required'); + if (!options.storeName) throw new Error('Store name is required.'); + let type = options.type ? options.type : 'ReferenceID'; + let config = { + operationName: FIND_EBAY_STORE, + additionalParam: constructAdditionalParams(options) } - // replace extra space - params = params.replace(/\s/g, ''); - return params.substring(0, params.length - 1); + return getRequest(buildSearchUrl(this, config)).then((data) => { + return JSON.parse(data).findItemsIneBayStoresResponse; + + }, console.error // eslint-disable-line no-console + ); }; module.exports = { findItemsByKeywords, findItemsByCategory, findCompletedItems, - constructAdditionalParams, findItemsByProduct, findItemsAdvanced, + findItemsIneBayStores, getVersion }; diff --git a/src/index.js b/src/index.js index 010d565..1225a85 100644 --- a/src/index.js +++ b/src/index.js @@ -3,15 +3,10 @@ const qs = require('querystring'); const ebayBuyApi = require('./buy-api'); const shoppingApi = require('./shopping'); -const { getDefaultCategoryTreeId, - getCategoryTree, - getCategorySubtree, - getCategorySuggestions, - getItemAspectsForCategory -} = require('./taxonomy-api'); +const taxonomyApi = require('./taxonomy-api'); const ebayFindingApi = require('./findingApi'); const { getSimilarItems, getMostWatchedItems } = require('./merchandising'); -const { getSiteId, base64Encode } = require('./utils'); +const utils = require('./utils'); const { postRequest } = require('./request'); const { PROD_OAUTHENVIRONMENT_WEBENDPOINT, SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT, @@ -59,7 +54,7 @@ function Ebay(options) { // Set the headers this.headers = options.headers; this.globalID = options.countryCode || 'EBAY-US'; - this.siteID = getSiteId(this.globalID); + this.siteID = utils.getSiteId(this.globalID); } /** @@ -75,7 +70,7 @@ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { grant_type: 'client_credentials', scope: scopes }); - const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); + const encodedStr = utils.base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); @@ -117,7 +112,7 @@ const getAccessTokenByCode = function (code) { grant_type: 'authorization_code', redirect_uri: this.credentials.redirectUri }); - const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); + const encodedStr = utils.base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); @@ -144,7 +139,7 @@ const getAccessTokenByRefresh = function (refreshToken = null, scopes) { grant_type: 'refresh_token', scope: scopesParam }); - const encodedStr = base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); + const encodedStr = utils.base64Encode(`${this.credentials.clientID}:${this.credentials.clientSecret}`); const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); @@ -192,15 +187,12 @@ Ebay.prototype = { getRefreshToken, getUserAccessToken, getAppAccessToken, - getDefaultCategoryTreeId, - getCategoryTree, - getCategorySubtree, - getCategorySuggestions, - getItemAspectsForCategory, getMostWatchedItems, getSimilarItems, + ...utils, ...shoppingApi, ...ebayBuyApi, + ...taxonomyApi, ...ebayFindingApi }; diff --git a/src/utils/URLQuery.js b/src/utils/URLQuery.js index dd5f8ec..fd95274 100644 --- a/src/utils/URLQuery.js +++ b/src/utils/URLQuery.js @@ -16,5 +16,41 @@ module.exports = { } } return url; - } + }, + /** + * Constructs query param based on some logic to support filter and aspect_filter params. + * output will be keywords=iphone&itemFilter(0).name=Condition&itemFilter(0).value=3000&itemFilter(1).name=FreeShippingOnly&itemFilter(1).value=true&itemFilter(2).name=SoldItemsOnly&itemFilter(2).value=true + * @param {Object} options + */ + constructAdditionalParams: options => { + let params = ''; + let count = 0; + for (let key in options) { + if (options.hasOwnProperty(key)) { + if (key === 'entriesPerPage' || key === 'pageNumber') { + params = `${params}paginationInput.${key}=${options[key]}&`; + } + else if (key === 'keywords' || key === 'sortOrder') { + params = `${params}${key}=${options[key]}&`; + } + else if (key === 'categoryID' || key === 'productID') { + params = `${params}${key.replace(/ID$/, 'Id')}=${options[key]}&`; + } + else if (key === 'affiliate') { + const innerParams = options[key]; + for (let innerKey in innerParams) { + params = `${params}${key}.${innerKey.replace(/ID$/, 'Id')}=${innerParams[innerKey]}&`; + } + } + else { + params = `${params}itemFilter(${count}).name=${key}& + itemFilter(${count}).value=${options[key]}&`; + count += 1; + } + } + } + // replace extra space + params = params.replace(/\s/g, ''); + return params.substring(0, params.length - 1); + }, } \ No newline at end of file diff --git a/src/utils/index.js b/src/utils/index.js index 6fea5cc..2c9e534 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -8,7 +8,7 @@ const { isEmptyObj, } = require('./general'); const { buildSearchUrl, buildShoppingUrl } = require('./buildURL'); -const { urlParseObj, encodeURLQuery } = require('./URLQuery'); +const { urlParseObj, encodeURLQuery, constructAdditionalParams } = require('./URLQuery'); module.exports = { base64Encode, @@ -19,5 +19,6 @@ module.exports = { buildSearchUrl, buildShoppingUrl, urlParseObj, - encodeURLQuery + encodeURLQuery, + constructAdditionalParams }; From b41c60fcdd4b8e465e67e8195cd6e6b13280ea7a Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 16:21:55 +0700 Subject: [PATCH 09/39] Delete package-lock --- package-lock.json | 738 ---------------------------------------------- 1 file changed, 738 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 7960e30..0000000 --- a/package-lock.json +++ /dev/null @@ -1,738 +0,0 @@ -{ - "name": "ebay-node-api", - "version": "2.8.4", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@sinonjs/commons": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", - "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", - "dev": true, - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, - "optional": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "docsify": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.3.tgz", - "integrity": "sha512-o9AvGb4vZOlmorg/58Kj6tNdfBaoSQUJZSFC6fJsfLjGFt45kiXhA2UmALnnVk5sol0WgSzxZlcZw6tu1gVu4Q==", - "dev": true, - "requires": { - "marked": "^0.7.0", - "medium-zoom": "^1.0.5", - "opencollective-postinstall": "^2.0.2", - "prismjs": "^1.19.0", - "strip-indent": "^3.0.0", - "tinydate": "^1.0.0", - "tweezer.js": "^1.4.0" - } - }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - }, - "make-string": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/make-string/-/make-string-1.0.3.tgz", - "integrity": "sha512-qpC9vH1GPDr1VEAIL1jicyoR77SjSuFPE5QYm/lKEFA/br21jKpAehGVZ11i23ai7UhfFGpJ1Hukw6EPi81Rvg==" - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "medium-zoom": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.5.tgz", - "integrity": "sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ==", - "dev": true - }, - "min-indent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", - "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^5.0.1", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - } - } - }, - "nock": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-9.6.1.tgz", - "integrity": "sha512-EDgl/WgNQ0C1BZZlASOQkQdE6tAWXJi8QQlugqzN64JJkvZ7ILijZuG24r4vCC7yOfnm6HKpne5AGExLGCeBWg==", - "dev": true, - "requires": { - "chai": "^4.1.2", - "debug": "^3.1.0", - "deep-equal": "^1.0.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.5", - "mkdirp": "^0.5.0", - "propagate": "^1.0.0", - "qs": "^6.5.1", - "semver": "^5.5.0" - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "prismjs": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", - "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", - "dev": true, - "requires": { - "clipboard": "^2.0.0" - } - }, - "propagate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", - "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", - "dev": true - }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "sinon": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", - "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, - "tinydate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz", - "integrity": "sha512-3GwPk8VhDFnUZ2TrgkhXJs6hcMAIIw4x/xkz+ayK6dGoQmp2nUwKzBXK0WnMsqkh6vfUhpqQicQF3rbshfyJkg==", - "dev": true - }, - "tweezer.js": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", - "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - } - } -} From 145033e3da2348f05b655b7a29a02563221b3d31 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 16:22:22 +0700 Subject: [PATCH 10/39] Update with new utility import --- test/finding.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/finding.test.js b/test/finding.test.js index bc7fd3e..f5aeec0 100644 --- a/test/finding.test.js +++ b/test/finding.test.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const should = require('chai').should(); const nock = require('nock'); const Ebay = require('../src/index'); -const { constructAdditionalParams } = require('../src/findingApi'); +const { constructAdditionalParams } = require('../src/utils'); const nockFindingApi = nock('https://svcs.ebay.com/'); describe('test ebay finding Api', () => { From 5111e6631eb4377b70096ccfdeace5bd2379db63 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 16:22:36 +0700 Subject: [PATCH 11/39] Change version number to 2.8.6 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0a6c5b1..95840be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ebay-node-api", - "version": "2.8.4", + "version": "2.8.6", "description": "Ebay node api client", "main": "./src/index.js", "homepage": "https://github.com/pajaydev/ebay-node-api", @@ -9,7 +9,7 @@ "test": "mocha && npm run lint", "docs": "docsify init ./docs", "serve-docs": "docsify serve docs", - "publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", + "docs-publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", "prepublish": "npm run test" }, "author": "Ajaykumar prathap", From 049a4c3750f25a97aac410319dd66a25b53aaa51 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 21:41:42 +0700 Subject: [PATCH 12/39] fix typos --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 1225a85..e112190 100644 --- a/src/index.js +++ b/src/index.js @@ -32,7 +32,7 @@ const SANDBOX_ENV = 'SANDBOX'; */ function Ebay(options) { - if (!options) throw new Error('Options is missing, please provide the input'); + if (!options) throw new Error('Options is required'); if (!options.clientID) throw Error('Client ID is Missing\nCheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); if (!(this instanceof Ebay)) return new Ebay(options); if (options.environment === SANDBOX_ENV) { @@ -160,7 +160,7 @@ const setUserAccessTokens = function (userAccessToken) { /** * Assign application access token returned from client credentials workflow (i.e getApplicationToken) * - * @param appAccessToken userAccessToken obj returned from getApplicationToken + * @param appAccessToken appAccessToken obj returned from getApplicationToken */ const setAppAccessToken = function (appAccessToken) { if (!appAccessToken.token_type == 'Application Access Token') throw new Error('appAccessToken is either missing or invalid'); From b66a9ab19becc9db3d367b5905a53cf5178e104d Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Fri, 22 May 2020 21:45:01 +0700 Subject: [PATCH 13/39] Remove unnecessary new line --- src/index.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index e112190..03045a0 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,6 @@ const SANDBOX_ENV = 'SANDBOX'; * @constructor * @public */ - function Ebay(options) { if (!options) throw new Error('Options is required'); if (!options.clientID) throw Error('Client ID is Missing\nCheck documentation to get Client ID http://developer.ebay.com/DevZone/account/'); @@ -90,10 +89,10 @@ const getUserAuthorizationUrl = function (scopes, state = null) { if (!this.credentials.redirectUri) throw new Error('redirect_uri is required for redirection after sign in\nkindly check here https://developer.ebay.com/api-docs/static/oauth-redirect-uri.html'); let scopesParam = Array.isArray(scopes) ? scopes.join('%20') : scopes; let queryParam = `client_id=${this.credentials.clientID}`; - queryParam = `${queryParam}&redirect_uri=${this.credentials.redirectUri}`; - queryParam = `${queryParam}&response_type=code`; - queryParam = `${queryParam}&scope=${scopesParam}`; - queryParam = state ? `${queryParam}&state=${state}` : queryParam; + queryParam += `&redirect_uri=${this.credentials.redirectUri}`; + queryParam += `&response_type=code`; + queryParam += `&scope=${scopesParam}`; + queryParam += state ? `&state=${state}` : ''; return `${this.oauthEndpoint}?${queryParam}`; } From 78eadcfa8e06253a6b5e3de47c9a9cadd18f7bab Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sat, 23 May 2020 14:44:34 +0700 Subject: [PATCH 14/39] Remove unused variable --- package.json | 49 ----------------------------------------------- src/findingApi.js | 1 - 2 files changed, 50 deletions(-) delete mode 100644 package.json diff --git a/package.json b/package.json deleted file mode 100644 index 95840be..0000000 --- a/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "ebay-node-api", - "version": "2.8.6", - "description": "Ebay node api client", - "main": "./src/index.js", - "homepage": "https://github.com/pajaydev/ebay-node-api", - "scripts": { - "lint": "eslint src/*.js test/*.js", - "test": "mocha && npm run lint", - "docs": "docsify init ./docs", - "serve-docs": "docsify serve docs", - "docs-publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", - "prepublish": "npm run test" - }, - "author": "Ajaykumar prathap", - "keywords": [ - "eBay", - "Shopping", - "Searching", - "products", - "Browse", - "Category", - "FindingApi", - "node-api" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "git@github.com:pajaydev/ebay-node-api.git" - }, - "eslintConfig": { - "extends": "ajay" - }, - "dependencies": { - "eslint-config-ajay": "^1.0.6", - "make-string": "^1.0.3", - "oauth-ebay": "^1.0.0" - }, - "devDependencies": { - "chai": "^4.2.0", - "docsify": "^4.11.3", - "documentation": "^12.1.4", - "eslint": "^5.8.0", - "gh-pages": "^2.2.0", - "mocha": "^5.2.0", - "nock": "^9.6.1", - "sinon": "^4.5.0" - } -} diff --git a/src/findingApi.js b/src/findingApi.js index 536d913..22d6065 100644 --- a/src/findingApi.js +++ b/src/findingApi.js @@ -121,7 +121,6 @@ const findItemsByProduct = function (options) { const findItemsIneBayStores = function (options) { if (!options) throw new Error('Options is required'); if (!options.storeName) throw new Error('Store name is required.'); - let type = options.type ? options.type : 'ReferenceID'; let config = { operationName: FIND_EBAY_STORE, additionalParam: constructAdditionalParams(options) From 078d2cea91d40b0330a071c8a24881b601b78b88 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 21:22:24 +0700 Subject: [PATCH 15/39] Change package version to 2.8.7 --- package.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..f6520f1 --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "ebay-node-api", + "version": "2.8.7", + "description": "Ebay node api client", + "main": "./src/index.js", + "homepage": "https://github.com/pajaydev/ebay-node-api", + "scripts": { + "lint": "eslint src/*.js test/*.js", + "test": "mocha && npm run lint", + "docs": "docsify init ./docs", + "serve-docs": "docsify serve docs", + "docs-publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", + "prepublish": "npm run test" + }, + "author": "Ajaykumar prathap", + "keywords": [ + "eBay", + "Shopping", + "Searching", + "products", + "Browse", + "Category", + "FindingApi", + "node-api" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:pajaydev/ebay-node-api.git" + }, + "eslintConfig": { + "extends": "ajay" + }, + "dependencies": { + "eslint-config-ajay": "^1.0.6", + "make-string": "^1.0.3", + "oauth-ebay": "^1.0.0" + }, + "devDependencies": { + "chai": "^4.2.0", + "docsify": "^4.11.3", + "documentation": "^12.1.4", + "eslint": "^5.8.0", + "gh-pages": "^2.2.0", + "mocha": "^5.2.0", + "nock": "^9.6.1", + "sinon": "^4.5.0" + } +} From 61dd172a56a152387bd18058b95e0162d2695893 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 21:23:25 +0700 Subject: [PATCH 16/39] Rename findingApi.js to finding.js --- src/{findingApi.js => finding.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{findingApi.js => finding.js} (100%) diff --git a/src/findingApi.js b/src/finding.js similarity index 100% rename from src/findingApi.js rename to src/finding.js From 33bd9e1e976c4147882f9ad33d37e4cde972027a Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 21:34:50 +0700 Subject: [PATCH 17/39] Fix merges --- src/finding.js | 93 +++++++++++++++++++++++++--------------------- test/index.test.js | 2 +- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/finding.js b/src/finding.js index cee5e0f..22d6065 100644 --- a/src/finding.js +++ b/src/finding.js @@ -1,25 +1,27 @@ 'use strict'; -const urlObject = require('./buildURL'); +const { buildSearchUrl, constructAdditionalParams } = require('./utils') const { getRequest } = require('./request'); -const { constructAdditionalParams } = require('./utils'); const FIND_ITEMS_BY_KEYWORD = 'findItemsByKeywords'; const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; const FIND_COMPLETED_ITEMS = 'findCompletedItems'; +const FIND_ITEMS_PROD = 'findItemsByProduct'; const FIND_ITEMS_ADV = 'findItemsAdvanced'; -const FIND_EBAY_STORES = 'findItemsIneBayStores'; +const FIND_EBAY_STORE = 'findItemsInEbayStores'; const findItemsByKeywords = function (options) { if (!options) { - throw new Error('INVALID_REQUEST_PARMS --> Keyword is missing, Keyword is required'); + throw new Error('Keyword is required'); } - this.options.operationName = FIND_ITEMS_BY_KEYWORD; - this.options.param = 'keywords'; + let config = { + operationName: FIND_ITEMS_BY_KEYWORD, + param: 'keywords' + }; // support only keyword string. - if (!options.keywords) options = { keywords: options }; - options.keywords = encodeURIComponent(options.keywords); - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); + if (!options.keywords) config = { keywords: options }; + config.keywords = encodeURIComponent(options.keywords); + config.additionalParam = constructAdditionalParams(options); + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; }, console.error // eslint-disable-line no-console @@ -27,11 +29,13 @@ const findItemsByKeywords = function (options) { }; const findItemsByCategory = function (categoryID) { - if (!categoryID) throw new Error('INVALID_REQUEST_PARMS --> Category ID is null or invalid'); - this.options.name = categoryID; - this.options.operationName = FIND_ITEMS_BY_CATEGORY; - this.options.param = 'categoryId'; - const url = urlObject.buildSearchUrl(this.options); + if (!categoryID) throw new Error('Category ID is required'); + let config = { + name: categoryID, + operationName: FIND_ITEMS_BY_CATEGORY, + param: 'categoryId' + } + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByCategoryResponse; }, console.error // eslint-disable-line no-console @@ -40,18 +44,19 @@ const findItemsByCategory = function (categoryID) { /** * searches for items whose listings are completed and are no longer available for - * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. + * sale by category (using categoryD), by keywords (using keywords), or a combination of the two. * @param {Object} options */ const findCompletedItems = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> Keyword or category ID are required.'); - if (!options.keywords && !options.categoryId) throw new Error('Keyword or category ID are required.'); + if (!options || options.keywords || options.categoryID) throw new Error('Keyword or category ID is required'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } - this.options.operationName = FIND_COMPLETED_ITEMS; - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: FIND_COMPLETED_ITEMS, + additionalParam: constructAdditionalParams(options), + } + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findCompletedItemsResponse; @@ -62,28 +67,30 @@ const findCompletedItems = function (options) { /** * searches for items whose listings are completed and are no longer available for - * sale by category (using categoryId), by keywords (using keywords), or a combination of the two. + * sale by category (using categoryID), by keywords (using keywords), or a combination of the two. * @param {Object} options */ const findItemsAdvanced = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> check here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); + if (!options) throw new Error('Options is required\nCheck here for input fields https://developer.ebay.com/DevZone/finding/CallRef/findItemsAdvanced.html#Input'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } - this.options.operationName = FIND_ITEMS_ADV; - this.options.additionalParam = constructAdditionalParams(options); - const url = urlObject.buildSearchUrl(this.options); - console.log(url); + let config = { + operationName: FIND_ITEMS_ADV, + additionalParam: constructAdditionalParams(options), + } + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).findItemsAdvancedResponse; }, console.error // eslint-disable-line no-console ); }; - const getVersion = function () { - this.options.operationName = 'getVersion'; - const url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: 'getVersion', + } + const url = buildSearchUrl(this, config); return getRequest(url).then((data) => { return JSON.parse(data).getVersionResponse[0]; }, console.error // eslint-disable-line no-console @@ -95,14 +102,15 @@ const getVersion = function () { * @param {Object} options */ const findItemsByProduct = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> Please enter the Valid input.'); - if (!options.productId) throw new Error('INVALID_REQUEST_PARMS --> Product ID is required.'); + if (!options) throw new Error('Options is required'); + if (!options.productID) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; - this.options.operationName = 'findItemsByProduct'; - this.options.additionalParam = constructAdditionalParams(options); - let url = urlObject.buildSearchUrl(this.options); + let config = { + operationName: FIND_ITEMS_PROD, + additionalParam: constructAdditionalParams(options) + } + let url = buildSearchUrl(this, config); url = `${url}&productId.@type=${type}`; - console.log(url); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByProductResponse; @@ -111,12 +119,13 @@ const findItemsByProduct = function (options) { }; const findItemsIneBayStores = function (options) { - if (!options) throw new Error('INVALID_REQUEST_PARMS --> Please enter the Valid input.'); - if (!options.storeName) throw new Error('INVALID_REQUEST_PARMS --> Store name is required.'); - this.options.operationName = FIND_EBAY_STORES; - this.options.additionalParam = constructAdditionalParams(options); - console.log(urlObject.buildSearchUrl(this.options)); - return getRequest(urlObject.buildSearchUrl(this.options)).then((data) => { + if (!options) throw new Error('Options is required'); + if (!options.storeName) throw new Error('Store name is required.'); + let config = { + operationName: FIND_EBAY_STORE, + additionalParam: constructAdditionalParams(options) + } + return getRequest(buildSearchUrl(this, config)).then((data) => { return JSON.parse(data).findItemsIneBayStoresResponse; }, console.error // eslint-disable-line no-console diff --git a/test/index.test.js b/test/index.test.js index dc9e0c8..9956443 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -6,7 +6,7 @@ describe('check all the options provided is valid or not - Ebay Constructor ', ( it('check input is provided or not', () => { expect(() => { new Ebay(); - }).to.throw('Options is missing, please provide the input'); + }).to.throw('Options is required'); }); it('should have client ID', () => { From 89022d12275245b1f41ac768a304ccdc73749c0d Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 21:36:22 +0700 Subject: [PATCH 18/39] Fix some resource lookups --- src/index.js | 2 +- test/index.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 03045a0..7b9fb82 100644 --- a/src/index.js +++ b/src/index.js @@ -4,7 +4,7 @@ const qs = require('querystring'); const ebayBuyApi = require('./buy-api'); const shoppingApi = require('./shopping'); const taxonomyApi = require('./taxonomy-api'); -const ebayFindingApi = require('./findingApi'); +const ebayFindingApi = require('./finding'); const { getSimilarItems, getMostWatchedItems } = require('./merchandising'); const utils = require('./utils'); const { postRequest } = require('./request'); diff --git a/test/index.test.js b/test/index.test.js index dc9e0c8..9956443 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -6,7 +6,7 @@ describe('check all the options provided is valid or not - Ebay Constructor ', ( it('check input is provided or not', () => { expect(() => { new Ebay(); - }).to.throw('Options is missing, please provide the input'); + }).to.throw('Options is required'); }); it('should have client ID', () => { From 94294ce40af54be3dcdcc5e785fc4e1e9d2764df Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 22:17:39 +0700 Subject: [PATCH 19/39] Small fix for taxonomy api --- src/taxonomy-api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/taxonomy-api.js b/src/taxonomy-api.js index 73bd710..1dc8155 100644 --- a/src/taxonomy-api.js +++ b/src/taxonomy-api.js @@ -3,12 +3,12 @@ const { makeRequest } = require('./request'); const { upperCase } = require('./utils'); /** - * @method getDefaultcategoryTreeID {Function} + * @method getDefaultcategoryTreeId {Function} * @param {String} marketPlaceId = default = EBAY_US */ const DEFAULT_CATEGORY_TREE = 'EBAY_US'; -const getDefaultCategoryTreeId = marketPlaceId => { +const getDefaultCategoryTreeId = function (marketPlaceId) { if (!marketPlaceId) marketPlaceId = DEFAULT_CATEGORY_TREE; marketPlaceId = upperCase(marketPlaceId); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); From d78e866f5c18baa96ce2eadc37545b57c7ed8fd2 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 23:00:26 +0700 Subject: [PATCH 20/39] Properly use buildSearchUrl --- src/finding.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/finding.js b/src/finding.js index 22d6065..d83c106 100644 --- a/src/finding.js +++ b/src/finding.js @@ -76,10 +76,9 @@ const findItemsAdvanced = function (options) { options.keywords = encodeURIComponent(options.keywords); } let config = { - operationName: FIND_ITEMS_ADV, additionalParam: constructAdditionalParams(options), } - const url = buildSearchUrl(this, config); + const url = buildSearchUrl(this, config, FIND_ITEMS_ADV); return getRequest(url).then((data) => { return JSON.parse(data).findItemsAdvancedResponse; }, console.error // eslint-disable-line no-console @@ -87,10 +86,7 @@ const findItemsAdvanced = function (options) { }; const getVersion = function () { - let config = { - operationName: 'getVersion', - } - const url = buildSearchUrl(this, config); + const url = buildSearchUrl(this, {}, 'getVersion'); return getRequest(url).then((data) => { return JSON.parse(data).getVersionResponse[0]; }, console.error // eslint-disable-line no-console @@ -106,10 +102,9 @@ const findItemsByProduct = function (options) { if (!options.productID) throw new Error('Product ID is required.'); let type = options.type ? options.type : 'ReferenceID'; let config = { - operationName: FIND_ITEMS_PROD, additionalParam: constructAdditionalParams(options) } - let url = buildSearchUrl(this, config); + let url = buildSearchUrl(this, config, FIND_ITEMS_PROD); url = `${url}&productId.@type=${type}`; return getRequest(url).then((data) => { return JSON.parse(data).findItemsByProductResponse; @@ -122,10 +117,9 @@ const findItemsIneBayStores = function (options) { if (!options) throw new Error('Options is required'); if (!options.storeName) throw new Error('Store name is required.'); let config = { - operationName: FIND_EBAY_STORE, additionalParam: constructAdditionalParams(options) } - return getRequest(buildSearchUrl(this, config)).then((data) => { + return getRequest(buildSearchUrl(this, config, FIND_EBAY_STORE)).then((data) => { return JSON.parse(data).findItemsIneBayStoresResponse; }, console.error // eslint-disable-line no-console From 58361bc9dffe799fd6abee8f3d3313e3fd2fb26c Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 23:00:49 +0700 Subject: [PATCH 21/39] Avoid include selector query param from duping --- src/shopping.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shopping.js b/src/shopping.js index a273435..ceb16a8 100644 --- a/src/shopping.js +++ b/src/shopping.js @@ -15,8 +15,10 @@ const getAllCategories = function (categoryID) { const getUserDetails = function (input) { if (!input || typeof input !== 'object') throw new Error('Invalid input'); if (!input.userID) throw new Error('User ID is required'); - input.includeSelector = input.includeSelector ? input.includeSelector : 'Details'; - const requestUrl = `${buildShoppingUrl(this, 'GetUserProfile', input.includeSelector)}&${stringifyUrl(input)}`; + let includeSelector = input.includeSelector ? input.includeSelector : 'Details'; + // Remove the includeSelector property so it doesn't get added twice due to stringifyUrl + delete input.includeSelector; + const requestUrl = `${buildShoppingUrl(this, 'GetUserProfile', includeSelector)}&${stringifyUrl(input)}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console @@ -52,7 +54,7 @@ const getShippingCosts = function (input) { */ const getMultipleItems = function (options) { if (!options || !options.itemID) throw new Error('Item ID is required'); - const requestUrl = `${buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemId': makeString(options.itemID, { braces: 'false', quotes: 'no' }) })}`; + const requestUrl = `${buildShoppingUrl(this, 'GetMultipleItems')}&${stringifyUrl({ 'itemID': makeString(options.itemID, { braces: 'false', quotes: 'no' }) })}`; return getRequest(requestUrl).then((data) => { return JSON.parse(data); }, console.error // eslint-disable-line no-console From fdffa304e591bd2f3dc3c33c9dad11fa56f412a4 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 23:01:10 +0700 Subject: [PATCH 22/39] Use template strings consistently --- src/utils/buildURL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/buildURL.js b/src/utils/buildURL.js index 8590f2a..f25a74c 100644 --- a/src/utils/buildURL.js +++ b/src/utils/buildURL.js @@ -25,7 +25,7 @@ module.exports = { url += `appid=${self.credentials.clientID}`; url += `&callname=${operationName}`; url += `&version=967&siteid=${self.siteID || 0}&responseencoding=JSON`; - url += includeSelector ? '&IncludeSelector=' + includeSelector : ''; + url += includeSelector ? `&IncludeSelector=${includeSelector}` : ''; return url; } }; From 2d31163f6a48e95e9eaa3c8b203189ef61e4b629 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 23:01:27 +0700 Subject: [PATCH 23/39] Fix errorful links --- test/shopping.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/shopping.test.js b/test/shopping.test.js index f14c75f..acb7aba 100644 --- a/test/shopping.test.js +++ b/test/shopping.test.js @@ -37,7 +37,7 @@ describe('test shopping api', () => { clientID: 'ABCXXX123' }); nock('https://api.ebay.com') - .get('/Shopping?appid=ABCXXX123&callname=GetMultipleItems&version=967&siteid=0&responseencoding=JSON&itemId=12345,4567') + .get('/Shopping?appid=ABCXXX123&callname=GetMultipleItems&version=967&siteid=0&responseencoding=JSON&itemID=12345,4567') .reply(200, { getMultipleItems: true }); ebay.getMultipleItems({ itemID: ['12345', '4567'] }).then((data) => { expect(data).to.deep.equal({ getMultipleItems: true }); @@ -49,7 +49,7 @@ describe('test shopping api', () => { clientID: 'ABCXXX123' }); nock('https://api.ebay.com') - .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=Details') + .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&IncludeSelector=Details&userID=test') .reply(200, { getUserDetails: true }); ebay.getUserDetails({ userID: 'test' }).then((data) => { expect(data).to.deep.equal({ getUserDetails: true }); @@ -61,7 +61,7 @@ describe('test shopping api', () => { clientID: 'ABCXXX123' }); nock('https://api.ebay.com') - .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&userId=test&includeSelector=sample') + .get('/Shopping?appid=ABCXXX123&callname=GetUserProfile&version=967&siteid=0&responseencoding=JSON&IncludeSelector=sample&userID=test') .reply(200, { getUserDetailsWithIncludeSelector: true }); ebay.getUserDetails({ userID: 'test', includeSelector: 'sample' }).then((data) => { expect(data).to.deep.equal({ getUserDetailsWithIncludeSelector: true }); @@ -73,10 +73,10 @@ describe('test shopping api', () => { clientID: 'ABCXXX123' }); nock('https://api.ebay.com') - .get('/Shopping?appid=ABCXXX123&callname=GetShippingCosts&version=967&siteid=0&responseencoding=JSON&itemId=153265274986&destinationCountryCode=US&destinationPostalCode=95128') + .get('/Shopping?appid=ABCXXX123&callname=GetShippingCosts&version=967&siteid=0&responseencoding=JSON&itemID=153265274986&destinationCountryCode=US&destinationPostalCode=95128') .reply(200, { getShippingCosts: true }); ebay.getShippingCosts({ - itemId: '153265274986', destinationCountryCode: 'US', + itemID: '153265274986', destinationCountryCode: 'US', destinationPostalCode: '95128' }).then((data) => { expect(data).to.deep.equal({ getShippingCosts: true }); From 192aad71c48804d167e4b729952e1715a886661a Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 24 May 2020 23:16:42 +0700 Subject: [PATCH 24/39] Update the demo files with the new changes --- demo/browseApi.js | 17 ++++------------- demo/getAccessToken.js | 14 +++----------- demo/searchApi.js | 12 ++++++------ demo/shopping.js | 4 ++-- demo/taxonomyApi.js | 7 +------ 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/demo/browseApi.js b/demo/browseApi.js index 294c1b4..b544b5b 100644 --- a/demo/browseApi.js +++ b/demo/browseApi.js @@ -5,15 +5,10 @@ let access_token = ''; let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, - body: { - grant_type: 'client_credentials', - scope: 'https://api.ebay.com/oauth/api_scope' - - } }); // Getting access token and calling getItem method. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.getItem('v1|202117468662|0').then((data) => { console.log(data); @@ -25,7 +20,7 @@ ebay.getAccessToken() // Reference ebay developer page https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItemByLegacyId#_samples // Getting access token and calling getItemByLegacyId method. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.getItemByLegacyId({ 'legacyItemId': 2628001 // Get Item Details Using a Legacy ID @@ -37,7 +32,7 @@ ebay.getAccessToken() }); //Get Item Details Using a Legacy ID and SKU -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.getItemByLegacyId({ 'legacyItemId': 2628001, @@ -52,7 +47,7 @@ ebay.getAccessToken() //retrieves the details of the individual items in an item group // reference https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItemsByItemGroup#uri.item_group_id -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.getItemByItemGroup('151915076499').then((data) => { // Data is in format of JSON @@ -62,7 +57,3 @@ ebay.getAccessToken() console.log(error); }); }); - - - - diff --git a/demo/getAccessToken.js b/demo/getAccessToken.js index 759003b..0b9d706 100644 --- a/demo/getAccessToken.js +++ b/demo/getAccessToken.js @@ -4,17 +4,9 @@ const { clientId, clientSecret } = require('./credentials/index'); let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, - body: { - grant_type: 'client_credentials', - scope: 'https://api.ebay.com/oauth/api_scope' - - } }); -//console.log(ebay.getAccessToken()); - -// // //Search for Items by Keyword. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { console.log("generate tokensss"); console.log(data); @@ -22,7 +14,7 @@ ebay.getAccessToken() console.log("++++++++++++++++++++"); -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { console.log("generate tokensss"); console.log(data); @@ -30,7 +22,7 @@ ebay.getAccessToken() setTimeout(() => { - ebay.getAccessToken() + ebay.getApplicationToken() .then((data) => { console.log("generate tokensss"); console.log(data); diff --git a/demo/searchApi.js b/demo/searchApi.js index 84dcd9c..dee3b21 100644 --- a/demo/searchApi.js +++ b/demo/searchApi.js @@ -14,7 +14,7 @@ let ebay = new Ebay({ // // //Search for Items by Keyword. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.searchItems({ keyword: 'drone', @@ -28,7 +28,7 @@ ebay.getAccessToken() // // Search for Items by Category. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.searchItems({ categoryId: 2080, @@ -43,7 +43,7 @@ ebay.getAccessToken() // // Retrieve the Item Aspects by Keyword Search. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.searchItems({ keyword: 'iphone', @@ -58,7 +58,7 @@ ebay.getAccessToken() // // Return Items with Free Shipping. // // Pass params inside filter object to filter items. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.searchItems({ keyword: 'drone', @@ -74,7 +74,7 @@ ebay.getAccessToken() // Return Items Based on Price and Condition. -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.searchItems({ keyword: 'iphone', @@ -90,7 +90,7 @@ ebay.getAccessToken() // // Search items by Image, this is in experimental mode. // https://developer.ebay.com/api-docs/buy/browse/resources/search_by_image/methods/searchByImage -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { console.log ebay.searchByImage({ diff --git a/demo/shopping.js b/demo/shopping.js index af9db5b..66f4f65 100644 --- a/demo/shopping.js +++ b/demo/shopping.js @@ -16,7 +16,7 @@ ebay.getAllCategories('1234').then((data) => { // // Get User Profile // // https://developer.ebay.com/devzone/shopping/docs/callref/GetUserProfile.html -ebay.getUserDetails({ userId: 'ajaykumapratha_0', includeSelector: 'Details' }).then((data) => { +ebay.getUserDetails({ userID: 'ajaykumapratha_0', includeSelector: 'Details' }).then((data) => { console.log(data); }, (error) => { console.log(error); @@ -46,6 +46,6 @@ ebay.getSingleItem('153265274986').then((data) => { console.log(data); }); -ebay.getMultipleItems({ itemId: ['153265274986', '153265274986'] }).then((data) => { +ebay.getMultipleItems({ itemID: ['153265274986', '153265274986'] }).then((data) => { console.log(data); }); \ No newline at end of file diff --git a/demo/taxonomyApi.js b/demo/taxonomyApi.js index 7bc71e5..ce0c81e 100644 --- a/demo/taxonomyApi.js +++ b/demo/taxonomyApi.js @@ -4,15 +4,10 @@ const { clientId, clientSecret } = require('./credentials'); let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, - body: { - grant_type: 'client_credentials', - scope: 'https://api.ebay.com/oauth/api_scope' - - } }); // reference https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getDefaultCategoryTreeId -ebay.getAccessToken() +ebay.getApplicationToken() .then((data) => { ebay.getDefaultCategoryTreeId('EBAY_US').then((data) => { console.log(data); From 8b88396ae0e9c2f7aa96e321df9935bcc1622bb3 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 00:53:47 +0700 Subject: [PATCH 25/39] Add setAppAccessToken function calls in demo --- demo/browseApi.js | 4 ++++ demo/helper/readInput.js | 14 ++++++++++++++ demo/searchApi.js | 8 ++++++-- demo/taxonomyApi.js | 1 + src/constants.js | 2 +- src/index.js | 10 +++++++--- 6 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 demo/helper/readInput.js diff --git a/demo/browseApi.js b/demo/browseApi.js index b544b5b..9cfc73e 100644 --- a/demo/browseApi.js +++ b/demo/browseApi.js @@ -10,6 +10,7 @@ let ebay = new Ebay({ // Getting access token and calling getItem method. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.getItem('v1|202117468662|0').then((data) => { console.log(data); // Data is in format of JSON @@ -22,6 +23,7 @@ ebay.getApplicationToken() // Getting access token and calling getItemByLegacyId method. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.getItemByLegacyId({ 'legacyItemId': 2628001 // Get Item Details Using a Legacy ID }).then((data) => { @@ -34,6 +36,7 @@ ebay.getApplicationToken() //Get Item Details Using a Legacy ID and SKU ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.getItemByLegacyId({ 'legacyItemId': 2628001, 'legacyVariationSku': 'V-00031-WHM' @@ -49,6 +52,7 @@ ebay.getApplicationToken() // reference https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItemsByItemGroup#uri.item_group_id ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.getItemByItemGroup('151915076499').then((data) => { // Data is in format of JSON // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) diff --git a/demo/helper/readInput.js b/demo/helper/readInput.js new file mode 100644 index 0000000..6c56331 --- /dev/null +++ b/demo/helper/readInput.js @@ -0,0 +1,14 @@ +const readline = require('readline'); + +module.exports = { + getCodeInput: query => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + return new Promise(resolve => rl.prompt(query, ans => { + rl.close(); + resolve(ans); + })); + } +} \ No newline at end of file diff --git a/demo/searchApi.js b/demo/searchApi.js index dee3b21..921257f 100644 --- a/demo/searchApi.js +++ b/demo/searchApi.js @@ -1,6 +1,5 @@ const Ebay = require('../src/index'); const { clientId, clientSecret } = require('./credentials'); -const makeString = require('make-string'); let ebay = new Ebay({ clientID: clientId, @@ -16,6 +15,7 @@ let ebay = new Ebay({ // // //Search for Items by Keyword. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.searchItems({ keyword: 'drone', limit: '3' @@ -30,6 +30,7 @@ ebay.getApplicationToken() // // Search for Items by Category. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.searchItems({ categoryId: 2080, limit: '3' @@ -45,6 +46,7 @@ ebay.getApplicationToken() // // Retrieve the Item Aspects by Keyword Search. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.searchItems({ keyword: 'iphone', fieldgroups: 'ASPECT_REFINEMENTS' @@ -60,6 +62,7 @@ ebay.getApplicationToken() // // Pass params inside filter object to filter items. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.searchItems({ keyword: 'drone', limit: 3, @@ -76,6 +79,7 @@ ebay.getApplicationToken() // Return Items Based on Price and Condition. ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.searchItems({ keyword: 'iphone', limit: 3, @@ -92,7 +96,7 @@ ebay.getApplicationToken() // https://developer.ebay.com/api-docs/buy/browse/resources/search_by_image/methods/searchByImage ebay.getApplicationToken() .then((data) => { - console.log + ebay.setAppAccessToken(data); ebay.searchByImage({ imgPath: 'demo/shoe.jpg', limit: 3, diff --git a/demo/taxonomyApi.js b/demo/taxonomyApi.js index ce0c81e..9832740 100644 --- a/demo/taxonomyApi.js +++ b/demo/taxonomyApi.js @@ -9,6 +9,7 @@ let ebay = new Ebay({ // reference https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getDefaultCategoryTreeId ebay.getApplicationToken() .then((data) => { + ebay.setAppAccessToken(data); ebay.getDefaultCategoryTreeId('EBAY_US').then((data) => { console.log(data); // for EN_US { categoryTreeId: '0', categoryTreeVersion: '119' } diff --git a/src/constants.js b/src/constants.js index 8b64deb..9f158e8 100644 --- a/src/constants.js +++ b/src/constants.js @@ -8,5 +8,5 @@ module.exports = { BASE_SVC_URL: 'svcs.ebay.com', BASE_SANDBX_SVC_URL: 'svcs.sandbox.ebay.com', MERCH_SRVC_NAME: 'MerchandisingService', - CLIENT_CRED_SCOPE: 'https://api.ebay.com/oauth/api_scope' + DEFAULT_API_SCOPE: 'https://api.ebay.com/oauth/api_scope' }; diff --git a/src/index.js b/src/index.js index 7b9fb82..7314c1a 100644 --- a/src/index.js +++ b/src/index.js @@ -12,7 +12,7 @@ const { PROD_OAUTHENVIRONMENT_WEBENDPOINT, SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT, PROD_BASE_URL, SANDBOX_BASE_URL, BASE_SANDBX_SVC_URL, - BASE_SVC_URL, CLIENT_CRED_SCOPE + BASE_SVC_URL, DEFAULT_API_SCOPE } = require('./constants'); const PROD_ENV = 'PROD'; const SANDBOX_ENV = 'SANDBOX'; @@ -50,6 +50,10 @@ function Ebay(options) { clientID: options.clientID, clientSecret: options.clientSecret }; + if (options.redirectUri) { + // Assign the redirectUri if provided + this.credentials.redirectUri = options.redirectUri; + } // Set the headers this.headers = options.headers; this.globalID = options.countryCode || 'EBAY-US'; @@ -62,7 +66,7 @@ function Ebay(options) { * @param scopes array of scopes for the access token * @return appAccessToken object */ -const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { +const getApplicationToken = function (scopes = DEFAULT_API_SCOPE) { if (!this.credentials) throw new Error('Credentials are required'); scopes = Array.isArray(scopes) ? scopes.join('%20') : scopes; const data = qs.stringify({ @@ -83,7 +87,7 @@ const getApplicationToken = function (scopes = CLIENT_CRED_SCOPE) { * @param state custom state value * @return userConsentUrl */ -const getUserAuthorizationUrl = function (scopes, state = null) { +const getUserAuthorizationUrl = function (scopes = DEFAULT_API_SCOPE, state = null) { if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); if (!this.credentials.redirectUri) throw new Error('redirect_uri is required for redirection after sign in\nkindly check here https://developer.ebay.com/api-docs/static/oauth-redirect-uri.html'); From aab631f2b5098bb399ec22da4474696b53226e00 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 01:52:28 +0700 Subject: [PATCH 26/39] Remove helpers --- demo/helper/readInput.js | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 demo/helper/readInput.js diff --git a/demo/helper/readInput.js b/demo/helper/readInput.js deleted file mode 100644 index 6c56331..0000000 --- a/demo/helper/readInput.js +++ /dev/null @@ -1,14 +0,0 @@ -const readline = require('readline'); - -module.exports = { - getCodeInput: query => { - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); - return new Promise(resolve => rl.prompt(query, ans => { - rl.close(); - resolve(ans); - })); - } -} \ No newline at end of file From eb7d5b61428ccde43c3bde7246a26b5db4c3284e Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 01:52:52 +0700 Subject: [PATCH 27/39] Add user access token demo --- demo/{getAccessToken.js => getAppToken.js} | 19 +++++++-------- demo/getUserToken.js | 27 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) rename demo/{getAccessToken.js => getAppToken.js} (57%) create mode 100644 demo/getUserToken.js diff --git a/demo/getAccessToken.js b/demo/getAppToken.js similarity index 57% rename from demo/getAccessToken.js rename to demo/getAppToken.js index 0b9d706..2aaa29f 100644 --- a/demo/getAccessToken.js +++ b/demo/getAppToken.js @@ -8,23 +8,20 @@ let ebay = new Ebay({ ebay.getApplicationToken() .then((data) => { - console.log("generate tokensss"); console.log(data); + if (!data.error) { + ebay.setAppAccessToken(data); + console.log(`App token: ${ebay.appAccessToken}`); + } }); -console.log("++++++++++++++++++++"); - -ebay.getApplicationToken() - .then((data) => { - console.log("generate tokensss"); - console.log(data); - }); - - setTimeout(() => { ebay.getApplicationToken() .then((data) => { - console.log("generate tokensss"); console.log(data); + if (!data.error) { + ebay.setAppAccessToken(data); + console.log(`App token: ${ebay.appAccessToken}`); + } }); }, 7200); \ No newline at end of file diff --git a/demo/getUserToken.js b/demo/getUserToken.js new file mode 100644 index 0000000..1e1a566 --- /dev/null +++ b/demo/getUserToken.js @@ -0,0 +1,27 @@ +const readline = require('readline'); +const Ebay = require('../src/index'); +const { clientId, clientSecret, redirectUri } = require('./credentials/index'); + +let ebay = new Ebay({ + clientID: clientId, + clientSecret: clientSecret, + redirectUri: redirectUri, +}); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +const authURL = ebay.getUserAuthorizationUrl(); +console.log(`Please go here for auth code: ${authURL}`); +rl.question("Enter the auth code recieved from the redirect url: ", code => { + rl.close(); + ebay.getAccessTokenByCode(code).then(data => { + console.log(data); + if (!data.error) { + ebay.setUserAccessToken(data); + console.log(`User token: ${ebay.userAccessToken}\nRefresh token: ${ebay.refreshToken}`); + } + }) +}); From 939bb70b897a63b70483e245a56123fed1ad519c Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 01:53:04 +0700 Subject: [PATCH 28/39] Remove unnecessary functions --- src/index.js | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/index.js b/src/index.js index 7314c1a..a60da3c 100644 --- a/src/index.js +++ b/src/index.js @@ -107,7 +107,7 @@ const getUserAuthorizationUrl = function (scopes = DEFAULT_API_SCOPE, state = nu * @param code code generated from browser using the method generateUserAuthorizationUrl. * @return userAccessToken object. */ -const getAccessTokenByCode = function (code) { +const getUserTokenByCode = function (code) { if (!code) throw new Error('Authorization code is required'); if (!this.credentials) throw new Error('Credentials are required'); const data = qs.stringify({ @@ -154,7 +154,7 @@ const getAccessTokenByRefresh = function (refreshToken = null, scopes) { * * @param userAccessToken userAccessToken obj returned from getAccessTokenByCode or getAccessTokenByRefresh */ -const setUserAccessTokens = function (userAccessToken) { +const setUserAccessToken = function (userAccessToken) { if (!userAccessToken.token_type == 'User Access Token') throw new Error('userAccessToken is either missing or invalid'); this.refreshToken = userAccessToken.refresh_token; this.userAccessToken = userAccessToken.access_token; @@ -170,26 +170,13 @@ const setAppAccessToken = function (appAccessToken) { this.appAccessToken = appAccessToken.access_token; } -const getRefreshToken = function () { - return this.refreshToken; -} -const getUserAccessToken = function () { - return this.userAccessToken; -} -const getAppAccessToken = function () { - return this.appAccessToken; -} - Ebay.prototype = { getApplicationToken, getUserAuthorizationUrl, - getAccessTokenByCode, + getAccessTokenByCode: getUserTokenByCode, getAccessTokenByRefresh, setAppAccessToken, - setUserAccessTokens, - getRefreshToken, - getUserAccessToken, - getAppAccessToken, + setUserAccessToken, getMostWatchedItems, getSimilarItems, ...utils, From 4ff27aba1f1d3ab54dc1bebcaf1a7520d5775aef Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 16:35:47 +0700 Subject: [PATCH 29/39] Fix a crooked conditional --- src/finding.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/finding.js b/src/finding.js index d83c106..6380f7a 100644 --- a/src/finding.js +++ b/src/finding.js @@ -48,7 +48,7 @@ const findItemsByCategory = function (categoryID) { * @param {Object} options */ const findCompletedItems = function (options) { - if (!options || options.keywords || options.categoryID) throw new Error('Keyword or category ID is required'); + if (!options || !options.keywords || !options.categoryID) throw new Error('Keyword or category ID is required'); if (options.keywords) { options.keywords = encodeURIComponent(options.keywords); } From d5e19d6d4cf8e0c22b751455dba10e849f2282af Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 16:37:05 +0700 Subject: [PATCH 30/39] Update options fields in demo files --- demo/browseApi.js | 24 +++++++++++------------- demo/finding.js | 8 ++++---- demo/merchandisingApi.js | 9 ++------- demo/searchApi.js | 7 +------ demo/shopping.js | 2 +- 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/demo/browseApi.js b/demo/browseApi.js index 9cfc73e..9f60ccf 100644 --- a/demo/browseApi.js +++ b/demo/browseApi.js @@ -1,7 +1,6 @@ const Ebay = require('../src/index'); const { clientId, clientSecret } = require('./credentials/index'); -let access_token = ''; let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, @@ -11,49 +10,48 @@ let ebay = new Ebay({ ebay.getApplicationToken() .then((data) => { ebay.setAppAccessToken(data); - ebay.getItem('v1|202117468662|0').then((data) => { + ebay.getItemById('v1|202117468662|0').then((data) => { console.log(data); // Data is in format of JSON // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) }) }); - // Reference ebay developer page https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItemByLegacyId#_samples // Getting access token and calling getItemByLegacyId method. ebay.getApplicationToken() .then((data) => { ebay.setAppAccessToken(data); ebay.getItemByLegacyId({ - 'legacyItemId': 2628001 // Get Item Details Using a Legacy ID + legacyItemID: 2628001 // Get Item Details Using a Legacy ID }).then((data) => { - if (!data) console.log(data); + console.log(data); // Data is in format of JSON // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) }); }); -//Get Item Details Using a Legacy ID and SKU +// Get Item Details Using a Legacy ID and SKU ebay.getApplicationToken() .then((data) => { ebay.setAppAccessToken(data); ebay.getItemByLegacyId({ - 'legacyItemId': 2628001, - 'legacyVariationSku': 'V-00031-WHM' + legacyItemID: 110039490209, + legacyVariationSku: 'V-00031-WHM' }).then((data) => { - if (!data) console.log(data); - // Data is in format of JSON - // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) + console.log(data); + Data is in format of JSON + To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) }); }); -//retrieves the details of the individual items in an item group +// retrieves the details of the individual items in an item group // reference https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItemsByItemGroup#uri.item_group_id ebay.getApplicationToken() .then((data) => { ebay.setAppAccessToken(data); - ebay.getItemByItemGroup('151915076499').then((data) => { + ebay.getItemByItemGroup('351825690866').then((data) => { // Data is in format of JSON // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) console.log(data) diff --git a/demo/finding.js b/demo/finding.js index 4d8817f..4475934 100644 --- a/demo/finding.js +++ b/demo/finding.js @@ -21,8 +21,8 @@ ebay.findItemsByKeywords({ Condition: 3000, SoldItemsOnly: false, affiliate: { - networkId: 9, - trackingId: 1234567890 + networkID: 9, + trackingID: 1234567890 } }).then((data) => { console.log(data); @@ -36,7 +36,7 @@ sale by category (using categoryId), by keywords (using keywords), or a combinat Keyword queries search the title and subtitle of the item; they do not search descriptions. */ ebay.findCompletedItems({ keywords: 'Garmin nuvi 1300 Automotive GPS Receiver', - categoryId: '156955', + categoryID: '156955', sortOrder: 'PricePlusShippingLowest', //https://developer.ebay.com/devzone/finding/callref/extra/fndcmpltditms.rqst.srtordr.html Condition: 3000, SoldItemsOnly: true, @@ -50,7 +50,7 @@ ebay.findCompletedItems({ // // This call searches for items on eBay using specific eBay product values. // https://developer.ebay.com/DevZone/finding/CallRef/findItemsByProduct.html#findItemsByProduct ebay.findItemsByProduct({ - productId: 53039031, + productID: 53039031, entriesPerPage: 2 }).then((data) => { console.log(data); diff --git a/demo/merchandisingApi.js b/demo/merchandisingApi.js index 591c064..1d88b2d 100644 --- a/demo/merchandisingApi.js +++ b/demo/merchandisingApi.js @@ -4,17 +4,12 @@ const { clientId, clientSecret } = require('./credentials/index'); let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, - body: { - grant_type: 'client_credentials', - scope: 'https://api.ebay.com/oauth/api_scope' - - } }); ebay.getMostWatchedItems({ maxResults: 3, // optional - categoryId: 267 // optional + categoryID: 267 // optional }).then((data) => { if (data.errorMessage) { console.log('Error:' + data.errorMessage); @@ -25,7 +20,7 @@ ebay.getMostWatchedItems({ ebay.getSimilarItems({ maxResults: 3, // optional - itemId: '280254552262' // optional + itemID: '280254552262' // optional }).then((data) => { if (data.errorMessage) { console.log('Error:' + data.errorMessage); diff --git a/demo/searchApi.js b/demo/searchApi.js index 921257f..c402338 100644 --- a/demo/searchApi.js +++ b/demo/searchApi.js @@ -4,11 +4,6 @@ const { clientId, clientSecret } = require('./credentials'); let ebay = new Ebay({ clientID: clientId, clientSecret: clientSecret, - body: { - grant_type: 'client_credentials', - scope: 'https://api.ebay.com/oauth/api_scope' - - } }); @@ -32,7 +27,7 @@ ebay.getApplicationToken() .then((data) => { ebay.setAppAccessToken(data); ebay.searchItems({ - categoryId: 2080, + categoryID: 2080, limit: '3' }).then((data) => { console.log(data); diff --git a/demo/shopping.js b/demo/shopping.js index 66f4f65..a740c3e 100644 --- a/demo/shopping.js +++ b/demo/shopping.js @@ -33,7 +33,7 @@ ebay.getItemStatus(['153265274986', '153265274986']).then((data) => { // https://developer.ebay.com/devzone/shopping/docs/callref/GetShippingCosts.html ebay.getShippingCosts({ - itemId: '153265274986', destinationCountryCode: 'US', + itemID: '153265274986', destinationCountryCode: 'US', destinationPostalCode: '95128' }).then((data) => { console.log(data); From 773efbcf81fb95e3af658a8da3f92b26e335f295 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 16:45:27 +0700 Subject: [PATCH 31/39] Fix missing param in buildSearchUrl --- src/finding.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/finding.js b/src/finding.js index 6380f7a..52b1bb0 100644 --- a/src/finding.js +++ b/src/finding.js @@ -14,14 +14,13 @@ const findItemsByKeywords = function (options) { throw new Error('Keyword is required'); } let config = { - operationName: FIND_ITEMS_BY_KEYWORD, param: 'keywords' }; // support only keyword string. if (!options.keywords) config = { keywords: options }; config.keywords = encodeURIComponent(options.keywords); config.additionalParam = constructAdditionalParams(options); - const url = buildSearchUrl(this, config); + const url = buildSearchUrl(this, config, FIND_ITEMS_BY_KEYWORD); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; }, console.error // eslint-disable-line no-console @@ -32,10 +31,9 @@ const findItemsByCategory = function (categoryID) { if (!categoryID) throw new Error('Category ID is required'); let config = { name: categoryID, - operationName: FIND_ITEMS_BY_CATEGORY, param: 'categoryId' } - const url = buildSearchUrl(this, config); + const url = buildSearchUrl(this, config, FIND_ITEMS_BY_CATEGORY); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByCategoryResponse; }, console.error // eslint-disable-line no-console @@ -53,10 +51,9 @@ const findCompletedItems = function (options) { options.keywords = encodeURIComponent(options.keywords); } let config = { - operationName: FIND_COMPLETED_ITEMS, additionalParam: constructAdditionalParams(options), } - const url = buildSearchUrl(this, config); + const url = buildSearchUrl(this, config, FIND_COMPLETED_ITEMS); return getRequest(url).then((data) => { return JSON.parse(data).findCompletedItemsResponse; From 61fc9cce77fef800d1d4109582b894c96fdb2d16 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 16:48:53 +0700 Subject: [PATCH 32/39] Fix wrongly named constant --- src/finding.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/finding.js b/src/finding.js index 52b1bb0..1c5730c 100644 --- a/src/finding.js +++ b/src/finding.js @@ -7,7 +7,7 @@ const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; const FIND_COMPLETED_ITEMS = 'findCompletedItems'; const FIND_ITEMS_PROD = 'findItemsByProduct'; const FIND_ITEMS_ADV = 'findItemsAdvanced'; -const FIND_EBAY_STORE = 'findItemsInEbayStores'; +const FIND_EBAY_STORE = 'findItemsIneBayStores'; const findItemsByKeywords = function (options) { if (!options) { From 1fbac91b2912d35101c8bcc59ba6222734032e78 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 17:11:47 +0700 Subject: [PATCH 33/39] Fix some error messages --- src/buy-api.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/buy-api.js b/src/buy-api.js index 815c4b2..8d284ea 100644 --- a/src/buy-api.js +++ b/src/buy-api.js @@ -23,7 +23,7 @@ const getItemById = function (itemID) { }; const getItemByLegacyId = function (legacyOptions) { - if (!legacyOptions) throw new Error('Error Required input to get Items By LegacyID'); + if (!legacyOptions) throw new Error('Required input to get Items By LegacyID'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); if (!legacyOptions.legacyItemID) throw new Error('Error Legacy Item ID is required'); const auth = 'Bearer ' + this.appAccessToken; @@ -43,7 +43,7 @@ const getItemByLegacyId = function (legacyOptions) { const getItemByItemGroup = function (itemGroupID) { if (typeof itemGroupID === 'object') throw new Error('Expecting String or number (Item group id)'); - if (!itemGroupID) throw new Error('Error Item Group ID is required'); + if (!itemGroupID) throw new Error('Item Group ID is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; let config = { @@ -60,12 +60,12 @@ const getItemByItemGroup = function (itemGroupID) { const searchItems = function (searchConfig) { if (!searchConfig) throw new Error('Missing or invalid input parameter to search'); - if (!searchConfig.keyword && !searchConfig.categoryID && !searchConfig.gtin) throw new Error('Error --> Keyword or category id is required in query param'); + if (!searchConfig.keyword && !searchConfig.categoryID && !searchConfig.gtin) throw new Error('Keyword or category id is required'); if (!this.appAccessToken) throw new Error('Missing Application Access token, Generate access token'); const auth = 'Bearer ' + this.appAccessToken; let queryParam = searchConfig.keyword ? 'q=' + encodeURIComponent(searchConfig.keyword) : ''; queryParam = queryParam + (searchConfig.gtin ? '>in=' + searchConfig.gtin : ''); - queryParam = queryParam + (searchConfig.categoryId ? '&category_ids=' + searchConfig.categoryID : ''); + queryParam = queryParam + (searchConfig.categoryID ? '&category_ids=' + searchConfig.categoryID : ''); queryParam = queryParam + (searchConfig.limit ? '&limit=' + searchConfig.limit : ''); queryParam = queryParam + (searchConfig.offset ? '&offset=' + searchConfig.offset : ''); queryParam = queryParam + (searchConfig.sort ? '&sort=' + searchConfig.sort : ''); @@ -90,10 +90,10 @@ const searchByImage = function (searchConfig) { if (!searchConfig.imgPath && !searchConfig.base64Image) throw new Error('imgPath or base64Image is required'); const auth = 'Bearer ' + this.appAccessToken; const encodeImage = searchConfig.imgPath ? base64Encode(fs.readFileSync(searchConfig.imgPath)) : searchConfig.base64Image; - let config = qs.stringify({ - data: { image: encodeImage }, - contentType: "application/json", - }); + let config = { + data: JSON.stringify({ image: encodeImage }), + contentType: 'application/json', + }; const queryString = makeString(searchConfig, { quotes: 'no', braces: 'false', seperator: '&', assignment: '=' }); return new Promise((resolve, reject) => { makeRequest(this, config, `/buy/browse/v1/item_summary/search_by_image?${queryString}`, 'POST', auth).then((result) => { From d9c5e34a027700ec72bc4011f3ecbbb3d07ba0a7 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 17:12:02 +0700 Subject: [PATCH 34/39] Make variable naming consistent --- src/taxonomy-api.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/taxonomy-api.js b/src/taxonomy-api.js index 1dc8155..634911b 100644 --- a/src/taxonomy-api.js +++ b/src/taxonomy-api.js @@ -4,19 +4,19 @@ const { upperCase } = require('./utils'); /** * @method getDefaultcategoryTreeId {Function} - * @param {String} marketPlaceId = default = EBAY_US + * @param {String} marketPlaceID = default = EBAY_US */ const DEFAULT_CATEGORY_TREE = 'EBAY_US'; -const getDefaultCategoryTreeId = function (marketPlaceId) { - if (!marketPlaceId) marketPlaceId = DEFAULT_CATEGORY_TREE; - marketPlaceId = upperCase(marketPlaceId); +const getDefaultCategoryTreeId = function (marketPlaceID) { + if (!marketPlaceID) marketPlaceID = DEFAULT_CATEGORY_TREE; + marketPlaceID = upperCase(marketPlaceID); if (!this.appAccessToken) throw new Error('Missing Access token, Generate access token'); let config = { contentType: 'application/json' }; const auth = 'Bearer ' + this.appAccessToken; - return makeRequest(this, config, `/commerce/taxonomy/v1_beta/get_default_category_tree_id?marketplace_id=${marketPlaceId}`, 'GET', auth).then((result) => { + return makeRequest(this, config, `/commerce/taxonomy/v1_beta/get_default_category_tree_id?marketplace_id=${marketPlaceID}`, 'GET', auth).then((result) => { return JSON.parse(result); }); }; From 59389b0c66eb0ced2f2709b4bd46206b6eb6f84a Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 17:20:59 +0700 Subject: [PATCH 35/39] Fix `isString` use --- src/utils/general.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/utils/general.js b/src/utils/general.js index 2129713..b8c683c 100644 --- a/src/utils/general.js +++ b/src/utils/general.js @@ -1,5 +1,9 @@ 'use strict'; +const isString = value => { + return typeof value === 'string' || value instanceof String; +}; + module.exports = { base64Encode: data => { const buff = Buffer.from(data); @@ -54,16 +58,14 @@ module.exports = { throw new Error('Invalid globalID'); } }, + + isString, + upperCase: data => { if (!isString(data)) data = data.toString(); return data.toUpperCase(); }, - // Returns if a value is a string - isString: value => { - return typeof value === 'string' || value instanceof String; - }, - // Returns if object is empty or not isEmptyObj: obj => { for (let key in obj) { From deb7dc73f9ec9c407a372347cfabfcff285c3ec2 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 17:36:39 +0700 Subject: [PATCH 36/39] Comment wrongly uncommented line --- demo/browseApi.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/browseApi.js b/demo/browseApi.js index 9f60ccf..a5db80f 100644 --- a/demo/browseApi.js +++ b/demo/browseApi.js @@ -40,8 +40,8 @@ ebay.getApplicationToken() legacyVariationSku: 'V-00031-WHM' }).then((data) => { console.log(data); - Data is in format of JSON - To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) + // Data is in format of JSON + // To check the format of Data, Go to this url (https://jsonblob.com/56cbea67-30b8-11e8-953c-5d1886dcf4a0) }); }); From b2b875724432057191a6f03603c10ba42ba58144 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 18:03:41 +0700 Subject: [PATCH 37/39] Add missing params --- src/finding.js | 1 + src/utils/URLQuery.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/finding.js b/src/finding.js index 1c5730c..486d17e 100644 --- a/src/finding.js +++ b/src/finding.js @@ -113,6 +113,7 @@ const findItemsByProduct = function (options) { const findItemsIneBayStores = function (options) { if (!options) throw new Error('Options is required'); if (!options.storeName) throw new Error('Store name is required.'); + options.storeName = encodeURIComponent(options.storeName); let config = { additionalParam: constructAdditionalParams(options) } diff --git a/src/utils/URLQuery.js b/src/utils/URLQuery.js index fd95274..653e0e3 100644 --- a/src/utils/URLQuery.js +++ b/src/utils/URLQuery.js @@ -30,7 +30,7 @@ module.exports = { if (key === 'entriesPerPage' || key === 'pageNumber') { params = `${params}paginationInput.${key}=${options[key]}&`; } - else if (key === 'keywords' || key === 'sortOrder') { + else if (key === 'keywords' || key === 'sortOrder' || key === 'storeName') { params = `${params}${key}=${options[key]}&`; } else if (key === 'categoryID' || key === 'productID') { From a40be925d24c667f1dee7e8709d657e1389c8099 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Mon, 25 May 2020 18:25:08 +0700 Subject: [PATCH 38/39] Fix a query param bug --- src/finding.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/finding.js b/src/finding.js index 486d17e..c9e29b0 100644 --- a/src/finding.js +++ b/src/finding.js @@ -13,13 +13,15 @@ const findItemsByKeywords = function (options) { if (!options) { throw new Error('Keyword is required'); } - let config = { - param: 'keywords' - }; // support only keyword string. - if (!options.keywords) config = { keywords: options }; - config.keywords = encodeURIComponent(options.keywords); - config.additionalParam = constructAdditionalParams(options); + if (!options.keywords) { + options = { keywords: encodeURIComponent(options)}; + } else { + options.keywords = encodeURIComponent(options.keywords); + } + let config = { + additionalParam: constructAdditionalParams(options) + } const url = buildSearchUrl(this, config, FIND_ITEMS_BY_KEYWORD); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; From 7f76f5965b919605b7e8fc146e84c6875c14602b Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Tue, 26 May 2020 13:44:22 +0700 Subject: [PATCH 39/39] Sync lockfile and eslint --- src/buy-api.js | 4 ++-- src/finding.js | 21 ++++++++++--------- src/index.js | 44 +++++++++++++++++++++------------------- src/request.js | 5 +++-- test/buildURL.test.js | 4 ++-- yarn.lock | 47 +++++++++++++++++++++++++++++-------------- 6 files changed, 73 insertions(+), 52 deletions(-) diff --git a/src/buy-api.js b/src/buy-api.js index 8d284ea..b8b8b00 100644 --- a/src/buy-api.js +++ b/src/buy-api.js @@ -3,7 +3,7 @@ const fs = require('fs'); const makeString = require('make-string'); const qs = require('querystring'); const { makeRequest } = require('./request'); -const { base64Encode, encodeURLQuery } = require('./utils') +const { base64Encode, encodeURLQuery } = require('./utils'); const getItemById = function (itemID) { if (!itemID) throw new Error('Item ID is required'); @@ -92,7 +92,7 @@ const searchByImage = function (searchConfig) { const encodeImage = searchConfig.imgPath ? base64Encode(fs.readFileSync(searchConfig.imgPath)) : searchConfig.base64Image; let config = { data: JSON.stringify({ image: encodeImage }), - contentType: 'application/json', + contentType: 'application/json' }; const queryString = makeString(searchConfig, { quotes: 'no', braces: 'false', seperator: '&', assignment: '=' }); return new Promise((resolve, reject) => { diff --git a/src/finding.js b/src/finding.js index c9e29b0..2b549d4 100644 --- a/src/finding.js +++ b/src/finding.js @@ -1,6 +1,6 @@ 'use strict'; -const { buildSearchUrl, constructAdditionalParams } = require('./utils') +const { buildSearchUrl, constructAdditionalParams } = require('./utils'); const { getRequest } = require('./request'); const FIND_ITEMS_BY_KEYWORD = 'findItemsByKeywords'; const FIND_ITEMS_BY_CATEGORY = 'findItemsByCategory'; @@ -16,12 +16,13 @@ const findItemsByKeywords = function (options) { // support only keyword string. if (!options.keywords) { options = { keywords: encodeURIComponent(options)}; - } else { + } + else { options.keywords = encodeURIComponent(options.keywords); } let config = { additionalParam: constructAdditionalParams(options) - } + }; const url = buildSearchUrl(this, config, FIND_ITEMS_BY_KEYWORD); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByKeywordsResponse; @@ -34,7 +35,7 @@ const findItemsByCategory = function (categoryID) { let config = { name: categoryID, param: 'categoryId' - } + }; const url = buildSearchUrl(this, config, FIND_ITEMS_BY_CATEGORY); return getRequest(url).then((data) => { return JSON.parse(data).findItemsByCategoryResponse; @@ -53,8 +54,8 @@ const findCompletedItems = function (options) { options.keywords = encodeURIComponent(options.keywords); } let config = { - additionalParam: constructAdditionalParams(options), - } + additionalParam: constructAdditionalParams(options) + }; const url = buildSearchUrl(this, config, FIND_COMPLETED_ITEMS); return getRequest(url).then((data) => { return JSON.parse(data).findCompletedItemsResponse; @@ -75,8 +76,8 @@ const findItemsAdvanced = function (options) { options.keywords = encodeURIComponent(options.keywords); } let config = { - additionalParam: constructAdditionalParams(options), - } + additionalParam: constructAdditionalParams(options) + }; const url = buildSearchUrl(this, config, FIND_ITEMS_ADV); return getRequest(url).then((data) => { return JSON.parse(data).findItemsAdvancedResponse; @@ -102,7 +103,7 @@ const findItemsByProduct = function (options) { let type = options.type ? options.type : 'ReferenceID'; let config = { additionalParam: constructAdditionalParams(options) - } + }; let url = buildSearchUrl(this, config, FIND_ITEMS_PROD); url = `${url}&productId.@type=${type}`; return getRequest(url).then((data) => { @@ -118,7 +119,7 @@ const findItemsIneBayStores = function (options) { options.storeName = encodeURIComponent(options.storeName); let config = { additionalParam: constructAdditionalParams(options) - } + }; return getRequest(buildSearchUrl(this, config, FIND_EBAY_STORE)).then((data) => { return JSON.parse(data).findItemsIneBayStoresResponse; diff --git a/src/index.js b/src/index.js index a60da3c..4a769e2 100644 --- a/src/index.js +++ b/src/index.js @@ -8,11 +8,12 @@ const ebayFindingApi = require('./finding'); const { getSimilarItems, getMostWatchedItems } = require('./merchandising'); const utils = require('./utils'); const { postRequest } = require('./request'); -const { PROD_OAUTHENVIRONMENT_WEBENDPOINT, - SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT, - PROD_BASE_URL, SANDBOX_BASE_URL, - BASE_SANDBX_SVC_URL, - BASE_SVC_URL, DEFAULT_API_SCOPE +const { + PROD_OAUTHENVIRONMENT_WEBENDPOINT, + SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT, + PROD_BASE_URL, SANDBOX_BASE_URL, + BASE_SANDBX_SVC_URL, + BASE_SVC_URL, DEFAULT_API_SCOPE } = require('./constants'); const PROD_ENV = 'PROD'; const SANDBOX_ENV = 'SANDBOX'; @@ -39,7 +40,8 @@ function Ebay(options) { this.baseUrl = SANDBOX_BASE_URL; this.baseSvcUrl = BASE_SANDBX_SVC_URL; this.oauthEndpoint = SANDBOX_OAUTHENVIRONMENT_WEBENDPOINT; - } else { + } + else { this.environment = PROD_ENV; this.baseUrl = PROD_BASE_URL; this.baseSvcUrl = BASE_SVC_URL; @@ -78,11 +80,11 @@ const getApplicationToken = function (scopes = DEFAULT_API_SCOPE) { return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); }); -} +}; /** * Generates user consent authorization url - * + * * @param scopes array of scopes for the access token * @param state custom state value * @return userConsentUrl @@ -98,11 +100,11 @@ const getUserAuthorizationUrl = function (scopes = DEFAULT_API_SCOPE, state = nu queryParam += `&scope=${scopesParam}`; queryParam += state ? `&state=${state}` : ''; return `${this.oauthEndpoint}?${queryParam}`; -} +}; /** * Generates a User access token given auth code - * + * * @param environment Environment (production/sandbox). * @param code code generated from browser using the method generateUserAuthorizationUrl. * @return userAccessToken object. @@ -119,12 +121,12 @@ const getUserTokenByCode = function (code) { const auth = `Basic ${encodedStr}`; return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); - });; -} + }); +}; /** * Use a refresh token to update a User access token (Updating the expired access token) - * + * * @param refreshToken refresh token, defaults to pre-assigned refresh token * @param scopes array of scopes for the access token * @return userAccessToken object @@ -134,7 +136,7 @@ const getAccessTokenByRefresh = function (refreshToken = null, scopes) { if (!scopes) throw new Error('Scopes parameter is required'); if (!this.credentials) throw new Error('Credentials are required'); let scopesParam = Array.isArray(scopes) ? scopes.join('%20') : scopes; - if (!token) { + if (!refreshToken) { throw new Error('Refresh token is required, to generate refresh token use exchangeCodeForAccessToken method'); // eslint-disable-line max-len } const data = qs.stringify({ @@ -147,28 +149,28 @@ const getAccessTokenByRefresh = function (refreshToken = null, scopes) { return postRequest(this, 'application/x-www-form-urlencoded', data, '/identity/v1/oauth2/token', auth).then(result => { return JSON.parse(result); }); -} +}; /** * Assign user access token and refresh token returned from authorization grant workflow (i.e getAccessTokenByCode) - * + * * @param userAccessToken userAccessToken obj returned from getAccessTokenByCode or getAccessTokenByRefresh */ const setUserAccessToken = function (userAccessToken) { - if (!userAccessToken.token_type == 'User Access Token') throw new Error('userAccessToken is either missing or invalid'); + if (!userAccessToken.token_type === 'User Access Token') throw new Error('userAccessToken is either missing or invalid'); this.refreshToken = userAccessToken.refresh_token; this.userAccessToken = userAccessToken.access_token; -} +}; /** * Assign application access token returned from client credentials workflow (i.e getApplicationToken) - * + * * @param appAccessToken appAccessToken obj returned from getApplicationToken */ const setAppAccessToken = function (appAccessToken) { - if (!appAccessToken.token_type == 'Application Access Token') throw new Error('appAccessToken is either missing or invalid'); + if (!appAccessToken.token_type === 'Application Access Token') throw new Error('appAccessToken is either missing or invalid'); this.appAccessToken = appAccessToken.access_token; -} +}; Ebay.prototype = { getApplicationToken, diff --git a/src/request.js b/src/request.js index c791ce3..e1b104c 100644 --- a/src/request.js +++ b/src/request.js @@ -29,7 +29,8 @@ const makeRequest = (self, customOptions, endpoint, methodName, token) => { let dataString = ''; if (customOptions.data) { dataString = customOptions.data; - } else { + } + else { methodName === 'POST' ? dataString = qs.stringify(customOptions.body) : ''; } const options = { @@ -76,7 +77,7 @@ const postRequest = (self, contentType, data, endpoint, authToken) => { 'Content-Type': contentType, 'authorization': authToken, ...self.headers - }, + } }); req.on('response', (res) => { let body = ''; diff --git a/test/buildURL.test.js b/test/buildURL.test.js index c0db624..e7af0d3 100644 --- a/test/buildURL.test.js +++ b/test/buildURL.test.js @@ -11,7 +11,7 @@ describe('test building url methods', () => { let options = { name: 'iphone', param: 'keywords', - limit: 6, + limit: 6 }; self = { baseSvcUrl: 'svcs.ebay.com', @@ -19,7 +19,7 @@ describe('test building url methods', () => { clientID: 'testID' }, globalID: 'EBAY-US' - } + }; expect(buildSearchUrl(self, options, 'findItemsByKeywords')).to.be.equal(expectedSearchUrl); }); diff --git a/yarn.lock b/yarn.lock index e43aac0..97d3ca2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1345,9 +1345,10 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== -chai@^4.1.2: +chai@^4.1.2, chai@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== dependencies: assertion-error "^1.1.0" check-error "^1.0.2" @@ -1700,15 +1701,16 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -docsify@^4.10.2: - version "4.10.2" - resolved "https://registry.yarnpkg.com/docsify/-/docsify-4.10.2.tgz#0e4e7efad511b75680c69a4d648253e63c8cf647" - integrity sha512-Y1LbI29X9c4uRVEp7wGOYhy8lDrn47o96or0Dbj+pElxWk1cLYQ5CVYPHnf75P3oM1CrEGIrazac6AjYXaD1kw== +docsify@^4.11.3: + version "4.11.3" + resolved "https://registry.yarnpkg.com/docsify/-/docsify-4.11.3.tgz#d79af6f92d48d2c1857b7f76df333db4fd6d19ec" + integrity sha512-o9AvGb4vZOlmorg/58Kj6tNdfBaoSQUJZSFC6fJsfLjGFt45kiXhA2UmALnnVk5sol0WgSzxZlcZw6tu1gVu4Q== dependencies: marked "^0.7.0" - medium-zoom "^1.0.4" + medium-zoom "^1.0.5" opencollective-postinstall "^2.0.2" - prismjs "^1.15.0" + prismjs "^1.19.0" + strip-indent "^3.0.0" tinydate "^1.0.0" tweezer.js "^1.4.0" @@ -3052,7 +3054,7 @@ mdurl@^1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= -medium-zoom@^1.0.4: +medium-zoom@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/medium-zoom/-/medium-zoom-1.0.5.tgz#81413dda20ccdd857141ff420cfab788dd32e20e" integrity sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ== @@ -3099,6 +3101,11 @@ mimic-fn@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-indent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.0.tgz#cfc45c37e9ec0d8f0a0ec3dd4ef7f7c3abe39256" + integrity sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY= + minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -3128,9 +3135,10 @@ mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" -mocha@^5.0.1: +mocha@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== dependencies: browser-stdout "1.3.1" commander "2.15.1" @@ -3216,9 +3224,10 @@ nise@^1.2.0: lolex "^2.3.2" path-to-regexp "^1.7.0" -nock@^9.2.3: +nock@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/nock/-/nock-9.6.1.tgz#d96e099be9bc1d0189a77f4490bbbb265c381b49" + integrity sha512-EDgl/WgNQ0C1BZZlASOQkQdE6tAWXJi8QQlugqzN64JJkvZ7ILijZuG24r4vCC7yOfnm6HKpne5AGExLGCeBWg== dependencies: chai "^4.1.2" debug "^3.1.0" @@ -3579,10 +3588,10 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -prismjs@^1.15.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.19.0.tgz#713afbd45c3baca4b321569f2df39e17e729d4dc" - integrity sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw== +prismjs@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03" + integrity sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ== optionalDependencies: clipboard "^2.0.0" @@ -4076,9 +4085,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@^4.4.5: +sinon@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.5.0.tgz#427ae312a337d3c516804ce2754e8c0d5028cb04" + integrity sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w== dependencies: "@sinonjs/formatio" "^2.0.0" diff "^3.1.0" @@ -4330,6 +4340,13 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + strip-json-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"