diff --git a/packages/core/src/validation.test.ts b/packages/core/src/validation.test.ts index 85fefb47..1bd89c5d 100644 --- a/packages/core/src/validation.test.ts +++ b/packages/core/src/validation.test.ts @@ -152,6 +152,16 @@ describe("builtInValidationFunctions", () => { expect(builtInValidationFunctions.numeric(NaN)).toBe(false); expect(builtInValidationFunctions.numeric(null)).toBe(false); }); + + it("fails for strings with trailing non-numeric characters", () => { + expect(builtInValidationFunctions.numeric("123abc")).toBe(false); + expect(builtInValidationFunctions.numeric("99bottles")).toBe(false); + }); + + it("fails for empty and whitespace-only strings", () => { + expect(builtInValidationFunctions.numeric("")).toBe(false); + expect(builtInValidationFunctions.numeric(" ")).toBe(false); + }); }); describe("url", () => { diff --git a/packages/core/src/validation.ts b/packages/core/src/validation.ts index fd9c20e8..848870a1 100644 --- a/packages/core/src/validation.ts +++ b/packages/core/src/validation.ts @@ -153,7 +153,9 @@ export const builtInValidationFunctions: Record = { */ numeric: (value: unknown) => { if (typeof value === "number") return !isNaN(value); - if (typeof value === "string") return !isNaN(parseFloat(value)); + if (typeof value === "string") { + return value.trim() !== "" && !isNaN(Number(value)); + } return false; },