@sasjs/adapter 3.10.11 → 3.10.14

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.
Files changed (36) hide show
  1. package/README.md +2 -1
  2. package/SASjs.d.ts +2 -1
  3. package/SASjsApiClient.d.ts +2 -1
  4. package/index.js +2 -2
  5. package/job-execution/JobExecutor.d.ts +1 -0
  6. package/job-execution/Sas9JobExecutor.d.ts +1 -1
  7. package/job-execution/SasjsJobExecutor.d.ts +9 -0
  8. package/job-execution/WebJobExecutor.d.ts +0 -2
  9. package/job-execution/index.d.ts +1 -0
  10. package/node/SASjs.d.ts +2 -1
  11. package/node/SASjsApiClient.d.ts +2 -1
  12. package/node/index.js +2 -2
  13. package/node/job-execution/JobExecutor.d.ts +1 -0
  14. package/node/job-execution/Sas9JobExecutor.d.ts +1 -1
  15. package/node/job-execution/SasjsJobExecutor.d.ts +9 -0
  16. package/node/job-execution/WebJobExecutor.d.ts +0 -2
  17. package/node/job-execution/index.d.ts +1 -0
  18. package/node/request/SasjsRequestClient.d.ts +7 -0
  19. package/node/utils/constants.d.ts +1 -0
  20. package/node/utils/index.d.ts +1 -0
  21. package/package.json +1 -1
  22. package/request/SasjsRequestClient.d.ts +7 -0
  23. package/src/SASjs.ts +15 -3
  24. package/src/SASjsApiClient.ts +9 -8
  25. package/src/job-execution/FileUploader.ts +3 -15
  26. package/src/job-execution/JobExecutor.ts +14 -1
  27. package/src/job-execution/Sas9JobExecutor.ts +1 -1
  28. package/src/job-execution/SasjsJobExecutor.ts +141 -0
  29. package/src/job-execution/WebJobExecutor.ts +4 -78
  30. package/src/job-execution/index.ts +1 -0
  31. package/src/request/RequestClient.ts +5 -21
  32. package/src/request/SasjsRequestClient.ts +31 -0
  33. package/src/utils/constants.ts +2 -0
  34. package/src/utils/index.ts +1 -0
  35. package/utils/constants.d.ts +1 -0
  36. package/utils/index.d.ts +1 -0
@@ -13,4 +13,5 @@ export declare abstract class BaseJobExecutor implements JobExecutor {
13
13
  abstract execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig | undefined, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<any>;
14
14
  resendWaitingRequests: () => Promise<void>;
15
15
  protected appendWaitingRequest(request: ExecuteFunction): void;
16
+ protected getRequestParams(config: any): any;
16
17
  }
@@ -15,5 +15,5 @@ export declare class Sas9JobExecutor extends BaseJobExecutor {
15
15
  private sas9RequestClient;
16
16
  constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient, httpsAgentOptions?: https.AgentOptions);
17
17
  execute(sasJob: string, data: any, config: any): Promise<unknown>;
18
- private getRequestParams;
18
+ protected getRequestParams(config: any): any;
19
19
  }
@@ -0,0 +1,9 @@
1
+ import { AuthConfig, ExtraResponseAttributes } from '@sasjs/utils/types';
2
+ import { RequestClient } from '../request/RequestClient';
3
+ import { BaseJobExecutor } from './JobExecutor';
4
+ export declare class SasjsJobExecutor extends BaseJobExecutor {
5
+ private jobsPath;
6
+ private requestClient;
7
+ constructor(serverUrl: string, jobsPath: string, requestClient: RequestClient);
8
+ execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<unknown>;
9
+ }
@@ -14,6 +14,4 @@ export declare class WebJobExecutor extends BaseJobExecutor {
14
14
  constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient, sasViyaApiClient: SASViyaApiClient);
15
15
  execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<unknown>;
16
16
  private getJobUri;
17
- private getRequestParams;
18
- private parseSAS9ErrorResponse;
19
17
  }
@@ -4,3 +4,4 @@ export * from './JesJobExecutor';
4
4
  export * from './JobExecutor';
5
5
  export * from './Sas9JobExecutor';
6
6
  export * from './WebJobExecutor';
7
+ export * from './SasjsJobExecutor';
@@ -1,8 +1,15 @@
1
1
  import { RequestClient } from './RequestClient';
2
+ import { AxiosResponse } from 'axios';
2
3
  /**
3
4
  * Specific request client for SASJS.
4
5
  * Append tokens in headers.
5
6
  */
6
7
  export declare class SasjsRequestClient extends RequestClient {
7
8
  getHeaders: (accessToken: string | undefined, contentType: string) => any;
9
+ protected parseResponse<T>(response: AxiosResponse<any>): {
10
+ result: T;
11
+ log: any;
12
+ etag: string;
13
+ status: number;
14
+ };
8
15
  }
@@ -0,0 +1 @@
1
+ export declare const SASJS_LOGS_SEPARATOR = "SASJS_LOGS_SEPARATOR_163ee17b6ff24f028928972d80a26784";
@@ -2,6 +2,7 @@ export * from './appendExtraResponseAttributes';
2
2
  export * from './asyncForEach';
3
3
  export * from './compareTimestamps';
4
4
  export * from './convertToCsv';
5
+ export * from './constants';
5
6
  export * from './createAxiosInstance';
6
7
  export * from './delay';
7
8
  export * from './fetchLogByChunks';
package/package.json CHANGED
@@ -87,5 +87,5 @@
87
87
  "https": "1.0.0",
88
88
  "tough-cookie": "4.0.0"
89
89
  },
90
- "version": "3.10.11"
90
+ "version": "3.10.14"
91
91
  }
@@ -1,8 +1,15 @@
1
1
  import { RequestClient } from './RequestClient';
2
+ import { AxiosResponse } from 'axios';
2
3
  /**
3
4
  * Specific request client for SASJS.
4
5
  * Append tokens in headers.
5
6
  */
6
7
  export declare class SasjsRequestClient extends RequestClient {
7
8
  getHeaders: (accessToken: string | undefined, contentType: string) => any;
9
+ protected parseResponse<T>(response: AxiosResponse<any>): {
10
+ result: T;
11
+ log: any;
12
+ etag: string;
13
+ status: number;
14
+ };
8
15
  }
package/src/SASjs.ts CHANGED
@@ -24,6 +24,7 @@ import { SasjsRequestClient } from './request/SasjsRequestClient'
24
24
  import {
25
25
  JobExecutor,
26
26
  WebJobExecutor,
27
+ SasjsJobExecutor,
27
28
  ComputeJobExecutor,
28
29
  JesJobExecutor,
29
30
  Sas9JobExecutor,
@@ -59,6 +60,7 @@ export default class SASjs {
59
60
  private authManager: AuthManager | null = null
60
61
  private requestClient: RequestClient | null = null
61
62
  private webJobExecutor: JobExecutor | null = null
63
+ private sasjsJobExecutor: JobExecutor | null = null
62
64
  private computeJobExecutor: JobExecutor | null = null
63
65
  private jesJobExecutor: JobExecutor | null = null
64
66
  private sas9JobExecutor: JobExecutor | null = null
@@ -102,10 +104,14 @@ export default class SASjs {
102
104
  * @param code - a string of code from the file to run.
103
105
  * @param authConfig - (optional) a valid client, secret, refresh and access tokens that are authorised to execute scripts.
104
106
  */
105
- public async executeScriptSASjs(code: string, authConfig?: AuthConfig) {
107
+ public async executeScriptSASjs(
108
+ code: string,
109
+ runTime?: string,
110
+ authConfig?: AuthConfig
111
+ ) {
106
112
  this.isMethodSupported('executeScriptSASJS', [ServerType.Sasjs])
107
113
 
108
- return await this.sasJSApiClient?.executeScript(code, authConfig)
114
+ return await this.sasJSApiClient?.executeScript(code, runTime, authConfig)
109
115
  }
110
116
 
111
117
  /**
@@ -691,7 +697,7 @@ export default class SASjs {
691
697
  // status is true if the data passes validation checks above
692
698
  if (validationResult.status) {
693
699
  if (config.serverType === ServerType.Sasjs) {
694
- return await this.webJobExecutor!.execute(
700
+ return await this.sasjsJobExecutor!.execute(
695
701
  sasJob,
696
702
  data,
697
703
  config,
@@ -1049,6 +1055,12 @@ export default class SASjs {
1049
1055
  this.sasViyaApiClient!
1050
1056
  )
1051
1057
 
1058
+ this.sasjsJobExecutor = new SasjsJobExecutor(
1059
+ this.sasjsConfig.serverUrl,
1060
+ this.jobsPath,
1061
+ this.requestClient
1062
+ )
1063
+
1052
1064
  this.sas9JobExecutor = new Sas9JobExecutor(
1053
1065
  this.sasjsConfig.serverUrl,
1054
1066
  this.sasjsConfig.serverType!,
@@ -3,7 +3,7 @@ import { ExecutionQuery } from './types'
3
3
  import { RequestClient } from './request/RequestClient'
4
4
  import { getAccessTokenForSasjs } from './auth/getAccessTokenForSasjs'
5
5
  import { refreshTokensForSasjs } from './auth/refreshTokensForSasjs'
6
- import { parseWeboutResponse } from './utils'
6
+ import { parseWeboutResponse, SASJS_LOGS_SEPARATOR } from './utils'
7
7
  import { getTokens } from './auth/getTokens'
8
8
 
9
9
  export class SASjsApiClient {
@@ -64,9 +64,14 @@ export class SASjsApiClient {
64
64
  /**
65
65
  * Executes code on a SASJS server.
66
66
  * @param code - a string of code to execute.
67
+ * @param runTime - a string to representing runTime for code execution
67
68
  * @param authConfig - an object for authentication.
68
69
  */
69
- public async executeScript(code: string, authConfig?: AuthConfig) {
70
+ public async executeScript(
71
+ code: string,
72
+ runTime: string = 'sas',
73
+ authConfig?: AuthConfig
74
+ ) {
70
75
  let access_token = (authConfig || {}).access_token
71
76
  if (authConfig) {
72
77
  ;({ access_token } = await getTokens(
@@ -79,13 +84,9 @@ export class SASjsApiClient {
79
84
  let parsedSasjsServerLog = ''
80
85
 
81
86
  await this.requestClient
82
- .post('SASjsApi/code/execute', { code }, access_token)
87
+ .post('SASjsApi/code/execute', { code, runTime }, access_token)
83
88
  .then((res: any) => {
84
- if (res.result?.log) {
85
- parsedSasjsServerLog = res.result.log
86
- .map((logLine: any) => logLine.line)
87
- .join('\n')
88
- }
89
+ if (res.log) parsedSasjsServerLog = res.log
89
90
  })
90
91
  .catch((err) => {
91
92
  parsedSasjsServerLog = err
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  getValidJson,
3
3
  parseSasViyaDebugResponse,
4
- parseWeboutResponse
4
+ parseWeboutResponse,
5
+ SASJS_LOGS_SEPARATOR
5
6
  } from '../utils'
6
7
  import { UploadFile } from '../types/UploadFile'
7
8
  import {
@@ -99,21 +100,8 @@ export class FileUploader extends BaseJobExecutor {
99
100
  ? parseWeboutResponse(res.result, uploadUrl)
100
101
  : res.result
101
102
  break
102
- case ServerType.Sasjs:
103
- if (typeof res.result._webout === 'object') {
104
- jsonResponse = res.result._webout
105
- } else {
106
- const webout = parseWeboutResponse(
107
- res.result._webout,
108
- uploadUrl
109
- )
110
- jsonResponse = getValidJson(webout)
111
- }
112
- break
113
103
  }
114
- } else if (this.serverType === ServerType.Sasjs) {
115
- jsonResponse = getValidJson(res.result._webout)
116
- } else {
104
+ } else if (this.serverType !== ServerType.Sasjs) {
117
105
  jsonResponse =
118
106
  typeof res.result === 'string'
119
107
  ? getValidJson(res.result)
@@ -1,6 +1,6 @@
1
1
  import { AuthConfig, ServerType } from '@sasjs/utils/types'
2
2
  import { ExtraResponseAttributes } from '@sasjs/utils/types'
3
- import { asyncForEach } from '../utils'
3
+ import { asyncForEach, isRelativePath } from '../utils'
4
4
 
5
5
  export type ExecuteFunction = () => Promise<any>
6
6
 
@@ -45,4 +45,17 @@ export abstract class BaseJobExecutor implements JobExecutor {
45
45
  protected appendWaitingRequest(request: ExecuteFunction) {
46
46
  this.waitingRequests.push(request)
47
47
  }
48
+
49
+ protected getRequestParams(config: any): any {
50
+ const requestParams: any = {}
51
+
52
+ if (config.debug) {
53
+ requestParams['_omittextlog'] = 'false'
54
+ requestParams['_omitsessionresults'] = 'false'
55
+
56
+ requestParams['_debug'] = 131
57
+ }
58
+
59
+ return requestParams
60
+ }
48
61
  }
@@ -102,7 +102,7 @@ export class Sas9JobExecutor extends BaseJobExecutor {
102
102
  return requestPromise
103
103
  }
104
104
 
105
- private getRequestParams(config: any): any {
105
+ protected getRequestParams(config: any): any {
106
106
  const requestParams: any = {}
107
107
 
108
108
  if (config.debug) {
@@ -0,0 +1,141 @@
1
+ import * as NodeFormData from 'form-data'
2
+ import {
3
+ AuthConfig,
4
+ ExtraResponseAttributes,
5
+ ServerType
6
+ } from '@sasjs/utils/types'
7
+ import {
8
+ ErrorResponse,
9
+ JobExecutionError,
10
+ LoginRequiredError
11
+ } from '../types/errors'
12
+ import { generateFileUploadForm } from '../file/generateFileUploadForm'
13
+
14
+ import { RequestClient } from '../request/RequestClient'
15
+
16
+ import { isRelativePath, appendExtraResponseAttributes } from '../utils'
17
+ import { BaseJobExecutor } from './JobExecutor'
18
+
19
+ export class SasjsJobExecutor extends BaseJobExecutor {
20
+ constructor(
21
+ serverUrl: string,
22
+ private jobsPath: string,
23
+ private requestClient: RequestClient
24
+ ) {
25
+ super(serverUrl, ServerType.Sasjs)
26
+ }
27
+
28
+ async execute(
29
+ sasJob: string,
30
+ data: any,
31
+ config: any,
32
+ loginRequiredCallback?: any,
33
+ authConfig?: AuthConfig,
34
+ extraResponseAttributes: ExtraResponseAttributes[] = []
35
+ ) {
36
+ const loginCallback = loginRequiredCallback
37
+ const program =
38
+ isRelativePath(sasJob) && config.appLoc
39
+ ? config.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
40
+ : sasJob
41
+
42
+ let apiUrl = `${config.serverUrl}${this.jobsPath}/?${'_program=' + program}`
43
+
44
+ let requestParams = {
45
+ ...this.getRequestParams(config)
46
+ }
47
+
48
+ /**
49
+ * Use the available form data object (FormData in Browser, NodeFormData in
50
+ * Node)
51
+ */
52
+ let formData =
53
+ typeof FormData === 'undefined' ? new NodeFormData() : new FormData()
54
+
55
+ if (data) {
56
+ // file upload approach
57
+ try {
58
+ formData = generateFileUploadForm(formData, data)
59
+ } catch (e: any) {
60
+ return Promise.reject(new ErrorResponse(e?.message, e))
61
+ }
62
+ }
63
+
64
+ for (const key in requestParams) {
65
+ if (requestParams.hasOwnProperty(key)) {
66
+ formData.append(key, requestParams[key])
67
+ }
68
+ }
69
+
70
+ /* The NodeFormData object does not set the request header - so, set it */
71
+ const contentType =
72
+ formData instanceof NodeFormData && typeof FormData === 'undefined'
73
+ ? `multipart/form-data; boundary=${formData.getBoundary()}`
74
+ : undefined
75
+
76
+ const requestPromise = new Promise((resolve, reject) => {
77
+ this.requestClient!.post(
78
+ apiUrl,
79
+ formData,
80
+ authConfig?.access_token,
81
+ contentType
82
+ )
83
+ .then(async (res: any) => {
84
+ if (Object.entries(res.result).length < 1) {
85
+ throw new JobExecutionError(
86
+ 0,
87
+ `No webout was returned by job ${program}. Please check the SAS log for more info.`,
88
+ res.log
89
+ )
90
+ }
91
+
92
+ this.requestClient!.appendRequest(res, sasJob, config.debug)
93
+
94
+ const responseObject = appendExtraResponseAttributes(
95
+ res,
96
+ extraResponseAttributes
97
+ )
98
+ resolve(responseObject)
99
+ })
100
+ .catch(async (e: Error) => {
101
+ if (e instanceof JobExecutionError) {
102
+ this.requestClient!.appendRequest(e, sasJob, config.debug)
103
+ reject(new ErrorResponse(e?.message, e))
104
+ }
105
+
106
+ if (e instanceof LoginRequiredError) {
107
+ if (!loginRequiredCallback) {
108
+ reject(
109
+ new ErrorResponse(
110
+ 'Request is not authenticated. Make sure .env file exists with valid credentials.',
111
+ e
112
+ )
113
+ )
114
+ }
115
+
116
+ this.appendWaitingRequest(() => {
117
+ return this.execute(
118
+ sasJob,
119
+ data,
120
+ config,
121
+ loginRequiredCallback,
122
+ authConfig,
123
+ extraResponseAttributes
124
+ ).then(
125
+ (res: any) => {
126
+ resolve(res)
127
+ },
128
+ (err: any) => {
129
+ reject(err)
130
+ }
131
+ )
132
+ })
133
+
134
+ if (loginCallback) await loginCallback()
135
+ } else reject(new ErrorResponse(e?.message, e))
136
+ })
137
+ })
138
+
139
+ return requestPromise
140
+ }
141
+ }
@@ -16,12 +16,10 @@ import { SASViyaApiClient } from '../SASViyaApiClient'
16
16
  import {
17
17
  isRelativePath,
18
18
  parseSasViyaDebugResponse,
19
- appendExtraResponseAttributes,
20
- getValidJson
19
+ appendExtraResponseAttributes
21
20
  } from '../utils'
22
21
  import { BaseJobExecutor } from './JobExecutor'
23
22
  import { parseWeboutResponse } from '../utils/parseWeboutResponse'
24
- import { Server } from 'https'
25
23
 
26
24
  export interface WaitingRequstPromise {
27
25
  promise: Promise<any> | null
@@ -121,7 +119,6 @@ export class WebJobExecutor extends BaseJobExecutor {
121
119
  const stringifiedData = JSON.stringify(data)
122
120
  if (
123
121
  config.serverType === ServerType.Sas9 ||
124
- config.serverType === ServerType.Sasjs ||
125
122
  stringifiedData.length > 500000 ||
126
123
  stringifiedData.includes(';')
127
124
  ) {
@@ -164,31 +161,7 @@ export class WebJobExecutor extends BaseJobExecutor {
164
161
  contentType
165
162
  )
166
163
  .then(async (res: any) => {
167
- const parsedSasjsServerLog =
168
- this.serverType === ServerType.Sasjs
169
- ? res.result.log.map((logLine: any) => logLine.line).join('\n')
170
- : res.result.log
171
-
172
- const resObj =
173
- this.serverType === ServerType.Sasjs
174
- ? {
175
- result: res.result._webout,
176
- log: parsedSasjsServerLog
177
- }
178
- : res
179
-
180
- if (
181
- this.serverType === ServerType.Sasjs &&
182
- res.result._webout.length < 1
183
- ) {
184
- throw new JobExecutionError(
185
- 0,
186
- `No webout was returned by job ${program}. Server type is SASJS and the calling function is WebJobExecutor. Please check the SAS log for more info.`,
187
- parsedSasjsServerLog
188
- )
189
- }
190
-
191
- this.requestClient!.appendRequest(resObj, sasJob, config.debug)
164
+ this.requestClient!.appendRequest(res, sasJob, config.debug)
192
165
 
193
166
  let jsonResponse = res.result
194
167
 
@@ -207,21 +180,11 @@ export class WebJobExecutor extends BaseJobExecutor {
207
180
  ? parseWeboutResponse(res.result, apiUrl)
208
181
  : res.result
209
182
  break
210
- case ServerType.Sasjs:
211
- if (typeof res.result._webout === 'object') {
212
- jsonResponse = res.result._webout
213
- } else {
214
- const webout = parseWeboutResponse(res.result._webout, apiUrl)
215
- jsonResponse = getValidJson(webout)
216
- }
217
- break
218
183
  }
219
- } else if (this.serverType === ServerType.Sasjs) {
220
- jsonResponse = getValidJson(res.result._webout)
221
184
  }
222
185
 
223
186
  const responseObject = appendExtraResponseAttributes(
224
- { result: jsonResponse, log: parsedSasjsServerLog },
187
+ { result: jsonResponse, log: res.log },
225
188
  extraResponseAttributes
226
189
  )
227
190
  resolve(responseObject)
@@ -261,9 +224,7 @@ export class WebJobExecutor extends BaseJobExecutor {
261
224
  })
262
225
 
263
226
  if (loginCallback) await loginCallback()
264
- } else {
265
- reject(new ErrorResponse(e?.message, e))
266
- }
227
+ } else reject(new ErrorResponse(e?.message, e))
267
228
  })
268
229
  })
269
230
 
@@ -301,39 +262,4 @@ export class WebJobExecutor extends BaseJobExecutor {
301
262
  }
302
263
  return uri
303
264
  }
304
-
305
- private getRequestParams(config: any): any {
306
- const requestParams: any = {}
307
-
308
- if (config.debug) {
309
- requestParams['_omittextlog'] = 'false'
310
- requestParams['_omitsessionresults'] = 'false'
311
-
312
- requestParams['_debug'] = 131
313
- }
314
-
315
- return requestParams
316
- }
317
-
318
- private parseSAS9ErrorResponse(response: string) {
319
- const logLines = response.split('\n')
320
- const parsedLines: string[] = []
321
- let firstErrorLineIndex: number = -1
322
-
323
- logLines.map((line: string, index: number) => {
324
- if (
325
- line.toLowerCase().includes('error') &&
326
- !line.toLowerCase().includes('this request completed with errors.') &&
327
- firstErrorLineIndex === -1
328
- ) {
329
- firstErrorLineIndex = index
330
- }
331
- })
332
-
333
- for (let i = firstErrorLineIndex - 10; i <= firstErrorLineIndex + 10; i++) {
334
- parsedLines.push(logLines[i])
335
- }
336
-
337
- return parsedLines.join(', ')
338
- }
339
265
  }
@@ -4,3 +4,4 @@ export * from './JesJobExecutor'
4
4
  export * from './JobExecutor'
5
5
  export * from './Sas9JobExecutor'
6
6
  export * from './WebJobExecutor'
7
+ export * from './SasjsJobExecutor'
@@ -133,29 +133,13 @@ export class RequestClient implements HttpClient {
133
133
  } else {
134
134
  sasWork = response.log
135
135
  }
136
- } else if (response?.result?.log) {
137
- //In this scenario we know we got the response from SASJS server
138
- //Log is array of `{ line: '' }` so we need to convert it back to text
139
- //To be able to parse it with current functions.
140
- let log: string = ''
141
-
142
- if (typeof log !== 'string') {
143
- log = response.result.log
144
- .map((logLine: any) => logLine.line)
145
- .join('\n')
136
+ } else if (response?.result) {
137
+ // We parse only if it's a string, otherwise it would throw error
138
+ if (typeof response.result === 'string') {
139
+ sourceCode = parseSourceCode(response.result)
140
+ generatedCode = parseGeneratedCode(response.result)
146
141
  }
147
142
 
148
- sourceCode = parseSourceCode(log)
149
- generatedCode = parseGeneratedCode(log)
150
-
151
- if (response?.result?._webout) {
152
- sasWork = response.result._webout.WORK
153
- } else {
154
- sasWork = log
155
- }
156
- } else if (response?.result) {
157
- sourceCode = parseSourceCode(response.result)
158
- generatedCode = parseGeneratedCode(response.result)
159
143
  sasWork = response.result.WORK
160
144
  }
161
145
  }
@@ -1,9 +1,12 @@
1
1
  import { RequestClient } from './RequestClient'
2
+ import { AxiosResponse } from 'axios'
3
+ import { SASJS_LOGS_SEPARATOR, getValidJson } from '../utils'
2
4
 
3
5
  /**
4
6
  * Specific request client for SASJS.
5
7
  * Append tokens in headers.
6
8
  */
9
+
7
10
  export class SasjsRequestClient extends RequestClient {
8
11
  getHeaders = (accessToken: string | undefined, contentType: string) => {
9
12
  const headers: any = {}
@@ -20,4 +23,32 @@ export class SasjsRequestClient extends RequestClient {
20
23
 
21
24
  return headers
22
25
  }
26
+
27
+ protected parseResponse<T>(response: AxiosResponse<any>) {
28
+ const etag = response?.headers ? response.headers['etag'] : ''
29
+ let parsedResponse = {}
30
+ let log
31
+
32
+ try {
33
+ if (typeof response.data === 'string') {
34
+ parsedResponse = JSON.parse(response.data)
35
+ } else {
36
+ parsedResponse = response.data
37
+ }
38
+ } catch {
39
+ if (response.data.includes(SASJS_LOGS_SEPARATOR)) {
40
+ const splittedResponse = response.data.split(SASJS_LOGS_SEPARATOR)
41
+ log = splittedResponse[1]
42
+ if (splittedResponse[0].trim())
43
+ parsedResponse = getValidJson(splittedResponse[0])
44
+ } else parsedResponse = response.data
45
+ }
46
+
47
+ return {
48
+ result: parsedResponse as T,
49
+ log,
50
+ etag,
51
+ status: response.status
52
+ }
53
+ }
23
54
  }
@@ -0,0 +1,2 @@
1
+ export const SASJS_LOGS_SEPARATOR =
2
+ 'SASJS_LOGS_SEPARATOR_163ee17b6ff24f028928972d80a26784'
@@ -2,6 +2,7 @@ export * from './appendExtraResponseAttributes'
2
2
  export * from './asyncForEach'
3
3
  export * from './compareTimestamps'
4
4
  export * from './convertToCsv'
5
+ export * from './constants'
5
6
  export * from './createAxiosInstance'
6
7
  export * from './delay'
7
8
  export * from './fetchLogByChunks'
@@ -0,0 +1 @@
1
+ export declare const SASJS_LOGS_SEPARATOR = "SASJS_LOGS_SEPARATOR_163ee17b6ff24f028928972d80a26784";
package/utils/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './appendExtraResponseAttributes';
2
2
  export * from './asyncForEach';
3
3
  export * from './compareTimestamps';
4
4
  export * from './convertToCsv';
5
+ export * from './constants';
5
6
  export * from './createAxiosInstance';
6
7
  export * from './delay';
7
8
  export * from './fetchLogByChunks';