mirror of
https://github.com/sasjs/server.git
synced 2026-01-08 07:00:04 +00:00
chore: drive auto-generated swagger
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { MemberType, FolderMember, ServiceMember } from '../types'
|
||||
import { MemberType, FolderMember, ServiceMember, FileTree } from '../types'
|
||||
import { getTmpFilesFolderPath } from '../utils/file'
|
||||
import { createFolder, createFile, asyncForEach } from '@sasjs/utils'
|
||||
import path from 'path'
|
||||
|
||||
// REFACTOR: export FileTreeCpntroller
|
||||
export const createFileTree = async (
|
||||
members: [FolderMember, ServiceMember],
|
||||
members: (FolderMember | ServiceMember)[],
|
||||
parentFolders: string[] = []
|
||||
) => {
|
||||
const destinationPath = path.join(
|
||||
@@ -16,7 +16,7 @@ export const createFileTree = async (
|
||||
await asyncForEach(members, async (member: FolderMember | ServiceMember) => {
|
||||
let name = member.name
|
||||
|
||||
if (member.type === 'service') name += '.sas'
|
||||
if (member.type === MemberType.service) name += '.sas'
|
||||
|
||||
if (member.type === MemberType.folder) {
|
||||
await createFolder(path.join(destinationPath, name)).catch((err) =>
|
||||
@@ -36,19 +36,19 @@ export const createFileTree = async (
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
export const getTreeExample = () => ({
|
||||
export const getTreeExample = (): FileTree => ({
|
||||
members: [
|
||||
{
|
||||
name: 'jobs',
|
||||
type: 'folder',
|
||||
type: MemberType.folder,
|
||||
members: [
|
||||
{
|
||||
name: 'extract',
|
||||
type: 'folder',
|
||||
type: MemberType.folder,
|
||||
members: [
|
||||
{
|
||||
name: 'makedata1',
|
||||
type: 'service',
|
||||
type: MemberType.service,
|
||||
code: '%put Hello World!;'
|
||||
}
|
||||
]
|
||||
|
||||
63
src/controllers/drive.ts
Normal file
63
src/controllers/drive.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Security, Route, Tags, Example, Post, Body, Response } from 'tsoa'
|
||||
import { createFileTree, getTreeExample } from '.'
|
||||
|
||||
import { FileTree, isFileTree } from '../types'
|
||||
|
||||
interface DeployPayload {
|
||||
appLoc?: string
|
||||
fileTree: FileTree
|
||||
}
|
||||
|
||||
interface DeployResponse {
|
||||
status: string
|
||||
message: string
|
||||
example?: FileTree
|
||||
}
|
||||
|
||||
const fileTreeExample = getTreeExample()
|
||||
|
||||
const successResponse: DeployResponse = {
|
||||
status: 'success',
|
||||
message: 'Files deployed successfully to @sasjs/server.'
|
||||
}
|
||||
const invalidFormatResponse: DeployResponse = {
|
||||
status: 'failure',
|
||||
message: 'Provided not supported data format.',
|
||||
example: fileTreeExample
|
||||
}
|
||||
const execErrorResponse: DeployResponse = {
|
||||
status: 'failure',
|
||||
message: 'Deployment failed!'
|
||||
}
|
||||
|
||||
@Security('bearerAuth')
|
||||
@Route('SASjsApi/drive')
|
||||
@Tags('Drive')
|
||||
export default class DriveController {
|
||||
/**
|
||||
* Creates/updates files within SASjs Drive using provided payload.
|
||||
*
|
||||
*/
|
||||
@Example<DeployResponse>(successResponse)
|
||||
@Response<DeployResponse>(400, 'Invalid Format', invalidFormatResponse)
|
||||
@Response<DeployResponse>(500, 'Execution Error', execErrorResponse)
|
||||
@Post('/deploy')
|
||||
public async deploy(@Body() body: DeployPayload): Promise<DeployResponse> {
|
||||
return deploy(body)
|
||||
}
|
||||
}
|
||||
|
||||
const deploy = async (data: DeployPayload) => {
|
||||
if (!isFileTree(data.fileTree)) {
|
||||
throw { code: 400, ...invalidFormatResponse }
|
||||
}
|
||||
|
||||
await createFileTree(
|
||||
data.fileTree.members,
|
||||
data.appLoc ? data.appLoc.replace(/^\//, '').split('/') : []
|
||||
).catch((err) => {
|
||||
throw { code: 500, ...execErrorResponse, ...err }
|
||||
})
|
||||
|
||||
return successResponse
|
||||
}
|
||||
@@ -1,35 +1,18 @@
|
||||
import express from 'express'
|
||||
import { createFileTree, getTreeExample } from '../../controllers'
|
||||
import { isFileTree } from '../../types'
|
||||
import DriveController from '../../controllers/drive'
|
||||
|
||||
const driveRouter = express.Router()
|
||||
|
||||
driveRouter.post('/deploy', async (req, res) => {
|
||||
if (!isFileTree(req.body.fileTree)) {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Provided not supported data format.',
|
||||
example: getTreeExample()
|
||||
})
|
||||
|
||||
return
|
||||
const controller = new DriveController()
|
||||
try {
|
||||
const response = await controller.deploy(req.body)
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
const statusCode = err.code
|
||||
delete err.code
|
||||
res.status(statusCode).send(err)
|
||||
}
|
||||
|
||||
await createFileTree(
|
||||
req.body.fileTree.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 })
|
||||
})
|
||||
})
|
||||
|
||||
export default driveRouter
|
||||
|
||||
@@ -25,7 +25,7 @@ router.use(
|
||||
swaggerUi.serve,
|
||||
swaggerUi.setup(undefined, {
|
||||
swaggerOptions: {
|
||||
url: '/swagger.json'
|
||||
url: '/swagger.yaml'
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ import { folderExists, fileExists, readFile, deleteFolder } from '@sasjs/utils'
|
||||
import path from 'path'
|
||||
import { generateAccessToken } from '../../../controllers/auth'
|
||||
import { saveTokensInDB } from '../../../utils'
|
||||
import { FolderMember, ServiceMember } from '../../../types'
|
||||
|
||||
const clientId = 'someclientID'
|
||||
const user = {
|
||||
@@ -135,21 +136,20 @@ describe('files', () => {
|
||||
)
|
||||
await expect(folderExists(testJobFolder)).resolves.toEqual(true)
|
||||
|
||||
const testJobFile =
|
||||
path.join(
|
||||
testJobFolder,
|
||||
getTreeExample().members[0].members[0].members[0].name
|
||||
) + '.sas'
|
||||
const exampleService = getExampleService()
|
||||
const testJobFile = path.join(testJobFolder, exampleService.name) + '.sas'
|
||||
|
||||
console.log(`[testJobFile]`, testJobFile)
|
||||
|
||||
await expect(fileExists(testJobFile)).resolves.toEqual(true)
|
||||
|
||||
await expect(readFile(testJobFile)).resolves.toEqual(
|
||||
getTreeExample().members[0].members[0].members[0].code
|
||||
)
|
||||
await expect(readFile(testJobFile)).resolves.toEqual(exampleService.code)
|
||||
|
||||
await deleteFolder(getTmpFilesFolderPath())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const getExampleService = (): ServiceMember =>
|
||||
((getTreeExample().members[0] as FolderMember).members[0] as FolderMember)
|
||||
.members[0] as ServiceMember
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export interface FileTree {
|
||||
members: [FolderMember, ServiceMember]
|
||||
members: (FolderMember | ServiceMember)[]
|
||||
}
|
||||
|
||||
export enum MemberType {
|
||||
@@ -10,7 +10,7 @@ export enum MemberType {
|
||||
export interface FolderMember {
|
||||
name: string
|
||||
type: MemberType.folder
|
||||
members: [FolderMember, ServiceMember]
|
||||
members: (FolderMember | ServiceMember)[]
|
||||
}
|
||||
|
||||
export interface ServiceMember {
|
||||
|
||||
Reference in New Issue
Block a user