Skip to content

Commit 45c7318

Browse files
fix(core): harden RunEvent schema and acknowledge contract change risk
1 parent fd2f823 commit 45c7318

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

packages/core/src/v3/schemas/api-type.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ describe("RunEvent Schema", () => {
204204
expect(result.startTime.toISOString()).toBe("2024-03-14T00:00:00.000Z");
205205
});
206206

207+
it("fails on invalid startTime", () => {
208+
const event = { ...validEvent, startTime: "not-a-date" };
209+
const result = RunEvent.safeParse(event);
210+
expect(result.success).toBe(false);
211+
});
212+
207213
it("allows optional/null parentId", () => {
208214
const eventWithoutParent = { ...validEvent };
209215
delete (eventWithoutParent as any).parentId;

packages/core/src/v3/schemas/api.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,23 +1646,25 @@ export type TaskEventLevel = z.infer<typeof TaskEventLevel>;
16461646
export const NanosecondTimestampSchema = z
16471647
.union([z.string(), z.number(), z.bigint()])
16481648
.transform((val) => {
1649-
// If it's already a Date, return it (though union doesn't include it)
1650-
if (typeof val === "object" && val instanceof Date) return val;
1651-
16521649
const str = val.toString();
16531650

1651+
let date: Date;
1652+
16541653
// 19 digits is nanoseconds (e.g., 1710374400000000000)
16551654
if (str.length === 19) {
1656-
return new Date(Number(BigInt(str) / 1000000n));
1655+
date = new Date(Number(BigInt(str) / 1000000n));
1656+
} else if (str.length === 13) {
1657+
// 13 digits is milliseconds
1658+
date = new Date(Number(str));
1659+
} else {
1660+
// Default to standard date coercion
1661+
date = new Date(str);
16571662
}
16581663

1659-
// 13 digits is milliseconds
1660-
if (str.length === 13) {
1661-
return new Date(Number(val));
1662-
}
1663-
1664-
// Default to standard date coercion
1665-
return new Date(val as any);
1664+
return date;
1665+
})
1666+
.refine((d) => !isNaN(d.getTime()), {
1667+
message: "Invalid timestamp",
16661668
});
16671669

16681670
export const RunEvent = z.object({

0 commit comments

Comments
 (0)