diff --git a/traffic/v2/index.ts b/traffic/v2/index.ts index cbc651c..1f02d88 100644 --- a/traffic/v2/index.ts +++ b/traffic/v2/index.ts @@ -3,7 +3,7 @@ import type { APITrafficServerGameName } from './server'; export * from './server'; export * from './traffic'; -export const APITrafficVersion = '2'; +export const APITrafficVersion = '2' as const; export const APITrafficRoutes = { /** diff --git a/traffic/v2/server.ts b/traffic/v2/server.ts index c2a4cec..1d0af95 100644 --- a/traffic/v2/server.ts +++ b/traffic/v2/server.ts @@ -70,16 +70,30 @@ export interface APITrafficServer { /** * Response type of the traffic servers API end-point. */ -export interface APITrafficServers { - /** - * Determines whether the service is offline. If this is the case, no servers - * and/or traffic information may be provided. - */ - offline: boolean; +export type APITrafficServers = + | { + /** + * Determines whether the service is offline. If this is the case, no servers + * and/or traffic information may be provided. + */ + offline: false; - /** - * A collection of public game servers. - * @see https://truckersmp.com/developers/api#operation/get-servers - */ - servers?: APITrafficServer[]; -} + /** + * A collection of public game servers. + * @see https://truckersmp.com/developers/api#operation/get-servers + */ + servers: APITrafficServer[]; + } + | { + /** + * Determines whether the service is offline. If this is the case, no servers + * and/or traffic information may be provided. + */ + offline: true; + + /** + * A collection of public game servers. + * @see https://truckersmp.com/developers/api#operation/get-servers + */ + servers?: never; + }; diff --git a/traffic/v2/traffic.ts b/traffic/v2/traffic.ts index a4dc4fd..d14a912 100644 --- a/traffic/v2/traffic.ts +++ b/traffic/v2/traffic.ts @@ -3,7 +3,12 @@ import type { APITrafficServer } from './server'; /** * The congestion severity of the given location. */ -export type APITrafficLocationSeverity = 'Empty' | 'Low' | 'Moderate' | 'Congested' | 'Heavy'; +export type APITrafficLocationSeverity = + | 'Empty' + | 'Low' + | 'Moderate' + | 'Congested' + | 'Heavy'; /** * Information about a traffic location on the map. @@ -60,21 +65,40 @@ export interface APITrafficServerTop { /** * Response type for all locations on the game server. */ -export interface APITrafficServerTraffic { - /** - * Determines whether the service is offline. If this is the case, no servers - * and/or traffic information may be provided. - */ - offline: boolean; +export type APITrafficServerTraffic = + | { + /** + * Determines whether the service is offline. If this is the case, no servers + * and/or traffic information may be provided. + */ + offline: false; - /** - * Basic information of a TruckersMP server. - * @see https://truckersmp.com/developers/api#operation/get-servers - */ - server?: Omit; + /** + * Basic information of a TruckersMP server. + * @see https://truckersmp.com/developers/api#operation/get-servers + */ + server: Omit; - /** - * All locations on the map. - */ - traffic?: APITrafficLocation[]; -} + /** + * All locations on the map. + */ + traffic: APITrafficLocation[]; + } + | { + /** + * Determines whether the service is offline. If this is the case, no servers + * and/or traffic information may be provided. + */ + offline: true; + + /** + * Basic information of a TruckersMP server. + * @see https://truckersmp.com/developers/api#operation/get-servers + */ + server?: never; + + /** + * All locations on the map. + */ + traffic?: never; + }; diff --git a/tsconfig.json b/tsconfig.json index 64f0255..3454e8c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,8 @@ "skipLibCheck": true, "sourceMap": true, "declaration": true, - "declarationMap": true + "declarationMap": true, + "strictNullChecks": true }, "exclude": ["./node_modules"] } diff --git a/web/v2/ban.ts b/web/v2/ban.ts index 31c7285..71bd0c7 100644 --- a/web/v2/ban.ts +++ b/web/v2/ban.ts @@ -26,12 +26,16 @@ export interface APIPlayerBan { reason: string; /** - * Name of the admin that banned the user. + * @deprecated - v2.21.1.0 + * Name of the admin that banned the user. This field is no longer provided. + * @see https://forum.truckersmp.com/index.php?/topic/112993-website-v221-release/#comment-1111277 */ - adminName: string; + adminName: 'Game Moderator'; /** - * TruckersMP ID for the admin that banned the user. + * @deprecated - v2.21.1.0 + * TruckersMP ID for the admin that banned the user. This field is no longer provided. + * @see https://forum.truckersmp.com/index.php?/topic/112993-website-v221-release/#comment-1111277 */ - adminID: number; + adminID: null; } diff --git a/web/v2/event.ts b/web/v2/event.ts index aefb265..c18b806 100644 --- a/web/v2/event.ts +++ b/web/v2/event.ts @@ -61,7 +61,7 @@ export interface APIGameEventType { /** * The event's type key. */ - key: string; + key: 'convoy' | 'truck_show' | 'truck_show_and_convoy'; /** * The event's type name. @@ -241,6 +241,11 @@ export interface APIGameEvent { */ arrive: APIGameEventLocation; + /** + * The date and time the event's meetup is scheduled at (UTC). + */ + meetup_at: string | null; + /** * The date and time the event starts at (UTC). */ @@ -298,8 +303,11 @@ export interface APIGameEvent { /** * The event's required DLCs. + * + * - Empty array when no DLCs are required; + * - Record when DLCs are required, where the key is the Steam app ID and value is the DLC's name. */ - dlcs: Record; + dlcs: Record | []; /** * The relative URL to the event page. diff --git a/web/v2/index.ts b/web/v2/index.ts index 483eb44..3861f5d 100644 --- a/web/v2/index.ts +++ b/web/v2/index.ts @@ -6,7 +6,7 @@ export * from './rules'; export * from './server'; export * from './version'; -export const APIWebVersion = '2'; +export const APIWebVersion = '2' as const; export const APIWebRoutes = { /** @@ -17,7 +17,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - bans(id: bigint) { + bans(id: bigint | string) { return `/bans/${id}` as const; }, @@ -39,7 +39,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - company(id: string | number) { + company(id: number | string) { return `/vtc/${id}` as const; }, @@ -51,7 +51,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyEvents(companyId: string | number) { + companyEvents(companyId: number | string) { return `/vtc/${companyId}/events` as const; }, @@ -64,7 +64,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyEvent(companyId: string | number, eventId: number) { + companyEvent(companyId: number | string, eventId: number) { return `/vtc/${companyId}/events/${eventId}` as const; }, @@ -76,7 +76,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyMembers(companyId: string | number) { + companyMembers(companyId: number | string) { return `/vtc/${companyId}/members` as const; }, @@ -89,7 +89,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyMember(companyId: string | number, memberId: number) { + companyMember(companyId: number | string, memberId: number) { return `/vtc/${companyId}/member/${memberId}` as const; }, @@ -101,7 +101,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyNews(companyId: string | number) { + companyNews(companyId: number | string) { return `/vtc/${companyId}/news` as const; }, @@ -114,7 +114,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyNewsEntry(companyId: string | number, newsId: number) { + companyNewsEntry(companyId: number | string, newsId: number) { return `/vtc/${companyId}/news/${newsId}` as const; }, @@ -126,7 +126,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyRoles(companyId: string | number) { + companyRoles(companyId: number | string) { return `/vtc/${companyId}/roles` as const; }, @@ -139,7 +139,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - companyRole(companyId: string | number, roleId: number) { + companyRole(companyId: number | string, roleId: number) { return `/vtc/${companyId}/role/${roleId}` as const; }, @@ -185,7 +185,7 @@ export const APIWebRoutes = { * * @returns APIResponse */ - player(id: bigint) { + player(id: bigint | number) { return `/player/${id}` as const; }, diff --git a/web/v2/player.ts b/web/v2/player/index.ts similarity index 69% rename from web/v2/player.ts rename to web/v2/player/index.ts index de4d2bd..a53b3b3 100644 --- a/web/v2/player.ts +++ b/web/v2/player/index.ts @@ -1,69 +1,52 @@ -/** - * Information about player's Patreon status. - */ -export interface APIPlayerPatreon { - /** - * If the user has donated or is currently donating via Patreon. - */ - isPatron: boolean; - - /** - * If the user has an active Patreon subscription. - */ - active: boolean; - - /** - * HEX code for subscribed tier. - */ - color: string | null; +import APIPlayerPatreon from './patreon'; +export { type APIPlayerPatreon }; +export interface APIPlayerPermissions { /** - * The tier ID of current pledge. + * If the user is a TruckersMP staff member. */ - tierId: number | null; + isStaff: boolean; /** - * Current pledge in cents. + * If the user is part of upper staff within the TruckersMP team. */ - currentPledge: number | null; + isUpperStaff: boolean; /** - * Lifetime pledge in cents. + * If the user has Game Moderator permissions. */ - lifetimePledge: number | null; + isGameAdmin: boolean; +} +/** + * Information about player's membership in a virtual trucking company. + */ +export type APIPlayerCompanyMember = { /** - * Next pledge in cents. + * ID of the company the user belongs to or 0 if not in a company. */ - nextPledge: number | null; + id: 0; /** - * If user has their Patreon information hidden. + * Name of the company the user belongs to or empty if not in a company. */ - hidden: boolean | null; -} + name: ''; -export interface APIPlayerPermissions { /** - * If the user is a TruckersMP staff member. + * Tag of the company the user belongs to or empty if not in a company. */ - isStaff: boolean; + tag: ''; /** - * If the user is part of upper staff within the TruckersMP team. + * If the user is in a company. */ - isUpperStaff: boolean; + inVTC: false; /** - * If the user has Game Moderator permissions. + * Company member ID or 0 if not in a company. */ - isGameAdmin: boolean; -} - -/** - * Information about player's membership in a virtual trucking company. - */ -export interface APIPlayerCompanyMember { + memberID: 0; +} | { /** * ID of the company the user belongs to or 0 if not in a company. */ @@ -82,7 +65,7 @@ export interface APIPlayerCompanyMember { /** * If the user is in a company. */ - inVTC: boolean; + inVTC: true; /** * Company member ID or 0 if not in a company. @@ -124,7 +107,12 @@ export interface APIPlayerCompanyHistory { * Information about a TruckersMP player. * @see https://truckersmp.com/developers/api#operation/get-player-id */ -export interface APIPlayer { +export type APIPlayer = _APIPlayerBase & _APIPlayerVTCHistory & _APIPlayerBanData; + +/** + * Base interface containing property annotations + */ +interface _APIPlayerBase { /** * The ID of the requested user. */ @@ -191,9 +179,10 @@ export interface APIPlayer { banned: boolean; /** - * The date and time the ban will expire (UTC) or `null` if not banned or ban is permanent. + * @deprecated - v2.21.1.0 + * This field is no longer provided. */ - bannedUntil: string | null; + bannedUntil: null; /** * The number of active bans a user has or `null` if private. @@ -227,3 +216,33 @@ export interface APIPlayer { */ vtcHistory: APIPlayerCompanyHistory[] | null; } + +/** + * Specific properties of the player object regarding their VTC history + */ +type _APIPlayerVTCHistory = Pick<_APIPlayerBase, 'displayVTCHistory' | 'vtcHistory'> & + ( + | { + displayVTCHistory: false; + vtcHistory: null; + } + | { + displayVTCHistory: true; + vtcHistory: APIPlayerCompanyHistory[]; + } + ); + +/** + * Specific properties of the player object regarding bans + */ +type _APIPlayerBanData = Pick<_APIPlayerBase, 'displayBans' | 'bansCount'> & + ( + | { + displayBans: false; + bansCount: null; + } + | { + displayBans: true; + bansCount: number; + } + ); diff --git a/web/v2/player/patreon.ts b/web/v2/player/patreon.ts new file mode 100644 index 0000000..1e2962e --- /dev/null +++ b/web/v2/player/patreon.ts @@ -0,0 +1,115 @@ +/** + * Information about player's Patreon status. + */ +type APIPlayerPatreon = + | _APIPlayerPatreonPrivate + | _APIPlayerPatreonNonPatron + | _APIPlayerPatreonIsPatron; +export default APIPlayerPatreon; + +/** + * Base interface containing property type annotations and documentation. + */ +interface _APIPlayerPatreonBase { + /** + * If the user has donated or is currently donating via Patreon. + */ + isPatron: boolean | null; + + /** + * If the user has an active Patreon subscription. + */ + active: boolean | null; + + /** + * Hex code for subscribed tier. + */ + color: string | null; + + /** + * The tier ID of current pledge. + */ + tierId: number | null; + + /** + * Current pledge in cents. + */ + currentPledge: number | null; + + /** + * Lifetime pledge in cents. + */ + lifetimePledge: number | null; + + /** + * Next pledge in cents. + */ + nextPledge: number | null; + + /** + * If user has their Patreon information hidden. + */ + hidden: boolean | null; +} + +/** + * `patreon` field when the user has their Patreon information hidden + */ +interface _APIPlayerPatreonPrivate extends _APIPlayerPatreonBase { + isPatron: false | null; + active: null; + color: null; + tierId: null; + currentPledge: null; + lifetimePledge: null; + nextPledge: null; + hidden: true; +} + +/** + * Base interface for public Patreon information + */ +interface _APIPartialPlayerPatreonPublicBase { + lifetimePledge: number | null; + hidden: false | null; +} + +/** + * Properties specific to the `patreon` field when the user is an inactive patron + */ +interface _APIPartialPlayerPatreonPublicInactive + extends _APIPartialPlayerPatreonPublicBase { + active: false; + color: null; + tierId: null; + currentPledge: null; + nextPledge: null; +} + +/** + * Properties specific to the `patreon` field when the user is an active patron + */ +interface _APIPartialPlayerPatreonPublicActive + extends _APIPartialPlayerPatreonPublicBase { + active: true; + color: string; + tierId: number; + currentPledge: number; + nextPledge: number | null; +} + +/** + * `patreon` field when the user is not a patron (ie. has never donated) + */ +interface _APIPlayerPatreonNonPatron + extends _APIPartialPlayerPatreonPublicInactive { + isPatron: false; +} + +/** + * `patreon` field when the user is a current or former patron + */ +type _APIPlayerPatreonIsPatron = _APIPlayerPatreonBase & { isPatron: true } & ( + | _APIPartialPlayerPatreonPublicInactive + | _APIPartialPlayerPatreonPublicActive + ); diff --git a/web/v2/server.ts b/web/v2/server.ts index 4265eae..2d264ba 100644 --- a/web/v2/server.ts +++ b/web/v2/server.ts @@ -74,9 +74,9 @@ export interface APIGameServer { displayorder: number; /** - * If the speed limiter is enabled on the server (110 kmh for ETS2 and 80 mph for ATS). + * Whether or not the speed limiter is enabled on the server (110 kmh for ETS2 and 80 mph for ATS). */ - speedlimiter: number; + speedlimiter: 0 | 1; /** * If server wide collisions is enabled.