Documentation Index
Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
Use this file to discover all available pages before exploring further.
Envuelve una API externa inyectando credenciales desde secrets. El cliente llama a tu función, y tu función llama a la API real con las claves correctas.
Patrón: ruta con parámetros + inyección de autenticación + transformación de respuesta.
import { define, z } from "@jelou/functions";
export default define({
name: "api-proxy",
description: "Proxy a una API externa con autenticación inyectada",
input: z.object({
fields: z.array(z.string()).optional().describe("Campos a incluir en la respuesta"),
}),
config: {
path: "/users/:id",
methods: ["GET"],
cors: {
origin: "https://app.example.com",
credentials: true,
},
},
handler: async (input, ctx) => {
const apiKey = ctx.env.get("INTERNAL_API_KEY");
const baseUrl = ctx.env.get("API_BASE_URL");
ctx.log("Proxy request", {
userId: ctx.params.id,
fields: input.fields,
});
const res = await fetch(
`${baseUrl}/api/users/${ctx.params.id}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (!res.ok) {
ctx.log("Upstream error", { status: res.status, userId: ctx.params.id });
return { error: "not_found", status: res.status };
}
const user = await res.json();
const result: Record<string, unknown> = {
id: user.id,
name: user.name,
email: user.email,
};
if (input.fields?.includes("address")) {
result.address = user.address;
}
if (input.fields?.includes("orders")) {
result.recentOrders = user.orders?.slice(0, 5);
}
return result;
},
});
Prueba local
curl "http://localhost:3000/users/42?fields=address,orders"
Por qué funciona así
config.path: "/users/:id" — el :id se captura en ctx.params.id.
- Las credenciales nunca se exponen al cliente; viven en secrets.
cors.origin restringe qué dominios pueden llamar al proxy desde el navegador.
- Puedes transformar o filtrar la respuesta antes de devolverla.