@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.
- package/README.md +9 -7
- package/SASViyaApiClient.d.ts +7 -0
- package/SASjs.d.ts +15 -2
- package/index.js +2 -2
- package/job-execution/FileUploader.d.ts +9 -0
- package/job-execution/JobExecutor.d.ts +0 -7
- package/job-execution/index.d.ts +1 -0
- package/node/SASViyaApiClient.d.ts +7 -0
- package/node/SASjs.d.ts +15 -2
- package/node/index.js +2 -2
- package/node/job-execution/FileUploader.d.ts +9 -0
- package/node/job-execution/JobExecutor.d.ts +0 -7
- package/node/job-execution/index.d.ts +1 -0
- package/node/request/RequestClient.d.ts +20 -0
- package/package.json +6 -6
- package/request/RequestClient.d.ts +20 -0
- package/src/SASViyaApiClient.ts +10 -0
- package/src/SASjs.ts +44 -29
- package/src/job-execution/ComputeJobExecutor.ts +4 -5
- package/src/job-execution/FileUploader.ts +143 -0
- package/src/job-execution/JesJobExecutor.ts +4 -4
- package/src/job-execution/JobExecutor.ts +1 -52
- package/src/job-execution/Sas9JobExecutor.ts +1 -1
- package/src/job-execution/WebJobExecutor.ts +35 -7
- package/src/job-execution/index.ts +1 -0
- package/src/request/RequestClient.ts +95 -20
- package/src/utils/getValidJson.ts +2 -0
- package/src/utils/loginPrompt/index.ts +21 -11
- package/src/utils/parseViyaDebugResponse.ts +1 -1
- package/FileUploader.d.ts +0 -10
- package/node/FileUploader.d.ts +0 -10
- package/src/FileUploader.ts +0 -98
|
@@ -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
|
}
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|
package/src/SASViyaApiClient.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
584
|
+
params: { [key: string]: any } | null,
|
|
585
|
+
config: { [key: string]: any } = {},
|
|
586
|
+
loginRequiredCallback?: () => any
|
|
581
587
|
) {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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
|
|
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.
|
|
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
|
|
945
|
-
this.
|
|
946
|
-
|
|
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
|
|
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
|
}
|