mirror of
https://github.com/sasjs/server.git
synced 2026-01-17 10:50:05 +00:00
Merge pull request #73 from sasjs/issue-72
fix(stp): return json for webout
This commit is contained in:
@@ -92,6 +92,10 @@ components:
|
|||||||
- clientSecret
|
- clientSecret
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
IRecordOfAny:
|
||||||
|
properties: {}
|
||||||
|
type: object
|
||||||
|
additionalProperties: {}
|
||||||
LogLine:
|
LogLine:
|
||||||
properties:
|
properties:
|
||||||
line:
|
line:
|
||||||
@@ -110,7 +114,11 @@ components:
|
|||||||
status:
|
status:
|
||||||
type: string
|
type: string
|
||||||
_webout:
|
_webout:
|
||||||
type: string
|
anyOf:
|
||||||
|
-
|
||||||
|
type: string
|
||||||
|
-
|
||||||
|
$ref: '#/components/schemas/IRecordOfAny'
|
||||||
log:
|
log:
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/LogLine'
|
$ref: '#/components/schemas/LogLine'
|
||||||
@@ -539,9 +547,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
anyOf:
|
$ref: '#/components/schemas/ExecuteReturnJsonResponse'
|
||||||
- {$ref: '#/components/schemas/ExecuteReturnJsonResponse'}
|
|
||||||
- {type: string, format: byte}
|
|
||||||
description: 'Execute SAS code.'
|
description: 'Execute SAS code.'
|
||||||
summary: 'Run SAS Code and returns log'
|
summary: 'Run SAS Code and returns log'
|
||||||
tags:
|
tags:
|
||||||
@@ -630,6 +636,7 @@ paths:
|
|||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
-
|
-
|
||||||
|
description: 'Location of SAS program'
|
||||||
in: query
|
in: query
|
||||||
name: filePath
|
name: filePath
|
||||||
required: true
|
required: true
|
||||||
@@ -1068,6 +1075,7 @@ paths:
|
|||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
-
|
-
|
||||||
|
description: 'Location of SAS program'
|
||||||
in: query
|
in: query
|
||||||
name: _program
|
name: _program
|
||||||
required: true
|
required: true
|
||||||
@@ -1082,9 +1090,7 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
anyOf:
|
$ref: '#/components/schemas/ExecuteReturnJsonResponse'
|
||||||
- {$ref: '#/components/schemas/ExecuteReturnJsonResponse'}
|
|
||||||
- {type: string, format: byte}
|
|
||||||
examples:
|
examples:
|
||||||
'Example 1':
|
'Example 1':
|
||||||
value: {status: success, _webout: 'webout content', log: [], httpHeaders: {Content-type: application/zip, Cache-Control: 'public, max-age=1000'}}
|
value: {status: success, _webout: 'webout content', log: [], httpHeaders: {Content-type: application/zip, Cache-Control: 'public, max-age=1000'}}
|
||||||
@@ -1097,6 +1103,7 @@ paths:
|
|||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
-
|
-
|
||||||
|
description: 'Location of SAS program'
|
||||||
in: query
|
in: query
|
||||||
name: _program
|
name: _program
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export class CodeController {
|
|||||||
public async executeSASCode(
|
public async executeSASCode(
|
||||||
@Request() request: express.Request,
|
@Request() request: express.Request,
|
||||||
@Body() body: ExecuteSASCodePayload
|
@Body() body: ExecuteSASCodePayload
|
||||||
): Promise<ExecuteReturnJsonResponse | Buffer> {
|
): Promise<ExecuteReturnJsonResponse> {
|
||||||
return executeSASCode(request, body)
|
return executeSASCode(request, body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,14 +41,9 @@ const executeSASCode = async (req: any, { code }: ExecuteSASCodePayload) => {
|
|||||||
true
|
true
|
||||||
)) as ExecuteReturnJson
|
)) as ExecuteReturnJson
|
||||||
|
|
||||||
if (webout instanceof Buffer) {
|
|
||||||
;(req as any).sasHeaders = httpHeaders
|
|
||||||
return webout
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
_webout: webout,
|
_webout: webout as string,
|
||||||
log: parseLogToArray(log),
|
log: parseLogToArray(log),
|
||||||
httpHeaders
|
httpHeaders
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export class DriveController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Get file from SASjs Drive
|
* @summary Get file from SASjs Drive
|
||||||
* @query filePath Location of SAS program
|
* @param filePath Location of SAS program
|
||||||
* @example filePath "/Public/somefolder/some.file"
|
* @example filePath "/Public/somefolder/some.file"
|
||||||
*/
|
*/
|
||||||
@Example<GetFileResponse>({
|
@Example<GetFileResponse>({
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ ${program}`
|
|||||||
? await readFile(headersPath)
|
? await readFile(headersPath)
|
||||||
: ''
|
: ''
|
||||||
const httpHeaders: HTTPHeaders = extractHeaders(headersContent)
|
const httpHeaders: HTTPHeaders = extractHeaders(headersContent)
|
||||||
const fileResponse: boolean = httpHeaders.hasOwnProperty('content-type')
|
const fileResponse: boolean =
|
||||||
|
httpHeaders.hasOwnProperty('content-type') && !returnJson
|
||||||
|
|
||||||
const webout = (await fileExists(weboutPath))
|
const webout = (await fileExists(weboutPath))
|
||||||
? fileResponse
|
? fileResponse
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ interface ExecuteReturnJsonPayload {
|
|||||||
*/
|
*/
|
||||||
_program?: string
|
_program?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IRecordOfAny {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
export interface ExecuteReturnJsonResponse {
|
export interface ExecuteReturnJsonResponse {
|
||||||
status: string
|
status: string
|
||||||
_webout: string
|
_webout: string | IRecordOfAny
|
||||||
log: LogLine[]
|
log: LogLine[]
|
||||||
message?: string
|
message?: string
|
||||||
httpHeaders: HTTPHeaders
|
httpHeaders: HTTPHeaders
|
||||||
@@ -46,13 +50,23 @@ export interface ExecuteReturnJsonResponse {
|
|||||||
@Tags('STP')
|
@Tags('STP')
|
||||||
export class STPController {
|
export class STPController {
|
||||||
/**
|
/**
|
||||||
* Trigger a SAS program using it's location in the _program parameter.
|
* Trigger a SAS program using it's location in the _program URL parameter.
|
||||||
* Enable debugging using the _debug parameter.
|
* Enable debugging using the _debug URL parameter. Setting _debug=131 will
|
||||||
|
* cause the log to be streamed in the output.
|
||||||
|
*
|
||||||
* Additional URL parameters are turned into SAS macro variables.
|
* Additional URL parameters are turned into SAS macro variables.
|
||||||
* Any files provided are placed into the session and
|
*
|
||||||
* corresponding _WEBIN_XXX variables are created.
|
* Any files provided in the request body are placed into the SAS session with
|
||||||
* @summary Execute Stored Program, return raw content
|
* corresponding _WEBIN_XXX variables created.
|
||||||
* @query _program Location of SAS program
|
*
|
||||||
|
* The response headers can be adjusted using the mfs_httpheader() macro. Any
|
||||||
|
* file type can be returned, including binary files such as zip or xls.
|
||||||
|
*
|
||||||
|
* This behaviour differs for POST requests, in which case the reponse is
|
||||||
|
* always JSON.
|
||||||
|
*
|
||||||
|
* @summary Execute Stored Program, return raw _webout content.
|
||||||
|
* @param _program Location of SAS program
|
||||||
* @example _program "/Public/somefolder/some.file"
|
* @example _program "/Public/somefolder/some.file"
|
||||||
*/
|
*/
|
||||||
@Get('/execute')
|
@Get('/execute')
|
||||||
@@ -64,13 +78,28 @@ export class STPController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger a SAS program using it's location in the _program parameter.
|
* Trigger a SAS program using it's location in the _program URL parameter.
|
||||||
* Enable debugging using the _debug parameter.
|
* Enable debugging using the _debug URL parameter. In any case, the log is
|
||||||
|
* always returned in the log object.
|
||||||
|
*
|
||||||
* Additional URL parameters are turned into SAS macro variables.
|
* Additional URL parameters are turned into SAS macro variables.
|
||||||
* Any files provided are placed into the session and
|
*
|
||||||
* corresponding _WEBIN_XXX variables are created.
|
* Any files provided in the request body are placed into the SAS session with
|
||||||
|
* corresponding _WEBIN_XXX variables created.
|
||||||
|
*
|
||||||
|
* The response will be a JSON object with the following root attributes: log,
|
||||||
|
* webout, headers.
|
||||||
|
*
|
||||||
|
* The webout will be a nested JSON object ONLY if the response-header
|
||||||
|
* contains a content-type of application/json AND it is valid JSON.
|
||||||
|
* Otherwise it will be a stringified version of the webout content.
|
||||||
|
*
|
||||||
|
* Response headers from the mfs_httpheader macro are simply listed in the
|
||||||
|
* headers object, for POST requests they have no effect on the actual
|
||||||
|
* response header.
|
||||||
|
*
|
||||||
* @summary Execute Stored Program, return JSON
|
* @summary Execute Stored Program, return JSON
|
||||||
* @query _program Location of SAS program
|
* @param _program Location of SAS program
|
||||||
* @example _program "/Public/somefolder/some.file"
|
* @example _program "/Public/somefolder/some.file"
|
||||||
*/
|
*/
|
||||||
@Example<ExecuteReturnJsonResponse>({
|
@Example<ExecuteReturnJsonResponse>({
|
||||||
@@ -87,7 +116,7 @@ export class STPController {
|
|||||||
@Request() request: express.Request,
|
@Request() request: express.Request,
|
||||||
@Body() body?: ExecuteReturnJsonPayload,
|
@Body() body?: ExecuteReturnJsonPayload,
|
||||||
@Query() _program?: string
|
@Query() _program?: string
|
||||||
): Promise<ExecuteReturnJsonResponse | Buffer> {
|
): Promise<ExecuteReturnJsonResponse> {
|
||||||
const program = _program ?? body?._program
|
const program = _program ?? body?._program
|
||||||
return executeReturnJson(request, program!)
|
return executeReturnJson(request, program!)
|
||||||
}
|
}
|
||||||
@@ -131,7 +160,7 @@ const executeReturnRaw = async (
|
|||||||
const executeReturnJson = async (
|
const executeReturnJson = async (
|
||||||
req: any,
|
req: any,
|
||||||
_program: string
|
_program: string
|
||||||
): Promise<ExecuteReturnJsonResponse | Buffer> => {
|
): Promise<ExecuteReturnJsonResponse> => {
|
||||||
const sasCodePath =
|
const sasCodePath =
|
||||||
path
|
path
|
||||||
.join(getTmpFilesFolderPath(), _program)
|
.join(getTmpFilesFolderPath(), _program)
|
||||||
@@ -149,14 +178,16 @@ const executeReturnJson = async (
|
|||||||
true
|
true
|
||||||
)) as ExecuteReturnJson
|
)) as ExecuteReturnJson
|
||||||
|
|
||||||
if (webout instanceof Buffer) {
|
let weboutRes: string | IRecordOfAny = webout
|
||||||
;(req as any).sasHeaders = httpHeaders
|
if (httpHeaders['content-type']?.toLowerCase() === 'application/json') {
|
||||||
return webout
|
try {
|
||||||
|
weboutRes = JSON.parse(webout as string)
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
_webout: webout,
|
_webout: weboutRes,
|
||||||
log: parseLogToArray(log),
|
log: parseLogToArray(log),
|
||||||
httpHeaders
|
httpHeaders
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user