diff --git a/package-lock.json b/package-lock.json
index 9d896d1..f51088d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,7 @@
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
- "@sasjs/utils": "2.40.1",
+ "@sasjs/utils": "2.42.0",
"axios": "0.26.0",
"axios-cookiejar-support": "1.0.1",
"form-data": "4.0.0",
@@ -1142,9 +1142,9 @@
}
},
"node_modules/@sasjs/utils": {
- "version": "2.40.1",
- "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.40.1.tgz",
- "integrity": "sha512-wWYElDH71bSZTdZ5V38743vAnw2EPDhzH7+1s7zxINHpaQWK/qrDldI0vgVFLeGpxVU0D7WPZ/ltG6MoE2obeg==",
+ "version": "2.42.0",
+ "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.42.0.tgz",
+ "integrity": "sha512-Y69l89PYNF/h9xvVH72om/39xA+cY80bhiVLzp/fJb3BlvzCf4RNswBBanUOv2I5JNa7gPpJuE7mEiXOlhD3eg==",
"hasInstallScript": true,
"dependencies": {
"@types/fs-extra": "9.0.13",
@@ -13870,9 +13870,9 @@
}
},
"@sasjs/utils": {
- "version": "2.40.1",
- "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.40.1.tgz",
- "integrity": "sha512-wWYElDH71bSZTdZ5V38743vAnw2EPDhzH7+1s7zxINHpaQWK/qrDldI0vgVFLeGpxVU0D7WPZ/ltG6MoE2obeg==",
+ "version": "2.42.0",
+ "resolved": "https://registry.npmjs.org/@sasjs/utils/-/utils-2.42.0.tgz",
+ "integrity": "sha512-Y69l89PYNF/h9xvVH72om/39xA+cY80bhiVLzp/fJb3BlvzCf4RNswBBanUOv2I5JNa7gPpJuE7mEiXOlhD3eg==",
"requires": {
"@types/fs-extra": "9.0.13",
"@types/prompts": "2.0.13",
diff --git a/package.json b/package.json
index f1b8a52..e2e4dc5 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
},
"main": "index.js",
"dependencies": {
- "@sasjs/utils": "2.40.1",
+ "@sasjs/utils": "2.42.0",
"axios": "0.26.0",
"axios-cookiejar-support": "1.0.1",
"form-data": "4.0.0",
diff --git a/src/SASjs.ts b/src/SASjs.ts
index 8aed075..2b2fb6d 100644
--- a/src/SASjs.ts
+++ b/src/SASjs.ts
@@ -5,8 +5,7 @@ import {
EditContextInput,
PollOptions,
LoginMechanism,
- ExecutionQuery,
- FileTree
+ ExecutionQuery
} from './types'
import { SASViyaApiClient } from './SASViyaApiClient'
import { SAS9ApiClient } from './SAS9ApiClient'
@@ -18,7 +17,7 @@ import {
AuthConfig,
ExtraResponseAttributes,
SasAuthResponse,
- StreamConfig
+ ServicePackSASjs
} from '@sasjs/utils/types'
import { RequestClient } from './request/RequestClient'
import { SasjsRequestClient } from './request/SasjsRequestClient'
@@ -889,27 +888,21 @@ export default class SASjs {
/**
* Creates the folders and services at the given location `appLoc` on the given server `serverUrl`.
- * @param members - the JSON specifying the folders and services to be created.
- * @param appLoc - the base folder in which to create the new folders and
- * services. If not provided, is taken from SASjsConfig.
- * @param streamConfig - optional configuration object of StreamConfig for deploying streaming app.
- * @param authConfig - a valid client, secret, refresh and access tokens that are authorised to execute compute jobs.
+ * @param dataJson - the JSON specifying the folders and files to be created, can also includes
+ * appLoc, streamServiceName, streamWebFolder, streamLogo
+ * @param appLoc - (optional) the base folder in which to create the new folders and
+ * services. If not provided, is taken from SASjsConfig. Precedence will be of appLoc present in dataJson.
+ * @param authConfig - (optional) a valid client, secret, refresh and access tokens that are authorised to execute compute jobs.
*/
public async deployToSASjs(
- members: FileTree,
+ dataJson: ServicePackSASjs,
appLoc?: string,
- streamConfig?: StreamConfig,
authConfig?: AuthConfig
) {
if (!appLoc) {
appLoc = this.sasjsConfig.appLoc
}
- return await this.sasJSApiClient?.deploy(
- members,
- appLoc,
- streamConfig,
- authConfig
- )
+ return await this.sasJSApiClient?.deploy(dataJson, appLoc, authConfig)
}
public async executeJobSASjs(query: ExecutionQuery) {
@@ -1102,13 +1095,8 @@ export default class SASjs {
}
if (this.sasjsConfig.serverType === ServerType.Sasjs) {
- if (this.sasJSApiClient) {
- this.sasJSApiClient.setConfig(this.sasjsConfig.serverUrl)
- } else {
- this.sasJSApiClient = new SASjsApiClient(
- this.sasjsConfig.serverUrl,
- this.requestClient
- )
+ if (!this.sasJSApiClient) {
+ this.sasJSApiClient = new SASjsApiClient(this.requestClient)
}
}
diff --git a/src/SASjsApiClient.ts b/src/SASjsApiClient.ts
index e4fa737..c0a4268 100644
--- a/src/SASjsApiClient.ts
+++ b/src/SASjsApiClient.ts
@@ -1,5 +1,5 @@
-import { AuthConfig, ServerType, StreamConfig } from '@sasjs/utils/types'
-import { FileTree, ExecutionQuery } from './types'
+import { AuthConfig, ServerType, ServicePackSASjs } from '@sasjs/utils/types'
+import { ExecutionQuery } from './types'
import { RequestClient } from './request/RequestClient'
import { getAccessTokenForSasjs } from './auth/getAccessTokenForSasjs'
import { refreshTokensForSasjs } from './auth/refreshTokensForSasjs'
@@ -8,19 +8,11 @@ import { parseWeboutResponse } from './utils'
import { getTokens } from './auth/getTokens'
export class SASjsApiClient {
- constructor(
- private serverUrl: string,
- private requestClient: RequestClient
- ) {}
-
- public setConfig(serverUrl: string) {
- if (serverUrl) this.serverUrl = serverUrl
- }
+ constructor(private requestClient: RequestClient) {}
public async deploy(
- members: FileTree,
+ dataJson: ServicePackSASjs,
appLoc: string,
- streamConfig?: StreamConfig,
authConfig?: AuthConfig
) {
let access_token = (authConfig || {}).access_token
@@ -31,6 +23,9 @@ export class SASjsApiClient {
ServerType.Sasjs
))
}
+
+ dataJson.appLoc = dataJson.appLoc || appLoc
+
const { result } = await this.requestClient.post<{
status: string
message: string
@@ -38,13 +33,7 @@ export class SASjsApiClient {
example?: {}
}>(
'SASjsApi/drive/deploy',
- {
- fileTree: members,
- appLoc: appLoc,
- streamServiceName: streamConfig?.streamServiceName,
- streamWebFolder: streamConfig?.streamWebFolder,
- streamLogo: streamConfig?.streamLogo
- },
+ dataJson,
access_token,
undefined,
{},
diff --git a/src/file/generateFileUploadForm.ts b/src/file/generateFileUploadForm.ts
index 04e9c30..d88f13d 100644
--- a/src/file/generateFileUploadForm.ts
+++ b/src/file/generateFileUploadForm.ts
@@ -26,11 +26,18 @@ export const generateFileUploadForm = (
)
}
- const file = new Blob([csv], {
- type: 'application/csv'
- })
+ if (typeof FormData === 'undefined' && formData instanceof NodeFormData) {
+ formData.append(name, csv, {
+ filename: `${name}.csv`,
+ contentType: 'application/csv'
+ })
+ } else {
+ const file = new Blob([csv], {
+ type: 'application/csv'
+ })
- formData.append(name, file, `${name}.csv`)
+ formData.append(name, file, `${name}.csv`)
+ }
}
return formData
diff --git a/src/types/FileTree.ts b/src/types/FileTree.ts
deleted file mode 100644
index 548bc5a..0000000
--- a/src/types/FileTree.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-export interface FileTree {
- members: [FolderMember, ServiceMember]
-}
-
-export enum MemberType {
- folder = 'folder',
- service = 'service'
-}
-
-export interface FolderMember {
- name: string
- type: MemberType.folder
- members: [FolderMember, ServiceMember]
-}
-
-export interface ServiceMember {
- name: string
- type: MemberType.service
- code: string
-}
-
-export const isFileTree = (arg: any): arg is FileTree =>
- arg &&
- arg.members &&
- Array.isArray(arg.members) &&
- arg.members.filter(
- (member: FolderMember | ServiceMember) =>
- !isFolderMember(member) && !isServiceMember(member)
- ).length === 0
-
-const isFolderMember = (arg: any): arg is FolderMember =>
- arg &&
- typeof arg.name === 'string' &&
- arg.type === MemberType.folder &&
- arg.members &&
- Array.isArray(arg.members) &&
- arg.members.filter(
- (member: FolderMember | ServiceMember) =>
- !isFolderMember(member) && !isServiceMember(member)
- ).length === 0
-
-const isServiceMember = (arg: any): arg is ServiceMember =>
- arg &&
- typeof arg.name === 'string' &&
- arg.type === MemberType.service &&
- arg.code &&
- typeof arg.code === 'string'
diff --git a/src/types/index.ts b/src/types/index.ts
index 97f5406..c5994f7 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -12,5 +12,4 @@ export * from './Session'
export * from './UploadFile'
export * from './PollOptions'
export * from './WriteStream'
-export * from './FileTree'
export * from './ExecuteScript'
diff --git a/src/utils/parseViyaDebugResponse.ts b/src/utils/parseViyaDebugResponse.ts
index d3d3e6e..f5e4e54 100644
--- a/src/utils/parseViyaDebugResponse.ts
+++ b/src/utils/parseViyaDebugResponse.ts
@@ -16,10 +16,15 @@ export const parseSasViyaDebugResponse = async (
requestClient: RequestClient,
serverUrl: string
) => {
+ // On viya 3.5, iframe is like
+ // On viya 4, iframe is like
+
const iframeStart = response.split(
- '')[0] : null
+ const jsonUrl = iframeStart
+ ? iframeStart.split(/"><\/iframe>|><\/iframe>/)[0]
+ : null
if (!jsonUrl) {
throw new Error('Unable to find webout file URL.')
}