mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-11 01:14:36 +00:00
157 lines
4.6 KiB
TypeScript
157 lines
4.6 KiB
TypeScript
import {
|
|
getValidJson,
|
|
parseSasViyaDebugResponse,
|
|
parseWeboutResponse
|
|
} from '../utils'
|
|
import { UploadFile } from '../types/UploadFile'
|
|
import {
|
|
ErrorResponse,
|
|
JobExecutionError,
|
|
LoginRequiredError
|
|
} from '../types/errors'
|
|
import { RequestClient } from '../request/RequestClient'
|
|
import { ServerType } from '@sasjs/utils/types'
|
|
import { BaseJobExecutor } from './JobExecutor'
|
|
|
|
interface dataFileUpload {
|
|
files: UploadFile[]
|
|
params: { [key: string]: any } | null
|
|
}
|
|
|
|
export class FileUploader extends BaseJobExecutor {
|
|
constructor(
|
|
serverUrl: string,
|
|
serverType: ServerType,
|
|
private jobsPath: string,
|
|
private requestClient: RequestClient
|
|
) {
|
|
super(serverUrl, serverType)
|
|
}
|
|
|
|
public async execute(
|
|
sasJob: string,
|
|
data: any,
|
|
config: any,
|
|
loginRequiredCallback?: any
|
|
) {
|
|
const { files, params }: dataFileUpload = data
|
|
const loginCallback = loginRequiredCallback || (() => Promise.resolve())
|
|
|
|
if (!files?.length)
|
|
throw new ErrorResponse('At least one file must be provided.')
|
|
|
|
if (!sasJob || sasJob === '')
|
|
throw new ErrorResponse('sasJob must be provided.')
|
|
|
|
let paramsString = ''
|
|
|
|
for (let param in params)
|
|
if (params.hasOwnProperty(param))
|
|
paramsString += `&${param}=${params[param]}`
|
|
|
|
const program = config.appLoc
|
|
? config.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
|
|
: sasJob
|
|
const uploadUrl = `${this.jobsPath}/?${
|
|
'_program=' + program
|
|
}${paramsString}`
|
|
|
|
const formData = new FormData()
|
|
|
|
for (let file of files) {
|
|
formData.append('file', file.file, file.fileName)
|
|
}
|
|
|
|
const csrfToken = this.requestClient.getCsrfToken('file')
|
|
if (csrfToken) formData.append('_csrf', csrfToken.value)
|
|
if (config.debug) formData.append('_debug', '131')
|
|
if (config.serverType === ServerType.SasViya && config.contextName)
|
|
formData.append('_contextname', config.contextName)
|
|
|
|
const headers = {
|
|
'cache-control': 'no-cache',
|
|
Accept: '*/*',
|
|
'Content-Type': 'text/plain'
|
|
}
|
|
|
|
// currently only web approach is supported for file upload
|
|
// therefore log is part of response with debug enabled and must be parsed
|
|
const requestPromise = new Promise((resolve, reject) => {
|
|
this.requestClient
|
|
.post(uploadUrl, formData, undefined, 'application/json', headers)
|
|
.then(async (res: any) => {
|
|
this.requestClient.appendRequest(res, sasJob, config.debug)
|
|
|
|
let jsonResponse = res.result
|
|
|
|
if (config.debug) {
|
|
switch (this.serverType) {
|
|
case ServerType.SasViya:
|
|
jsonResponse = await parseSasViyaDebugResponse(
|
|
res.result,
|
|
this.requestClient,
|
|
config.serverUrl
|
|
)
|
|
break
|
|
case ServerType.Sas9:
|
|
jsonResponse =
|
|
typeof res.result === 'string'
|
|
? parseWeboutResponse(res.result, uploadUrl)
|
|
: res.result
|
|
break
|
|
case ServerType.Sasjs:
|
|
if (typeof res.result._webout === 'object') {
|
|
jsonResponse = res.result._webout
|
|
} else {
|
|
const webout = parseWeboutResponse(
|
|
res.result._webout,
|
|
uploadUrl
|
|
)
|
|
jsonResponse = getValidJson(webout)
|
|
}
|
|
break
|
|
}
|
|
} else if (this.serverType === ServerType.Sasjs) {
|
|
jsonResponse = getValidJson(res.result._webout)
|
|
} else {
|
|
jsonResponse =
|
|
typeof res.result === 'string'
|
|
? getValidJson(res.result)
|
|
: res.result
|
|
}
|
|
|
|
resolve(jsonResponse)
|
|
})
|
|
.catch(async (e: Error) => {
|
|
if (e instanceof JobExecutionError) {
|
|
this.requestClient!.appendRequest(e, sasJob, config.debug)
|
|
reject(new ErrorResponse(e?.message, e))
|
|
}
|
|
|
|
if (e instanceof LoginRequiredError) {
|
|
this.appendWaitingRequest(() => {
|
|
return this.execute(
|
|
sasJob,
|
|
data,
|
|
config,
|
|
loginRequiredCallback
|
|
).then(
|
|
(res: any) => {
|
|
resolve(res)
|
|
},
|
|
(err: any) => {
|
|
reject(err)
|
|
}
|
|
)
|
|
})
|
|
|
|
await loginCallback()
|
|
} else {
|
|
reject(new ErrorResponse('File upload request failed.', e))
|
|
}
|
|
})
|
|
})
|
|
return requestPromise
|
|
}
|
|
}
|