@sasjs/adapter 3.8.1 → 3.8.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.
@@ -12,5 +12,4 @@ export * from './Session';
12
12
  export * from './UploadFile';
13
13
  export * from './PollOptions';
14
14
  export * from './WriteStream';
15
- export * from './FileTree';
16
15
  export * from './ExecuteScript';
package/package.json CHANGED
@@ -72,12 +72,12 @@
72
72
  },
73
73
  "main": "index.js",
74
74
  "dependencies": {
75
- "@sasjs/utils": "2.40.0",
75
+ "@sasjs/utils": "2.42.0",
76
76
  "axios": "0.26.0",
77
77
  "axios-cookiejar-support": "1.0.1",
78
78
  "form-data": "4.0.0",
79
79
  "https": "1.0.0",
80
80
  "tough-cookie": "4.0.0"
81
81
  },
82
- "version": "3.8.1"
82
+ "version": "3.8.4"
83
83
  }
package/src/SASjs.ts CHANGED
@@ -5,8 +5,7 @@ import {
5
5
  EditContextInput,
6
6
  PollOptions,
7
7
  LoginMechanism,
8
- ExecutionQuery,
9
- FileTree
8
+ ExecutionQuery
10
9
  } from './types'
11
10
  import { SASViyaApiClient } from './SASViyaApiClient'
12
11
  import { SAS9ApiClient } from './SAS9ApiClient'
@@ -18,7 +17,7 @@ import {
18
17
  AuthConfig,
19
18
  ExtraResponseAttributes,
20
19
  SasAuthResponse,
21
- StreamConfig
20
+ ServicePackSASjs
22
21
  } from '@sasjs/utils/types'
23
22
  import { RequestClient } from './request/RequestClient'
24
23
  import { SasjsRequestClient } from './request/SasjsRequestClient'
@@ -889,27 +888,21 @@ export default class SASjs {
889
888
 
890
889
  /**
891
890
  * Creates the folders and services at the given location `appLoc` on the given server `serverUrl`.
892
- * @param members - the JSON specifying the folders and services to be created.
893
- * @param appLoc - the base folder in which to create the new folders and
894
- * services. If not provided, is taken from SASjsConfig.
895
- * @param streamConfig - optional configuration object of StreamConfig for deploying streaming app.
896
- * @param authConfig - a valid client, secret, refresh and access tokens that are authorised to execute compute jobs.
891
+ * @param dataJson - the JSON specifying the folders and files to be created, can also includes
892
+ * appLoc, streamServiceName, streamWebFolder, streamLogo
893
+ * @param appLoc - (optional) the base folder in which to create the new folders and
894
+ * services. If not provided, is taken from SASjsConfig. Precedence will be of appLoc present in dataJson.
895
+ * @param authConfig - (optional) a valid client, secret, refresh and access tokens that are authorised to execute compute jobs.
897
896
  */
898
897
  public async deployToSASjs(
899
- members: FileTree,
898
+ dataJson: ServicePackSASjs,
900
899
  appLoc?: string,
901
- streamConfig?: StreamConfig,
902
900
  authConfig?: AuthConfig
903
901
  ) {
904
902
  if (!appLoc) {
905
903
  appLoc = this.sasjsConfig.appLoc
906
904
  }
907
- return await this.sasJSApiClient?.deploy(
908
- members,
909
- appLoc,
910
- streamConfig,
911
- authConfig
912
- )
905
+ return await this.sasJSApiClient?.deploy(dataJson, appLoc, authConfig)
913
906
  }
914
907
 
915
908
  public async executeJobSASjs(query: ExecutionQuery) {
@@ -1102,13 +1095,8 @@ export default class SASjs {
1102
1095
  }
1103
1096
 
1104
1097
  if (this.sasjsConfig.serverType === ServerType.Sasjs) {
1105
- if (this.sasJSApiClient) {
1106
- this.sasJSApiClient.setConfig(this.sasjsConfig.serverUrl)
1107
- } else {
1108
- this.sasJSApiClient = new SASjsApiClient(
1109
- this.sasjsConfig.serverUrl,
1110
- this.requestClient
1111
- )
1098
+ if (!this.sasJSApiClient) {
1099
+ this.sasJSApiClient = new SASjsApiClient(this.requestClient)
1112
1100
  }
1113
1101
  }
1114
1102
 
@@ -1,5 +1,5 @@
1
- import { AuthConfig, ServerType, StreamConfig } from '@sasjs/utils/types'
2
- import { FileTree, ExecutionQuery } from './types'
1
+ import { AuthConfig, ServerType, ServicePackSASjs } from '@sasjs/utils/types'
2
+ import { ExecutionQuery } from './types'
3
3
  import { RequestClient } from './request/RequestClient'
4
4
  import { getAccessTokenForSasjs } from './auth/getAccessTokenForSasjs'
5
5
  import { refreshTokensForSasjs } from './auth/refreshTokensForSasjs'
@@ -8,19 +8,11 @@ import { parseWeboutResponse } from './utils'
8
8
  import { getTokens } from './auth/getTokens'
9
9
 
10
10
  export class SASjsApiClient {
11
- constructor(
12
- private serverUrl: string,
13
- private requestClient: RequestClient
14
- ) {}
15
-
16
- public setConfig(serverUrl: string) {
17
- if (serverUrl) this.serverUrl = serverUrl
18
- }
11
+ constructor(private requestClient: RequestClient) {}
19
12
 
20
13
  public async deploy(
21
- members: FileTree,
14
+ dataJson: ServicePackSASjs,
22
15
  appLoc: string,
23
- streamConfig?: StreamConfig,
24
16
  authConfig?: AuthConfig
25
17
  ) {
26
18
  let access_token = (authConfig || {}).access_token
@@ -31,6 +23,9 @@ export class SASjsApiClient {
31
23
  ServerType.Sasjs
32
24
  ))
33
25
  }
26
+
27
+ dataJson.appLoc = dataJson.appLoc || appLoc
28
+
34
29
  const { result } = await this.requestClient.post<{
35
30
  status: string
36
31
  message: string
@@ -38,13 +33,7 @@ export class SASjsApiClient {
38
33
  example?: {}
39
34
  }>(
40
35
  'SASjsApi/drive/deploy',
41
- {
42
- fileTree: members,
43
- appLoc: appLoc,
44
- streamServiceName: streamConfig?.streamServiceName,
45
- streamWebFolder: streamConfig?.streamWebFolder,
46
- streamLogo: streamConfig?.streamLogo
47
- },
36
+ dataJson,
48
37
  access_token,
49
38
  undefined,
50
39
  {},
@@ -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'
@@ -131,6 +131,26 @@ export class RequestClient implements HttpClient {
131
131
  } else {
132
132
  sasWork = response.log
133
133
  }
134
+ } else if (response?.result?.log) {
135
+ //In this scenario we know we got the response from SASJS server
136
+ //Log is array of `{ line: '' }` so we need to convert it back to text
137
+ //To be able to parse it with current functions.
138
+ let log: string = ''
139
+
140
+ if (typeof log !== 'string') {
141
+ log = response.result.log
142
+ .map((logLine: any) => logLine.line)
143
+ .join('\n')
144
+ }
145
+
146
+ sourceCode = parseSourceCode(log)
147
+ generatedCode = parseGeneratedCode(log)
148
+
149
+ if (response?.result?._webout) {
150
+ sasWork = response.result._webout.WORK
151
+ } else {
152
+ sasWork = log
153
+ }
134
154
  } else if (response?.result) {
135
155
  sourceCode = parseSourceCode(response.result)
136
156
  generatedCode = parseGeneratedCode(response.result)
@@ -12,5 +12,4 @@ export * from './Session'
12
12
  export * from './UploadFile'
13
13
  export * from './PollOptions'
14
14
  export * from './WriteStream'
15
- export * from './FileTree'
16
15
  export * from './ExecuteScript'
@@ -16,10 +16,15 @@ export const parseSasViyaDebugResponse = async (
16
16
  requestClient: RequestClient,
17
17
  serverUrl: string
18
18
  ) => {
19
+ // On viya 3.5, iframe is like <iframe style="width: 99%; height: 500px" src="..."></iframe>
20
+ // On viya 4, iframe is like <iframe style="width: 99%; height: 500px; background-color:Canvas;" src=...></iframe>
21
+
19
22
  const iframeStart = response.split(
20
- '<iframe style="width: 99%; height: 500px" src="'
23
+ /<iframe style="width: 99%; height: 500px" src="|<iframe style="width: 99%; height: 500px; background-color:Canvas;" src=/
21
24
  )[1]
22
- const jsonUrl = iframeStart ? iframeStart.split('"></iframe>')[0] : null
25
+ const jsonUrl = iframeStart
26
+ ? iframeStart.split(/"><\/iframe>|><\/iframe>/)[0]
27
+ : null
23
28
  if (!jsonUrl) {
24
29
  throw new Error('Unable to find webout file URL.')
25
30
  }
package/types/index.d.ts CHANGED
@@ -12,5 +12,4 @@ export * from './Session';
12
12
  export * from './UploadFile';
13
13
  export * from './PollOptions';
14
14
  export * from './WriteStream';
15
- export * from './FileTree';
16
15
  export * from './ExecuteScript';
@@ -1,18 +0,0 @@
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,47 +0,0 @@
1
- export interface FileTree {
2
- members: [FolderMember, ServiceMember]
3
- }
4
-
5
- export enum MemberType {
6
- folder = 'folder',
7
- service = 'service'
8
- }
9
-
10
- export interface FolderMember {
11
- name: string
12
- type: MemberType.folder
13
- members: [FolderMember, ServiceMember]
14
- }
15
-
16
- export interface ServiceMember {
17
- name: string
18
- type: MemberType.service
19
- code: string
20
- }
21
-
22
- export const isFileTree = (arg: any): arg is FileTree =>
23
- arg &&
24
- arg.members &&
25
- Array.isArray(arg.members) &&
26
- arg.members.filter(
27
- (member: FolderMember | ServiceMember) =>
28
- !isFolderMember(member) && !isServiceMember(member)
29
- ).length === 0
30
-
31
- const isFolderMember = (arg: any): arg is FolderMember =>
32
- arg &&
33
- typeof arg.name === 'string' &&
34
- arg.type === MemberType.folder &&
35
- arg.members &&
36
- Array.isArray(arg.members) &&
37
- arg.members.filter(
38
- (member: FolderMember | ServiceMember) =>
39
- !isFolderMember(member) && !isServiceMember(member)
40
- ).length === 0
41
-
42
- const isServiceMember = (arg: any): arg is ServiceMember =>
43
- arg &&
44
- typeof arg.name === 'string' &&
45
- arg.type === MemberType.service &&
46
- arg.code &&
47
- typeof arg.code === 'string'
@@ -1,18 +0,0 @@
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;