fix(build): remove @netlify/functions dependency, use inline types

This commit is contained in:
Wayne Sutton
2025-12-24 00:45:14 -08:00
parent c98049c411
commit 6cbe5006ac
5 changed files with 62 additions and 23 deletions

View File

@@ -1,4 +1,3 @@
import type { Handler, HandlerEvent, HandlerContext } from "@netlify/functions";
import * as fs from "fs";
import * as path from "path";
@@ -9,8 +8,20 @@ import * as path from "path";
* Returns text/plain with minimal headers for reliable AI ingestion.
*/
// Inline types for Netlify Functions (avoids external dependency)
interface HandlerEvent {
path: string;
httpMethod: string;
}
interface HandlerResponse {
statusCode: number;
headers: Record<string, string>;
body: string;
}
// Response headers optimized for AI crawlers
const AI_HEADERS = {
const AI_HEADERS: Record<string, string> = {
"Content-Type": "text/plain; charset=utf-8",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "public, max-age=3600",
@@ -20,10 +31,7 @@ const AI_HEADERS = {
// Extract slug from path like /api/raw/my-post or /.netlify/functions/raw/my-post
function extractSlug(rawPath: string): string | null {
// Handle both /api/raw/:slug and /.netlify/functions/raw/:slug patterns
const patterns = [
/^\/api\/raw\/(.+)$/,
/^\/.netlify\/functions\/raw\/(.+)$/,
];
const patterns = [/^\/api\/raw\/(.+)$/, /^\/.netlify\/functions\/raw\/(.+)$/];
for (const pattern of patterns) {
const match = rawPath.match(pattern);
@@ -59,10 +67,8 @@ function readMarkdownFile(slug: string): string | null {
return null;
}
const handler: Handler = async (
event: HandlerEvent,
_context: HandlerContext,
) => {
// Netlify Function handler
const handler = async (event: HandlerEvent): Promise<HandlerResponse> => {
// Only allow GET requests
if (event.httpMethod !== "GET") {
return {
@@ -103,4 +109,3 @@ const handler: Handler = async (
};
export { handler };

View File

@@ -37,7 +37,6 @@
"remark-gfm": "^4.0.0"
},
"devDependencies": {
"@netlify/functions": "^2.8.2",
"@types/node": "^25.0.2",
"@types/react": "^18.2.56",
"@types/react-dom": "^18.2.19",

View File

@@ -98,6 +98,7 @@ export default function Home() {
<strong>
An open-source publishing framework for AI agents and developers.
</strong>{" "}
<br />
Write markdown, sync from the terminal. <br />
<br />
<a

View File

@@ -10,7 +10,7 @@ import {
BookOpen,
Activity,
} from "lucide-react";
import { GithubLogo } from "@phosphor-icons/react";
import { GithubLogo, Spinner } from "@phosphor-icons/react";
import VisitorMap from "../components/VisitorMap";
import siteConfig from "../config/siteConfig";
@@ -48,9 +48,27 @@ export default function Stats() {
.catch(() => setGithubStars(null));
}, []);
// Don't render until stats load
// Show loading spinner while stats load
if (stats === undefined) {
return null;
return (
<div className="stats-page-wide">
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
minHeight: "60vh",
flexDirection: "column",
gap: "1rem",
}}
>
<Spinner size={32} className="spinner-icon" />
<p style={{ color: "var(--text-secondary)", fontSize: "0.875rem" }}>
Loading statistics...
</p>
</div>
</div>
);
}
// Stats card configuration with numbered sections

View File

@@ -715,6 +715,20 @@ body {
animation: dropdownFadeIn 0.15s ease;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spinner-icon {
animation: spin 1s linear infinite;
color: var(--text-secondary);
}
@keyframes dropdownFadeIn {
from {
opacity: 0;
@@ -878,8 +892,8 @@ body {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: none;
@@ -896,6 +910,8 @@ body {
}
.page-sidebar-expand svg {
width: 16px;
height: 16px;
transition: transform 0.15s ease;
}
@@ -904,7 +920,7 @@ body {
}
.page-sidebar-spacer {
width: 20px;
width: 24px;
flex-shrink: 0;
}
@@ -1012,17 +1028,17 @@ body {
}
.page-sidebar-expand {
width: 18px;
height: 18px;
width: 24px;
height: 24px;
}
.page-sidebar-expand svg {
width: 12px;
height: 12px;
width: 16px;
height: 16px;
}
.page-sidebar-spacer {
width: 18px;
width: 24px;
}
.page-sidebar-link {