From eb04bd83ed90fe0768d7259e41e7ee1b470afe2f Mon Sep 17 00:00:00 2001 From: crazywriter1 Date: Tue, 22 Sep 2026 00:04:07 +0300 Subject: [PATCH] fix(ack-pay): reject unsafe integer amounts in valibot schema Align the payment option amount number arm with Number.isSafeInteger so valibot matches zod; keep the string arm for larger amounts. --- .changeset/payment-option-safe-integer-amount.md | 5 +++++ packages/ack-pay/src/schemas/payment-option.test.ts | 7 +++++++ packages/ack-pay/src/schemas/valibot.ts | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/payment-option-safe-integer-amount.md diff --git a/.changeset/payment-option-safe-integer-amount.md b/.changeset/payment-option-safe-integer-amount.md new file mode 100644 index 00000000..0069538a --- /dev/null +++ b/.changeset/payment-option-safe-integer-amount.md @@ -0,0 +1,5 @@ +--- +"@agentcommercekit/ack-pay": patch +--- + +Reject unsafe integer numbers on the payment option amount number arm so valibot matches zod (and Number.isSafeInteger), keeping the string arm for amounts larger than the safe integer range. diff --git a/packages/ack-pay/src/schemas/payment-option.test.ts b/packages/ack-pay/src/schemas/payment-option.test.ts index 166b4496..f6f016d5 100644 --- a/packages/ack-pay/src/schemas/payment-option.test.ts +++ b/packages/ack-pay/src/schemas/payment-option.test.ts @@ -34,4 +34,11 @@ describe("paymentOptionSchema amount", () => { expect(acceptsAmount(amount)).toEqual({ valibot: false, zod: false }) }, ) + + it.each([Number.MAX_SAFE_INTEGER + 1, 1e21])( + "rejects an unsafe integer number amount %s", + (amount) => { + expect(acceptsAmount(amount)).toEqual({ valibot: false, zod: false }) + }, + ) }) diff --git a/packages/ack-pay/src/schemas/valibot.ts b/packages/ack-pay/src/schemas/valibot.ts index 75fc9807..8de72391 100644 --- a/packages/ack-pay/src/schemas/valibot.ts +++ b/packages/ack-pay/src/schemas/valibot.ts @@ -14,7 +14,8 @@ const timestampSchema = v.pipe( export const paymentOptionSchema = v.object({ id: v.string(), amount: v.union([ - v.pipe(v.number(), v.integer(), v.gtValue(0)), + // Unsafe integers are not exact; use the string arm for large amounts. + v.pipe(v.number(), v.safeInteger(), v.gtValue(0)), positiveIntegerString, ]), decimals: v.pipe(v.number(), v.integer(), v.toMinValue(0)),