@v5x/events 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Beanarchy Studios
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # @v5x/events
2
+
3
+ Strictly typed TypeScript client for the [VEX Events API v2](https://events.vex.com/api/v2).
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ bun add @v5x/events
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Create a personal access token in your VEX Events account, then pass it to the
14
+ client. The package works in browsers, Bun, and modern Node.js runtimes with
15
+ `fetch`.
16
+
17
+ ```ts
18
+ import { VexEventsClient } from "@v5x/events";
19
+
20
+ const vex = new VexEventsClient({
21
+ token: process.env.VEX_EVENTS_TOKEN!,
22
+ });
23
+
24
+ const teams = await vex.teams.list({
25
+ numbers: ["123A"],
26
+ registered: true,
27
+ perPage: 100,
28
+ });
29
+
30
+ for (const team of teams.data ?? []) {
31
+ console.log(team.number, team.team_name);
32
+ }
33
+ ```
34
+
35
+ Resources mirror the API:
36
+
37
+ - `vex.events`: events, event teams, skills, awards, division matches, and rankings
38
+ - `vex.teams`: teams and their events, matches, rankings, skills, and awards
39
+ - `vex.programs`: programs
40
+ - `vex.seasons`: seasons and season events
41
+
42
+ All filters, response models, pagination metadata, and API error bodies are
43
+ exported as TypeScript types. Array filters use normal arrays; the client
44
+ encodes them using the API's repeated `field[]` query parameters. `Date` values
45
+ are converted to RFC 3339 strings automatically.
46
+
47
+ ```ts
48
+ import { VexEventsApiError } from "@v5x/events";
49
+
50
+ try {
51
+ const event = await vex.events.get(123);
52
+ console.log(event.name);
53
+ } catch (error) {
54
+ if (error instanceof VexEventsApiError) {
55
+ console.error(error.status, error.body);
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## Build
61
+
62
+ ```sh
63
+ bun run build
64
+ ```
@@ -0,0 +1,55 @@
1
+ import type { Award, Event, ListDivisionMatchesOptions, ListDivisionRankingsOptions, ListEventAwardsOptions, ListEventsOptions, ListEventSkillsOptions, ListEventTeamsOptions, ListProgramsOptions, ListSeasonEventsOptions, ListSeasonsOptions, ListTeamAwardsOptions, ListTeamEventsOptions, ListTeamMatchesOptions, ListTeamRankingsOptions, ListTeamsOptions, ListTeamSkillsOptions, Match, PaginatedResponse, Program, Ranking, Season, Skill, Team } from "./types.js";
2
+ export interface RequestOptions {
3
+ signal?: AbortSignal;
4
+ }
5
+ export type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
6
+ export interface VexEventsClientOptions {
7
+ /** Personal access token sent using bearer authentication. */
8
+ token: string;
9
+ /** Override for tests, proxies, or compatible API deployments. */
10
+ baseUrl?: string;
11
+ /** Fetch implementation to use. Defaults to globalThis.fetch. */
12
+ fetch?: Fetch;
13
+ /** Additional headers included with every request. */
14
+ headers?: Readonly<Record<string, string>>;
15
+ }
16
+ export interface EventsResource {
17
+ list(options?: ListEventsOptions, request?: RequestOptions): Promise<PaginatedResponse<Event>>;
18
+ get(id: number, request?: RequestOptions): Promise<Event>;
19
+ teams(id: number, options?: ListEventTeamsOptions, request?: RequestOptions): Promise<PaginatedResponse<Team>>;
20
+ skills(id: number, options?: ListEventSkillsOptions, request?: RequestOptions): Promise<PaginatedResponse<Skill>>;
21
+ awards(id: number, options?: ListEventAwardsOptions, request?: RequestOptions): Promise<PaginatedResponse<Award>>;
22
+ matches(id: number, division: number, options?: ListDivisionMatchesOptions, request?: RequestOptions): Promise<PaginatedResponse<Match>>;
23
+ finalistRankings(id: number, division: number, options?: ListDivisionRankingsOptions, request?: RequestOptions): Promise<PaginatedResponse<Ranking>>;
24
+ rankings(id: number, division: number, options?: ListDivisionRankingsOptions, request?: RequestOptions): Promise<PaginatedResponse<Ranking>>;
25
+ }
26
+ export interface TeamsResource {
27
+ list(options?: ListTeamsOptions, request?: RequestOptions): Promise<PaginatedResponse<Team>>;
28
+ get(id: number, request?: RequestOptions): Promise<Team>;
29
+ events(id: number, options?: ListTeamEventsOptions, request?: RequestOptions): Promise<PaginatedResponse<Event>>;
30
+ matches(id: number, options?: ListTeamMatchesOptions, request?: RequestOptions): Promise<PaginatedResponse<Match>>;
31
+ rankings(id: number, options?: ListTeamRankingsOptions, request?: RequestOptions): Promise<PaginatedResponse<Ranking>>;
32
+ skills(id: number, options?: ListTeamSkillsOptions, request?: RequestOptions): Promise<PaginatedResponse<Skill>>;
33
+ awards(id: number, options?: ListTeamAwardsOptions, request?: RequestOptions): Promise<PaginatedResponse<Award>>;
34
+ }
35
+ export interface ProgramsResource {
36
+ list(options?: ListProgramsOptions, request?: RequestOptions): Promise<PaginatedResponse<Program>>;
37
+ get(id: number, request?: RequestOptions): Promise<Program>;
38
+ }
39
+ export interface SeasonsResource {
40
+ list(options?: ListSeasonsOptions, request?: RequestOptions): Promise<PaginatedResponse<Season>>;
41
+ get(id: number, request?: RequestOptions): Promise<Season>;
42
+ events(id: number, options?: ListSeasonEventsOptions, request?: RequestOptions): Promise<PaginatedResponse<Event>>;
43
+ }
44
+ export declare class VexEventsClient {
45
+ readonly events: EventsResource;
46
+ readonly teams: TeamsResource;
47
+ readonly programs: ProgramsResource;
48
+ readonly seasons: SeasonsResource;
49
+ private readonly token;
50
+ private readonly baseUrl;
51
+ private readonly fetch;
52
+ private readonly headers;
53
+ constructor(options: VexEventsClientOptions);
54
+ private request;
55
+ }
@@ -0,0 +1,15 @@
1
+ import type { ApiErrorBody } from "./types.js";
2
+ export declare class VexEventsApiError extends Error {
3
+ readonly status: number;
4
+ readonly statusText: string;
5
+ readonly body: ApiErrorBody | string | null;
6
+ readonly url: string;
7
+ readonly name = "VexEventsApiError";
8
+ constructor(status: number, statusText: string, body: ApiErrorBody | string | null, url: string);
9
+ }
10
+ export declare class VexEventsResponseError extends Error {
11
+ readonly url: string;
12
+ readonly cause?: unknown;
13
+ readonly name = "VexEventsResponseError";
14
+ constructor(message: string, url: string, cause?: unknown);
15
+ }
@@ -0,0 +1,10 @@
1
+ import * as client from "./client.js";
2
+ import * as errors from "./errors.js";
3
+ export declare const VexEventsClient: typeof client.VexEventsClient;
4
+ export declare const VexEventsApiError: typeof errors.VexEventsApiError;
5
+ export declare const VexEventsResponseError: typeof errors.VexEventsResponseError;
6
+ export type VexEventsClient = client.VexEventsClient;
7
+ export type VexEventsApiError = errors.VexEventsApiError;
8
+ export type VexEventsResponseError = errors.VexEventsResponseError;
9
+ export type { EventsResource, Fetch, ProgramsResource, RequestOptions, SeasonsResource, TeamsResource, VexEventsClientOptions, } from "./client.js";
10
+ export type * from "./types.js";
package/dist/index.js ADDED
@@ -0,0 +1,300 @@
1
+ // src/errors.ts
2
+ class VexEventsApiError extends Error {
3
+ status;
4
+ statusText;
5
+ body;
6
+ url;
7
+ name = "VexEventsApiError";
8
+ constructor(status, statusText, body, url) {
9
+ const apiMessage = typeof body === "object" && body !== null ? body.message : undefined;
10
+ super(apiMessage ?? `VEX Events API request failed: ${status} ${statusText}`);
11
+ this.status = status;
12
+ this.statusText = statusText;
13
+ this.body = body;
14
+ this.url = url;
15
+ }
16
+ }
17
+
18
+ class VexEventsResponseError extends Error {
19
+ url;
20
+ cause;
21
+ name = "VexEventsResponseError";
22
+ constructor(message, url, cause) {
23
+ super(message, cause === undefined ? undefined : { cause });
24
+ this.url = url;
25
+ this.cause = cause;
26
+ }
27
+ }
28
+
29
+ // src/client.ts
30
+ var DEFAULT_BASE_URL = "https://events.vex.com/api/v2";
31
+ function paginationEntries(options) {
32
+ return [
33
+ ["page", options.page],
34
+ ["per_page", options.perPage]
35
+ ];
36
+ }
37
+ function serializeDate(value) {
38
+ return value instanceof Date ? value.toISOString() : value;
39
+ }
40
+ function appendQuery(url, entries) {
41
+ for (const [name, value] of entries) {
42
+ if (value === undefined)
43
+ continue;
44
+ if (Array.isArray(value)) {
45
+ for (const item of value)
46
+ url.searchParams.append(name, String(item));
47
+ continue;
48
+ }
49
+ url.searchParams.set(name, value instanceof Date ? serializeDate(value) : String(value));
50
+ }
51
+ }
52
+ function isApiErrorBody(value) {
53
+ if (typeof value !== "object" || value === null)
54
+ return false;
55
+ const body = value;
56
+ return (body.code === undefined || typeof body.code === "number") && (body.message === undefined || typeof body.message === "string");
57
+ }
58
+ function normalizeErrorBody(value) {
59
+ if (isApiErrorBody(value))
60
+ return value;
61
+ return typeof value === "string" ? value : null;
62
+ }
63
+ function isJsonContentType(contentType) {
64
+ const mediaType = contentType.split(";", 1)[0]?.trim().toLowerCase();
65
+ return mediaType === "application/json" || mediaType?.endsWith("+json") === true;
66
+ }
67
+ function isObjectResponse(value) {
68
+ return typeof value === "object" && value !== null && !Array.isArray(value);
69
+ }
70
+ function isPaginatedResponse(value) {
71
+ if (!isObjectResponse(value))
72
+ return false;
73
+ return (value.data === undefined || Array.isArray(value.data)) && (value.meta === undefined || isObjectResponse(value.meta));
74
+ }
75
+ function hasResponseShape(value, responseShape) {
76
+ return responseShape === "paginated" ? isPaginatedResponse(value) : isObjectResponse(value);
77
+ }
78
+
79
+ class VexEventsClient {
80
+ events;
81
+ teams;
82
+ programs;
83
+ seasons;
84
+ token;
85
+ baseUrl;
86
+ fetch;
87
+ headers;
88
+ constructor(options) {
89
+ if (options.token.trim() === "") {
90
+ throw new TypeError("token must not be empty");
91
+ }
92
+ this.token = options.token;
93
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
94
+ this.fetch = options.fetch ?? globalThis.fetch;
95
+ this.headers = options.headers ?? {};
96
+ this.events = {
97
+ list: (options2 = {}, request) => this.request("/events", eventEntries(options2), request, "paginated"),
98
+ get: (id, request) => this.request(`/events/${id}`, [], request, "object"),
99
+ teams: (id, options2 = {}, request) => this.request(`/events/${id}/teams`, eventTeamEntries(options2), request, "paginated"),
100
+ skills: (id, options2 = {}, request) => this.request(`/events/${id}/skills`, eventSkillEntries(options2), request, "paginated"),
101
+ awards: (id, options2 = {}, request) => this.request(`/events/${id}/awards`, eventAwardEntries(options2), request, "paginated"),
102
+ matches: (id, division, options2 = {}, request) => this.request(`/events/${id}/divisions/${division}/matches`, divisionMatchEntries(options2), request, "paginated"),
103
+ finalistRankings: (id, division, options2 = {}, request) => this.request(`/events/${id}/divisions/${division}/finalistRankings`, divisionRankingEntries(options2), request, "paginated"),
104
+ rankings: (id, division, options2 = {}, request) => this.request(`/events/${id}/divisions/${division}/rankings`, divisionRankingEntries(options2), request, "paginated")
105
+ };
106
+ this.teams = {
107
+ list: (options2 = {}, request) => this.request("/teams", teamEntries(options2), request, "paginated"),
108
+ get: (id, request) => this.request(`/teams/${id}`, [], request, "object"),
109
+ events: (id, options2 = {}, request) => this.request(`/teams/${id}/events`, teamEventEntries(options2), request, "paginated"),
110
+ matches: (id, options2 = {}, request) => this.request(`/teams/${id}/matches`, teamMatchEntries(options2), request, "paginated"),
111
+ rankings: (id, options2 = {}, request) => this.request(`/teams/${id}/rankings`, teamRankingEntries(options2), request, "paginated"),
112
+ skills: (id, options2 = {}, request) => this.request(`/teams/${id}/skills`, teamSkillEntries(options2), request, "paginated"),
113
+ awards: (id, options2 = {}, request) => this.request(`/teams/${id}/awards`, teamAwardEntries(options2), request, "paginated")
114
+ };
115
+ this.programs = {
116
+ list: (options2 = {}, request) => this.request("/programs", [...paginationEntries(options2), ["id[]", options2.ids]], request, "paginated"),
117
+ get: (id, request) => this.request(`/programs/${id}`, [], request, "object")
118
+ };
119
+ this.seasons = {
120
+ list: (options2 = {}, request) => this.request("/seasons", seasonEntries(options2), request, "paginated"),
121
+ get: (id, request) => this.request(`/seasons/${id}`, [], request, "object"),
122
+ events: (id, options2 = {}, request) => this.request(`/seasons/${id}/events`, seasonEventEntries(options2), request, "paginated")
123
+ };
124
+ }
125
+ async request(path, query, options, responseShape) {
126
+ const url = new URL(`${this.baseUrl}${path}`);
127
+ appendQuery(url, query);
128
+ const response = await this.fetch(url, {
129
+ headers: {
130
+ ...this.headers,
131
+ Accept: "application/json",
132
+ Authorization: `Bearer ${this.token}`
133
+ },
134
+ signal: options?.signal
135
+ });
136
+ const contentType = response.headers.get("content-type") ?? "";
137
+ const isJson = isJsonContentType(contentType);
138
+ let body;
139
+ try {
140
+ body = isJson ? await response.json() : await response.text();
141
+ } catch (error) {
142
+ throw new VexEventsResponseError("VEX Events API returned an unreadable response", url.toString(), error);
143
+ }
144
+ if (!response.ok) {
145
+ throw new VexEventsApiError(response.status, response.statusText, normalizeErrorBody(body), url.toString());
146
+ }
147
+ if (!isJson) {
148
+ throw new VexEventsResponseError("VEX Events API returned a non-JSON response", url.toString());
149
+ }
150
+ if (!hasResponseShape(body, responseShape)) {
151
+ throw new VexEventsResponseError(`VEX Events API returned an invalid response for ${path}`, url.toString());
152
+ }
153
+ return body;
154
+ }
155
+ }
156
+ function eventEntries(options) {
157
+ return [
158
+ ...paginationEntries(options),
159
+ ["id[]", options.ids],
160
+ ["sku[]", options.skus],
161
+ ["team[]", options.teams],
162
+ ["season[]", options.seasons],
163
+ ["start", options.start],
164
+ ["end", options.end],
165
+ ["region", options.region],
166
+ ["level[]", options.levels],
167
+ ["myEvents", options.myEvents],
168
+ ["eventTypes[]", options.eventTypes]
169
+ ];
170
+ }
171
+ function eventTeamEntries(options) {
172
+ return [
173
+ ...paginationEntries(options),
174
+ ["number[]", options.numbers],
175
+ ["registered", options.registered],
176
+ ["grade[]", options.grades],
177
+ ["country[]", options.countries],
178
+ ["myTeams", options.myTeams]
179
+ ];
180
+ }
181
+ function eventSkillEntries(options) {
182
+ return [
183
+ ...paginationEntries(options),
184
+ ["team[]", options.teams],
185
+ ["type[]", options.types]
186
+ ];
187
+ }
188
+ function eventAwardEntries(options) {
189
+ return [
190
+ ...paginationEntries(options),
191
+ ["team[]", options.teams],
192
+ ["winner[]", options.winners]
193
+ ];
194
+ }
195
+ function divisionMatchEntries(options) {
196
+ return [
197
+ ...paginationEntries(options),
198
+ ["team[]", options.teams],
199
+ ["round[]", options.rounds],
200
+ ["instance[]", options.instances],
201
+ ["matchnum[]", options.matchNumbers]
202
+ ];
203
+ }
204
+ function divisionRankingEntries(options) {
205
+ return [
206
+ ...paginationEntries(options),
207
+ ["team[]", options.teams],
208
+ ["rank[]", options.ranks]
209
+ ];
210
+ }
211
+ function teamEntries(options) {
212
+ return [
213
+ ...paginationEntries(options),
214
+ ["id[]", options.ids],
215
+ ["number[]", options.numbers],
216
+ ["event[]", options.events],
217
+ ["registered", options.registered],
218
+ ["program[]", options.programs],
219
+ ["grade[]", options.grades],
220
+ ["country[]", options.countries],
221
+ ["myTeams", options.myTeams]
222
+ ];
223
+ }
224
+ function teamEventEntries(options) {
225
+ return [
226
+ ...paginationEntries(options),
227
+ ["sku[]", options.skus],
228
+ ["season[]", options.seasons],
229
+ ["start", options.start],
230
+ ["end", options.end],
231
+ ["level[]", options.levels]
232
+ ];
233
+ }
234
+ function teamMatchEntries(options) {
235
+ return [
236
+ ...paginationEntries(options),
237
+ ["event[]", options.events],
238
+ ["season[]", options.seasons],
239
+ ["round[]", options.rounds],
240
+ ["instance[]", options.instances],
241
+ ["matchnum[]", options.matchNumbers]
242
+ ];
243
+ }
244
+ function teamRankingEntries(options) {
245
+ return [
246
+ ...paginationEntries(options),
247
+ ["event[]", options.events],
248
+ ["rank[]", options.ranks],
249
+ ["season[]", options.seasons]
250
+ ];
251
+ }
252
+ function teamSkillEntries(options) {
253
+ return [
254
+ ...paginationEntries(options),
255
+ ["event[]", options.events],
256
+ ["type[]", options.types],
257
+ ["season[]", options.seasons]
258
+ ];
259
+ }
260
+ function teamAwardEntries(options) {
261
+ return [
262
+ ...paginationEntries(options),
263
+ ["event[]", options.events],
264
+ ["season[]", options.seasons]
265
+ ];
266
+ }
267
+ function seasonEntries(options) {
268
+ return [
269
+ ...paginationEntries(options),
270
+ ["id[]", options.ids],
271
+ ["program[]", options.programs],
272
+ ["team[]", options.teams],
273
+ ["start", options.start],
274
+ ["end", options.end],
275
+ ["active", options.active]
276
+ ];
277
+ }
278
+ function seasonEventEntries(options) {
279
+ return [
280
+ ...paginationEntries(options),
281
+ ["sku[]", options.skus],
282
+ ["team[]", options.teams],
283
+ ["start", options.start],
284
+ ["end", options.end],
285
+ ["level[]", options.levels]
286
+ ];
287
+ }
288
+
289
+ // src/index.ts
290
+ var VexEventsClient2 = VexEventsClient;
291
+ var VexEventsApiError2 = VexEventsApiError;
292
+ var VexEventsResponseError2 = VexEventsResponseError;
293
+ export {
294
+ VexEventsResponseError2 as VexEventsResponseError,
295
+ VexEventsClient2 as VexEventsClient,
296
+ VexEventsApiError2 as VexEventsApiError
297
+ };
298
+
299
+ //# debugId=794DCB1DDF226CF164756E2164756E21
300
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/errors.ts", "../src/client.ts", "../src/index.ts"],
4
+ "sourcesContent": [
5
+ "import type { ApiErrorBody } from \"./types.js\";\n\nexport class VexEventsApiError extends Error {\n override readonly name = \"VexEventsApiError\";\n\n constructor(\n readonly status: number,\n readonly statusText: string,\n readonly body: ApiErrorBody | string | null,\n readonly url: string,\n ) {\n const apiMessage =\n typeof body === \"object\" && body !== null ? body.message : undefined;\n super(\n apiMessage ?? `VEX Events API request failed: ${status} ${statusText}`,\n );\n }\n}\n\nexport class VexEventsResponseError extends Error {\n override readonly name = \"VexEventsResponseError\";\n\n constructor(\n message: string,\n readonly url: string,\n override readonly cause?: unknown,\n ) {\n super(message, cause === undefined ? undefined : { cause });\n }\n}\n",
6
+ "import { VexEventsApiError, VexEventsResponseError } from \"./errors.js\";\nimport type {\n ApiErrorBody,\n Award,\n DateInput,\n Event,\n ListDivisionMatchesOptions,\n ListDivisionRankingsOptions,\n ListEventAwardsOptions,\n ListEventsOptions,\n ListEventSkillsOptions,\n ListEventTeamsOptions,\n ListProgramsOptions,\n ListSeasonEventsOptions,\n ListSeasonsOptions,\n ListTeamAwardsOptions,\n ListTeamEventsOptions,\n ListTeamMatchesOptions,\n ListTeamRankingsOptions,\n ListTeamsOptions,\n ListTeamSkillsOptions,\n Match,\n PaginatedResponse,\n PaginationOptions,\n Program,\n Ranking,\n Season,\n Skill,\n Team,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://events.vex.com/api/v2\";\n\ntype QueryValue = DateInput | boolean | number | readonly (number | string)[];\ntype QueryEntry = readonly [name: string, value: QueryValue | undefined];\ntype ResponseShape = \"object\" | \"paginated\";\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n}\n\nexport type Fetch = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport interface VexEventsClientOptions {\n /** Personal access token sent using bearer authentication. */\n token: string;\n /** Override for tests, proxies, or compatible API deployments. */\n baseUrl?: string;\n /** Fetch implementation to use. Defaults to globalThis.fetch. */\n fetch?: Fetch;\n /** Additional headers included with every request. */\n headers?: Readonly<Record<string, string>>;\n}\n\nexport interface EventsResource {\n list(\n options?: ListEventsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Event>>;\n get(id: number, request?: RequestOptions): Promise<Event>;\n teams(\n id: number,\n options?: ListEventTeamsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Team>>;\n skills(\n id: number,\n options?: ListEventSkillsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Skill>>;\n awards(\n id: number,\n options?: ListEventAwardsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Award>>;\n matches(\n id: number,\n division: number,\n options?: ListDivisionMatchesOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Match>>;\n finalistRankings(\n id: number,\n division: number,\n options?: ListDivisionRankingsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Ranking>>;\n rankings(\n id: number,\n division: number,\n options?: ListDivisionRankingsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Ranking>>;\n}\n\nexport interface TeamsResource {\n list(\n options?: ListTeamsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Team>>;\n get(id: number, request?: RequestOptions): Promise<Team>;\n events(\n id: number,\n options?: ListTeamEventsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Event>>;\n matches(\n id: number,\n options?: ListTeamMatchesOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Match>>;\n rankings(\n id: number,\n options?: ListTeamRankingsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Ranking>>;\n skills(\n id: number,\n options?: ListTeamSkillsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Skill>>;\n awards(\n id: number,\n options?: ListTeamAwardsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Award>>;\n}\n\nexport interface ProgramsResource {\n list(\n options?: ListProgramsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Program>>;\n get(id: number, request?: RequestOptions): Promise<Program>;\n}\n\nexport interface SeasonsResource {\n list(\n options?: ListSeasonsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Season>>;\n get(id: number, request?: RequestOptions): Promise<Season>;\n events(\n id: number,\n options?: ListSeasonEventsOptions,\n request?: RequestOptions,\n ): Promise<PaginatedResponse<Event>>;\n}\n\nfunction paginationEntries(options: PaginationOptions): QueryEntry[] {\n return [\n [\"page\", options.page],\n [\"per_page\", options.perPage],\n ];\n}\n\nfunction serializeDate(value: DateInput): string {\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction appendQuery(url: URL, entries: readonly QueryEntry[]): void {\n for (const [name, value] of entries) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const item of value) url.searchParams.append(name, String(item));\n continue;\n }\n url.searchParams.set(\n name,\n value instanceof Date ? serializeDate(value) : String(value),\n );\n }\n}\n\nfunction isApiErrorBody(value: unknown): value is ApiErrorBody {\n if (typeof value !== \"object\" || value === null) return false;\n const body = value as Record<string, unknown>;\n return (\n (body.code === undefined || typeof body.code === \"number\") &&\n (body.message === undefined || typeof body.message === \"string\")\n );\n}\n\nfunction normalizeErrorBody(value: unknown): ApiErrorBody | string | null {\n if (isApiErrorBody(value)) return value;\n return typeof value === \"string\" ? value : null;\n}\n\nfunction isJsonContentType(contentType: string): boolean {\n const mediaType = contentType.split(\";\", 1)[0]?.trim().toLowerCase();\n return (\n mediaType === \"application/json\" || mediaType?.endsWith(\"+json\") === true\n );\n}\n\nfunction isObjectResponse(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPaginatedResponse(value: unknown): boolean {\n if (!isObjectResponse(value)) return false;\n return (\n (value.data === undefined || Array.isArray(value.data)) &&\n (value.meta === undefined || isObjectResponse(value.meta))\n );\n}\n\nfunction hasResponseShape<T>(\n value: unknown,\n responseShape: ResponseShape,\n): value is T {\n return responseShape === \"paginated\"\n ? isPaginatedResponse(value)\n : isObjectResponse(value);\n}\n\nexport class VexEventsClient {\n readonly events: EventsResource;\n readonly teams: TeamsResource;\n readonly programs: ProgramsResource;\n readonly seasons: SeasonsResource;\n\n private readonly token: string;\n private readonly baseUrl: string;\n private readonly fetch: Fetch;\n private readonly headers: Readonly<Record<string, string>>;\n\n constructor(options: VexEventsClientOptions) {\n if (options.token.trim() === \"\") {\n throw new TypeError(\"token must not be empty\");\n }\n\n this.token = options.token;\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.fetch = options.fetch ?? globalThis.fetch;\n this.headers = options.headers ?? {};\n\n this.events = {\n list: (options = {}, request) =>\n this.request(\"/events\", eventEntries(options), request, \"paginated\"),\n get: (id, request) =>\n this.request(`/events/${id}`, [], request, \"object\"),\n teams: (id, options = {}, request) =>\n this.request(\n `/events/${id}/teams`,\n eventTeamEntries(options),\n request,\n \"paginated\",\n ),\n skills: (id, options = {}, request) =>\n this.request(\n `/events/${id}/skills`,\n eventSkillEntries(options),\n request,\n \"paginated\",\n ),\n awards: (id, options = {}, request) =>\n this.request(\n `/events/${id}/awards`,\n eventAwardEntries(options),\n request,\n \"paginated\",\n ),\n matches: (id, division, options = {}, request) =>\n this.request(\n `/events/${id}/divisions/${division}/matches`,\n divisionMatchEntries(options),\n request,\n \"paginated\",\n ),\n finalistRankings: (id, division, options = {}, request) =>\n this.request(\n `/events/${id}/divisions/${division}/finalistRankings`,\n divisionRankingEntries(options),\n request,\n \"paginated\",\n ),\n rankings: (id, division, options = {}, request) =>\n this.request(\n `/events/${id}/divisions/${division}/rankings`,\n divisionRankingEntries(options),\n request,\n \"paginated\",\n ),\n };\n\n this.teams = {\n list: (options = {}, request) =>\n this.request(\"/teams\", teamEntries(options), request, \"paginated\"),\n get: (id, request) => this.request(`/teams/${id}`, [], request, \"object\"),\n events: (id, options = {}, request) =>\n this.request(\n `/teams/${id}/events`,\n teamEventEntries(options),\n request,\n \"paginated\",\n ),\n matches: (id, options = {}, request) =>\n this.request(\n `/teams/${id}/matches`,\n teamMatchEntries(options),\n request,\n \"paginated\",\n ),\n rankings: (id, options = {}, request) =>\n this.request(\n `/teams/${id}/rankings`,\n teamRankingEntries(options),\n request,\n \"paginated\",\n ),\n skills: (id, options = {}, request) =>\n this.request(\n `/teams/${id}/skills`,\n teamSkillEntries(options),\n request,\n \"paginated\",\n ),\n awards: (id, options = {}, request) =>\n this.request(\n `/teams/${id}/awards`,\n teamAwardEntries(options),\n request,\n \"paginated\",\n ),\n };\n\n this.programs = {\n list: (options = {}, request) =>\n this.request(\n \"/programs\",\n [...paginationEntries(options), [\"id[]\", options.ids]],\n request,\n \"paginated\",\n ),\n get: (id, request) =>\n this.request(`/programs/${id}`, [], request, \"object\"),\n };\n\n this.seasons = {\n list: (options = {}, request) =>\n this.request(\"/seasons\", seasonEntries(options), request, \"paginated\"),\n get: (id, request) =>\n this.request(`/seasons/${id}`, [], request, \"object\"),\n events: (id, options = {}, request) =>\n this.request(\n `/seasons/${id}/events`,\n seasonEventEntries(options),\n request,\n \"paginated\",\n ),\n };\n }\n\n private async request<T>(\n path: string,\n query: readonly QueryEntry[],\n options: RequestOptions | undefined,\n responseShape: ResponseShape,\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n appendQuery(url, query);\n\n const response = await this.fetch(url, {\n headers: {\n ...this.headers,\n Accept: \"application/json\",\n Authorization: `Bearer ${this.token}`,\n },\n signal: options?.signal,\n });\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = isJsonContentType(contentType);\n let body: unknown;\n try {\n body = isJson ? await response.json() : await response.text();\n } catch (error) {\n throw new VexEventsResponseError(\n \"VEX Events API returned an unreadable response\",\n url.toString(),\n error,\n );\n }\n\n if (!response.ok) {\n throw new VexEventsApiError(\n response.status,\n response.statusText,\n normalizeErrorBody(body),\n url.toString(),\n );\n }\n\n if (!isJson) {\n throw new VexEventsResponseError(\n \"VEX Events API returned a non-JSON response\",\n url.toString(),\n );\n }\n\n if (!hasResponseShape<T>(body, responseShape)) {\n throw new VexEventsResponseError(\n `VEX Events API returned an invalid response for ${path}`,\n url.toString(),\n );\n }\n\n return body;\n }\n}\n\nfunction eventEntries(options: ListEventsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"id[]\", options.ids],\n [\"sku[]\", options.skus],\n [\"team[]\", options.teams],\n [\"season[]\", options.seasons],\n [\"start\", options.start],\n [\"end\", options.end],\n [\"region\", options.region],\n [\"level[]\", options.levels],\n [\"myEvents\", options.myEvents],\n [\"eventTypes[]\", options.eventTypes],\n ];\n}\n\nfunction eventTeamEntries(options: ListEventTeamsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"number[]\", options.numbers],\n [\"registered\", options.registered],\n [\"grade[]\", options.grades],\n [\"country[]\", options.countries],\n [\"myTeams\", options.myTeams],\n ];\n}\n\nfunction eventSkillEntries(options: ListEventSkillsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"team[]\", options.teams],\n [\"type[]\", options.types],\n ];\n}\n\nfunction eventAwardEntries(options: ListEventAwardsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"team[]\", options.teams],\n [\"winner[]\", options.winners],\n ];\n}\n\nfunction divisionMatchEntries(\n options: ListDivisionMatchesOptions,\n): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"team[]\", options.teams],\n [\"round[]\", options.rounds],\n [\"instance[]\", options.instances],\n [\"matchnum[]\", options.matchNumbers],\n ];\n}\n\nfunction divisionRankingEntries(\n options: ListDivisionRankingsOptions,\n): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"team[]\", options.teams],\n [\"rank[]\", options.ranks],\n ];\n}\n\nfunction teamEntries(options: ListTeamsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"id[]\", options.ids],\n [\"number[]\", options.numbers],\n [\"event[]\", options.events],\n [\"registered\", options.registered],\n [\"program[]\", options.programs],\n [\"grade[]\", options.grades],\n [\"country[]\", options.countries],\n [\"myTeams\", options.myTeams],\n ];\n}\n\nfunction teamEventEntries(options: ListTeamEventsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"sku[]\", options.skus],\n [\"season[]\", options.seasons],\n [\"start\", options.start],\n [\"end\", options.end],\n [\"level[]\", options.levels],\n ];\n}\n\nfunction teamMatchEntries(options: ListTeamMatchesOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"event[]\", options.events],\n [\"season[]\", options.seasons],\n [\"round[]\", options.rounds],\n [\"instance[]\", options.instances],\n [\"matchnum[]\", options.matchNumbers],\n ];\n}\n\nfunction teamRankingEntries(options: ListTeamRankingsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"event[]\", options.events],\n [\"rank[]\", options.ranks],\n [\"season[]\", options.seasons],\n ];\n}\n\nfunction teamSkillEntries(options: ListTeamSkillsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"event[]\", options.events],\n [\"type[]\", options.types],\n [\"season[]\", options.seasons],\n ];\n}\n\nfunction teamAwardEntries(options: ListTeamAwardsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"event[]\", options.events],\n [\"season[]\", options.seasons],\n ];\n}\n\nfunction seasonEntries(options: ListSeasonsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"id[]\", options.ids],\n [\"program[]\", options.programs],\n [\"team[]\", options.teams],\n [\"start\", options.start],\n [\"end\", options.end],\n [\"active\", options.active],\n ];\n}\n\nfunction seasonEventEntries(options: ListSeasonEventsOptions): QueryEntry[] {\n return [\n ...paginationEntries(options),\n [\"sku[]\", options.skus],\n [\"team[]\", options.teams],\n [\"start\", options.start],\n [\"end\", options.end],\n [\"level[]\", options.levels],\n ];\n}\n",
7
+ "import * as client from \"./client.js\";\nimport * as errors from \"./errors.js\";\n\nexport const VexEventsClient = client.VexEventsClient;\nexport const VexEventsApiError = errors.VexEventsApiError;\nexport const VexEventsResponseError = errors.VexEventsResponseError;\nexport type VexEventsClient = client.VexEventsClient;\nexport type VexEventsApiError = errors.VexEventsApiError;\nexport type VexEventsResponseError = errors.VexEventsResponseError;\nexport type {\n EventsResource,\n Fetch,\n ProgramsResource,\n RequestOptions,\n SeasonsResource,\n TeamsResource,\n VexEventsClientOptions,\n} from \"./client.js\";\nexport type * from \"./types.js\";\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "794DCB1DDF226CF164756E2164756E21",
11
+ "names": []
12
+ }
@@ -0,0 +1,261 @@
1
+ /** A value accepted by date filters. Strings must use RFC 3339 format. */
2
+ export type DateInput = Date | string;
3
+ export type EventType = "tournament" | "league" | "workshop" | "virtual";
4
+ export type EventLevel = "World" | "National" | "Regional" | "State" | "Signature" | "Other";
5
+ /** Event levels accepted by the API's event-list filters. */
6
+ export type EventLevelFilter = Exclude<EventLevel, "Regional">;
7
+ export type Grade = "College" | "High School" | "Middle School" | "Elementary School";
8
+ export type SkillType = "driver" | "programming" | "package_delivery_time";
9
+ /** Skill types accepted by the API's skills-list filters. */
10
+ export type SkillTypeFilter = Exclude<SkillType, "package_delivery_time">;
11
+ export interface Coordinates {
12
+ lat?: number;
13
+ lon?: number;
14
+ }
15
+ export interface Location {
16
+ venue?: string;
17
+ address_1?: string;
18
+ address_2?: string;
19
+ city?: string;
20
+ region?: string;
21
+ postcode?: string;
22
+ country?: string;
23
+ coordinates?: Coordinates;
24
+ }
25
+ export type NamedLocations = Record<string, Location>;
26
+ export interface IdInfo {
27
+ id: number;
28
+ name: string;
29
+ code?: string | null;
30
+ }
31
+ export interface Division {
32
+ id?: number;
33
+ name?: string;
34
+ order?: number;
35
+ }
36
+ export interface Event {
37
+ id: number;
38
+ sku: string;
39
+ name: string;
40
+ start?: string;
41
+ end?: string;
42
+ season: IdInfo;
43
+ program: IdInfo;
44
+ location: Location;
45
+ locations?: NamedLocations[];
46
+ divisions?: Division[];
47
+ level?: EventLevel;
48
+ ongoing?: boolean;
49
+ awards_finalized?: boolean;
50
+ event_type?: EventType;
51
+ }
52
+ export interface Program {
53
+ id?: number;
54
+ abbr?: string;
55
+ name?: string;
56
+ }
57
+ export interface Team {
58
+ id: number;
59
+ number: string;
60
+ team_name?: string;
61
+ robot_name?: string;
62
+ organization?: string;
63
+ location?: Location;
64
+ registered?: boolean;
65
+ program: IdInfo;
66
+ grade?: Grade;
67
+ }
68
+ export interface AllianceTeam {
69
+ team?: IdInfo;
70
+ sitting?: boolean;
71
+ }
72
+ export interface Alliance {
73
+ color: "red" | "blue";
74
+ score: number;
75
+ teams: AllianceTeam[];
76
+ }
77
+ export interface Match {
78
+ id: number;
79
+ event: IdInfo;
80
+ division: IdInfo;
81
+ round: number;
82
+ instance: number;
83
+ matchnum: number;
84
+ scheduled?: string;
85
+ started?: string;
86
+ field?: string;
87
+ scored: boolean;
88
+ name: string;
89
+ alliances: Alliance[];
90
+ }
91
+ export interface Ranking {
92
+ id?: number;
93
+ event?: IdInfo;
94
+ division?: IdInfo;
95
+ rank?: number;
96
+ team?: IdInfo;
97
+ wins?: number;
98
+ losses?: number;
99
+ ties?: number;
100
+ wp?: number;
101
+ ap?: number;
102
+ sp?: number;
103
+ high_score?: number;
104
+ average_points?: number;
105
+ total_points?: number;
106
+ }
107
+ export interface Skill {
108
+ id?: number;
109
+ event?: IdInfo;
110
+ team?: IdInfo;
111
+ type?: SkillType;
112
+ season?: IdInfo;
113
+ division?: IdInfo;
114
+ rank?: number;
115
+ score?: number;
116
+ attempts?: number;
117
+ }
118
+ export interface TeamAwardWinner {
119
+ division?: IdInfo;
120
+ team?: IdInfo;
121
+ }
122
+ export interface Award {
123
+ id?: number;
124
+ event?: IdInfo;
125
+ order?: number;
126
+ title?: string;
127
+ qualifications?: string[];
128
+ designation?: "tournament" | "division" | null;
129
+ classification?: "champion" | "finalist" | "semifinalist" | "quarterfinalist" | null;
130
+ teamWinners?: TeamAwardWinner[];
131
+ individualWinners?: string[];
132
+ }
133
+ export interface Season {
134
+ id?: number;
135
+ name?: string;
136
+ program?: IdInfo;
137
+ start?: string;
138
+ end?: string;
139
+ years_start?: number;
140
+ years_end?: number;
141
+ }
142
+ export interface ApiErrorBody {
143
+ code?: number;
144
+ message?: string;
145
+ }
146
+ export interface PageMeta {
147
+ current_page?: number;
148
+ first_page_url?: string;
149
+ from?: number | null;
150
+ last_page?: number;
151
+ last_page_url?: string;
152
+ next_page_url?: string | null;
153
+ path?: string;
154
+ per_page?: number;
155
+ prev_page_url?: string | null;
156
+ to?: number | null;
157
+ total?: number;
158
+ }
159
+ export interface PaginatedResponse<T> {
160
+ meta?: PageMeta;
161
+ data?: T[];
162
+ }
163
+ export interface PaginationOptions {
164
+ /** One-indexed page number. */
165
+ page?: number;
166
+ /** Number of results per page. The API maximum is 250. */
167
+ perPage?: number;
168
+ }
169
+ export interface ListEventsOptions extends PaginationOptions {
170
+ ids?: readonly number[];
171
+ skus?: readonly string[];
172
+ teams?: readonly number[];
173
+ seasons?: readonly number[];
174
+ start?: DateInput;
175
+ end?: DateInput;
176
+ region?: string;
177
+ levels?: readonly EventLevelFilter[];
178
+ myEvents?: boolean;
179
+ eventTypes?: readonly EventType[];
180
+ }
181
+ export interface ListEventTeamsOptions extends PaginationOptions {
182
+ numbers?: readonly string[];
183
+ registered?: boolean;
184
+ grades?: readonly Grade[];
185
+ countries?: readonly string[];
186
+ myTeams?: boolean;
187
+ }
188
+ export interface ListEventSkillsOptions extends PaginationOptions {
189
+ teams?: readonly number[];
190
+ types?: readonly SkillTypeFilter[];
191
+ }
192
+ export interface ListEventAwardsOptions extends PaginationOptions {
193
+ teams?: readonly number[];
194
+ winners?: readonly string[];
195
+ }
196
+ export interface ListDivisionMatchesOptions extends PaginationOptions {
197
+ teams?: readonly number[];
198
+ rounds?: readonly number[];
199
+ instances?: readonly number[];
200
+ matchNumbers?: readonly number[];
201
+ }
202
+ export interface ListDivisionRankingsOptions extends PaginationOptions {
203
+ teams?: readonly number[];
204
+ ranks?: readonly number[];
205
+ }
206
+ export interface ListTeamsOptions extends PaginationOptions {
207
+ ids?: readonly number[];
208
+ numbers?: readonly string[];
209
+ events?: readonly number[];
210
+ registered?: boolean;
211
+ programs?: readonly number[];
212
+ grades?: readonly Grade[];
213
+ countries?: readonly string[];
214
+ myTeams?: boolean;
215
+ }
216
+ export interface ListTeamEventsOptions extends PaginationOptions {
217
+ skus?: readonly string[];
218
+ seasons?: readonly number[];
219
+ start?: DateInput;
220
+ end?: DateInput;
221
+ levels?: readonly EventLevelFilter[];
222
+ }
223
+ export interface ListTeamMatchesOptions extends PaginationOptions {
224
+ events?: readonly number[];
225
+ seasons?: readonly number[];
226
+ rounds?: readonly number[];
227
+ instances?: readonly number[];
228
+ matchNumbers?: readonly number[];
229
+ }
230
+ export interface ListTeamRankingsOptions extends PaginationOptions {
231
+ events?: readonly number[];
232
+ ranks?: readonly number[];
233
+ seasons?: readonly number[];
234
+ }
235
+ export interface ListTeamSkillsOptions extends PaginationOptions {
236
+ events?: readonly number[];
237
+ types?: readonly SkillTypeFilter[];
238
+ seasons?: readonly number[];
239
+ }
240
+ export interface ListTeamAwardsOptions extends PaginationOptions {
241
+ events?: readonly number[];
242
+ seasons?: readonly number[];
243
+ }
244
+ export interface ListProgramsOptions extends PaginationOptions {
245
+ ids?: readonly number[];
246
+ }
247
+ export interface ListSeasonsOptions extends PaginationOptions {
248
+ ids?: readonly number[];
249
+ programs?: readonly number[];
250
+ teams?: readonly number[];
251
+ start?: DateInput;
252
+ end?: DateInput;
253
+ active?: boolean;
254
+ }
255
+ export interface ListSeasonEventsOptions extends PaginationOptions {
256
+ skus?: readonly string[];
257
+ teams?: readonly number[];
258
+ start?: DateInput;
259
+ end?: DateInput;
260
+ levels?: readonly EventLevelFilter[];
261
+ }
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@v5x/events",
3
+ "version": "0.1.1",
4
+ "description": "Strictly typed TypeScript client for the VEX Events API",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "sideEffects": false,
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "bun run clean && bun run build:dts && bun run build:esm",
18
+ "build:esm": "bun build ./src/index.ts --target browser --format esm --sourcemap=linked --outdir ./dist --entry-naming=index.js",
19
+ "build:dts": "tsc -p tsconfig.build.json",
20
+ "typecheck": "tsc --noEmit",
21
+ "lint": "oxlint src --type-aware",
22
+ "test": "bun test",
23
+ "prepack": "bun run build",
24
+ "clean": "rm -rf dist"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/v5x-dev/v5x.git",
29
+ "directory": "packages/events"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "LICENSE",
34
+ "README.md"
35
+ ],
36
+ "keywords": [
37
+ "vex",
38
+ "vex-robotics",
39
+ "robotics",
40
+ "events",
41
+ "api",
42
+ "typescript"
43
+ ],
44
+ "author": "qainguin <slimaster14@gmail.com>",
45
+ "license": "MIT",
46
+ "bugs": {
47
+ "url": "https://github.com/v5x-dev/v5x/issues"
48
+ },
49
+ "homepage": "https://docs.v5x.dev/events/overview",
50
+ "devDependencies": {
51
+ "@types/bun": "latest"
52
+ }
53
+ }