1
0
silverbullet/plugbox/endpoints.ts
2022-03-21 15:21:34 +01:00

86 lines
2.4 KiB
TypeScript

import { System } from "./runtime";
import { EndpointHook } from "./types";
import express from "express";
export type EndpointRequest = {
method: string;
path: string;
query: { [key: string]: string };
headers: { [key: string]: string };
body: any;
};
export type EndpointResponse = {
status: number;
headers?: { [key: string]: string };
body: any;
};
const endPointPrefix = "/_";
export function exposeSystem(system: System<EndpointHook>) {
return (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
if (!req.path.startsWith(endPointPrefix)) {
return next();
}
Promise.resolve()
.then(async () => {
for (const [plugName, plug] of system.loadedPlugs.entries()) {
const manifest = plug.manifest;
if (!manifest) {
continue;
}
const endpoints = manifest.hooks?.endpoints;
if (endpoints) {
let prefix = `${endPointPrefix}/${plugName}`;
if (!req.path.startsWith(prefix)) {
continue;
}
for (const { path, method, handler } of endpoints) {
let prefixedPath = `${prefix}${path}`;
if (prefixedPath === req.path && method === req.method) {
try {
const response: EndpointResponse = await plug.invoke(
handler,
[
{
path: req.path,
method: req.method,
body: req.body,
query: req.query,
headers: req.headers,
} as EndpointRequest,
]
);
let resp = res.status(response.status);
if (response.headers) {
for (const [key, value] of Object.entries(
response.headers
)) {
resp = resp.header(key, value);
}
}
resp.send(response.body);
return;
} catch (e: any) {
console.error("Error executing function", e);
res.status(500).send(e.message);
return;
}
}
}
}
}
next();
})
.catch((e) => {
console.error(e);
next(e);
});
};
}