Skip to content

Commit 8f4cf67

Browse files
authored
Merge pull request #16 from ScrawnDotDev/refactor(streamEvent)
Refactor(stream event)
2 parents 045f46a + 52e0735 commit 8f4cf67

48 files changed

Lines changed: 444 additions & 450 deletions

Some content is hidden

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

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# dependencies (bun install)
22
node_modules
3+
nul
34

45
# output
56
out

.prettierrc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": false,
7+
"quoteProps": "as-needed",
8+
"jsxSingleQuote": false,
9+
"trailingComma": "es5",
10+
"bracketSpacing": true,
11+
"bracketSameLine": false,
12+
"arrowParens": "always",
13+
"proseWrap": "preserve",
14+
"htmlWhitespaceSensitivity": "css",
15+
"endOfLine": "lf",
16+
"embeddedLanguageFormatting": "auto"
17+
}

proto/event/v1/event.proto

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@ message RegisterEventResponse {
4343
string random = 1;
4444
}
4545

46-
message StreamEventRequest {
47-
EventType type = 1;
48-
string userId = 2;
49-
oneof data {
50-
SDKCall sdkCall = 3;
51-
AITokenUsage aiTokenUsage = 4;
52-
}
53-
}
46+
message StreamEventRequest {
47+
EventType type = 1;
48+
string userId = 2;
49+
oneof data {
50+
AITokenUsage aiTokenUsage = 4;
51+
}
52+
}
5453

5554
message AITokenUsage {
5655
string model = 1;

src/__tests__/unit/http/createdCheckout.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ describe("handleLemonSqueezyWebhook", () => {
166166
"MISSING_WEBHOOK_SECRET",
167167
"Webhook secret not configured",
168168
undefined,
169-
{},
169+
{}
170170
);
171171
});
172172

@@ -194,7 +194,7 @@ describe("handleLemonSqueezyWebhook", () => {
194194
"INVALID_SIGNATURE",
195195
"Invalid webhook signature",
196196
undefined,
197-
{},
197+
{}
198198
);
199199
});
200200

@@ -225,7 +225,7 @@ describe("handleLemonSqueezyWebhook", () => {
225225
"INVALID_JSON",
226226
"Invalid JSON payload",
227227
expect.any(Error),
228-
{},
228+
{}
229229
);
230230
});
231231

@@ -255,7 +255,7 @@ describe("handleLemonSqueezyWebhook", () => {
255255
expect((res as any).statusCode).toBe(200);
256256
expect((res as any).body).toContain("Event ignored");
257257
expect(
258-
storageModule.StorageAdapterFactory.getStorageAdapter,
258+
storageModule.StorageAdapterFactory.getStorageAdapter
259259
).not.toHaveBeenCalled();
260260
expect(paymentConstructorCalls.length).toBe(0);
261261
});
@@ -295,7 +295,7 @@ describe("handleLemonSqueezyWebhook", () => {
295295
"MISSING_USER_ID",
296296
"Missing user_id in webhook payload",
297297
undefined,
298-
{},
298+
{}
299299
);
300300
});
301301

@@ -336,7 +336,7 @@ describe("handleLemonSqueezyWebhook", () => {
336336
"MISSING_API_KEY_ID",
337337
"Missing apiKeyId in webhook payload",
338338
undefined,
339-
{ userId: "user-123" },
339+
{ userId: "user-123" }
340340
);
341341
});
342342

@@ -346,7 +346,7 @@ describe("handleLemonSqueezyWebhook", () => {
346346

347347
const adapterAddMock = vi.fn().mockResolvedValue(undefined);
348348
vi.mocked(
349-
storageModule.StorageAdapterFactory.getStorageAdapter,
349+
storageModule.StorageAdapterFactory.getStorageAdapter
350350
).mockResolvedValue({
351351
add: adapterAddMock,
352352
} as any);
@@ -394,10 +394,10 @@ describe("handleLemonSqueezyWebhook", () => {
394394
});
395395

396396
expect(
397-
storageModule.StorageAdapterFactory.getStorageAdapter,
397+
storageModule.StorageAdapterFactory.getStorageAdapter
398398
).toHaveBeenCalledTimes(1);
399399
const adapterCall = vi.mocked(
400-
storageModule.StorageAdapterFactory.getStorageAdapter,
400+
storageModule.StorageAdapterFactory.getStorageAdapter
401401
).mock.calls[0];
402402
expect(adapterCall[1]).toBe("api-key-456");
403403

@@ -414,7 +414,7 @@ describe("handleLemonSqueezyWebhook", () => {
414414
const dbError = new Error("DB error");
415415
const adapterAddMock = vi.fn().mockRejectedValue(dbError);
416416
vi.mocked(
417-
storageModule.StorageAdapterFactory.getStorageAdapter,
417+
storageModule.StorageAdapterFactory.getStorageAdapter
418418
).mockResolvedValue({
419419
add: adapterAddMock,
420420
} as any);
@@ -464,7 +464,7 @@ describe("handleLemonSqueezyWebhook", () => {
464464
"DATABASE_ERROR",
465465
"Database error while storing payment",
466466
dbError,
467-
{ userId: "user-123", apiKeyId: "api-key-456" },
467+
{ userId: "user-123", apiKeyId: "api-key-456" }
468468
);
469469
});
470470

@@ -492,7 +492,7 @@ describe("handleLemonSqueezyWebhook", () => {
492492
"UNEXPECTED_ERROR",
493493
"Unexpected error in webhook handler",
494494
expect.any(Error),
495-
{},
495+
{}
496496
);
497497
});
498498
});

src/__tests__/unit/interceptors/auth.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,24 @@ describe("authInterceptor", () => {
5959

6060
// Empty Authorization should be rejected
6161
await expect(interceptor(next)(makeReq() as any)).rejects.toThrow(
62-
"Missing Authorization header",
62+
"Missing Authorization header"
6363
);
6464

6565
// Authorization that does not start with Bearer should be rejected
6666
await expect(
67-
interceptor(next)(makeReq("Token abcdef") as any),
67+
interceptor(next)(makeReq("Token abcdef") as any)
6868
).rejects.toThrow(
69-
'Authorization header must be in format "Bearer <api_key>"',
69+
'Authorization header must be in format "Bearer <api_key>"'
7070
);
7171

7272
// Authorization with invalid API key format (not starting with scrn_) should be rejected
7373
await expect(
74-
interceptor(next)(makeReq("Bearer " + "a".repeat(37)) as any),
74+
interceptor(next)(makeReq("Bearer " + "a".repeat(37)) as any)
7575
).rejects.toThrow("Invalid API key: Invalid API key format");
7676

7777
// Authorization with invalid API key format (wrong length) should be rejected
7878
await expect(
79-
interceptor(next)(makeReq("Bearer scrn_short") as any),
79+
interceptor(next)(makeReq("Bearer scrn_short") as any)
8080
).rejects.toThrow("Invalid API key: Invalid API key format");
8181
});
8282

src/__tests__/unit/storage/postgres/addAiTokenUsage.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
148148

149149
// Find GPT-4 aggregated record
150150
const gpt4Record = aiTokenUsageInsertCall[0].find(
151-
(r: any) => r.model === "gpt-4",
151+
(r: any) => r.model === "gpt-4"
152152
);
153153
expect(gpt4Record).toEqual({
154154
id: expect.any(String),
@@ -161,7 +161,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
161161

162162
// Find Claude aggregated record
163163
const claudeRecord = aiTokenUsageInsertCall[0].find(
164-
(r: any) => r.model === "claude-3-opus",
164+
(r: any) => r.model === "claude-3-opus"
165165
);
166166
expect(claudeRecord).toEqual({
167167
id: expect.any(String),
@@ -313,12 +313,12 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
313313

314314
// Verify aggregation: should have 2 gpt-4 records and 1 claude record
315315
const gpt4Records = aiTokenUsageInsertCall[0].filter(
316-
(r: any) => r.model === "gpt-4",
316+
(r: any) => r.model === "gpt-4"
317317
);
318318
expect(gpt4Records).toHaveLength(2);
319319

320320
const claudeRecords = aiTokenUsageInsertCall[0].filter(
321-
(r: any) => r.model === "claude-3-sonnet",
321+
(r: any) => r.model === "claude-3-sonnet"
322322
);
323323
expect(claudeRecords).toHaveLength(1);
324324

@@ -419,7 +419,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
419419
{ id: "user-1" },
420420
{ id: "user-2" },
421421
{ id: "user-3" },
422-
]),
422+
])
423423
);
424424
});
425425

@@ -491,7 +491,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
491491
mockTransaction.returning.mockResolvedValueOnce([]);
492492

493493
await expect(
494-
handleAddAiTokenUsage(events, "api-key-123"),
494+
handleAddAiTokenUsage(events, "api-key-123")
495495
).rejects.toThrow("Event insert returned no IDs");
496496
});
497497

@@ -527,7 +527,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
527527
mockTransaction.returning.mockResolvedValueOnce([{ id: "event-1" }]);
528528

529529
await expect(
530-
handleAddAiTokenUsage(events, "api-key-123"),
530+
handleAddAiTokenUsage(events, "api-key-123")
531531
).rejects.toThrow("Expected 2 event IDs but got 1");
532532
});
533533
});
@@ -552,7 +552,7 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
552552
mockDb.transaction.mockRejectedValueOnce(new Error("Transaction failed"));
553553

554554
await expect(
555-
handleAddAiTokenUsage(events, "api-key-123"),
555+
handleAddAiTokenUsage(events, "api-key-123")
556556
).rejects.toThrow("Transaction failed");
557557
});
558558

@@ -573,11 +573,11 @@ describe("handleAddAiTokenUsage - Aggregation and Batch Insert", () => {
573573
];
574574

575575
mockTransaction.returning.mockRejectedValueOnce(
576-
new Error("Insert failed"),
576+
new Error("Insert failed")
577577
);
578578

579579
await expect(
580-
handleAddAiTokenUsage(events, "api-key-123"),
580+
handleAddAiTokenUsage(events, "api-key-123")
581581
).rejects.toThrow();
582582
});
583583
});

src/__tests__/unit/storage/postgres/addKey.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe("PostgresAdapter - addKey handler", () => {
9292
const adapter = new PostgresAdapter(invalidEvent as any);
9393
const serialized = invalidEvent.serialize() as any;
9494
await expect(adapter.add(serialized)).rejects.toThrow(
95-
"Missing data field",
95+
"Missing data field"
9696
);
9797
});
9898

@@ -119,7 +119,7 @@ describe("PostgresAdapter - addKey handler", () => {
119119
const adapter = new PostgresAdapter(invalidEvent as any);
120120
const serialized = invalidEvent.serialize() as any;
121121
await expect(adapter.add(serialized)).rejects.toThrow(
122-
"Invalid or missing 'name'",
122+
"Invalid or missing 'name'"
123123
);
124124
});
125125

@@ -146,7 +146,7 @@ describe("PostgresAdapter - addKey handler", () => {
146146
const adapter = new PostgresAdapter(invalidEvent as any);
147147
const serialized = invalidEvent.serialize() as any;
148148
await expect(adapter.add(serialized)).rejects.toThrow(
149-
"Invalid or missing 'key'",
149+
"Invalid or missing 'key'"
150150
);
151151
});
152152

@@ -175,7 +175,7 @@ describe("PostgresAdapter - addKey handler", () => {
175175
const adapter = new PostgresAdapter(invalidEvent as any);
176176
const serialized = invalidEvent.serialize() as any;
177177
await expect(adapter.add(serialized)).rejects.toThrow(
178-
"API key cannot be empty",
178+
"API key cannot be empty"
179179
);
180180
});
181181

@@ -202,7 +202,7 @@ describe("PostgresAdapter - addKey handler", () => {
202202
const adapter = new PostgresAdapter(invalidEvent as any);
203203
const serialized = invalidEvent.serialize() as any;
204204
await expect(adapter.add(serialized)).rejects.toThrow(
205-
"Timestamp is undefined or empty",
205+
"Timestamp is undefined or empty"
206206
);
207207
});
208208
});
@@ -216,7 +216,7 @@ describe("PostgresAdapter - addKey handler", () => {
216216
});
217217

218218
mockTransaction.returning.mockRejectedValueOnce(
219-
new Error("Database connection error"),
219+
new Error("Database connection error")
220220
);
221221

222222
const adapter = new PostgresAdapter(addKeyEvent);
@@ -236,7 +236,7 @@ describe("PostgresAdapter - addKey handler", () => {
236236
const adapter = new PostgresAdapter(addKeyEvent);
237237
const serialized = addKeyEvent.serialize();
238238
await expect(adapter.add(serialized)).rejects.toThrow(
239-
"API key insert returned no record",
239+
"API key insert returned no record"
240240
);
241241
});
242242

@@ -252,7 +252,7 @@ describe("PostgresAdapter - addKey handler", () => {
252252
const adapter = new PostgresAdapter(addKeyEvent);
253253
const serialized = addKeyEvent.serialize();
254254
await expect(adapter.add(serialized)).rejects.toThrow(
255-
"API key insert returned object without id field",
255+
"API key insert returned object without id field"
256256
);
257257
});
258258
});

src/__tests__/unit/storage/postgres/addPayment.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ describe("PostgresAdapter - addPayment handler", () => {
163163
const adapter = new PostgresAdapter(invalidEvent as any);
164164
const serialized = invalidEvent.serialize() as any;
165165
await expect(adapter.add(serialized)).rejects.toThrow(
166-
"Timestamp is undefined or empty",
166+
"Timestamp is undefined or empty"
167167
);
168168
});
169169
});
@@ -176,7 +176,7 @@ describe("PostgresAdapter - addPayment handler", () => {
176176

177177
mockTransaction.returning.mockResolvedValueOnce([]);
178178
mockTransaction.returning.mockRejectedValueOnce(
179-
new Error("Event insert failed"),
179+
new Error("Event insert failed")
180180
);
181181

182182
const adapter = new PostgresAdapter(paymentEvent);
@@ -195,7 +195,7 @@ describe("PostgresAdapter - addPayment handler", () => {
195195
const adapter = new PostgresAdapter(paymentEvent);
196196
const serialized = paymentEvent.serialize();
197197
await expect(adapter.add(serialized)).rejects.toThrow(
198-
"Event insert returned no ID",
198+
"Event insert returned no ID"
199199
);
200200
});
201201
});

0 commit comments

Comments
 (0)