mirror of
https://github.com/sasjs/server.git
synced 2026-01-11 08:20:04 +00:00
chore: restructure repo into sub folders
This commit is contained in:
155
api/src/routes/index.ts
Normal file
155
api/src/routes/index.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import {
|
||||
createFileTree,
|
||||
getTreeExample,
|
||||
sasjsExecutor,
|
||||
SASjsDriveController,
|
||||
ExecutionController,
|
||||
FileUploadController
|
||||
} from '../controllers'
|
||||
import { isExecutionQuery, isFileQuery, isFileTree } from '../types'
|
||||
import { getTmpFilesFolderPath, makeFilesNamesMap } from '../utils'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
const fileUploadController = new FileUploadController()
|
||||
|
||||
router.get('/', async (_, res) => {
|
||||
res.sendFile(
|
||||
path.join(__dirname, '..', '..', '..', 'web', 'build', 'index.html')
|
||||
)
|
||||
})
|
||||
|
||||
router.post('/deploy', async (req, res) => {
|
||||
if (!isFileTree({ members: req.body.members })) {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Provided not supported data format.',
|
||||
example: getTreeExample()
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await createFileTree(
|
||||
req.body.members,
|
||||
req.body.appLoc ? req.body.appLoc.replace(/^\//, '').split('/') : []
|
||||
)
|
||||
.then(() => {
|
||||
res.status(200).send({
|
||||
status: 'success',
|
||||
message: 'Files deployed successfully to @sasjs/server.'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
res
|
||||
.status(500)
|
||||
.send({ status: 'failure', message: 'Deployment failed!', ...err })
|
||||
})
|
||||
})
|
||||
|
||||
router.get('/SASjsApi/files', async (req, res) => {
|
||||
if (isFileQuery(req.query)) {
|
||||
const filePath = path
|
||||
.join(getTmpFilesFolderPath(), req.query.filePath)
|
||||
.replace(new RegExp('/', 'g'), path.sep)
|
||||
const fileContent = await new SASjsDriveController().readFile(filePath)
|
||||
res.status(200).send({ status: 'success', fileContent: fileContent })
|
||||
} else {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Invalid Request: Expected parameter filePath was not provided'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/SASjsApi/files', async (req, res) => {
|
||||
const filePath = path
|
||||
.join(getTmpFilesFolderPath(), req.body.filePath)
|
||||
.replace(new RegExp('/', 'g'), path.sep)
|
||||
await new SASjsDriveController().updateFile(filePath, req.body.fileContent)
|
||||
res.status(200).send({ status: 'success' })
|
||||
})
|
||||
|
||||
router.get('/SASjsApi/executor', async (req, res) => {
|
||||
const tree = sasjsExecutor()
|
||||
res.status(200).send({ status: 'success', tree })
|
||||
})
|
||||
|
||||
router.get('/SASjsExecutor/do', async (req, res) => {
|
||||
if (isExecutionQuery(req.query)) {
|
||||
let sasCodePath = path
|
||||
.join(getTmpFilesFolderPath(), req.query._program)
|
||||
.replace(new RegExp('/', 'g'), path.sep)
|
||||
|
||||
// If no extension provided, add .sas extension
|
||||
sasCodePath += '.sas'
|
||||
|
||||
await new ExecutionController()
|
||||
.execute(sasCodePath, undefined, undefined, { ...req.query })
|
||||
.then((result: {}) => {
|
||||
res.status(200).send(result)
|
||||
})
|
||||
.catch((err: {} | string) => {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: `Please provide the location of SAS code`
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
router.post(
|
||||
'/SASjsExecutor/do',
|
||||
fileUploadController.preuploadMiddleware,
|
||||
fileUploadController.getMulterUploadObject().any(),
|
||||
async (req: any, res: any) => {
|
||||
if (isExecutionQuery(req.query)) {
|
||||
let sasCodePath = path
|
||||
.join(getTmpFilesFolderPath(), req.query._program)
|
||||
.replace(new RegExp('/', 'g'), path.sep)
|
||||
|
||||
// If no extension provided, add .sas extension
|
||||
sasCodePath += '.sas'
|
||||
|
||||
let filesNamesMap = null
|
||||
|
||||
if (req.files && req.files.length > 0) {
|
||||
filesNamesMap = makeFilesNamesMap(req.files)
|
||||
}
|
||||
|
||||
await new ExecutionController()
|
||||
.execute(
|
||||
sasCodePath,
|
||||
undefined,
|
||||
req.sasSession,
|
||||
{ ...req.query, ...req.body },
|
||||
{ filesNamesMap: filesNamesMap }
|
||||
)
|
||||
.then((result: {}) => {
|
||||
res.status(200).send(result)
|
||||
})
|
||||
.catch((err: {} | string) => {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: `Please provide the location of SAS code`
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export default router
|
||||
101
api/src/routes/spec/routes.spec.ts
Normal file
101
api/src/routes/spec/routes.spec.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import request from 'supertest'
|
||||
import app from '../../app'
|
||||
import { getTreeExample } from '../../controllers/deploy'
|
||||
import { getTmpFilesFolderPath } from '../../utils/file'
|
||||
import { folderExists, fileExists, readFile, deleteFolder } from '@sasjs/utils'
|
||||
import path from 'path'
|
||||
|
||||
describe('deploy', () => {
|
||||
const shouldFailAssertion = async (payload: any) => {
|
||||
const res = await request(app).post('/deploy').send(payload)
|
||||
|
||||
expect(res.statusCode).toEqual(400)
|
||||
expect(res.body).toEqual({
|
||||
status: 'failure',
|
||||
message: 'Provided not supported data format.',
|
||||
example: getTreeExample()
|
||||
})
|
||||
}
|
||||
|
||||
it('should respond with payload example if valid payload was not provided', async () => {
|
||||
await shouldFailAssertion(null)
|
||||
await shouldFailAssertion(undefined)
|
||||
await shouldFailAssertion('data')
|
||||
await shouldFailAssertion({})
|
||||
await shouldFailAssertion({
|
||||
userId: 1,
|
||||
title: 'test is cool'
|
||||
})
|
||||
await shouldFailAssertion({
|
||||
membersWRONG: []
|
||||
})
|
||||
await shouldFailAssertion({
|
||||
members: {}
|
||||
})
|
||||
await shouldFailAssertion({
|
||||
members: [
|
||||
{
|
||||
nameWRONG: 'jobs',
|
||||
type: 'folder',
|
||||
members: []
|
||||
}
|
||||
]
|
||||
})
|
||||
await shouldFailAssertion({
|
||||
members: [
|
||||
{
|
||||
name: 'jobs',
|
||||
type: 'WRONG',
|
||||
members: []
|
||||
}
|
||||
]
|
||||
})
|
||||
await shouldFailAssertion({
|
||||
members: [
|
||||
{
|
||||
name: 'jobs',
|
||||
type: 'folder',
|
||||
members: [
|
||||
{
|
||||
name: 'extract',
|
||||
type: 'folder',
|
||||
members: [
|
||||
{
|
||||
name: 'makedata1',
|
||||
type: 'service',
|
||||
codeWRONG: '%put Hello World!;'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
it('should respond with payload example if valid payload was not provided', async () => {
|
||||
const res = await request(app).post('/deploy').send(getTreeExample())
|
||||
|
||||
expect(res.statusCode).toEqual(200)
|
||||
expect(res.text).toEqual(
|
||||
'{"status":"success","message":"Files deployed successfully to @sasjs/server."}'
|
||||
)
|
||||
await expect(folderExists(getTmpFilesFolderPath())).resolves.toEqual(true)
|
||||
|
||||
const testJobFolder = path.join(getTmpFilesFolderPath(), 'jobs', 'extract')
|
||||
await expect(folderExists(testJobFolder)).resolves.toEqual(true)
|
||||
|
||||
const testJobFile = path.join(
|
||||
testJobFolder,
|
||||
getTreeExample().members[0].members[0].members[0].name
|
||||
)
|
||||
|
||||
await expect(fileExists(testJobFile)).resolves.toEqual(true)
|
||||
|
||||
await expect(readFile(testJobFile)).resolves.toEqual(
|
||||
getTreeExample().members[0].members[0].members[0].code
|
||||
)
|
||||
|
||||
await deleteFolder(getTmpFilesFolderPath())
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user