diff --git a/packages/core/src/routes/admin-api.ts b/packages/core/src/routes/admin-api.ts index 49e592c..c0ce682 100644 --- a/packages/core/src/routes/admin-api.ts +++ b/packages/core/src/routes/admin-api.ts @@ -709,11 +709,13 @@ async function deleteShippingZone( if (!current) return json({ error: "Zone not found" }, 404); // Zones own methods; fail fast if any method still references this zone // rather than leaving orphaned methods in the store. + // Use fetch+filter instead of .where — EmDash's where clause building + // breaks on Postgres (syntax error near "="). const methods = await storeOf(ctx, "shipping_methods").query({ - where: { zoneId: id }, - limit: 1, + limit: 500, }); - if (methods.items.length > 0) { + const zoneHasMethods = methods.items.some((r) => (r.data as ShippingMethod).zoneId === id); + if (zoneHasMethods) { return json( { error: diff --git a/packages/core/src/routes/cart.ts b/packages/core/src/routes/cart.ts index 359f3a8..8b678ff 100644 --- a/packages/core/src/routes/cart.ts +++ b/packages/core/src/routes/cart.ts @@ -612,29 +612,29 @@ export const cartRoutes = { }; } ).shipping_zones; - const methodsStore = ( - ctx.storage as unknown as { - shipping_methods: { - query(opts: { - where: Record; - limit: number; - }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; - }; - } - ).shipping_methods; - - const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ - ...r.data, - id: r.id, - })); - const zone = pickZone(cart.shippingAddress, zones); - if (!zone) return jsonResponse({ options: [] }, withSessionCookie(setCookie)); - const methods = ( - await methodsStore.query({ - where: { zoneId: zone.id, enabled: 1 }, - limit: 50, - }) - ).items.map((r) => ({ ...r.data, id: r.id })); + const methodsStore = ( + ctx.storage as unknown as { + shipping_methods: { + query(opts: { + where?: Record; + limit: number; + }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; + }; + } + ).shipping_methods; + + const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ + ...r.data, + id: r.id, + })); + const zone = pickZone(cart.shippingAddress, zones); + if (!zone) return jsonResponse({ options: [] }, withSessionCookie(setCookie)); + // Fetch all methods and filter in JS — EmDash's .where builds SQLite-style + // SQL that breaks on Postgres (syntax error near "="). This fetch+filter + // approach works across both databases. + const methods = (await methodsStore.query({ limit: 200 })).items + .map((r) => ({ ...r.data, id: r.id })) + .filter((m) => m.zoneId === zone.id && (m.enabled === true || (m.enabled as unknown) === 1)); const options = calculateRates({ items: cart.items, @@ -669,31 +669,31 @@ export const cartRoutes = { }; } ).shipping_zones; - const methodsStore = ( - ctx.storage as unknown as { - shipping_methods: { - get(id: string): Promise; - query(opts: { - where: Record; - limit: number; - }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; - }; - } - ).shipping_methods; - const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ - ...r.data, - id: r.id, - })); - const zone = pickZone(cart.shippingAddress, zones); - if (!zone) { - return errorResponse("No shipping zone matches the address", 409, setCookie); + const methodsStore = ( + ctx.storage as unknown as { + shipping_methods: { + get(id: string): Promise; + query(opts: { + where?: Record; + limit: number; + }): Promise<{ items: Array<{ id: string; data: ShippingMethod }> }>; + }; } - const methods = ( - await methodsStore.query({ - where: { zoneId: zone.id, enabled: 1 }, - limit: 50, - }) - ).items.map((r) => ({ ...r.data, id: r.id })); + ).shipping_methods; + const zones = (await zonesStore.query({ limit: 200 })).items.map((r) => ({ + ...r.data, + id: r.id, + })); + const zone = pickZone(cart.shippingAddress, zones); + if (!zone) { + return errorResponse("No shipping zone matches the address", 409, setCookie); + } + // Fetch all methods and filter in JS — EmDash's .where builds SQLite-style + // SQL that breaks on Postgres (syntax error near "="). This fetch+filter + // approach works across both databases. + const methods = (await methodsStore.query({ limit: 200 })).items + .map((r) => ({ ...r.data, id: r.id })) + .filter((m) => m.zoneId === zone.id && (m.enabled === true || (m.enabled as unknown) === 1)); const options = calculateRates({ items: cart.items, currency: cart.currency,