From 2fa3a353facadfa52d8d1b65bad225e6ebe7398e Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 8 Jun 2021 13:25:08 +0200 Subject: [PATCH 1/5] feat: select extra attributes in JES response --- src/SASjs.ts | 10 ++++++++-- src/job-execution/JesJobExecutor.ts | 28 ++++++++++++++++++++++++---- src/job-execution/JobExecutor.ts | 7 +++++-- src/types/ExtraResponseAttributes.ts | 6 ++++++ 4 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 src/types/ExtraResponseAttributes.ts diff --git a/src/SASjs.ts b/src/SASjs.ts index c19f778..4f456d2 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -14,6 +14,7 @@ import { Sas9JobExecutor } from './job-execution' import { ErrorResponse } from './types/errors' +import { ExtraResponseAttributes } from './types/ExtraResponseAttributes' const defaultConfig: SASjsConfig = { serverUrl: '', @@ -540,13 +541,17 @@ export default class SASjs { * `await request(sasJobPath, data, config, () => setIsLoggedIn(false))` * If you are not passing in any data and configuration, it will look like so: * `await request(sasJobPath, {}, {}, () => setIsLoggedIn(false))` + * @param extraResponseAttributes - a array of predefined values that are used + * to provide extra attributes (same names as those values) to be added in response + * Supported values: 'file' | 'output' | 'data' */ public async request( sasJob: string, data: { [key: string]: any }, config: { [key: string]: any } = {}, loginRequiredCallback?: () => any, - accessToken?: string + accessToken?: string, + extraResponseAttributes: ExtraResponseAttributes[] = [] ) { config = { ...this.sasjsConfig, @@ -568,7 +573,8 @@ export default class SASjs { data, config, loginRequiredCallback, - accessToken + accessToken, + extraResponseAttributes ) } } else if ( diff --git a/src/job-execution/JesJobExecutor.ts b/src/job-execution/JesJobExecutor.ts index 42d22a4..b64006c 100644 --- a/src/job-execution/JesJobExecutor.ts +++ b/src/job-execution/JesJobExecutor.ts @@ -5,6 +5,7 @@ import { JobExecutionError, LoginRequiredError } from '../types/errors' +import { ExtraResponseAttributes } from '../types/ExtraResponseAttributes' import { BaseJobExecutor } from './JobExecutor' export class JesJobExecutor extends BaseJobExecutor { @@ -17,7 +18,8 @@ export class JesJobExecutor extends BaseJobExecutor { data: any, config: any, loginRequiredCallback?: any, - accessToken?: string + accessToken?: string, + extraResponseAttributes: ExtraResponseAttributes[] = [] ) { const loginCallback = loginRequiredCallback || (() => Promise.resolve()) @@ -30,10 +32,26 @@ export class JesJobExecutor extends BaseJobExecutor { data, accessToken ) - .then((response) => { + .then((response: any) => { this.appendRequest(response, sasJob, config.debug) - resolve(response) + let responseObject = {} + + if (extraResponseAttributes && extraResponseAttributes.length > 0) { + const extraAttributes = extraResponseAttributes.reduce( + (map: any, obj: any) => ((map[obj] = response[obj]), map), + {} + ) + + responseObject = { + result: response.result, + ...extraAttributes + } + } else { + responseObject = response.result + } + + resolve(responseObject) }) .catch(async (e: Error) => { if (e instanceof JobExecutionError) { @@ -50,7 +68,9 @@ export class JesJobExecutor extends BaseJobExecutor { sasJob, data, config, - loginRequiredCallback + loginRequiredCallback, + accessToken, + extraResponseAttributes ).then( (res: any) => { resolve(res) diff --git a/src/job-execution/JobExecutor.ts b/src/job-execution/JobExecutor.ts index df75cb6..bc91a46 100644 --- a/src/job-execution/JobExecutor.ts +++ b/src/job-execution/JobExecutor.ts @@ -1,5 +1,6 @@ import { ServerType } from '@sasjs/utils/types' import { SASjsRequest } from '../types' +import { ExtraResponseAttributes } from '../types/ExtraResponseAttributes' import { asyncForEach, parseGeneratedCode, parseSourceCode } from '../utils' export type ExecuteFunction = () => Promise @@ -10,7 +11,8 @@ export interface JobExecutor { data: any, config: any, loginRequiredCallback?: any, - accessToken?: string + accessToken?: string, + extraResponseAttributes?: ExtraResponseAttributes[] ) => Promise resendWaitingRequests: () => Promise getRequests: () => SASjsRequest[] @@ -28,7 +30,8 @@ export abstract class BaseJobExecutor implements JobExecutor { data: any, config: any, loginRequiredCallback?: any, - accessToken?: string | undefined + accessToken?: string | undefined, + extraResponseAttributes?: ExtraResponseAttributes[] ): Promise resendWaitingRequests = async () => { diff --git a/src/types/ExtraResponseAttributes.ts b/src/types/ExtraResponseAttributes.ts new file mode 100644 index 0000000..1d9b837 --- /dev/null +++ b/src/types/ExtraResponseAttributes.ts @@ -0,0 +1,6 @@ +/** + * Represents a SASjs request parameter that will select which attributes are wanted in + * response object on top of default `webout` object. + * + */ +export type ExtraResponseAttributes = 'file' | 'data' | 'output' | null From d4357d939e9ff4ed822e1268acee264cb8f1de00 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 8 Jun 2021 16:54:46 +0200 Subject: [PATCH 2/5] test: extra attributes on JES --- sasjs-tests/package-lock.json | 68 +++++++++++++++++++++++++---- sasjs-tests/src/testSuites/Basic.ts | 16 +++++++ 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/sasjs-tests/package-lock.json b/sasjs-tests/package-lock.json index d198432..7b45515 100644 --- a/sasjs-tests/package-lock.json +++ b/sasjs-tests/package-lock.json @@ -2005,12 +2005,15 @@ }, "@sasjs/adapter": { "version": "file:../build/sasjs-adapter-5.0.0.tgz", - "integrity": "sha512-DxoQbdJqzqOTIuT7qwSfAbmNTWdpOx5zGkiMuZBSwoi9lSsRNoARiWnJq5Vl6h4RXJlc/FVdBFt35RZm4Mc0ZQ==", + "integrity": "sha512-1GSSoHt6MumQQ0Y080PA4PCHJ1vRpkx+Syi3Io6poQzOGrYM6Z4lQFilXsdoogPdcfgO5po9OX1dr7AM0hKugQ==", "requires": { - "@sasjs/utils": "^2.10.2", + "@sasjs/utils": "^2.17.1", "axios": "^0.21.1", + "axios-cookiejar-support": "^1.0.1", "form-data": "^4.0.0", - "https": "^1.0.0" + "https": "^1.0.0", + "tough-cookie": "^4.0.0", + "url": "^0.11.0" }, "dependencies": { "form-data": { @@ -2022,6 +2025,21 @@ "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -2046,14 +2064,15 @@ } }, "@sasjs/utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.12.1.tgz", - "integrity": "sha512-6gZS5zW0J70P7XaVuEczyfHVaVa8Ks/aWr4PIlpJcxWD0enJtCEmos2DdnezdSoNvODkPq/8rzMPqko5jaXK1Q==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.18.0.tgz", + "integrity": "sha512-6VTbRP1KU0gGi1mSIHl+XyL9Vqk8rBW7a7VQOF6vzD+AVgfgYd0t76djAUCcA7Dos8NJXAoDUuah+iNvXJY+cw==", "requires": { "@types/prompts": "^2.0.11", "chalk": "^4.1.1", "cli-table": "^0.3.6", "consola": "^2.15.0", + "fs-extra": "^10.0.0", "prompts": "^2.4.1", "valid-url": "^1.0.9" }, @@ -2088,6 +2107,16 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2422,9 +2451,9 @@ "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==" }, "@types/prompts": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.11.tgz", - "integrity": "sha512-dcF5L3rU9VfpLEJIV++FEyhGhuIpJllNEwllVuJ5g8eoVqjf048tW9+spivIwjzgPbtaGAl7mIZW3cmhDAq2UQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.12.tgz", + "integrity": "sha512-Hr6osqfNg3IcQT3pJDXCsSnb0KnldY/hXeJCKJriwbZLnedN9n1e8kcZwLc25GIWULDb6h5aEyOBbf33XpZBXQ==", "requires": { "@types/node": "*" } @@ -3467,6 +3496,22 @@ "follow-redirects": "^1.10.0" } }, + "axios-cookiejar-support": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-1.0.1.tgz", + "integrity": "sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==", + "requires": { + "is-redirect": "^1.0.0", + "pify": "^5.0.0" + }, + "dependencies": { + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" + } + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -8557,6 +8602,11 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, "is-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", diff --git a/sasjs-tests/src/testSuites/Basic.ts b/sasjs-tests/src/testSuites/Basic.ts index e1b5887..a352fdb 100644 --- a/sasjs-tests/src/testSuites/Basic.ts +++ b/sasjs-tests/src/testSuites/Basic.ts @@ -145,6 +145,22 @@ export const basicTests = ( sasjsConfig.debug === false ) } + }, + { + title: 'Request with extra attributes on JES approach', + description: + 'Should complete successful request with extra attributes present in response', + test: async () => { + const config = { + useComputeApi: false + } + + return await adapter.request('common/sendArr', stringData, config, undefined, undefined, ['output', 'file', 'data']) + }, + assertion: (response: any) => { + const responseKeys: any = Object.keys(response) + return responseKeys.includes('file') && responseKeys.includes('output') && responseKeys.includes('data') + } } ] }) From 89ff3232060a8c0ed85547e4f9dfc581d8aba379 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 8 Jun 2021 16:55:10 +0200 Subject: [PATCH 3/5] style: lint --- sasjs-tests/src/testSuites/Basic.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sasjs-tests/src/testSuites/Basic.ts b/sasjs-tests/src/testSuites/Basic.ts index a352fdb..457f1a2 100644 --- a/sasjs-tests/src/testSuites/Basic.ts +++ b/sasjs-tests/src/testSuites/Basic.ts @@ -155,11 +155,22 @@ export const basicTests = ( useComputeApi: false } - return await adapter.request('common/sendArr', stringData, config, undefined, undefined, ['output', 'file', 'data']) + return await adapter.request( + 'common/sendArr', + stringData, + config, + undefined, + undefined, + ['output', 'file', 'data'] + ) }, assertion: (response: any) => { const responseKeys: any = Object.keys(response) - return responseKeys.includes('file') && responseKeys.includes('output') && responseKeys.includes('data') + return ( + responseKeys.includes('file') && + responseKeys.includes('output') && + responseKeys.includes('data') + ) } } ] From dadce3d4c93de228718c57035abe2e9a2a80b89d Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Thu, 10 Jun 2021 14:22:31 +0200 Subject: [PATCH 4/5] chore: added extra attributes type from @sasjs/utils --- package-lock.json | 8 ++++---- package.json | 2 +- src/SASjs.ts | 2 +- src/job-execution/JesJobExecutor.ts | 2 +- src/job-execution/JobExecutor.ts | 2 +- src/types/ExtraResponseAttributes.ts | 6 ------ 6 files changed, 8 insertions(+), 14 deletions(-) delete mode 100644 src/types/ExtraResponseAttributes.ts diff --git a/package-lock.json b/package-lock.json index eecafd0..789b688 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1253,11 +1253,11 @@ } }, "@sasjs/utils": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.18.0.tgz", - "integrity": "sha512-6VTbRP1KU0gGi1mSIHl+XyL9Vqk8rBW7a7VQOF6vzD+AVgfgYd0t76djAUCcA7Dos8NJXAoDUuah+iNvXJY+cw==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.20.0.tgz", + "integrity": "sha512-PBJswfumyejsb8wJQpSZ96zFEEeJ+AlpxWXhz9uT9D8bNCStfCd75E1JdV71RwxdavsKiGMSSh5UcGDyehFA4w==", "requires": { - "@types/prompts": "^2.0.11", + "@types/prompts": "^2.0.13", "chalk": "^4.1.1", "cli-table": "^0.3.6", "consola": "^2.15.0", diff --git a/package.json b/package.json index c226a51..7dab86f 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "main": "index.js", "dependencies": { - "@sasjs/utils": "^2.18.0", + "@sasjs/utils": "^2.20.0", "axios": "^0.21.1", "axios-cookiejar-support": "^1.0.1", "form-data": "^4.0.0", diff --git a/src/SASjs.ts b/src/SASjs.ts index 013bf7f..3a3e555 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -14,7 +14,7 @@ import { Sas9JobExecutor } from './job-execution' import { ErrorResponse } from './types/errors' -import { ExtraResponseAttributes } from './types/ExtraResponseAttributes' +import { ExtraResponseAttributes } from '@sasjs/utils/types' const defaultConfig: SASjsConfig = { serverUrl: '', diff --git a/src/job-execution/JesJobExecutor.ts b/src/job-execution/JesJobExecutor.ts index b64006c..ce82083 100644 --- a/src/job-execution/JesJobExecutor.ts +++ b/src/job-execution/JesJobExecutor.ts @@ -5,7 +5,7 @@ import { JobExecutionError, LoginRequiredError } from '../types/errors' -import { ExtraResponseAttributes } from '../types/ExtraResponseAttributes' +import { ExtraResponseAttributes } from '@sasjs/utils/types' import { BaseJobExecutor } from './JobExecutor' export class JesJobExecutor extends BaseJobExecutor { diff --git a/src/job-execution/JobExecutor.ts b/src/job-execution/JobExecutor.ts index bc91a46..48b2dd9 100644 --- a/src/job-execution/JobExecutor.ts +++ b/src/job-execution/JobExecutor.ts @@ -1,6 +1,6 @@ import { ServerType } from '@sasjs/utils/types' import { SASjsRequest } from '../types' -import { ExtraResponseAttributes } from '../types/ExtraResponseAttributes' +import { ExtraResponseAttributes } from '@sasjs/utils/types' import { asyncForEach, parseGeneratedCode, parseSourceCode } from '../utils' export type ExecuteFunction = () => Promise diff --git a/src/types/ExtraResponseAttributes.ts b/src/types/ExtraResponseAttributes.ts deleted file mode 100644 index 1d9b837..0000000 --- a/src/types/ExtraResponseAttributes.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Represents a SASjs request parameter that will select which attributes are wanted in - * response object on top of default `webout` object. - * - */ -export type ExtraResponseAttributes = 'file' | 'data' | 'output' | null From 33d4ee92a72d2369781558f1464dcc1b84a94afc Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Thu, 10 Jun 2021 15:03:51 +0200 Subject: [PATCH 5/5] chore: updated utils and comment --- package-lock.json | 6 +++--- package.json | 2 +- src/SASjs.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 789b688..6153904 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1253,9 +1253,9 @@ } }, "@sasjs/utils": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.20.0.tgz", - "integrity": "sha512-PBJswfumyejsb8wJQpSZ96zFEEeJ+AlpxWXhz9uT9D8bNCStfCd75E1JdV71RwxdavsKiGMSSh5UcGDyehFA4w==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.20.1.tgz", + "integrity": "sha512-Wer6RrGPowBgvgJ2Hdk2nrdA9mIsG4AKI50s/cEWKfzMnQRQVrCNmVUyZlM5I8/pZRzsMzwq7PLaxjAADYUCuQ==", "requires": { "@types/prompts": "^2.0.13", "chalk": "^4.1.1", diff --git a/package.json b/package.json index 7dab86f..e4eba45 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "main": "index.js", "dependencies": { - "@sasjs/utils": "^2.20.0", + "@sasjs/utils": "^2.20.1", "axios": "^0.21.1", "axios-cookiejar-support": "^1.0.1", "form-data": "^4.0.0", diff --git a/src/SASjs.ts b/src/SASjs.ts index 3a3e555..0af290e 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -543,7 +543,7 @@ export default class SASjs { * `await request(sasJobPath, {}, {}, () => setIsLoggedIn(false))` * @param extraResponseAttributes - a array of predefined values that are used * to provide extra attributes (same names as those values) to be added in response - * Supported values: 'file' | 'output' | 'data' + * Supported values are declared in ExtraResponseAttributes type. */ public async request( sasJob: string,