@skillmark/webapp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/cd45cc5264daa1c125545b5b4c0756df95d8b6ac5900ecf52323d90f61a47f2d.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/fc50b649db51ed0c303ff2c4b7c0eca2da269cc3dfc7ce40615fc37a7b53366c.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/fc50b649db51ed0c303ff2c4b7c0eca2da269cc3dfc7ce40615fc37a7b53366c.sqlite-shm +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/fc50b649db51ed0c303ff2c4b7c0eca2da269cc3dfc7ce40615fc37a7b53366c.sqlite-wal +0 -0
- package/.wrangler/tmp/bundle-lfa2r7/checked-fetch.js +30 -0
- package/.wrangler/tmp/bundle-lfa2r7/middleware-insertion-facade.js +11 -0
- package/.wrangler/tmp/bundle-lfa2r7/middleware-loader.entry.ts +134 -0
- package/.wrangler/tmp/bundle-lfa2r7/strip-cf-connecting-ip-header.js +13 -0
- package/.wrangler/tmp/dev-IDqSK4/worker-entry-point.js +4918 -0
- package/.wrangler/tmp/dev-IDqSK4/worker-entry-point.js.map +8 -0
- package/package.json +22 -0
- package/src/assets/favicon.png +0 -0
- package/src/assets/skillmark-thumb.png +0 -0
- package/src/db/d1-database-schema.sql +69 -0
- package/src/db/migrations/001-add-github-oauth-and-user-session-tables.sql +40 -0
- package/src/db/migrations/002-add-security-benchmark-columns.sql +30 -0
- package/src/db/migrations/003-add-repo-url-and-update-composite-formula.sql +27 -0
- package/src/routes/api-endpoints-handler.ts +380 -0
- package/src/routes/github-oauth-authentication-handler.ts +427 -0
- package/src/routes/html-pages-renderer.ts +2263 -0
- package/src/routes/static-assets-handler.ts +58 -0
- package/src/worker-entry-point.ts +143 -0
- package/tsconfig.json +19 -0
- package/wrangler.toml +19 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static assets handler for favicon and OG image
|
|
3
|
+
*/
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
|
|
6
|
+
export const assetsRouter = new Hono();
|
|
7
|
+
|
|
8
|
+
// Favicon - base64 encoded PNG (36x35px)
|
|
9
|
+
const FAVICON_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAACQAAAAjCAYAAAD8BaggAAAKq2lDQ1BJQ0MgUHJvZmlsZQAASImVlwdUk8kWx+f70kNCCyAgJfQmvQWQEkILvTdRCUmAUGIMBBGxIYsrsKKISFMWdJWi4KoUWSsWLCwKCtg3yKKirosFGyrvAw5hd9957513z5nM7/xz586de2ZybgAgK7MEgjRYFoB0fqYw1NudGh0TS8U9BxCgABlAACYsdoaAHhzsDxCbn/9u74cQb8Rumc7E+vfv/6vJcbgZbACgYIQTOBnsdIRPIOMNWyDMBADVgOg6azIFM9yLsIIQSRBh8QwnzfG7GU6YZTR+1ic8lIGwGgB4EoslTAKAZIjo1Cx2EhKH5IOwBZ/D4yOcjbBLevoqDsKdCBsiPgKEZ+LTEv4SJ+lvMRMkMVmsJAnPnWXW8B68DEEaa+3/WY7/belpovk9DJBBShb6hCKzNFKz31NX+UmYnxAYNM88zqz/LCeLfCLmmZ3BiJ3njLQw5jxzWB5+kjhpgf7znMjzkvjwMpnh88zN8AybZ+GqUMm+iUIGfZ5ZwoUcRKkREj2Zy5TEz0kOj5rnLF5koCS31DC/BR+GRBeKQiVn4fK93Rf29ZLUIT3jL2fnMSVrM5PDfSR1YC3kz+XTF2JmREty43A9PBd8IiT+gkx3yV6CtGCJPzfNW6JnZIVJ1mYil3NhbbCkhiks3+B5Bt4gAFgDG2AKGACpSCY3O3PmEIxVgrVCXlJyJpWOvDQulclnmy2hWllY2QEw827nrsXbO7PvEVLCL2gbcpHrrI5A9oLGLALgyHEAZOMWNLMbAKhaANAdwxYJs+Y09MwHBhCR3wMFoAI0gA4wRDKzAnbACbgBT+ALgkA4iAErABskg3QgBGtALtgMCkAR2AF2gypQC/aDBnAEHAMd4BQ4Dy6D6+AmGAT3gRiMgRdgArwHUxAE4SAyRIFUIE1IDzKBrCAa5AJ5Qv5QKBQDxUNJEB8SQbnQFqgIKoWqoDqoEfoZOgmdh65C/dBdaAQah95An2EUTIIVYHVYHzaHaTAd9oPD4eVwErwazoHz4O1wBVwPH4bb4fPwdXgQFsMv4EkUQEmhlFBaKFMUDcVABaFiUYkoIWoDqhBVjqpHtaC6UD2oWygx6iXqExqLpqCpaFO0E9oHHYFmo1ejN6CL0VXoBnQ7+iL6FnoEPYH+hiFj1DAmGEcMExONScKswRRgyjEHMW2YS5hBzBjmPRaLVcIaYO2xPtgYbAp2HbYYuxfbij2H7ceOYidxOJwKzgTnjAvCsXCZuAJcJe4w7ixuADeG+4iXwmvirfBe+Fg8H5+HL8c34c/gB/BP8VMEWYIewZEQROAQ1hJKCAcIXYQbhDHCFFGOaEB0JoYTU4ibiRXEFuIl4gPiWykpKW0pB6kQKZ7UJqkKqaNSV6RGpD6R5EnGJAYpjiQibScdIp0j3SW9JZPJ+mQ3ciw5k7yd3Ei+QH5E/ihNkTaTZkpzpDdKV0u3Sw9Iv5IhyOjJ0GVWyOTIlMscl7kh81KWIKsvy5BlyW6QrZY9KTssOylHkbOUC5JLlyuWa5K7KvdMHievL+8pz5HPl98vf0F+lIKi6FAYFDZlC+UA5RJlTAGrYKDAVEhRKFI4otCnMKEor2ijGKmYrViteFpRrIRS0ldiKqUplSgdUxpS+rxIfRF9EXfRtkUtiwYWfVBerOymzFUuVG5VHlT+rEJV8VRJVdmp0qHyUBWtaqwaorpGdZ/qJdWXixUWOy1mLy5cfGzxPTVYzVgtVG2d2n61XrVJdQ11b3WBeqX6BfWXGkoabhopGmUaZzTGNSmaLpo8zTLNs5rPqYpUOjWNWkG9SJ3QUtPy0RJp1Wn1aU1pG2hHaOdpt2o/1CHq0HQSdcp0unUmdDV1A3RzdZt17+kR9Gh6yXp79Hr0Pugb6Efpb9Xv0H9moGzANMgxaDZ4YEg2dDVcbVhveNsIa0QzSjXaa3TTGDa2NU42rja+YQKb2JnwTPaa9C/BLHFYwl9Sv2TYlGRKN80ybTYdMVMy8zfLM+swe2Wuax5rvtO8x/ybha1FmsUBi/uW8pa+lnmWXZZvrIyt2FbVVretydZe1hutO61f25jYcG322dyxpdgG2G617bb9amdvJ7RrsRu317WPt6+xH6Yp0IJpxbQrDhgHd4eNDqccPjnaOWY6HnP808nUKdWpyenZUoOl3KUHlo46azuznOucxS5Ul3iXH13ErlquLNd618duOm4ct4NuT+lG9BT6Yfordwt3oXub+weGI2M945wHysPbo9Cjz1PeM8KzyvORl7ZXklez14S3rfc673M+GB8/n50+w0x1JpvZyJzwtfdd73vRj+QX5lfl99jf2F/o3xUAB/gG7Ap4EKgXyA/sCAJBzKBdQQ+DDYJXB/8Sgg0JDqkOeRJqGZob2hNGCVsZ1hT2Ptw9vCT8foRhhCiiO1ImMi6yMfJDlEdUaZQ42jx6ffT1GNUYXkxnLC42MvZg7OQyz2W7l43F2cYVxA0tN1ievfzqCtUVaStOr5RZyVp5PB4THxXfFP+FFcSqZ00mMBNqEibYDPYe9guOG6eMM8515pZynyY6J5YmPktyTtqVNJ7smlye/JLH4FXxXqf4pNSmfEgNSj2UOp0Wldaajk+PTz/Jl+en8i+u0liVvapfYCIoEIhXO67evXpC6Cc8mAFlLM/ozFRAGqRekaHoO9FIlktWddbHNZFrjmfLZfOze9car9269mmOV85P69Dr2Ou6c7VyN+eOrKevr9sAbUjY0L1RZ2P+xrFN3psaNhM3p27+Nc8irzTv3ZaoLV356vmb8ke/8/6uuUC6QFgwvNVpa+336O953/dts95Wue1bIafwWpFFUXnRl2J28bUfLH+o+GF6e+L2vhK7kn07sDv4O4Z2uu5sKJUrzSkd3RWwq72MWlZY9m73yt1Xy23Ka/cQ94j2iCv8KzordSt3VH6pSq4arHavbq1Rq9lW82EvZ+/APrd9LbXqtUW1n3/k/XinzruuvV6/vnw/dn/W/icHIg/0/ET7qfGg6sGig98P8Q+JG0IbLjbaNzY2qTWVNMPNoubxw3GHbx7xONLZYtpS16rUWnQUHBUdff5z/M9Dx/yOdR+nHW85oXeipo3SVtgOta9tn+hI7hB3xnT2n/Q92d3l1NX2i9kvh05pnao+rXi65AzxTP6Z6bM5ZyfPCc69PJ90frR7Zff9C9EXbl8Mudh3ye/Slctely/00HvOXnG+cuqq49WT12jXOq7bXW/vte1t+9X217Y+u772G/Y3Om463OzqX9p/ZsB14Pwtj1uXbzNvXx8MHOwfihi6Mxw3LL7DufPsbtrd1/ey7k3d3/QA86DwoezD8kdqj+p/M/qtVWwnPj3iMdL7OOzx/VH26IvfM37/Mpb/hPyk/Knm08ZnVs9OjXuN33y+7PnYC8GLqZcFf8j9UfPK8NWJP93+7J2Inhh7LXw9/ab4rcrbQ+9s3nVPBk8+ep/+fupD4UeVjw2faJ96Pkd9fjq15gvuS8VXo69d3/y+PZhOn54WsISs2VYAhQw4MRGAN4cAIMcAQLkJAHHZXF89a9Bcf4FZAv+J53rvWUM6l6NuAAQiw30TAE3nADBGZEVkDka0cDcAW1tLxnwPPNuvzxi5ESBt0ozdraksAP+wuV7+L3n/cwaSqH+b/wU37QX8G4OYsAAAAFZlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA5KGAAcAAAASAAAARKACAAQAAAABAAAAJKADAAQAAAABAAAAIwAAAABBU0NJSQAAAFNjcmVlbnNob3Qa73x3AAAB1GlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4zNjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlVzZXJDb21tZW50PlNjcmVlbnNob3Q8L2V4aWY6VXNlckNvbW1lbnQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpJaYwnAAABRElEQVRYCe1U0RGDIAy1ncFpdAfH0Rl0HIdwGnewPM9HKfVMCfnwenDHCQkhj/dMHlVVbW7eZjxvg+QAUgBJihSGCkMSA5L/v/6htm2lB6v86NTJs+/7bV3XbZ7n5NirfI/DmfwSB8bH1HXt17kL1T/k2PnIaymdCtAHGrcZhiE2qfcqySjXsixV0zR7civZkhkK5eq6zjNhJVsyICKYpmlfgiUMS9nEskVpo8TDibJ3ODbHjLdjz3kWg7P0X3zfl5wdChMSUNx7aGdC9ija8Y1jznIdtmtAF4H+tWSDSQmILP5yR3AmH1DIIi4mMxpAqrJ3Sb+GA7HbcluBuspiRKw29iVWYXxO2psBGsdRyvWT30wyZKNsWGs7txlDAEHZtHLhDgxfvhZr9iLtXaaS4XW5w1SyXDCIL4AkFgtDhSGJAcn/AqbFa8IIHwjUAAAAAElFTkSuQmCC';
|
|
10
|
+
|
|
11
|
+
// OG Image - served from embedded base64
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
|
|
14
|
+
/** Get favicon as PNG response */
|
|
15
|
+
assetsRouter.get('/favicon.ico', (c) => {
|
|
16
|
+
const buffer = Uint8Array.from(atob(FAVICON_BASE64), c => c.charCodeAt(0));
|
|
17
|
+
return new Response(buffer, {
|
|
18
|
+
headers: {
|
|
19
|
+
'Content-Type': 'image/png',
|
|
20
|
+
'Cache-Control': 'public, max-age=31536000',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
assetsRouter.get('/favicon.png', (c) => {
|
|
26
|
+
const buffer = Uint8Array.from(atob(FAVICON_BASE64), c => c.charCodeAt(0));
|
|
27
|
+
return new Response(buffer, {
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'image/png',
|
|
30
|
+
'Cache-Control': 'public, max-age=31536000',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// OG Image - embedded base64 (loaded at build time)
|
|
36
|
+
// Note: For production, consider using Cloudflare R2 for large assets
|
|
37
|
+
const OG_IMAGE_BASE64 = `OG_IMAGE_PLACEHOLDER`;
|
|
38
|
+
|
|
39
|
+
assetsRouter.get('/og-image.png', async (c) => {
|
|
40
|
+
// Return a redirect to a placeholder or serve embedded image
|
|
41
|
+
// For now, we'll serve a simple SVG placeholder that can be replaced
|
|
42
|
+
const svg = `<svg width="1200" height="630" xmlns="http://www.w3.org/2000/svg">
|
|
43
|
+
<rect width="100%" height="100%" fill="#0a0a0a"/>
|
|
44
|
+
<text x="100" y="150" font-family="monospace" font-size="72" font-weight="bold" fill="#fff">SKILLMARK</text>
|
|
45
|
+
<text x="100" y="210" font-family="monospace" font-size="24" fill="#888">THE AGENT SKILL BENCHMARKING PLATFORM</text>
|
|
46
|
+
<text x="100" y="320" font-family="sans-serif" font-size="36" fill="#ccc">Benchmark your AI agent skills with detailed</text>
|
|
47
|
+
<text x="100" y="370" font-family="sans-serif" font-size="36" fill="#ccc">metrics. Compare accuracy, token usage, and</text>
|
|
48
|
+
<text x="100" y="420" font-family="sans-serif" font-size="36" fill="#ccc">cost across models.</text>
|
|
49
|
+
<text x="100" y="540" font-family="monospace" font-size="20" fill="#666">$ npx skillmark run <skill-path></text>
|
|
50
|
+
</svg>`;
|
|
51
|
+
|
|
52
|
+
return new Response(svg, {
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'image/svg+xml',
|
|
55
|
+
'Cache-Control': 'public, max-age=86400',
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skillmark Cloudflare Worker entry point
|
|
3
|
+
*
|
|
4
|
+
* Routes:
|
|
5
|
+
* GET / - Leaderboard HTML page
|
|
6
|
+
* POST /api/results - Submit benchmark results
|
|
7
|
+
* GET /api/leaderboard - Get skill rankings JSON
|
|
8
|
+
* GET /api/skill/:name - Get specific skill details
|
|
9
|
+
* POST /api/verify - Verify API key
|
|
10
|
+
*/
|
|
11
|
+
import { Hono } from 'hono';
|
|
12
|
+
import { cors } from 'hono/cors';
|
|
13
|
+
import { logger } from 'hono/logger';
|
|
14
|
+
import { apiRouter } from './routes/api-endpoints-handler.js';
|
|
15
|
+
import { pagesRouter } from './routes/html-pages-renderer.js';
|
|
16
|
+
import { authRouter } from './routes/github-oauth-authentication-handler.js';
|
|
17
|
+
import { assetsRouter } from './routes/static-assets-handler.js';
|
|
18
|
+
|
|
19
|
+
type Bindings = {
|
|
20
|
+
DB: D1Database;
|
|
21
|
+
ENVIRONMENT: string;
|
|
22
|
+
GITHUB_CLIENT_ID: string;
|
|
23
|
+
GITHUB_CLIENT_SECRET: string;
|
|
24
|
+
SESSION_SECRET: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const app = new Hono<{ Bindings: Bindings }>();
|
|
28
|
+
|
|
29
|
+
// Middleware
|
|
30
|
+
app.use('*', cors({
|
|
31
|
+
origin: '*',
|
|
32
|
+
allowMethods: ['GET', 'POST', 'OPTIONS'],
|
|
33
|
+
allowHeaders: ['Content-Type', 'Authorization', 'X-Skillmark-Version'],
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
// Only log in development
|
|
37
|
+
app.use('*', async (c, next) => {
|
|
38
|
+
if (c.env.ENVIRONMENT !== 'production') {
|
|
39
|
+
return logger()(c, next);
|
|
40
|
+
}
|
|
41
|
+
return next();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Health check
|
|
45
|
+
app.get('/health', (c) => {
|
|
46
|
+
return c.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Static assets (favicon, og-image)
|
|
50
|
+
app.route('/', assetsRouter);
|
|
51
|
+
|
|
52
|
+
// Auth routes (GitHub OAuth)
|
|
53
|
+
app.route('/auth', authRouter);
|
|
54
|
+
|
|
55
|
+
// API routes
|
|
56
|
+
app.route('/api', apiRouter);
|
|
57
|
+
|
|
58
|
+
// HTML pages
|
|
59
|
+
app.route('/', pagesRouter);
|
|
60
|
+
|
|
61
|
+
// 404 handler
|
|
62
|
+
app.notFound((c) => {
|
|
63
|
+
const accept = c.req.header('Accept') || '';
|
|
64
|
+
|
|
65
|
+
if (accept.includes('application/json')) {
|
|
66
|
+
return c.json({ error: 'Not found' }, 404);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return c.html(`
|
|
70
|
+
<!DOCTYPE html>
|
|
71
|
+
<html>
|
|
72
|
+
<head>
|
|
73
|
+
<title>404 - Skillmark</title>
|
|
74
|
+
<style>
|
|
75
|
+
body {
|
|
76
|
+
font-family: system-ui, sans-serif;
|
|
77
|
+
background: #0d1117;
|
|
78
|
+
color: #c9d1d9;
|
|
79
|
+
display: flex;
|
|
80
|
+
justify-content: center;
|
|
81
|
+
align-items: center;
|
|
82
|
+
min-height: 100vh;
|
|
83
|
+
margin: 0;
|
|
84
|
+
}
|
|
85
|
+
.container { text-align: center; }
|
|
86
|
+
h1 { color: #58a6ff; }
|
|
87
|
+
a { color: #58a6ff; }
|
|
88
|
+
</style>
|
|
89
|
+
</head>
|
|
90
|
+
<body>
|
|
91
|
+
<div class="container">
|
|
92
|
+
<h1>404</h1>
|
|
93
|
+
<p>Page not found</p>
|
|
94
|
+
<p><a href="/">Back to leaderboard</a></p>
|
|
95
|
+
</div>
|
|
96
|
+
</body>
|
|
97
|
+
</html>
|
|
98
|
+
`, 404);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Error handler
|
|
102
|
+
app.onError((err, c) => {
|
|
103
|
+
console.error('Unhandled error:', err);
|
|
104
|
+
|
|
105
|
+
const accept = c.req.header('Accept') || '';
|
|
106
|
+
|
|
107
|
+
if (accept.includes('application/json')) {
|
|
108
|
+
return c.json({ error: 'Internal server error' }, 500);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return c.html(`
|
|
112
|
+
<!DOCTYPE html>
|
|
113
|
+
<html>
|
|
114
|
+
<head>
|
|
115
|
+
<title>Error - Skillmark</title>
|
|
116
|
+
<style>
|
|
117
|
+
body {
|
|
118
|
+
font-family: system-ui, sans-serif;
|
|
119
|
+
background: #0d1117;
|
|
120
|
+
color: #c9d1d9;
|
|
121
|
+
display: flex;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
align-items: center;
|
|
124
|
+
min-height: 100vh;
|
|
125
|
+
margin: 0;
|
|
126
|
+
}
|
|
127
|
+
.container { text-align: center; }
|
|
128
|
+
h1 { color: #f85149; }
|
|
129
|
+
a { color: #58a6ff; }
|
|
130
|
+
</style>
|
|
131
|
+
</head>
|
|
132
|
+
<body>
|
|
133
|
+
<div class="container">
|
|
134
|
+
<h1>Error</h1>
|
|
135
|
+
<p>Something went wrong</p>
|
|
136
|
+
<p><a href="/">Back to leaderboard</a></p>
|
|
137
|
+
</div>
|
|
138
|
+
</body>
|
|
139
|
+
</html>
|
|
140
|
+
`, 500);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
export default app;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"types": ["@cloudflare/workers-types"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"allowSyntheticDefaultImports": true,
|
|
15
|
+
"isolatedModules": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules"]
|
|
19
|
+
}
|
package/wrangler.toml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name = "skillmark"
|
|
2
|
+
main = "src/worker-entry-point.ts"
|
|
3
|
+
compatibility_date = "2024-01-01"
|
|
4
|
+
|
|
5
|
+
[[d1_databases]]
|
|
6
|
+
binding = "DB"
|
|
7
|
+
database_name = "skillmark-db"
|
|
8
|
+
database_id = "e1b45b94-f799-4e75-83f2-bebd777b040d"
|
|
9
|
+
|
|
10
|
+
[vars]
|
|
11
|
+
ENVIRONMENT = "production"
|
|
12
|
+
|
|
13
|
+
# Custom domain (configured via Cloudflare dashboard)
|
|
14
|
+
# Domain: skillmark.sh
|
|
15
|
+
|
|
16
|
+
# Required secrets (set via wrangler secret put):
|
|
17
|
+
# - GITHUB_CLIENT_ID: GitHub OAuth App client ID
|
|
18
|
+
# - GITHUB_CLIENT_SECRET: GitHub OAuth App client secret
|
|
19
|
+
# - SESSION_SECRET: Random secret for signing session cookies
|