@sasjs/adapter 2.11.0 → 2.11.4

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.
@@ -0,0 +1,9 @@
1
+ import { RequestClient } from '../request/RequestClient';
2
+ import { ServerType } from '@sasjs/utils/types';
3
+ import { BaseJobExecutor } from './JobExecutor';
4
+ export declare class FileUploader extends BaseJobExecutor {
5
+ private jobsPath;
6
+ private requestClient;
7
+ constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient);
8
+ execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any): Promise<unknown>;
9
+ }
@@ -1,23 +1,16 @@
1
1
  import { AuthConfig, ServerType } from '@sasjs/utils/types';
2
- import { SASjsRequest } from '../types';
3
2
  import { ExtraResponseAttributes } from '@sasjs/utils/types';
4
3
  export declare type ExecuteFunction = () => Promise<any>;
5
4
  export interface JobExecutor {
6
5
  execute: (sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig, extraResponseAttributes?: ExtraResponseAttributes[]) => Promise<any>;
7
6
  resendWaitingRequests: () => Promise<void>;
8
- getRequests: () => SASjsRequest[];
9
- clearRequests: () => void;
10
7
  }
11
8
  export declare abstract class BaseJobExecutor implements JobExecutor {
12
9
  protected serverUrl: string;
13
10
  protected serverType: ServerType;
14
11
  constructor(serverUrl: string, serverType: ServerType);
15
12
  private waitingRequests;
16
- private requests;
17
13
  abstract execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig | undefined, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<any>;
18
14
  resendWaitingRequests: () => Promise<void>;
19
- getRequests: () => SASjsRequest[];
20
- clearRequests: () => void;
21
15
  protected appendWaitingRequest(request: ExecuteFunction): void;
22
- protected appendRequest(response: any, program: string, debug: boolean): void;
23
16
  }
@@ -3,3 +3,4 @@ export * from './JesJobExecutor';
3
3
  export * from './JobExecutor';
4
4
  export * from './Sas9JobExecutor';
5
5
  export * from './WebJobExecutor';
6
+ export * from './FileUploader';
@@ -1,5 +1,6 @@
1
1
  import { AxiosInstance, AxiosResponse } from 'axios';
2
2
  import { CsrfToken } from '..';
3
+ import { SASjsRequest } from '../types';
3
4
  export interface HttpClient {
4
5
  get<T>(url: string, accessToken: string | undefined, contentType: string, overrideHeaders: {
5
6
  [key: string]: string | number;
@@ -29,13 +30,31 @@ export interface HttpClient {
29
30
  }
30
31
  export declare class RequestClient implements HttpClient {
31
32
  protected baseUrl: string;
33
+ private requests;
32
34
  protected csrfToken: CsrfToken;
33
35
  protected fileUploadCsrfToken: CsrfToken | undefined;
34
36
  protected httpClient: AxiosInstance;
35
37
  constructor(baseUrl: string, allowInsecure?: boolean);
38
+ setConfig(baseUrl: string, allowInsecure?: boolean): void;
36
39
  getCsrfToken(type?: 'general' | 'file'): CsrfToken | undefined;
37
40
  clearCsrfTokens(): void;
38
41
  getBaseUrl(): string;
42
+ /**
43
+ * this method returns all requests, an array of SASjsRequest type
44
+ * @returns SASjsRequest[]
45
+ */
46
+ getRequests: () => SASjsRequest[];
47
+ /**
48
+ * this method clears the requests array, i.e set to empty
49
+ */
50
+ clearRequests: () => void;
51
+ /**
52
+ * this method appends the response from sasjs request to requests array
53
+ * @param response - response from sasjs request
54
+ * @param program - name of program
55
+ * @param debug - a boolean that indicates whether debug was enabled or not
56
+ */
57
+ appendRequest(response: any, program: string, debug: boolean): void;
39
58
  get<T>(url: string, accessToken: string | undefined, contentType?: string, overrideHeaders?: {
40
59
  [key: string]: string | number;
41
60
  }, debug?: boolean): Promise<{
@@ -76,5 +95,6 @@ export declare class RequestClient implements HttpClient {
76
95
  log?: string | undefined;
77
96
  status: number;
78
97
  };
98
+ private createHttpClient;
79
99
  }
80
100
  export declare const throwIfError: (response: AxiosResponse) => void;
package/package.json CHANGED
@@ -48,33 +48,33 @@
48
48
  "copyfiles": "^2.4.1",
49
49
  "cp": "^0.2.0",
50
50
  "dotenv": "^10.0.0",
51
- "jest": "^27.1.0",
51
+ "jest": "^27.2.0",
52
52
  "jest-extended": "^0.11.5",
53
53
  "node-polyfill-webpack-plugin": "^1.1.4",
54
54
  "path": "^0.12.7",
55
55
  "process": "^0.11.10",
56
56
  "rimraf": "^3.0.2",
57
57
  "semantic-release": "^17.4.7",
58
- "terser-webpack-plugin": "^5.2.0",
58
+ "terser-webpack-plugin": "^5.2.4",
59
59
  "ts-jest": "^27.0.3",
60
60
  "ts-loader": "^9.2.2",
61
61
  "tslint": "^6.1.3",
62
62
  "tslint-config-prettier": "^1.18.0",
63
- "typedoc": "^0.21.9",
63
+ "typedoc": "^0.22.3",
64
64
  "typedoc-neo-theme": "^1.1.1",
65
65
  "typedoc-plugin-external-module-name": "^4.0.6",
66
66
  "typescript": "4.3.5",
67
- "webpack": "^5.44.0",
67
+ "webpack": "^5.52.1",
68
68
  "webpack-cli": "^4.7.2"
69
69
  },
70
70
  "main": "index.js",
71
71
  "dependencies": {
72
72
  "@sasjs/utils": "^2.30.0",
73
- "axios": "^0.21.1",
73
+ "axios": "^0.21.4",
74
74
  "axios-cookiejar-support": "^1.0.1",
75
75
  "form-data": "^4.0.0",
76
76
  "https": "^1.0.0",
77
77
  "tough-cookie": "^4.0.0"
78
78
  },
79
- "version": "2.11.0"
79
+ "version": "2.11.4"
80
80
  }
@@ -1,5 +1,6 @@
1
1
  import { AxiosInstance, AxiosResponse } from 'axios';
2
2
  import { CsrfToken } from '..';
3
+ import { SASjsRequest } from '../types';
3
4
  export interface HttpClient {
4
5
  get<T>(url: string, accessToken: string | undefined, contentType: string, overrideHeaders: {
5
6
  [key: string]: string | number;
@@ -29,13 +30,31 @@ export interface HttpClient {
29
30
  }
30
31
  export declare class RequestClient implements HttpClient {
31
32
  protected baseUrl: string;
33
+ private requests;
32
34
  protected csrfToken: CsrfToken;
33
35
  protected fileUploadCsrfToken: CsrfToken | undefined;
34
36
  protected httpClient: AxiosInstance;
35
37
  constructor(baseUrl: string, allowInsecure?: boolean);
38
+ setConfig(baseUrl: string, allowInsecure?: boolean): void;
36
39
  getCsrfToken(type?: 'general' | 'file'): CsrfToken | undefined;
37
40
  clearCsrfTokens(): void;
38
41
  getBaseUrl(): string;
42
+ /**
43
+ * this method returns all requests, an array of SASjsRequest type
44
+ * @returns SASjsRequest[]
45
+ */
46
+ getRequests: () => SASjsRequest[];
47
+ /**
48
+ * this method clears the requests array, i.e set to empty
49
+ */
50
+ clearRequests: () => void;
51
+ /**
52
+ * this method appends the response from sasjs request to requests array
53
+ * @param response - response from sasjs request
54
+ * @param program - name of program
55
+ * @param debug - a boolean that indicates whether debug was enabled or not
56
+ */
57
+ appendRequest(response: any, program: string, debug: boolean): void;
39
58
  get<T>(url: string, accessToken: string | undefined, contentType?: string, overrideHeaders?: {
40
59
  [key: string]: string | number;
41
60
  }, debug?: boolean): Promise<{
@@ -76,5 +95,6 @@ export declare class RequestClient implements HttpClient {
76
95
  log?: string | undefined;
77
96
  status: number;
78
97
  };
98
+ private createHttpClient;
79
99
  }
80
100
  export declare const throwIfError: (response: AxiosResponse) => void;
@@ -51,6 +51,16 @@ export class SASViyaApiClient {
51
51
  )
52
52
  private folderMap = new Map<string, Job[]>()
53
53
 
54
+ /**
55
+ * A helper method used to call appendRequest method of RequestClient
56
+ * @param response - response from sasjs request
57
+ * @param program - name of program
58
+ * @param debug - a boolean that indicates whether debug was enabled or not
59
+ */
60
+ public appendRequest(response: any, program: string, debug: boolean) {
61
+ this.requestClient!.appendRequest(response, program, debug)
62
+ }
63
+
54
64
  public get debug() {
55
65
  return this._debug
56
66
  }
package/src/SASjs.ts CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  } from './types'
9
9
  import { SASViyaApiClient } from './SASViyaApiClient'
10
10
  import { SAS9ApiClient } from './SAS9ApiClient'
11
- import { FileUploader } from './FileUploader'
12
11
  import { AuthManager } from './auth'
13
12
  import {
14
13
  ServerType,
@@ -22,7 +21,8 @@ import {
22
21
  WebJobExecutor,
23
22
  ComputeJobExecutor,
24
23
  JesJobExecutor,
25
- Sas9JobExecutor
24
+ Sas9JobExecutor,
25
+ FileUploader
26
26
  } from './job-execution'
27
27
  import { ErrorResponse } from './types/errors'
28
28
  import { LoginOptions, LoginResult } from './types/Login'
@@ -507,7 +507,7 @@ export default class SASjs {
507
507
  ...this.sasjsConfig,
508
508
  ...config
509
509
  }
510
- await this.setupConfiguration()
510
+ this.setupConfiguration()
511
511
  }
512
512
 
513
513
  /**
@@ -571,24 +571,32 @@ export default class SASjs {
571
571
  * Process). Is prepended at runtime with the value of `appLoc`.
572
572
  * @param files - array of files to be uploaded, including File object and file name.
573
573
  * @param params - request URL parameters.
574
- * @param overrideSasjsConfig - object to override existing config (optional)
574
+ * @param config - provide any changes to the config here, for instance to
575
+ * enable/disable `debug`. Any change provided will override the global config,
576
+ * for that particular function call.
577
+ * @param loginRequiredCallback - a function that is called if the
578
+ * user is not logged in (eg to display a login form). The request will be
579
+ * resubmitted after successful login.
575
580
  */
576
- public uploadFile(
581
+ public async uploadFile(
577
582
  sasJob: string,
578
583
  files: UploadFile[],
579
- params: any,
580
- overrideSasjsConfig?: any
584
+ params: { [key: string]: any } | null,
585
+ config: { [key: string]: any } = {},
586
+ loginRequiredCallback?: () => any
581
587
  ) {
582
- const fileUploader = overrideSasjsConfig
583
- ? new FileUploader(
584
- { ...this.sasjsConfig, ...overrideSasjsConfig },
585
- this.jobsPath,
586
- this.requestClient!
587
- )
588
- : this.fileUploader ||
589
- new FileUploader(this.sasjsConfig, this.jobsPath, this.requestClient!)
588
+ config = {
589
+ ...this.sasjsConfig,
590
+ ...config
591
+ }
592
+ const data = { files, params }
590
593
 
591
- return fileUploader.uploadFile(sasJob, files, params)
594
+ return await this.fileUploader!.execute(
595
+ sasJob,
596
+ data,
597
+ config,
598
+ loginRequiredCallback
599
+ )
592
600
  }
593
601
 
594
602
  /**
@@ -874,6 +882,7 @@ export default class SASjs {
874
882
  await this.webJobExecutor?.resendWaitingRequests()
875
883
  await this.computeJobExecutor?.resendWaitingRequests()
876
884
  await this.jesJobExecutor?.resendWaitingRequests()
885
+ await this.fileUploader?.resendWaitingRequests()
877
886
  }
878
887
 
879
888
  /**
@@ -905,20 +914,18 @@ export default class SASjs {
905
914
  })
906
915
  }
907
916
 
917
+ /**
918
+ * this method returns an array of SASjsRequest
919
+ * @returns SASjsRequest[]
920
+ */
908
921
  public getSasRequests() {
909
- const requests = [
910
- ...this.webJobExecutor!.getRequests(),
911
- ...this.computeJobExecutor!.getRequests(),
912
- ...this.jesJobExecutor!.getRequests()
913
- ]
922
+ const requests = [...this.requestClient!.getRequests()]
914
923
  const sortedRequests = requests.sort(compareTimestamps)
915
924
  return sortedRequests
916
925
  }
917
926
 
918
927
  public clearSasRequests() {
919
- this.webJobExecutor!.clearRequests()
920
- this.computeJobExecutor!.clearRequests()
921
- this.jesJobExecutor!.clearRequests()
928
+ this.requestClient!.clearRequests()
922
929
  }
923
930
 
924
931
  private setupConfiguration() {
@@ -941,10 +948,17 @@ export default class SASjs {
941
948
  this.sasjsConfig.serverUrl = this.sasjsConfig.serverUrl.slice(0, -1)
942
949
  }
943
950
 
944
- this.requestClient = new RequestClient(
945
- this.sasjsConfig.serverUrl,
946
- this.sasjsConfig.allowInsecureRequests
947
- )
951
+ if (!this.requestClient) {
952
+ this.requestClient = new RequestClient(
953
+ this.sasjsConfig.serverUrl,
954
+ this.sasjsConfig.allowInsecureRequests
955
+ )
956
+ } else {
957
+ this.requestClient.setConfig(
958
+ this.sasjsConfig.serverUrl,
959
+ this.sasjsConfig.allowInsecureRequests
960
+ )
961
+ }
948
962
 
949
963
  this.jobsPath =
950
964
  this.sasjsConfig.serverType === ServerType.SasViya
@@ -986,7 +1000,8 @@ export default class SASjs {
986
1000
  }
987
1001
 
988
1002
  this.fileUploader = new FileUploader(
989
- this.sasjsConfig,
1003
+ this.sasjsConfig.serverUrl,
1004
+ this.sasjsConfig.serverType!,
990
1005
  this.jobsPath,
991
1006
  this.requestClient
992
1007
  )
@@ -35,19 +35,16 @@ export class ComputeJobExecutor extends BaseJobExecutor {
35
35
  expectWebout
36
36
  )
37
37
  .then((response) => {
38
- this.appendRequest(response, sasJob, config.debug)
39
-
38
+ this.sasViyaApiClient.appendRequest(response, sasJob, config.debug)
40
39
  resolve(response.result)
41
40
  })
42
41
  .catch(async (e: Error) => {
43
42
  if (e instanceof ComputeJobExecutionError) {
44
- this.appendRequest(e, sasJob, config.debug)
45
-
43
+ this.sasViyaApiClient.appendRequest(e, sasJob, config.debug)
46
44
  reject(new ErrorResponse(e?.message, e))
47
45
  }
48
46
 
49
47
  if (e instanceof LoginRequiredError) {
50
- await loginCallback()
51
48
  this.appendWaitingRequest(() => {
52
49
  return this.execute(
53
50
  sasJob,
@@ -63,6 +60,8 @@ export class ComputeJobExecutor extends BaseJobExecutor {
63
60
  }
64
61
  )
65
62
  })
63
+
64
+ await loginCallback()
66
65
  } else {
67
66
  reject(new ErrorResponse(e?.message, e))
68
67
  }
@@ -0,0 +1,143 @@
1
+ import {
2
+ getValidJson,
3
+ parseSasViyaDebugResponse,
4
+ parseWeboutResponse
5
+ } from '../utils'
6
+ import { UploadFile } from '../types/UploadFile'
7
+ import {
8
+ ErrorResponse,
9
+ JobExecutionError,
10
+ LoginRequiredError
11
+ } from '../types/errors'
12
+ import { RequestClient } from '../request/RequestClient'
13
+ import { ServerType } from '@sasjs/utils/types'
14
+ import { BaseJobExecutor } from './JobExecutor'
15
+
16
+ interface dataFileUpload {
17
+ files: UploadFile[]
18
+ params: { [key: string]: any } | null
19
+ }
20
+
21
+ export class FileUploader extends BaseJobExecutor {
22
+ constructor(
23
+ serverUrl: string,
24
+ serverType: ServerType,
25
+ private jobsPath: string,
26
+ private requestClient: RequestClient
27
+ ) {
28
+ super(serverUrl, serverType)
29
+ }
30
+
31
+ public async execute(
32
+ sasJob: string,
33
+ data: any,
34
+ config: any,
35
+ loginRequiredCallback?: any
36
+ ) {
37
+ const { files, params }: dataFileUpload = data
38
+ const loginCallback = loginRequiredCallback || (() => Promise.resolve())
39
+
40
+ if (!files?.length)
41
+ throw new ErrorResponse('At least one file must be provided.')
42
+
43
+ if (!sasJob || sasJob === '')
44
+ throw new ErrorResponse('sasJob must be provided.')
45
+
46
+ let paramsString = ''
47
+
48
+ for (let param in params)
49
+ if (params.hasOwnProperty(param))
50
+ paramsString += `&${param}=${params[param]}`
51
+
52
+ const program = config.appLoc
53
+ ? config.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
54
+ : sasJob
55
+ const uploadUrl = `${this.jobsPath}/?${
56
+ '_program=' + program
57
+ }${paramsString}`
58
+
59
+ const formData = new FormData()
60
+
61
+ for (let file of files) {
62
+ formData.append('file', file.file, file.fileName)
63
+ }
64
+
65
+ const csrfToken = this.requestClient.getCsrfToken('file')
66
+ if (csrfToken) formData.append('_csrf', csrfToken.value)
67
+ if (config.debug) formData.append('_debug', '131')
68
+ if (config.serverType === ServerType.SasViya && config.contextName)
69
+ formData.append('_contextname', config.contextName)
70
+
71
+ const headers = {
72
+ 'cache-control': 'no-cache',
73
+ Accept: '*/*',
74
+ 'Content-Type': 'text/plain'
75
+ }
76
+
77
+ // currently only web approach is supported for file upload
78
+ // therefore log is part of response with debug enabled and must be parsed
79
+ const requestPromise = new Promise((resolve, reject) => {
80
+ this.requestClient
81
+ .post(uploadUrl, formData, undefined, 'application/json', headers)
82
+ .then(async (res: any) => {
83
+ this.requestClient.appendRequest(res, sasJob, config.debug)
84
+
85
+ let jsonResponse = res.result
86
+
87
+ if (config.debug) {
88
+ switch (this.serverType) {
89
+ case ServerType.SasViya:
90
+ jsonResponse = await parseSasViyaDebugResponse(
91
+ res.result,
92
+ this.requestClient,
93
+ config.serverUrl
94
+ )
95
+ break
96
+ case ServerType.Sas9:
97
+ jsonResponse =
98
+ typeof res.result === 'string'
99
+ ? parseWeboutResponse(res.result, uploadUrl)
100
+ : res.result
101
+ break
102
+ }
103
+ } else {
104
+ jsonResponse =
105
+ typeof res.result === 'string'
106
+ ? getValidJson(res.result)
107
+ : res.result
108
+ }
109
+
110
+ resolve(jsonResponse)
111
+ })
112
+ .catch(async (e: Error) => {
113
+ if (e instanceof JobExecutionError) {
114
+ this.requestClient!.appendRequest(e, sasJob, config.debug)
115
+ reject(new ErrorResponse(e?.message, e))
116
+ }
117
+
118
+ if (e instanceof LoginRequiredError) {
119
+ this.appendWaitingRequest(() => {
120
+ return this.execute(
121
+ sasJob,
122
+ data,
123
+ config,
124
+ loginRequiredCallback
125
+ ).then(
126
+ (res: any) => {
127
+ resolve(res)
128
+ },
129
+ (err: any) => {
130
+ reject(err)
131
+ }
132
+ )
133
+ })
134
+
135
+ await loginCallback()
136
+ } else {
137
+ reject(new ErrorResponse('File upload request failed.', e))
138
+ }
139
+ })
140
+ })
141
+ return requestPromise
142
+ }
143
+ }
@@ -28,7 +28,7 @@ export class JesJobExecutor extends BaseJobExecutor {
28
28
  this.sasViyaApiClient
29
29
  ?.executeJob(sasJob, config.contextName, config.debug, data, authConfig)
30
30
  .then((response: any) => {
31
- this.appendRequest(response, sasJob, config.debug)
31
+ this.sasViyaApiClient.appendRequest(response, sasJob, config.debug)
32
32
 
33
33
  const responseObject = appendExtraResponseAttributes(
34
34
  response,
@@ -39,14 +39,12 @@ export class JesJobExecutor extends BaseJobExecutor {
39
39
  })
40
40
  .catch(async (e: Error) => {
41
41
  if (e instanceof JobExecutionError) {
42
- this.appendRequest(e, sasJob, config.debug)
42
+ this.sasViyaApiClient.appendRequest(e, sasJob, config.debug)
43
43
 
44
44
  reject(new ErrorResponse(e?.message, e))
45
45
  }
46
46
 
47
47
  if (e instanceof LoginRequiredError) {
48
- await loginCallback()
49
-
50
48
  this.appendWaitingRequest(() => {
51
49
  return this.execute(
52
50
  sasJob,
@@ -64,6 +62,8 @@ export class JesJobExecutor extends BaseJobExecutor {
64
62
  }
65
63
  )
66
64
  })
65
+
66
+ await loginCallback()
67
67
  } else {
68
68
  reject(new ErrorResponse(e?.message, e))
69
69
  }
@@ -1,7 +1,6 @@
1
1
  import { AuthConfig, ServerType } from '@sasjs/utils/types'
2
- import { SASjsRequest } from '../types'
3
2
  import { ExtraResponseAttributes } from '@sasjs/utils/types'
4
- import { asyncForEach, parseGeneratedCode, parseSourceCode } from '../utils'
3
+ import { asyncForEach } from '../utils'
5
4
 
6
5
  export type ExecuteFunction = () => Promise<any>
7
6
 
@@ -15,15 +14,12 @@ export interface JobExecutor {
15
14
  extraResponseAttributes?: ExtraResponseAttributes[]
16
15
  ) => Promise<any>
17
16
  resendWaitingRequests: () => Promise<void>
18
- getRequests: () => SASjsRequest[]
19
- clearRequests: () => void
20
17
  }
21
18
 
22
19
  export abstract class BaseJobExecutor implements JobExecutor {
23
20
  constructor(protected serverUrl: string, protected serverType: ServerType) {}
24
21
 
25
22
  private waitingRequests: ExecuteFunction[] = []
26
- private requests: SASjsRequest[] = []
27
23
 
28
24
  abstract execute(
29
25
  sasJob: string,
@@ -46,54 +42,7 @@ export abstract class BaseJobExecutor implements JobExecutor {
46
42
  return
47
43
  }
48
44
 
49
- getRequests = () => this.requests
50
-
51
- clearRequests = () => {
52
- this.requests = []
53
- }
54
-
55
45
  protected appendWaitingRequest(request: ExecuteFunction) {
56
46
  this.waitingRequests.push(request)
57
47
  }
58
-
59
- protected appendRequest(response: any, program: string, debug: boolean) {
60
- let sourceCode = ''
61
- let generatedCode = ''
62
- let sasWork = null
63
-
64
- if (debug) {
65
- if (response?.log) {
66
- sourceCode = parseSourceCode(response.log)
67
- generatedCode = parseGeneratedCode(response.log)
68
-
69
- if (response?.result) {
70
- sasWork = response.result.WORK
71
- } else {
72
- sasWork = response.log
73
- }
74
- } else if (response?.result) {
75
- sourceCode = parseSourceCode(response.result)
76
- generatedCode = parseGeneratedCode(response.result)
77
- sasWork = response.result.WORK
78
- }
79
- }
80
-
81
- const stringifiedResult =
82
- typeof response?.result === 'string'
83
- ? response?.result
84
- : JSON.stringify(response?.result, null, 2)
85
-
86
- this.requests.push({
87
- logFile: response?.log || stringifiedResult || response,
88
- serviceLink: program,
89
- timestamp: new Date(),
90
- sourceCode,
91
- generatedCode,
92
- SASWORK: sasWork
93
- })
94
-
95
- if (this.requests.length > 20) {
96
- this.requests.splice(0, 1)
97
- }
98
- }
99
48
  }
@@ -45,7 +45,7 @@ export class Sas9JobExecutor extends BaseJobExecutor {
45
45
  if (data) {
46
46
  try {
47
47
  formData = generateFileUploadForm(formData, data)
48
- } catch (e) {
48
+ } catch (e: any) {
49
49
  return Promise.reject(new ErrorResponse(e?.message, e))
50
50
  }
51
51
  }