Skip to content

Commit 057c755

Browse files
committed
adapter-cf: static routes exposed through worker reverted
1 parent a5c0ae7 commit 057c755

3 files changed

Lines changed: 11 additions & 164 deletions

File tree

example/cloudflare/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"private": true,
44
"type": "module",
55
"scripts": {
6-
"cf:bundle": "statikapi-cf --watch --src src-api --out dist/worker.mjs",
6+
"cf:bundle": "statikapi-cf --src src-api --out dist/worker.mjs",
77
"cf:watch": "chokidar \"src-api/**/*.{js,mjs,cjs}\" -c \"pnpm cf:bundle\"",
88
"cf:wrangler:dev": "wrangler dev --local",
99
"cf:dev": "concurrently -n BUILD,WRANGLER -c yellow,cyan \"pnpm cf:watch\" \"pnpm cf:wrangler:dev\""

example/cloudflare/wrangler.example.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,4 @@ STATIK_BUILD_TOKEN = "REPLACE_ME_STATIK_BUILD_TOKEN"
1515
STATIK_SRC = "src-api" # optional: lets the CLI auto-detect
1616

1717
# API access
18-
STATIK_ALLOWED_ORIGINS = "https://statikapi.dev,https://example.com"
19-
STATIK_API_REQUIRE_AUTH = "false" # or "true"
20-
STATIK_API_AUTH_TOKEN = "super-secret-api-token"
21-
STATIK_PRETTY_ROUTES = "true"
2218
STATIK_USE_INDEX_JSON = "true"

packages/adapter-cloudflare/src/node/bundle.js

Lines changed: 10 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -208,49 +208,6 @@ const WORKER_RUNTIME_JS = `
208208
// -------------------------
209209
// Config helpers
210210
// -------------------------
211-
function isPrettyRoutes(env) {
212-
return (env.STATIK_PRETTY_ROUTES || 'true').toLowerCase() === 'true';
213-
}
214-
215-
function parseAllowedOrigins(env) {
216-
const raw = env.STATIK_ALLOWED_ORIGINS || '';
217-
return raw
218-
.split(',')
219-
.map((s) => s.trim())
220-
.filter(Boolean);
221-
}
222-
223-
function isOriginAllowed(origin, env) {
224-
if (!origin) return true; // server-to-server, curl, etc.
225-
const allowed = parseAllowedOrigins(env);
226-
if (!allowed.length) return true; // no restriction configured
227-
return allowed.includes(origin);
228-
}
229-
230-
function isReadAuthorized(req, env) {
231-
const requireAuth = (env.STATIK_API_REQUIRE_AUTH || 'false').toLowerCase() === 'true';
232-
if (!requireAuth) return true;
233-
234-
const auth = req.headers.get('authorization') || '';
235-
const token = env.STATIK_API_AUTH_TOKEN || '';
236-
if (!token) return false;
237-
238-
const want = 'Bearer ' + token;
239-
return auth === want;
240-
}
241-
242-
function corsHeaders(origin, extra = {}) {
243-
const headers = {
244-
'content-type': 'application/json; charset=utf-8',
245-
...extra,
246-
};
247-
if (origin) {
248-
headers['access-control-allow-origin'] = origin;
249-
headers['vary'] = 'origin';
250-
}
251-
return headers;
252-
}
253-
254211
function useIndexJson(env) {
255212
return (env.STATIK_USE_INDEX_JSON || 'true').toLowerCase() === 'true';
256213
}
@@ -373,60 +330,23 @@ const WORKER_RUNTIME_JS = `
373330
const clean = concreteRoute.replace(/^\\/+/, '');
374331
375332
if (useIndex) {
376-
// old behavior: posts -> posts/index.json
333+
// index.json mode: posts -> posts/index.json
377334
return clean + '/index.json';
378335
}
379336
380337
// flat mode: posts -> posts
381338
return clean;
382339
}
383340
384-
// From request path ('/', '/posts', '/posts/index.json') to R2 key,
385-
// obeying STATIK_PRETTY_ROUTES and STATIK_USE_INDEX_JSON.
386-
function r2KeyFromRequestPath(pathname, env) {
387-
const pretty = isPrettyRoutes(env);
388-
const useIndex = useIndexJson(env);
389-
390-
// Root handling
391-
if (!pathname || pathname === '/') {
392-
return useIndex ? 'index.json' : 'index';
393-
}
394-
395-
let p = pathname;
396-
if (p.startsWith('/')) p = p.slice(1);
397-
398-
// If user explicitly asks for .json, always respect it,
399-
// but in flat mode we map \`/foo.json\` -> \`foo\`.
400-
if (p.endsWith('.json')) {
401-
if (useIndex) {
402-
// index.json mode: the key really is '...json'
403-
return p;
404-
}
405-
// flat mode: drop '.json' and read from bare key
406-
return p.slice(0, -5);
407-
}
408-
409-
// Pretty routes: '/posts' is valid
410-
if (pretty) {
411-
return useIndex ? p + '/index.json' : p;
412-
}
413-
414-
// Non-pretty mode:
415-
// - index.json mode: require explicit '/foo/index.json' (handled above)
416-
// - flat mode: treat '/foo' as key 'foo'
417-
return useIndex ? null : p;
418-
}
419-
420-
// All public paths that should map to a given route
421-
// (for cache purge, etc.)
341+
// All public paths that *should* map to a given route
342+
// (used only for worker cache purge; actual public access is via R2 now).
422343
function publicPathsForRoute(route, env) {
423-
const pretty = isPrettyRoutes(env);
424344
const useIndex = useIndexJson(env);
425345
426346
if (route === '/') {
427347
if (useIndex) {
428-
// root index.json plus pretty '/'
429-
return pretty ? ['/', '/index.json'] : ['/index.json'];
348+
// root index.json plus '/'
349+
return ['/', '/index.json'];
430350
}
431351
// flat root: underlying key 'index', but we still may serve '/', '/index', '/index.json'
432352
return ['/', '/index', '/index.json'];
@@ -435,12 +355,12 @@ const WORKER_RUNTIME_JS = `
435355
const base = route; // e.g. '/posts', '/users/1'
436356
437357
if (useIndex) {
438-
const jsonPath = base + '/index.json';
439-
return pretty ? [base, jsonPath] : [jsonPath];
358+
// index.json mode: primary JSON path is '/posts/index.json'
359+
return [base + '/index.json'];
440360
}
441361
442362
// flat keys: underlying key is 'posts' or 'users/1'
443-
// we purge both pretty path and .json alias
363+
// purge both extensionless and .json alias
444364
return [base, base + '.json'];
445365
}
446366
@@ -464,50 +384,6 @@ const WORKER_RUNTIME_JS = `
464384
await env.STATIK_MANIFEST.put(MANIFEST_KEY, JSON.stringify(list));
465385
}
466386
467-
// -------------------------
468-
// Read: GET JSON from R2
469-
// -------------------------
470-
async function handleRead(req, env) {
471-
const url = new URL(req.url);
472-
const origin = req.headers.get('origin') || '';
473-
474-
if (!isOriginAllowed(origin, env)) {
475-
return new Response('forbidden', { status: 403 });
476-
}
477-
478-
if (!isReadAuthorized(req, env)) {
479-
return new Response(
480-
JSON.stringify({ ok: false, error: 'unauthorized' }),
481-
{ status: 401, headers: corsHeaders(origin) },
482-
);
483-
}
484-
485-
const key = r2KeyFromRequestPath(url.pathname, env);
486-
if (!key) {
487-
return new Response(
488-
JSON.stringify({ ok: false, error: 'not_found' }),
489-
{ status: 404, headers: corsHeaders(origin) },
490-
);
491-
}
492-
493-
const obj = await env.STATIK_BUCKET.get(key);
494-
495-
if (!obj) {
496-
return new Response(
497-
JSON.stringify({ ok: false, error: 'not_found' }),
498-
{ status: 404, headers: corsHeaders(origin) },
499-
);
500-
}
501-
502-
const body = await obj.text();
503-
504-
return new Response(body, {
505-
headers: corsHeaders(origin, {
506-
'cache-control': 'public, max-age=0, s-maxage=600',
507-
}),
508-
});
509-
}
510-
511387
// -------------------------
512388
// Cache purge helpers
513389
// -------------------------
@@ -521,26 +397,6 @@ const WORKER_RUNTIME_JS = `
521397
}
522398
}
523399
524-
// -------------------------
525-
// CORS preflight
526-
// -------------------------
527-
async function handleOptions(req, env) {
528-
const origin = req.headers.get('origin') || '';
529-
if (!isOriginAllowed(origin, env)) {
530-
return new Response('forbidden', { status: 403 });
531-
}
532-
533-
return new Response(null, {
534-
headers: {
535-
...(origin ? { 'access-control-allow-origin': origin } : {}),
536-
'access-control-allow-methods': 'GET, OPTIONS, POST',
537-
'access-control-allow-headers': 'Content-Type, Authorization',
538-
'access-control-max-age': '86400',
539-
'vary': 'origin',
540-
},
541-
});
542-
}
543-
544400
// -------------------------
545401
// Build single route
546402
// -------------------------
@@ -678,9 +534,9 @@ const WORKER_RUNTIME_JS = `
678534
async fetch(req, env) {
679535
const url = new URL(req.url);
680536
681-
// CORS preflight
537+
// Minimal OPTIONS handler
682538
if (req.method === 'OPTIONS') {
683-
return handleOptions(req, env);
539+
return new Response(null, { status: 204 });
684540
}
685541
686542
if (req.method === 'POST' && url.pathname === '/__statikapi/build/route') {
@@ -696,11 +552,6 @@ const WORKER_RUNTIME_JS = `
696552
return new Response(JSON.stringify(list), { headers: { 'content-type': 'application/json' } });
697553
}
698554
699-
// Public API: serve JSON directly from R2
700-
if (req.method === 'GET') {
701-
return handleRead(req, env);
702-
}
703-
704555
return new Response('Not found', { status: 404 });
705556
}
706557
};

0 commit comments

Comments
 (0)