Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/signals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The person an event belongs to always comes from the token: Didit overwrites any
| `validation` | The event failed validation; `error.errors` has Didit's per-field details |
| `dropped` | The queue was full and the event was dropped before it was sent |

`submitEvent` itself throws a `DiditEventError` only for a missing token (`invalid_token`), a missing `category` or `actionType` (`validation`), or an environment without `fetch` (`network`).
`submitEvent` itself throws a `DiditEventError` only for a missing token (`invalid_token`), a missing `category` or `actionType` or an unusable `occurredAt` Date (`validation`), or an environment without `fetch` (`network`).

## API

Expand Down
6 changes: 6 additions & 0 deletions packages/signals/src/__tests__/events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,12 @@ describe("submitEvent input", () => {
);
});

it("refuses an unusable occurredAt with a typed validation error", () => {
expect(() =>
submitEvent({ monitoringToken: "valid", event: { category: "auth", actionType: "login", occurredAt: new Date("not a date") } })
).toThrow(expect.objectContaining({ name: "DiditEventError", type: "validation" }));
});

it("returns the integrator's event id, or a new one per event", () => {
const event: DiditEvent = { category: "auth", actionType: "login" };

Expand Down
3 changes: 3 additions & 0 deletions packages/signals/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ export function submitEvent(options: SubmitEventOptions): string {
if (!isRecord(event) || !event.category || typeof event.actionType !== "string" || !event.actionType.trim()) {
throw new DiditEventError("validation", "event.category and event.actionType are required.");
}
if (event.occurredAt instanceof Date && Number.isNaN(event.occurredAt.getTime())) {
throw new DiditEventError("validation", "event.occurredAt must be a valid date.");
}
if (typeof fetch !== "function") {
throw new DiditEventError("network", "fetch is not available in this environment.");
}
Expand Down
2 changes: 1 addition & 1 deletion packages/signals/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export interface DiditEvent {
* same content is a harmless replay; with different content it is rejected.
*/
eventId?: string;
/** When it happened. @default the time submitEvent was called */
/** When it happened. An invalid Date is refused with a "validation" error. @default the time submitEvent was called */
occurredAt?: Date | string;
/** IANA time zone of the end user. @default the browser's time zone */
timeZone?: string;
Expand Down
Loading