@@ -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