File size: 2,661 Bytes
b5762ec
d856122
b5762ec
6be9266
b5762ec
6be9266
b5762ec
 
6be9266
 
b5762ec
 
6be9266
b5762ec
 
 
 
 
 
6be9266
 
b5762ec
 
 
 
6be9266
b5762ec
 
d856122
b5762ec
6be9266
b5762ec
 
 
6be9266
b5762ec
 
 
 
 
 
 
 
 
 
 
6be9266
 
b5762ec
 
 
 
d856122
b5762ec
6be9266
 
b5762ec
d856122
6be9266
 
b5762ec
 
6be9266
 
b5762ec
 
6be9266
b5762ec
6be9266
b5762ec
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
 * Deprecated HF mirror — bundled reference Q&A removed. Deploy holocron-trask-http for live research.
 */

import { createServer } from 'node:http';

function normalizeCorsOrigin(origin) {
  return origin?.trim() ? origin.trim() : '*';
}

function jsonResponse(status, body, origin) {
  const payload = JSON.stringify(body);
  return {
    status,
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'Content-Length': String(Buffer.byteLength(payload)),
      'Access-Control-Allow-Origin': normalizeCorsOrigin(origin),
      'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Trask-Api-Key',
      Vary: 'Origin',
    },
    body: payload,
  };
}

const LIVE_RESEARCH_REQUIRED = {
  error:
    'Bundled reference answers are disabled on this Space. Use OpenKotOR/holocron-trask-http (full trask-http-server) as TRASK_RESEARCHWIZARD_BASE_URL.',
};

async function handleRequest(request) {
  const origin = request.headers.get('origin');
  const url = new URL(request.url);

  if (request.method === 'OPTIONS') {
    return {
      status: 204,
      headers: {
        'Access-Control-Allow-Origin': normalizeCorsOrigin(origin),
        'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Trask-Api-Key',
        Vary: 'Origin',
      },
      body: '',
    };
  }

  if (url.pathname === '/' && request.method === 'GET') {
    return {
      status: 200,
      headers: { 'Content-Type': 'text/plain; charset=utf-8' },
      body: 'Holocron Trask API — live research only (bundled references removed).\n',
    };
  }

  if (url.pathname === '/healthz' && request.method === 'GET') {
    return jsonResponse(200, { ok: true, mode: 'live-trask-http-required', bundledReferenceApi: false }, origin);
  }

  if (url.pathname.startsWith('/reference') || url.pathname.startsWith('/api/trask')) {
    return jsonResponse(503, LIVE_RESEARCH_REQUIRED, origin);
  }

  return jsonResponse(404, { error: 'Not found' }, origin);
}

const port = Number(process.env.PORT || 7860);

createServer(async (req, res) => {
  const request = new Request(`http://${req.headers.host ?? 'localhost'}${req.url ?? '/'}`, {
    method: req.method,
    headers: req.headers,
    body: req.method === 'GET' || req.method === 'HEAD' ? undefined : req,
    duplex: 'half',
  });
  const response = await handleRequest(request);
  res.writeHead(response.status, response.headers);
  res.end(response.body);
}).listen(port, () => {
  console.log(`holocron-trask-api stub listening on ${port}`);
});