diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 40b878d..2feefdf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -node_modules/ \ No newline at end of file +node_modules/ +/dist +.DS_Store \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..ff65059 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.13.0 diff --git a/package.json b/package.json index f7d091d..87dc07d 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,12 @@ "name": "ebay-oauth-nodejs-client", "version": "1.2.1", "description": "Get oauth2 token for ebay developer application", - "main": "src/index.js", + "main": "dist/index.js", "scripts": { "lint": "eslint .", - "test": "eslint . && mocha" + "test": "eslint . && mocha", + "build": "tsc --build", + "clean": "tsc --build --clean" }, "author": "Ajaykumar Prathap", "license": "ISC", @@ -25,11 +27,13 @@ "querystring": "^0.2.0" }, "devDependencies": { + "@types/node": "^17.0.35", "chai": "^4.2.0", "eslint": "^6.8.0", "eslint-config-ebay": "^1.1.1", "mocha": "^6.1.4", - "nock": "^10.0.6" + "nock": "^10.0.6", + "typescript": "^4.6.4" }, "publishConfig": { "registry": "https://registry.npmjs.org/" diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index f00c96c..0000000 --- a/src/constants.js +++ /dev/null @@ -1,29 +0,0 @@ - -module.exports.PAYLOAD_STATE = 'state'; -module.exports.PAYLOAD_REFRESH_TOKEN = 'refresh_token'; - -// HTTP Header Constants -module.exports.HEADER_CONTENT_TYPE = 'application/x-www-form-urlencoded'; -module.exports.HEADER_PREFIX_BASIC = 'Basic '; -module.exports.HEADER_AUTHORIZATION = 'Authorization'; - -// HTTP Request -module.exports.PAYLOAD_VALUE_CLIENT_CREDENTIALS = 'client_credentials'; -module.exports.PAYLOAD_VALUE_AUTHORIZATION_CODE = 'authorization_code'; -module.exports.PAYLOAD_REFRESH_TOKEN = 'refresh_token'; -module.exports.PAYLOAD_STATE = 'state'; - -// Web End point -module.exports.OAUTHENVIRONMENT_WEBENDPOINT_PRODUCTION = 'https://auth.ebay.com/oauth2/authorize'; -module.exports.OAUTHENVIRONMENT_WEBENDPOINT_SANDBOX = 'https://auth.sandbox.ebay.com/oauth2/authorize'; - -// API End Point -module.exports.OAUTHENVIRONMENT_APIENDPOINT_SANDBOX = 'https://api.sandbox.ebay.com/identity/v1/oauth2/token'; -module.exports.OAUTHENVIRONMENT_APIENDPOINT_PRODUCTION = 'https://api.ebay.com/identity/v1/oauth2/token'; - -// Scopes -module.exports.CLIENT_CRED_SCOPE = 'https://api.ebay.com/oauth/api_scope'; - -// Environments -module.exports.PROD_ENV = 'PRODUCTION'; -module.exports.SANDBOX_ENV = 'SANDBOX'; diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..5b1446d --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,27 @@ + +export const PAYLOAD_STATE = 'state'; +export const PAYLOAD_REFRESH_TOKEN = 'refresh_token'; + +// HTTP Header Constants +export const HEADER_CONTENT_TYPE = 'application/x-www-form-urlencoded'; +export const HEADER_PREFIX_BASIC = 'Basic '; +export const HEADER_AUTHORIZATION = 'Authorization'; + +// HTTP Request +export const PAYLOAD_VALUE_CLIENT_CREDENTIALS = 'client_credentials'; +export const PAYLOAD_VALUE_AUTHORIZATION_CODE = 'authorization_code'; + +// Web End point +export const OAUTHENVIRONMENT_WEBENDPOINT_PRODUCTION = 'https://auth.ebay.com/oauth2/authorize'; +export const OAUTHENVIRONMENT_WEBENDPOINT_SANDBOX = 'https://auth.sandbox.ebay.com/oauth2/authorize'; + +// API End Point +export const OAUTHENVIRONMENT_APIENDPOINT_SANDBOX = 'https://api.sandbox.ebay.com/identity/v1/oauth2/token'; +export const OAUTHENVIRONMENT_APIENDPOINT_PRODUCTION = 'https://api.ebay.com/identity/v1/oauth2/token'; + +// Scopes +export const CLIENT_CRED_SCOPE = 'https://api.ebay.com/oauth/api_scope'; + +// Environments +export const PROD_ENV = 'PRODUCTION'; +export const SANDBOX_ENV = 'SANDBOX'; diff --git a/src/index.js b/src/index.ts similarity index 81% rename from src/index.js rename to src/index.ts index 072613c..59cf900 100644 --- a/src/index.js +++ b/src/index.ts @@ -18,9 +18,10 @@ 'use strict'; +import { postRequest } from "./request"; + const queryString = require('querystring'); const consts = require('./constants'); -const postRequest = require('./request'); const { readJSONFile, validateParams, readOptions } = require('./utils'); /** @@ -36,8 +37,34 @@ const { readJSONFile, validateParams, readOptions } = require('./utils'); * @public */ -class EbayOauthToken { - constructor(options) { +export type EbayOptions = EbayCredential & { + filePath: string + prompt: unknown + state: unknown + env: EbayEnvironment +} +export type EbayEnvironment = "PRODUCTION"|"SANDBOX" +export type EbayCredentials = { [env in EbayEnvironment]: Partial }; +export type EbayCredential = { + redirectUri: string + clientId: string + clientSecret: string + baseUrl: string + + +} +type RefreshToken = string +type Scope = string +export type EbayScopes = string[] | string + +export default class EbayOauthToken { + + credentials: Partial + grantType: string + scope: string = '' + refreshToken: RefreshToken = '' + + constructor(options: Partial) { if (!options) { throw new Error('This method accepts an object with filepath or with client id and client secret'); } @@ -53,7 +80,7 @@ class EbayOauthToken { * @param scopes array list of scopes for which you need to generate the access token. * @return accessToken object. */ - getApplicationToken(environment, scopes = consts.CLIENT_CRED_SCOPE) { + getApplicationToken(environment:EbayEnvironment, scopes:EbayScopes = consts.CLIENT_CRED_SCOPE) { validateParams(environment, scopes, this.credentials); this.grantType = consts.PAYLOAD_VALUE_CLIENT_CREDENTIALS; this.scope = Array.isArray(scopes) ? scopes.join('%20') : scopes; @@ -73,7 +100,7 @@ class EbayOauthToken { * @param {string} options.prompt enforce to log in * @return userConsentUrl */ - generateUserAuthorizationUrl(environment, scopes, options) { + generateUserAuthorizationUrl(environment: EbayEnvironment, scopes:EbayScopes, options:EbayOptions) { validateParams(environment, scopes, this.credentials); const credentials = this.credentials[environment]; if (!credentials) throw new Error('Error while reading the credentials, Kindly check here to configure'); @@ -98,13 +125,13 @@ class EbayOauthToken { * @param code code generated from browser using the method generateUserAuthorizationUrl. * @return accessToken object. */ - exchangeCodeForAccessToken(environment, code) { + exchangeCodeForAccessToken(environment: EbayEnvironment, code: string) { if (!code) { throw new Error('Authorization code is required'); } validateParams(environment, true, this.credentials[environment]); const credentials = this.credentials[environment]; - const data = `code=${code}&grant_type=${consts.PAYLOAD_VALUE_AUTHORIZATION_CODE}&redirect_uri=${credentials.redirectUri}`; // eslint-disable-line + const data = `code=${code}&grant_type=${consts.PAYLOAD_VALUE_AUTHORIZATION_CODE}&redirect_uri=${credentials?.redirectUri}`; // eslint-disable-line return postRequest(data, credentials); } @@ -115,7 +142,7 @@ class EbayOauthToken { * @param scopes array list of scopes for which you need to generate the access token. * @return accessToken object. */ - getAccessToken(environment, refreshToken, scopes) { + getAccessToken(environment: EbayEnvironment, refreshToken:RefreshToken, scopes:EbayScopes) { const token = refreshToken || this.getRefreshToken(); validateParams(environment, scopes, this.credentials); this.scope = Array.isArray(scopes) ? scopes.join('%20') : scopes; @@ -126,7 +153,7 @@ class EbayOauthToken { return postRequest(data, this.credentials[environment]); } - setRefreshToken(refreshToken) { + setRefreshToken(refreshToken:RefreshToken) { this.refreshToken = refreshToken; } @@ -135,4 +162,4 @@ class EbayOauthToken { } } -module.exports = EbayOauthToken; + diff --git a/src/request.js b/src/request.ts similarity index 78% rename from src/request.js rename to src/request.ts index f0100b6..3c617ce 100644 --- a/src/request.js +++ b/src/request.ts @@ -17,14 +17,19 @@ */ 'use strict'; + +import { EbayCredential } from "."; + const https = require('https'); -const base64Encode = (encodeData) => { - const buff = new Buffer.from(encodeData); // eslint-disable-line +const base64Encode = (encodeData:string) => { + const buff = Buffer.from(encodeData); return buff.toString('base64'); }; -const postRequest = (data, ebayAuthToken) => { + + +export const postRequest = (data:string, ebayAuthToken: Partial) => { const encodedStr = base64Encode(`${ebayAuthToken.clientId}:${ebayAuthToken.clientSecret}`); const auth = `Basic ${encodedStr}`; return new Promise((resolve, reject) => { @@ -38,10 +43,10 @@ const postRequest = (data, ebayAuthToken) => { hostname: ebayAuthToken.baseUrl, method: 'POST' }); - request.on('response', (response) => { - let body = ''; + request.on('response', (response: any) => { + let body:any = ''; response.setEncoding('utf8'); - response.on('data', (chunk) => body += chunk); // eslint-disable-line + response.on('data', (chunk:any) => body += chunk); // eslint-disable-line response.on('end', () => { if (body.error) { reject(body); @@ -50,11 +55,10 @@ const postRequest = (data, ebayAuthToken) => { }); }); - request.on('error', (error) => { + request.on('error', (error:any) => { reject(error); }); request.end(data); }); }; -module.exports = postRequest; diff --git a/src/utils.js b/src/utils.ts similarity index 80% rename from src/utils.js rename to src/utils.ts index bd4da71..be6ff00 100644 --- a/src/utils.js +++ b/src/utils.ts @@ -1,3 +1,4 @@ +import { EbayEnvironment, EbayScopes, EbayCredentials, EbayOptions } from './index'; 'use strict'; /* * * @@ -21,7 +22,7 @@ const path = require('path'); const sandboxBaseUrl = 'api.sandbox.ebay.com'; const prodBaseUrl = 'api.ebay.com'; -const readJSONFile = (fileName) => { +export const readJSONFile = (fileName: string) => { try { const resolvePath = path.resolve(process.cwd(), fileName); const configData = JSON.parse(fs.readFileSync(resolvePath)); @@ -31,18 +32,17 @@ const readJSONFile = (fileName) => { } }; -const validateParams = (environment, scopes, credentials) => { +export const validateParams = (environment:EbayEnvironment, scopes:EbayScopes, credentials:EbayCredentials) => { if (!environment) throw new Error('Kindly provide the environment - PRODUCTION/SANDBOX'); if (!scopes) throw new Error('scopes is required'); if (!credentials) throw new Error('credentials configured incorrectly'); }; -const readOptions = (options) => { - const credentials = {}; +export const readOptions = (options:EbayOptions) => { + const credentials:Partial = {}; if (!options.env) options.env = 'PRODUCTION'; options.baseUrl = options.env === 'PRODUCTION' ? prodBaseUrl : sandboxBaseUrl; credentials[options.env] = { ...options }; return credentials; }; -module.exports = { readJSONFile, validateParams, readOptions }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..01ea0ac --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "strict": true, + "noImplicitAny": true, + "noEmitOnError": true, + "removeComments": true, + "sourceMap": true, + "target": "es5", + "outDir": "dist", + "declaration": true + }, + "include": [ + "src/**/*" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0c570dc..1bb1d42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,11 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@types/node@^17.0.35": + version "17.0.35" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.35.tgz#635b7586086d51fb40de0a2ec9d1014a5283ba4a" + integrity sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg== + acorn-jsx@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" @@ -1224,6 +1229,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typescript@^4.6.4: + version "4.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"