mirror of
https://github.com/sasjs/server.git
synced 2026-01-06 22:20:06 +00:00
feat: set response headers provded by SAS Code execution
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import express from 'express'
|
||||
import { Request, Security, Route, Tags, Post, Body } from 'tsoa'
|
||||
import { ExecutionController } from './internal'
|
||||
import { ExecuteReturnRaw, ExecutionController } from './internal'
|
||||
import { PreProgramVars } from '../types'
|
||||
|
||||
interface ExecuteSASCodePayload {
|
||||
@@ -30,13 +30,13 @@ export class CodeController {
|
||||
|
||||
const executeSASCode = async (req: any, { code }: ExecuteSASCodePayload) => {
|
||||
try {
|
||||
const result = await new ExecutionController().executeProgram(
|
||||
const { result } = (await new ExecutionController().executeProgram(
|
||||
code,
|
||||
getPreProgramVariables(req),
|
||||
{ ...req.query, _debug: 131 },
|
||||
undefined,
|
||||
true
|
||||
)
|
||||
)) as ExecuteReturnRaw
|
||||
|
||||
return result as string
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -3,12 +3,28 @@ import fs from 'fs'
|
||||
import { getSessionController } from './'
|
||||
import { readFile, fileExists, createFile, moveFile } from '@sasjs/utils'
|
||||
import { PreProgramVars, TreeNode } from '../../types'
|
||||
import { generateFileUploadSasCode, getTmpFilesFolderPath } from '../../utils'
|
||||
import {
|
||||
extractHeaders,
|
||||
generateFileUploadSasCode,
|
||||
getTmpFilesFolderPath,
|
||||
HTTPHeaders
|
||||
} from '../../utils'
|
||||
|
||||
export interface ExecutionVars {
|
||||
[key: string]: string | number | undefined
|
||||
}
|
||||
|
||||
export interface ExecuteReturnRaw {
|
||||
httpHeaders: HTTPHeaders
|
||||
result: string
|
||||
}
|
||||
|
||||
export interface ExecuteReturnJson {
|
||||
httpHeaders: HTTPHeaders
|
||||
webout: string
|
||||
log?: string
|
||||
}
|
||||
|
||||
export class ExecutionController {
|
||||
async executeFile(
|
||||
programPath: string,
|
||||
@@ -30,13 +46,14 @@ export class ExecutionController {
|
||||
returnJson
|
||||
)
|
||||
}
|
||||
|
||||
async executeProgram(
|
||||
program: string,
|
||||
preProgramVariables: PreProgramVars,
|
||||
vars: ExecutionVars,
|
||||
otherArgs?: any,
|
||||
returnJson?: boolean
|
||||
) {
|
||||
): Promise<ExecuteReturnRaw | ExecuteReturnJson> {
|
||||
const sessionController = getSessionController()
|
||||
|
||||
const session = await sessionController.getSession()
|
||||
@@ -44,11 +61,11 @@ export class ExecutionController {
|
||||
session.consumed = true
|
||||
|
||||
const logPath = path.join(session.path, 'log.log')
|
||||
|
||||
const headersPath = path.join(session.path, 'stpsrv_header.txt')
|
||||
const weboutPath = path.join(session.path, 'webout.txt')
|
||||
await createFile(weboutPath, '')
|
||||
|
||||
const tokenFile = path.join(session.path, 'accessToken.txt')
|
||||
|
||||
await createFile(weboutPath, '')
|
||||
await createFile(
|
||||
tokenFile,
|
||||
preProgramVariables?.accessToken ?? 'accessToken'
|
||||
@@ -124,6 +141,12 @@ ${program}`
|
||||
const webout = (await fileExists(weboutPath))
|
||||
? await readFile(weboutPath)
|
||||
: ''
|
||||
const headersContent = (await fileExists(headersPath))
|
||||
? await readFile(headersPath)
|
||||
: ''
|
||||
const httpHeaders: HTTPHeaders = headersContent
|
||||
? extractHeaders(headersContent)
|
||||
: {}
|
||||
|
||||
const debugValue =
|
||||
typeof vars._debug === 'string' ? parseInt(vars._debug) : vars._debug
|
||||
@@ -133,15 +156,20 @@ ${program}`
|
||||
|
||||
if (returnJson) {
|
||||
return {
|
||||
httpHeaders,
|
||||
webout,
|
||||
log:
|
||||
(debugValue && debugValue >= 131) || session.crashed ? log : undefined
|
||||
}
|
||||
}
|
||||
|
||||
return (debugValue && debugValue >= 131) || session.crashed
|
||||
? `<html><body>${webout}<div style="text-align:left"><hr /><h2>SAS Log</h2><pre>${log}</pre></div></body></html>`
|
||||
: webout
|
||||
return {
|
||||
httpHeaders,
|
||||
result:
|
||||
(debugValue && debugValue >= 131) || session.crashed
|
||||
? `<html><body>${webout}<div style="text-align:left"><hr /><h2>SAS Log</h2><pre>${log}</pre></div></body></html>`
|
||||
: webout
|
||||
}
|
||||
}
|
||||
|
||||
buildDirectoryTree() {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import { Request, Security, Route, Tags, Post, Body, Get, Query } from 'tsoa'
|
||||
import { ExecutionController, ExecutionVars } from './internal'
|
||||
import {
|
||||
ExecuteReturnJson,
|
||||
ExecuteReturnRaw,
|
||||
ExecutionController,
|
||||
ExecutionVars
|
||||
} from './internal'
|
||||
import { PreProgramVars } from '../types'
|
||||
import { getTmpFilesFolderPath, makeFilesNamesMap } from '../utils'
|
||||
|
||||
@@ -73,11 +78,16 @@ const executeReturnRaw = async (
|
||||
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
|
||||
|
||||
try {
|
||||
const result = await new ExecutionController().executeFile(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
query
|
||||
)
|
||||
const { result, httpHeaders } =
|
||||
(await new ExecutionController().executeFile(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
query
|
||||
)) as ExecuteReturnRaw
|
||||
|
||||
Object.entries(httpHeaders ?? {}).forEach(([key, value]) => {
|
||||
req.res?.set(key, value)
|
||||
})
|
||||
|
||||
return result as string
|
||||
} catch (err: any) {
|
||||
@@ -102,16 +112,22 @@ const executeReturnJson = async (
|
||||
const filesNamesMap = req.files?.length ? makeFilesNamesMap(req.files) : null
|
||||
|
||||
try {
|
||||
const { webout, log } = (await new ExecutionController().executeFile(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
{ ...req.query, ...req.body },
|
||||
{ filesNamesMap: filesNamesMap },
|
||||
true
|
||||
)) as { webout: string; log: string }
|
||||
const { webout, log, httpHeaders } =
|
||||
(await new ExecutionController().executeFile(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
{ ...req.query, ...req.body },
|
||||
{ filesNamesMap: filesNamesMap },
|
||||
true
|
||||
)) as ExecuteReturnJson
|
||||
|
||||
Object.entries(httpHeaders ?? {}).forEach(([key, value]) => {
|
||||
req.res?.set(key, value)
|
||||
})
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
_webout: webout,
|
||||
_webout: webout as string,
|
||||
log
|
||||
}
|
||||
} catch (err: any) {
|
||||
|
||||
Reference in New Issue
Block a user