mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 19:34:34 +00:00
feat: created api endpoint for adding empty folder in drive
This commit is contained in:
@@ -230,7 +230,7 @@ components:
|
||||
- fileTree
|
||||
type: object
|
||||
additionalProperties: false
|
||||
UpdateFileResponse:
|
||||
FileFolderResponse:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
@@ -240,6 +240,16 @@ components:
|
||||
- status
|
||||
type: object
|
||||
additionalProperties: false
|
||||
AddFolderPayload:
|
||||
properties:
|
||||
folderPath:
|
||||
type: string
|
||||
description: 'Location of folder'
|
||||
example: /Public/someFolder
|
||||
required:
|
||||
- folderPath
|
||||
type: object
|
||||
additionalProperties: false
|
||||
TreeNode:
|
||||
properties:
|
||||
name:
|
||||
@@ -839,7 +849,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateFileResponse'
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: success}
|
||||
@@ -848,7 +858,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateFileResponse'
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'File request failed.'}
|
||||
@@ -861,7 +871,7 @@ paths:
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'Location of SAS program'
|
||||
description: 'Location of file'
|
||||
in: query
|
||||
name: _filePath
|
||||
required: false
|
||||
@@ -890,7 +900,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateFileResponse'
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: success}
|
||||
@@ -899,7 +909,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateFileResponse'
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'File request failed.'}
|
||||
@@ -990,6 +1000,40 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
example: /Public/somefolder/
|
||||
post:
|
||||
operationId: AddFolder
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: success}
|
||||
'409':
|
||||
description: 'Folder already exists'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/FileFolderResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'Add folder request failed.'}
|
||||
summary: 'Create an empty folder in SASjs Drive'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AddFolderPayload'
|
||||
/SASjsApi/drive/filetree:
|
||||
get:
|
||||
operationId: GetFileTree
|
||||
|
||||
@@ -59,11 +59,19 @@ interface GetFileTreeResponse {
|
||||
tree: TreeNode
|
||||
}
|
||||
|
||||
interface UpdateFileResponse {
|
||||
interface FileFolderResponse {
|
||||
status: string
|
||||
message?: string
|
||||
}
|
||||
|
||||
interface AddFolderPayload {
|
||||
/**
|
||||
* Location of folder
|
||||
* @example "/Public/someFolder"
|
||||
*/
|
||||
folderPath: string
|
||||
}
|
||||
|
||||
const fileTreeExample = getTreeExample()
|
||||
|
||||
const successDeployResponse: DeployResponse = {
|
||||
@@ -141,6 +149,17 @@ export class DriveController {
|
||||
return getFolder(_folderPath)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Delete file from SASjs Drive
|
||||
* @query _filePath Location of file
|
||||
* @example _filePath "/Public/somefolder/some.file"
|
||||
*/
|
||||
@Delete('/file')
|
||||
public async deleteFile(@Query() _filePath: string) {
|
||||
return deleteFile(_filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Delete folder from SASjs Drive
|
||||
@@ -152,31 +171,20 @@ export class DriveController {
|
||||
return deleteFolder(_folderPath)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Delete file from SASjs Drive
|
||||
* @query _filePath Location of SAS program
|
||||
* @example _filePath "/Public/somefolder/some.file"
|
||||
*/
|
||||
@Delete('/file')
|
||||
public async deleteFile(@Query() _filePath: string) {
|
||||
return deleteFile(_filePath)
|
||||
}
|
||||
|
||||
/**
|
||||
* It's optional to either provide `_filePath` in url as query parameter
|
||||
* Or provide `filePath` in body as form field.
|
||||
* But it's required to provide else API will respond with Bad Request.
|
||||
*
|
||||
* @summary Create a file in SASjs Drive
|
||||
* @param _filePath Location of SAS program
|
||||
* @param _filePath Location of file
|
||||
* @example _filePath "/Public/somefolder/some.file.sas"
|
||||
*
|
||||
*/
|
||||
@Example<UpdateFileResponse>({
|
||||
@Example<FileFolderResponse>({
|
||||
status: 'success'
|
||||
})
|
||||
@Response<UpdateFileResponse>(403, 'File already exists', {
|
||||
@Response<FileFolderResponse>(403, 'File already exists', {
|
||||
status: 'failure',
|
||||
message: 'File request failed.'
|
||||
})
|
||||
@@ -185,10 +193,28 @@ export class DriveController {
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Query() _filePath?: string,
|
||||
@FormField() filePath?: string
|
||||
): Promise<UpdateFileResponse> {
|
||||
): Promise<FileFolderResponse> {
|
||||
return saveFile((_filePath ?? filePath)!, file)
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Create an empty folder in SASjs Drive
|
||||
*
|
||||
*/
|
||||
@Example<FileFolderResponse>({
|
||||
status: 'success'
|
||||
})
|
||||
@Response<FileFolderResponse>(409, 'Folder already exists', {
|
||||
status: 'failure',
|
||||
message: 'Add folder request failed.'
|
||||
})
|
||||
@Post('/folder')
|
||||
public async addFolder(
|
||||
@Body() body: AddFolderPayload
|
||||
): Promise<FileFolderResponse> {
|
||||
return addFolder(body.folderPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* It's optional to either provide `_filePath` in url as query parameter
|
||||
* Or provide `filePath` in body as form field.
|
||||
@@ -199,10 +225,10 @@ export class DriveController {
|
||||
* @example _filePath "/Public/somefolder/some.file.sas"
|
||||
*
|
||||
*/
|
||||
@Example<UpdateFileResponse>({
|
||||
@Example<FileFolderResponse>({
|
||||
status: 'success'
|
||||
})
|
||||
@Response<UpdateFileResponse>(403, `File doesn't exist`, {
|
||||
@Response<FileFolderResponse>(403, `File doesn't exist`, {
|
||||
status: 'failure',
|
||||
message: 'File request failed.'
|
||||
})
|
||||
@@ -211,7 +237,7 @@ export class DriveController {
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Query() _filePath?: string,
|
||||
@FormField() filePath?: string
|
||||
): Promise<UpdateFileResponse> {
|
||||
): Promise<FileFolderResponse> {
|
||||
return updateFile((_filePath ?? filePath)!, file)
|
||||
}
|
||||
|
||||
@@ -372,6 +398,26 @@ const saveFile = async (
|
||||
return { status: 'success' }
|
||||
}
|
||||
|
||||
const addFolder = async (folderPath: string): Promise<FileFolderResponse> => {
|
||||
const drivePath = getFilesFolder()
|
||||
|
||||
const folderPathFull = path
|
||||
.join(drivePath, folderPath)
|
||||
.replace(new RegExp('/', 'g'), path.sep)
|
||||
|
||||
if (!folderPathFull.includes(drivePath)) {
|
||||
throw new Error('Cannot put folder outside drive.')
|
||||
}
|
||||
|
||||
if (await folderExists(folderPathFull)) {
|
||||
throw new Error('Folder already exists.')
|
||||
}
|
||||
|
||||
await createFolder(folderPathFull)
|
||||
|
||||
return { status: 'success' }
|
||||
}
|
||||
|
||||
const updateFile = async (
|
||||
filePath: string,
|
||||
multerFile: Express.Multer.File
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
extractName,
|
||||
fileBodyValidation,
|
||||
fileParamValidation,
|
||||
folderBodyValidation,
|
||||
folderParamValidation,
|
||||
isZipFile
|
||||
} from '../../utils'
|
||||
@@ -190,6 +191,19 @@ driveRouter.post(
|
||||
}
|
||||
)
|
||||
|
||||
driveRouter.post('/folder', async (req, res) => {
|
||||
const { error, value: body } = folderBodyValidation(req.body)
|
||||
|
||||
if (error) return res.status(400).send(error.details[0].message)
|
||||
|
||||
try {
|
||||
const response = await controller.addFolder(body)
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
res.status(403).send(err.toString())
|
||||
}
|
||||
})
|
||||
|
||||
driveRouter.patch(
|
||||
'/file',
|
||||
(...arg) => multerSingle('file', arg),
|
||||
|
||||
@@ -143,6 +143,11 @@ export const folderParamValidation = (data: any): Joi.ValidationResult =>
|
||||
_folderPath: Joi.string()
|
||||
}).validate(data)
|
||||
|
||||
export const folderBodyValidation = (data: any): Joi.ValidationResult =>
|
||||
Joi.object({
|
||||
folderPath: Joi.string()
|
||||
}).validate(data)
|
||||
|
||||
export const runCodeValidation = (data: any): Joi.ValidationResult =>
|
||||
Joi.object({
|
||||
code: Joi.string().required(),
|
||||
|
||||
Reference in New Issue
Block a user