diff --git a/apps/http-backend/src/routes/userRoutes/userRoutes.ts b/apps/http-backend/src/routes/userRoutes/userRoutes.ts index 2d6bccf..6cf40f5 100644 --- a/apps/http-backend/src/routes/userRoutes/userRoutes.ts +++ b/apps/http-backend/src/routes/userRoutes/userRoutes.ts @@ -9,6 +9,7 @@ import { AvailableNodes, TriggerSchema, WorkflowSchema, + NodeSchema, } from "@repo/common/zod"; import { GoogleSheetsNodeExecutor } from "@repo/nodes"; const router: Router = Router(); @@ -34,16 +35,18 @@ const router: Router = Router(); // } // }); -router.post("/createNode", async (req: AuthRequest, res: Response) => { +// ------------------- AVALIABLE TRIGGERS AND NODES CREATION AND FETCHING ROUTES -------------------------- + +router.post("/createAvaliableNode", async (req: AuthRequest, res: Response) => { try { const Data = req.body; - console.log("Thi is the Data from Normal Data", Data); + // console.log("Thi is the Data from Normal Data", Data); const parseData = AvailableNodes.safeParse(Data); - console.log("This is the ParsedData", parseData.data); + // console.log("This is the ParsedData", parseData.data); // if(!parseData) return if (!parseData.success) { return res.status(statusCodes.BAD_REQUEST).json({ - message: "Invalid Inpput in node creating", + message: "Invalid Input in node creating", }); } const createNode = await prismaClient.availableNode.create({ @@ -58,7 +61,7 @@ router.post("/createNode", async (req: AuthRequest, res: Response) => { Data: createNode, }); } catch (e) { - console.log("This is the error from Node creatig", e); + console.log("This is the error from Node creating", e); return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({ message: "Internal server Error from Node creation", }); @@ -90,7 +93,7 @@ router.get("/getAvailableNodes", } ); -router.post("/createTriggers", +router.post("/createAvaliableTriggers", userMiddleware, async (req: AuthRequest, res: Response) => { try { @@ -148,6 +151,8 @@ router.get("/getAvailableTriggers", } ); +//------------------------------ GET CREDENTIALS ----------------------------- + router.get('/getCredentials/:type', userMiddleware, async (req: AuthRequest, res) =>{ @@ -195,6 +200,7 @@ router.get('/getCredentials/:type', } ); +// ----------------------------------- CREATE WORKFLOW --------------------------------- router.post("/create/workflow", userMiddleware, @@ -219,57 +225,18 @@ router.post("/create/workflow", // Example JSON body to test this route: /* { - "Name": "My Workflow Trigger", - "AvailableTriggerId": "trigger123", - "Config": { - "key1": "value1", - "key2": 42, - "key3": true - }, - "AvailableNodes": [ - { - "name": "First Node", - "config": { "foo": "bar" }, - "type": "TypeA", - "id": "nodeA1" - }, - { - "name": "Second Node", - "config": { "baz": 123 }, - "type": "TypeB", - "nodeId": "nodeB2" - }, - { - "name": "Third Node", - "config": { "example": false }, - "type": "TypeC", - "AvailabeNodeID": "nodeC3" - } - ] + "Name":"workflow-1", + "UserId": "", + "Config":[{}] } */ data: { user: { connect: { id: UserID }, }, - description: "First Workflow", + description: "Workflow-generated", name: ParsedData.data.Name, config: ParsedData.data.Config, - Trigger: { - create: { - name: ParsedData.data.Name, - AvailableTriggerID: ParsedData.data.AvailableTriggerId, - config: ParsedData.data.Config, - }, - }, - nodes: { - create: ParsedData.data.AvailableNodes.map((x, index) => ({ - name: x.Name, - AvailabeNodeID: x.AvailableNodeId, - config: x.Config, - position: index, - })), - }, }, }); return res.status(statusCodes.CREATED).json({ @@ -285,6 +252,8 @@ router.post("/create/workflow", } ); +// ------------------------------------ FETCHING WORKFLOWS ----------------------------------- + router.get("/workflows", userMiddleware, async (req: AuthRequest, res: Response) => { @@ -313,6 +282,34 @@ router.get("/workflows", } ); +router.get('/empty/workflow', userMiddleware, async(req:AuthRequest, res: Response)=>{ + try{ + if (!req.user) + return res + .status(statusCodes.UNAUTHORIZED) + .json({ message: "User is not logged in /not authorized" }); + const userId = req.user.id; + const workflow = await prismaClient.workflow.findFirst({ + where:{ + userId: userId, + isEmpty: true + }, + orderBy: { + createdAt: 'desc' + } + }) + return res + .status(statusCodes.OK) + .json({ message: "Workflow fetched succesful", Data: workflow }); + + }catch(e){ + console.log("The error is from getting wrkflows", e instanceof Error ? e.message : "UNKNOWN ERROR"); + + return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({ + meesage: "Internal Server Error From getting workflows for the user", + }); + } +}) router.get("/workflow/:workflowId", userMiddleware, async (req: AuthRequest, res: Response) => { @@ -329,6 +326,10 @@ router.get("/workflow/:workflowId", id: workflowId, userId: userId, }, + include:{ + Trigger: true, + nodes: { orderBy: {position: 'asc'}} + } }); if (!getWorkflow) { return res.status(statusCodes.UNAUTHORIZED).json({ @@ -347,6 +348,110 @@ router.get("/workflow/:workflowId", } } ); + +// ---------------------------------------- INSERTING DATA INTO NODES/ TRIGGER TABLE----------------------------- + +router.post('/create/trigger', userMiddleware, async(req: AuthRequest, res: Response)=>{ + try { + if (!req.user) { + return res.status(statusCodes.BAD_REQUEST).json({ + message: "User is not logged in ", + }); + } + const data = req.body; + const dataSafe = TriggerSchema.safeParse(data) + if(!dataSafe.success) + return res.status(statusCodes.BAD_REQUEST).json({ + message: "Invalid input" + }) + const createdTrigger = await prismaClient.trigger.create({ + data:{ + name: dataSafe.data.Name, + AvailableTriggerID: dataSafe.data.AvailableTriggerID, + config: dataSafe.data.Config, + workflowId: dataSafe.data.WorkflowId, + // trigger type pettla db lo ledu aa column + } + }) + + if(createdTrigger){ + return res.status(statusCodes.CREATED).json({ + message: "Trigger created", + data: createdTrigger + }) + } + }catch(e){ + console.log("This is the error from Trigger creatig", e); + return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({ + message: "Internal server Error from Trigger creation ", + }); + } + + // INPUT FORMAT + // { + // "Name": "test-1", + // "AvailableTriggerID": "153c62fb-d61e-4e10-a8f4-d54780883200", + // "Config": {}, + // "WorkflowId": "d0216fca-ca9b-4f3f-b01c-0a29b4305708", + // "TriggerType":"" + // } +}) + +router.post('/create/node', userMiddleware, async(req: AuthRequest, res: Response)=>{ + try{ + if(!req.user){ + return res.status(statusCodes.BAD_REQUEST).json({ + message: "User is not logged in ", + }); + } + const data = req.body; + console.log(data," from http-backeden" ); + + const dataSafe = NodeSchema.safeParse(data) + if(!dataSafe.success) { + return res.status(statusCodes.BAD_REQUEST).json({ + message: "Invalid input" + }) + } + const createdNode = await prismaClient.node.create({ + data:{ + name: dataSafe.data.Name, + workflowId: dataSafe.data.WorkflowId, + AvailableNodeID: dataSafe.data.AvailableNodeId, + // AvailabeNodeID: dataSafe.data.AvailableNodeId, + config: dataSafe.data.Config, + position: dataSafe.data.Position + } + }) + + if(createdNode) + return res.status(statusCodes.CREATED).json({ + message: "Node created", + data: createdNode + }) + }catch(e){ + console.log("This is the error from Node creating", e); + return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({ + message: "Internal server Error from Node creation", + }); + } +}) + + +// ----------------------- GET WORKFLOW DATA(NODES, TRIGGER)--------------------- + +// router.get('/getworkflowData', userMiddleware, async(req: AuthRequest, res: Response)=>{ +// try{ +// if(!req.user){ +// return res.status(statusCodes.BAD_REQUEST).json({ +// message: "User is not logged in ", +// }); +// } +// }catch(e){ + +// } +// }) + router.get("/protected", userMiddleware, (req: AuthRequest, res) => { return res.json({ ok: true, diff --git a/apps/http-backend/tsconfig.tsbuildinfo b/apps/http-backend/tsconfig.tsbuildinfo index f8e5606..ed1b0ca 100644 --- a/apps/http-backend/tsconfig.tsbuildinfo +++ b/apps/http-backend/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/index.ts","./src/routes/nodes.routes.ts","./src/routes/userRoutes/userMiddleware.ts","./src/routes/userRoutes/userRoutes.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/index.ts","./src/routes/google_callback.ts","./src/routes/nodes.routes.ts","./src/routes/userroutes/usermiddleware.ts","./src/routes/userroutes/userroutes.ts"],"version":"5.7.3"} \ No newline at end of file diff --git a/apps/web/app/api/google-sheets/documents/route.ts b/apps/web/app/api/google-sheets/documents/route.ts deleted file mode 100644 index f4e1cdd..0000000 --- a/apps/web/app/api/google-sheets/documents/route.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { GoogleSheetsNodeExecutor } from '@repo/nodes'; - -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - const { userId, nodeId } = body; - - if (!userId || !nodeId) { - return NextResponse.json( - { success: false, error: 'Missing userId or nodeId' }, - { status: 400 } - ); - } - - const executor = new GoogleSheetsNodeExecutor(); - const context = { - userId, - nodeId, - config: { operation: 'read_rows' } - }; - - const result = await executor.getSheets(context); - - if ((result as any)?.success === false) { - return NextResponse.json(result, { status: 400 }); - } - - // Extract files from the response - const files = (result as any)?.data?.data?.files || []; - - return NextResponse.json({ - success: true, - data: files - }); - - } catch (error) { - console.error('Error fetching documents:', error); - return NextResponse.json( - { success: false, error: error instanceof Error ? error.message : 'Unknown error' }, - { status: 500 } - ); - } -} diff --git a/apps/web/app/api/google-sheets/tabs/route.ts b/apps/web/app/api/google-sheets/tabs/route.ts deleted file mode 100644 index ac7a20e..0000000 --- a/apps/web/app/api/google-sheets/tabs/route.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { GoogleSheetsNodeExecutor } from '@repo/nodes'; - -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - const { userId, nodeId, spreadsheetId } = body; - - if (!userId || !nodeId || !spreadsheetId) { - return NextResponse.json( - { success: false, error: 'Missing required parameters' }, - { status: 400 } - ); - } - - const executor = new GoogleSheetsNodeExecutor(); - const context = { - userId, - nodeId, - config: { operation: 'read_rows' } - }; - - const result = await executor.getSheetTabs(context, spreadsheetId); - - if ((result as any)?.success === false) { - return NextResponse.json(result, { status: 400 }); - } - - return NextResponse.json(result); - - } catch (error) { - console.error('Error fetching sheet tabs:', error); - return NextResponse.json( - { success: false, error: error instanceof Error ? error.message : 'Unknown error' }, - { status: 500 } - ); - } -} diff --git a/apps/web/app/components/nodes/CreateWorkFlow.tsx b/apps/web/app/components/nodes/CreateWorkFlow.tsx index 60583a3..86b9b9a 100644 --- a/apps/web/app/components/nodes/CreateWorkFlow.tsx +++ b/apps/web/app/components/nodes/CreateWorkFlow.tsx @@ -9,9 +9,11 @@ import { TriggerSideBar } from "./TriggerSidebar"; import ActionSideBar from "../Actions/ActionSidebar"; import ActionNode from "../Actions/ActionNode"; import { GoogleSheetFormClient } from "./GoogleSheetFormClient"; -import { getEmptyWorkflow } from "@/app/workflow/lib/dbHandler"; import { useDispatch } from "react-redux"; import { workflowActions, workflowReducer } from "@/store/slices/workflowSlice"; +import { createWorkflow, getEmptyWorkflow, getworkflowData } from "@/app/workflow/lib/config"; +import { useAppSelector } from '@/app/hooks/redux'; + interface NodeType { @@ -37,8 +39,14 @@ export const CreateWorkFlow = () => { const [sidebarOpen, setSidebarOpen] = useState(false); const [actionSidebarOpen, setActionSidebarOpen] = useState(false); const [credType, setCredType] = useState(""); + const [nodeIDType, setNodeIDType] = useState('') const [loadSheet, setLoadSheet] = useState(false) const dispatch = useDispatch(); + const userId = useAppSelector(s=>s.user.userId) + const workflowId = useAppSelector(s=>s.workflow.workflow_id) + const existingTrigger = useAppSelector(s=>s.workflow.trigger?.name) + const existingNodes = useAppSelector(s=>s.workflow.nodes) + console.log(`workflow from redux, TRigger: ${existingTrigger}, Nodes: ${existingNodes}`) const [nodes, setNodes] = useState([ { @@ -68,7 +76,7 @@ export const CreateWorkFlow = () => { }) => { const timestamp = Date.now(); const placeholderId = `placeholder-${timestamp}`; - const triggerNodeId = `trigger-${trigger.id}`; + const triggerNodeId = `trigger~${trigger.id}`; const edgeId = `e-${triggerNodeId}-${placeholderId}`; setNodes((currentNodes) => { @@ -121,11 +129,25 @@ export const CreateWorkFlow = () => { dispatch(workflowActions.setWorkflowStatus(isEmpty)) } else{ - const newWorkflow + if (!userId) return + const newWorkflow = await createWorkflow(userId) + dispatch(workflowActions.setWorkflowId(newWorkflow.id)) + dispatch(workflowActions.setWorkflowStatus(newWorkflow.isEmpty)) + } + } + async function getWorkflowData(){ + if(!workflowId) return + const workflow = await getworkflowData(workflowId) + if(workflow.success){ + dispatch(workflowActions.setWorkflowStatus(false)) + dispatch(workflowActions.setWorkflowNodes(workflow.data.nodes)) + dispatch(workflowActions.setWorkflowTrigger(workflow.data.Trigger)) + // console.log(`workfklow from redux: ${workflow.data}`) } } - getEmptyWorkflowID() - },[dispatch]) + if(!workflowId) getEmptyWorkflowID() + getWorkflowData(); + },[dispatch, userId, workflowId]) const handleSelectAction = (action: { id: string; @@ -135,7 +157,7 @@ export const CreateWorkFlow = () => { }) => { const timestamp = Date.now(); const newPlaceholderId = `placeholder-${timestamp}`; - const actionNodeId = `action-${action.id}-${timestamp}`; + const actionNodeId = `action~${action.id}`; setNodes((currentNodes) => { const placeholderNode = currentNodes.find( @@ -221,6 +243,7 @@ export const CreateWorkFlow = () => { // getCredentials(node.data.type ? node.data.type : "") // setNodeId(node.id.split("trigger-")[1] || "") // if(cred) setLoadSheet(true) + setNodeIDType(node.id) setCredType(node.data.type === "google_sheet" ? "google_oauth" : "") setLoadSheet(!loadSheet) console.log("hook called") @@ -242,8 +265,7 @@ export const CreateWorkFlow = () => { /> {loadSheet && - + } ); diff --git a/apps/web/app/components/nodes/GoogleSheetFormClient.tsx b/apps/web/app/components/nodes/GoogleSheetFormClient.tsx index 79e4b9a..aab2779 100644 --- a/apps/web/app/components/nodes/GoogleSheetFormClient.tsx +++ b/apps/web/app/components/nodes/GoogleSheetFormClient.tsx @@ -22,7 +22,7 @@ interface GoogleSheetFormClientProps { nodeId: string; } -export function GoogleSheetFormClient(type:{type: string}) { +export function GoogleSheetFormClient(type:{type: string, nodeType: string}) { const [selectedCredential, setSelectedCredential] = useState(''); const [documents, setDocuments] = useState>([]); const [selectedDocument, setSelectedDocument] = useState(''); @@ -36,9 +36,14 @@ export function GoogleSheetFormClient(type:{type: string}) { const [credId, setCredId] = useState(); // const [authUrl, setAuthUrl] = useState() const userId = useAppSelector(s=>s.user.userId) || "" + const workflowId = useAppSelector(s=>s.workflow.workflow_id) || '' console.log(userId, 'id from client') const credType = type.type - + const nodeType = type.nodeType.split("~")[0] || "" + console.log('checking nodeType: ', nodeType); + + const nodeId = type.nodeType.split("~")[1] || "" + console.log('checking node id: ',nodeId) const {cred: response, authUrl} = useCredentials(credType) console.log('response from form client', typeof(response)) @@ -121,8 +126,11 @@ export function GoogleSheetFormClient(type:{type: string}) { const handleSaveClick = () => { const config = { - userId, - // nodeId, + userId:userId, + node_Trigger:nodeId, + workflowId, + type:nodeType, + name: `Google sheet - ${nodeType}`, credentialId: selectedCredential, spreadsheetId: selectedDocument, sheetName: selectedSheet, @@ -134,14 +142,14 @@ export function GoogleSheetFormClient(type:{type: string}) { console.log('Sending config:', config); const res = await handleSaveConfig(config); console.log('Full response:', res); - console.log('Success:', res.success); - console.log('Output:', res.output); - console.log('Error:', res.error); - setResult(res); + // console.log('Success:', res.success); + // console.log('Output:', res.output); + // console.log('Error:', res.error); + // setResult(res); if (res.success) { toast.success("Configuration saved!"); - } else if (res.error) { - toast.error(res.error); + } else { + toast.error(res.data); } }); } diff --git a/apps/web/app/components/nodes/actions.ts b/apps/web/app/components/nodes/actions.ts index 44cf69d..8ecb06a 100644 --- a/apps/web/app/components/nodes/actions.ts +++ b/apps/web/app/components/nodes/actions.ts @@ -1,38 +1,64 @@ -'use server'; -import { GoogleSheetsNodeExecutor } from '@repo/nodes'; +import { createNode, createTrigger } from '@/app/workflow/lib/config'; interface SaveConfigFormData { - userId: string; + // userId: string; + type: string credentialId: string; spreadsheetId: string; sheetName: string; operation: string; range: string; + position?: number; + name: string; + node_Trigger: string; + workflowId: string; + } export async function handleSaveConfig(formData: SaveConfigFormData) { - const executor = new GoogleSheetsNodeExecutor(); - + // const executor = new GoogleSheetsNodeExecutor(); const context = { - userId: formData.userId, - credId: formData.credentialId, + // userId: formData.userId, + name: formData.name, + workflowId: formData.workflowId, + node_Trigger: formData.node_Trigger, config: { + credId: formData.credentialId, operation: formData.operation, spreadsheetId: formData.spreadsheetId, range: formData.range, sheetName: formData.sheetName, }, }; + if(formData.type === 'trigger') + { + const trigger = await createTrigger(context) + console.log('triggger created using config backend: ',trigger) + + return{ + success: trigger.success, + data: trigger.data + } + } + else{ + const node = await createNode({...context, position: formData.position ? formData.position : 0}) + console.log('NOde created using config backend: ',node); + return { + success:node.success, + data: node.data + } + } + - const result = await executor.execute(context); + // const result = await executor.execute(context); - // Return plain object (not class instance) - return { - success: result.success, - output: result.output || null, - error: result.error || null, - authUrl: result.authUrl || null, - requiresAuth: result.requiresAuth || false, - }; + // // Return plain object (not class instance) + // return { + // success: result.success, + // output: result.output || null, + // error: result.error || null, + // authUrl: result.authUrl || null, + // requiresAuth: result.requiresAuth || false, + // }; } diff --git a/apps/web/app/workflow/lib/config.ts b/apps/web/app/workflow/lib/config.ts index 7fd1041..c877bce 100644 --- a/apps/web/app/workflow/lib/config.ts +++ b/apps/web/app/workflow/lib/config.ts @@ -43,3 +43,152 @@ export const getCredentials = async(type: string)=>{ throw e; } } + +const date = new Date() + + +export const createWorkflow = async(userId: string)=>{ + try{ + const response = await axios.post(`${BACKEND_URL}/user/create/workflow`, + { + Name:`workflow-${date.getTime()}`, + UserId: userId, + Config: {} + },{ + headers: { + 'Content-Type': 'application/json' + }, + withCredentials: true + } + ) + + const workflow = response.data + console.log('new workflow: ',workflow) + return workflow.Data + }catch(e){ + console.error("Error in creating workflow:", e); + throw e; + } +} + +interface Triggercontext{ + // userId: formData.userId, + name: string, + workflowId: string, + node_Trigger: string, + config: { + credId: string, + operation: string, + spreadsheetId: string, + range: string, + sheetName: string, + }, + }; +export const createTrigger = async(context: Triggercontext)=>{ + try{ + console.log('Trigger context: ', context) + const response = await axios.post(`${BACKEND_URL}/user/create/trigger`, + { + Name: context.name, + AvailableTriggerID: context.node_Trigger, + Config: context.config, + WorkflowId: context.workflowId, + TriggerType:"" + }, + { + headers: {"Content-Type": "application/json"}, + withCredentials:true + }) + + const trigger = (response.data) + console.log('trigger created: ', trigger); + return { + success: true, + data: trigger + } + }catch(e){ + console.error("Error in creating Trigger:", e); + return { + success: false, + data: e instanceof Error ? e.message : `unknown error ${e}` + } + } +} + +interface Nodecontext{ + // userId: formData.userId, + name: string, + workflowId: string, + node_Trigger: string, + position? :number, + config: { + credId: string, + operation: string, + spreadsheetId: string, + range: string, + sheetName: string, + }, + }; +export const createNode = async(context: Nodecontext)=>{ + try{ + console.log('Node context: ', context) + + const response = await axios.post(`${BACKEND_URL}/user/create/node`,{ + + Name: context.name, + AvailableNodeId: context.node_Trigger, + WorkflowId: context.workflowId, + Config: context.config, + Position: context.position ? context.position : 0 + },{ + headers: {"Content-Type": "application/json"}, + withCredentials:true + }) + + const node = (response.data) + console.log('Node created: ', node); + return { + success: true, + data: node + } + + }catch(e){ + console.error("Error in creating Node:", e); + return {success: false, + data: e instanceof Error ? e.message : `unknown error ${e}` + }; + } +} + +export const getEmptyWorkflow = async()=>{ + try{ + const res = await axios.get(`${BACKEND_URL}/user/empty/workflow`,{ + withCredentials: true + }) + + const workflow = res.data.Data + return workflow + } + catch(e){ + console.error("Error in fetching workflows:", e); + throw e; + } +} + +export const getworkflowData = async(workflowId: string)=>{ + try{ + const res = await axios.get(`${BACKEND_URL}/user/workflow/${workflowId}`,{ + withCredentials: true + }) + console.log('workflow data includes trigger and nodes: ', res.data.Data ) + return { + success: true, + data: res.data.Data + } + }catch(e){ + console.error("Error in creating Node:", e); + return {success: false, + data: e instanceof Error ? e.message : `unknown error ${e}` + }; + } +} \ No newline at end of file diff --git a/apps/web/app/workflow/lib/dbHandler.ts b/apps/web/app/workflow/lib/dbHandler.ts deleted file mode 100644 index 5780b06..0000000 --- a/apps/web/app/workflow/lib/dbHandler.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use server' - -import { prismaClient } from "@repo/db"; - -export const getEmptyWorkflow = async() =>{ - const workflow_id = await prismaClient.workflow.findFirst({ - where:{ - isEmpty: true - }, - orderBy:{ - createdAt: 'desc' - } - }); - return workflow_id || null -} diff --git a/apps/web/package.json b/apps/web/package.json index 910a271..f0e4873 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -26,6 +26,7 @@ "client-only": "^0.0.1", "fetch": "link:@trpc/server/adapters/fetch", "googleapis": "^166.0.0", + "immer": "^11.1.0", "lucide-react": "^0.475.0", "next": "^15.4.5", "next-auth": "^4.24.13", diff --git a/apps/web/store/slices/workflowSlice.ts b/apps/web/store/slices/workflowSlice.ts index a9cbeeb..2cd9dfa 100644 --- a/apps/web/store/slices/workflowSlice.ts +++ b/apps/web/store/slices/workflowSlice.ts @@ -1,26 +1,55 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit"; -export interface WorkflowSlice{ - workflow_id: string | null, - empty: boolean | null +interface Trigger { + dbId: string; + name: string; + type: string; + config: any; +} + +interface NodeItem { + dbId: string; + name: string; + type: string; + config: any; + position: number; +} + +type Nodes = NodeItem[]; +export interface WorkflowSlice { + workflow_id: string | null; + empty: boolean | null; + trigger: Trigger | null; + nodes: Nodes; } const initialState: WorkflowSlice = { - workflow_id :null, - empty: true + workflow_id: null, + empty: true, + trigger: null, + nodes: [] } const workflowSlice = createSlice({ name: 'workflow', initialState, - reducers:{ - setWorkflowId(state, action:PayloadAction){ + reducers: { + setWorkflowId(state, action: PayloadAction) { state.workflow_id = action.payload }, - setWorkflowStatus(state, action: PayloadAction){ + setWorkflowStatus(state, action: PayloadAction) { state.empty = action.payload }, - clearWorkflow(){ + setWorkflowTrigger(state, action: PayloadAction) { + state.trigger = action.payload + }, + setWorkflowNodes(state, action: PayloadAction) { + state.nodes = action.payload + }, + addWorkflowNode(state, action: PayloadAction) { + state.nodes.push(action.payload) + }, + clearWorkflow() { return initialState } } diff --git a/package.json b/package.json index a193973..9bfde54 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,11 @@ "devDependencies": { "@workspace/eslint-config": "workspace:*", "@workspace/typescript-config": "workspace:*", - "prettier": "^3.6.2", - "turbo": "^2.5.5", + "prettier": "^3.7.4", + "turbo": "^2.7.2", "typescript": "5.7.3" }, - "packageManager": "pnpm@10.25.0", + "packageManager": "pnpm@10.26.2", "engines": { "node": ">=20" } diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 0e549e1..f749675 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -27,7 +27,7 @@ export const TriggerSchema = z.object({ export const NodeSchema = z.object({ Name: z.string(), - AvailabeNodeId: z.string(), + AvailableNodeId: z.string(), Config: z.any(), Position: z.number(), WorkflowId: z.string(), @@ -38,14 +38,7 @@ export const WorkflowSchema = z.object({ Name: z.string(), UserId: z.string(), Config: z.any(), - AvailableTriggerId: z.string(), - AvailableNodes: z.array( - z.object({ - Name: z.string(), - AvailableNodeId: z.string(), - Config: z.any(), - }) - ), + }); export enum statusCodes { diff --git a/packages/db/package-lock.json b/packages/db/package-lock.json index 49a0ce9..c6880a7 100644 --- a/packages/db/package-lock.json +++ b/packages/db/package-lock.json @@ -9,11 +9,10 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@prisma/client": "^7.0.1", + "@prisma/adapter-pg": "^7.2.0", + "@prisma/client": "^6.19.0", "@types/dotenv": "^8.2.3", - "dotenv": "^17.2.3" - }, - "devDependencies": { + "dotenv": "^17.2.3", "prisma": "^6.19.0" } }, @@ -44,20 +43,29 @@ "url": "https://dotenvx.com" } }, - "node_modules/@prisma/client": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.0.1.tgz", - "integrity": "sha512-O74T6xcfaGAq5gXwCAvfTLvI6fmC3and2g5yLRMkNjri1K8mSpEgclDNuUWs9xj5AwNEMQ88NeD3asI+sovm1g==", + "node_modules/@prisma/adapter-pg": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.2.0.tgz", + "integrity": "sha512-euIdQ13cRB2wZ3jPsnDnFhINquo1PYFPCg6yVL8b2rp3EdinQHsX9EDdCtRr489D5uhphcRk463OdQAFlsCr0w==", "license": "Apache-2.0", "dependencies": { - "@prisma/client-runtime-utils": "7.0.1" - }, + "@prisma/driver-adapter-utils": "7.2.0", + "pg": "^8.16.3", + "postgres-array": "3.0.4" + } + }, + "node_modules/@prisma/client": { + "version": "6.19.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.1.tgz", + "integrity": "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A==", + "hasInstallScript": true, + "license": "Apache-2.0", "engines": { - "node": "^20.19 || ^22.12 || >=24.0" + "node": ">=18.18" }, "peerDependencies": { "prisma": "*", - "typescript": ">=5.4.0" + "typescript": ">=5.1.0" }, "peerDependenciesMeta": { "prisma": { @@ -68,17 +76,10 @@ } } }, - "node_modules/@prisma/client-runtime-utils": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@prisma/client-runtime-utils/-/client-runtime-utils-7.0.1.tgz", - "integrity": "sha512-R26BVX9D/iw4toUmZKZf3jniM/9pMGHHdZN5LVP2L7HNiCQKNQQx/9LuMtjepbgRqSqQO3oHN0yzojHLnKTGEw==", - "license": "Apache-2.0" - }, "node_modules/@prisma/config": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.0.tgz", "integrity": "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==", - "devOptional": true, "license": "Apache-2.0", "dependencies": { "c12": "3.1.0", @@ -91,14 +92,27 @@ "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.0.tgz", "integrity": "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==", - "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/driver-adapter-utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.2.0.tgz", + "integrity": "sha512-gzrUcbI9VmHS24Uf+0+7DNzdIw7keglJsD5m/MHxQOU68OhGVzlphQRobLiDMn8CHNA2XN8uugwKjudVtnfMVQ==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "7.2.0" + } + }, + "node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.2.0.tgz", + "integrity": "sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==", "license": "Apache-2.0" }, "node_modules/@prisma/engines": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.0.tgz", "integrity": "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==", - "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -112,14 +126,12 @@ "version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773.tgz", "integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==", - "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz", "integrity": "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==", - "devOptional": true, "license": "Apache-2.0", "dependencies": { "@prisma/debug": "6.19.0", @@ -131,7 +143,6 @@ "version": "6.19.0", "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.0.tgz", "integrity": "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==", - "devOptional": true, "license": "Apache-2.0", "dependencies": { "@prisma/debug": "6.19.0" @@ -141,7 +152,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "devOptional": true, "license": "MIT" }, "node_modules/@types/dotenv": { @@ -152,7 +162,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", - "devOptional": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.3", @@ -181,7 +190,6 @@ "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "devOptional": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -194,7 +202,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "devOptional": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -210,7 +217,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "devOptional": true, "license": "MIT", "dependencies": { "consola": "^3.2.3" @@ -220,14 +226,12 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "devOptional": true, "license": "MIT" }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "devOptional": true, "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" @@ -237,7 +241,6 @@ "version": "7.1.5", "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", - "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=16.0.0" @@ -247,14 +250,12 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "devOptional": true, "license": "MIT" }, "node_modules/destr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "devOptional": true, "license": "MIT" }, "node_modules/dotenv": { @@ -265,7 +266,6 @@ "version": "3.18.4", "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", - "devOptional": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -276,7 +276,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=14" @@ -286,14 +285,12 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", - "devOptional": true, "license": "MIT" }, "node_modules/fast-check": { "version": "3.23.2", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", - "devOptional": true, "funding": [ { "type": "individual", @@ -316,7 +313,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", - "devOptional": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -334,7 +330,6 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "devOptional": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -344,14 +339,12 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "devOptional": true, "license": "MIT" }, "node_modules/nypm": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", - "devOptional": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -371,28 +364,122 @@ "version": "2.0.11", "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "devOptional": true, "license": "MIT" }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "devOptional": true, "license": "MIT" }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "devOptional": true, "license": "MIT" }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pg-types/node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/pkg-types": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "devOptional": true, "license": "MIT", "dependencies": { "confbox": "^0.2.2", @@ -400,11 +487,49 @@ "pathe": "^2.0.3" } }, + "node_modules/postgres-array": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz", + "integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prisma": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.0.tgz", "integrity": "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==", - "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -430,7 +555,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "devOptional": true, "funding": [ { "type": "individual", @@ -447,7 +571,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", - "devOptional": true, "license": "MIT", "dependencies": { "defu": "^6.1.4", @@ -458,7 +581,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -468,15 +590,32 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/tinyexec": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=18" } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } } } } diff --git a/packages/db/package.json b/packages/db/package.json index 2afe0ac..ebb4e49 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -6,7 +6,6 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "prisma generate && tsc -b ", - "dev": "node dist/index.js", "run": "npm run build && npm run dev" }, @@ -19,6 +18,7 @@ "author": "", "license": "ISC", "dependencies": { + "@prisma/adapter-pg": "^7.2.0", "@prisma/client": "^6.19.0", "@types/dotenv": "^8.2.3", "dotenv": "^17.2.3", diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index dc0d5f9..edddb57 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -54,20 +54,20 @@ model AvailableNode { authType String? requireAuth Boolean? description String? - nodes Node[] + Node Node[] } model Node { - id String @id @default(uuid()) - name String - config Json - position Int - workflowId String? - AvailabeNodeID String - credentials Credential[] - AvailabeNodeId AvailableNode @relation(fields: [AvailabeNodeID], references: [id]) - workflow Workflow? @relation(fields: [workflowId], references: [id]) - executions NodeExecution[] + id String @id @default(uuid()) + name String + config Json + position Int + workflowId String? + AvailableNodeID String + credentials Credential[] + AvailableNode AvailableNode @relation(fields: [AvailableNodeID], references: [id]) + workflow Workflow? @relation(fields: [workflowId], references: [id]) + executions NodeExecution[] } model Workflow { @@ -79,6 +79,7 @@ model Workflow { config Json updatedAt DateTime @updatedAt status WorkflowStatus? + isEmpty Boolean? @default(true) nodes Node[] Trigger Trigger? user User @relation(fields: [userId], references: [id]) diff --git a/packages/db/tsconfig.tsbuildinfo b/packages/db/tsconfig.tsbuildinfo index 0713707..44940f3 100644 --- a/packages/db/tsconfig.tsbuildinfo +++ b/packages/db/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/index.ts"],"version":"5.9.2"} \ No newline at end of file +{"root":["./src/index.ts"],"version":"5.7.3"} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ceb00d4..e2b33d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,11 +15,11 @@ importers: specifier: workspace:* version: link:packages/typescript-config prettier: - specifier: ^3.6.2 - version: 3.6.2 + specifier: ^3.7.4 + version: 3.7.4 turbo: - specifier: ^2.5.5 - version: 2.5.5 + specifier: ^2.7.2 + version: 2.7.2 typescript: specifier: 5.7.3 version: 5.7.3 @@ -119,6 +119,9 @@ importers: '@radix-ui/react-dialog': specifier: ^1.1.15 version: 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@reduxjs/toolkit': + specifier: ^2.11.2 + version: 2.11.2(react-redux@9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1))(react@19.1.1) '@repo/common': specifier: workspace:* version: link:../../packages/common @@ -136,7 +139,7 @@ importers: version: link:../../packages/ui '@xyflow/react': specifier: ^12.9.3 - version: 12.9.3(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 12.9.3(@types/react@19.1.9)(immer@11.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) add: specifier: ^2.0.6 version: 2.0.6 @@ -155,6 +158,9 @@ importers: googleapis: specifier: ^166.0.0 version: 166.0.0 + immer: + specifier: ^11.1.0 + version: 11.1.0 lucide-react: specifier: ^0.475.0 version: 0.475.0(react@19.1.1) @@ -164,6 +170,9 @@ importers: next-auth: specifier: ^4.24.13 version: 4.24.13(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + next-redux-wrapper: + specifier: ^8.1.0 + version: 8.1.0(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-redux@9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1))(react@19.1.1) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -176,6 +185,9 @@ importers: react-dom: specifier: ^19.1.1 version: 19.1.1(react@19.1.1) + react-redux: + specifier: ^9.2.0 + version: 9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1) server-only: specifier: ^0.0.1 version: 0.0.1 @@ -239,6 +251,9 @@ importers: packages/db: dependencies: + '@prisma/adapter-pg': + specifier: ^7.2.0 + version: 7.2.0 '@prisma/client': specifier: ^6.19.0 version: 6.19.0(prisma@6.19.0(typescript@5.9.2))(typescript@5.9.2) @@ -283,7 +298,7 @@ importers: version: 5.2.0(eslint@9.32.0(jiti@2.5.1)) eslint-plugin-turbo: specifier: ^2.5.5 - version: 2.5.5(eslint@9.32.0(jiti@2.5.1))(turbo@2.5.5) + version: 2.5.5(eslint@9.32.0(jiti@2.5.1))(turbo@2.7.2) globals: specifier: ^15.15.0 version: 15.15.0 @@ -715,6 +730,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@prisma/adapter-pg@7.2.0': + resolution: {integrity: sha512-euIdQ13cRB2wZ3jPsnDnFhINquo1PYFPCg6yVL8b2rp3EdinQHsX9EDdCtRr489D5uhphcRk463OdQAFlsCr0w==} + '@prisma/client@6.19.0': resolution: {integrity: sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g==} engines: {node: '>=18.18'} @@ -733,6 +751,12 @@ packages: '@prisma/debug@6.19.0': resolution: {integrity: sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==} + '@prisma/debug@7.2.0': + resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} + + '@prisma/driver-adapter-utils@7.2.0': + resolution: {integrity: sha512-gzrUcbI9VmHS24Uf+0+7DNzdIw7keglJsD5m/MHxQOU68OhGVzlphQRobLiDMn8CHNA2XN8uugwKjudVtnfMVQ==} + '@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773': resolution: {integrity: sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==} @@ -1058,9 +1082,23 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@reduxjs/toolkit@2.11.2': + resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 || ^19 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -1285,6 +1323,9 @@ packages: '@types/tinycolor2@1.4.6': resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@typescript-eslint/eslint-plugin@8.39.0': resolution: {integrity: sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2311,6 +2352,9 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + immer@11.1.0: + resolution: {integrity: sha512-dlzb07f5LDY+tzs+iLCSXV2yuhaYfezqyZQc+n6baLECWkOMEWxkECAOnXL0ba7lsA25fM9b2jtzpu/uxo1a7g==} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -2820,6 +2864,13 @@ packages: nodemailer: optional: true + next-redux-wrapper@8.1.0: + resolution: {integrity: sha512-2hIau0hcI6uQszOtrvAFqgc0NkZegKYhBB7ZAKiG3jk7zfuQb4E7OV9jfxViqqojh3SEHdnFfPkN9KErttUKuw==} + peerDependencies: + next: '>=9' + react: '*' + react-redux: '*' + next-themes@0.4.6: resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: @@ -3024,6 +3075,40 @@ packages: perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} + + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -3049,6 +3134,26 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-array@3.0.4: + resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} + engines: {node: '>=12'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + preact-render-to-string@5.2.6: resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: @@ -3061,8 +3166,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} engines: {node: '>=14'} hasBin: true @@ -3130,6 +3235,18 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-redux@9.2.0: + resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==} + peerDependencies: + '@types/react': ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + redux: + optional: true + react-remove-scroll-bar@2.3.8: resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} engines: {node: '>=10'} @@ -3172,6 +3289,14 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + redux-thunk@3.1.0: + resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} + peerDependencies: + redux: ^5.0.0 + + redux@5.0.1: + resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -3187,6 +3312,9 @@ packages: resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} engines: {node: '>=0.10.0'} + reselect@5.1.1: + resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -3370,6 +3498,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} @@ -3535,38 +3667,38 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-darwin-64@2.5.5: - resolution: {integrity: sha512-RYnTz49u4F5tDD2SUwwtlynABNBAfbyT2uU/brJcyh5k6lDLyNfYKdKmqd3K2ls4AaiALWrFKVSBsiVwhdFNzQ==} + turbo-darwin-64@2.7.2: + resolution: {integrity: sha512-dxY3X6ezcT5vm3coK6VGixbrhplbQMwgNsCsvZamS/+/6JiebqW9DKt4NwpgYXhDY2HdH00I7FWs3wkVuan4rA==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.5: - resolution: {integrity: sha512-Tk+ZeSNdBobZiMw9aFypQt0DlLsWSFWu1ymqsAdJLuPoAH05qCfYtRxE1pJuYHcJB5pqI+/HOxtJoQ40726Btw==} + turbo-darwin-arm64@2.7.2: + resolution: {integrity: sha512-1bXmuwPLqNFt3mzrtYcVx1sdJ8UYb124Bf48nIgcpMCGZy3kDhgxNv1503kmuK/37OGOZbsWSQFU4I08feIuSg==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.5: - resolution: {integrity: sha512-2/XvMGykD7VgsvWesZZYIIVXMlgBcQy+ZAryjugoTcvJv8TZzSU/B1nShcA7IAjZ0q7OsZ45uP2cOb8EgKT30w==} + turbo-linux-64@2.7.2: + resolution: {integrity: sha512-kP+TiiMaiPugbRlv57VGLfcjFNsFbo8H64wMBCPV2270Or2TpDCBULMzZrvEsvWFjT3pBFvToYbdp8/Kw0jAQg==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.5: - resolution: {integrity: sha512-DW+8CjCjybu0d7TFm9dovTTVg1VRnlkZ1rceO4zqsaLrit3DgHnN4to4uwyuf9s2V/BwS3IYcRy+HG9BL596Iw==} + turbo-linux-arm64@2.7.2: + resolution: {integrity: sha512-VDJwQ0+8zjAfbyY6boNaWfP6RIez4ypKHxwkuB6SrWbOSk+vxTyW5/hEjytTwK8w/TsbKVcMDyvpora8tEsRFw==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.5: - resolution: {integrity: sha512-q5p1BOy8ChtSZfULuF1BhFMYIx6bevXu4fJ+TE/hyNfyHJIfjl90Z6jWdqAlyaFLmn99X/uw+7d6T/Y/dr5JwQ==} + turbo-windows-64@2.7.2: + resolution: {integrity: sha512-rPjqQXVnI6A6oxgzNEE8DNb6Vdj2Wwyhfv3oDc+YM3U9P7CAcBIlKv/868mKl4vsBtz4ouWpTQNXG8vljgJO+w==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.5: - resolution: {integrity: sha512-AXbF1KmpHUq3PKQwddMGoKMYhHsy5t1YBQO8HZ04HLMR0rWv9adYlQ8kaeQJTko1Ay1anOBFTqaxfVOOsu7+1Q==} + turbo-windows-arm64@2.7.2: + resolution: {integrity: sha512-tcnHvBhO515OheIFWdxA+qUvZzNqqcHbLVFc1+n+TJ1rrp8prYicQtbtmsiKgMvr/54jb9jOabU62URAobnB7g==} cpu: [arm64] os: [win32] - turbo@2.5.5: - resolution: {integrity: sha512-eZ7wI6KjtT1eBqCnh2JPXWNUAxtoxxfi6VdBdZFvil0ychCOTxbm7YLRBi1JSt7U3c+u3CLxpoPxLdvr/Npr3A==} + turbo@2.7.2: + resolution: {integrity: sha512-5JIA5aYBAJSAhrhbyag1ZuMSgUZnHtI+Sq3H8D3an4fL8PeF+L1yYvbEJg47akP1PFfATMf5ehkqFnxfkmuwZQ==} hasBin: true tw-animate-css@1.3.6: @@ -3745,6 +3877,10 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -4043,6 +4179,14 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@prisma/adapter-pg@7.2.0': + dependencies: + '@prisma/driver-adapter-utils': 7.2.0 + pg: 8.16.3 + postgres-array: 3.0.4 + transitivePeerDependencies: + - pg-native + '@prisma/client@6.19.0(prisma@6.19.0(typescript@5.9.2))(typescript@5.9.2)': optionalDependencies: prisma: 6.19.0(typescript@5.9.2) @@ -4059,6 +4203,12 @@ snapshots: '@prisma/debug@6.19.0': {} + '@prisma/debug@7.2.0': {} + + '@prisma/driver-adapter-utils@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + '@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773': {} '@prisma/engines@6.19.0': @@ -4353,8 +4503,22 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1))(react@19.1.1)': + dependencies: + '@standard-schema/spec': 1.0.0 + '@standard-schema/utils': 0.3.0 + immer: 11.1.0 + redux: 5.0.1 + redux-thunk: 3.1.0(redux@5.0.1) + reselect: 5.1.1 + optionalDependencies: + react: 19.1.1 + react-redux: 9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1) + '@standard-schema/spec@1.0.0': {} + '@standard-schema/utils@0.3.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -4606,6 +4770,8 @@ snapshots: '@types/tinycolor2@1.4.6': {} + '@types/use-sync-external-store@0.0.6': {} + '@typescript-eslint/eslint-plugin@8.39.0(@typescript-eslint/parser@8.39.0(eslint@9.32.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.32.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -4699,13 +4865,13 @@ snapshots: '@typescript-eslint/types': 8.39.0 eslint-visitor-keys: 4.2.1 - '@xyflow/react@12.9.3(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@xyflow/react@12.9.3(@types/react@19.1.9)(immer@11.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@xyflow/system': 0.0.73 classcat: 5.0.5 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - zustand: 4.5.7(@types/react@19.1.9)(react@19.1.1) + zustand: 4.5.7(@types/react@19.1.9)(immer@11.1.0)(react@19.1.1) transitivePeerDependencies: - '@types/react' - immer @@ -5419,11 +5585,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.5.5(eslint@9.32.0(jiti@2.5.1))(turbo@2.5.5): + eslint-plugin-turbo@2.5.5(eslint@9.32.0(jiti@2.5.1))(turbo@2.7.2): dependencies: dotenv: 16.0.3 eslint: 9.32.0(jiti@2.5.1) - turbo: 2.5.5 + turbo: 2.7.2 eslint-scope@8.4.0: dependencies: @@ -5913,6 +6079,8 @@ snapshots: ignore@7.0.5: {} + immer@11.1.0: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -6400,6 +6568,12 @@ snapshots: react-dom: 19.1.1(react@19.1.1) uuid: 8.3.2 + next-redux-wrapper@8.1.0(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-redux@9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1))(react@19.1.1): + dependencies: + next: 15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-redux: 9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1) + next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: react: 19.1.1 @@ -6643,6 +6817,41 @@ snapshots: perfect-debounce@1.0.0: {} + pg-cloudflare@1.2.7: + optional: true + + pg-connection-string@2.9.1: {} + + pg-int8@1.0.1: {} + + pg-pool@3.10.1(pg@8.16.3): + dependencies: + pg: 8.16.3 + + pg-protocol@1.10.3: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.16.3: + dependencies: + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.2.7 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + picocolors@1.0.1: {} picocolors@1.1.1: {} @@ -6669,6 +6878,18 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postgres-array@2.0.0: {} + + postgres-array@3.0.4: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + preact-render-to-string@5.2.6(preact@10.27.2): dependencies: preact: 10.27.2 @@ -6678,7 +6899,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.6.2: {} + prettier@3.7.4: {} pretty-format@3.8.0: {} @@ -6755,6 +6976,15 @@ snapshots: react-is@16.13.1: {} + react-redux@9.2.0(@types/react@19.1.9)(react@19.1.1)(redux@5.0.1): + dependencies: + '@types/use-sync-external-store': 0.0.6 + react: 19.1.1 + use-sync-external-store: 1.6.0(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + redux: 5.0.1 + react-remove-scroll-bar@2.3.8(@types/react@19.1.9)(react@19.1.1): dependencies: react: 19.1.1 @@ -6792,6 +7022,12 @@ snapshots: readdirp@4.1.2: {} + redux-thunk@3.1.0(redux@5.0.1): + dependencies: + redux: 5.0.1 + + redux@5.0.1: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -6821,6 +7057,8 @@ snapshots: dependencies: rc: 1.2.8 + reselect@5.1.1: {} + resolve-from@4.0.0: {} resolve@1.22.10: @@ -7064,6 +7302,8 @@ snapshots: source-map@0.6.1: {} + split2@4.2.0: {} + sprintf-js@1.1.3: {} statuses@2.0.1: {} @@ -7242,32 +7482,32 @@ snapshots: tslib@2.8.1: {} - turbo-darwin-64@2.5.5: + turbo-darwin-64@2.7.2: optional: true - turbo-darwin-arm64@2.5.5: + turbo-darwin-arm64@2.7.2: optional: true - turbo-linux-64@2.5.5: + turbo-linux-64@2.7.2: optional: true - turbo-linux-arm64@2.5.5: + turbo-linux-arm64@2.7.2: optional: true - turbo-windows-64@2.5.5: + turbo-windows-64@2.7.2: optional: true - turbo-windows-arm64@2.5.5: + turbo-windows-arm64@2.7.2: optional: true - turbo@2.5.5: + turbo@2.7.2: optionalDependencies: - turbo-darwin-64: 2.5.5 - turbo-darwin-arm64: 2.5.5 - turbo-linux-64: 2.5.5 - turbo-linux-arm64: 2.5.5 - turbo-windows-64: 2.5.5 - turbo-windows-arm64: 2.5.5 + turbo-darwin-64: 2.7.2 + turbo-darwin-arm64: 2.7.2 + turbo-linux-64: 2.7.2 + turbo-linux-arm64: 2.7.2 + turbo-windows-64: 2.7.2 + turbo-windows-arm64: 2.7.2 tw-animate-css@1.3.6: {} @@ -7468,6 +7708,8 @@ snapshots: wrappy@1.0.2: {} + xtend@4.0.2: {} + yallist@4.0.0: {} yallist@5.0.0: {} @@ -7478,9 +7720,10 @@ snapshots: zod@3.25.76: {} - zustand@4.5.7(@types/react@19.1.9)(react@19.1.1): + zustand@4.5.7(@types/react@19.1.9)(immer@11.1.0)(react@19.1.1): dependencies: use-sync-external-store: 1.6.0(react@19.1.1) optionalDependencies: '@types/react': 19.1.9 + immer: 11.1.0 react: 19.1.1