powr-sdk-api
Version:
Shared API core library for PowrStack projects. Zero dependencies - works with Express, Next.js API routes, and other frameworks. All features are optional and install only what you need.
237 lines (223 loc) • 6.22 kB
JavaScript
"use strict";
const express = require("express");
const router = express.Router();
const functionsManager = require("../managers/functions");
const {
getDb
} = require("../services/mongo");
// Get Functions status
router.get("/status", async (req, res) => {
try {
const stats = functionsManager.getStats();
return res.status(200).json({
success: true,
data: {
...stats,
message: stats.isEnabled ? "Functions is running" : "Functions is disabled"
}
});
} catch (err) {
console.error("Error getting Functions status:", err);
return res.status(500).json({
success: false,
message: "Error getting Functions status"
});
}
});
// Enable Functions
router.post("/enable", async (req, res) => {
try {
functionsManager.enable();
return res.status(200).json({
success: true,
message: "Functions enabled successfully",
data: functionsManager.getStats()
});
} catch (err) {
console.error("Error enabling Functions:", err);
return res.status(500).json({
success: false,
message: "Error enabling Functions"
});
}
});
// Disable Functions
router.post("/disable", async (req, res) => {
try {
functionsManager.disable();
return res.status(200).json({
success: true,
message: "Functions disabled successfully",
data: functionsManager.getStats()
});
} catch (err) {
console.error("Error disabling Functions:", err);
return res.status(500).json({
success: false,
message: "Error disabling Functions"
});
}
});
// Toggle Functions
router.post("/toggle", async (req, res) => {
try {
const isEnabled = functionsManager.toggle();
return res.status(200).json({
success: true,
message: isEnabled ? "Functions enabled" : "Functions disabled",
data: functionsManager.getStats()
});
} catch (err) {
console.error("Error toggling Functions:", err);
return res.status(500).json({
success: false,
message: "Error toggling Functions"
});
}
});
// CRUD Operations for Functions
// Get all functions entries
router.get('/', async (req, res) => {
const projectId = req.projectId;
try {
const query = {
projectId
};
const db = await getDb();
const functionsData = await db.collection("functions").find(query).toArray();
return res.status(200).json({
success: true,
allfunctions: functionsData
});
} catch (error) {
console.error("Error retrieving functions entries:", error);
return res.status(500).json({
success: false,
message: "Failed to retrieve functions entries."
});
}
});
// Create a new function
router.post('/', async (req, res) => {
try {
const projectId = req.projectId;
const newFunction = req.body;
newFunction.projectId = projectId;
if (!newFunction || Object.keys(newFunction).length === 0) {
return res.status(400).json({
success: false,
message: 'Request body is empty or invalid.'
});
}
const db = await getDb();
const result = await db.collection('functions').insertOne(newFunction);
// Recompile the new function using Functions manager (only if enabled)
if (functionsManager.getStats().isEnabled) {
await functionsManager.updateRoute(projectId, newFunction.route, newFunction.code);
}
return res.status(201).json({
success: true,
entry: result.ops ? result.ops[0] : newFunction
});
} catch (error) {
console.error('Error inserting function entry:', error);
return res.status(500).json({
success: false,
message: 'Failed to insert function entry.'
});
}
});
// Update function code
router.put('/:function', async (req, res) => {
try {
const {
function: functionName
} = req.params;
const {
code
} = req.body;
const projectId = req.projectId;
if (!code) {
return res.status(400).json({
success: false,
message: 'Code field is required.'
});
}
const query = {
route: functionName,
projectId
};
const db = await getDb();
const existingFunction = await db.collection('functions').findOne(query);
if (!existingFunction) {
return res.status(404).json({
success: false,
message: 'Function not found.'
});
}
// Update database
const result = await db.collection('functions').updateOne(query, {
$set: {
code
}
});
if (result.matchedCount === 0) {
return res.status(404).json({
success: false,
message: 'Function not found.'
});
}
// Recompile the updated function using Functions manager (only if enabled)
if (functionsManager.getStats().isEnabled) {
await functionsManager.updateRoute(projectId, functionName, code);
}
const updatedFunction = await db.collection('functions').findOne(query);
return res.status(200).json({
success: true,
entry: updatedFunction
});
} catch (error) {
console.error('Error updating function code:', error);
return res.status(500).json({
success: false,
message: 'Failed to update function code.',
error: error.message
});
}
});
// Execute dynamic function
router.post("/:function", async (req, res) => {
const {
function: functionName
} = req.params;
const projectId = req.projectId;
try {
// Use pre-compiled function (NO COMPILATION HERE)
const params = {
...req.query,
...req.body
};
const result = await functionsManager.execute(projectId, functionName, params);
// Handle the standardized response format
if (result.success) {
return res.status(200).json({
success: true,
data: result.data,
message: result.message
});
} else {
return res.status(404).json({
success: false,
message: result.message,
data: result.data
});
}
} catch (err) {
console.error("Error executing function:", err);
return res.status(500).json({
success: false,
message: "Error executing function"
});
}
});
module.exports = router;