Skip to content

Commit 08edb92

Browse files
committed
good progress
1 parent 703457b commit 08edb92

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+38588
-156
lines changed

epicshop/epic-me/workers/app.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import OAuthProvider from '@cloudflare/workers-oauth-provider'
22
import { createRequestHandler } from 'react-router'
33
import { type Env } from '#types/helpers'
44
import { DB } from './db/index.ts'
5+
import { withCors } from './utils.ts'
56

67
const requestHandler = createRequestHandler(
78
() => import('virtual:react-router/server-build'),
@@ -17,7 +18,7 @@ const defaultHandler = {
1718
},
1819
} satisfies ExportedHandler<Env>
1920

20-
export default new OAuthProvider({
21+
const oauthProvider = new OAuthProvider({
2122
apiRoute: ['/whoami', '/db-api', '/introspect'],
2223
// @ts-expect-error these types are wrong...
2324
apiHandler: defaultHandler,
@@ -27,3 +28,20 @@ export default new OAuthProvider({
2728
tokenEndpoint: '/token',
2829
clientRegistrationEndpoint: '/register',
2930
})
31+
32+
export default {
33+
fetch: withCors({
34+
getCorsHeaders: (request) => {
35+
if (request.url.includes('/.well-known')) {
36+
return {
37+
'Access-Control-Allow-Origin': '*',
38+
'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
39+
'Cross-Origin-Resource-Policy': 'cross-origin',
40+
}
41+
}
42+
},
43+
handler: (request, env, ctx) => {
44+
return oauthProvider.fetch(request, env, ctx)
45+
},
46+
}),
47+
} satisfies ExportedHandler<Env>

epicshop/epic-me/workers/utils.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export function withCors({
2+
getCorsHeaders,
3+
handler,
4+
}: {
5+
getCorsHeaders(
6+
request: Request,
7+
): Record<string, string> | Headers | null | undefined
8+
handler: ExportedHandlerFetchHandler<Env>
9+
}): ExportedHandlerFetchHandler<Env> {
10+
return async (request, env, ctx) => {
11+
const corsHeaders = getCorsHeaders(request)
12+
if (!corsHeaders) {
13+
return handler(request, env, ctx)
14+
}
15+
16+
// Handle CORS preflight requests
17+
if (request.method === 'OPTIONS') {
18+
return new Response(null, {
19+
status: 200,
20+
headers: mergeHeaders(corsHeaders, {
21+
'Access-Control-Max-Age': '86400',
22+
}),
23+
})
24+
}
25+
26+
// Call the original handler
27+
const response = await handler(request, env, ctx)
28+
29+
// Add CORS headers to ALL responses, including early returns
30+
const newHeaders = mergeHeaders(response.headers, corsHeaders)
31+
32+
return new Response(response.body, {
33+
status: response.status,
34+
statusText: response.statusText,
35+
headers: newHeaders,
36+
})
37+
}
38+
}
39+
40+
/**
41+
* Merge multiple headers objects into one (uses set so headers are overridden)
42+
*/
43+
export function mergeHeaders(
44+
...headers: Array<ResponseInit['headers'] | null | undefined>
45+
) {
46+
const merged = new Headers()
47+
for (const header of headers) {
48+
if (!header) continue
49+
for (const [key, value] of new Headers(header).entries()) {
50+
merged.set(key, value)
51+
}
52+
}
53+
return merged
54+
}

epicshop/mcp-dev/dev.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ const { createProxyServer } = httpProxy
1313
const [, , ...args] = process.argv
1414
const [transport = 'streamable-http'] = args
1515

16-
const proxyPort = process.env.PORT || 3000
16+
const proxyPort = Number(process.env.PORT || 3000)
1717
const inspectorServerPort = await getPort({
18-
port: Array.from({ length: 1000 }, (_, i) => i + 10000),
18+
port: Array.from({ length: 100 }, (_, i) => proxyPort + i + 50000),
1919
exclude: [process.env.PORT].filter(Boolean).map(Number),
2020
})
2121
const inspectorClientPort = await getPort({
22-
port: Array.from({ length: 1000 }, (_, i) => i + 9000),
22+
port: Array.from({ length: 100 }, (_, i) => proxyPort + i + 51000),
2323
exclude: [process.env.PORT, inspectorServerPort].filter(Boolean).map(Number),
2424
})
2525
const mcpServerPort = await getPort({
26-
port: Array.from({ length: 1000 }, (_, i) => i + 11000),
26+
port: Array.from({ length: 100 }, (_, i) => proxyPort + i + 52000),
2727
exclude: [process.env.PORT, inspectorServerPort, inspectorClientPort]
2828
.filter(Boolean)
2929
.map(Number),

exercises/01.start/01.solution/src/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DBClient } from '@epic-web/epicme-db-client'
22

3-
const EPIC_ME_SERVER_URL = 'http://localhost:7788'
3+
export const EPIC_ME_SERVER_URL = 'http://localhost:7788'
44

55
export function getClient() {
66
return new DBClient(EPIC_ME_SERVER_URL)

exercises/01.start/01.solution/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { initializeResources } from './resources.ts'
1111
import { initializeTools } from './tools.ts'
1212

1313
type State = { loggingLevel: LoggingLevel }
14+
1415
export class EpicMeMCP extends McpAgent<Env, State> {
1516
db!: DBClient
1617
initialState: State = { loggingLevel: 'info' }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Authenticate Header

0 commit comments

Comments
 (0)