mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
Featured Section - Frontmatter-controlled featured items with featured: true and featuredOrder - Card view with excerpts and list/card toggle button - View preference saved to localStorage - New Convex queries for featured posts and pages with by_featured index Logo Gallery - Continuous marquee scroll with clickable logos - CSS animation, grayscale with color on hover - Configurable speed, position, and title - 5 sample logos included Firecrawl Content Importer - npm run import <url> scrapes external URLs to markdown drafts - Creates local files in content/blog/ with frontmatter - Then sync to dev or prod (no separate import:prod command) API Enhancements - New /api/export endpoint for batch content fetching - AI plugin discovery at /.well-known/ai-plugin.json - OpenAPI 3.0 spec at /openapi.yaml - Enhanced llms.txt documentation Documentation - AGENTS.md with codebase instructions for AI agents - Updated all sync vs deploy tables to include import workflow - Renamed content/pages/changelog.md to changelog-page.md Technical - New components: FeaturedCards.tsx, LogoMarquee.tsx - New script: scripts/import-url.ts - New dependency: @mendable/firecrawl-js - Schema updates with featured, featuredOrder, excerpt fields
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import type { Context } from "@netlify/edge-functions";
|
|
|
|
// Edge function to proxy API endpoints to Convex HTTP
|
|
export default async function handler(
|
|
request: Request,
|
|
_context: Context,
|
|
): Promise<Response> {
|
|
const convexUrl =
|
|
Deno.env.get("VITE_CONVEX_URL") || Deno.env.get("CONVEX_URL");
|
|
|
|
if (!convexUrl) {
|
|
return new Response(
|
|
JSON.stringify({
|
|
error:
|
|
"VITE_CONVEX_URL not set. Add it to Netlify environment variables.",
|
|
}),
|
|
{ status: 500, headers: { "Content-Type": "application/json" } },
|
|
);
|
|
}
|
|
|
|
// Construct the Convex site URL for the HTTP endpoint
|
|
const convexSiteUrl = convexUrl.replace(".cloud", ".site");
|
|
const url = new URL(request.url);
|
|
const targetUrl = `${convexSiteUrl}${url.pathname}${url.search}`;
|
|
|
|
try {
|
|
const response = await fetch(targetUrl, {
|
|
headers: {
|
|
Accept: "application/json",
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return new Response(JSON.stringify({ error: "API endpoint error" }), {
|
|
status: response.status,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
const data = await response.text();
|
|
const contentType =
|
|
response.headers.get("Content-Type") || "application/json";
|
|
|
|
return new Response(data, {
|
|
headers: {
|
|
"Content-Type": contentType,
|
|
"Cache-Control": "public, max-age=300, s-maxage=600",
|
|
"Access-Control-Allow-Origin": "*",
|
|
},
|
|
});
|
|
} catch {
|
|
return new Response(JSON.stringify({ error: "Failed to fetch from API" }), {
|
|
status: 502,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
}
|
|
|
|
export const config = {
|
|
path: ["/api/posts", "/api/post", "/api/export"],
|
|
};
|