1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-11 03:34:35 +00:00

Compare commits

...

21 Commits

Author SHA1 Message Date
semantic-release-bot
a4f78ab48d chore(release): 0.35.1 [skip ci]
## [0.35.1](https://github.com/sasjs/server/compare/v0.35.0...v0.35.1) (2023-07-25)

### Bug Fixes

* **log-separator:** log separator should always wrap log ([8940f4d](8940f4dc47))
2023-07-25 06:05:23 +00:00
Yury Shkoda
2f47a2213b Merge pull request #364 from sasjs/log-separator
fix(log-separator): log separator should always wrap log
2023-07-25 09:01:36 +03:00
Yury Shkoda
0f91395fbb lint: fixed linting issues 2023-07-24 18:36:08 +03:00
Yury Shkoda
167b14fed0 docs(log-separator): left comment 2023-07-24 18:29:20 +03:00
Yury Shkoda
8940f4dc47 fix(log-separator): log separator should always wrap log 2023-07-24 18:27:21 +03:00
semantic-release-bot
48c1ada1b6 chore(release): 0.35.0 [skip ci]
# [0.35.0](https://github.com/sasjs/server/compare/v0.34.2...v0.35.0) (2023-05-03)

### Bug Fixes

* **editor:** fixed log/webout/print tabs ([d2de9dc](d2de9dc13e))
* **execute:** added atribute indicating stp api ([e78f87f](e78f87f5c0))
* **execute:** fixed adding print output ([9aaffce](9aaffce820))
* **execution:** removed empty webout from response ([6dd2f4f](6dd2f4f876))
* **webout:** fixed adding empty webout to response payload ([31df72a](31df72ad88))

### Features

* **editor:** parse print output in response payload ([eb42683](eb42683fff))
2023-05-03 09:34:56 +00:00
Allan Bowe
0532488b55 Merge pull request #360 from sasjs/issue-354
Support print destination natively
2023-05-03 10:31:06 +01:00
Yury Shkoda
d458b5bb81 chore: cleanup 2023-05-03 10:56:17 +03:00
Yury Shkoda
958ab9cad2 chore(execution): add includePrintOutput to ExecuteFileParams 2023-05-03 10:46:21 +03:00
Yury Shkoda
78ceed13e1 docs(code): updated execute endpoint info 2023-05-02 16:01:00 +03:00
Yury Shkoda
a17814fc90 chore(stp): removed redundant argument 2023-05-02 15:53:13 +03:00
Yury Shkoda
9aaffce820 fix(execute): fixed adding print output 2023-05-02 15:49:44 +03:00
Yury Shkoda
e78f87f5c0 fix(execute): added atribute indicating stp api 2023-05-02 15:18:05 +03:00
Yury Shkoda
bd1b58086d docs: left a comment regarding payload parts 2023-05-02 12:10:17 +03:00
Yury Shkoda
9f521634d9 chore(webout): added comment 2023-05-02 11:30:55 +03:00
Yury Shkoda
a696168443 Merge branch 'main' of github.com:sasjs/server into issue-354 2023-05-02 11:17:41 +03:00
Yury Shkoda
31df72ad88 fix(webout): fixed adding empty webout to response payload 2023-05-02 11:17:12 +03:00
Yury Shkoda
eb42683fff feat(editor): parse print output in response payload 2023-05-01 08:18:49 +03:00
Yury Shkoda
d2de9dc13e fix(editor): fixed log/webout/print tabs 2023-05-01 07:28:23 +03:00
Yury Shkoda
6dd2f4f876 fix(execution): removed empty webout from response 2023-04-28 17:25:30 +03:00
Yury Shkoda
c0f38ba7c9 wip(print-output): added print output to response payload 2023-04-28 15:09:44 +03:00
11 changed files with 143 additions and 70 deletions

View File

@@ -1,3 +1,26 @@
## [0.35.1](https://github.com/sasjs/server/compare/v0.35.0...v0.35.1) (2023-07-25)
### Bug Fixes
* **log-separator:** log separator should always wrap log ([8940f4d](https://github.com/sasjs/server/commit/8940f4dc47abae2036b4fcdeb772c31a0ca07cca))
# [0.35.0](https://github.com/sasjs/server/compare/v0.34.2...v0.35.0) (2023-05-03)
### Bug Fixes
* **editor:** fixed log/webout/print tabs ([d2de9dc](https://github.com/sasjs/server/commit/d2de9dc13ef2e980286dd03cca5e22cea443ed0c))
* **execute:** added atribute indicating stp api ([e78f87f](https://github.com/sasjs/server/commit/e78f87f5c00038ea11261dffb525ac8f1024e40b))
* **execute:** fixed adding print output ([9aaffce](https://github.com/sasjs/server/commit/9aaffce82051d81bf39adb69942bb321e9795141))
* **execution:** removed empty webout from response ([6dd2f4f](https://github.com/sasjs/server/commit/6dd2f4f87673336135bc7a6de0d2e143e192c025))
* **webout:** fixed adding empty webout to response payload ([31df72a](https://github.com/sasjs/server/commit/31df72ad88fe2c771d0ef8445d6db9dd147c40c9))
### Features
* **editor:** parse print output in response payload ([eb42683](https://github.com/sasjs/server/commit/eb42683fff701bd5b4d2b68760fe0c3ecad573dd))
## [0.34.2](https://github.com/sasjs/server/compare/v0.34.1...v0.34.2) (2023-05-01)

View File

@@ -158,7 +158,7 @@ CORS=
WHITELIST=
# HELMET Cross Origin Embedder Policy
# Sets the Cross-Origin-Embedder-Policy header to require-corp when `true`
# Sets the Cross-Origin-Embedder-Policy header to require-corp when `true`
# options: [true|false] default: true
# Docs: https://helmetjs.github.io/#reference (`crossOriginEmbedderPolicy`)
HELMET_COEP=

View File

@@ -28,7 +28,14 @@ interface ExecuteCodePayload {
export class CodeController {
/**
* Execute Code on the Specified Runtime
* @summary Run Code and Return Webout Content and Log
* @summary Run Code and Return Webout Content, Log and Print output
* The order of returned parts of the payload is:
* 1. Webout (if present)
* 2. Logs UUID (used as separator)
* 3. Log
* 4. Logs UUID (used as separator)
* 5. Print (if present and if the runtime is SAS)
* Please see @sasjs/server/api/src/controllers/internal/Execution.ts for more information
*/
@Post('/execute')
public async executeCode(
@@ -55,7 +62,8 @@ const executeCode = async (
preProgramVariables: getPreProgramVariables(req),
vars: { ...req.query, _debug: 131 },
otherArgs: { userAutoExec },
runTime: runTime
runTime: runTime,
includePrintOutput: true
})
return result

View File

@@ -33,6 +33,7 @@ interface ExecuteFileParams {
interface ExecuteProgramParams extends Omit<ExecuteFileParams, 'programPath'> {
program: string
includePrintOutput?: boolean
}
export class ExecutionController {
@@ -67,7 +68,8 @@ export class ExecutionController {
otherArgs,
session: sessionByFileUpload,
runTime,
forceStringResult
forceStringResult,
includePrintOutput
}: ExecuteProgramParams): Promise<ExecuteReturnRaw> {
const sessionController = getSessionController(runTime)
@@ -78,7 +80,6 @@ export class ExecutionController {
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')
const tokenFile = path.join(session.path, 'reqHeaders.txt')
@@ -122,12 +123,29 @@ export class ExecutionController {
// it should be deleted by scheduleSessionDestroy
session.inUse = false
const resultParts = []
// INFO: webout can be a Buffer, that is why it's length should be checked to determine if it is empty
if (webout && webout.length !== 0) resultParts.push(webout)
// INFO: log separator wraps the log from the beginning and the end
resultParts.push(process.logsUUID)
resultParts.push(log)
resultParts.push(process.logsUUID)
if (includePrintOutput && runTime === RunTimeType.SAS) {
const printOutputPath = path.join(session.path, 'output.lst')
const printOutput = (await fileExists(printOutputPath))
? await readFile(printOutputPath)
: ''
if (printOutput) resultParts.push(printOutput)
}
return {
httpHeaders,
result:
isDebugOn(vars) || session.crashed
? `${webout}\n${process.logsUUID}\n${log}`
: webout
isDebugOn(vars) || session.crashed ? resultParts.join(`\n`) : webout
}
}

View File

@@ -190,7 +190,8 @@ ${autoExecContent}`
}
private scheduleSessionDestroy(session: Session) {
setTimeout(async () => {
setTimeout(
async () => {
if (session.inUse) {
// adding 10 more minutes
const newDeathTimeStamp = parseInt(session.deathTimeStamp) + 10 * 1000
@@ -200,7 +201,9 @@ ${autoExecContent}`
} else {
await this.deleteSession(session)
}
}, parseInt(session.deathTimeStamp) - new Date().getTime() - 100)
},
parseInt(session.deathTimeStamp) - new Date().getTime() - 100
)
}
}

View File

@@ -3,8 +3,6 @@ import { Request, Security, Route, Tags, Post, Body, Get, Query } from 'tsoa'
import { ExecutionController, ExecutionVars } from './internal'
import {
getPreProgramVariables,
HTTPHeaders,
LogLine,
makeFilesNamesMap,
getRunTimeAndFilePath
} from '../utils'
@@ -39,6 +37,7 @@ export class STPController {
@Query() _program: string
): Promise<string | Buffer> {
const vars = request.query as ExecutionVars
return execute(request, _program, vars)
}

View File

@@ -3,12 +3,11 @@ import Snackbar from '@mui/material/Snackbar'
import MuiAlert, { AlertProps } from '@mui/material/Alert'
import Slide, { SlideProps } from '@mui/material/Slide'
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(function Alert(
props,
ref
) {
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
function Alert(props, ref) {
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />
})
}
)
const Transition = (props: SlideProps) => {
return <Slide {...props} direction="up" />

View File

@@ -62,6 +62,7 @@ const SASjsEditor = ({
selectedRunTime,
showDiff,
webout,
printOutput,
Dialog,
handleChangeRunTime,
handleDiffEditorDidMount,
@@ -153,6 +154,7 @@ const SASjsEditor = ({
>
<TabList onChange={handleTabChange} centered>
<StyledTab label="Code" value="code" />
{log && (
<StyledTab
label={logWithErrorsOrWarnings ? '' : 'log'}
value="log"
@@ -169,6 +171,8 @@ const SASjsEditor = ({
if (logWrapper) logWrapper.scrollTop = 0
}}
/>
)}
{webout && (
<StyledTab
label={
<Tooltip title="Displays content from the _webout fileref">
@@ -177,6 +181,8 @@ const SASjsEditor = ({
}
value="webout"
/>
)}
{printOutput && <StyledTab label="print" value="printOutput" />}
</TabList>
</Box>
@@ -222,11 +228,20 @@ const SASjsEditor = ({
<LogComponent log={log} selectedRunTime={selectedRunTime} />
)}
</StyledTabPanel>
{webout && (
<StyledTabPanel value="webout">
<div>
<pre>{webout}</pre>
</div>
</StyledTabPanel>
)}
{printOutput && (
<StyledTabPanel value="printOutput">
<div>
<pre>{printOutput}</pre>
</div>
</StyledTabPanel>
)}
</TabContext>
)}
<Dialog />

View File

@@ -7,8 +7,10 @@
border: none;
outline: none;
transition: 0.4s;
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 1px -1px,
rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px;
box-shadow:
rgba(0, 0, 0, 0.2) 0px 2px 1px -1px,
rgba(0, 0, 0, 0.14) 0px 1px 1px 0px,
rgba(0, 0, 0, 0.12) 0px 1px 3px 0px;
}
.ChunkDetails {

View File

@@ -39,14 +39,14 @@ const useEditor = ({
const { Snackbar, setOpenSnackbar, setSnackbarMessage, setSnackbarSeverity } =
useSnackbar()
const [isLoading, setIsLoading] = useState(false)
const [prevFileContent, setPrevFileContent] = useStateWithCallback('')
const [fileContent, setFileContent] = useState('')
const [log, setLog] = useState<LogObject | string>()
const [webout, setWebout] = useState('')
const [webout, setWebout] = useState<string>()
const [printOutput, setPrintOutput] = useState<string>()
const [runTimes, setRunTimes] = useState<string[]>([])
const [selectedRunTime, setSelectedRunTime] = useState<RunTimeType | string>(
''
const [selectedRunTime, setSelectedRunTime] = useState<RunTimeType>(
RunTimeType.SAS
)
const [selectedFileExtension, setSelectedFileExtension] = useState('')
const [openFilePathInputModal, setOpenFilePathInputModal] = useState(false)
@@ -169,25 +169,30 @@ const useEditor = ({
),
runTime: selectedRunTime
})
.then((res: any) => {
if (selectedRunTime === RunTimeType.SAS) {
const { errors, warnings, logLines } = parseErrorsAndWarnings(
res.data.split(SASJS_LOGS_SEPARATOR)[1]
)
.then((res: { data: string }) => {
// INFO: the order of payload parts is set in @sasjs/server/api/src/controllers/internal/Execution.ts
const resDataSplitted = res.data.split(SASJS_LOGS_SEPARATOR)
const webout = resDataSplitted[0]
const log = resDataSplitted[1]
const printOutput = resDataSplitted[2]
const log: LogObject = {
if (selectedRunTime === RunTimeType.SAS) {
const { errors, warnings, logLines } = parseErrorsAndWarnings(log)
const logObject: LogObject = {
body: logLines.join(`\n`),
errors,
warnings,
linesCount: logLines.length
}
setLog(log)
setLog(logObject)
} else {
setLog(res.data.split(SASJS_LOGS_SEPARATOR)[1] ?? '')
setLog(log)
}
setWebout(res.data.split(SASJS_LOGS_SEPARATOR)[0] ?? '')
setWebout(webout)
setPrintOutput(printOutput)
setTab('log')
// Scroll to bottom of log
@@ -335,6 +340,7 @@ const useEditor = ({
selectedRunTime,
showDiff,
webout,
printOutput,
Dialog,
handleChangeRunTime,
handleDiffEditorDidMount,

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />