-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspecs.ts
More file actions
79 lines (71 loc) · 2.97 KB
/
specs.ts
File metadata and controls
79 lines (71 loc) · 2.97 KB
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
/**
* A Cloudflare Worker to serve OXA JSON Schema, JSON-LD and other specs
*
* Acts as a reverse proxy to translate requested paths and `Content-Type`
* headers into requests for files from the oxa-dev/oxa GitHub repository.
*
* Handles versioned paths like /v1/schema.json, /v2.0/schema.json, etc.
* and rewrites them to fetch from the corresponding GitHub branch/tag.
*/
export default {
async fetch(request: Request) {
const CORS_HEADERS = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type,Accept',
// Cache the pre-flight result for 24 h
'Access-Control-Max-Age': '86400',
};
if (request.method === 'OPTIONS') {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
const url = new URL(request.url);
let path = url.pathname.slice(1);
// Determine which version to use from /v* paths
// Examples: /v1/schema.json -> version: v1, path: schema.json
// /v2.0/schema.json -> version: v2.0, path: schema.json
// /v1.2.3/schema.json -> version: v1.2.3, path: schema.json
// /schema.json -> version: main, path: schema.json
let version = 'main';
const versionMatch = path.match(/^v\d+(\.\d+)*\//);
if (versionMatch) {
// Extract version (e.g., "v1", "v2.0", or "v1.2.3") and remove it from path
version = versionMatch[0].slice(0, -1); // Remove trailing slash
path = path.slice(versionMatch[0].length);
}
// Apply basic content negotiation based on the `Accept` header
const accept = request.headers.get('Accept') ?? '';
if (accept.includes('application/ld+json') && !path.endsWith('.jsonld')) {
path += '.jsonld';
} else if (accept.includes('application/schema+json') && !path.endsWith('schema.json')) {
path += '.schema.json';
}
// Complete path and content type header value
let contentType = 'text/plain; charset=utf-8';
if (path.endsWith('.jsonld')) {
path = `schema/${path}`;
contentType = 'application/ld+json';
} else if (path.endsWith('.schema.json')) {
path = `schema/${path}`;
contentType = 'application/schema+json';
}
// https://raw.githubusercontent.com/oxa-dev/oxa/refs/heads/main/schema/schema.json
// https://raw.githubusercontent.com/oxa-dev/oxa/refs/tags/v0.0.0/schema/schema.json
// const githubUrl = `https://raw.githubusercontent.com/oxa-dev/oxa/${version}/${path}`;
const githubUrl = `https://raw.githubusercontent.com/oxa-dev/oxa/refs/heads/main/schema/schema.json`;
const file = await fetch(githubUrl);
// If the file wasn't found, return a 404
if (!file.ok) {
return new Response(`File not found: ${path} (version: ${version})`, {
status: file.status,
headers: CORS_HEADERS,
});
}
return new Response(file.body, {
headers: {
'Content-Type': contentType,
...CORS_HEADERS,
},
});
},
};