import { isUrl, getValidJson, parseSasViyaDebugResponse } from './utils' import { UploadFile } from './types/UploadFile' import { ErrorResponse, LoginRequiredError } from './types/errors' import { RequestClient } from './request/RequestClient' import { ServerType } from '@sasjs/utils/types' import { SASjsConfig } from './types' export class FileUploader { constructor(private jobsPath: string, private requestClient: RequestClient) {} public async uploadFile( sasJob: string, files: UploadFile[], params: any, config: SASjsConfig ) { if (files?.length < 1) return Promise.reject( new ErrorResponse('At least one file must be provided.') ) if (!sasJob || sasJob === '') return Promise.reject(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 return this.requestClient .post(uploadUrl, formData, undefined, 'application/json', headers) .then(async (res) => { this.requestClient.appendRequest(res, sasJob, config.debug) if (config.serverType === ServerType.SasViya && config.debug) { const jsonResponse = await parseSasViyaDebugResponse( res.result as string, this.requestClient, config.serverUrl ) return jsonResponse } return typeof res.result === 'string' ? getValidJson(res.result) : res.result //TODO: append to SASjs requests }) .catch((err: Error) => { if (err instanceof LoginRequiredError) { return Promise.reject( new ErrorResponse('You must be logged in to upload a file.', err) ) } return Promise.reject( new ErrorResponse('File upload request failed.', err) ) }) } }