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

feat(studio): run selected code + open in studio

This commit is contained in:
Saad Jutt
2021-12-16 12:14:32 +05:00
parent da11c03d55
commit 27129a8921
7 changed files with 204 additions and 14 deletions

View File

@@ -358,6 +358,16 @@ components:
- description
type: object
additionalProperties: false
RunSASPayload:
properties:
code:
type: string
description: 'Code of SAS program'
example: '* SAS Code HERE;'
required:
- code
type: object
additionalProperties: false
ExecuteReturnJsonResponse:
properties:
status:
@@ -1027,6 +1037,30 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ExecuteReturnJsonPayload'
/SASjsApi/stp/run:
post:
operationId: RunSAS
responses:
'200':
description: Ok
content:
application/json:
schema:
type: string
description: 'Trigger a SAS program.'
summary: 'Run SAS Program, return raw content'
tags:
- STP
security:
-
bearerAuth: []
parameters: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RunSASPayload'
/SASjsApi/session:
get:
operationId: Session

View File

@@ -6,7 +6,7 @@ import { PreProgramVars, TreeNode } from '../../types'
import { generateFileUploadSasCode, getTmpFilesFolderPath } from '../../utils'
export class ExecutionController {
async execute(
async executeFile(
programPath: string,
preProgramVariables: PreProgramVars,
vars: { [key: string]: string | number | undefined },
@@ -16,8 +16,23 @@ export class ExecutionController {
if (!(await fileExists(programPath)))
throw 'ExecutionController: SAS file does not exist.'
let program = await readFile(programPath)
const program = await readFile(programPath)
return this.executeProgram(
program,
preProgramVariables,
vars,
otherArgs,
returnJson
)
}
async executeProgram(
program: string,
preProgramVariables: PreProgramVars,
vars: { [key: string]: string | number | undefined },
otherArgs?: any,
returnJson?: boolean
) {
const sessionController = getSessionController()
const session = await sessionController.getSession()

View File

@@ -5,6 +5,13 @@ import { ExecutionController } from './internal'
import { PreProgramVars } from '../types'
import { getTmpFilesFolderPath, makeFilesNamesMap } from '../utils'
interface RunSASPayload {
/**
* Code of SAS program
* @example "* SAS Code HERE;"
*/
code: string
}
interface ExecuteReturnJsonPayload {
/**
* Location of SAS program
@@ -40,6 +47,19 @@ export class STPController {
): Promise<string> {
return executeReturnRaw(request, _program)
}
/**
* Trigger a SAS program.
* @summary Run SAS Program, return raw content
*/
@Post('/run')
public async runSAS(
@Request() request: express.Request,
@Body() body: RunSASPayload
): Promise<string> {
return runSAS(request, body)
}
/**
* Trigger a SAS program using it's location in the _program parameter.
* Enable debugging using the _debug parameter.
@@ -72,7 +92,7 @@ const executeReturnRaw = async (
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
try {
const result = await new ExecutionController().execute(
const result = await new ExecutionController().executeFile(
sasCodePath,
getPreProgramVariables(req),
query
@@ -89,6 +109,25 @@ const executeReturnRaw = async (
}
}
const runSAS = async (req: any, { code }: RunSASPayload) => {
try {
const result = await new ExecutionController().executeProgram(
code,
getPreProgramVariables(req),
req.query
)
return result as string
} catch (err: any) {
throw {
code: 400,
status: 'failure',
message: 'Job execution failed.',
error: typeof err === 'object' ? err.toString() : err
}
}
}
const executeReturnJson = async (
req: any,
_program: string
@@ -101,7 +140,7 @@ const executeReturnJson = async (
const filesNamesMap = req.files?.length ? makeFilesNamesMap(req.files) : null
try {
const { webout, log } = (await new ExecutionController().execute(
const { webout, log } = (await new ExecutionController().executeFile(
sasCodePath,
getPreProgramVariables(req),
{ ...req.query, ...req.body },

View File

@@ -1,5 +1,5 @@
import express from 'express'
import { executeProgramRawValidation } from '../../utils'
import { executeProgramRawValidation, runSASValidation } from '../../utils'
import { STPController } from '../../controllers/'
import { FileUploadController } from '../../controllers/internal'
@@ -24,6 +24,22 @@ stpRouter.get('/execute', async (req, res) => {
}
})
stpRouter.post('/run', async (req, res) => {
const { error, value: body } = runSASValidation(req.body)
if (error) return res.status(400).send(error.details[0].message)
try {
const response = await controller.runSAS(req, body)
res.send(response)
} catch (err: any) {
const statusCode = err.code
delete err.code
res.status(statusCode).send(err)
}
})
stpRouter.post(
'/execute',
fileUploadController.preuploadMiddleware,

View File

@@ -77,6 +77,11 @@ export const updateFileDriveValidation = (data: any): Joi.ValidationResult =>
fileContent: Joi.string().required()
}).validate(data)
export const runSASValidation = (data: any): Joi.ValidationResult =>
Joi.object({
code: Joi.string().required()
}).validate(data)
export const executeProgramRawValidation = (data: any): Joi.ValidationResult =>
Joi.object({
_program: Joi.string().required()