doover-js 0.1.0

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.
Files changed (61) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +35 -0
  3. package/dist/apis/agents-api.d.ts +22 -0
  4. package/dist/apis/agents-api.js +20 -0
  5. package/dist/apis/aggregates-api.d.ts +15 -0
  6. package/dist/apis/aggregates-api.js +21 -0
  7. package/dist/apis/alarms-api.d.ts +12 -0
  8. package/dist/apis/alarms-api.js +27 -0
  9. package/dist/apis/channels-api.d.ts +27 -0
  10. package/dist/apis/channels-api.js +24 -0
  11. package/dist/apis/connections-api.d.ts +23 -0
  12. package/dist/apis/connections-api.js +24 -0
  13. package/dist/apis/messages-api.d.ts +32 -0
  14. package/dist/apis/messages-api.js +45 -0
  15. package/dist/apis/notifications-api.d.ts +23 -0
  16. package/dist/apis/notifications-api.js +54 -0
  17. package/dist/apis/permissions-api.d.ts +9 -0
  18. package/dist/apis/permissions-api.js +18 -0
  19. package/dist/apis/processors-api.d.ts +21 -0
  20. package/dist/apis/processors-api.js +45 -0
  21. package/dist/apis/turn-api.d.ts +7 -0
  22. package/dist/apis/turn-api.js +12 -0
  23. package/dist/client/doover-client.d.ts +29 -0
  24. package/dist/client/doover-client.js +34 -0
  25. package/dist/gateway/gateway-client.d.ts +37 -0
  26. package/dist/gateway/gateway-client.js +258 -0
  27. package/dist/gateway/types.d.ts +135 -0
  28. package/dist/gateway/types.js +2 -0
  29. package/dist/http/errors.d.ts +19 -0
  30. package/dist/http/errors.js +28 -0
  31. package/dist/http/rest-client.d.ts +35 -0
  32. package/dist/http/rest-client.js +129 -0
  33. package/dist/index.d.ts +22 -0
  34. package/dist/index.js +41 -0
  35. package/dist/test/apis.test.d.ts +1 -0
  36. package/dist/test/apis.test.js +248 -0
  37. package/dist/test/doover-client.test.d.ts +1 -0
  38. package/dist/test/doover-client.test.js +29 -0
  39. package/dist/test/doover-data-provider.test.d.ts +1 -0
  40. package/dist/test/doover-data-provider.test.js +228 -0
  41. package/dist/test/gateway-client.test.d.ts +1 -0
  42. package/dist/test/gateway-client.test.js +235 -0
  43. package/dist/test/helpers.d.ts +32 -0
  44. package/dist/test/helpers.js +115 -0
  45. package/dist/test/rest-client.test.d.ts +1 -0
  46. package/dist/test/rest-client.test.js +115 -0
  47. package/dist/test/utils.test.d.ts +1 -0
  48. package/dist/test/utils.test.js +54 -0
  49. package/dist/types/common.d.ts +130 -0
  50. package/dist/types/common.js +2 -0
  51. package/dist/types/openapi.d.ts +144 -0
  52. package/dist/types/openapi.js +2 -0
  53. package/dist/types/viewer.d.ts +70 -0
  54. package/dist/types/viewer.js +2 -0
  55. package/dist/utils/snowflake.d.ts +13 -0
  56. package/dist/utils/snowflake.js +26 -0
  57. package/dist/viewer/doover-data-provider.d.ts +55 -0
  58. package/dist/viewer/doover-data-provider.js +191 -0
  59. package/dist/viewer/path-parsing.d.ts +5 -0
  60. package/dist/viewer/path-parsing.js +38 -0
  61. package/package.json +46 -0
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const chai_1 = require("chai");
7
+ const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
8
+ const mocha_1 = require("mocha");
9
+ const rest_client_1 = require("../http/rest-client");
10
+ const helpers_1 = require("./helpers");
11
+ (0, chai_1.use)(chai_as_promised_1.default);
12
+ (0, mocha_1.describe)("RestClient", () => {
13
+ (0, mocha_1.beforeEach)(() => {
14
+ (0, helpers_1.installSessionStorageMock)();
15
+ });
16
+ (0, mocha_1.it)("adds query params and compatibility headers", async () => {
17
+ sessionStorage.setItem("impersonate_user_id", "user-2");
18
+ const fetchMock = (0, helpers_1.createFetchMock)();
19
+ const client = new rest_client_1.RestClient({
20
+ dataRestUrl: "https://api.example.com",
21
+ controlApiUrl: "https://control.example.com",
22
+ dataWssUrl: "wss://ws.example.com",
23
+ organisationId: "org-1",
24
+ fetchImpl: fetchMock,
25
+ });
26
+ await client.get("/items", { tag: ["a", "b"], enabled: true });
27
+ (0, chai_1.expect)(fetchMock.callCount).to.equal(1);
28
+ const [url, init] = fetchMock.getCall(0).args;
29
+ (0, chai_1.expect)(url).to.equal("https://api.example.com/items?tag=a&tag=b&enabled=true");
30
+ (0, chai_1.expect)(init?.credentials).to.equal("include");
31
+ const headers = init?.headers;
32
+ (0, chai_1.expect)(headers.get("X-Doover-Sharing")).to.equal("internal");
33
+ (0, chai_1.expect)(headers.get("X-Doover-Organisation")).to.equal("org-1");
34
+ (0, chai_1.expect)(headers.get("X-Doover-Assume")).to.equal("user-2");
35
+ });
36
+ (0, mocha_1.it)("serializes JSON request bodies", async () => {
37
+ const fetchMock = (0, helpers_1.createFetchMock)();
38
+ const client = new rest_client_1.RestClient({
39
+ dataRestUrl: "https://api.example.com",
40
+ controlApiUrl: "https://control.example.com",
41
+ dataWssUrl: "wss://ws.example.com",
42
+ fetchImpl: fetchMock,
43
+ });
44
+ await client.post("/items", { name: "alpha" });
45
+ const [, init] = fetchMock.getCall(0).args;
46
+ (0, chai_1.expect)(init?.method).to.equal("POST");
47
+ (0, chai_1.expect)(init?.body).to.equal(JSON.stringify({ name: "alpha" }));
48
+ const headers = init?.headers;
49
+ (0, chai_1.expect)(headers.get("Content-Type")).to.equal("application/json");
50
+ });
51
+ (0, mocha_1.it)("passes through FormData bodies without forcing JSON content type", async () => {
52
+ const fetchMock = (0, helpers_1.createFetchMock)();
53
+ const client = new rest_client_1.RestClient({
54
+ dataRestUrl: "https://api.example.com",
55
+ controlApiUrl: "https://control.example.com",
56
+ dataWssUrl: "wss://ws.example.com",
57
+ fetchImpl: fetchMock,
58
+ });
59
+ const formData = new FormData();
60
+ formData.set("a", "1");
61
+ await client.post("/upload", formData);
62
+ const [, init] = fetchMock.getCall(0).args;
63
+ (0, chai_1.expect)(init?.body).to.equal(formData);
64
+ const headers = init?.headers;
65
+ (0, chai_1.expect)(headers.get("Content-Type")).to.equal(null);
66
+ });
67
+ (0, mocha_1.it)("parses blob responses for attachments", async () => {
68
+ const fetchMock = (0, helpers_1.createFetchMock)(() => (0, helpers_1.createBlobResponse)("hello"));
69
+ const client = new rest_client_1.RestClient({
70
+ dataRestUrl: "https://api.example.com",
71
+ controlApiUrl: "https://control.example.com",
72
+ dataWssUrl: "wss://ws.example.com",
73
+ fetchImpl: fetchMock,
74
+ });
75
+ const blob = await client.get("/blob");
76
+ (0, chai_1.expect)(blob).to.be.instanceOf(Blob);
77
+ (0, chai_1.expect)(await blob.text()).to.equal("hello");
78
+ });
79
+ (0, mocha_1.it)("returns undefined for empty 204 responses", async () => {
80
+ const fetchMock = (0, helpers_1.createFetchMock)(() => new Response(null, { status: 204 }));
81
+ const client = new rest_client_1.RestClient({
82
+ dataRestUrl: "https://api.example.com",
83
+ controlApiUrl: "https://control.example.com",
84
+ dataWssUrl: "wss://ws.example.com",
85
+ fetchImpl: fetchMock,
86
+ });
87
+ await (0, chai_1.expect)(client.delete("/items/1")).to.eventually.equal(undefined);
88
+ });
89
+ (0, mocha_1.it)("throws a DooverApiError on non-2xx responses", async () => {
90
+ const fetchMock = (0, helpers_1.createFetchMock)(() => (0, helpers_1.createJsonResponse)({ message: "bad request" }, { status: 400 }));
91
+ const client = new rest_client_1.RestClient({
92
+ dataRestUrl: "https://api.example.com",
93
+ controlApiUrl: "https://control.example.com",
94
+ dataWssUrl: "wss://ws.example.com",
95
+ fetchImpl: fetchMock,
96
+ });
97
+ await (0, chai_1.expect)(client.get("/broken")).to.be.rejected.then((error) => {
98
+ (0, chai_1.expect)(error.name).to.equal("DooverApiError");
99
+ (0, chai_1.expect)(error.status).to.equal(400);
100
+ (0, chai_1.expect)(error.message).to.equal("bad request");
101
+ (0, chai_1.expect)(error.url).to.equal("https://api.example.com/broken");
102
+ (0, chai_1.expect)(error.method).to.equal("GET");
103
+ });
104
+ });
105
+ (0, mocha_1.it)("returns text bodies when the response is not JSON", async () => {
106
+ const fetchMock = (0, helpers_1.createFetchMock)(() => (0, helpers_1.createTextResponse)("plain text"));
107
+ const client = new rest_client_1.RestClient({
108
+ dataRestUrl: "https://api.example.com",
109
+ controlApiUrl: "https://control.example.com",
110
+ dataWssUrl: "wss://ws.example.com",
111
+ fetchImpl: fetchMock,
112
+ });
113
+ await (0, chai_1.expect)(client.get("/text")).to.eventually.equal("plain text");
114
+ });
115
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chai_1 = require("chai");
4
+ const mocha_1 = require("mocha");
5
+ const snowflake_1 = require("../utils/snowflake");
6
+ const path_parsing_1 = require("../viewer/path-parsing");
7
+ (0, mocha_1.describe)("snowflake utilities", () => {
8
+ (0, mocha_1.it)("generates and extracts timestamps consistently", () => {
9
+ const date = new Date("2026-01-02T03:04:05.000Z");
10
+ const id = (0, snowflake_1.generateSnowflakeIdAtTime)(date);
11
+ const extracted = (0, snowflake_1.extractSnowflakeId)(id);
12
+ (0, chai_1.expect)(extracted.timestamp).to.equal(date.getTime());
13
+ (0, chai_1.expect)(id).to.match(/^\d+$/);
14
+ });
15
+ (0, mocha_1.it)("adds a second-based timestamp to messages", () => {
16
+ const date = new Date("2026-01-02T03:04:05.000Z");
17
+ const id = (0, snowflake_1.generateSnowflakeIdAtTime)(date);
18
+ const message = (0, snowflake_1.addTimestampToMessage)({
19
+ id,
20
+ author_id: "user",
21
+ channel: { agent_id: "agent", name: "channel" },
22
+ data: {},
23
+ attachments: [],
24
+ });
25
+ (0, chai_1.expect)(message.timestamp).to.equal(date.getTime() / 1000);
26
+ });
27
+ });
28
+ (0, mocha_1.describe)("path parsing", () => {
29
+ (0, mocha_1.it)("parses agent-only paths", () => {
30
+ (0, chai_1.expect)((0, path_parsing_1.getIdentifierFromPath)("agent-1", new URLSearchParams())).to.deep.equal({
31
+ identifier: {
32
+ agentId: "agent-1",
33
+ channelName: undefined,
34
+ },
35
+ });
36
+ });
37
+ (0, mocha_1.it)("parses channel paths with aggregate tails", () => {
38
+ (0, chai_1.expect)((0, path_parsing_1.getIdentifierFromPath)("/agent-1/channel-1/path/to/value", new URLSearchParams())).to.deep.equal({
39
+ identifier: {
40
+ agentId: "agent-1",
41
+ channelName: "channel-1",
42
+ },
43
+ aggregatePath: "path/to/value",
44
+ });
45
+ });
46
+ (0, mocha_1.it)("returns an empty identifier for an empty path", () => {
47
+ (0, chai_1.expect)((0, path_parsing_1.getIdentifierFromPath)("/", new URLSearchParams())).to.deep.equal({
48
+ identifier: {
49
+ agentId: undefined,
50
+ channelName: undefined,
51
+ },
52
+ });
53
+ });
54
+ });
@@ -0,0 +1,130 @@
1
+ export type JSONPrimitive = null | boolean | number | string;
2
+ export type JSONValue = JSONPrimitive | JSONValue[] | {
3
+ [key: string]: JSONValue;
4
+ };
5
+ export interface Attachment {
6
+ url: string;
7
+ content_type: string | null;
8
+ filename: string;
9
+ size: number;
10
+ }
11
+ export interface ChannelRef {
12
+ agent_id: string;
13
+ name: string;
14
+ }
15
+ export interface Aggregate<TData = Record<string, JSONValue>> {
16
+ data: TData;
17
+ attachments: Attachment[];
18
+ last_updated?: number | null;
19
+ }
20
+ export interface MessageAttachment extends Attachment {
21
+ }
22
+ export interface MessageStructure<TData = JSONValue> {
23
+ data: TData;
24
+ attachments: MessageAttachment[];
25
+ id: string;
26
+ author_id: string;
27
+ channel: ChannelRef;
28
+ timestamp: number;
29
+ record_log?: boolean;
30
+ }
31
+ export interface Channel<TAgg = Record<string, JSONValue>> {
32
+ aggregate?: Aggregate<TAgg>;
33
+ is_private: boolean;
34
+ id?: string;
35
+ name: string;
36
+ owner_id: string;
37
+ alarms_enabled?: boolean;
38
+ aggregate_schema?: Record<string, JSONValue> | null;
39
+ message_schema?: Record<string, JSONValue> | null;
40
+ daily_message_summaries?: unknown[];
41
+ alarms?: Alarm[];
42
+ }
43
+ export interface Alarm {
44
+ id: string;
45
+ name: string;
46
+ description: string;
47
+ enabled: boolean;
48
+ key: string;
49
+ operator: AlarmOperator;
50
+ value: JSONValue;
51
+ state: AlarmState;
52
+ expiry_mins: number | null;
53
+ entered_state_ts: number;
54
+ }
55
+ export type AlarmOperator = "eq" | "ge" | "gt" | "le" | "lt";
56
+ export type AlarmState = "NoData" | "OK" | "Alarm";
57
+ export interface ConnectionSubscription {
58
+ channel: ChannelRef;
59
+ subscribed_at: number;
60
+ connection_id: string;
61
+ }
62
+ export interface ConnectionSubscriptionLog {
63
+ channel: ChannelRef;
64
+ subscribed_at?: number | null;
65
+ unsubscribed_at?: number | null;
66
+ connection_id: string;
67
+ }
68
+ export interface ConnectionDetails {
69
+ address: string;
70
+ agent_id: string;
71
+ default_session: boolean;
72
+ session_id: string;
73
+ last_ping?: number | null;
74
+ latency?: number | null;
75
+ status: number;
76
+ subscriptions: ConnectionSubscription[];
77
+ }
78
+ export interface NotificationSubscriptionEndpoint {
79
+ id: string;
80
+ name: string;
81
+ default: boolean;
82
+ }
83
+ export interface NotificationSubscription {
84
+ id: string;
85
+ subscriber: string;
86
+ subscribed_to: string;
87
+ severity: number;
88
+ topic_filter: string[];
89
+ endpoints: NotificationSubscriptionEndpoint[];
90
+ }
91
+ export interface NotificationEndpoint {
92
+ id: string;
93
+ agent_id: string;
94
+ type: number;
95
+ priority: number | null;
96
+ extra_data: Record<string, JSONValue>;
97
+ name: string;
98
+ default: boolean;
99
+ }
100
+ export interface ResourcePermission {
101
+ permission_id: string;
102
+ permission: string;
103
+ }
104
+ export interface AgentPermission {
105
+ agent_id: string;
106
+ is_superuser: boolean;
107
+ resources: ResourcePermission[];
108
+ last_updated?: number | null;
109
+ }
110
+ export interface TurnCredential {
111
+ username: string;
112
+ credential: string;
113
+ ttl: number;
114
+ expires_at: number;
115
+ uris: string[];
116
+ }
117
+ export interface AgentAggregate<TData = Record<string, JSONValue>> {
118
+ agent_id: string;
119
+ data: TData;
120
+ attachments: Attachment[];
121
+ last_updated?: number | null;
122
+ }
123
+ export interface DataSeriesResult {
124
+ value: JSONValue;
125
+ message_id: string;
126
+ }
127
+ export interface DataSeries {
128
+ count: number;
129
+ results: DataSeriesResult[];
130
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,144 @@
1
+ import type { AgentAggregate, AgentPermission, Alarm, Aggregate, Channel, ConnectionDetails, ConnectionSubscription, ConnectionSubscriptionLog, DataSeries, MessageStructure, NotificationEndpoint, NotificationSubscription, ResourcePermission, TurnCredential } from "./common";
2
+ export type { AgentAggregate, AgentPermission, Alarm, Aggregate, Channel, ConnectionDetails, ConnectionSubscription, ConnectionSubscriptionLog, DataSeries, MessageStructure, NotificationEndpoint, NotificationSubscription, ResourcePermission, TurnCredential, };
3
+ export interface BatchMessagesResponse {
4
+ results: MessageStructure[];
5
+ count: number;
6
+ next?: string;
7
+ }
8
+ export interface BatchAggregatesResponse {
9
+ results: AgentAggregate[];
10
+ count: number;
11
+ }
12
+ export interface NotificationDataResponse {
13
+ subscriptions: NotificationSubscription[];
14
+ subscribers: NotificationSubscription[];
15
+ endpoints: NotificationEndpoint[];
16
+ }
17
+ export interface NotificationEndpointsResponse {
18
+ endpoints: NotificationEndpoint[];
19
+ }
20
+ export interface NotificationSubscriptionsResponse {
21
+ subscriptions: NotificationSubscription[];
22
+ }
23
+ export interface NotificationSubscribersResponse {
24
+ subscribers: NotificationSubscription[];
25
+ }
26
+ export interface NotificationSubscriptionCreateResponse {
27
+ subscriptions: Array<{
28
+ id: string;
29
+ endpoint_id: string;
30
+ }>;
31
+ }
32
+ export interface PermissionDebugResponse {
33
+ cache?: AgentPermission | null;
34
+ db: AgentPermission;
35
+ }
36
+ export interface ScheduleInfo {
37
+ [key: string]: unknown;
38
+ }
39
+ export interface ProcessorSubscriptionInfo {
40
+ [key: string]: unknown;
41
+ }
42
+ export interface IngestionEndpointInfo {
43
+ [key: string]: unknown;
44
+ }
45
+ export interface SubscriptionInfo {
46
+ agent_id: string;
47
+ organisation_id: string;
48
+ app_key: string;
49
+ deployment_config: Record<string, unknown>;
50
+ ui_state: Record<string, unknown>;
51
+ ui_cmds: Record<string, unknown>;
52
+ tag_values: Record<string, unknown>;
53
+ connection_data: Record<string, unknown>;
54
+ token: string;
55
+ }
56
+ export interface SuccessListResponse<T = string> {
57
+ success: T[];
58
+ }
59
+ export interface CreateChannelRequest {
60
+ is_private?: boolean;
61
+ message_schema?: Record<string, unknown> | null;
62
+ aggregate_schema?: Record<string, unknown> | null;
63
+ }
64
+ export interface PutChannelRequest extends CreateChannelRequest {
65
+ is_private: boolean;
66
+ }
67
+ export interface CreateMessageRequest {
68
+ data: Record<string, unknown>;
69
+ ts?: number;
70
+ }
71
+ export interface UpdateMessageRequest {
72
+ data: Record<string, unknown>;
73
+ }
74
+ export interface CreateAlarmRequest {
75
+ name: string;
76
+ description?: string;
77
+ enabled?: boolean;
78
+ key: string;
79
+ operator: Alarm["operator"];
80
+ value: unknown;
81
+ expiry_mins?: number | null;
82
+ }
83
+ export interface PatchAlarmRequest extends Partial<CreateAlarmRequest> {
84
+ }
85
+ export interface CreateEndpointRequest {
86
+ name: string;
87
+ priority?: number | null;
88
+ type: number;
89
+ extra_data: Record<string, unknown>;
90
+ default: boolean;
91
+ }
92
+ export interface UpdateEndpointRequest {
93
+ extra_data?: Record<string, unknown> | null;
94
+ priority?: number | null;
95
+ name?: string;
96
+ }
97
+ export interface CreateNotificationSubscriptionRequest {
98
+ subscribe_to: string;
99
+ endpoint_id?: string | null;
100
+ severity: number;
101
+ topic_filter: string[];
102
+ }
103
+ export interface UpdateNotificationSubscriptionRequest {
104
+ severity?: number;
105
+ topic_filter?: string[];
106
+ }
107
+ export interface UpdateMeWebPushEndpointRequest {
108
+ old_endpoint: string;
109
+ endpoint: string;
110
+ key_p256dh: string;
111
+ key_auth: string;
112
+ expires_at: number;
113
+ }
114
+ export interface SyncPermissionRequest {
115
+ agent_permissions: AgentPermission[];
116
+ }
117
+ export interface PutScheduleRequest {
118
+ app_key: string;
119
+ is_org?: boolean | null;
120
+ permissions: ResourcePermission[];
121
+ }
122
+ export interface PutSubscriptionRequest {
123
+ subscription_arn: string;
124
+ app_key: string;
125
+ is_org?: boolean | null;
126
+ permissions: ResourcePermission[];
127
+ }
128
+ export interface CreateIngestionRequest {
129
+ lambda_arn: string;
130
+ cidr_ranges: string[];
131
+ signing_key?: string | null;
132
+ signing_key_hash_header?: string | null;
133
+ throttle_limit: number;
134
+ never_replace_token?: boolean;
135
+ mini_token?: boolean;
136
+ is_org?: boolean | null;
137
+ app_key: string;
138
+ permissions: ResourcePermission[];
139
+ }
140
+ export interface TurnTokenRequest {
141
+ role: "client" | "device";
142
+ device_id?: string;
143
+ camera_name: string;
144
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,70 @@
1
+ import type { Aggregate, Channel, ConnectionDetails, MessageStructure } from "./common";
2
+ export interface ChannelIdentifier {
3
+ agentId?: string;
4
+ channelName?: string;
5
+ error?: string;
6
+ }
7
+ export interface Agent {
8
+ id: string;
9
+ organisation: string;
10
+ name: string;
11
+ display_name: string;
12
+ archived: boolean;
13
+ group: string;
14
+ fa_icon: string;
15
+ type: "device" | "dashboard";
16
+ fixed_location: {
17
+ latitude: number;
18
+ longitude: number;
19
+ };
20
+ extra_config: Record<string, unknown>;
21
+ connection_determination?: "Online" | "Offline";
22
+ }
23
+ export interface User {
24
+ id: string;
25
+ email?: string;
26
+ name?: string;
27
+ [key: string]: unknown;
28
+ }
29
+ export interface AgentsResponse {
30
+ agents?: Agent[];
31
+ results?: Agent[];
32
+ count?: number;
33
+ [key: string]: unknown;
34
+ }
35
+ export interface SubscriptionDetails {
36
+ channel: {
37
+ agent_id: string;
38
+ name: string;
39
+ };
40
+ connection_id: string;
41
+ subscribed_at: number;
42
+ }
43
+ export interface ChannelsDataProvider<TIdentifier extends ChannelIdentifier = ChannelIdentifier> {
44
+ getMe: () => Promise<User>;
45
+ getAgents: () => Promise<AgentsResponse>;
46
+ getChannels: (identifier: TIdentifier, options?: {
47
+ includeArchived?: boolean;
48
+ }) => Promise<Channel[] | undefined>;
49
+ createChannel: (identifier: TIdentifier, channelName: string, options?: {
50
+ is_private?: boolean;
51
+ }) => Promise<unknown>;
52
+ archiveChannel: (identifier: TIdentifier) => Promise<unknown>;
53
+ unarchiveChannel: (identifier: TIdentifier) => Promise<unknown>;
54
+ getChannel: (identifier: TIdentifier) => Promise<Channel | undefined>;
55
+ subscribeToChannel: (identifier: TIdentifier, callback: (identifier: ChannelIdentifier, message: MessageStructure) => void, aggregateCallback: (identifier: ChannelIdentifier, aggregate: Aggregate) => void) => Promise<void | undefined>;
56
+ unsubscribeFromChannel: (identifier: TIdentifier, callback: (identifier: ChannelIdentifier, message: MessageStructure) => void) => Promise<void | undefined>;
57
+ getAggregate: (identifier: TIdentifier) => Promise<Aggregate | undefined>;
58
+ getMessages: (identifier: TIdentifier, beforeId?: string) => Promise<MessageStructure[] | undefined>;
59
+ deleteMessage: (identifier: TIdentifier, messageId: string) => Promise<unknown>;
60
+ sendMessage: (identifier: TIdentifier, message: object) => Promise<MessageStructure>;
61
+ updateAggregate: (identifier: TIdentifier, message: object) => Promise<Aggregate>;
62
+ putAggregate: (identifier: TIdentifier, message: object) => Promise<Aggregate>;
63
+ getChannelSubscriptions: (identifier: TIdentifier) => Promise<SubscriptionDetails[]>;
64
+ getAgentConnections: (identifier: TIdentifier) => Promise<ConnectionDetails[]>;
65
+ getIdentifierFromPath: (path: string, searchParams: URLSearchParams) => {
66
+ identifier: TIdentifier;
67
+ aggregatePath?: string;
68
+ };
69
+ getAgentInfo: (agentId: string) => Promise<Agent | undefined>;
70
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ export declare function generateSnowflakeIdAtTime(time: {
2
+ valueOf(): number;
3
+ }): string;
4
+ export declare function extractSnowflakeId(id: string): {
5
+ timestamp: number;
6
+ machineId: number;
7
+ sequence: number;
8
+ };
9
+ export declare function addTimestampToMessage<T extends {
10
+ id: string;
11
+ }>(message: T): T & {
12
+ timestamp: number;
13
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSnowflakeIdAtTime = generateSnowflakeIdAtTime;
4
+ exports.extractSnowflakeId = extractSnowflakeId;
5
+ exports.addTimestampToMessage = addTimestampToMessage;
6
+ function generateSnowflakeIdAtTime(time) {
7
+ const offset = 1735689600000;
8
+ const bigTime = BigInt(time.valueOf() - offset);
9
+ const bigId = bigTime << 22n;
10
+ return bigId.toString();
11
+ }
12
+ function extractSnowflakeId(id) {
13
+ const offset = 1735689600000n;
14
+ return {
15
+ timestamp: Number((BigInt(id) >> 22n) + offset),
16
+ machineId: Number((BigInt(id) >> 12n) & 1023n),
17
+ sequence: Number(BigInt(id) & 4095n),
18
+ };
19
+ }
20
+ function addTimestampToMessage(message) {
21
+ const extracted = extractSnowflakeId(message.id);
22
+ return {
23
+ ...message,
24
+ timestamp: extracted.timestamp / 1000,
25
+ };
26
+ }
@@ -0,0 +1,55 @@
1
+ import { AgentsApi } from "../apis/agents-api";
2
+ import { AggregatesApi } from "../apis/aggregates-api";
3
+ import { ChannelsApi } from "../apis/channels-api";
4
+ import { ConnectionsApi } from "../apis/connections-api";
5
+ import { MessagesApi } from "../apis/messages-api";
6
+ import { GatewayClient } from "../gateway/gateway-client";
7
+ import { RestClient, type DooverClientConfig } from "../http/rest-client";
8
+ import type { Aggregate, Channel, ConnectionDetails, MessageStructure } from "../types/common";
9
+ import type { Agent, AgentsResponse, ChannelIdentifier, ChannelsDataProvider, SubscriptionDetails, User } from "../types/viewer";
10
+ interface SubscriptionEntry {
11
+ messageCallback: (identifier: ChannelIdentifier, message: MessageStructure) => void;
12
+ aggregateCallback: (identifier: ChannelIdentifier, aggregate: Aggregate) => void;
13
+ }
14
+ export declare class DooverDataProvider implements ChannelsDataProvider<ChannelIdentifier> {
15
+ private readonly config;
16
+ readonly rest: RestClient;
17
+ readonly gateway: GatewayClient;
18
+ readonly agentsApi: AgentsApi;
19
+ readonly channelsApi: ChannelsApi;
20
+ readonly messagesApi: MessagesApi;
21
+ readonly aggregatesApi: AggregatesApi;
22
+ readonly connectionsApi: ConnectionsApi;
23
+ private readonly subscriptions;
24
+ constructor(config: DooverClientConfig);
25
+ getMe(): Promise<User>;
26
+ getAgents(): Promise<AgentsResponse>;
27
+ getChannels(identifier: ChannelIdentifier, options?: {
28
+ includeArchived?: boolean;
29
+ }): Promise<Channel[] | undefined>;
30
+ createChannel(identifier: ChannelIdentifier, channelName: string, options?: {
31
+ is_private?: boolean;
32
+ }): Promise<unknown>;
33
+ archiveChannel(identifier: ChannelIdentifier): Promise<unknown>;
34
+ unarchiveChannel(identifier: ChannelIdentifier): Promise<unknown>;
35
+ getChannel(identifier: ChannelIdentifier): Promise<Channel | undefined>;
36
+ subscribeToChannel(identifier: ChannelIdentifier, callback: SubscriptionEntry["messageCallback"], aggregateCallback: SubscriptionEntry["aggregateCallback"]): Promise<void>;
37
+ unsubscribeFromChannel(identifier: ChannelIdentifier, callback: SubscriptionEntry["messageCallback"]): Promise<void>;
38
+ getAggregate(identifier: ChannelIdentifier): Promise<Aggregate | undefined>;
39
+ getMessages(identifier: ChannelIdentifier, beforeId?: string): Promise<MessageStructure[] | undefined>;
40
+ deleteMessage(identifier: ChannelIdentifier, messageId: string): Promise<unknown>;
41
+ sendMessage(identifier: ChannelIdentifier, message: object): Promise<MessageStructure>;
42
+ updateAggregate(identifier: ChannelIdentifier, message: object): Promise<Aggregate>;
43
+ putAggregate(identifier: ChannelIdentifier, message: object): Promise<Aggregate>;
44
+ getChannelSubscriptions(identifier: ChannelIdentifier): Promise<SubscriptionDetails[]>;
45
+ getAgentConnections(identifier: ChannelIdentifier): Promise<ConnectionDetails[]>;
46
+ getIdentifierFromPath(path: string, searchParams: URLSearchParams): {
47
+ identifier: ChannelIdentifier;
48
+ aggregatePath?: string;
49
+ };
50
+ getAgentInfo(agentId: string): Promise<Agent | undefined>;
51
+ private requireChannel;
52
+ private channelKey;
53
+ private toIdentifier;
54
+ }
55
+ export {};