From caa5aa47dc577c877536a102f9ec2b92d1b5a244 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Mon, 18 Apr 2022 14:49:57 +0200 Subject: [PATCH 01/10] fix: isSpecialMissing from utils --- src/utils/convertToCsv.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/utils/convertToCsv.ts b/src/utils/convertToCsv.ts index bab7788..46007dd 100644 --- a/src/utils/convertToCsv.ts +++ b/src/utils/convertToCsv.ts @@ -1,3 +1,5 @@ +import { isSpecialMissing } from '@sasjs/utils' + /** * Converts the given JSON object array to a CSV string. * @param data - the array of JSON objects to convert. @@ -18,7 +20,6 @@ export const convertToCSV = ( let headers: string[] = [] let csvTest let invalidString = false - const specialMissingValueRegExp = /^[a-z_]{1}$/i if (formats) { headers = Object.keys(formats).map((key) => `${key}:${formats![key]}`) @@ -36,7 +37,7 @@ export const convertToCSV = ( hasNullOrNumber = true } else if ( typeof row[field] === 'string' && - specialMissingValueRegExp.test(row[field]) + isSpecialMissing(row[field]) ) { hasSpecialMissingString = true } @@ -130,10 +131,10 @@ export const convertToCSV = ( value = currentCell === null ? '' : currentCell if (formats && formats[fieldName] === 'best.') { - if (value && !specialMissingValueRegExp.test(value)) { + if (value && !isSpecialMissing(value)) { console.log(`🤖[value]🤖`, value) throw new Error( - 'Special missing value can only be a single character from A to Z or _' + 'A Special missing value can only be a single character from A to Z or _ or .[a-z] or ._' ) } From 9bf38858686fd567dff405288958b0897340f222 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Mon, 18 Apr 2022 14:54:50 +0200 Subject: [PATCH 02/10] chore: test fix --- src/test/utils/formatDataForRequest.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/utils/formatDataForRequest.spec.ts b/src/test/utils/formatDataForRequest.spec.ts index 9a74998..a311c60 100644 --- a/src/test/utils/formatDataForRequest.spec.ts +++ b/src/test/utils/formatDataForRequest.spec.ts @@ -62,7 +62,7 @@ describe('formatDataForRequest', () => { expect(() => formatDataForRequest(tableWithMissingValues)).toThrow( new Error( - 'Special missing value can only be a single character from A to Z or _' + 'A Special missing value can only be a single character from A to Z or _ or .[a-z] or ._' ) ) }) From ecec2e77c067b5d86cff454fd871317bf53136d1 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Thu, 21 Apr 2022 15:45:59 +0200 Subject: [PATCH 03/10] chore: error improved --- src/test/utils/formatDataForRequest.spec.ts | 2 +- src/utils/convertToCsv.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/utils/formatDataForRequest.spec.ts b/src/test/utils/formatDataForRequest.spec.ts index a311c60..3303a2b 100644 --- a/src/test/utils/formatDataForRequest.spec.ts +++ b/src/test/utils/formatDataForRequest.spec.ts @@ -62,7 +62,7 @@ describe('formatDataForRequest', () => { expect(() => formatDataForRequest(tableWithMissingValues)).toThrow( new Error( - 'A Special missing value can only be a single character from A to Z or _ or .[a-z] or ._' + 'A Special missing value can only be a single character from \'A\' to \'Z\', \'_\', \'.[a-z]\', \'._\'' ) ) }) diff --git a/src/utils/convertToCsv.ts b/src/utils/convertToCsv.ts index 46007dd..fb32cad 100644 --- a/src/utils/convertToCsv.ts +++ b/src/utils/convertToCsv.ts @@ -134,7 +134,7 @@ export const convertToCSV = ( if (value && !isSpecialMissing(value)) { console.log(`🤖[value]🤖`, value) throw new Error( - 'A Special missing value can only be a single character from A to Z or _ or .[a-z] or ._' + 'A Special missing value can only be a single character from \'A\' to \'Z\', \'_\', \'.[a-z]\', \'._\'' ) } From 54516665bf28213f10f8502bf188e8490ebbf8f4 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Fri, 22 Apr 2022 11:54:59 +0200 Subject: [PATCH 04/10] chore: string escaping --- src/test/utils/formatDataForRequest.spec.ts | 2 +- src/utils/convertToCsv.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/utils/formatDataForRequest.spec.ts b/src/test/utils/formatDataForRequest.spec.ts index 3303a2b..eee87a4 100644 --- a/src/test/utils/formatDataForRequest.spec.ts +++ b/src/test/utils/formatDataForRequest.spec.ts @@ -62,7 +62,7 @@ describe('formatDataForRequest', () => { expect(() => formatDataForRequest(tableWithMissingValues)).toThrow( new Error( - 'A Special missing value can only be a single character from \'A\' to \'Z\', \'_\', \'.[a-z]\', \'._\'' + `A Special missing value can only be a single character from 'A' to 'Z', '_', '.[a-z]', '._'` ) ) }) diff --git a/src/utils/convertToCsv.ts b/src/utils/convertToCsv.ts index fb32cad..c792375 100644 --- a/src/utils/convertToCsv.ts +++ b/src/utils/convertToCsv.ts @@ -134,7 +134,7 @@ export const convertToCSV = ( if (value && !isSpecialMissing(value)) { console.log(`🤖[value]🤖`, value) throw new Error( - 'A Special missing value can only be a single character from \'A\' to \'Z\', \'_\', \'.[a-z]\', \'._\'' + `A Special missing value can only be a single character from 'A' to 'Z', '_', '.[a-z]', '._'` ) } From c00c8007e54abb23248cf8b761b1d6c68f52d593 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 26 Apr 2022 12:27:55 +0200 Subject: [PATCH 05/10] chore: utils update --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f51088d..255a302 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "hasInstallScript": true, "license": "ISC", "dependencies": { - "@sasjs/utils": "2.42.0", + "@sasjs/utils": "2.44.0", "axios": "0.26.0", "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", @@ -1142,9 +1142,9 @@ } }, "node_modules/@sasjs/utils": { - "version": "2.42.0", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.42.0.tgz", - "integrity": "sha512-Y69l89PYNF/h9xvVH72om/39xA+cY80bhiVLzp/fJb3BlvzCf4RNswBBanUOv2I5JNa7gPpJuE7mEiXOlhD3eg==", + "version": "2.44.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.44.0.tgz", + "integrity": "sha512-hpC4erHYA8Mcb38mzxFEP0cXehfa0iKeqSW2d9MmxZ9g2qpy0BU6xyZJohN9kOiafXo5H359ndNKsg4DOq5YgA==", "hasInstallScript": true, "dependencies": { "@types/fs-extra": "9.0.13", @@ -13870,9 +13870,9 @@ } }, "@sasjs/utils": { - "version": "2.42.0", - "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.42.0.tgz", - "integrity": "sha512-Y69l89PYNF/h9xvVH72om/39xA+cY80bhiVLzp/fJb3BlvzCf4RNswBBanUOv2I5JNa7gPpJuE7mEiXOlhD3eg==", + "version": "2.44.0", + "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.44.0.tgz", + "integrity": "sha512-hpC4erHYA8Mcb38mzxFEP0cXehfa0iKeqSW2d9MmxZ9g2qpy0BU6xyZJohN9kOiafXo5H359ndNKsg4DOq5YgA==", "requires": { "@types/fs-extra": "9.0.13", "@types/prompts": "2.0.13", diff --git a/package.json b/package.json index e2e4dc5..2be4b9a 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ }, "main": "index.js", "dependencies": { - "@sasjs/utils": "2.42.0", + "@sasjs/utils": "2.44.0", "axios": "0.26.0", "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", From 936e4f8c0a11413102401d86f3323ad5bc3fd2ab Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 26 Apr 2022 16:18:36 +0200 Subject: [PATCH 06/10] fix: sasjs server type - request and job execution auth fix --- src/SASjs.ts | 4 +-- src/SASjsApiClient.ts | 6 ++-- src/job-execution/WebJobExecutor.ts | 48 ++++++++++++++++++----------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/SASjs.ts b/src/SASjs.ts index ac83240..f554947 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -916,8 +916,8 @@ export default class SASjs { return await this.sasJSApiClient?.deploy(dataJson, appLoc, authConfig) } - public async executeJobSASjs(query: ExecutionQuery) { - return await this.sasJSApiClient?.executeJob(query) + public async executeJobSASjs(query: ExecutionQuery, authConfig?: AuthConfig) { + return await this.sasJSApiClient?.executeJob(query, authConfig) } /** diff --git a/src/SASjsApiClient.ts b/src/SASjsApiClient.ts index b152f5d..af17911 100644 --- a/src/SASjsApiClient.ts +++ b/src/SASjsApiClient.ts @@ -43,7 +43,9 @@ export class SASjsApiClient { return Promise.resolve(result) } - public async executeJob(query: ExecutionQuery) { + public async executeJob(query: ExecutionQuery, authConfig?: AuthConfig) { + const access_token = authConfig ? authConfig.access_token : undefined + const { result } = await this.requestClient.post<{ status: string message: string @@ -51,7 +53,7 @@ export class SASjsApiClient { logPath?: string error?: {} _webout?: string - }>('SASjsApi/stp/execute', query, undefined) + }>('SASjsApi/stp/execute', query, access_token) if (Object.keys(result).includes('_webout')) { result._webout = parseWeboutResponse(result._webout!) diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index f3c3031..187bc9c 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -21,6 +21,7 @@ import { } from '../utils' import { BaseJobExecutor } from './JobExecutor' import { parseWeboutResponse } from '../utils/parseWeboutResponse' +import { Server } from 'https' export interface WaitingRequstPromise { promise: Promise | null @@ -220,25 +221,36 @@ export class WebJobExecutor extends BaseJobExecutor { } if (e instanceof LoginRequiredError) { - this.appendWaitingRequest(() => { - return this.execute( - sasJob, - data, - config, - loginRequiredCallback, - authConfig, - extraResponseAttributes - ).then( - (res: any) => { - resolve(res) - }, - (err: any) => { - reject(err) - } - ) - }) + switch (this.serverType) { + case ServerType.Sasjs: + reject( + new ErrorResponse( + 'Request is not authenticated. Make sure .env file exists with valid credentials.', + e + ) + ) + break + default: + this.appendWaitingRequest(() => { + return this.execute( + sasJob, + data, + config, + loginRequiredCallback, + authConfig, + extraResponseAttributes + ).then( + (res: any) => { + resolve(res) + }, + (err: any) => { + reject(err) + } + ) + }) - await loginCallback() + await loginCallback() + } } else { reject(new ErrorResponse(e?.message, e)) } From 1cbe57d51261395a093f9bbb62d68f392ff4ac20 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Tue, 26 Apr 2022 17:25:21 +0300 Subject: [PATCH 07/10] chore: removed console.log --- src/utils/convertToCsv.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/convertToCsv.ts b/src/utils/convertToCsv.ts index c792375..2211cd8 100644 --- a/src/utils/convertToCsv.ts +++ b/src/utils/convertToCsv.ts @@ -132,7 +132,6 @@ export const convertToCSV = ( if (formats && formats[fieldName] === 'best.') { if (value && !isSpecialMissing(value)) { - console.log(`🤖[value]🤖`, value) throw new Error( `A Special missing value can only be a single character from 'A' to 'Z', '_', '.[a-z]', '._'` ) From fc47222830ed96c5ffff72725e734b38974dfbb7 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 26 Apr 2022 17:37:13 +0200 Subject: [PATCH 08/10] fix: web request method - login callback handling --- src/job-execution/WebJobExecutor.ts | 58 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index 187bc9c..62e2431 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -47,7 +47,7 @@ export class WebJobExecutor extends BaseJobExecutor { authConfig?: AuthConfig, extraResponseAttributes: ExtraResponseAttributes[] = [] ) { - const loginCallback = loginRequiredCallback || (() => Promise.resolve()) + const loginCallback = loginRequiredCallback const program = isRelativePath(sasJob) ? config.appLoc ? config.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '') @@ -80,7 +80,7 @@ export class WebJobExecutor extends BaseJobExecutor { ) }) - await loginCallback() + if (loginCallback) await loginCallback() } else { reject(new ErrorResponse(e?.message, e)) } @@ -221,36 +221,34 @@ export class WebJobExecutor extends BaseJobExecutor { } if (e instanceof LoginRequiredError) { - switch (this.serverType) { - case ServerType.Sasjs: - reject( - new ErrorResponse( - 'Request is not authenticated. Make sure .env file exists with valid credentials.', - e - ) + if (!loginRequiredCallback) { + reject( + new ErrorResponse( + 'Request is not authenticated. Make sure .env file exists with valid credentials.', + e ) - break - default: - this.appendWaitingRequest(() => { - return this.execute( - sasJob, - data, - config, - loginRequiredCallback, - authConfig, - extraResponseAttributes - ).then( - (res: any) => { - resolve(res) - }, - (err: any) => { - reject(err) - } - ) - }) - - await loginCallback() + ) } + + this.appendWaitingRequest(() => { + return this.execute( + sasJob, + data, + config, + loginRequiredCallback, + authConfig, + extraResponseAttributes + ).then( + (res: any) => { + resolve(res) + }, + (err: any) => { + reject(err) + } + ) + }) + + if (loginCallback) await loginCallback() } else { reject(new ErrorResponse(e?.message, e)) } From fdc3e1cce8948de2a5bd464084f6984c1d3ae5e2 Mon Sep 17 00:00:00 2001 From: Mihajlo Date: Tue, 26 Apr 2022 17:41:35 +0200 Subject: [PATCH 09/10] style: lint --- src/job-execution/WebJobExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index 62e2431..a4bdbe8 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -229,7 +229,7 @@ export class WebJobExecutor extends BaseJobExecutor { ) ) } - + this.appendWaitingRequest(() => { return this.execute( sasJob, From 72ed5e3fab79bb76f78367e2c0a058fbf4b7d65e Mon Sep 17 00:00:00 2001 From: Allan Bowe <4420615+allanbowe@users.noreply.github.com> Date: Thu, 28 Apr 2022 11:11:46 +0100 Subject: [PATCH 10/10] chore: update test suite README with lrecl option --- sasjs-tests/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sasjs-tests/README.md b/sasjs-tests/README.md index a400a1e..a475b56 100644 --- a/sasjs-tests/README.md +++ b/sasjs-tests/README.md @@ -65,7 +65,7 @@ The below services need to be created on your SAS server, at the location specif ```sas filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; %inc mc; -filename ft15f001 temp; +filename ft15f001 temp lrecl=1000; parmcards4; %webout(FETCH) %webout(OPEN) @@ -113,7 +113,7 @@ data _null_; ```sas filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas"; %inc mc; -filename ft15f001 temp; +filename ft15f001 temp lrecl=1000; parmcards4; %webout(FETCH) %webout(OPEN)