Initial commit

This commit is contained in:
agent
2026-03-13 23:21:55 +00:00
commit c8ed262197
113 changed files with 13211 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
kind = "api"
previewPath = "/api" # TODO - should be excluded from preview in the first place
title = "API Server"
version = "1.0.0"
id = "3B4_FFSkEVBkAeYMFRJ2e"
[[services]]
localPort = 8080
name = "API Server"
paths = ["/api"]
[services.development]
run = "pnpm --filter @workspace/api-server run dev"
[services.production]
build = "pnpm --filter @workspace/api-server run build"
[services.production.run]
args = ["node", "artifacts/api-server/dist/index.cjs"]
[services.production.run.env]
PORT = "8080"
[services.production.health.startup]
path = "/api/healthz"

View File

@@ -0,0 +1,75 @@
import path from "path";
import { fileURLToPath } from "url";
import { build as esbuild } from "esbuild";
import { rm, readFile } from "fs/promises";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// server deps to bundle to reduce openat(2) syscalls
// which helps cold start times without risking some
// packages that are not bundle compatible
const allowlist = [
"@google/generative-ai",
"axios",
"connect-pg-simple",
"cors",
"date-fns",
"drizzle-orm",
"drizzle-zod",
"express",
"express-rate-limit",
"express-session",
"jsonwebtoken",
"memorystore",
"multer",
"nanoid",
"nodemailer",
"openai",
"passport",
"passport-local",
"pg",
"stripe",
"uuid",
"ws",
"xlsx",
"zod",
"zod-validation-error",
];
async function buildAll() {
const distDir = path.resolve(__dirname, "dist");
await rm(distDir, { recursive: true, force: true });
console.log("building server...");
const pkgPath = path.resolve(__dirname, "package.json");
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
const allDeps = [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.devDependencies || {}),
];
const externals = allDeps.filter(
(dep) =>
!allowlist.includes(dep) &&
!(pkg.dependencies?.[dep]?.startsWith("workspace:")),
);
await esbuild({
entryPoints: [path.resolve(__dirname, "src/index.ts")],
platform: "node",
bundle: true,
format: "cjs",
outfile: path.resolve(distDir, "index.cjs"),
define: {
"process.env.NODE_ENV": '"production"',
},
minify: true,
external: externals,
logLevel: "info",
});
}
buildAll().catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -0,0 +1,27 @@
{
"name": "@workspace/api-server",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "NODE_ENV=development tsx ./src/index.ts",
"build": "tsx ./build.ts",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@workspace/db": "workspace:*",
"@workspace/api-zod": "workspace:*",
"drizzle-orm": "catalog:",
"express": "^5",
"cookie-parser": "^1.4.7",
"cors": "^2"
},
"devDependencies": {
"@types/node": "catalog:",
"@types/express": "^5.0.6",
"@types/cors": "^2.8.19",
"@types/cookie-parser": "^1.4.10",
"esbuild": "^0.27.3",
"tsx": "catalog:"
}
}

View File

@@ -0,0 +1,13 @@
import express, { type Express } from "express";
import cors from "cors";
import router from "./routes";
const app: Express = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/api", router);
export default app;

View File

@@ -0,0 +1,19 @@
import app from "./app";
const rawPort = process.env["PORT"];
if (!rawPort) {
throw new Error(
"PORT environment variable is required but was not provided.",
);
}
const port = Number(rawPort);
if (Number.isNaN(port) || port <= 0) {
throw new Error(`Invalid PORT value: "${rawPort}"`);
}
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});

View File

View File

@@ -0,0 +1,11 @@
import { Router, type IRouter } from "express";
import { HealthCheckResponse } from "@workspace/api-zod";
const router: IRouter = Router();
router.get("/healthz", (_req, res) => {
const data = HealthCheckResponse.parse({ status: "ok" });
res.json(data);
});
export default router;

View File

@@ -0,0 +1,8 @@
import { Router, type IRouter } from "express";
import healthRouter from "./health";
const router: IRouter = Router();
router.use(healthRouter);
export default router;

View File

@@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"types": ["node"]
},
"include": ["src"],
"references": [
{
"path": "../../lib/db"
},
{
"path": "../../lib/api-zod"
}
]
}