@sasjs/adapter 3.8.3 → 3.9.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.
@@ -0,0 +1,3 @@
1
+ export declare class CertificateError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -1,13 +1,14 @@
1
1
  export * from './AuthorizeError';
2
+ export * from './CertificateError';
2
3
  export * from './ComputeJobExecutionError';
4
+ export * from './ErrorResponse';
3
5
  export * from './InternalServerError';
6
+ export * from './InvalidJsonError';
4
7
  export * from './JobExecutionError';
5
8
  export * from './JobStatePollError';
9
+ export * from './JsonParseArrayError';
6
10
  export * from './LoginRequiredError';
7
- export * from './NotFoundError';
8
- export * from './ErrorResponse';
9
11
  export * from './NoSessionStateError';
12
+ export * from './NotFoundError';
10
13
  export * from './RootFolderNotFoundError';
11
- export * from './JsonParseArrayError';
12
14
  export * from './WeboutResponseError';
13
- export * from './InvalidJsonError';
package/package.json CHANGED
@@ -79,5 +79,5 @@
79
79
  "https": "1.0.0",
80
80
  "tough-cookie": "4.0.0"
81
81
  },
82
- "version": "3.8.3"
82
+ "version": "3.9.0"
83
83
  }
@@ -11,7 +11,11 @@ import {
11
11
  JobDefinition,
12
12
  PollOptions
13
13
  } from './types'
14
- import { JobExecutionError, RootFolderNotFoundError } from './types/errors'
14
+ import {
15
+ CertificateError,
16
+ JobExecutionError,
17
+ RootFolderNotFoundError
18
+ } from './types/errors'
15
19
  import { SessionManager } from './SessionManager'
16
20
  import { ContextManager } from './ContextManager'
17
21
  import { SasAuthResponse, MacroVar, AuthConfig } from '@sasjs/utils/types'
@@ -878,7 +882,8 @@ export class SASViyaApiClient {
878
882
 
879
883
  const { result: folder } = await this.requestClient
880
884
  .get<Folder>(`${this.serverUrl}${url}`, accessToken)
881
- .catch(() => {
885
+ .catch((err) => {
886
+ if (err instanceof CertificateError) throw err
882
887
  return { result: null }
883
888
  })
884
889
 
@@ -899,7 +904,8 @@ export class SASViyaApiClient {
899
904
 
900
905
  const { result: folder } = await this.requestClient
901
906
  .get<Folder>(`${this.serverUrl}${url}`, accessToken)
902
- .catch(() => {
907
+ .catch((err) => {
908
+ if (err instanceof CertificateError) throw err
903
909
  return { result: null }
904
910
  })
905
911
 
package/src/SASjs.ts CHANGED
@@ -77,7 +77,7 @@ export default class SASjs {
77
77
  }
78
78
 
79
79
  /**
80
- * Executes code against a SAS 9 server. Requires a runner to be present in
80
+ * Executes SAS code on a SAS 9 server. Requires a runner to be present in
81
81
  * the users home directory in metadata.
82
82
  * @param linesOfCode - lines of sas code from the file to run.
83
83
  * @param username - a string representing the username.
@@ -97,6 +97,17 @@ export default class SASjs {
97
97
  )
98
98
  }
99
99
 
100
+ /**
101
+ * Executes SAS code on a SASJS server
102
+ * @param code - a string of code from the file to run.
103
+ * @param authConfig - (optional) a valid client, secret, refresh and access tokens that are authorised to execute scripts.
104
+ */
105
+ public async executeScriptSASjs(code: string, authConfig?: AuthConfig) {
106
+ this.isMethodSupported('executeScriptSASJS', [ServerType.Sasjs])
107
+
108
+ return await this.sasJSApiClient?.executeScript(code, authConfig)
109
+ }
110
+
100
111
  /**
101
112
  * Executes sas code in a SAS Viya compute session.
102
113
  * @param fileName - name of the file to run. It will be converted to path to the file being submitted for execution.
@@ -60,6 +60,28 @@ export class SASjsApiClient {
60
60
  return Promise.resolve(result)
61
61
  }
62
62
 
63
+ /**
64
+ * Executes code on a SASJS server.
65
+ * @param serverUrl - a server url to execute code.
66
+ * @param code - a string of code to execute.
67
+ */
68
+ public async executeScript(code: string, authConfig?: AuthConfig) {
69
+ let access_token = (authConfig || {}).access_token
70
+ if (authConfig) {
71
+ ;({ access_token } = await getTokens(
72
+ this.requestClient,
73
+ authConfig,
74
+ ServerType.Sasjs
75
+ ))
76
+ }
77
+ const response = await this.requestClient.post(
78
+ 'SASjsApi/code/execute',
79
+ { code },
80
+ access_token
81
+ )
82
+ return response.result as string
83
+ }
84
+
63
85
  /**
64
86
  * Exchanges the auth code for an access token for the given client.
65
87
  * @param clientId - the client ID to authenticate with.
@@ -1,6 +1,7 @@
1
1
  import { SasAuthResponse } from '@sasjs/utils/types'
2
2
  import { prefixMessage } from '@sasjs/utils/error'
3
3
  import { RequestClient } from '../request/RequestClient'
4
+ import { CertificateError } from '../types/errors'
4
5
 
5
6
  /**
6
7
  * Exchanges the auth code for an access token for the given client.
@@ -36,6 +37,7 @@ export async function getAccessTokenForViya(
36
37
  .post(url, data, undefined, 'application/x-www-form-urlencoded', headers)
37
38
  .then((res) => res.result as SasAuthResponse)
38
39
  .catch((err) => {
40
+ if (err instanceof CertificateError) throw err
39
41
  throw prefixMessage(err, 'Error while getting access token. ')
40
42
  })
41
43
 
@@ -99,7 +99,20 @@ export class FileUploader extends BaseJobExecutor {
99
99
  ? parseWeboutResponse(res.result, uploadUrl)
100
100
  : res.result
101
101
  break
102
+ case ServerType.Sasjs:
103
+ if (typeof res.result._webout === 'object') {
104
+ jsonResponse = res.result._webout
105
+ } else {
106
+ const webout = parseWeboutResponse(
107
+ res.result._webout,
108
+ uploadUrl
109
+ )
110
+ jsonResponse = getValidJson(webout)
111
+ }
112
+ break
102
113
  }
114
+ } else if (this.serverType === ServerType.Sasjs) {
115
+ jsonResponse = getValidJson(res.result._webout)
103
116
  } else {
104
117
  jsonResponse =
105
118
  typeof res.result === 'string'
@@ -7,7 +7,8 @@ import {
7
7
  LoginRequiredError,
8
8
  NotFoundError,
9
9
  InternalServerError,
10
- JobExecutionError
10
+ JobExecutionError,
11
+ CertificateError
11
12
  } from '../types/errors'
12
13
  import { SASjsRequest } from '../types'
13
14
  import { parseWeboutResponse } from '../utils/parseWeboutResponse'
@@ -131,6 +132,26 @@ export class RequestClient implements HttpClient {
131
132
  } else {
132
133
  sasWork = response.log
133
134
  }
135
+ } else if (response?.result?.log) {
136
+ //In this scenario we know we got the response from SASJS server
137
+ //Log is array of `{ line: '' }` so we need to convert it back to text
138
+ //To be able to parse it with current functions.
139
+ let log: string = ''
140
+
141
+ if (typeof log !== 'string') {
142
+ log = response.result.log
143
+ .map((logLine: any) => logLine.line)
144
+ .join('\n')
145
+ }
146
+
147
+ sourceCode = parseSourceCode(log)
148
+ generatedCode = parseGeneratedCode(log)
149
+
150
+ if (response?.result?._webout) {
151
+ sasWork = response.result._webout.WORK
152
+ } else {
153
+ sasWork = log
154
+ }
134
155
  } else if (response?.result) {
135
156
  sourceCode = parseSourceCode(response.result)
136
157
  generatedCode = parseGeneratedCode(response.result)
@@ -497,6 +518,10 @@ export class RequestClient implements HttpClient {
497
518
  else return
498
519
  }
499
520
 
521
+ if (e.isAxiosError && e.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {
522
+ throw new CertificateError(e.message)
523
+ }
524
+
500
525
  if (e.message) throw e
501
526
  else throw prefixMessage(e, 'Error while handling error. ')
502
527
  }
@@ -0,0 +1,12 @@
1
+ const instructionsToFix =
2
+ 'https://github.com/sasjs/cli/issues/1181#issuecomment-1090638584'
3
+
4
+ export class CertificateError extends Error {
5
+ constructor(message: string) {
6
+ super(
7
+ `${message}\nPlease visit the link below for further information on this issue:\n- ${instructionsToFix}\n`
8
+ )
9
+ this.name = 'CertificateError'
10
+ Object.setPrototypeOf(this, CertificateError.prototype)
11
+ }
12
+ }
@@ -1,13 +1,14 @@
1
1
  export * from './AuthorizeError'
2
+ export * from './CertificateError'
2
3
  export * from './ComputeJobExecutionError'
4
+ export * from './ErrorResponse'
3
5
  export * from './InternalServerError'
6
+ export * from './InvalidJsonError'
4
7
  export * from './JobExecutionError'
5
8
  export * from './JobStatePollError'
9
+ export * from './JsonParseArrayError'
6
10
  export * from './LoginRequiredError'
7
- export * from './NotFoundError'
8
- export * from './ErrorResponse'
9
11
  export * from './NoSessionStateError'
12
+ export * from './NotFoundError'
10
13
  export * from './RootFolderNotFoundError'
11
- export * from './JsonParseArrayError'
12
14
  export * from './WeboutResponseError'
13
- export * from './InvalidJsonError'
@@ -0,0 +1,3 @@
1
+ export declare class CertificateError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -1,13 +1,14 @@
1
1
  export * from './AuthorizeError';
2
+ export * from './CertificateError';
2
3
  export * from './ComputeJobExecutionError';
4
+ export * from './ErrorResponse';
3
5
  export * from './InternalServerError';
6
+ export * from './InvalidJsonError';
4
7
  export * from './JobExecutionError';
5
8
  export * from './JobStatePollError';
9
+ export * from './JsonParseArrayError';
6
10
  export * from './LoginRequiredError';
7
- export * from './NotFoundError';
8
- export * from './ErrorResponse';
9
11
  export * from './NoSessionStateError';
12
+ export * from './NotFoundError';
10
13
  export * from './RootFolderNotFoundError';
11
- export * from './JsonParseArrayError';
12
14
  export * from './WeboutResponseError';
13
- export * from './InvalidJsonError';