rescript-eventor
v0.0.4
Published
Typed Eventor REST API client for ReScript
Maintainers
Readme
rescript-eventor
Typed Eventor REST API client for ReScript. Returns either native ReScript record types or parsed IOF XML 3.0 types via rescript-iof-xml.
References:
- API schema: eventor.orientering.se/api/schema
- OpenAPI spec: orienteering-oss/eventor-api-openapi-spec
Installation
rescript-iof-xml is a required peer-style runtime dependency and is installed alongside:
npm install --save-exact rescript-eventor rescript-iof-xmlAdd both to rescript.json:
{
"dependencies": ["rescript-eventor", "rescript-iof-xml"]
}Usage
let config = Eventor.makeConfig(~apiKey="your-api-key", ())
let result = await Eventor.getEvents(
config,
{
...Eventor.eventsParams,
fromDate: Some(Date.makeWithYMD(~year=2024, ~month=0, ~date=1)),
toDate: Some(Date.makeWithYMD(~year=2024, ~month=11, ~date=31)),
classificationIds: Some([EventClassification.National, EventClassification.Regional]),
},
)
switch result {
| Ok(events) => Console.log(events)
| Error(msg) => Console.error(msg)
}Eventor.eventsParams and Eventor.entriesParams are pre-built records with every field set to its zero value (None / false), so you only need to spell out the fields you care about.
API
All endpoint functions return promise<result<'a, string>>.
The Error payload is either an HTTP <status>: <statusText> string or a network error message.
| Function | Returns | Notes |
| --- | --- | --- |
| Eventor.makeConfig(~apiKey, ~baseUrl=?, ()) | config | baseUrl defaults to the Norwegian Eventor. |
| Eventor.getEvents(config, params) | array<NativeEvent.t> | See eventsParams below. |
| Eventor.getEvent(config, ~eventId, ()) | NativeEvent.t | |
| Eventor.getEntries(config, params) | array<NativeEntry.t> | See entriesParams below. |
| Eventor.getCompetitors(config, ~organisationId, ()) | array<NativeCompetitor.t> | |
| Eventor.getOrganisations(config, ~includeProperties=?, ()) | array<NativeOrganisation.t> | |
| Eventor.getEventClasses(config, ~eventId, ()) | array<NativeEventClass.t> | |
| Eventor.getPersons(config, ~organisationId, ~includeContactDetails=?, ~includePersonProperties=?, ~includePersonIdentifiers=?, ()) | array<NativePerson.t> | |
| Eventor.getStarts(config, ~eventId, ()) | IofXml.StartList.t | Parsed IOF XML 3.0. |
| Eventor.getResults(config, ~eventId, ~includeSplitTimes=?, ()) | IofXml.ResultList.t | Parsed IOF XML 3.0. |
eventsParams
| Field | Type | Description |
| --- | --- | --- |
| fromDate / toDate | option<Date.t> | Date range filter (formatted as local time). |
| fromModifyDate / toModifyDate | option<Date.t> | Modification date range filter. |
| eventIds | option<array<string>> | Filter by specific event IDs. |
| organisationIds | option<array<string>> | Filter by organiser organisation IDs. |
| classificationIds | option<array<EventClassification.t>> | Filter by classification level. |
| includeEntryBreaks | bool | Include entry deadline info. |
| includeAttributes | bool | Include event attributes. |
| parentIds | option<array<string>> | Filter by parent event IDs. |
entriesParams
| Field | Type | Description |
| --- | --- | --- |
| organisationIds | option<array<string>> | Filter by organisation IDs. |
| eventIds | option<array<string>> | Filter by event IDs. |
| eventClassIds | option<array<string>> | Filter by event class IDs. |
| fromEventDate / toEventDate | option<Date.t> | Event date range filter. |
| fromEntryDate / toEntryDate | option<Date.t> | Entry creation date filter. |
| fromModifyDate / toModifyDate | option<Date.t> | Modification date filter. |
| includePersonElement | bool | Embed the full <Person> element under each <Competitor> (name, birth date, sex, nationality). When set, NativeEntry.t.person is populated. |
| includeOrganisationElement | bool | Embed the full <Organisation> element under each <Competitor> (name, short name, country). When set, NativeEntry.t.organisation is populated. |
| includeEventElement | bool | Embed the full <Event> element under each <Entry> (name, dates, classification, races). When set, NativeEntry.t.event is populated. |
EventClassification.t
A variant type representing event classification levels:
type t = Championship | National | Regional | Nearby | ClubUse in queries:
classificationIds: Some([EventClassification.National, EventClassification.Regional])Also returned in parsed events via NativeEvent.t.classification.
IOF XML 3.0 variants
Eventor also exposes IOF XML 3.0 variants of several endpoints.
Eventor-specific data is preserved in <Extensions> elements under the namespace http://eventor.orientering.se/iofxmlextensions (e.g. EventRaceId, StartListExists, Discipline, LightCondition), so these endpoints are non-lossy.
Eventor.getEventsIofXml(config, params)/getEventsIofXmlRaw—/events/iofxmlEventor.getEventIofXml(config, ~eventId, ())/getEventIofXmlRaw—/event/iofxml/{id}Eventor.getOrganisationsIofXmlRaw(config, ~includeProperties=?, ())—/organisations/iofxmlEventor.getStartsIofXml(config, ~eventId, ~eventRaceId=?, ())/getStartsIofXmlRaw—/starts/event/iofxmlEventor.getResultsIofXml(config, ~eventId, ~eventRaceId=?, ~includeSplitTimes=?, ~totalResult=?, ())/getResultsIofXmlRaw—/results/event/iofxml
The typed variants return the IOF-standard fields only and do not carry the Eventor extensions.
To read the extensions, take a *Raw variant's XML and pass each <Event>/<Race> element to IofXml.EventorExtensions.fromElement (added in rescript-iof-xml v0.0.4).
Base URLs
- Norway (default):
https://eventor.orientering.no/api - Sweden:
https://eventor.orientering.se/api - Australia:
https://eventor.orienteering.asn.au/api - International:
https://eventor.orienteering.sport/api
Pass via ~baseUrl to makeConfig.
Not yet implemented
The following Eventor API endpoints are not yet wrapped by this library:
| Endpoint | Description |
| --- | --- |
| GET /authenticatePerson | Authenticate a person by username/password. |
| GET /activities | List activities for an organisation in a time period. |
| GET /activity | Get a single activity. |
| GET /competitorcount | Count entries matching filters. |
| GET /events/documents | List documents attached to events. |
| GET /entryfees/events/{eventId} | List entry fees for an event. |
| GET /externalLoginUrl | Generate a single-use redirect URL into Eventor. |
| GET /competitor/{competitorId} | Get a single competitor by internal ID. |
| PUT /competitor | Update a competitor's settings (card, default class). |
Additionally, some existing endpoints expose parameters not yet supported:
| Endpoint | Missing parameters |
| --- | --- |
| GET /entries | includeEntryFees |
| GET /results/event | top |
| GET /eventclasses | includeEntryFees |
| GET /starts/person | Entire endpoint (person-specific starts) |
| GET /starts/organisation | Entire endpoint (organisation-specific starts) |
| GET /results/person | Entire endpoint (person-specific results) |
| GET /results/organisation | Entire endpoint (organisation-specific results) |
CORS limitation
The Eventor API does not provide CORS headers, so direct browser requests will be blocked. This library works as intended in:
- Server-side environments (Node.js, Deno, Bun)
- Desktop apps (Tauri, Electron)
- Browser via a CORS proxy you control
Development
npm install
npm run build # one-shot compile
npm run dev # watch mode
npm test # runtime tests against fixtures in example-responses/
npm run format # rescript formatLicense
MIT — see LICENSE.
