Files
dsh-plugin-model-enhancer/lib/index.js
T

72 lines
2.0 KiB
JavaScript
Raw Normal View History

const name = "dsh-plugin-model-enhancer";
const inject = ["webServer"];
let cachedData = null;
let lastFetchedAt = 0;
const CACHE_TTL_MS = 3600 * 1e3;
async function getModelsDevData() {
const now = Date.now();
if (cachedData && now - lastFetchedAt < CACHE_TTL_MS) {
return cachedData;
}
try {
const res = await fetch("https://models.dev/api.json", {
headers: {
"User-Agent": "DSH-Model-Enhancer/1.0.0"
}
});
if (!res.ok) {
throw new Error(`Failed to fetch models.dev: HTTP ${res.status}`);
}
const json = await res.json();
cachedData = json;
lastFetchedAt = now;
return json;
} catch (err) {
if (cachedData) {
return cachedData;
}
throw err;
}
}
function apply(ctx) {
ctx.effect(() => {
return ctx.webServer.register({
kind: "exact",
path: "/api/models-dev/models",
handler: async (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
if (req.method === "OPTIONS") {
res.writeHead(204);
res.end();
return;
}
if (req.method !== "GET") {
res.writeHead(405, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: "Method Not Allowed" }));
return;
}
try {
const data = await getModelsDevData();
res.writeHead(200, {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=3600"
});
res.end(JSON.stringify(data));
} catch (err) {
ctx.logger?.error?.("[model-enhancer] Error fetching models.dev:", err);
res.writeHead(500, { "Content-Type": "application/json" });
res.end(JSON.stringify({ error: err.message || "Internal Server Error" }));
}
}
});
}, "dsh-plugin-model-enhancer: webServer proxy route");
}
export {
apply,
getModelsDevData,
inject,
name
};