Skip to content
Open
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
7 changes: 7 additions & 0 deletions src/lib/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ export {
tokenDeleteDeleteToken,
usersGetByName,
usersGetSelf,
usersGetSelfControlStats,
versionGetBackendInfo,
} from './internal/v1';

// Enum-like constants from v1 (each exports both a runtime value and a type).
export {
AutomationTokenType,
ConfigurationValueType,
ControlType,
EmailStatus,
EmailType,
MatchTypeEnum,
Expand Down Expand Up @@ -135,7 +137,10 @@ export type {
BackendInfoResponse,
BasicUserInfo,
ConfigurationItemDto,
ControlStatTotals,
ControlStatsResponse,
CreatedAutomationTokenDto,
DailyControlStats,
DeviceWithShockersResponse,
EmailOutboxBulkResultDto,
EmailOutboxMessageDto,
Expand All @@ -157,8 +162,10 @@ export type {
PublicShareResponse,
PublicShareShocker,
SharedShocker,
ShockerControlStats,
ShockerResponse,
ShockerWithDevice,
UserControlStats,
UserNameBlacklistDto,
WebhookDto,
} from './internal/v1';
Expand Down
22 changes: 22 additions & 0 deletions src/lib/api/internal/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export {
devicesOtaGetOtaUpdateHistory,
devicesRegenerateDeviceToken,
devicesRemoveDevice,
integrationsGetControlStatChanges,
publicGetOnlineDevicesStatistics,
publicGetPublicShare,
sessionsDeleteSession,
Expand Down Expand Up @@ -107,6 +108,7 @@ export {
tokensSelfGetSelfToken,
usersGetByName,
usersGetSelf,
usersGetSelfControlStats,
versionGetBackendInfo,
type Options,
} from './sdk.gen';
Expand Down Expand Up @@ -375,9 +377,14 @@ export {
type ConfigurationUpdateItemRequest,
type Control,
type ControlLogSenderLight,
type ControlStatChangesRequest,
type ControlStatChangesResponse,
type ControlStatTotals,
type ControlStatsResponse,
type CreateAutomationTokenDto,
type CreateTokenRequest,
type CreatedAutomationTokenDto,
type DailyControlStats,
type DeviceGetLiveControlGatewayData,
type DeviceGetLiveControlGatewayError,
type DeviceGetLiveControlGatewayErrors,
Expand Down Expand Up @@ -445,7 +452,13 @@ export {
type EmailOutboxMessageDto,
type EmailOutboxStatsDto,
type EmailProviderBlacklistDto,
type GivenControlStats,
type HubEditRequest,
type IntegrationsGetControlStatChangesData,
type IntegrationsGetControlStatChangesError,
type IntegrationsGetControlStatChangesErrors,
type IntegrationsGetControlStatChangesResponse,
type IntegrationsGetControlStatChangesResponses,
type LcgNodeResponse,
type LcgResponse,
type LegacyDataResponseOfArrayOfAdminOnlineDeviceResponse,
Expand Down Expand Up @@ -503,6 +516,7 @@ export {
type PublicShareEditShocker,
type PublicShareResponse,
type PublicShareShocker,
type ReceivedControlStats,
type ReportTokensRequest,
type SendTestEmailDto,
type SessionsDeleteSessionData,
Expand Down Expand Up @@ -563,6 +577,7 @@ export {
type SharesLinkShareCodeErrors,
type SharesLinkShareCodeResponse,
type SharesLinkShareCodeResponses,
type ShockerControlStats,
type ShockerEditShockerData,
type ShockerEditShockerError,
type ShockerEditShockerErrors,
Expand Down Expand Up @@ -667,6 +682,8 @@ export {
type TokensSelfGetSelfTokenData,
type TokensSelfGetSelfTokenResponse,
type TokensSelfGetSelfTokenResponses,
type UserControlStatTotals,
type UserControlStats,
type UserNameBlacklistDto,
type UserPatchDto,
type UserSelfResponse,
Expand All @@ -677,6 +694,11 @@ export {
type UsersGetByNameErrors,
type UsersGetByNameResponse,
type UsersGetByNameResponses,
type UsersGetSelfControlStatsData,
type UsersGetSelfControlStatsError,
type UsersGetSelfControlStatsErrors,
type UsersGetSelfControlStatsResponse,
type UsersGetSelfControlStatsResponses,
type UsersGetSelfData,
type UsersGetSelfResponse,
type UsersGetSelfResponses,
Expand Down
66 changes: 66 additions & 0 deletions src/lib/api/internal/v1/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
devicesGetShockersResponseTransformer,
devicesListDevicesResponseTransformer,
devicesOtaGetOtaUpdateHistoryResponseTransformer,
integrationsGetControlStatChangesResponseTransformer,
publicGetOnlineDevicesStatisticsResponseTransformer,
publicGetPublicShareResponseTransformer,
sessionsGetSelfSessionResponseTransformer,
Expand All @@ -39,6 +40,7 @@ import {
tokensGetTokenByIdResponseTransformer,
tokensListTokensResponseTransformer,
tokensSelfGetSelfTokenResponseTransformer,
usersGetSelfControlStatsResponseTransformer,
versionGetBackendInfoResponseTransformer,
} from './transformers.gen';
import type {
Expand Down Expand Up @@ -229,6 +231,9 @@ import type {
DevicesRemoveDeviceData,
DevicesRemoveDeviceErrors,
DevicesRemoveDeviceResponses,
IntegrationsGetControlStatChangesData,
IntegrationsGetControlStatChangesErrors,
IntegrationsGetControlStatChangesResponses,
PublicGetOnlineDevicesStatisticsData,
PublicGetOnlineDevicesStatisticsResponses,
PublicGetPublicShareData,
Expand Down Expand Up @@ -331,6 +336,9 @@ import type {
UsersGetByNameData,
UsersGetByNameErrors,
UsersGetByNameResponses,
UsersGetSelfControlStatsData,
UsersGetSelfControlStatsErrors,
UsersGetSelfControlStatsResponses,
UsersGetSelfData,
UsersGetSelfResponses,
VersionGetBackendInfoData,
Expand Down Expand Up @@ -380,6 +388,29 @@ export const usersGetSelf = <ThrowOnError extends boolean = true>(
...options,
});

/**
* Get control statistics for the current user, both for their own shockers and for controls they sent.
*/
export const usersGetSelfControlStats = <ThrowOnError extends boolean = true>(
options?: Options<UsersGetSelfControlStatsData, ThrowOnError>
): RequestResult<
UsersGetSelfControlStatsResponses,
UsersGetSelfControlStatsErrors,
ThrowOnError,
'data'
> =>
(options?.client ?? client).get<
UsersGetSelfControlStatsResponses,
UsersGetSelfControlStatsErrors,
ThrowOnError,
'data'
>({
responseTransformer: usersGetSelfControlStatsResponseTransformer,
responseStyle: 'data',
url: '/1/users/self/control-stats',
...options,
});

export const usersGetByName = <ThrowOnError extends boolean = true>(
options: Options<UsersGetByNameData, ThrowOnError>
): RequestResult<UsersGetByNameResponses, UsersGetByNameErrors, ThrowOnError, 'data'> =>
Expand Down Expand Up @@ -1121,6 +1152,41 @@ export const publicGetPublicShare = <ThrowOnError extends boolean = true>(
...options,
});

/**
* Lets a service holding many users keep their lifetime control stats in sync with a single call per tick.
* Returns the lifetime totals of every requested user whose stats changed since the given cursor.
*
* Requires an automation token granting `ControlStatsRead`. "Changed since" is answered from when each
* stats row was last written rather than the time it covers, so live control stats written late (e.g. after a
* database outage) are still picked up. Rows deleted along with their owner lower the totals of everyone who
* controlled them without leaving a row behind, those are picked up from ControlStatRemoval. The
* lookback is widened by ChangeOverlap to cover writes still committing while the previous call
* read, so a user can be reported again although nothing changed.
*/
export const integrationsGetControlStatChanges = <ThrowOnError extends boolean = true>(
options: Options<IntegrationsGetControlStatChangesData, ThrowOnError>
): RequestResult<
IntegrationsGetControlStatChangesResponses,
IntegrationsGetControlStatChangesErrors,
ThrowOnError,
'data'
> =>
(options.client ?? client).post<
IntegrationsGetControlStatChangesResponses,
IntegrationsGetControlStatChangesErrors,
ThrowOnError,
'data'
>({
responseTransformer: integrationsGetControlStatChangesResponseTransformer,
responseStyle: 'data',
url: '/1/integrations/control-stats/changes',
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
});

/**
* Gets the OTA update history for a device
*/
Expand Down
76 changes: 76 additions & 0 deletions src/lib/api/internal/v1/transformers.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
DevicesGetShockersResponse,
DevicesListDevicesResponse,
DevicesOtaGetOtaUpdateHistoryResponse,
IntegrationsGetControlStatChangesResponse,
PublicGetOnlineDevicesStatisticsResponse,
PublicGetPublicShareResponse,
SessionsGetSelfSessionResponse,
Expand All @@ -39,6 +40,7 @@ import type {
TokensGetTokenByIdResponse,
TokensListTokensResponse,
TokensSelfGetSelfTokenResponse,
UsersGetSelfControlStatsResponse,
VersionGetBackendInfoResponse,
} from './types.gen';

Expand All @@ -59,6 +61,59 @@ export const versionGetBackendInfoResponseTransformer = async (
return data;
};

const controlStatTotalsSchemaResponseTransformer = (data: any) => {
data.count = BigInt(data.count.toString());
data.durationMs = BigInt(data.durationMs.toString());
return data;
};

const shockerControlStatsSchemaResponseTransformer = (data: any) => {
data.stats = data.stats.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
return data;
};

const userControlStatsSchemaResponseTransformer = (data: any) => {
data.stats = data.stats.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
return data;
};

const dailyControlStatsSchemaResponseTransformer = (data: any) => {
data.date = Temporal.PlainDate.from(data.date);
data.stats = data.stats.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
return data;
};

const receivedControlStatsSchemaResponseTransformer = (data: any) => {
data.totals = data.totals.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
data.shockers = data.shockers.map((item: any) =>
shockerControlStatsSchemaResponseTransformer(item)
);
data.controllers = data.controllers.map((item: any) =>
userControlStatsSchemaResponseTransformer(item)
);
data.days = data.days.map((item: any) => dailyControlStatsSchemaResponseTransformer(item));
return data;
};

const givenControlStatsSchemaResponseTransformer = (data: any) => {
data.totals = data.totals.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
data.owners = data.owners.map((item: any) => userControlStatsSchemaResponseTransformer(item));
return data;
};

const controlStatsResponseSchemaResponseTransformer = (data: any) => {
data.received = receivedControlStatsSchemaResponseTransformer(data.received);
data.given = givenControlStatsSchemaResponseTransformer(data.given);
return data;
};

export const usersGetSelfControlStatsResponseTransformer = async (
data: any
): Promise<UsersGetSelfControlStatsResponse> => {
data = controlStatsResponseSchemaResponseTransformer(data);
return data;
};

const tokenResponseSchemaResponseTransformer = (data: any) => {
data.createdOn = Temporal.Instant.from(data.createdOn);
if (data.validUntil) {
Expand Down Expand Up @@ -297,6 +352,27 @@ export const publicGetPublicShareResponseTransformer = async (
return data;
};

const userControlStatTotalsSchemaResponseTransformer = (data: any) => {
data.received = data.received.map((item: any) =>
controlStatTotalsSchemaResponseTransformer(item)
);
data.given = data.given.map((item: any) => controlStatTotalsSchemaResponseTransformer(item));
return data;
};

const controlStatChangesResponseSchemaResponseTransformer = (data: any) => {
data.cursor = Temporal.Instant.from(data.cursor);
data.users = data.users.map((item: any) => userControlStatTotalsSchemaResponseTransformer(item));
return data;
};

export const integrationsGetControlStatChangesResponseTransformer = async (
data: any
): Promise<IntegrationsGetControlStatChangesResponse> => {
data = controlStatChangesResponseSchemaResponseTransformer(data);
return data;
};

const otaItemSchemaResponseTransformer = (data: any) => {
data.startedAt = Temporal.Instant.from(data.startedAt);
return data;
Expand Down
Loading
Loading