Skip to content

INTER-2457: [schema review prototype] Event union from openapi#494 - #300

Draft
JuroUhlar wants to merge 3 commits into
mainfrom
INTER-2457/spike-event-union
Draft

JuroUhlar wants to merge 3 commits into
mainfrom
INTER-2457/spike-event-union

Conversation

@JuroUhlar

@JuroUhlar JuroUhlar commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Schema review prototype, do not merge. This is to test the schema Event split (EventDevice | EventEdge) as part of reviewing koala#18895.

INTER-2457 | koala#18895 | schema from openapi#494 @ 78d51f2

Why

This checks that the Node SDK can take the EventDevice | EventEdge union from openapi#494 with only type changes and no runtime change, so users can see from the types that edge events never have identification.

Things to note

  • No runtime change. dist/index.mjs and dist/index.cjs are byte-identical to a main build, and Webhook is a type-only export. 140 tests, lint, all typechecks and test:dts pass.
  • Event keeps source required; the new Webhook makes it optional on device events. The API always returns source. Stored webhook bodies from before source existed don't have it, and koala's resend delivers the stored body as-is. There's no runtime hydration, matching the Slack idea of keeping source optional only on the webhook type.
  • Gap: unsealEventsResponse / parseEventsResponse return the strict Event, but a sealed result saved before source existed has none. Accepted, because sealed results are normally unsealed right away.

Change outline

Public types (src/types.ts, src/index.ts):

- type Event = { event_id, timestamp, source?, identification?, rule_action?, …smart signals }
+ type Event = EventDevice | EventEdge                          // discriminated on `source`
+   EventDevice { event_id, timestamp, source: 'device', identification?, rule_action?, … }
+   EventEdge   { event_id, timestamp, source: 'edge', ip_info, bot_info?, proxy_*?, vpn_*?, environment_id? }
+ type Webhook = (EventDevice with source?: 'device') | EventEdge   // for stored and resent webhook bodies

What users write now:

  const event = await client.getEvent(id, { ruleset_id })
- console.log(event.rule_action?.type)
+ if (event.source !== 'edge') console.log(event.rule_action?.type)

- const event = webhookBody as Event
+ const webhook = webhookBody as Webhook
+ if (webhook.source !== 'edge') console.log(webhook.identification?.visitor_id)

Files:

resources/fingerprint-server-api.yaml   # synced from openapi#494 (v4.yaml)
src/generatedApiTypes.ts                # regenerated: Event union, new EventEdge
src/types.ts, src/index.ts              # Event alias, new Webhook type
readme.md, example/getEvent.mjs         # narrow on `source !== 'edge'`, webhooks cast to Webhook
tests/unit-tests/eventType.spec.ts      # type tests: Event strict, Webhook accepts legacy, narrowing
tests/…/castWebhookEventTest.spec.ts    # old body without `source`: signature valid, casts to Webhook
tests/unit-tests/sealedResults.spec.ts  # existing sealed fixture (no `source`) still unseals

@changeset-bot

changeset-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d780992

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Coverage report

St.❔
Category Percentage Covered / Total
🟢 Statements 98.25% 168/171
🟢 Branches 97.03% 98/101
🟢 Functions 100% 37/37
🟢 Lines 98.21% 165/168

Test suite run success

140 tests passing in 33 suites.

Report generated by 🧪jest coverage report action from d780992

Show full coverage report
St File % Stmts % Branch % Funcs % Lines Uncovered Line #s
🟢 All files 98.24 97.02 100 98.21
🟢  src 98.54 98.76 100 98.51
🔴   ...edApiTypes.ts 0 0 0 0
🔴   index.ts 0 0 0 0
🟢   sealedResults.ts 100 100 100 100
🟢   ...rApiClient.ts 96.15 97.22 100 96.15 360,364
🟢   types.ts 100 100 100 100
🟢   urlUtils.ts 100 100 100 100
🟢   webhook.ts 100 100 100 100
🟢  src/errors 97.05 90 100 96.96
🟢   apiErrors.ts 100 100 100 100
🟢   ...orResponse.ts 100 100 100 100
🟢   toError.ts 87.5 88.88 100 87.5 21
🟢   unsealError.ts 100 50 100 100 14

Events stored before `source` was added (sealed results, webhook bodies) don't have it.
Check `source === 'edge'`; anything else is a device event.
The API always returns `source`, so `Event` keeps it required on device events.
`Webhook` makes it optional: webhook bodies stored before `source` existed don't have it,
and resent webhooks deliver the stored body as-is.
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR doesn't contain any changesets. If there are user-facing changes, don't forget to run:

pnpm exec changeset

to create a changeset.

@JuroUhlar JuroUhlar changed the title [SPIKE] INTER-2457: Event union from openapi#494 [schema review prototype] INTER-2457: Event union from openapi#494 Oct 15, 2026
@JuroUhlar JuroUhlar changed the title [schema review prototype] INTER-2457: Event union from openapi#494 INTER-2457: [schema review prototype] Event union from openapi#494 Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant