@sasjs/adapter 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SASjs.d.ts +2 -1
- package/index-dev.js +2 -2
- package/index.js +1 -1
- package/minified_sas9.js +1 -1
- package/node/SASjs.d.ts +2 -1
- package/node/index.js +1 -1
- package/node/request/RequestClient.d.ts +24 -0
- package/package.json +1 -1
- package/request/RequestClient.d.ts +24 -0
- package/src/SASjs.ts +6 -1
- package/src/request/RequestClient.ts +103 -0
|
@@ -36,6 +36,7 @@ export declare class RequestClient implements HttpClient {
|
|
|
36
36
|
protected baseUrl: string;
|
|
37
37
|
private requests;
|
|
38
38
|
private requestsLimit;
|
|
39
|
+
private httpInterceptor?;
|
|
39
40
|
protected csrfToken: CsrfToken;
|
|
40
41
|
protected fileUploadCsrfToken: CsrfToken | undefined;
|
|
41
42
|
protected httpClient: AxiosInstance;
|
|
@@ -93,6 +94,29 @@ export declare class RequestClient implements HttpClient {
|
|
|
93
94
|
}>;
|
|
94
95
|
uploadFile(url: string, content: string, accessToken?: string): Promise<any>;
|
|
95
96
|
authorize: (response: string) => Promise<any>;
|
|
97
|
+
/**
|
|
98
|
+
* Adds colors to the string.
|
|
99
|
+
* @param str - string to be prettified.
|
|
100
|
+
* @returns - prettified string
|
|
101
|
+
*/
|
|
102
|
+
private prettifyString;
|
|
103
|
+
/**
|
|
104
|
+
* Formats HTTP request/response body.
|
|
105
|
+
* @param body - HTTP request/response body.
|
|
106
|
+
* @returns - formatted string.
|
|
107
|
+
*/
|
|
108
|
+
private parseInterceptedBody;
|
|
109
|
+
private defaultInterceptionCallBack;
|
|
110
|
+
/**
|
|
111
|
+
* Turns on verbose mode to log every HTTP response.
|
|
112
|
+
* @param successCallBack - function that should be triggered on every HTTP response with the status 2**.
|
|
113
|
+
* @param errorCallBack - function that should be triggered on every HTTP response with the status different from 2**.
|
|
114
|
+
*/
|
|
115
|
+
enableVerboseMode: (successCallBack?: (response: AxiosResponse) => AxiosResponse<any, any>, errorCallBack?: (response: AxiosResponse) => AxiosResponse<any, any>) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Turns off verbose mode to log every HTTP response.
|
|
118
|
+
*/
|
|
119
|
+
disableVerboseMode: () => void;
|
|
96
120
|
protected getHeaders: (accessToken: string | undefined, contentType: string) => any;
|
|
97
121
|
protected parseAndSetFileUploadCsrfToken: (response: AxiosResponse) => void;
|
|
98
122
|
protected parseAndSetCsrfToken: (response: AxiosResponse) => void;
|
package/package.json
CHANGED
|
@@ -36,6 +36,7 @@ export declare class RequestClient implements HttpClient {
|
|
|
36
36
|
protected baseUrl: string;
|
|
37
37
|
private requests;
|
|
38
38
|
private requestsLimit;
|
|
39
|
+
private httpInterceptor?;
|
|
39
40
|
protected csrfToken: CsrfToken;
|
|
40
41
|
protected fileUploadCsrfToken: CsrfToken | undefined;
|
|
41
42
|
protected httpClient: AxiosInstance;
|
|
@@ -93,6 +94,29 @@ export declare class RequestClient implements HttpClient {
|
|
|
93
94
|
}>;
|
|
94
95
|
uploadFile(url: string, content: string, accessToken?: string): Promise<any>;
|
|
95
96
|
authorize: (response: string) => Promise<any>;
|
|
97
|
+
/**
|
|
98
|
+
* Adds colors to the string.
|
|
99
|
+
* @param str - string to be prettified.
|
|
100
|
+
* @returns - prettified string
|
|
101
|
+
*/
|
|
102
|
+
private prettifyString;
|
|
103
|
+
/**
|
|
104
|
+
* Formats HTTP request/response body.
|
|
105
|
+
* @param body - HTTP request/response body.
|
|
106
|
+
* @returns - formatted string.
|
|
107
|
+
*/
|
|
108
|
+
private parseInterceptedBody;
|
|
109
|
+
private defaultInterceptionCallBack;
|
|
110
|
+
/**
|
|
111
|
+
* Turns on verbose mode to log every HTTP response.
|
|
112
|
+
* @param successCallBack - function that should be triggered on every HTTP response with the status 2**.
|
|
113
|
+
* @param errorCallBack - function that should be triggered on every HTTP response with the status different from 2**.
|
|
114
|
+
*/
|
|
115
|
+
enableVerboseMode: (successCallBack?: (response: AxiosResponse) => AxiosResponse<any, any>, errorCallBack?: (response: AxiosResponse) => AxiosResponse<any, any>) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Turns off verbose mode to log every HTTP response.
|
|
118
|
+
*/
|
|
119
|
+
disableVerboseMode: () => void;
|
|
96
120
|
protected getHeaders: (accessToken: string | undefined, contentType: string) => any;
|
|
97
121
|
protected parseAndSetFileUploadCsrfToken: (response: AxiosResponse) => void;
|
|
98
122
|
protected parseAndSetCsrfToken: (response: AxiosResponse) => void;
|
package/src/SASjs.ts
CHANGED
|
@@ -854,6 +854,7 @@ export default class SASjs {
|
|
|
854
854
|
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { maxPollCount: 24 * 60 * 60, pollInterval: 1000 }. More information available at src/api/viya/pollJobState.ts.
|
|
855
855
|
* @param printPid - a boolean that indicates whether the function should print (PID) of the started job.
|
|
856
856
|
* @param variables - an object that represents macro variables.
|
|
857
|
+
* @param verboseMode - boolean to enable verbose mode (log every HTTP response).
|
|
857
858
|
*/
|
|
858
859
|
public async startComputeJob(
|
|
859
860
|
sasJob: string,
|
|
@@ -863,7 +864,8 @@ export default class SASjs {
|
|
|
863
864
|
waitForResult?: boolean,
|
|
864
865
|
pollOptions?: PollOptions,
|
|
865
866
|
printPid = false,
|
|
866
|
-
variables?: MacroVar
|
|
867
|
+
variables?: MacroVar,
|
|
868
|
+
verboseMode?: boolean
|
|
867
869
|
) {
|
|
868
870
|
config = {
|
|
869
871
|
...this.sasjsConfig,
|
|
@@ -877,6 +879,9 @@ export default class SASjs {
|
|
|
877
879
|
)
|
|
878
880
|
}
|
|
879
881
|
|
|
882
|
+
if (verboseMode) this.requestClient?.enableVerboseMode()
|
|
883
|
+
else this.requestClient?.disableVerboseMode()
|
|
884
|
+
|
|
880
885
|
return this.sasViyaApiClient?.executeComputeJob(
|
|
881
886
|
sasJob,
|
|
882
887
|
config.contextName,
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
createAxiosInstance
|
|
21
21
|
} from '../utils'
|
|
22
22
|
import { InvalidSASjsCsrfError } from '../types/errors/InvalidSASjsCsrfError'
|
|
23
|
+
import { inspect } from 'util'
|
|
23
24
|
|
|
24
25
|
export interface HttpClient {
|
|
25
26
|
get<T>(
|
|
@@ -59,6 +60,7 @@ export interface HttpClient {
|
|
|
59
60
|
export class RequestClient implements HttpClient {
|
|
60
61
|
private requests: SASjsRequest[] = []
|
|
61
62
|
private requestsLimit: number = 10
|
|
63
|
+
private httpInterceptor?: number
|
|
62
64
|
|
|
63
65
|
protected csrfToken: CsrfToken = { headerName: '', value: '' }
|
|
64
66
|
protected fileUploadCsrfToken: CsrfToken | undefined
|
|
@@ -70,6 +72,7 @@ export class RequestClient implements HttpClient {
|
|
|
70
72
|
requestsLimit?: number
|
|
71
73
|
) {
|
|
72
74
|
this.createHttpClient(baseUrl, httpsAgentOptions)
|
|
75
|
+
|
|
73
76
|
if (requestsLimit) this.requestsLimit = requestsLimit
|
|
74
77
|
}
|
|
75
78
|
|
|
@@ -180,6 +183,7 @@ export class RequestClient implements HttpClient {
|
|
|
180
183
|
responseType: contentType === 'text/plain' ? 'text' : 'json',
|
|
181
184
|
withCredentials: true
|
|
182
185
|
}
|
|
186
|
+
|
|
183
187
|
if (contentType === 'text/plain') {
|
|
184
188
|
requestConfig.transformResponse = undefined
|
|
185
189
|
}
|
|
@@ -389,6 +393,105 @@ export class RequestClient implements HttpClient {
|
|
|
389
393
|
})
|
|
390
394
|
}
|
|
391
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Adds colors to the string.
|
|
398
|
+
* @param str - string to be prettified.
|
|
399
|
+
* @returns - prettified string
|
|
400
|
+
*/
|
|
401
|
+
private prettifyString = (str: any) => inspect(str, { colors: true })
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Formats HTTP request/response body.
|
|
405
|
+
* @param body - HTTP request/response body.
|
|
406
|
+
* @returns - formatted string.
|
|
407
|
+
*/
|
|
408
|
+
private parseInterceptedBody = (body: any) => {
|
|
409
|
+
if (!body) return ''
|
|
410
|
+
|
|
411
|
+
let parsedBody
|
|
412
|
+
|
|
413
|
+
// Tries to parse body into JSON object.
|
|
414
|
+
if (typeof body === 'string') {
|
|
415
|
+
try {
|
|
416
|
+
parsedBody = JSON.parse(body)
|
|
417
|
+
} catch (error) {
|
|
418
|
+
parsedBody = body
|
|
419
|
+
}
|
|
420
|
+
} else {
|
|
421
|
+
parsedBody = body
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const bodyLines = this.prettifyString(parsedBody).split('\n')
|
|
425
|
+
|
|
426
|
+
// Leaves first 50 lines
|
|
427
|
+
if (bodyLines.length > 51) {
|
|
428
|
+
bodyLines.splice(50)
|
|
429
|
+
bodyLines.push('...')
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return bodyLines.join('\n')
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
private defaultInterceptionCallBack = (response: AxiosResponse) => {
|
|
436
|
+
const { status, config, request, data: resData } = response
|
|
437
|
+
const { data: reqData } = config
|
|
438
|
+
const { _header: reqHeaders, res } = request
|
|
439
|
+
const { rawHeaders } = res
|
|
440
|
+
|
|
441
|
+
// Converts an array of strings into a single string with the following format:
|
|
442
|
+
// <headerName>: <headerValue>
|
|
443
|
+
const resHeaders = rawHeaders.reduce(
|
|
444
|
+
(acc: string, value: string, i: number) => {
|
|
445
|
+
if (i % 2 === 0) {
|
|
446
|
+
acc += `${i === 0 ? '' : '\n'}${value}`
|
|
447
|
+
} else {
|
|
448
|
+
acc += `: ${value}`
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return acc
|
|
452
|
+
},
|
|
453
|
+
''
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
const parsedResBody = this.parseInterceptedBody(resData)
|
|
457
|
+
|
|
458
|
+
// HTTP response summary.
|
|
459
|
+
process.logger?.info(`HTTP Request (first 50 lines):
|
|
460
|
+
${reqHeaders}${this.parseInterceptedBody(reqData)}
|
|
461
|
+
|
|
462
|
+
HTTP Response Code: ${this.prettifyString(status)}
|
|
463
|
+
|
|
464
|
+
HTTP Response (first 50 lines):
|
|
465
|
+
${resHeaders}${parsedResBody ? `\n\n${parsedResBody}` : ''}
|
|
466
|
+
`)
|
|
467
|
+
|
|
468
|
+
return response
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Turns on verbose mode to log every HTTP response.
|
|
473
|
+
* @param successCallBack - function that should be triggered on every HTTP response with the status 2**.
|
|
474
|
+
* @param errorCallBack - function that should be triggered on every HTTP response with the status different from 2**.
|
|
475
|
+
*/
|
|
476
|
+
public enableVerboseMode = (
|
|
477
|
+
successCallBack = this.defaultInterceptionCallBack,
|
|
478
|
+
errorCallBack = this.defaultInterceptionCallBack
|
|
479
|
+
) => {
|
|
480
|
+
this.httpInterceptor = this.httpClient.interceptors.response.use(
|
|
481
|
+
successCallBack,
|
|
482
|
+
errorCallBack
|
|
483
|
+
)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Turns off verbose mode to log every HTTP response.
|
|
488
|
+
*/
|
|
489
|
+
public disableVerboseMode = () => {
|
|
490
|
+
if (this.httpInterceptor) {
|
|
491
|
+
this.httpClient.interceptors.response.eject(this.httpInterceptor)
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
392
495
|
protected getHeaders = (
|
|
393
496
|
accessToken: string | undefined,
|
|
394
497
|
contentType: string
|