@sasjs/adapter 2.11.4 → 3.0.2

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 (48) hide show
  1. package/SAS9ApiClient.d.ts +3 -1
  2. package/SASViyaApiClient.d.ts +7 -1
  3. package/SASjs.d.ts +15 -2
  4. package/SASjsApiClient.d.ts +20 -0
  5. package/index.js +2 -2
  6. package/job-execution/Sas9JobExecutor.d.ts +6 -5
  7. package/node/SAS9ApiClient.d.ts +3 -1
  8. package/node/SASViyaApiClient.d.ts +7 -1
  9. package/node/SASjs.d.ts +15 -2
  10. package/node/SASjsApiClient.d.ts +20 -0
  11. package/node/index.js +2 -2
  12. package/node/job-execution/Sas9JobExecutor.d.ts +6 -5
  13. package/node/request/RequestClient.d.ts +4 -2
  14. package/node/request/Sas9RequestClient.d.ts +3 -1
  15. package/node/types/ExecuteScript.d.ts +4 -0
  16. package/node/types/FileTree.d.ts +18 -0
  17. package/node/types/SASjsConfig.d.ts +6 -4
  18. package/node/types/index.d.ts +2 -0
  19. package/node/utils/createAxiosInstance.d.ts +3 -0
  20. package/node/utils/index.d.ts +1 -0
  21. package/package.json +11 -7
  22. package/request/RequestClient.d.ts +4 -2
  23. package/request/Sas9RequestClient.d.ts +3 -1
  24. package/src/SAS9ApiClient.ts +3 -2
  25. package/src/SASjs.ts +39 -12
  26. package/src/SASjsApiClient.ts +39 -0
  27. package/src/auth/AuthManager.ts +4 -0
  28. package/src/auth/getAccessToken.ts +1 -1
  29. package/src/job-execution/Sas9JobExecutor.ts +36 -5
  30. package/src/request/RequestClient.ts +24 -21
  31. package/src/request/Sas9RequestClient.ts +3 -2
  32. package/src/test/SAS_server_app.ts +38 -0
  33. package/src/types/ExecuteScript.ts +4 -0
  34. package/src/types/FileTree.ts +47 -0
  35. package/src/types/SASjsConfig.ts +5 -4
  36. package/src/types/index.ts +2 -0
  37. package/src/utils/createAxiosInstance.ts +7 -0
  38. package/src/utils/index.ts +1 -0
  39. package/test/RequestClient.spec.d.ts +1 -0
  40. package/test/SAS_server_app.d.ts +10 -0
  41. package/types/ExecuteScript.d.ts +4 -0
  42. package/types/FileTree.d.ts +18 -0
  43. package/types/SASjsConfig.d.ts +6 -4
  44. package/types/index.d.ts +2 -0
  45. package/utils/createAxiosInstance.d.ts +3 -0
  46. package/utils/index.d.ts +1 -0
  47. package/.all-contributorsrc +0 -103
  48. 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
- constructor(serverUrl: string, serverType: ServerType, jobsPath: string, allowInsecureRequests: boolean);
13
- execute(sasJob: string, data: any, config: any): Promise<{
14
- result: unknown;
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, allowInsecure?: boolean);
38
- setConfig(baseUrl: string, allowInsecure?: boolean): void;
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, allowInsecure?: boolean);
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;
@@ -0,0 +1,4 @@
1
+ export interface ExecutionQuery {
2
+ _program: string;
3
+ _debug?: number;
4
+ }
@@ -0,0 +1,18 @@
1
+ export interface FileTree {
2
+ members: [FolderMember, ServiceMember];
3
+ }
4
+ export declare enum MemberType {
5
+ folder = "folder",
6
+ service = "service"
7
+ }
8
+ export interface FolderMember {
9
+ name: string;
10
+ type: MemberType.folder;
11
+ members: [FolderMember, ServiceMember];
12
+ }
13
+ export interface ServiceMember {
14
+ name: string;
15
+ type: MemberType.service;
16
+ code: string;
17
+ }
18
+ export declare const isFileTree: (arg: any) => arg is FileTree;
@@ -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
@@ -53,11 +55,11 @@ export declare class SASjsConfig {
53
55
  */
54
56
  useComputeApi: boolean | null;
55
57
  /**
56
- * Defaults to `false`.
57
- * When set to `true`, the adapter will allow requests to SAS servers that use a self-signed SSL certificate.
58
- * Changing this setting is not recommended.
58
+ * Optional settings to configure HTTPS Agent.
59
+ * By providing `key`, `cert`, `ca` to connect with server
60
+ * Other options can be set `rejectUnauthorized` and `requestCert`
59
61
  */
60
- allowInsecureRequests: boolean;
62
+ httpsAgentOptions?: https.AgentOptions;
61
63
  /**
62
64
  * Supported login mechanisms are - Redirected and Default
63
65
  */
@@ -12,3 +12,5 @@ export * from './Session';
12
12
  export * from './UploadFile';
13
13
  export * from './PollOptions';
14
14
  export * from './WriteStream';
15
+ export * from './FileTree';
16
+ export * from './ExecuteScript';
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import * as https from 'https';
3
+ export declare const createAxiosInstance: (baseURL: string, httpsAgent?: https.Agent | undefined) => import("axios").AxiosInstance;
@@ -1,6 +1,7 @@
1
1
  export * from './asyncForEach';
2
2
  export * from './compareTimestamps';
3
3
  export * from './convertToCsv';
4
+ export * from './createAxiosInstance';
4
5
  export * from './delay';
5
6
  export * from './isNode';
6
7
  export * from './isRelativePath';
package/package.json CHANGED
@@ -41,40 +41,44 @@
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.1",
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": "^17.4.7",
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.2",
64
+ "ts-loader": "^9.2.6",
61
65
  "tslint": "^6.1.3",
62
66
  "tslint-config-prettier": "^1.18.0",
63
- "typedoc": "^0.22.3",
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.52.1",
71
+ "webpack": "^5.56.0",
68
72
  "webpack-cli": "^4.7.2"
69
73
  },
70
74
  "main": "index.js",
71
75
  "dependencies": {
72
- "@sasjs/utils": "^2.30.0",
76
+ "@sasjs/utils": "^2.32.0",
73
77
  "axios": "^0.21.4",
74
78
  "axios-cookiejar-support": "^1.0.1",
75
79
  "form-data": "^4.0.0",
76
80
  "https": "^1.0.0",
77
81
  "tough-cookie": "^4.0.0"
78
82
  },
79
- "version": "2.11.4"
83
+ "version": "3.0.2"
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, allowInsecure?: boolean);
38
- setConfig(baseUrl: string, allowInsecure?: boolean): void;
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, allowInsecure?: boolean);
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,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
- allowInsecureRequests: boolean
17
+ httpsAgentOptions?: https.AgentOptions
17
18
  ) {
18
19
  if (serverUrl) isUrl(serverUrl)
19
- this.requestClient = new Sas9RequestClient(serverUrl, allowInsecureRequests)
20
+ this.requestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions)
20
21
  }
21
22
 
22
23
  /**
package/src/SASjs.ts CHANGED
@@ -4,10 +4,14 @@ import {
4
4
  UploadFile,
5
5
  EditContextInput,
6
6
  PollOptions,
7
- LoginMechanism
7
+ LoginMechanism,
8
+ FolderMember,
9
+ ServiceMember,
10
+ ExecutionQuery
8
11
  } from './types'
9
12
  import { SASViyaApiClient } from './SASViyaApiClient'
10
13
  import { SAS9ApiClient } from './SAS9ApiClient'
14
+ import { SASjsApiClient } from './SASjsApiClient'
11
15
  import { AuthManager } from './auth'
12
16
  import {
13
17
  ServerType,
@@ -36,7 +40,6 @@ const defaultConfig: SASjsConfig = {
36
40
  debug: false,
37
41
  contextName: 'SAS Job Execution compute context',
38
42
  useComputeApi: null,
39
- allowInsecureRequests: false,
40
43
  loginMechanism: LoginMechanism.Default
41
44
  }
42
45
 
@@ -49,6 +52,7 @@ export default class SASjs {
49
52
  private jobsPath: string = ''
50
53
  private sasViyaApiClient: SASViyaApiClient | null = null
51
54
  private sas9ApiClient: SAS9ApiClient | null = null
55
+ private SASjsApiClient: SASjsApiClient | null = null
52
56
  private fileUploader: FileUploader | null = null
53
57
  private authManager: AuthManager | null = null
54
58
  private requestClient: RequestClient | null = null
@@ -57,7 +61,7 @@ export default class SASjs {
57
61
  private jesJobExecutor: JobExecutor | null = null
58
62
  private sas9JobExecutor: JobExecutor | null = null
59
63
 
60
- constructor(config?: any) {
64
+ constructor(config?: Partial<SASjsConfig>) {
61
65
  this.sasjsConfig = {
62
66
  ...defaultConfig,
63
67
  ...config
@@ -792,7 +796,7 @@ export default class SASjs {
792
796
  sasApiClient = new SAS9ApiClient(
793
797
  serverUrl,
794
798
  this.jobsPath,
795
- this.sasjsConfig.allowInsecureRequests
799
+ this.sasjsConfig.httpsAgentOptions
796
800
  )
797
801
  }
798
802
  } else {
@@ -824,6 +828,14 @@ export default class SASjs {
824
828
  )
825
829
  }
826
830
 
831
+ public async deployToSASjs(members: [FolderMember, ServiceMember]) {
832
+ return await this.SASjsApiClient?.deploy(members, this.sasjsConfig.appLoc)
833
+ }
834
+
835
+ public async executeJobSASjs(query: ExecutionQuery) {
836
+ return await this.SASjsApiClient?.executeJob(query)
837
+ }
838
+
827
839
  /**
828
840
  * Kicks off execution of the given job via the compute API.
829
841
  * @returns an object representing the compute session created for the given job.
@@ -951,12 +963,12 @@ export default class SASjs {
951
963
  if (!this.requestClient) {
952
964
  this.requestClient = new RequestClient(
953
965
  this.sasjsConfig.serverUrl,
954
- this.sasjsConfig.allowInsecureRequests
966
+ this.sasjsConfig.httpsAgentOptions
955
967
  )
956
968
  } else {
957
969
  this.requestClient.setConfig(
958
970
  this.sasjsConfig.serverUrl,
959
- this.sasjsConfig.allowInsecureRequests
971
+ this.sasjsConfig.httpsAgentOptions
960
972
  )
961
973
  }
962
974
 
@@ -973,30 +985,44 @@ export default class SASjs {
973
985
  )
974
986
 
975
987
  if (this.sasjsConfig.serverType === ServerType.SasViya) {
976
- if (this.sasViyaApiClient)
988
+ if (this.sasViyaApiClient) {
977
989
  this.sasViyaApiClient!.setConfig(
978
990
  this.sasjsConfig.serverUrl,
979
991
  this.sasjsConfig.appLoc
980
992
  )
981
- else
993
+ } else {
982
994
  this.sasViyaApiClient = new SASViyaApiClient(
983
995
  this.sasjsConfig.serverUrl,
984
996
  this.sasjsConfig.appLoc,
985
997
  this.sasjsConfig.contextName,
986
998
  this.requestClient
987
999
  )
1000
+ }
988
1001
 
989
1002
  this.sasViyaApiClient.debug = this.sasjsConfig.debug
990
1003
  }
1004
+
991
1005
  if (this.sasjsConfig.serverType === ServerType.Sas9) {
992
- if (this.sas9ApiClient)
1006
+ if (this.sas9ApiClient) {
993
1007
  this.sas9ApiClient!.setConfig(this.sasjsConfig.serverUrl)
994
- else
1008
+ } else {
995
1009
  this.sas9ApiClient = new SAS9ApiClient(
996
1010
  this.sasjsConfig.serverUrl,
997
1011
  this.jobsPath,
998
- this.sasjsConfig.allowInsecureRequests
1012
+ this.sasjsConfig.httpsAgentOptions
999
1013
  )
1014
+ }
1015
+ }
1016
+
1017
+ if (this.sasjsConfig.serverType === ServerType.Sasjs) {
1018
+ if (this.SASjsApiClient) {
1019
+ this.SASjsApiClient.setConfig(this.sasjsConfig.serverUrl)
1020
+ } else {
1021
+ this.SASjsApiClient = new SASjsApiClient(
1022
+ this.sasjsConfig.serverUrl,
1023
+ this.requestClient
1024
+ )
1025
+ }
1000
1026
  }
1001
1027
 
1002
1028
  this.fileUploader = new FileUploader(
@@ -1018,7 +1044,8 @@ export default class SASjs {
1018
1044
  this.sasjsConfig.serverUrl,
1019
1045
  this.sasjsConfig.serverType!,
1020
1046
  this.jobsPath,
1021
- this.sasjsConfig.allowInsecureRequests
1047
+ this.requestClient,
1048
+ this.sasjsConfig.httpsAgentOptions
1022
1049
  )
1023
1050
 
1024
1051
  this.computeJobExecutor = new ComputeJobExecutor(
@@ -0,0 +1,39 @@
1
+ import { FolderMember, ServiceMember, ExecutionQuery } from './types'
2
+ import { RequestClient } from './request/RequestClient'
3
+
4
+ export class SASjsApiClient {
5
+ constructor(
6
+ private serverUrl: string,
7
+ private requestClient: RequestClient
8
+ ) {}
9
+
10
+ public setConfig(serverUrl: string) {
11
+ if (serverUrl) this.serverUrl = serverUrl
12
+ }
13
+
14
+ public async deploy(members: [FolderMember, ServiceMember], appLoc: string) {
15
+ const { result } = await this.requestClient.post<{
16
+ status: string
17
+ message: string
18
+ example?: {}
19
+ }>(
20
+ 'SASjsApi/drive/deploy',
21
+ { fileTree: members, appLoc: appLoc },
22
+ undefined
23
+ )
24
+
25
+ return Promise.resolve(result)
26
+ }
27
+
28
+ public async executeJob(query: ExecutionQuery) {
29
+ const { result } = await this.requestClient.post<{
30
+ status: string
31
+ message: string
32
+ log?: string
33
+ logPath?: string
34
+ error?: {}
35
+ }>('SASjsApi/stp/execute', query, undefined)
36
+
37
+ return Promise.resolve(result)
38
+ }
39
+ }
@@ -256,6 +256,10 @@ export class AuthManager {
256
256
  .split(' ')
257
257
  .map((name: string) => name.slice(0, 3).toLowerCase())
258
258
  .join('')
259
+
260
+ default:
261
+ console.error('Server Type not found in extractUserName function')
262
+ return ''
259
263
  }
260
264
  }
261
265
 
@@ -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 requestClient: Sas9RequestClient
17
+ private sas9RequestClient: Sas9RequestClient
16
18
  constructor(
17
19
  serverUrl: string,
18
20
  serverType: ServerType,
19
21
  private jobsPath: string,
20
- allowInsecureRequests: boolean
22
+ private requestClient: RequestClient,
23
+ httpsAgentOptions?: https.AgentOptions
21
24
  ) {
22
25
  super(serverUrl, serverType)
23
- this.requestClient = new Sas9RequestClient(serverUrl, allowInsecureRequests)
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.requestClient.login(
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
- return await this.requestClient!.post(
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 {
@@ -1,4 +1,5 @@
1
- import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
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 { parseGeneratedCode, parseSourceCode } from '../utils'
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(protected baseUrl: string, allowInsecure = false) {
58
- this.createHttpClient(baseUrl, allowInsecure)
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, allowInsecure = false) {
62
- this.createHttpClient(baseUrl, allowInsecure)
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,23 +519,18 @@ export class RequestClient implements HttpClient {
511
519
  return responseToReturn
512
520
  }
513
521
 
514
- private createHttpClient(baseUrl: string, allowInsecure = false) {
515
- const https = require('https')
516
- if (allowInsecure && https.Agent) {
517
- this.httpClient = axios.create({
518
- baseURL: baseUrl,
519
- httpsAgent: new https.Agent({
520
- rejectUnauthorized: !allowInsecure
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
- status >= 200 && status < 305
533
+ status >= 200 && status < 401
531
534
  }
532
535
  }
533
536
 
@@ -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, allowInsecure = false) {
13
- super(baseUrl, allowInsecure)
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
@@ -0,0 +1,38 @@
1
+ import express = require('express')
2
+
3
+ export const app = express()
4
+
5
+ export const mockedAuthResponse = {
6
+ access_token: 'access_token',
7
+ token_type: 'bearer',
8
+ id_token: 'id_token',
9
+ refresh_token: 'refresh_token',
10
+ expires_in: 43199,
11
+ scope: 'openid',
12
+ jti: 'jti'
13
+ }
14
+
15
+ app.get('/', function (req: any, res: any) {
16
+ res.send('Hello World')
17
+ })
18
+
19
+ app.post('/SASLogon/oauth/token', function (req: any, res: any) {
20
+ let valid = true
21
+ // capture the encoded form data
22
+ req.on('data', (data: any) => {
23
+ const resData = data.toString()
24
+
25
+ if (resData.includes('incorrect')) valid = false
26
+ })
27
+
28
+ // send a response when finished reading
29
+ // the encoded form data
30
+ req.on('end', () => {
31
+ if (valid) res.status(200).send(mockedAuthResponse)
32
+ else
33
+ res.status(401).send({
34
+ error: 'unauthorized',
35
+ error_description: 'Bad credentials'
36
+ })
37
+ })
38
+ })
@@ -0,0 +1,4 @@
1
+ export interface ExecutionQuery {
2
+ _program: string
3
+ _debug?: number
4
+ }