Skip to content

Commit cfc3200

Browse files
committed
fix typecheck
1 parent 2e35901 commit cfc3200

File tree

4 files changed

+130
-122
lines changed

4 files changed

+130
-122
lines changed

evals/git-evals/runners/codebuff.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ export class CodebuffRunner implements Runner {
9292
}
9393
},
9494
handleStreamChunk: (chunk) => {
95+
if (typeof chunk !== 'string') {
96+
return
97+
}
9598
process.stdout.write(chunk)
9699
},
97100
maxAgentSteps: MAX_AGENT_STEPS_DEFAULT,

web/src/app/api/v1/me/__tests__/route.test.ts renamed to web/src/app/api/v1/me/impl/__tests__/route.test.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { TEST_AGENT_RUNTIME_IMPL } from '@codebuff/common/testing/impl/agent-run
22
import { describe, test, expect, beforeEach } from 'bun:test'
33
import { NextRequest } from 'next/server'
44

5-
import { _meGet } from '../route'
5+
import { meGet } from '../_get'
66

77
import type { AgentRuntimeDeps } from '@codebuff/common/types/contracts/agent-runtime'
88
import type { GetUserInfoFromApiKeyOutput } from '@codebuff/common/types/contracts/database'
@@ -49,7 +49,7 @@ describe('/api/v1/me route', () => {
4949
describe('Authentication', () => {
5050
test('returns 401 when Authorization header is missing', async () => {
5151
const req = new NextRequest('http://localhost:3000/api/v1/me')
52-
const response = await _meGet({
52+
const response = await meGet({
5353
...agentRuntimeImpl,
5454
req,
5555
})
@@ -63,7 +63,7 @@ describe('/api/v1/me route', () => {
6363
const req = new NextRequest('http://localhost:3000/api/v1/me', {
6464
headers: { Authorization: 'InvalidFormat' },
6565
})
66-
const response = await _meGet({
66+
const response = await meGet({
6767
...agentRuntimeImpl,
6868
req,
6969
})
@@ -79,7 +79,7 @@ describe('/api/v1/me route', () => {
7979
headers: { 'x-codebuff-api-key': apiKey },
8080
})
8181

82-
const response = await _meGet({
82+
const response = await meGet({
8383
...agentRuntimeImpl,
8484
req,
8585
})
@@ -94,7 +94,7 @@ describe('/api/v1/me route', () => {
9494
headers: { Authorization: `Bearer ${apiKey}` },
9595
})
9696

97-
const response = await _meGet({
97+
const response = await meGet({
9898
...agentRuntimeImpl,
9999
req,
100100
})
@@ -108,7 +108,7 @@ describe('/api/v1/me route', () => {
108108
headers: { Authorization: 'Bearer invalid-key' },
109109
})
110110

111-
const response = await _meGet({
111+
const response = await meGet({
112112
...agentRuntimeImpl,
113113
req,
114114
})
@@ -124,7 +124,7 @@ describe('/api/v1/me route', () => {
124124
headers: { Authorization: 'Bearer test-api-key-123' },
125125
})
126126

127-
const response = await _meGet({
127+
const response = await meGet({
128128
...agentRuntimeImpl,
129129
req,
130130
})
@@ -141,7 +141,7 @@ describe('/api/v1/me route', () => {
141141
},
142142
)
143143

144-
const response = await _meGet({
144+
const response = await meGet({
145145
...agentRuntimeImpl,
146146
req,
147147
})
@@ -158,7 +158,7 @@ describe('/api/v1/me route', () => {
158158
},
159159
)
160160

161-
const response = await _meGet({
161+
const response = await meGet({
162162
...agentRuntimeImpl,
163163
req,
164164
})
@@ -179,7 +179,7 @@ describe('/api/v1/me route', () => {
179179
},
180180
)
181181

182-
const response = await _meGet({
182+
const response = await meGet({
183183
...agentRuntimeImpl,
184184
req,
185185
})
@@ -200,7 +200,7 @@ describe('/api/v1/me route', () => {
200200
},
201201
)
202202

203-
const response = await _meGet({
203+
const response = await meGet({
204204
...agentRuntimeImpl,
205205
req,
206206
})
@@ -220,7 +220,7 @@ describe('/api/v1/me route', () => {
220220
},
221221
)
222222

223-
const response = await _meGet({
223+
const response = await meGet({
224224
...agentRuntimeImpl,
225225
req,
226226
})
@@ -237,7 +237,7 @@ describe('/api/v1/me route', () => {
237237
},
238238
)
239239

240-
const response = await _meGet({
240+
const response = await meGet({
241241
...agentRuntimeImpl,
242242
req,
243243
})
@@ -251,7 +251,7 @@ describe('/api/v1/me route', () => {
251251
headers: { Authorization: 'Bearer test-api-key-123' },
252252
})
253253

254-
const response = await _meGet({
254+
const response = await meGet({
255255
...agentRuntimeImpl,
256256
req,
257257
})
@@ -268,7 +268,7 @@ describe('/api/v1/me route', () => {
268268
},
269269
)
270270

271-
const response = await _meGet({
271+
const response = await meGet({
272272
...agentRuntimeImpl,
273273
req,
274274
})
@@ -285,7 +285,7 @@ describe('/api/v1/me route', () => {
285285
},
286286
)
287287

288-
const response = await _meGet({
288+
const response = await meGet({
289289
...agentRuntimeImpl,
290290
req,
291291
})
@@ -306,7 +306,7 @@ describe('/api/v1/me route', () => {
306306
},
307307
)
308308

309-
const response = await _meGet({
309+
const response = await meGet({
310310
...agentRuntimeImpl,
311311
req,
312312
})
@@ -322,7 +322,7 @@ describe('/api/v1/me route', () => {
322322
headers: { Authorization: 'Bearer test-api-key-123' },
323323
})
324324

325-
const response = await _meGet({
325+
const response = await meGet({
326326
...agentRuntimeImpl,
327327
req,
328328
})
@@ -339,7 +339,7 @@ describe('/api/v1/me route', () => {
339339
},
340340
)
341341

342-
const response = await _meGet({
342+
const response = await meGet({
343343
...agentRuntimeImpl,
344344
req,
345345
})
@@ -354,7 +354,7 @@ describe('/api/v1/me route', () => {
354354
},
355355
)
356356

357-
const response = await _meGet({
357+
const response = await meGet({
358358
...agentRuntimeImpl,
359359
req,
360360
})

web/src/app/api/v1/me/impl/_get.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { AnalyticsEvent } from '@codebuff/common/constants/analytics-events'
2+
import { NextResponse } from 'next/server'
3+
4+
import type { TrackEventFn } from '@codebuff/common/types/contracts/analytics'
5+
import type { GetUserInfoFromApiKeyFn } from '@codebuff/common/types/contracts/database'
6+
import type { Logger } from '@codebuff/common/types/contracts/logger'
7+
import type { NextRequest } from 'next/server'
8+
9+
import { VALID_USER_INFO_FIELDS } from '@/db/user'
10+
import { extractApiKeyFromHeader } from '@/util/auth'
11+
12+
type ValidField = (typeof VALID_USER_INFO_FIELDS)[number]
13+
14+
export async function meGet(params: {
15+
req: NextRequest
16+
getUserInfoFromApiKey: GetUserInfoFromApiKeyFn
17+
logger: Logger
18+
trackEvent: TrackEventFn
19+
}) {
20+
const { req, getUserInfoFromApiKey, logger, trackEvent } = params
21+
22+
const apiKey = extractApiKeyFromHeader(req)
23+
24+
if (!apiKey) {
25+
return NextResponse.json(
26+
{ error: 'Missing or invalid Authorization header' },
27+
{ status: 401 },
28+
)
29+
}
30+
31+
// Parse fields from query parameter
32+
const fieldsParam = req.nextUrl.searchParams.get('fields')
33+
let fields: ValidField[]
34+
if (fieldsParam !== null) {
35+
const requestedFields = fieldsParam
36+
.split(',')
37+
.map((f) => f.trim())
38+
.filter((f) => f.length > 0)
39+
40+
// Check if we have any fields after filtering
41+
if (requestedFields.length === 0) {
42+
return NextResponse.json(
43+
{
44+
error: `Invalid fields: empty. Valid fields are: ${VALID_USER_INFO_FIELDS.join(', ')}`,
45+
},
46+
{ status: 400 },
47+
)
48+
}
49+
50+
// Validate that all requested fields are valid
51+
const invalidFields = requestedFields.filter(
52+
(f) => !VALID_USER_INFO_FIELDS.includes(f as ValidField),
53+
)
54+
if (invalidFields.length > 0) {
55+
trackEvent({
56+
event: AnalyticsEvent.ME_VALIDATION_ERROR,
57+
userId: 'unknown',
58+
properties: {
59+
invalidFields,
60+
requestedFields,
61+
},
62+
logger,
63+
})
64+
return NextResponse.json(
65+
{
66+
error: `Invalid fields: ${invalidFields.join(', ')}. Valid fields are: ${VALID_USER_INFO_FIELDS.join(', ')}`,
67+
},
68+
{ status: 400 },
69+
)
70+
}
71+
fields = requestedFields as ValidField[]
72+
} else {
73+
// Default to just 'id'
74+
fields = ['id']
75+
}
76+
77+
// Get user info
78+
const userInfo = await getUserInfoFromApiKey({
79+
apiKey,
80+
fields,
81+
logger,
82+
})
83+
84+
if (!userInfo) {
85+
return NextResponse.json(
86+
{ error: 'Invalid API key or user not found' },
87+
{ status: 404 },
88+
)
89+
}
90+
91+
// Track successful API request
92+
trackEvent({
93+
event: AnalyticsEvent.ME_API_REQUEST,
94+
userId: userInfo.id,
95+
properties: {
96+
requestedFields: fields,
97+
},
98+
logger,
99+
})
100+
101+
return NextResponse.json(userInfo)
102+
}

0 commit comments

Comments
 (0)