mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 15:00:57 +03:00
feature: modularized express routes for reusability, testability, composability and performance (#2030)
* transition GET /api/v1/apikey * transition POST /api/v1/apikey * transition PUT /api/v1/apikey/:id * transition DELETE /api/v1/apikey/:id * Enable e2e tests for api/v1/apikey routes * remove unused addChatflowsCount * Enable e2e tests for api/v1/variables routes * Enable Cypress in GitHub Action * Update main.yml * Update main.yml * Transition GET /api/v1/variables * Enable cypress on github workflow * Transition POST /api/v1/variables * Transition PUT /api/v1/variables * Transition DELETE /api/v1/variables * Transition GET /api/v1/variables * Transition GET /api/v1/chatflows * Transition GET /api/v1/chatflows/:id * Transition POST /api/v1/chatflows * Transition DELETE /api/v1/chatflows/:id * Transition PUT /api/v1/chatflows/:id * Transition GET /api/v1/chatflows/apikey/:apiKey * Transition GET /api/v1/credentials * Transition POST /api/v1/credentials * Transition GET /api/v1/credentials/:id * Transition PUT /api/v1/credentials/:id * Transition DELETE /api/v1/credentials/:id * Transition GET /api/v1/tools * Transition GET /api/v1/tools/:id * Transition POST /api/v1/tools * Transition PUT & DELETE /api/v1/tools/:id * Transition /api/v1/assistants routes * Transition /api/v1/nodes routes * Transition GET /api/v1/chatflows-streaming/:id & GET /api/v1/chatflows-uploads/:id * wip-all-routes * Transition GET /api/v1/public-chatflows/:id & /api/v1/public-chatbotConfig/:id * Remove ts-ignore annotations * Transition GET /api/v1/chatmessage/:id * Transition POST /api/v1/chatmessage/:id * delete /api/v1/chatmessage/:id * transition /api/v1/feedback/:id routes * transition /api/v1/stats/:id * Transition GET /api/v1/openai-assistants/:id * Transition GET /api/v1/openai-assistants * Transition POST /api/v1/openai-assistants-file * transition GET /api/v1/get-upload-path * transition GET /api/v1/get-upload-file * transition GET /api/v1/flow-config/:id * transition POST /api/v1/node-config * transition GET /api/v1/version * transition GET /api/v1/fetch-links * transition POST /api/v1/vector/upsert/:id * transition POST /api/v1/vector/internal-upsert/:id * transition POST /api/v1/load-prompt * Update index.ts * transition POST /api/v1/prompts-list * transition predictions * Update index.ts * transition GET /api/v1/marketplaces/templates * Router update modularity cleanup * extend request interface - express namespace * Update index.ts * add errorMiddleware * Add custom application error handler * Fix pnpm lock file * prediction return and vector upsert * Move the getUploadsConfig into its own file * Remove lint warnings * fix undefined variable value * Fix node-load-method api call * standardize the error message display * Apply review comment bugfixes * Update index.ts * standardize error message display in snack notifications * Error message standard in the UI * Rename flowXpressApp to appServer * Upload middleware fix and axios update * fix async await --------- Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
committed by
GitHub
parent
ea255db15d
commit
957694a912
@@ -0,0 +1,79 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { StatusCodes } from 'http-status-codes'
|
||||
import { ApiError } from '../../errors/apiError'
|
||||
import apikeyService from '../../services/apikey'
|
||||
|
||||
// Get api keys
|
||||
const getAllApiKeys = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await apikeyService.getAllApiKeys()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const createApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body.keyName === 'undefined' || req.body.keyName === '') {
|
||||
throw new ApiError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.createApiKey - keyName not provided!`)
|
||||
}
|
||||
const apiResponse = await apikeyService.createApiKey(req.body.keyName)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Update api key
|
||||
const updateApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
new ApiError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - id not provided!`)
|
||||
}
|
||||
if (typeof req.body.keyName === 'undefined' || req.body.keyName === '') {
|
||||
new ApiError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - keyName not provided!`)
|
||||
}
|
||||
const apiResponse = await apikeyService.updateApiKey(req.params.id, req.body.keyName)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete api key
|
||||
const deleteApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
new ApiError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.deleteApiKey - id not provided!`)
|
||||
}
|
||||
const apiResponse = await apikeyService.deleteApiKey(req.params.id)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify api key
|
||||
const verifyApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.apiKey === 'undefined' || req.params.apiKey === '') {
|
||||
new ApiError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.verifyApiKey - apiKey not provided!`)
|
||||
}
|
||||
const apiResponse = await apikeyService.verifyApiKey(req.params.apiKey)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createApiKey,
|
||||
deleteApiKey,
|
||||
getAllApiKeys,
|
||||
updateApiKey,
|
||||
verifyApiKey
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import assistantsService from '../../services/assistants'
|
||||
|
||||
const creatAssistant = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: assistantsController.creatAssistant - body not provided!`)
|
||||
}
|
||||
const apiResponse = await assistantsService.creatAssistant(req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteAssistant = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: assistantsController.deleteAssistant - id not provided!`)
|
||||
}
|
||||
const apiResponse = await assistantsService.deleteAssistant(req.params.id, req.query.isDeleteBoth)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllAssistants = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await assistantsService.getAllAssistants()
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAssistantById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: assistantsController.getAssistantById - id not provided!`)
|
||||
}
|
||||
const apiResponse = await assistantsService.getAssistantById(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateAssistant = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: assistantsController.updateAssistant - id not provided!`)
|
||||
}
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: assistantsController.updateAssistant - body not provided!`)
|
||||
}
|
||||
const apiResponse = await assistantsService.updateAssistant(req.params.id, req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
creatAssistant,
|
||||
deleteAssistant,
|
||||
getAllAssistants,
|
||||
getAssistantById,
|
||||
updateAssistant
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { chatType, IReactFlowObject } from '../../Interface'
|
||||
import chatflowsService from '../../services/chatflows'
|
||||
import chatMessagesService from '../../services/chat-messages'
|
||||
import { clearSessionMemory } from '../../utils'
|
||||
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
|
||||
import { FindOptionsWhere } from 'typeorm'
|
||||
import { ChatMessage } from '../../database/entities/ChatMessage'
|
||||
|
||||
const createChatMessage = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error('Error: chatMessagesController.createChatMessage - request body not provided!')
|
||||
}
|
||||
const apiResponse = await chatMessagesService.createChatMessage(req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllChatMessages = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
let chatTypeFilter = req.query?.chatType as chatType | undefined
|
||||
if (chatTypeFilter) {
|
||||
try {
|
||||
const chatTypeFilterArray = JSON.parse(chatTypeFilter)
|
||||
if (chatTypeFilterArray.includes(chatType.EXTERNAL) && chatTypeFilterArray.includes(chatType.INTERNAL)) {
|
||||
chatTypeFilter = undefined
|
||||
} else if (chatTypeFilterArray.includes(chatType.EXTERNAL)) {
|
||||
chatTypeFilter = chatType.EXTERNAL
|
||||
} else if (chatTypeFilterArray.includes(chatType.INTERNAL)) {
|
||||
chatTypeFilter = chatType.INTERNAL
|
||||
}
|
||||
} catch (e) {
|
||||
return res.status(500).send(e)
|
||||
}
|
||||
}
|
||||
const sortOrder = req.query?.order as string | undefined
|
||||
const chatId = req.query?.chatId as string | undefined
|
||||
const memoryType = req.query?.memoryType as string | undefined
|
||||
const sessionId = req.query?.sessionId as string | undefined
|
||||
const messageId = req.query?.messageId as string | undefined
|
||||
const startDate = req.query?.startDate as string | undefined
|
||||
const endDate = req.query?.endDate as string | undefined
|
||||
const feedback = req.query?.feedback as boolean | undefined
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatMessageController.getAllChatMessages - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatMessagesService.getAllChatMessages(
|
||||
req.params.id,
|
||||
chatTypeFilter,
|
||||
sortOrder,
|
||||
chatId,
|
||||
memoryType,
|
||||
sessionId,
|
||||
startDate,
|
||||
endDate,
|
||||
messageId,
|
||||
feedback
|
||||
)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllInternalChatMessages = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const sortOrder = req.query?.order as string | undefined
|
||||
const chatId = req.query?.chatId as string | undefined
|
||||
const memoryType = req.query?.memoryType as string | undefined
|
||||
const sessionId = req.query?.sessionId as string | undefined
|
||||
const messageId = req.query?.messageId as string | undefined
|
||||
const startDate = req.query?.startDate as string | undefined
|
||||
const endDate = req.query?.endDate as string | undefined
|
||||
const feedback = req.query?.feedback as boolean | undefined
|
||||
const apiResponse = await chatMessagesService.getAllInternalChatMessages(
|
||||
req.params.id,
|
||||
chatType.INTERNAL,
|
||||
sortOrder,
|
||||
chatId,
|
||||
memoryType,
|
||||
sessionId,
|
||||
startDate,
|
||||
endDate,
|
||||
messageId,
|
||||
feedback
|
||||
)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
//Delete all chatmessages from chatId
|
||||
const removeAllChatMessages = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const appServer = getRunningExpressApp()
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error('Error: chatMessagesController.removeAllChatMessages - id not provided!')
|
||||
}
|
||||
const chatflowid = req.params.id
|
||||
const chatflow = await chatflowsService.getChatflowById(req.params.id)
|
||||
if (!chatflow) {
|
||||
return res.status(404).send(`Chatflow ${req.params.id} not found`)
|
||||
}
|
||||
const chatId = req.query?.chatId as string
|
||||
const memoryType = req.query?.memoryType as string | undefined
|
||||
const sessionId = req.query?.sessionId as string | undefined
|
||||
const chatType = req.query?.chatType as string | undefined
|
||||
const isClearFromViewMessageDialog = req.query?.isClearFromViewMessageDialog as string | undefined
|
||||
const flowData = chatflow.flowData
|
||||
const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
|
||||
const nodes = parsedFlowData.nodes
|
||||
try {
|
||||
await clearSessionMemory(
|
||||
nodes,
|
||||
appServer.nodesPool.componentNodes,
|
||||
chatId,
|
||||
appServer.AppDataSource,
|
||||
sessionId,
|
||||
memoryType,
|
||||
isClearFromViewMessageDialog
|
||||
)
|
||||
} catch (e) {
|
||||
return res.status(500).send('Error clearing chat messages')
|
||||
}
|
||||
|
||||
const deleteOptions: FindOptionsWhere<ChatMessage> = { chatflowid }
|
||||
if (chatId) deleteOptions.chatId = chatId
|
||||
if (memoryType) deleteOptions.memoryType = memoryType
|
||||
if (sessionId) deleteOptions.sessionId = sessionId
|
||||
if (chatType) deleteOptions.chatType = chatType
|
||||
const apiResponse = await chatMessagesService.removeAllChatMessages(chatId, chatflowid, deleteOptions)
|
||||
if (apiResponse.executionError) {
|
||||
res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createChatMessage,
|
||||
getAllChatMessages,
|
||||
getAllInternalChatMessages,
|
||||
removeAllChatMessages
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import chatflowsService from '../../services/chatflows'
|
||||
import { ChatFlow } from '../../database/entities/ChatFlow'
|
||||
import { createRateLimiter } from '../../utils/rateLimit'
|
||||
import { getApiKey } from '../../utils/apiKey'
|
||||
|
||||
const checkIfChatflowIsValidForStreaming = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.checkIfChatflowIsValidForStreaming - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.checkIfChatflowIsValidForStreaming(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const checkIfChatflowIsValidForUploads = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.checkIfChatflowIsValidForUploads - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.checkIfChatflowIsValidForUploads(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.deleteChatflow - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.deleteChatflow(req.params.id)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllChatflows = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await chatflowsService.getAllChatflows()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Get specific chatflow via api key
|
||||
const getChatflowByApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.apiKey === 'undefined' || req.params.apiKey === '') {
|
||||
throw new Error(`Error: chatflowsRouter.getChatflowById - apiKey not provided!`)
|
||||
}
|
||||
const apiKey = await getApiKey(req.params.apiKey)
|
||||
if (!apiKey) {
|
||||
return res.status(401).send('Unauthorized')
|
||||
}
|
||||
const apiResponse = await chatflowsService.getChatflowByApiKey(apiKey.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getChatflowById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.getChatflowById - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.getChatflowById(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const saveChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: chatflowsRouter.saveChatflow - body not provided!`)
|
||||
}
|
||||
const body = req.body
|
||||
const newChatFlow = new ChatFlow()
|
||||
Object.assign(newChatFlow, body)
|
||||
const apiResponse = await chatflowsService.saveChatflow(newChatFlow)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.updateChatflow - id not provided!`)
|
||||
}
|
||||
const chatflow = await chatflowsService.getChatflowById(req.params.id)
|
||||
if (!chatflow) {
|
||||
return res.status(404).send(`Chatflow ${req.params.id} not found`)
|
||||
}
|
||||
const body = req.body
|
||||
const updateChatFlow = new ChatFlow()
|
||||
Object.assign(updateChatFlow, body)
|
||||
updateChatFlow.id = chatflow.id
|
||||
createRateLimiter(updateChatFlow)
|
||||
const apiResponse = await chatflowsService.updateChatflow(chatflow, updateChatFlow)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getSinglePublicChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.updateChatflow - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.getSinglePublicChatflow(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getSinglePublicChatbotConfig = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: chatflowsRouter.getSinglePublicChatbotConfig - id not provided!`)
|
||||
}
|
||||
const apiResponse = await chatflowsService.getSinglePublicChatbotConfig(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
checkIfChatflowIsValidForStreaming,
|
||||
checkIfChatflowIsValidForUploads,
|
||||
deleteChatflow,
|
||||
getAllChatflows,
|
||||
getChatflowByApiKey,
|
||||
getChatflowById,
|
||||
saveChatflow,
|
||||
updateChatflow,
|
||||
getSinglePublicChatflow,
|
||||
getSinglePublicChatbotConfig
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import componentsCredentialsService from '../../services/components-credentials'
|
||||
|
||||
// Get all component credentials
|
||||
const getAllComponentsCredentials = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await componentsCredentialsService.getAllComponentsCredentials()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Get component credential via name
|
||||
const getComponentByName = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.name === 'undefined' || req.params.name === '') {
|
||||
throw new Error(`Error: componentsCredentialsController.getComponentByName - name not provided!`)
|
||||
}
|
||||
const apiResponse = await componentsCredentialsService.getComponentByName(req.params.name)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns specific component credential icon via name
|
||||
const getSingleComponentsCredentialIcon = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.name === 'undefined' || req.params.name === '') {
|
||||
throw new Error(`Error: componentsCredentialsController.getSingleComponentsCredentialIcon - name not provided!`)
|
||||
}
|
||||
const apiResponse = await componentsCredentialsService.getSingleComponentsCredentialIcon(req.params.name)
|
||||
return res.sendFile(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllComponentsCredentials,
|
||||
getComponentByName,
|
||||
getSingleComponentsCredentialIcon
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import credentialsService from '../../services/credentials'
|
||||
|
||||
const createCredential = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: credentialsController.createCredential - body not provided!`)
|
||||
}
|
||||
const apiResponse = await credentialsService.createCredential(req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCredentials = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: credentialsController.deleteCredentials - id not provided!`)
|
||||
}
|
||||
const apiResponse = await credentialsService.deleteCredentials(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllCredentials = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await credentialsService.getAllCredentials(req.query.credentialName)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getCredentialById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: credentialsController.getCredentialById - id not provided!`)
|
||||
}
|
||||
const apiResponse = await credentialsService.getCredentialById(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateCredential = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: credentialsController.updateCredential - id not provided!`)
|
||||
}
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: credentialsController.updateCredential - body not provided!`)
|
||||
}
|
||||
const apiResponse = await credentialsService.updateCredential(req.params.id, req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createCredential,
|
||||
deleteCredentials,
|
||||
getAllCredentials,
|
||||
getCredentialById,
|
||||
updateCredential
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import feedbackService from '../../services/feedback'
|
||||
|
||||
const getAllChatMessageFeedback = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: feedbackController.getAllChatMessageFeedback - id not provided!`)
|
||||
}
|
||||
const chatflowid = req.params.id
|
||||
const chatId = req.query?.chatId as string | undefined
|
||||
const sortOrder = req.query?.order as string | undefined
|
||||
const startDate = req.query?.startDate as string | undefined
|
||||
const endDate = req.query?.endDate as string | undefined
|
||||
const apiResponse = await feedbackService.getAllChatMessageFeedback(chatflowid, chatId, sortOrder, startDate, endDate)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const createChatMessageFeedbackForChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: feedbackController.createChatMessageFeedbackForChatflow - body not provided!`)
|
||||
}
|
||||
const apiResponse = await feedbackService.createChatMessageFeedbackForChatflow(req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateChatMessageFeedbackForChatflow = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: feedbackController.updateChatMessageFeedbackForChatflow - body not provided!`)
|
||||
}
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: feedbackController.updateChatMessageFeedbackForChatflow - id not provided!`)
|
||||
}
|
||||
const apiResponse = await feedbackService.updateChatMessageFeedbackForChatflow(req.params.id, req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllChatMessageFeedback,
|
||||
createChatMessageFeedbackForChatflow,
|
||||
updateChatMessageFeedbackForChatflow
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import fetchLinksService from '../../services/fetch-links'
|
||||
|
||||
const getAllLinks = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.query.url === 'undefined' || req.query.url === '') {
|
||||
throw new Error(`Error: fetchLinksController.getAllLinks - url not provided!`)
|
||||
}
|
||||
if (typeof req.query.relativeLinksMethod === 'undefined' || req.query.relativeLinksMethod === '') {
|
||||
throw new Error(`Error: fetchLinksController.getAllLinks - relativeLinksMethod not provided!`)
|
||||
}
|
||||
if (typeof req.query.limit === 'undefined' || req.query.limit === '') {
|
||||
throw new Error(`Error: fetchLinksController.getAllLinks - limit not provided!`)
|
||||
}
|
||||
const apiResponse = await fetchLinksService.getAllLinks(
|
||||
req.query.url as string,
|
||||
req.query.relativeLinksMethod as string,
|
||||
req.query.limit as string
|
||||
)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllLinks
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import flowConfigsService from '../../services/flow-configs'
|
||||
|
||||
const getSingleFlowConfig = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: flowConfigsController.getSingleFlowConfig - id not provided!`)
|
||||
}
|
||||
const apiResponse = await flowConfigsService.getSingleFlowConfig(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getSingleFlowConfig
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import path from 'path'
|
||||
import contentDisposition from 'content-disposition'
|
||||
import { getStoragePath } from 'flowise-components'
|
||||
import * as fs from 'fs'
|
||||
|
||||
const streamUploadedImage = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (!req.query.chatflowId || !req.query.chatId || !req.query.fileName) {
|
||||
return res.status(500).send(`Invalid file path`)
|
||||
}
|
||||
const chatflowId = req.query.chatflowId as string
|
||||
const chatId = req.query.chatId as string
|
||||
const fileName = req.query.fileName as string
|
||||
const filePath = path.join(getStoragePath(), chatflowId, chatId, fileName)
|
||||
//raise error if file path is not absolute
|
||||
if (!path.isAbsolute(filePath)) return res.status(500).send(`Invalid file path`)
|
||||
//raise error if file path contains '..'
|
||||
if (filePath.includes('..')) return res.status(500).send(`Invalid file path`)
|
||||
//only return from the storage folder
|
||||
if (!filePath.startsWith(getStoragePath())) return res.status(500).send(`Invalid file path`)
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
res.setHeader('Content-Disposition', contentDisposition(path.basename(filePath)))
|
||||
const fileStream = fs.createReadStream(filePath)
|
||||
fileStream.pipe(res)
|
||||
} else {
|
||||
return res.status(404).send(`File ${fileName} not found`)
|
||||
}
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
streamUploadedImage
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { getStoragePath } from 'flowise-components'
|
||||
|
||||
const getPathForUploads = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = {
|
||||
storagePath: getStoragePath()
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getPathForUploads
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { utilBuildChatflow } from '../../utils/buildChatflow'
|
||||
|
||||
// Send input message and get prediction result (Internal)
|
||||
const createInternalPrediction = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await utilBuildChatflow(req, req.io, true)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createInternalPrediction
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
|
||||
// Configure number of proxies in Host Environment
|
||||
const configureProxyNrInHostEnv = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.ip === 'undefined' || req.ip) {
|
||||
throw new Error(`Error: ipController.configureProxyNrInHostEnv - ip not provided!`)
|
||||
}
|
||||
const apiResponse = {
|
||||
ip: req.ip,
|
||||
msg: `Check returned IP address in the response. If it matches your current IP address ( which you can get by going to http://ip.nfriedly.com/ or https://api.ipify.org/ ), then the number of proxies is correct and the rate limiter should now work correctly. If not, increase the number of proxies by 1 and restart Cloud-Hosted Flowise until the IP address matches your own. Visit https://docs.flowiseai.com/configuration/rate-limit#cloud-hosted-rate-limit-setup-guide for more information.`
|
||||
}
|
||||
return res.send(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
configureProxyNrInHostEnv
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import loadPromptsService from '../../services/load-prompts'
|
||||
|
||||
const createPrompt = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || typeof req.body.promptName === 'undefined' || req.body.promptName === '') {
|
||||
throw new Error(`Error: loadPromptsController.createPrompt - promptName not provided!`)
|
||||
}
|
||||
const apiResponse = await loadPromptsService.createPrompt(req.body.promptName as string)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createPrompt
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import marketplacesService from '../../services/marketplaces'
|
||||
|
||||
// Get all templates for marketplaces
|
||||
const getAllTemplates = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await marketplacesService.getAllTemplates()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllTemplates
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import nodeConfigsService from '../../services/node-configs'
|
||||
|
||||
const getAllNodeConfigs = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: nodeConfigsController.getAllNodeConfigs - body not provided!`)
|
||||
}
|
||||
const apiResponse = await nodeConfigsService.getAllNodeConfigs(req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllNodeConfigs
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
|
||||
|
||||
// Returns specific component node icon via name
|
||||
const getSingleNodeIcon = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const appServer = getRunningExpressApp()
|
||||
if (Object.prototype.hasOwnProperty.call(appServer.nodesPool.componentNodes, req.params.name)) {
|
||||
const nodeInstance = appServer.nodesPool.componentNodes[req.params.name]
|
||||
if (nodeInstance.icon === undefined) {
|
||||
throw new Error(`Error: nodeIconController.getSingleNodeIcon - Node ${req.params.name} icon not found`)
|
||||
}
|
||||
|
||||
if (nodeInstance.icon.endsWith('.svg') || nodeInstance.icon.endsWith('.png') || nodeInstance.icon.endsWith('.jpg')) {
|
||||
const filepath = nodeInstance.icon
|
||||
res.sendFile(filepath)
|
||||
} else {
|
||||
throw new Error(`Error: nodeIconController.getSingleNodeIcon - Node ${req.params.name} icon is missing icon`)
|
||||
}
|
||||
} else {
|
||||
throw new Error(`Error: nodeIconController.getSingleNodeIcon - Node ${req.params.name} not found`)
|
||||
}
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getSingleNodeIcon
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import nodesService from '../../services/nodes'
|
||||
|
||||
const getAllNodes = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await nodesService.getAllNodes()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getNodeByName = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.name === 'undefined' || req.params.name === '') {
|
||||
throw new Error(`Error: nodesController.getNodeByName - name not provided!`)
|
||||
}
|
||||
const apiResponse = await nodesService.getNodeByName(req.params.name)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getSingleNodeIcon = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.name === 'undefined' || req.params.name === '') {
|
||||
throw new Error(`Error: nodesController.getSingleNodeIcon - name not provided!`)
|
||||
}
|
||||
const apiResponse = await nodesService.getSingleNodeIcon(req.params.name)
|
||||
return res.sendFile(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getSingleNodeAsyncOptions = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: nodesController.getSingleNodeAsyncOptions - body not provided!`)
|
||||
}
|
||||
if (typeof req.params.name === 'undefined' || req.params.name === '') {
|
||||
throw new Error(`Error: nodesController.getSingleNodeAsyncOptions - name not provided!`)
|
||||
}
|
||||
const apiResponse = await nodesService.getSingleNodeAsyncOptions(req.params.name, req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const executeCustomFunction = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: nodesController.executeCustomFunction - body not provided!`)
|
||||
}
|
||||
const apiResponse = await nodesService.executeCustomFunction(req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllNodes,
|
||||
getNodeByName,
|
||||
getSingleNodeIcon,
|
||||
getSingleNodeAsyncOptions,
|
||||
executeCustomFunction
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import path from 'path'
|
||||
import * as fs from 'fs'
|
||||
import openaiAssistantsService from '../../services/openai-assistants'
|
||||
import { getUserHome } from '../../utils'
|
||||
import contentDisposition from 'content-disposition'
|
||||
|
||||
// List available assistants
|
||||
const getAllOpenaiAssistants = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.query.credential === 'undefined' || req.query.credential === '') {
|
||||
throw new Error(`Error: openaiAssistantsController.getAllOpenaiAssistants - credential not provided!`)
|
||||
}
|
||||
const apiResponse = await openaiAssistantsService.getAllOpenaiAssistants(req.query.credential as string)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Get assistant object
|
||||
const getSingleOpenaiAssistant = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: openaiAssistantsController.getSingleOpenaiAssistant - id not provided!`)
|
||||
}
|
||||
if (typeof req.query.credential === 'undefined' || req.query.credential === '') {
|
||||
throw new Error(`Error: openaiAssistantsController.getSingleOpenaiAssistant - credential not provided!`)
|
||||
}
|
||||
const apiResponse = await openaiAssistantsService.getSingleOpenaiAssistant(req.query.credential as string, req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
// Download file from assistant
|
||||
const getFileFromAssistant = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const filePath = path.join(getUserHome(), '.flowise', 'openai-assistant', req.body.fileName)
|
||||
//raise error if file path is not absolute
|
||||
if (!path.isAbsolute(filePath)) return res.status(500).send(`Invalid file path`)
|
||||
//raise error if file path contains '..'
|
||||
if (filePath.includes('..')) return res.status(500).send(`Invalid file path`)
|
||||
//only return from the .flowise openai-assistant folder
|
||||
if (!(filePath.includes('.flowise') && filePath.includes('openai-assistant'))) return res.status(500).send(`Invalid file path`)
|
||||
if (fs.existsSync(filePath)) {
|
||||
res.setHeader('Content-Disposition', contentDisposition(path.basename(filePath)))
|
||||
const fileStream = fs.createReadStream(filePath)
|
||||
fileStream.pipe(res)
|
||||
} else {
|
||||
return res.status(404).send(`File ${req.body.fileName} not found`)
|
||||
}
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllOpenaiAssistants,
|
||||
getSingleOpenaiAssistant,
|
||||
getFileFromAssistant
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import { getRateLimiter } from '../../utils/rateLimit'
|
||||
import chatflowsService from '../../services/chatflows'
|
||||
import logger from '../../utils/logger'
|
||||
import { utilBuildChatflow } from '../../utils/buildChatflow'
|
||||
|
||||
// Send input message and get prediction result (External)
|
||||
const createPrediction = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: predictionsController.createPrediction - id not provided!`)
|
||||
}
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: predictionsController.createPrediction - body not provided!`)
|
||||
}
|
||||
const chatflow = await chatflowsService.getChatflowById(req.params.id)
|
||||
if (!chatflow) {
|
||||
return res.status(404).send(`Chatflow ${req.params.id} not found`)
|
||||
}
|
||||
let isDomainAllowed = true
|
||||
logger.info(`[server]: Request originated from ${req.headers.origin}`)
|
||||
if (chatflow.chatbotConfig) {
|
||||
const parsedConfig = JSON.parse(chatflow.chatbotConfig)
|
||||
// check whether the first one is not empty. if it is empty that means the user set a value and then removed it.
|
||||
const isValidAllowedOrigins = parsedConfig.allowedOrigins?.length && parsedConfig.allowedOrigins[0] !== ''
|
||||
if (isValidAllowedOrigins) {
|
||||
const originHeader = req.headers.origin as string
|
||||
const origin = new URL(originHeader).host
|
||||
isDomainAllowed =
|
||||
parsedConfig.allowedOrigins.filter((domain: string) => {
|
||||
try {
|
||||
const allowedOrigin = new URL(domain).host
|
||||
return origin === allowedOrigin
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}).length > 0
|
||||
}
|
||||
}
|
||||
|
||||
if (isDomainAllowed) {
|
||||
const apiResponse = await utilBuildChatflow(req, req.io)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} else {
|
||||
return res.status(401).send(`This site is not allowed to access this chatbot`)
|
||||
}
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getRateLimiterMiddleware = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
return getRateLimiter(req, res, next)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createPrediction,
|
||||
getRateLimiterMiddleware
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import promptsListsService from '../../services/prompts-lists'
|
||||
|
||||
// Prompt from Hub
|
||||
const createPromptsList = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await promptsListsService.createPromptsList(req.body)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createPromptsList
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import statsService from '../../services/stats'
|
||||
import { chatType } from '../../Interface'
|
||||
|
||||
const getChatflowStats = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: statsController.getChatflowStats - id not provided!`)
|
||||
}
|
||||
const chatflowid = req.params.id
|
||||
let chatTypeFilter = req.query?.chatType as chatType | undefined
|
||||
const startDate = req.query?.startDate as string | undefined
|
||||
const endDate = req.query?.endDate as string | undefined
|
||||
if (chatTypeFilter) {
|
||||
try {
|
||||
const chatTypeFilterArray = JSON.parse(chatTypeFilter)
|
||||
if (chatTypeFilterArray.includes(chatType.EXTERNAL) && chatTypeFilterArray.includes(chatType.INTERNAL)) {
|
||||
chatTypeFilter = undefined
|
||||
} else if (chatTypeFilterArray.includes(chatType.EXTERNAL)) {
|
||||
chatTypeFilter = chatType.EXTERNAL
|
||||
} else if (chatTypeFilterArray.includes(chatType.INTERNAL)) {
|
||||
chatTypeFilter = chatType.INTERNAL
|
||||
}
|
||||
} catch (e) {
|
||||
return res.status(500).send(e)
|
||||
}
|
||||
}
|
||||
const apiResponse = await statsService.getChatflowStats(chatflowid, chatTypeFilter, startDate, endDate, '', true)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getChatflowStats
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import toolsService from '../../services/tools'
|
||||
|
||||
const creatTool = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: toolsController.creatTool - body not provided!`)
|
||||
}
|
||||
const apiResponse = await toolsService.creatTool(req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteTool = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: toolsController.updateTool - id not provided!`)
|
||||
}
|
||||
const apiResponse = await toolsService.deleteTool(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllTools = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await toolsService.getAllTools()
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getToolById = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: toolsController.getToolById - id not provided!`)
|
||||
}
|
||||
const apiResponse = await toolsService.getToolById(req.params.id)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateTool = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error(`Error: toolsController.updateTool - id not provided!`)
|
||||
}
|
||||
if (typeof req.body === 'undefined' || req.body === '') {
|
||||
throw new Error(`Error: toolsController.deleteTool - body not provided!`)
|
||||
}
|
||||
const apiResponse = await toolsService.updateTool(req.params.id, req.body)
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
creatTool,
|
||||
deleteTool,
|
||||
getAllTools,
|
||||
getToolById,
|
||||
updateTool
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import variablesService from '../../services/variables'
|
||||
import { Variable } from '../../database/entities/Variable'
|
||||
|
||||
const createVariable = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.body === 'undefined') {
|
||||
throw new Error(`Error: variablesController.createVariable - body not provided!`)
|
||||
}
|
||||
const body = req.body
|
||||
const newVariable = new Variable()
|
||||
Object.assign(newVariable, body)
|
||||
const apiResponse = await variablesService.createVariable(newVariable)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteVariable = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error('Error: variablesController.deleteVariable - id not provided!')
|
||||
}
|
||||
const apiResponse = await variablesService.deleteVariable(req.params.id)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const getAllVariables = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await variablesService.getAllVariables()
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateVariable = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
if (typeof req.params.id === 'undefined' || req.params.id === '') {
|
||||
throw new Error('Error: variablesController.updateVariable - id not provided!')
|
||||
}
|
||||
if (typeof req.body === 'undefined') {
|
||||
throw new Error('Error: variablesController.updateVariable - body not provided!')
|
||||
}
|
||||
const variable = await variablesService.getVariableById(req.params.id)
|
||||
if (!variable) {
|
||||
return res.status(404).send(`Variable ${req.params.id} not found in the database`)
|
||||
}
|
||||
const body = req.body
|
||||
const updatedVariable = new Variable()
|
||||
Object.assign(updatedVariable, body)
|
||||
const apiResponse = await variablesService.updateVariable(variable, updatedVariable)
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createVariable,
|
||||
deleteVariable,
|
||||
getAllVariables,
|
||||
updateVariable
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import vectorsService from '../../services/vectors'
|
||||
import { getRateLimiter } from '../../utils/rateLimit'
|
||||
|
||||
const getRateLimiterMiddleware = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
return getRateLimiter(req, res, next)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const upsertVectorMiddleware = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
return await vectorsService.upsertVectorMiddleware(req, res)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
const createInternalUpsert = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
return await vectorsService.upsertVectorMiddleware(req, res, true)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
upsertVectorMiddleware,
|
||||
createInternalUpsert,
|
||||
getRateLimiterMiddleware
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import versionsService from '../../services/versions'
|
||||
|
||||
const getVersion = async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const apiResponse = await versionsService.getVersion()
|
||||
if (apiResponse.executionError) {
|
||||
return res.status(apiResponse.status).send(apiResponse.msg)
|
||||
}
|
||||
return res.json(apiResponse)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getVersion
|
||||
}
|
||||
Reference in New Issue
Block a user