mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
170 lines
5.1 KiB
TypeScript
170 lines
5.1 KiB
TypeScript
import type { Express } from "express";
|
|
import { json } from "express";
|
|
import uniq from "lodash/uniq";
|
|
import {
|
|
AvailablePackageType,
|
|
Feed,
|
|
PackageType,
|
|
} from "@refinedev/devtools-shared";
|
|
|
|
import { Data } from "./create-db";
|
|
import { getFeed } from "./feed/get-feed";
|
|
import { getAllPackages } from "./packages/get-all-packages";
|
|
import { getAvailablePackages } from "./packages/get-available-packages";
|
|
import { updatePackage } from "./packages/update-package";
|
|
import { getLatestPackageData } from "./packages/get-latest-package-data";
|
|
import { getProjectIdFromPackageJson } from "./project-id/get-project-id-from-package-json";
|
|
import { updateProjectId } from "./project-id/update-project-id";
|
|
|
|
export const serveApi = (app: Express, db: Data) => {
|
|
app.use("/api", json());
|
|
|
|
app.get("/api/connected-app", (_, res) => {
|
|
res.json({ url: db.connectedApp });
|
|
});
|
|
|
|
app.get("/api/activities", (req, res) => {
|
|
const { offset = 0, limit = db.activities.length } = req.query;
|
|
|
|
res.setHeader("x-total-count", db.activities.length);
|
|
|
|
res.json({
|
|
data: db.activities.slice(Number(offset), Number(limit)),
|
|
});
|
|
});
|
|
|
|
app.get("/api/activities/reset", (_, res) => {
|
|
db.activities = [];
|
|
res.json({ success: true });
|
|
});
|
|
|
|
app.get("/api/unique-trace-items", (req, res) => {
|
|
res.header("Access-Control-Allow-Origin", "*");
|
|
res.header(
|
|
"Access-Control-Allow-Headers",
|
|
"Origin, X-Requested-With, Content-Type, Accept",
|
|
);
|
|
|
|
const traceItems = db.activities.flatMap(
|
|
(activity) =>
|
|
activity.trace?.map((t) => t.function).filter(Boolean) ?? [],
|
|
) as string[];
|
|
const uniqueTraceItems = uniq(traceItems);
|
|
|
|
res.setHeader("x-total-count", uniqueTraceItems.length);
|
|
|
|
res.json({ data: uniqueTraceItems });
|
|
});
|
|
|
|
let cachedInstalledPackages: PackageType[] | null = null;
|
|
app.get("/api/installed-packages", async (req, res) => {
|
|
const { force } = req.query ?? {};
|
|
|
|
if (!cachedInstalledPackages || force) {
|
|
cachedInstalledPackages = await getAllPackages();
|
|
}
|
|
|
|
res.header("x-total-count", `${cachedInstalledPackages.length}`);
|
|
|
|
res.json({ data: cachedInstalledPackages });
|
|
});
|
|
|
|
let cachedAvailablePackages: AvailablePackageType[] | null = null;
|
|
app.get("/api/available-packages", async (_, res) => {
|
|
if (!cachedAvailablePackages) {
|
|
cachedAvailablePackages = await getAvailablePackages();
|
|
}
|
|
|
|
res.header("x-total-count", `${cachedAvailablePackages.length}`);
|
|
|
|
res.json({ data: cachedAvailablePackages });
|
|
});
|
|
|
|
const cachedLatestPackages = new Map<string, any>();
|
|
app.get("/api/packages/:packageName/latest", async (req, res) => {
|
|
const { packageName } = req.params ?? {};
|
|
|
|
if (!packageName) {
|
|
res.status(400).json({ error: "Package name is required" });
|
|
return;
|
|
}
|
|
|
|
if (!cachedLatestPackages.has(packageName)) {
|
|
const latest = await getLatestPackageData(packageName);
|
|
cachedLatestPackages.set(packageName, latest);
|
|
}
|
|
|
|
return res.json({ data: cachedLatestPackages.get(packageName) });
|
|
});
|
|
|
|
app.post("/api/packages/install", async (req, res) => {
|
|
const { packages } = req.body ?? {};
|
|
|
|
if (packages?.length === 0) {
|
|
res.status(400).json({ error: "Package name is required" });
|
|
return;
|
|
}
|
|
|
|
const success = await updatePackage(packages as string[]);
|
|
|
|
if (success) {
|
|
cachedInstalledPackages = null;
|
|
cachedAvailablePackages = null;
|
|
res.status(200).json({ success: true });
|
|
} else {
|
|
res.status(400).json({
|
|
success: false,
|
|
error: "Failed to update package",
|
|
});
|
|
}
|
|
});
|
|
|
|
let cachedFeed: Feed | null = null;
|
|
app.get("/api/feed", async (req, res) => {
|
|
if (!cachedFeed) {
|
|
cachedFeed = await getFeed();
|
|
}
|
|
|
|
res.header("x-total-count", `${cachedFeed.length}`);
|
|
|
|
res.json({ data: cachedFeed });
|
|
});
|
|
|
|
app.get("/api/project-id/status", async (_, res) => {
|
|
const projectId = await getProjectIdFromPackageJson();
|
|
|
|
if (projectId) {
|
|
res.status(200).json({ projectId });
|
|
return;
|
|
} else if (projectId === false) {
|
|
res.status(404).json({ projectId: null });
|
|
return;
|
|
} else {
|
|
res.status(500).json({ projectId: null });
|
|
return;
|
|
}
|
|
});
|
|
|
|
app.post("/api/project-id/update", async (req, res) => {
|
|
const { projectId } = req.body ?? {};
|
|
|
|
if (!projectId) {
|
|
res.status(400).json({ error: "Project ID is required" });
|
|
return;
|
|
}
|
|
|
|
const success = await updateProjectId(projectId);
|
|
|
|
if (success) {
|
|
res.status(200).json({ success: true });
|
|
return;
|
|
} else {
|
|
res.status(500).json({
|
|
success: false,
|
|
error: "Failed to update project ID",
|
|
});
|
|
return;
|
|
}
|
|
});
|
|
};
|