Skip to content

Commit 1f3e4bd

Browse files
committed
fix(worker): prettier formatting and downgrade typescript to 5.x
TypeScript 6 breaks npm ci: openapi-typescript@7.13.0 requires peer typescript@"^5.x". Downgrade to ^5.9.3 to restore compatibility. Also apply prettier formatting to reviews.ts, shared.ts, and reviews.test.js which CI's fmt check was rejecting. https://claude.ai/code/session_01VVTCRjdHqcTJCVEjEVQV6C
1 parent bb9e68f commit 1f3e4bd

5 files changed

Lines changed: 188 additions & 41 deletions

File tree

cloudflare-worker/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloudflare-worker/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@cloudflare/vitest-pool-workers": "^0.16.13",
1515
"@cloudflare/workers-types": "^4.20260613.1",
1616
"openapi-typescript": "^7.13.0",
17-
"typescript": "^6.0.3",
17+
"typescript": "^5.9.3",
1818
"vitest": "^4.1.8",
1919
"wrangler": "^4.88.0"
2020
}

cloudflare-worker/reviews.ts

Lines changed: 122 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,32 @@ export async function handleReviews(
186186

187187
switch (request.method) {
188188
case "GET":
189-
return getReview({ db, bucket, festivalId, drinkId, deviceId: deviceResult.deviceId, corsHeaders });
189+
return getReview({
190+
db,
191+
bucket,
192+
festivalId,
193+
drinkId,
194+
deviceId: deviceResult.deviceId,
195+
corsHeaders,
196+
});
190197
case "PATCH":
191-
return upsertReview(request, { db, bucket, festivalId, drinkId, deviceId: deviceResult.deviceId, corsHeaders });
198+
return upsertReview(request, {
199+
db,
200+
bucket,
201+
festivalId,
202+
drinkId,
203+
deviceId: deviceResult.deviceId,
204+
corsHeaders,
205+
});
192206
case "DELETE":
193-
return deleteReview({ db, bucket, festivalId, drinkId, deviceId: deviceResult.deviceId, corsHeaders });
207+
return deleteReview({
208+
db,
209+
bucket,
210+
festivalId,
211+
drinkId,
212+
deviceId: deviceResult.deviceId,
213+
corsHeaders,
214+
});
194215
default:
195216
return methodNotAllowed(corsHeaders);
196217
}
@@ -212,7 +233,14 @@ export async function handleReviews(
212233
if (isReviewList) {
213234
const deviceResult = getDeviceId(request, corsHeaders);
214235
if ("error" in deviceResult) return deviceResult.error;
215-
return listReviews({ db, bucket, festivalId, deviceId: deviceResult.deviceId, url, corsHeaders });
236+
return listReviews({
237+
db,
238+
bucket,
239+
festivalId,
240+
deviceId: deviceResult.deviceId,
241+
url,
242+
corsHeaders,
243+
});
216244
}
217245

218246
// isSummary
@@ -271,7 +299,8 @@ function summaryFields(row: Partial<SummaryRow>): Omit<ReviewSummary, "name"> {
271299
const recommendCount = row.recommend_count ?? 0;
272300
return {
273301
ratingCount,
274-
averageRating: ratingCount && row.avg_rating != null ? round1(row.avg_rating) : 0,
302+
averageRating:
303+
ratingCount && row.avg_rating != null ? round1(row.avg_rating) : 0,
275304
responseCount,
276305
recommendCount,
277306
recommendRate: responseCount ? round2(recommendCount / responseCount) : 0,
@@ -298,7 +327,13 @@ async function getReview(ctx: ReviewCtx): Promise<Response> {
298327
const { db, bucket, festivalId, drinkId, deviceId, corsHeaders } = ctx;
299328
const row = await readRow(db, bucket, festivalId, drinkId, deviceId);
300329
if (!row) {
301-
return errorResponse(404, "NOT_FOUND", "No review found", "NOT_FOUND", corsHeaders);
330+
return errorResponse(
331+
404,
332+
"NOT_FOUND",
333+
"No review found",
334+
"NOT_FOUND",
335+
corsHeaders,
336+
);
302337
}
303338
return jsonResponse<Review>(
304339
serializeReview(reviewName(festivalId, drinkId), row),
@@ -307,17 +342,32 @@ async function getReview(ctx: ReviewCtx): Promise<Response> {
307342
);
308343
}
309344

310-
async function upsertReview(request: Request, ctx: ReviewCtx): Promise<Response> {
345+
async function upsertReview(
346+
request: Request,
347+
ctx: ReviewCtx,
348+
): Promise<Response> {
311349
const { db, bucket, festivalId, drinkId, deviceId, corsHeaders } = ctx;
312350

313351
let body: unknown;
314352
try {
315353
body = await request.json();
316354
} catch {
317-
return errorResponse(400, "INVALID_ARGUMENT", "Invalid JSON body", "INVALID_BODY", corsHeaders);
355+
return errorResponse(
356+
400,
357+
"INVALID_ARGUMENT",
358+
"Invalid JSON body",
359+
"INVALID_BODY",
360+
corsHeaders,
361+
);
318362
}
319363
if (body === null || typeof body !== "object") {
320-
return errorResponse(400, "INVALID_ARGUMENT", "Body must be a JSON object", "INVALID_BODY", corsHeaders);
364+
return errorResponse(
365+
400,
366+
"INVALID_ARGUMENT",
367+
"Body must be a JSON object",
368+
"INVALID_BODY",
369+
corsHeaders,
370+
);
321371
}
322372

323373
// Parse updateMask: comma-separated field names. Absent/empty = all provided fields.
@@ -340,8 +390,10 @@ async function upsertReview(request: Request, ctx: ReviewCtx): Promise<Response>
340390
mask = new Set(fields);
341391
}
342392

343-
const updateStar = mask === null ? "starRating" in patch : mask.has("starRating");
344-
const updateRec = mask === null ? "wouldRecommend" in patch : mask.has("wouldRecommend");
393+
const updateStar =
394+
mask === null ? "starRating" in patch : mask.has("starRating");
395+
const updateRec =
396+
mask === null ? "wouldRecommend" in patch : mask.has("wouldRecommend");
345397

346398
if (!updateStar && !updateRec) {
347399
return errorResponse(
@@ -389,24 +441,44 @@ async function upsertReview(request: Request, ctx: ReviewCtx): Promise<Response>
389441
// Compute the final column values upfront so we can build the response
390442
// without a second DB read — avoids a round trip and the race where a
391443
// concurrent DELETE between write and re-read would make row! throw.
392-
const finalStarRating = updateStar ? (starRating ?? null) : (existing?.star_rating ?? null);
393-
const finalRecommend = updateRec ? (recommend ?? null) : (existing?.recommend ?? null);
444+
const finalStarRating = updateStar
445+
? (starRating ?? null)
446+
: (existing?.star_rating ?? null);
447+
const finalRecommend = updateRec
448+
? (recommend ?? null)
449+
: (existing?.recommend ?? null);
394450

395451
if (existing) {
396452
await db
397453
.prepare(
398454
"UPDATE reviews SET star_rating = ?, recommend = ?, updated_at = ? " +
399455
"WHERE bucket = ? AND festival_id = ? AND drink_id = ? AND device_id = ?",
400456
)
401-
.bind(finalStarRating, finalRecommend, now, bucket, festivalId, drinkId, deviceId)
457+
.bind(
458+
finalStarRating,
459+
finalRecommend,
460+
now,
461+
bucket,
462+
festivalId,
463+
drinkId,
464+
deviceId,
465+
)
402466
.run();
403467
} else {
404468
await db
405469
.prepare(
406470
"INSERT INTO reviews (bucket, festival_id, drink_id, device_id, star_rating, recommend, updated_at) " +
407471
"VALUES (?, ?, ?, ?, ?, ?, ?)",
408472
)
409-
.bind(bucket, festivalId, drinkId, deviceId, finalStarRating, finalRecommend, now)
473+
.bind(
474+
bucket,
475+
festivalId,
476+
drinkId,
477+
deviceId,
478+
finalStarRating,
479+
finalRecommend,
480+
now,
481+
)
410482
.run();
411483
}
412484

@@ -433,7 +505,13 @@ async function deleteReview(ctx: ReviewCtx): Promise<Response> {
433505

434506
const changes = result.meta?.changes ?? 0;
435507
if (!changes) {
436-
return errorResponse(404, "NOT_FOUND", "No review found", "NOT_FOUND", corsHeaders);
508+
return errorResponse(
509+
404,
510+
"NOT_FOUND",
511+
"No review found",
512+
"NOT_FOUND",
513+
corsHeaders,
514+
);
437515
}
438516
return jsonResponse({}, 200, corsHeaders);
439517
}
@@ -443,13 +521,25 @@ async function listReviews(ctx: ListCtx): Promise<Response> {
443521

444522
const sizeResult = resolvePageSize(url.searchParams.get("page_size"));
445523
if ("error" in sizeResult) {
446-
return errorResponse(400, "INVALID_ARGUMENT", "page_size must be >= 0", "INVALID_PAGE_SIZE", corsHeaders);
524+
return errorResponse(
525+
400,
526+
"INVALID_ARGUMENT",
527+
"page_size must be >= 0",
528+
"INVALID_PAGE_SIZE",
529+
corsHeaders,
530+
);
447531
}
448532
const pageSize = sizeResult.value;
449533

450534
const cursor = decodePageToken(url.searchParams.get("page_token"));
451535
if (cursor === undefined) {
452-
return errorResponse(400, "INVALID_ARGUMENT", "Invalid page_token", "INVALID_PAGE_TOKEN", corsHeaders);
536+
return errorResponse(
537+
400,
538+
"INVALID_ARGUMENT",
539+
"Invalid page_token",
540+
"INVALID_PAGE_TOKEN",
541+
corsHeaders,
542+
);
453543
}
454544

455545
const where = ["bucket = ?", "festival_id = ?", "device_id = ?"];
@@ -510,13 +600,25 @@ async function listReviewSummaries(ctx: ListSummaryCtx): Promise<Response> {
510600

511601
const sizeResult = resolvePageSize(url.searchParams.get("page_size"));
512602
if ("error" in sizeResult) {
513-
return errorResponse(400, "INVALID_ARGUMENT", "page_size must be >= 0", "INVALID_PAGE_SIZE", corsHeaders);
603+
return errorResponse(
604+
400,
605+
"INVALID_ARGUMENT",
606+
"page_size must be >= 0",
607+
"INVALID_PAGE_SIZE",
608+
corsHeaders,
609+
);
514610
}
515611
const pageSize = sizeResult.value;
516612

517613
const cursor = decodePageToken(url.searchParams.get("page_token"));
518614
if (cursor === undefined) {
519-
return errorResponse(400, "INVALID_ARGUMENT", "Invalid page_token", "INVALID_PAGE_TOKEN", corsHeaders);
615+
return errorResponse(
616+
400,
617+
"INVALID_ARGUMENT",
618+
"Invalid page_token",
619+
"INVALID_PAGE_TOKEN",
620+
corsHeaders,
621+
);
520622
}
521623

522624
const where = ["bucket = ?", "festival_id = ?"];

cloudflare-worker/shared.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export function encodePageToken(drinkId: string): string {
9595
}
9696

9797
/** Decode a page token back to its cursor, or null if absent. */
98-
export function decodePageToken(token: string | null): string | null | undefined {
98+
export function decodePageToken(
99+
token: string | null,
100+
): string | null | undefined {
99101
if (!token) return null;
100102
try {
101103
const b64 = token.replace(/-/g, "+").replace(/_/g, "/");
@@ -106,7 +108,9 @@ export function decodePageToken(token: string | null): string | null | undefined
106108
}
107109

108110
/** Resolve an effective page size, or { error } for a bad value. */
109-
export function resolvePageSize(raw: string | null): { value: number } | { error: true } {
111+
export function resolvePageSize(
112+
raw: string | null,
113+
): { value: number } | { error: true } {
110114
if (raw == null || raw === "") return { value: DEFAULT_PAGE_SIZE };
111115
const n = Number(raw);
112116
if (!Number.isInteger(n) || n < 0) return { error: true };

0 commit comments

Comments
 (0)