mirror of
https://github.com/sasjs/server.git
synced 2026-01-10 07:50:05 +00:00
chore: comments addressing
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,4 +6,4 @@ node_modules/
|
|||||||
sas/
|
sas/
|
||||||
tmp/
|
tmp/
|
||||||
build/
|
build/
|
||||||
certificates/
|
certificates/
|
||||||
|
|||||||
10
code.lst
Normal file
10
code.lst
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
The SAS System Friday, 15 October 2021 11:20:00 1
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
0
|
||||||
|
The SAS System Friday, 15 October 2021 11:20:00 2
|
||||||
|
|
||||||
|
|
||||||
|
--------
|
||||||
|
41140
|
||||||
24
package-lock.json
generated
24
package-lock.json
generated
@@ -1518,12 +1518,6 @@
|
|||||||
"integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==",
|
"integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/cors": {
|
|
||||||
"version": "2.8.12",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
|
||||||
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/express": {
|
"@types/express": {
|
||||||
"version": "4.17.12",
|
"version": "4.17.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz",
|
||||||
@@ -1693,6 +1687,15 @@
|
|||||||
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/multer": {
|
||||||
|
"version": "1.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||||
|
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/express": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "15.12.2",
|
"version": "15.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
|
||||||
@@ -2690,15 +2693,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||||
},
|
},
|
||||||
"cors": {
|
|
||||||
"version": "2.8.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
|
||||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
|
||||||
"requires": {
|
|
||||||
"object-assign": "^4",
|
|
||||||
"vary": "^1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cosmiconfig": {
|
"cosmiconfig": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.12",
|
"@types/express": "^4.17.12",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^26.0.24",
|
||||||
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^15.12.2",
|
"@types/node": "^15.12.2",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"jest": "^27.0.6",
|
"jest": "^27.0.6",
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ ${program}`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = path.join(session.path, 'code.sas')
|
const code = path.join(session.path, 'code.sas')
|
||||||
if (!(await fileExists(code))) {
|
if (!(await fileExists(code))) {
|
||||||
await createFile(code, program)
|
await createFile(code, program)
|
||||||
}
|
}
|
||||||
@@ -82,10 +82,6 @@ ${program}`
|
|||||||
if (await fileExists(log)) log = await readFile(log)
|
if (await fileExists(log)) log = await readFile(log)
|
||||||
else log = ''
|
else log = ''
|
||||||
|
|
||||||
// if (stderr) {
|
|
||||||
// return Promise.reject({ error: stderr, log: log })
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (await fileExists(webout)) webout = await readFile(webout)
|
if (await fileExists(webout)) webout = await readFile(webout)
|
||||||
else webout = ''
|
else webout = ''
|
||||||
|
|
||||||
|
|||||||
36
src/controllers/FileUploadController.ts
Normal file
36
src/controllers/FileUploadController.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { uuidv4 } from '@sasjs/utils'
|
||||||
|
import { getSessionController } from '.'
|
||||||
|
const multer = require('multer')
|
||||||
|
|
||||||
|
export class FileUploadController {
|
||||||
|
private storage = multer.diskStorage({
|
||||||
|
destination: function (req: any, file: any, cb: any) {
|
||||||
|
//Sending the intercepted files to the sessions subfolder
|
||||||
|
cb(null, req.sasSession.path)
|
||||||
|
},
|
||||||
|
filename: function (req: any, file: any, cb: any) {
|
||||||
|
//req_file prefix + unique hash added to sas request files
|
||||||
|
cb(null, `req_file_${uuidv4().replace(/-/gm, '')}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
private upload = multer({ storage: this.storage })
|
||||||
|
|
||||||
|
//It will intercept request and generate uniqe uuid to be used as a subfolder name
|
||||||
|
//that will store the files uploaded
|
||||||
|
public preuploadMiddleware = async (req: any, res: any, next: any) => {
|
||||||
|
let session
|
||||||
|
|
||||||
|
const sessionController = getSessionController()
|
||||||
|
session = await sessionController.getSession()
|
||||||
|
session.inUse = true
|
||||||
|
|
||||||
|
req.sasSession = session
|
||||||
|
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMulterUploadObject() {
|
||||||
|
return this.upload
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,7 +70,7 @@ export class SessionController {
|
|||||||
|
|
||||||
this.scheduleSessionDestroy(session)
|
this.scheduleSessionDestroy(session)
|
||||||
|
|
||||||
this.executionController.execute('', autoExec, session).catch((err) => {})
|
this.executionController.execute('', autoExec, session).catch(() => {})
|
||||||
|
|
||||||
this.sessions.push(session)
|
this.sessions.push(session)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './deploy'
|
export * from './deploy'
|
||||||
export * from './Session'
|
export * from './Session'
|
||||||
export * from './Execution'
|
export * from './Execution'
|
||||||
|
export * from './FileUploadController'
|
||||||
@@ -2,39 +2,12 @@ import express from 'express'
|
|||||||
import { createFileTree, getSessionController, getTreeExample } from '../controllers'
|
import { createFileTree, getSessionController, getTreeExample } from '../controllers'
|
||||||
import { ExecutionResult, isRequestQuery, isFileTree } from '../types'
|
import { ExecutionResult, isRequestQuery, isFileTree } from '../types'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { getTmpFilesFolderPath, getTmpFolderPath, makeFilesNamesMap } from '../utils'
|
import { addExtensionIfNotFound, getTmpFilesFolderPath, getTmpFolderPath, makeFilesNamesMap } from '../utils'
|
||||||
import { ExecutionController } from '../controllers'
|
import { ExecutionController, FileUploadController } from '../controllers'
|
||||||
import { uuidv4 } from '@sasjs/utils'
|
|
||||||
|
|
||||||
const multer = require('multer')
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
const storage = multer.diskStorage({
|
const fileUploadController = new FileUploadController()
|
||||||
destination: function (req: any, file: any, cb: any) {
|
|
||||||
//Sending the intercepted files to the sessions subfolder
|
|
||||||
cb(null, req.sasSession.path)
|
|
||||||
},
|
|
||||||
filename: function (req: any, file: any, cb: any) {
|
|
||||||
//req_file prefix + unique hash added to sas request files
|
|
||||||
cb(null, `req_file_${uuidv4().replace(/-/gm, '')}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const upload = multer({ storage: storage })
|
|
||||||
|
|
||||||
//It will intercept request and generate uniqe uuid to be used as a subfolder name
|
|
||||||
//that will store the files uploaded
|
|
||||||
const preuploadMiddleware = async (req: any, res: any, next: any) => {
|
|
||||||
let session
|
|
||||||
|
|
||||||
const sessionController = getSessionController()
|
|
||||||
session = await sessionController.getSession()
|
|
||||||
session.inUse = true
|
|
||||||
|
|
||||||
req.sasSession = session
|
|
||||||
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
|
|
||||||
router.get('/', async (_, res) => {
|
router.get('/', async (_, res) => {
|
||||||
res.status(200).send('Welcome to @sasjs/server API')
|
res.status(200).send('Welcome to @sasjs/server API')
|
||||||
@@ -102,14 +75,14 @@ router.get('/SASjsExecutor/do', async (req, res) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.post('/SASjsExecutor/do', preuploadMiddleware, upload.any(), async (req: any, res: any) => {
|
router.post('/SASjsExecutor/do', fileUploadController.preuploadMiddleware, fileUploadController.getMulterUploadObject().any(), async (req: any, res: any) => {
|
||||||
if (isRequestQuery(req.query)) {
|
if (isRequestQuery(req.query)) {
|
||||||
let sasCodePath = path
|
let sasCodePath = path
|
||||||
.join(getTmpFilesFolderPath(), req.query._program)
|
.join(getTmpFilesFolderPath(), req.query._program)
|
||||||
.replace(new RegExp('/', 'g'), path.sep)
|
.replace(new RegExp('/', 'g'), path.sep)
|
||||||
|
|
||||||
// If no extension provided, add .sas extension
|
// If no extension provided, add .sas extension
|
||||||
sasCodePath += !sasCodePath.includes('.') ? '.sas' : ''
|
sasCodePath += addExtensionIfNotFound(sasCodePath, 'sas')
|
||||||
|
|
||||||
let filesNamesMap = null
|
let filesNamesMap = null
|
||||||
|
|
||||||
|
|||||||
10
src/types/Upload.ts
Normal file
10
src/types/Upload.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export interface MulterFile {
|
||||||
|
fieldname: string
|
||||||
|
originalname: string
|
||||||
|
encoding: string
|
||||||
|
mimetype: string
|
||||||
|
destination: string
|
||||||
|
filename: string
|
||||||
|
path: string
|
||||||
|
size: number
|
||||||
|
}
|
||||||
@@ -24,3 +24,7 @@ export const generateUniqueFileName = (fileName: string, extension = '') =>
|
|||||||
new Date().getTime(),
|
new Date().getTime(),
|
||||||
extension
|
extension
|
||||||
].join('')
|
].join('')
|
||||||
|
|
||||||
|
export const addExtensionIfNotFound = (value: string, extension: string) => {
|
||||||
|
return !value.includes('.') ? `.${extension}` : ''
|
||||||
|
}
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { getTmpSessionsFolderPath } from '.'
|
import { getTmpSessionsFolderPath } from '.'
|
||||||
|
import { MulterFile } from '../types/Upload'
|
||||||
|
import { listFilesInFolder } from '@sasjs/utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It will create a object that maps hashed file names to the original names
|
* It will create an object that maps hashed file names to the original names
|
||||||
* @param files array of files to be mapped
|
* @param files array of files to be mapped
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export const makeFilesNamesMap = (files: any) => {
|
export const makeFilesNamesMap = (files: MulterFile[]) => {
|
||||||
if (!files) return null
|
if (!files) return null
|
||||||
|
|
||||||
const filesNamesMap: any = {}
|
const filesNamesMap: {[key: string]: string} = {}
|
||||||
|
|
||||||
for (let file of files) {
|
for (let file of files) {
|
||||||
filesNamesMap[file.filename] = file.fieldname
|
filesNamesMap[file.filename] = file.fieldname
|
||||||
@@ -20,7 +22,7 @@ export const makeFilesNamesMap = (files: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the sas code that reference uploaded files in the concurrent request
|
* Generates the sas code that references uploaded files in the concurrent request
|
||||||
* @param filesNamesMap object that maps hashed file names and original file names
|
* @param filesNamesMap object that maps hashed file names and original file names
|
||||||
* @param sasUploadFolder name of the folder that is created for the purpose of files in concurrent request
|
* @param sasUploadFolder name of the folder that is created for the purpose of files in concurrent request
|
||||||
* @returns generated sas code
|
* @returns generated sas code
|
||||||
@@ -29,8 +31,6 @@ export const makeFilesNamesMap = (files: any) => {
|
|||||||
filesNamesMap: any,
|
filesNamesMap: any,
|
||||||
sasSessionFolder: string
|
sasSessionFolder: string
|
||||||
): string => {
|
): string => {
|
||||||
const uploadFilesDirPath = sasSessionFolder
|
|
||||||
|
|
||||||
let uploadSasCode = ''
|
let uploadSasCode = ''
|
||||||
let fileCount = 0
|
let fileCount = 0
|
||||||
let uploadedFilesMap: {
|
let uploadedFilesMap: {
|
||||||
@@ -40,7 +40,8 @@ export const makeFilesNamesMap = (files: any) => {
|
|||||||
count: number
|
count: number
|
||||||
}[] = []
|
}[] = []
|
||||||
|
|
||||||
fs.readdirSync(uploadFilesDirPath).forEach((fileName) => {
|
|
||||||
|
fs.readdirSync(sasSessionFolder).forEach((fileName) => {
|
||||||
let fileCountString = fileCount < 100 ? '0' + fileCount : fileCount
|
let fileCountString = fileCount < 100 ? '0' + fileCount : fileCount
|
||||||
fileCountString = fileCount < 10 ? '00' + fileCount : fileCount
|
fileCountString = fileCount < 10 ? '00' + fileCount : fileCount
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ export const makeFilesNamesMap = (files: any) => {
|
|||||||
|
|
||||||
uploadedFilesMap.push({
|
uploadedFilesMap.push({
|
||||||
fileref: `_sjs${fileCountString}`,
|
fileref: `_sjs${fileCountString}`,
|
||||||
filepath: `${uploadFilesDirPath}/${fileName}`,
|
filepath: `${sasSessionFolder}/${fileName}`,
|
||||||
filename: filesNamesMap[fileName],
|
filename: filesNamesMap[fileName],
|
||||||
count: fileCount
|
count: fileCount
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user