chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { fileURLToPath } from 'node:url';
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { viteSingleFile } from 'vite-plugin-singlefile';
// The PDS this dev server proxies to for API, auth, and (pre-login) the
// account pages themselves. See `just dev-live`.
const PDS_TARGET = process.env.PDS_DEV_TARGET || 'http://localhost:2471';
const toPds = { target: PDS_TARGET, ws: true };
// One file out, by design. The PDS serves this from a JS module rather than a
// directory: Workers has no filesystem, and a single document means the
// account pages keep arriving in one request the way the server-rendered
// ones did.
export default defineConfig({
plugins: [react(), tailwindcss(), viteSingleFile()],
// Dev-only (ignored by `vite build`): serve this app with HMR while the real
// PDS answers everything dynamic. The Host header is forwarded as-is, so the
// PDS's same-origin POST check still passes.
server: {
proxy: {
// API, form posts, and xrpc always hit the PDS.
'^/(account/(api|sign-in|sign-out)|xrpc)(/|$)': toPds,
// Account pages: serve the local SPA (with HMR) once signed in; before
// that, proxy to the PDS so its sign-in / onboarding / consent screens
// render and can set the session cookie on this origin.
'^/account($|/)': {
...toPds,
bypass(req) {
const signedIn = (req.headers.cookie || '').includes(
'pdsjs_account=',
);
if (req.method === 'GET' && signedIn) return '/index.html';
},
},
},
},
resolve: {
alias: [
{
find: /^#\/(.*)/,
replacement: `${fileURLToPath(new URL('./src', import.meta.url))}/$1`,
},
],
},
build: {
target: 'es2022',
assetsInlineLimit: 100000000,
chunkSizeWarningLimit: 4096,
cssCodeSplit: false,
reportCompressedSize: false,
},
});