From 0cbf0d97610b79cd79bd8ea8b2accb33e5fd6384 Mon Sep 17 00:00:00 2001 From: mahajanankur Date: Tue, 18 Oct 2022 12:00:42 +0530 Subject: [PATCH] structure change and bug fixes --- README.md | 6 +-- index.js | 4 +- package-lock.json | 36 ++++++------- package.json | 2 +- .../analytics/analytics.js | 0 src/{controllers => core}/auth/oauth2.js | 37 ++++++++------ .../client/start-client.js | 2 +- src/{controllers => core}/content/content.js | 11 ++-- src/{controllers => core}/index.js | 0 src/{controllers => core}/search/search.js | 0 src/utils/constants.js | 14 ++--- src/utils/request-handler.js | 51 ++++++++----------- src/utils/response.js | 9 ++-- .../client/start-client-validation.js | 2 +- src/validations/content/content-validation.js | 21 ++++++-- 15 files changed, 105 insertions(+), 90 deletions(-) rename src/{controllers => core}/analytics/analytics.js (100%) rename src/{controllers => core}/auth/oauth2.js (62%) rename src/{controllers => core}/client/start-client.js (60%) rename src/{controllers => core}/content/content.js (93%) rename src/{controllers => core}/index.js (100%) rename src/{controllers => core}/search/search.js (100%) diff --git a/README.md b/README.md index a8704f9..d40b8b2 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,7 @@ The access token will expire after 4 hours, so you need to generate a new access ```javascript (async() => { try { - const refreshToken = await oauth.getRefreshedToken({ - refreshToken: 'changeme', - clientId: 'changeme', - clientSecret: 'changeme' - }); + const refreshToken = await oauth.getRefreshedToken(); console.log(refreshToken); } catch (error) { console.log(error.message); diff --git a/index.js b/index.js index 2515b52..2c73ad1 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ -const APIs = require('./src/controllers'); +const APIs = require('./src/core'); const validations = require('./src/validations'); -const { startClient } = require('./src/controllers/client/start-client'); +const { startClient } = require('./src/core/client/start-client'); /** * @class Searchunify diff --git a/package-lock.json b/package-lock.json index 76d50e1..5d3f74e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "su-sdk", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { "@hapi/hoek": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", - "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, "@hapi/topo": { "version": "5.1.0", @@ -18,9 +18,9 @@ } }, "@sideway/address": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", - "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "requires": { "@hapi/hoek": "^9.0.0" } @@ -36,11 +36,11 @@ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "call-bind": { @@ -53,9 +53,9 @@ } }, "follow-redirects": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", - "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "function-bind": { "version": "1.1.1", @@ -86,13 +86,13 @@ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "joi": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", - "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "version": "17.6.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.3.tgz", + "integrity": "sha512-YlQsIaS9MHYekzf1Qe11LjTkNzx9qhYluK3172z38RxYoAUf82XMX1p1DG1H4Wtk2ED/vPdSn9OggqtDu+aTow==", "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.0", + "@sideway/address": "^4.1.3", "@sideway/formula": "^3.0.0", "@sideway/pinpoint": "^2.0.0" } diff --git a/package.json b/package.json index b2fcd07..361b0c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "su-sdk", - "version": "1.0.3", + "version": "1.0.4", "description": "SearchUnify javascript SDK enables developers to easily work with the SearchUnify platform and build scalable solutions with search, analytics, crawlers and more.", "main": "index.js", "repository": { diff --git a/src/controllers/analytics/analytics.js b/src/core/analytics/analytics.js similarity index 100% rename from src/controllers/analytics/analytics.js rename to src/core/analytics/analytics.js diff --git a/src/controllers/auth/oauth2.js b/src/core/auth/oauth2.js similarity index 62% rename from src/controllers/auth/oauth2.js rename to src/core/auth/oauth2.js index 8fd07ec..e6bf563 100644 --- a/src/controllers/auth/oauth2.js +++ b/src/core/auth/oauth2.js @@ -27,22 +27,26 @@ const generateToken = async (params) => { } } - let response = await HttpRequest(options); - if (response.status && response.data && response.data.accessToken) { - AUTHENTICATION.OAUTH2.ACCESS_TOKEN = response.data.accessToken; - AUTHENTICATION.OAUTH2.REFRESH_TOKEN = response.data.refreshToken; + let { data, status, message } = await HttpRequest(options); + if (status && data.accessToken) { + AUTHENTICATION.OAUTH2.ACCESS_TOKEN = data.accessToken; + AUTHENTICATION.OAUTH2.REFRESH_TOKEN = data.refreshToken; AUTHENTICATION.AUTH_TYPE = 'oauth2'; + AUTHENTICATION.OAUTH2.CLIENT_ID = isValid.value.clientId; + AUTHENTICATION.OAUTH2.CLIENT_SECRET = isValid.value.clientSecret; + return 'Token generated successfully.'; + } + else { + throw new Error(`Client not initilized. Error message (${message})`); } - return response; } -const getRefreshedToken = async (params) => { - const isValid = validation.oauth2.refreshTokenValidation(params, validateClient()); - if (isValid.error) throw new Error(isValid.error.message); +const getRefreshedToken = async () => { + validateClient(); const queryStrings = qs.stringify({ grant_type: 'refresh_token', - client_id: isValid.value.clientId, - client_secret: isValid.value.clientSecret, + client_id: AUTHENTICATION.OAUTH2.CLIENT_ID, + client_secret: AUTHENTICATION.OAUTH2.CLIENT_SECRET, refresh_token: AUTHENTICATION.OAUTH2.REFRESH_TOKEN }); @@ -55,13 +59,16 @@ const getRefreshedToken = async (params) => { 'Cache-Control': 'no-cache' } } - let response = await HttpRequest(options); - if (response.status && response.data && response.data.accessToken) { - AUTHENTICATION.OAUTH2.ACCESS_TOKEN = response.data.accessToken; - AUTHENTICATION.OAUTH2.REFRESH_TOKEN = response.data.refreshToken; + let { data, status, message } = await HttpRequest(options); + if (status && data.accessToken) { + AUTHENTICATION.OAUTH2.ACCESS_TOKEN = data.accessToken; + AUTHENTICATION.OAUTH2.REFRESH_TOKEN = data.refreshToken; AUTHENTICATION.AUTH_TYPE = 'oauth2'; + return 'Token refreshed successfully.'; + } + else { + throw new Error(`Token not refreshed. Error message (${message})`); } - return response; } module.exports = { diff --git a/src/controllers/client/start-client.js b/src/core/client/start-client.js similarity index 60% rename from src/controllers/client/start-client.js rename to src/core/client/start-client.js index b31db9b..bfe51f7 100644 --- a/src/controllers/client/start-client.js +++ b/src/core/client/start-client.js @@ -2,6 +2,6 @@ const { AUTHENTICATION } = require("./../../utils/constants"); exports.startClient = (params) => { AUTHENTICATION.INSTANCE_URL = params.instance; - AUTHENTICATION.REQUEST_TIMEOUT = params.timeout; + AUTHENTICATION.REQUEST_TIMEOUT = params.timeout ? params.timeout: AUTHENTICATION.REQUEST_TIMEOUT; } diff --git a/src/controllers/content/content.js b/src/core/content/content.js similarity index 93% rename from src/controllers/content/content.js rename to src/core/content/content.js index 5d51b99..f2560ac 100644 --- a/src/controllers/content/content.js +++ b/src/core/content/content.js @@ -1,3 +1,4 @@ +const qs = require('qs'); const { CONTENT_API } = require("../../utils/su-apis"); const { AUTHENTICATION } = require("../../utils/constants"); const { HttpRequest } = require("../../utils/request-handler"); @@ -57,9 +58,14 @@ const getObjectSpecificData = async (params) => { const isValid = validation.content.objectSpecificDataValidation(params, validateClient(AUTHENTICATION)); if (isValid.error) throw new Error(isValid.error.message); + const queryParams = qs.stringify({ + from: isValid.value.offset, + size: isValid.value.size + }); + const options = { method: 'get', - url: `${AUTHENTICATION.INSTANCE_URL}${CONTENT_API.OBJECT_DATA.replace('', isValid.value.contentSourceId).replace('', isValid.value.objectId)}`, + url: `${AUTHENTICATION.INSTANCE_URL}${CONTENT_API.OBJECT_DATA.replace('', isValid.value.contentSourceId).replace('', isValid.value.objectId)}?${queryParams}`, headers: { 'Authorization': getAuthHeader(), 'Content-Type': 'application/json' @@ -71,9 +77,8 @@ const getObjectSpecificData = async (params) => { } const getObjectSpecificDataWithId = async (params) => { - const isValid = validation.content.objectSpecificDataWithIdValidation(params, validateClient(AUTHENTICATION)); + let isValid = validation.content.objectSpecificDataWithIdValidation(params, validateClient(AUTHENTICATION)); if (isValid.error) throw new Error(isValid.error.message); - const options = { method: 'get', url: `${AUTHENTICATION.INSTANCE_URL}${CONTENT_API.OBJECT_DATA_WITH_ID.replace('', isValid.value.contentSourceId).replace('', isValid.value.objectId).replace('', isValid.value.documentId)}`, diff --git a/src/controllers/index.js b/src/core/index.js similarity index 100% rename from src/controllers/index.js rename to src/core/index.js diff --git a/src/controllers/search/search.js b/src/core/search/search.js similarity index 100% rename from src/controllers/search/search.js rename to src/core/search/search.js diff --git a/src/utils/constants.js b/src/utils/constants.js index 77d3bd3..bfc3ff2 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -1,15 +1,17 @@ exports.AUTHENTICATION = { REQUEST_TIMEOUT: 60000, - INSTANCE_URL: '', - AUTH_TYPE: '', + INSTANCE_URL: null, + AUTH_TYPE: null, OAUTH2: { - ACCESS_TOKEN: '', - REFRESH_TOKEN: '' + ACCESS_TOKEN: null, + REFRESH_TOKEN: null, + CLIENT_ID: null, + CLIENT_SECRET: null }, JWT: { - JWT_TOKEN: '', + JWT_TOKEN: null, }, API_KEY: { - API_KEY_TOKEN: '', + API_KEY_TOKEN: null, } } \ No newline at end of file diff --git a/src/utils/request-handler.js b/src/utils/request-handler.js index 324e2c1..8edbd37 100644 --- a/src/utils/request-handler.js +++ b/src/utils/request-handler.js @@ -2,43 +2,36 @@ const axios = require('axios'); const { Response } = require('./response'); const { AUTHENTICATION } = require('./constants') -const updateResponse = (response) => { +const responseHandler = (response) => { + // delete extra message and statuscode. + let { data, message } = response; + let successMessage = message ? message : `Successfully done.`; + if (message) delete response.message; let result = { - message: null, - data: null - } - if (response.data && response.data.data) { - result.message = response.data.message; - result.data = response.data.data; - delete response.data.data.message; - delete response.data.data.status; - } - else if (response.data) { - result.message = response.data.message; - result.data = response.data; - delete response.data.message; - delete response.data.status; + status: true, + message: successMessage, + data: data ? data : response } return result; } exports.HttpRequest = async (options) => { try { - const requestPayload = {...options, timeout: AUTHENTICATION.REQUEST_TIMEOUT }; - let response = await axios(requestPayload); - const result = updateResponse(response); - return new Response(true, result.message, result.data); + const requestPayload = { ...options, timeout: AUTHENTICATION.REQUEST_TIMEOUT }; + let { data } = await axios(requestPayload); + const result = responseHandler(data); + return result } catch (error) { - let message = error.message; - if (error.response && error.response.data) { - if (error.response.data.message) { - message = error.response.data.message; - } - else if (error.response.data.error) { - message = error.response.data.error; - } + let errorMessage = ''; + let { response, message } = error; + let { data } = response; + if (data && data.error) { + errorMessage = data.error.message ? data.error.message : message; } - - return new Response(false, message); + else if (data && data.message) { + errorMessage = data.message ? data.message : message; + } + + return new Response(false, errorMessage); } } \ No newline at end of file diff --git a/src/utils/response.js b/src/utils/response.js index f10fd6a..7af2428 100644 --- a/src/utils/response.js +++ b/src/utils/response.js @@ -1,12 +1,9 @@ /** * @param status Api response status like true/false. * @param message Api response message. - * @param data Api response data. - * @summary Successful response format. + * @summary Unsuccessful response format. */ -exports.Response = function (status, message, data) { - const defaultMessage = 'Successful response.'; +exports.Response = function (status, message) { this.status = status; - this.message = message ? message : defaultMessage; - if (data) this.data = data; + this.message = message; }; \ No newline at end of file diff --git a/src/validations/client/start-client-validation.js b/src/validations/client/start-client-validation.js index 90ec32e..a5bc298 100644 --- a/src/validations/client/start-client-validation.js +++ b/src/validations/client/start-client-validation.js @@ -28,7 +28,7 @@ exports.validateClient = () => { const schema = Joi.object().keys({ ACCESS_TOKEN: Joi.string().trim().required().error(new Error(`Invalid access token.`)), REFRESH_TOKEN: Joi.string().trim().required().error(new Error(`Invalid refresh token.`)), - }) + }).unknown(true); const isValid = schema.validate(oauth2); if (isValid.error) throw new Error(isValid.error.message); } diff --git a/src/validations/content/content-validation.js b/src/validations/content/content-validation.js index a0ead1e..30a24bf 100644 --- a/src/validations/content/content-validation.js +++ b/src/validations/content/content-validation.js @@ -12,7 +12,7 @@ const objectSpecificDataValidation = (options) => { const schema = Joi.object().keys({ contentSourceId: Joi.string().trim().required(), objectId: Joi.string().trim().required(), - startFrom: Joi.number(), + offset: Joi.number(), size: Joi.number().min(1).max(50) }); const result = schema.validate(options); @@ -26,7 +26,10 @@ const objectSpecificDataWithIdValidation = (options) => { documentId: Joi.string().trim().required() }); const result = schema.validate(options); - return result; + const response = encodePathUri(result, { + documentId: true // Boolean values: if encode needed. + }) + return response; } @@ -38,7 +41,10 @@ const updateDoucmentByIdValidation = (options) => { data: Joi.object().min(1).required() }); const result = schema.validate(options); - return result; + const response = encodePathUri(result, { + documentId: true + }) + return response; } const uploadDataValidation = (options) => { @@ -51,6 +57,15 @@ const uploadDataValidation = (options) => { return result; } +const encodePathUri = (result, encodeParams) => { + Object.keys(encodeParams).forEach(items => { + if (encodeParams[items] === true) { + result.value[items] = encodeURIComponent(encodeURIComponent(result.value[items])) + } + }); + return result; +} + module.exports = { contentSourceIdValidation, objectSpecificDataValidation,