1
0
mirror of https://github.com/sasjs/server.git synced 2026-01-09 07:20:05 +00:00

feat: App Stream, load on startup, new route added

This commit is contained in:
Saad Jutt
2022-03-21 17:17:29 +05:00
parent b0fb858c49
commit 98a00ec7ac
17 changed files with 265 additions and 47 deletions

View File

@@ -22,9 +22,12 @@ driveRouter.post('/deploy', async (req, res) => {
try {
const response = await controller.deploy(body)
const appLoc = body.appLoc.replace(/^\//, '')?.split('/')
publishAppStream(appLoc)
if (body.streamWebFolder)
publishAppStream(
body.appLoc,
body.streamWebFolder,
body.streamServiceName
)
res.send(response)
} catch (err: any) {

View File

@@ -266,7 +266,7 @@ describe('files', () => {
it("should respond with Bad Request if filePath doesn't has correct extension", async () => {
const fileToAttachPath = path.join(__dirname, 'files', 'sample.sas')
const pathToUpload = '/my/path/code.oth'
const pathToUpload = '/my/path/code.exe'
const res = await request(app)
.post(`/SASjsApi/drive/file?_filePath=${pathToUpload}`)
@@ -275,7 +275,7 @@ describe('files', () => {
.attach('file', fileToAttachPath)
.expect(400)
expect(res.text).toEqual('Valid extensions for filePath: .sas')
expect(res.text).toEqual('Invalid file extension')
expect(res.body).toEqual({})
})
@@ -293,7 +293,7 @@ describe('files', () => {
})
it("should respond with Bad Request if attached file doesn't has correct extension", async () => {
const fileToAttachPath = path.join(__dirname, 'files', 'sample.oth')
const fileToAttachPath = path.join(__dirname, 'files', 'sample.exe')
const pathToUpload = '/my/path/code.sas'
const res = await request(app)
@@ -303,9 +303,7 @@ describe('files', () => {
.attach('file', fileToAttachPath)
.expect(400)
expect(res.text).toEqual(
`File extension '.oth' not acceptable. Valid extension(s): .sas`
)
expect(res.text).toEqual(`File extension '.exe' not acceptable.`)
expect(res.body).toEqual({})
})
@@ -426,7 +424,7 @@ describe('files', () => {
it("should respond with Bad Request if filePath doesn't has correct extension", async () => {
const fileToAttachPath = path.join(__dirname, 'files', 'sample.sas')
const pathToUpload = '/my/path/code.oth'
const pathToUpload = '/my/path/code.exe'
const res = await request(app)
.patch(`/SASjsApi/drive/file?_filePath=${pathToUpload}`)
@@ -435,7 +433,7 @@ describe('files', () => {
.attach('file', fileToAttachPath)
.expect(400)
expect(res.text).toEqual('Valid extensions for filePath: .sas')
expect(res.text).toEqual('Invalid file extension')
expect(res.body).toEqual({})
})
@@ -453,7 +451,7 @@ describe('files', () => {
})
it("should respond with Bad Request if attached file doesn't has correct extension", async () => {
const fileToAttachPath = path.join(__dirname, 'files', 'sample.oth')
const fileToAttachPath = path.join(__dirname, 'files', 'sample.exe')
const pathToUpload = '/my/path/code.sas'
const res = await request(app)
@@ -463,9 +461,7 @@ describe('files', () => {
.attach('file', fileToAttachPath)
.expect(400)
expect(res.text).toEqual(
`File extension '.oth' not acceptable. Valid extension(s): .sas`
)
expect(res.text).toEqual(`File extension '.exe' not acceptable.`)
expect(res.body).toEqual({})
})

View File

@@ -0,0 +1,47 @@
import { AppStreamConfig } from '../../types'
const style = `<style>
* {
font-family: 'Roboto', sans-serif;
}
.app-container {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: center;
}
.app-container .app {
width: 100px;
margin: 10px;
overflow: hidden;
border-radius: 10px 10px 0 0;
text-align: center;
}
</style>`
const defaultAppLogo = '/sasjs-logo.svg'
const singleAppStreamHtml = (streamServiceName: string, logo?: string) =>
` <a class="app" href="${streamServiceName}">
<img src="${logo ?? defaultAppLogo}" />
${streamServiceName}
</a>`
export const appStreamHtml = (appStreamConfig: AppStreamConfig) => `
<html>
<head>
<base href="/AppStream/">
${style}
</head>
<body>
<h1>App Stream</h1>
<div class="app-container">
${Object.entries(appStreamConfig).map(([streamServiceName, entry]) =>
singleAppStreamHtml(streamServiceName, entry.logo)
)}
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a>
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a>
<a class="app" href="#"><img src="/sasjs-logo.svg" />App Name here</a>
</div>
</body>
</html>`

View File

@@ -2,24 +2,60 @@ import path from 'path'
import express from 'express'
import { folderExists } from '@sasjs/utils'
import { getTmpFilesFolderPath } from '../../utils'
import { addEntryToAppStreamConfig, getTmpFilesFolderPath } from '../../utils'
import { appStreamHtml } from './appStreamHtml'
const router = express.Router()
export const publishAppStream = async (appLoc: string[]) => {
const appLocUrl = encodeURI(appLoc.join('/'))
const appLocPath = appLoc.join(path.sep)
router.get('/', async (_, res) => {
const content = appStreamHtml(process.appStreamConfig)
const pathToDeployment = path.join(
getTmpFilesFolderPath(),
appLocPath,
'services',
'webv'
)
return res.send(content)
})
export const publishAppStream = async (
appLoc: string,
streamWebFolder: string,
streamServiceName?: string,
addEntryToFile: boolean = true
) => {
const driveFilesPath = getTmpFilesFolderPath()
const appLocParts = appLoc.replace(/^\//, '')?.split('/')
const appLocPath = path.join(driveFilesPath, ...appLocParts)
if (!appLocPath.includes(driveFilesPath)) {
throw new Error('appLoc cannot be outside drive.')
}
const pathToDeployment = path.join(appLocPath, 'services', streamWebFolder)
if (!pathToDeployment.includes(appLocPath)) {
throw new Error('streamWebFolder cannot be outside appLoc.')
}
if (await folderExists(pathToDeployment)) {
router.use(`/${appLocUrl}`, express.static(pathToDeployment))
console.log('Serving Stream App: ', appLocUrl)
const appCount = process.appStreamConfig
? Object.keys(process.appStreamConfig).length
: 0
if (!streamServiceName || process.appStreamConfig[streamServiceName]) {
streamServiceName = `AppStreamName${appCount + 1}`
}
router.use(`/${streamServiceName}`, express.static(pathToDeployment))
addEntryToAppStreamConfig(
streamServiceName,
appLoc,
streamWebFolder,
undefined,
addEntryToFile
)
const sasJsPort = process.env.PORT ?? 5000
console.log(
'Serving Stream App: ',
`http://localhost:${sasJsPort}/AppStream/${streamServiceName}`
)
}
}