@sasjs/adapter 2.12.0 → 3.1.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/SAS9ApiClient.d.ts +3 -1
- package/SASViyaApiClient.d.ts +7 -1
- package/SASjs.d.ts +9 -7
- package/auth/AuthManager.d.ts +7 -2
- package/index.js +2 -2
- package/job-execution/Sas9JobExecutor.d.ts +6 -5
- package/node/SAS9ApiClient.d.ts +3 -1
- package/node/SASViyaApiClient.d.ts +7 -1
- package/node/SASjs.d.ts +9 -7
- package/node/auth/AuthManager.d.ts +7 -2
- package/node/index.js +2 -2
- package/node/job-execution/Sas9JobExecutor.d.ts +6 -5
- package/node/request/RequestClient.d.ts +4 -2
- package/node/request/Sas9RequestClient.d.ts +3 -1
- package/node/types/ExecuteScript.d.ts +0 -1
- package/node/types/SASjsConfig.d.ts +11 -4
- package/node/utils/createAxiosInstance.d.ts +3 -0
- package/node/utils/getValidJson.d.ts +1 -1
- package/node/utils/index.d.ts +1 -0
- package/node/utils/parseViyaDebugResponse.d.ts +1 -1
- package/package.json +10 -6
- package/request/RequestClient.d.ts +4 -2
- package/request/Sas9RequestClient.d.ts +3 -1
- package/src/SAS9ApiClient.ts +3 -2
- package/src/SASjs.ts +17 -12
- package/src/auth/AuthManager.ts +23 -10
- package/src/auth/getAccessToken.ts +1 -1
- package/src/job-execution/Sas9JobExecutor.ts +36 -5
- package/src/job-execution/WebJobExecutor.ts +18 -3
- package/src/request/RequestClient.ts +23 -20
- package/src/request/Sas9RequestClient.ts +3 -2
- package/src/test/SAS_server_app.ts +38 -0
- package/src/types/ExecuteScript.ts +0 -1
- package/src/types/SASjsConfig.ts +10 -4
- package/src/utils/createAxiosInstance.ts +7 -0
- package/src/utils/getValidJson.ts +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/parseWeboutResponse.ts +1 -1
- package/test/RequestClient.spec.d.ts +1 -0
- package/test/SAS_server_app.d.ts +10 -0
- package/types/ExecuteScript.d.ts +0 -1
- package/types/SASjsConfig.d.ts +11 -4
- package/utils/createAxiosInstance.d.ts +3 -0
- package/utils/getValidJson.d.ts +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/parseViyaDebugResponse.d.ts +1 -1
- package/CHANGELOG.md +0 -213
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as https from 'https';
|
|
1
3
|
import { ServerType } from '@sasjs/utils/types';
|
|
2
4
|
import { BaseJobExecutor } from './JobExecutor';
|
|
5
|
+
import { RequestClient } from '../request/RequestClient';
|
|
3
6
|
/**
|
|
4
7
|
* Job executor for SAS9 servers for use in Node.js environments.
|
|
5
8
|
* Initiates login with the provided username and password from the config
|
|
@@ -9,10 +12,8 @@ import { BaseJobExecutor } from './JobExecutor';
|
|
|
9
12
|
export declare class Sas9JobExecutor extends BaseJobExecutor {
|
|
10
13
|
private jobsPath;
|
|
11
14
|
private requestClient;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
etag: string;
|
|
16
|
-
}>;
|
|
15
|
+
private sas9RequestClient;
|
|
16
|
+
constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient, httpsAgentOptions?: https.AgentOptions);
|
|
17
|
+
execute(sasJob: string, data: any, config: any): Promise<any>;
|
|
17
18
|
private getRequestParams;
|
|
18
19
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { AxiosInstance, AxiosResponse } from 'axios';
|
|
3
|
+
import * as https from 'https';
|
|
2
4
|
import { CsrfToken } from '..';
|
|
3
5
|
import { SASjsRequest } from '../types';
|
|
4
6
|
export interface HttpClient {
|
|
@@ -34,8 +36,8 @@ export declare class RequestClient implements HttpClient {
|
|
|
34
36
|
protected csrfToken: CsrfToken;
|
|
35
37
|
protected fileUploadCsrfToken: CsrfToken | undefined;
|
|
36
38
|
protected httpClient: AxiosInstance;
|
|
37
|
-
constructor(baseUrl: string,
|
|
38
|
-
setConfig(baseUrl: string,
|
|
39
|
+
constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions);
|
|
40
|
+
setConfig(baseUrl: string, httpsAgentOptions?: https.AgentOptions): void;
|
|
39
41
|
getCsrfToken(type?: 'general' | 'file'): CsrfToken | undefined;
|
|
40
42
|
clearCsrfTokens(): void;
|
|
41
43
|
getBaseUrl(): string;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as https from 'https';
|
|
1
3
|
import { RequestClient } from './RequestClient';
|
|
2
4
|
/**
|
|
3
5
|
* Specific request client for SAS9 in Node.js environments.
|
|
4
6
|
* Handles redirects and cookie management.
|
|
5
7
|
*/
|
|
6
8
|
export declare class Sas9RequestClient extends RequestClient {
|
|
7
|
-
constructor(baseUrl: string,
|
|
9
|
+
constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions);
|
|
8
10
|
login(username: string, password: string, jobsPath: string): Promise<void>;
|
|
9
11
|
get<T>(url: string, accessToken: string | undefined, contentType?: string, overrideHeaders?: {
|
|
10
12
|
[key: string]: string | number;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as https from 'https';
|
|
1
3
|
import { ServerType } from '@sasjs/utils/types';
|
|
2
4
|
/**
|
|
3
5
|
* Specifies the configuration for the SASjs instance - eg where and how to
|
|
@@ -10,6 +12,11 @@ export declare class SASjsConfig {
|
|
|
10
12
|
* streamed.
|
|
11
13
|
*/
|
|
12
14
|
serverUrl: string;
|
|
15
|
+
/**
|
|
16
|
+
* The location of the STP Process Web Application. By default the adapter
|
|
17
|
+
* will use '/SASjsApi/stp/execute' on SAS JS.
|
|
18
|
+
*/
|
|
19
|
+
pathSASJS?: string;
|
|
13
20
|
/**
|
|
14
21
|
* The location of the Stored Process Web Application. By default the adapter
|
|
15
22
|
* will use '/SASStoredProcess/do' on SAS 9.
|
|
@@ -53,11 +60,11 @@ export declare class SASjsConfig {
|
|
|
53
60
|
*/
|
|
54
61
|
useComputeApi: boolean | null;
|
|
55
62
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
63
|
+
* Optional settings to configure HTTPS Agent.
|
|
64
|
+
* By providing `key`, `cert`, `ca` to connect with server
|
|
65
|
+
* Other options can be set `rejectUnauthorized` and `requestCert`
|
|
59
66
|
*/
|
|
60
|
-
|
|
67
|
+
httpsAgentOptions?: https.AgentOptions;
|
|
61
68
|
/**
|
|
62
69
|
* Supported login mechanisms are - Redirected and Default
|
|
63
70
|
*/
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* if string passed then parse the string to json else if throw error for all other types unless it is not a valid json object.
|
|
3
3
|
* @param str - string to check.
|
|
4
4
|
*/
|
|
5
|
-
export declare const getValidJson: (str: string | object) =>
|
|
5
|
+
export declare const getValidJson: (str: string | object) => object;
|
package/node/utils/index.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ import { RequestClient } from '../request/RequestClient';
|
|
|
9
9
|
* @param serverUrl
|
|
10
10
|
* @returns
|
|
11
11
|
*/
|
|
12
|
-
export declare const parseSasViyaDebugResponse: (response: string, requestClient: RequestClient, serverUrl: string) => Promise<
|
|
12
|
+
export declare const parseSasViyaDebugResponse: (response: string, requestClient: RequestClient, serverUrl: string) => Promise<object>;
|
package/package.json
CHANGED
|
@@ -41,30 +41,34 @@
|
|
|
41
41
|
"license": "ISC",
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/axios": "^0.14.0",
|
|
44
|
+
"@types/express": "^4.17.13",
|
|
44
45
|
"@types/form-data": "^2.5.0",
|
|
45
|
-
"@types/jest": "^27.0.
|
|
46
|
+
"@types/jest": "^27.0.2",
|
|
46
47
|
"@types/mime": "^2.0.3",
|
|
48
|
+
"@types/pem": "^1.9.6",
|
|
47
49
|
"@types/tough-cookie": "^4.0.1",
|
|
48
50
|
"copyfiles": "^2.4.1",
|
|
49
51
|
"cp": "^0.2.0",
|
|
50
52
|
"dotenv": "^10.0.0",
|
|
53
|
+
"express": "^4.17.1",
|
|
51
54
|
"jest": "^27.2.0",
|
|
52
55
|
"jest-extended": "^0.11.5",
|
|
53
56
|
"node-polyfill-webpack-plugin": "^1.1.4",
|
|
54
57
|
"path": "^0.12.7",
|
|
58
|
+
"pem": "^1.14.4",
|
|
55
59
|
"process": "^0.11.10",
|
|
56
60
|
"rimraf": "^3.0.2",
|
|
57
|
-
"semantic-release": "^
|
|
61
|
+
"semantic-release": "^18.0.0",
|
|
58
62
|
"terser-webpack-plugin": "^5.2.4",
|
|
59
63
|
"ts-jest": "^27.0.3",
|
|
60
|
-
"ts-loader": "^9.2.
|
|
64
|
+
"ts-loader": "^9.2.6",
|
|
61
65
|
"tslint": "^6.1.3",
|
|
62
66
|
"tslint-config-prettier": "^1.18.0",
|
|
63
|
-
"typedoc": "
|
|
67
|
+
"typedoc": "0.19.2",
|
|
64
68
|
"typedoc-neo-theme": "^1.1.1",
|
|
65
69
|
"typedoc-plugin-external-module-name": "^4.0.6",
|
|
66
70
|
"typescript": "4.3.5",
|
|
67
|
-
"webpack": "^5.
|
|
71
|
+
"webpack": "^5.56.0",
|
|
68
72
|
"webpack-cli": "^4.7.2"
|
|
69
73
|
},
|
|
70
74
|
"main": "index.js",
|
|
@@ -76,5 +80,5 @@
|
|
|
76
80
|
"https": "^1.0.0",
|
|
77
81
|
"tough-cookie": "^4.0.0"
|
|
78
82
|
},
|
|
79
|
-
"version": "
|
|
83
|
+
"version": "3.1.0"
|
|
80
84
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { AxiosInstance, AxiosResponse } from 'axios';
|
|
3
|
+
import * as https from 'https';
|
|
2
4
|
import { CsrfToken } from '..';
|
|
3
5
|
import { SASjsRequest } from '../types';
|
|
4
6
|
export interface HttpClient {
|
|
@@ -34,8 +36,8 @@ export declare class RequestClient implements HttpClient {
|
|
|
34
36
|
protected csrfToken: CsrfToken;
|
|
35
37
|
protected fileUploadCsrfToken: CsrfToken | undefined;
|
|
36
38
|
protected httpClient: AxiosInstance;
|
|
37
|
-
constructor(baseUrl: string,
|
|
38
|
-
setConfig(baseUrl: string,
|
|
39
|
+
constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions);
|
|
40
|
+
setConfig(baseUrl: string, httpsAgentOptions?: https.AgentOptions): void;
|
|
39
41
|
getCsrfToken(type?: 'general' | 'file'): CsrfToken | undefined;
|
|
40
42
|
clearCsrfTokens(): void;
|
|
41
43
|
getBaseUrl(): string;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as https from 'https';
|
|
1
3
|
import { RequestClient } from './RequestClient';
|
|
2
4
|
/**
|
|
3
5
|
* Specific request client for SAS9 in Node.js environments.
|
|
4
6
|
* Handles redirects and cookie management.
|
|
5
7
|
*/
|
|
6
8
|
export declare class Sas9RequestClient extends RequestClient {
|
|
7
|
-
constructor(baseUrl: string,
|
|
9
|
+
constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions);
|
|
8
10
|
login(username: string, password: string, jobsPath: string): Promise<void>;
|
|
9
11
|
get<T>(url: string, accessToken: string | undefined, contentType?: string, overrideHeaders?: {
|
|
10
12
|
[key: string]: string | number;
|
package/src/SAS9ApiClient.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as https from 'https'
|
|
1
2
|
import { generateTimestamp } from '@sasjs/utils/time'
|
|
2
3
|
import * as NodeFormData from 'form-data'
|
|
3
4
|
import { Sas9RequestClient } from './request/Sas9RequestClient'
|
|
@@ -13,10 +14,10 @@ export class SAS9ApiClient {
|
|
|
13
14
|
constructor(
|
|
14
15
|
private serverUrl: string,
|
|
15
16
|
private jobsPath: string,
|
|
16
|
-
|
|
17
|
+
httpsAgentOptions?: https.AgentOptions
|
|
17
18
|
) {
|
|
18
19
|
if (serverUrl) isUrl(serverUrl)
|
|
19
|
-
this.requestClient = new Sas9RequestClient(serverUrl,
|
|
20
|
+
this.requestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions)
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/**
|
package/src/SASjs.ts
CHANGED
|
@@ -33,6 +33,7 @@ import { LoginOptions, LoginResult } from './types/Login'
|
|
|
33
33
|
|
|
34
34
|
const defaultConfig: SASjsConfig = {
|
|
35
35
|
serverUrl: '',
|
|
36
|
+
pathSASJS: '/SASjsApi/stp/execute',
|
|
36
37
|
pathSAS9: '/SASStoredProcess/do',
|
|
37
38
|
pathSASViya: '/SASJobExecution',
|
|
38
39
|
appLoc: '/Public/seedapp',
|
|
@@ -40,7 +41,6 @@ const defaultConfig: SASjsConfig = {
|
|
|
40
41
|
debug: false,
|
|
41
42
|
contextName: 'SAS Job Execution compute context',
|
|
42
43
|
useComputeApi: null,
|
|
43
|
-
allowInsecureRequests: false,
|
|
44
44
|
loginMechanism: LoginMechanism.Default
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -62,7 +62,7 @@ export default class SASjs {
|
|
|
62
62
|
private jesJobExecutor: JobExecutor | null = null
|
|
63
63
|
private sas9JobExecutor: JobExecutor | null = null
|
|
64
64
|
|
|
65
|
-
constructor(config?:
|
|
65
|
+
constructor(config?: Partial<SASjsConfig>) {
|
|
66
66
|
this.sasjsConfig = {
|
|
67
67
|
...defaultConfig,
|
|
68
68
|
...config
|
|
@@ -528,10 +528,11 @@ export default class SASjs {
|
|
|
528
528
|
|
|
529
529
|
/**
|
|
530
530
|
* Checks whether a session is active, or login is required.
|
|
531
|
+
* @param accessToken - an optional access token is required for SASjs server type.
|
|
531
532
|
* @returns - a promise which resolves with an object containing two values - a boolean `isLoggedIn`, and a string `userName`.
|
|
532
533
|
*/
|
|
533
|
-
public async checkSession() {
|
|
534
|
-
return this.authManager!.checkSession()
|
|
534
|
+
public async checkSession(accessToken?: string) {
|
|
535
|
+
return this.authManager!.checkSession(accessToken)
|
|
535
536
|
}
|
|
536
537
|
|
|
537
538
|
/**
|
|
@@ -564,9 +565,10 @@ export default class SASjs {
|
|
|
564
565
|
|
|
565
566
|
/**
|
|
566
567
|
* Logs out of the configured SAS server.
|
|
568
|
+
* @param accessToken - an optional access token is required for SASjs server type.
|
|
567
569
|
*/
|
|
568
|
-
public logOut() {
|
|
569
|
-
return this.authManager!.logOut()
|
|
570
|
+
public logOut(accessToken?: string) {
|
|
571
|
+
return this.authManager!.logOut(accessToken)
|
|
570
572
|
}
|
|
571
573
|
|
|
572
574
|
/**
|
|
@@ -797,7 +799,7 @@ export default class SASjs {
|
|
|
797
799
|
sasApiClient = new SAS9ApiClient(
|
|
798
800
|
serverUrl,
|
|
799
801
|
this.jobsPath,
|
|
800
|
-
this.sasjsConfig.
|
|
802
|
+
this.sasjsConfig.httpsAgentOptions
|
|
801
803
|
)
|
|
802
804
|
}
|
|
803
805
|
} else {
|
|
@@ -964,19 +966,21 @@ export default class SASjs {
|
|
|
964
966
|
if (!this.requestClient) {
|
|
965
967
|
this.requestClient = new RequestClient(
|
|
966
968
|
this.sasjsConfig.serverUrl,
|
|
967
|
-
this.sasjsConfig.
|
|
969
|
+
this.sasjsConfig.httpsAgentOptions
|
|
968
970
|
)
|
|
969
971
|
} else {
|
|
970
972
|
this.requestClient.setConfig(
|
|
971
973
|
this.sasjsConfig.serverUrl,
|
|
972
|
-
this.sasjsConfig.
|
|
974
|
+
this.sasjsConfig.httpsAgentOptions
|
|
973
975
|
)
|
|
974
976
|
}
|
|
975
977
|
|
|
976
978
|
this.jobsPath =
|
|
977
979
|
this.sasjsConfig.serverType === ServerType.SasViya
|
|
978
980
|
? this.sasjsConfig.pathSASViya
|
|
979
|
-
: this.sasjsConfig.
|
|
981
|
+
: this.sasjsConfig.serverType === ServerType.Sas9
|
|
982
|
+
? this.sasjsConfig.pathSAS9
|
|
983
|
+
: this.sasjsConfig.pathSASJS || ''
|
|
980
984
|
|
|
981
985
|
this.authManager = new AuthManager(
|
|
982
986
|
this.sasjsConfig.serverUrl,
|
|
@@ -1010,7 +1014,7 @@ export default class SASjs {
|
|
|
1010
1014
|
this.sas9ApiClient = new SAS9ApiClient(
|
|
1011
1015
|
this.sasjsConfig.serverUrl,
|
|
1012
1016
|
this.jobsPath,
|
|
1013
|
-
this.sasjsConfig.
|
|
1017
|
+
this.sasjsConfig.httpsAgentOptions
|
|
1014
1018
|
)
|
|
1015
1019
|
}
|
|
1016
1020
|
}
|
|
@@ -1045,7 +1049,8 @@ export default class SASjs {
|
|
|
1045
1049
|
this.sasjsConfig.serverUrl,
|
|
1046
1050
|
this.sasjsConfig.serverType!,
|
|
1047
1051
|
this.jobsPath,
|
|
1048
|
-
this.
|
|
1052
|
+
this.requestClient,
|
|
1053
|
+
this.sasjsConfig.httpsAgentOptions
|
|
1049
1054
|
)
|
|
1050
1055
|
|
|
1051
1056
|
this.computeJobExecutor = new ComputeJobExecutor(
|
package/src/auth/AuthManager.ts
CHANGED
|
@@ -21,7 +21,9 @@ export class AuthManager {
|
|
|
21
21
|
this.logoutUrl =
|
|
22
22
|
this.serverType === ServerType.Sas9
|
|
23
23
|
? '/SASLogon/logout?'
|
|
24
|
-
:
|
|
24
|
+
: this.serverType === ServerType.SasViya
|
|
25
|
+
? '/SASLogon/logout.do?'
|
|
26
|
+
: '/SASjsApi/auth/logout'
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -180,20 +182,21 @@ export class AuthManager {
|
|
|
180
182
|
|
|
181
183
|
/**
|
|
182
184
|
* Checks whether a session is active, or login is required.
|
|
185
|
+
* @param accessToken - an optional access token is required for SASjs server type.
|
|
183
186
|
* @returns - a promise which resolves with an object containing three values
|
|
184
187
|
* - a boolean `isLoggedIn`
|
|
185
188
|
* - a string `userName` and
|
|
186
189
|
* - a form `loginForm` if not loggedin.
|
|
187
190
|
*/
|
|
188
|
-
public async checkSession(): Promise<{
|
|
191
|
+
public async checkSession(accessToken?: string): Promise<{
|
|
189
192
|
isLoggedIn: boolean
|
|
190
193
|
userName: string
|
|
191
194
|
loginForm?: any
|
|
192
195
|
}> {
|
|
193
|
-
const { isLoggedIn, userName } = await this.fetchUserName()
|
|
196
|
+
const { isLoggedIn, userName } = await this.fetchUserName(accessToken)
|
|
194
197
|
let loginForm = null
|
|
195
198
|
|
|
196
|
-
if (!isLoggedIn) {
|
|
199
|
+
if (!isLoggedIn && this.serverType !== ServerType.Sasjs) {
|
|
197
200
|
//We will logout to make sure cookies are removed and login form is presented
|
|
198
201
|
//Residue can happen in case of session expiration
|
|
199
202
|
await this.logOut()
|
|
@@ -218,19 +221,20 @@ export class AuthManager {
|
|
|
218
221
|
return await this.getLoginForm(formResponse)
|
|
219
222
|
}
|
|
220
223
|
|
|
221
|
-
private async fetchUserName(): Promise<{
|
|
224
|
+
private async fetchUserName(accessToken?: string): Promise<{
|
|
222
225
|
isLoggedIn: boolean
|
|
223
226
|
userName: string
|
|
224
227
|
}> {
|
|
225
|
-
//For VIYA we will send request on API endpoint. Which is faster then pinging SASJobExecution.
|
|
226
|
-
//For SAS9 we will send request on SASStoredProcess
|
|
227
228
|
const url =
|
|
228
229
|
this.serverType === ServerType.SasViya
|
|
229
230
|
? `${this.serverUrl}/identities/users/@currentUser`
|
|
230
|
-
:
|
|
231
|
+
: this.serverType === ServerType.Sas9
|
|
232
|
+
? `${this.serverUrl}/SASStoredProcess`
|
|
233
|
+
: `${this.serverUrl}/SASjsApi/session`
|
|
231
234
|
|
|
235
|
+
// Access token is required for server type `SASjs`
|
|
232
236
|
const { result: loginResponse } = await this.requestClient
|
|
233
|
-
.get<string>(url,
|
|
237
|
+
.get<string>(url, accessToken, 'text/plain')
|
|
234
238
|
.catch((err: any) => {
|
|
235
239
|
return { result: 'authErr' }
|
|
236
240
|
})
|
|
@@ -256,7 +260,12 @@ export class AuthManager {
|
|
|
256
260
|
.split(' ')
|
|
257
261
|
.map((name: string) => name.slice(0, 3).toLowerCase())
|
|
258
262
|
.join('')
|
|
263
|
+
|
|
264
|
+
case ServerType.Sasjs:
|
|
265
|
+
return response?.username
|
|
266
|
+
|
|
259
267
|
default:
|
|
268
|
+
console.error('Server Type not found in extractUserName function')
|
|
260
269
|
return ''
|
|
261
270
|
}
|
|
262
271
|
}
|
|
@@ -304,8 +313,12 @@ export class AuthManager {
|
|
|
304
313
|
|
|
305
314
|
/**
|
|
306
315
|
* Logs out of the configured SAS server.
|
|
316
|
+
* @param accessToken - an optional access token is required for SASjs server type.
|
|
307
317
|
*/
|
|
308
|
-
public logOut() {
|
|
318
|
+
public logOut(accessToken?: string) {
|
|
319
|
+
if (this.serverType === ServerType.Sasjs) {
|
|
320
|
+
return this.requestClient.post(this.logoutUrl, undefined, accessToken)
|
|
321
|
+
}
|
|
309
322
|
this.requestClient.clearCsrfTokens()
|
|
310
323
|
return this.requestClient.get(this.logoutUrl, undefined).then(() => true)
|
|
311
324
|
}
|
|
@@ -46,7 +46,7 @@ export async function getAccessToken(
|
|
|
46
46
|
)
|
|
47
47
|
.then((res) => res.result as SasAuthResponse)
|
|
48
48
|
.catch((err) => {
|
|
49
|
-
throw prefixMessage(err, 'Error while getting access token')
|
|
49
|
+
throw prefixMessage(err, 'Error while getting access token. ')
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
return authResponse
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import * as https from 'https'
|
|
1
2
|
import { ServerType } from '@sasjs/utils/types'
|
|
2
3
|
import * as NodeFormData from 'form-data'
|
|
3
4
|
import { ErrorResponse } from '../types/errors'
|
|
4
5
|
import { convertToCSV, isRelativePath } from '../utils'
|
|
5
6
|
import { BaseJobExecutor } from './JobExecutor'
|
|
6
7
|
import { Sas9RequestClient } from '../request/Sas9RequestClient'
|
|
8
|
+
import { RequestClient } from '../request/RequestClient'
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Job executor for SAS9 servers for use in Node.js environments.
|
|
@@ -12,15 +14,16 @@ import { Sas9RequestClient } from '../request/Sas9RequestClient'
|
|
|
12
14
|
* job execution requests.
|
|
13
15
|
*/
|
|
14
16
|
export class Sas9JobExecutor extends BaseJobExecutor {
|
|
15
|
-
private
|
|
17
|
+
private sas9RequestClient: Sas9RequestClient
|
|
16
18
|
constructor(
|
|
17
19
|
serverUrl: string,
|
|
18
20
|
serverType: ServerType,
|
|
19
21
|
private jobsPath: string,
|
|
20
|
-
|
|
22
|
+
private requestClient: RequestClient,
|
|
23
|
+
httpsAgentOptions?: https.AgentOptions
|
|
21
24
|
) {
|
|
22
25
|
super(serverUrl, serverType)
|
|
23
|
-
this.
|
|
26
|
+
this.sas9RequestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions)
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
async execute(sasJob: string, data: any, config: any) {
|
|
@@ -36,6 +39,8 @@ export class Sas9JobExecutor extends BaseJobExecutor {
|
|
|
36
39
|
: ''
|
|
37
40
|
}`
|
|
38
41
|
|
|
42
|
+
apiUrl = `${apiUrl}${config.debug ? '&_debug=131' : ''}`
|
|
43
|
+
|
|
39
44
|
let requestParams = {
|
|
40
45
|
...this.getRequestParams(config)
|
|
41
46
|
}
|
|
@@ -48,6 +53,8 @@ export class Sas9JobExecutor extends BaseJobExecutor {
|
|
|
48
53
|
} catch (e: any) {
|
|
49
54
|
return Promise.reject(new ErrorResponse(e?.message, e))
|
|
50
55
|
}
|
|
56
|
+
} else {
|
|
57
|
+
data = ''
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
for (const key in requestParams) {
|
|
@@ -56,16 +63,18 @@ export class Sas9JobExecutor extends BaseJobExecutor {
|
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
await this.
|
|
66
|
+
await this.sas9RequestClient.login(
|
|
60
67
|
config.username,
|
|
61
68
|
config.password,
|
|
62
69
|
this.jobsPath
|
|
63
70
|
)
|
|
71
|
+
|
|
64
72
|
const contentType =
|
|
65
73
|
data && Object.keys(data).length
|
|
66
74
|
? 'multipart/form-data; boundary=' + (formData as any)._boundary
|
|
67
75
|
: 'text/plain'
|
|
68
|
-
|
|
76
|
+
|
|
77
|
+
return await this.sas9RequestClient!.post(
|
|
69
78
|
apiUrl,
|
|
70
79
|
formData,
|
|
71
80
|
undefined,
|
|
@@ -75,6 +84,28 @@ export class Sas9JobExecutor extends BaseJobExecutor {
|
|
|
75
84
|
Connection: 'Keep-Alive'
|
|
76
85
|
}
|
|
77
86
|
)
|
|
87
|
+
.then((res: any) => {
|
|
88
|
+
let resString = res
|
|
89
|
+
|
|
90
|
+
if (typeof res === 'object') {
|
|
91
|
+
resString = JSON.stringify(res)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.requestClient!.appendRequest(resString, sasJob, config.debug)
|
|
95
|
+
|
|
96
|
+
return res
|
|
97
|
+
})
|
|
98
|
+
.catch((err: any) => {
|
|
99
|
+
let errString = err
|
|
100
|
+
|
|
101
|
+
if (typeof err === 'object') {
|
|
102
|
+
errString = JSON.stringify(errString)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.requestClient!.appendRequest(errString, sasJob, config.debug)
|
|
106
|
+
|
|
107
|
+
return err
|
|
108
|
+
})
|
|
78
109
|
}
|
|
79
110
|
|
|
80
111
|
private getRequestParams(config: any): any {
|
|
@@ -15,7 +15,8 @@ import { SASViyaApiClient } from '../SASViyaApiClient'
|
|
|
15
15
|
import {
|
|
16
16
|
isRelativePath,
|
|
17
17
|
parseSasViyaDebugResponse,
|
|
18
|
-
appendExtraResponseAttributes
|
|
18
|
+
appendExtraResponseAttributes,
|
|
19
|
+
getValidJson
|
|
19
20
|
} from '../utils'
|
|
20
21
|
import { BaseJobExecutor } from './JobExecutor'
|
|
21
22
|
import { parseWeboutResponse } from '../utils/parseWeboutResponse'
|
|
@@ -113,6 +114,7 @@ export class WebJobExecutor extends BaseJobExecutor {
|
|
|
113
114
|
const stringifiedData = JSON.stringify(data)
|
|
114
115
|
if (
|
|
115
116
|
config.serverType === ServerType.Sas9 ||
|
|
117
|
+
config.serverType === ServerType.Sasjs ||
|
|
116
118
|
stringifiedData.length > 500000 ||
|
|
117
119
|
stringifiedData.includes(';')
|
|
118
120
|
) {
|
|
@@ -142,12 +144,25 @@ export class WebJobExecutor extends BaseJobExecutor {
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
const requestPromise = new Promise((resolve, reject) => {
|
|
145
|
-
|
|
147
|
+
// Access token is required for server type `SASjs`
|
|
148
|
+
this.requestClient!.post(apiUrl, formData, authConfig?.access_token)
|
|
146
149
|
.then(async (res: any) => {
|
|
147
|
-
|
|
150
|
+
const resObj =
|
|
151
|
+
this.serverType === ServerType.Sasjs
|
|
152
|
+
? {
|
|
153
|
+
result: res.result._webout,
|
|
154
|
+
log: res.result.log
|
|
155
|
+
}
|
|
156
|
+
: res
|
|
157
|
+
this.requestClient!.appendRequest(resObj, sasJob, config.debug)
|
|
148
158
|
|
|
149
159
|
let jsonResponse = res.result
|
|
150
160
|
|
|
161
|
+
if (this.serverType === ServerType.Sasjs) {
|
|
162
|
+
const webout = parseWeboutResponse(res.result._webout, apiUrl)
|
|
163
|
+
jsonResponse = getValidJson(webout)
|
|
164
|
+
}
|
|
165
|
+
|
|
151
166
|
if (config.debug) {
|
|
152
167
|
switch (this.serverType) {
|
|
153
168
|
case ServerType.SasViya:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
|
|
2
|
+
import * as https from 'https'
|
|
2
3
|
import { CsrfToken } from '..'
|
|
3
4
|
import { isAuthorizeFormRequired, isLogInRequired } from '../auth'
|
|
4
5
|
import {
|
|
@@ -12,7 +13,11 @@ import { SASjsRequest } from '../types'
|
|
|
12
13
|
import { parseWeboutResponse } from '../utils/parseWeboutResponse'
|
|
13
14
|
import { prefixMessage } from '@sasjs/utils/error'
|
|
14
15
|
import { SAS9AuthError } from '../types/errors/SAS9AuthError'
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
parseGeneratedCode,
|
|
18
|
+
parseSourceCode,
|
|
19
|
+
createAxiosInstance
|
|
20
|
+
} from '../utils'
|
|
16
21
|
|
|
17
22
|
export interface HttpClient {
|
|
18
23
|
get<T>(
|
|
@@ -54,12 +59,15 @@ export class RequestClient implements HttpClient {
|
|
|
54
59
|
protected fileUploadCsrfToken: CsrfToken | undefined
|
|
55
60
|
protected httpClient!: AxiosInstance
|
|
56
61
|
|
|
57
|
-
constructor(
|
|
58
|
-
|
|
62
|
+
constructor(
|
|
63
|
+
protected baseUrl: string,
|
|
64
|
+
httpsAgentOptions?: https.AgentOptions
|
|
65
|
+
) {
|
|
66
|
+
this.createHttpClient(baseUrl, httpsAgentOptions)
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
public setConfig(baseUrl: string,
|
|
62
|
-
this.createHttpClient(baseUrl,
|
|
69
|
+
public setConfig(baseUrl: string, httpsAgentOptions?: https.AgentOptions) {
|
|
70
|
+
this.createHttpClient(baseUrl, httpsAgentOptions)
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
public getCsrfToken(type: 'general' | 'file' = 'general') {
|
|
@@ -511,20 +519,15 @@ export class RequestClient implements HttpClient {
|
|
|
511
519
|
return responseToReturn
|
|
512
520
|
}
|
|
513
521
|
|
|
514
|
-
private createHttpClient(
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
} else {
|
|
524
|
-
this.httpClient = axios.create({
|
|
525
|
-
baseURL: baseUrl
|
|
526
|
-
})
|
|
527
|
-
}
|
|
522
|
+
private createHttpClient(
|
|
523
|
+
baseUrl: string,
|
|
524
|
+
httpsAgentOptions?: https.AgentOptions
|
|
525
|
+
) {
|
|
526
|
+
const httpsAgent = httpsAgentOptions
|
|
527
|
+
? new https.Agent(httpsAgentOptions)
|
|
528
|
+
: undefined
|
|
529
|
+
|
|
530
|
+
this.httpClient = createAxiosInstance(baseUrl, httpsAgent)
|
|
528
531
|
|
|
529
532
|
this.httpClient.defaults.validateStatus = (status) =>
|
|
530
533
|
status >= 200 && status < 401
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as https from 'https'
|
|
1
2
|
import { AxiosRequestConfig } from 'axios'
|
|
2
3
|
import axiosCookieJarSupport from 'axios-cookiejar-support'
|
|
3
4
|
import * as tough from 'tough-cookie'
|
|
@@ -9,8 +10,8 @@ import { RequestClient, throwIfError } from './RequestClient'
|
|
|
9
10
|
* Handles redirects and cookie management.
|
|
10
11
|
*/
|
|
11
12
|
export class Sas9RequestClient extends RequestClient {
|
|
12
|
-
constructor(baseUrl: string,
|
|
13
|
-
super(baseUrl,
|
|
13
|
+
constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions) {
|
|
14
|
+
super(baseUrl, httpsAgentOptions)
|
|
14
15
|
this.httpClient.defaults.maxRedirects = 0
|
|
15
16
|
this.httpClient.defaults.validateStatus = (status) =>
|
|
16
17
|
status >= 200 && status < 303
|