rhombus-node-mcp 0.1.23 → 0.1.26
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/dist/api/access-control-tool-api.js +1 -1
- package/dist/api/alarm-monitoring-tool-api.js +1 -1
- package/dist/api/camera-tool-api.js +1 -1
- package/dist/api/camera-uptime-tool-api.js +1 -1
- package/dist/api/clips-tool-api.js +1 -1
- package/dist/api/create-camera-policy-tool-api.js +1 -1
- package/dist/api/create-tool-api.js +1 -1
- package/dist/api/door-schedule-exception-tool-api.js +199 -0
- package/dist/api/door-tool-api.js +1 -1
- package/dist/api/entity-lookup-tool-api.js +1 -1
- package/dist/api/events-tool-api.js +1 -1
- package/dist/api/faces-tool-api.js +1 -1
- package/dist/api/get-entity-tool-api.js +12 -11
- package/dist/api/get-org-information-tool-api.js +1 -1
- package/dist/api/guest-management-tool-api.js +1 -1
- package/dist/api/location-tool-api.js +1 -1
- package/dist/api/lpr-tool-api.js +1 -1
- package/dist/api/policy-alerts-tool-api.js +1 -1
- package/dist/api/reboot-cameras-tool-api.js +1 -1
- package/dist/api/report-tool-api.js +1 -1
- package/dist/api/rules-tool-api.js +1 -1
- package/dist/api/search-tool-api.js +1 -1
- package/dist/api/update-tool-api.js +1 -1
- package/dist/api/user-access-trail-tool-api.js +1 -1
- package/dist/api/user-audit-tool-api.js +1 -1
- package/dist/api/user-tool-api.js +1 -1
- package/dist/createServer.js +1 -0
- package/dist/filtering-utils.js +15 -7
- package/dist/network/locations.js +60 -0
- package/dist/{network.js → network/network.js} +8 -3
- package/dist/network/postApiMap.js +7 -0
- package/dist/tools/analytics-tool.js +1 -1
- package/dist/tools/create-camera-policy-tool.js +1 -1
- package/dist/tools/door-schedule-exception-tool.js +113 -0
- package/dist/types/access-control-tool-types.js +1 -1
- package/dist/types/door-schedule-exception-tool-types.js +160 -0
- package/dist/types/report-tool-types.js +7 -7
- package/dist/types/user-tool-types.js +1 -1
- package/dist/types/zod-schemas.js +670 -665
- package/dist/utils/timestampInput.js +5 -8
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getLogger } from "../logger.js";
|
|
2
|
-
import { constructRequestHeaders, postApi } from "../network.js";
|
|
2
|
+
import { constructRequestHeaders, postApi } from "../network/network.js";
|
|
3
3
|
import { removeNullFields } from "../util.js";
|
|
4
4
|
const logger = getLogger("camera-tool");
|
|
5
5
|
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { postApi } from "../network.js";
|
|
1
|
+
import { postApi } from "../network/network.js";
|
|
2
2
|
function computeUptimeStats(cameraUuid, cameraName, locationUuid, windows, startTimeSec, endTimeSec) {
|
|
3
3
|
const totalPeriodSeconds = endTimeSec - startTimeSec;
|
|
4
4
|
let totalUptimeSeconds = 0;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logger } from "../logger.js";
|
|
2
|
-
import { postApi } from "../network.js";
|
|
2
|
+
import { postApi } from "../network/network.js";
|
|
3
3
|
export async function createVideoWall(options, requestModifiers, sessionId) {
|
|
4
4
|
// our grid layout settings is a little complicated. we'll dumb it down
|
|
5
5
|
// to certain presets based on length of device list
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { postApi, throwIfApiError } from "../network/network.js";
|
|
3
|
+
import createUuidMap from "../network/postApiMap.js";
|
|
4
|
+
import { getAccessControlledDoors } from "./get-entity-tool-api.js";
|
|
5
|
+
export const DateRangeFilter = z.object({
|
|
6
|
+
localStartDateRangeStart: z.iso.datetime({ offset: true }).optional(),
|
|
7
|
+
localStartDateRangeEnd: z.iso.datetime({ offset: true }).optional(),
|
|
8
|
+
localEndDateRangeStart: z.iso.datetime({ offset: true }).optional(),
|
|
9
|
+
localEndDateRangeEnd: z.iso.datetime({ offset: true }).optional(),
|
|
10
|
+
});
|
|
11
|
+
function mapException(exception) {
|
|
12
|
+
const doorUuids = exception?.doorUuids?.filter((value) => value !== null) ??
|
|
13
|
+
[];
|
|
14
|
+
const intervalCount = Array.isArray(exception?.intervals)
|
|
15
|
+
? exception.intervals.length
|
|
16
|
+
: 0;
|
|
17
|
+
return {
|
|
18
|
+
uuid: exception?.uuid ?? undefined,
|
|
19
|
+
name: exception?.name ?? undefined,
|
|
20
|
+
description: exception?.description ?? undefined,
|
|
21
|
+
locationUuid: exception?.locationUuid ?? undefined,
|
|
22
|
+
localStartDate: exception?.localStartDate ?? undefined,
|
|
23
|
+
localEndDate: exception?.localEndDate ?? undefined,
|
|
24
|
+
defaultState: exception?.defaultState ?? undefined,
|
|
25
|
+
doorUuids,
|
|
26
|
+
intervalCount,
|
|
27
|
+
createdAtMillis: exception?.createdAtMillis ?? undefined,
|
|
28
|
+
updatedAtMillis: exception?.updatedAtMillis ?? undefined,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function buildDateRangeFilter(filter) {
|
|
32
|
+
if (!filter)
|
|
33
|
+
return undefined;
|
|
34
|
+
const { localStartDateRangeStart, localStartDateRangeEnd, localEndDateRangeStart, localEndDateRangeEnd, } = filter;
|
|
35
|
+
const hasAnyFilter = Boolean(localStartDateRangeStart ||
|
|
36
|
+
localStartDateRangeEnd ||
|
|
37
|
+
localEndDateRangeStart ||
|
|
38
|
+
localEndDateRangeEnd);
|
|
39
|
+
if (!hasAnyFilter)
|
|
40
|
+
return undefined;
|
|
41
|
+
return {
|
|
42
|
+
localStartDateRangeStart,
|
|
43
|
+
localStartDateRangeEnd,
|
|
44
|
+
localEndDateRangeStart,
|
|
45
|
+
localEndDateRangeEnd,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function verifyExceptionConfig(exception, requestModifiers, sessionId) {
|
|
49
|
+
const verified = {
|
|
50
|
+
...exception,
|
|
51
|
+
};
|
|
52
|
+
const cleanedDoorUuids = (Array.isArray(exception.doorUuids)
|
|
53
|
+
? exception.doorUuids.filter((doorUuid) => !!doorUuid)
|
|
54
|
+
: []) ?? [];
|
|
55
|
+
if (cleanedDoorUuids.length > 0) {
|
|
56
|
+
verified.doorUuids = cleanedDoorUuids;
|
|
57
|
+
}
|
|
58
|
+
if ((!Array.isArray(exception.intervals) || exception.intervals.length === 0) &&
|
|
59
|
+
exception.defaultState &&
|
|
60
|
+
exception.localStartDate &&
|
|
61
|
+
exception.localEndDate) {
|
|
62
|
+
verified.intervals = [
|
|
63
|
+
{
|
|
64
|
+
localStartDateTime: `${exception.localStartDate}T00:00:00`,
|
|
65
|
+
localEndDateTime: `${exception.localEndDate}T23:59:59`,
|
|
66
|
+
state: exception.defaultState,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
// construct locationToDoorsMap
|
|
71
|
+
const locationToDoorsMap = {};
|
|
72
|
+
if (cleanedDoorUuids.length > 0) {
|
|
73
|
+
const doors = await getAccessControlledDoors(requestModifiers, sessionId);
|
|
74
|
+
const doorsMap = await createUuidMap(doors.accessControlledDoors ?? [], "uuid");
|
|
75
|
+
for (const doorUuid of cleanedDoorUuids) {
|
|
76
|
+
const door = doorsMap.get(doorUuid);
|
|
77
|
+
const locationUuid = door?.locationUuid;
|
|
78
|
+
if (locationUuid) {
|
|
79
|
+
if (!locationToDoorsMap[locationUuid]) {
|
|
80
|
+
locationToDoorsMap[locationUuid] = [];
|
|
81
|
+
}
|
|
82
|
+
locationToDoorsMap[locationUuid].push(doorUuid);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
verified.locationToDoorsMap = locationToDoorsMap;
|
|
87
|
+
return verified;
|
|
88
|
+
}
|
|
89
|
+
export async function createDoorScheduleException(exception, requestModifiers, sessionId) {
|
|
90
|
+
const normalizedException = await verifyExceptionConfig(exception, requestModifiers, sessionId);
|
|
91
|
+
const res = await postApi({
|
|
92
|
+
route: "/accesscontrol/doorScheduleException/createExceptionV2",
|
|
93
|
+
body: {
|
|
94
|
+
exception: normalizedException,
|
|
95
|
+
},
|
|
96
|
+
modifiers: requestModifiers,
|
|
97
|
+
sessionId,
|
|
98
|
+
});
|
|
99
|
+
throwIfApiError(res);
|
|
100
|
+
return {
|
|
101
|
+
exception: res.exception ? mapException(res.exception) : undefined,
|
|
102
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export async function updateDoorScheduleException(exception, requestModifiers, sessionId) {
|
|
106
|
+
const normalizedException = await verifyExceptionConfig(exception, requestModifiers, sessionId);
|
|
107
|
+
const res = await postApi({
|
|
108
|
+
route: "/accesscontrol/doorScheduleException/updateExceptionV2",
|
|
109
|
+
body: {
|
|
110
|
+
exception: normalizedException,
|
|
111
|
+
},
|
|
112
|
+
modifiers: requestModifiers,
|
|
113
|
+
sessionId,
|
|
114
|
+
});
|
|
115
|
+
throwIfApiError(res);
|
|
116
|
+
return {
|
|
117
|
+
exception: res.exception ? mapException(res.exception) : undefined,
|
|
118
|
+
expiredACDLicensesDoorUuids: res.expiredACDLicensesDoorUuids?.filter((value) => value !== null) ?? [],
|
|
119
|
+
unassignedACDLicensesDoorUuids: res.unassignedACDLicensesDoorUuids?.filter((value) => value !== null) ?? [],
|
|
120
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export async function deleteDoorScheduleException(exceptionUuid, requestModifiers, sessionId) {
|
|
124
|
+
const res = await postApi({
|
|
125
|
+
route: "/accesscontrol/doorScheduleException/deleteExceptionV2",
|
|
126
|
+
body: {
|
|
127
|
+
exceptionUuid,
|
|
128
|
+
},
|
|
129
|
+
modifiers: requestModifiers,
|
|
130
|
+
sessionId,
|
|
131
|
+
});
|
|
132
|
+
throwIfApiError(res);
|
|
133
|
+
return {
|
|
134
|
+
deleted: { success: true, exceptionUuid },
|
|
135
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export async function getDoorScheduleException(exceptionUuid, requestModifiers, sessionId) {
|
|
139
|
+
const res = await postApi({
|
|
140
|
+
route: "/accesscontrol/doorScheduleException/getExceptionV2",
|
|
141
|
+
body: {
|
|
142
|
+
exceptionUuid,
|
|
143
|
+
},
|
|
144
|
+
modifiers: requestModifiers,
|
|
145
|
+
sessionId,
|
|
146
|
+
});
|
|
147
|
+
throwIfApiError(res);
|
|
148
|
+
return {
|
|
149
|
+
exception: res.exception ? mapException(res.exception) : undefined,
|
|
150
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function findDoorScheduleExceptions(filter, requestModifiers, sessionId) {
|
|
154
|
+
const res = await postApi({
|
|
155
|
+
route: "/accesscontrol/doorScheduleException/findExceptionsV2",
|
|
156
|
+
body: {
|
|
157
|
+
dateRangeFilter: buildDateRangeFilter(filter),
|
|
158
|
+
},
|
|
159
|
+
modifiers: requestModifiers,
|
|
160
|
+
sessionId,
|
|
161
|
+
});
|
|
162
|
+
throwIfApiError(res);
|
|
163
|
+
return {
|
|
164
|
+
exceptions: res.exceptions?.map(mapException) ?? [],
|
|
165
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export async function findDoorScheduleExceptionsForLocation(locationUuid, filter, requestModifiers, sessionId) {
|
|
169
|
+
const res = await postApi({
|
|
170
|
+
route: "/accesscontrol/doorScheduleException/findExceptionsForLocationV2",
|
|
171
|
+
body: {
|
|
172
|
+
locationUuid,
|
|
173
|
+
dateRangeFilter: buildDateRangeFilter(filter),
|
|
174
|
+
},
|
|
175
|
+
modifiers: requestModifiers,
|
|
176
|
+
sessionId,
|
|
177
|
+
});
|
|
178
|
+
throwIfApiError(res);
|
|
179
|
+
return {
|
|
180
|
+
exceptions: res.exceptions?.map(mapException) ?? [],
|
|
181
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
export async function findDoorScheduleExceptionsForDoor(doorUuid, filter, requestModifiers, sessionId) {
|
|
185
|
+
const res = await postApi({
|
|
186
|
+
route: "/accesscontrol/doorScheduleException/findExceptionsForDoor",
|
|
187
|
+
body: {
|
|
188
|
+
doorUuid,
|
|
189
|
+
dateRangeFilter: buildDateRangeFilter(filter),
|
|
190
|
+
},
|
|
191
|
+
modifiers: requestModifiers,
|
|
192
|
+
sessionId,
|
|
193
|
+
});
|
|
194
|
+
throwIfApiError(res);
|
|
195
|
+
return {
|
|
196
|
+
exceptions: res.exceptions?.map(mapException) ?? [],
|
|
197
|
+
warningMsg: res.warningMsg ?? undefined,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { postApi } from "../network.js";
|
|
1
|
+
import { postApi } from "../network/network.js";
|
|
2
2
|
import { getAccessControlledDoors, getAudioGateways, getBadgeReaders, getButtons, getCameraList, getDoorbellCameras, getDoorSensors, getEnvironmentalGateways, getEnvironmentalSensors, getKeypads, getMotionSensors, } from "./get-entity-tool-api.js";
|
|
3
3
|
async function getDeviceFeatures(deviceUuid, requestModifiers, sessionId) {
|
|
4
4
|
const response = await postApi({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
2
|
import { FIVE_SECONDS_MS, THREE_HOURS_MS } from "../constants.js";
|
|
3
|
-
import { postApi } from "../network.js";
|
|
3
|
+
import { postApi } from "../network/network.js";
|
|
4
4
|
import { formatTimestamp } from "../util.js";
|
|
5
5
|
import { tempFunc, TempUnit } from "../utils/temp.js";
|
|
6
6
|
// Type definitions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { postApi } from "../network.js";
|
|
1
|
+
import { postApi } from "../network/network.js";
|
|
2
2
|
import { formatTimestamp } from "../util.js";
|
|
3
3
|
import { removeNulls } from "../utils/remove-nulls.js";
|
|
4
4
|
export async function getFaceEvents(args, timeZone, requestModifiers, sessionId) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logger } from "../logger.js";
|
|
2
|
-
import { postApi } from "../network.js";
|
|
2
|
+
import { postApi } from "../network/network.js";
|
|
3
3
|
import { formatTimestamp } from "../util.js";
|
|
4
4
|
import { tempFunc } from "../utils/temp.js";
|
|
5
5
|
export async function getCameraList(requestModifiers, sessionId) {
|
|
@@ -28,7 +28,7 @@ export async function getBadgeReaders(requestModifiers, sessionId) {
|
|
|
28
28
|
body: {},
|
|
29
29
|
modifiers: requestModifiers,
|
|
30
30
|
sessionId,
|
|
31
|
-
}).then(response => {
|
|
31
|
+
}).then((response) => {
|
|
32
32
|
return {
|
|
33
33
|
badgeReaders: response.minimalStates.filter((badgeReader) => !!badgeReader.locationUuid),
|
|
34
34
|
};
|
|
@@ -40,7 +40,7 @@ export async function getAccessControlledDoors(requestModifiers, sessionId) {
|
|
|
40
40
|
body: {},
|
|
41
41
|
modifiers: requestModifiers,
|
|
42
42
|
sessionId,
|
|
43
|
-
}).then(response => {
|
|
43
|
+
}).then((response) => {
|
|
44
44
|
return {
|
|
45
45
|
accessControlledDoors: (response.accessControlledDoors || []).map((door) => {
|
|
46
46
|
return {
|
|
@@ -48,7 +48,8 @@ export async function getAccessControlledDoors(requestModifiers, sessionId) {
|
|
|
48
48
|
locationUuid: door.locationUuid,
|
|
49
49
|
policyUuid: door.policyUuid,
|
|
50
50
|
remoteUnlockEnabled: door.remoteUnlockEnabled,
|
|
51
|
-
associatedCameras: door.associatedCameras?.filter((c) => c !== null) ??
|
|
51
|
+
associatedCameras: door.associatedCameras?.filter((c) => c !== null) ??
|
|
52
|
+
[],
|
|
52
53
|
name: door.name,
|
|
53
54
|
uuid: door.uuid,
|
|
54
55
|
};
|
|
@@ -62,7 +63,7 @@ export async function getAudioGateways(timeZone, requestModifiers, sessionId) {
|
|
|
62
63
|
body: {},
|
|
63
64
|
modifiers: requestModifiers,
|
|
64
65
|
sessionId,
|
|
65
|
-
}).then(response => {
|
|
66
|
+
}).then((response) => {
|
|
66
67
|
return {
|
|
67
68
|
audioGateways: response.audioGatewayStates
|
|
68
69
|
.filter((camera) => !!camera.locationUuid)
|
|
@@ -81,7 +82,7 @@ export async function getDoorSensors(requestModifiers, sessionId) {
|
|
|
81
82
|
body: {},
|
|
82
83
|
modifiers: requestModifiers,
|
|
83
84
|
sessionId,
|
|
84
|
-
}).then(response => {
|
|
85
|
+
}).then((response) => {
|
|
85
86
|
return {
|
|
86
87
|
doorStates: response.doorStates.filter((door) => !!door.locationUuid),
|
|
87
88
|
};
|
|
@@ -93,7 +94,7 @@ export async function getEnvironmentalSensors(timeZone, tempUnit, requestModifie
|
|
|
93
94
|
body: {},
|
|
94
95
|
modifiers: requestModifiers,
|
|
95
96
|
sessionId,
|
|
96
|
-
}).then(response => {
|
|
97
|
+
}).then((response) => {
|
|
97
98
|
logger.info("Using tempUnit: ", tempUnit);
|
|
98
99
|
return {
|
|
99
100
|
climateStates: response.climateStates
|
|
@@ -117,7 +118,7 @@ export async function getMotionSensors(requestModifiers, sessionId) {
|
|
|
117
118
|
body: {},
|
|
118
119
|
modifiers: requestModifiers,
|
|
119
120
|
sessionId,
|
|
120
|
-
}).then(response => {
|
|
121
|
+
}).then((response) => {
|
|
121
122
|
return {
|
|
122
123
|
occupancySensorStates: response.occupancySensorStates.filter((occupancySensor) => !!occupancySensor.locationUuid),
|
|
123
124
|
};
|
|
@@ -129,7 +130,7 @@ export async function getButtons(timeZone, requestModifiers, sessionId) {
|
|
|
129
130
|
body: {},
|
|
130
131
|
modifiers: requestModifiers,
|
|
131
132
|
sessionId,
|
|
132
|
-
}).then(response => {
|
|
133
|
+
}).then((response) => {
|
|
133
134
|
return {
|
|
134
135
|
buttonStates: response.states
|
|
135
136
|
.filter((button) => !!button.locationUuid)
|
|
@@ -148,7 +149,7 @@ export async function getKeypads(requestModifiers, sessionId) {
|
|
|
148
149
|
body: {},
|
|
149
150
|
modifiers: requestModifiers,
|
|
150
151
|
sessionId,
|
|
151
|
-
}).then(response => {
|
|
152
|
+
}).then((response) => {
|
|
152
153
|
return {
|
|
153
154
|
keypadStates: response.keypads.filter((keypad) => !!keypad.locationUuid),
|
|
154
155
|
};
|
|
@@ -160,7 +161,7 @@ export async function getEnvironmentalGateways(timeZone, requestModifiers, sessi
|
|
|
160
161
|
body: {},
|
|
161
162
|
modifiers: requestModifiers,
|
|
162
163
|
sessionId,
|
|
163
|
-
}).then(response => {
|
|
164
|
+
}).then((response) => {
|
|
164
165
|
return {
|
|
165
166
|
minimalEnvironmentalGatewayStates: response.minimalEnvironmentalGatewayStates
|
|
166
167
|
.filter((gateway) => !!gateway.locationUuid)
|
package/dist/api/lpr-tool-api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DateTime } from "luxon";
|
|
2
2
|
import { getLogger } from "../logger.js";
|
|
3
|
-
import { postApi } from "../network.js";
|
|
3
|
+
import { postApi } from "../network/network.js";
|
|
4
4
|
import { ReportTypeEnum } from "../types/schema.js";
|
|
5
5
|
import { formatTimestamp } from "../util.js";
|
|
6
6
|
const REPORT_TYPES_THAT_RETURN_UTC = new Set([
|
package/dist/createServer.js
CHANGED
package/dist/filtering-utils.js
CHANGED
|
@@ -45,7 +45,9 @@ function filterByTrie(obj, trie) {
|
|
|
45
45
|
return obj;
|
|
46
46
|
}
|
|
47
47
|
if (Array.isArray(obj)) {
|
|
48
|
-
const mapped = obj
|
|
48
|
+
const mapped = obj
|
|
49
|
+
.map((item) => filterByTrie(item, trie))
|
|
50
|
+
.filter((item) => item !== undefined);
|
|
49
51
|
return mapped.length > 0 ? mapped : undefined;
|
|
50
52
|
}
|
|
51
53
|
if (typeof obj === "object" && obj !== null) {
|
|
@@ -180,8 +182,7 @@ export function applyFilterBy(obj, conditions) {
|
|
|
180
182
|
*/
|
|
181
183
|
export function zodToDotNotationPaths(schema, prefix = "") {
|
|
182
184
|
// Unwrap optional / nullable / default
|
|
183
|
-
if (schema instanceof z.ZodOptional ||
|
|
184
|
-
schema instanceof z.ZodNullable) {
|
|
185
|
+
if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable) {
|
|
185
186
|
return zodToDotNotationPaths(schema.unwrap(), prefix);
|
|
186
187
|
}
|
|
187
188
|
if (schema instanceof z.ZodDefault) {
|
|
@@ -248,11 +249,18 @@ function applyFilteringToResult(result, includeFields, filterBy) {
|
|
|
248
249
|
let filteredStructured = result.structuredContent;
|
|
249
250
|
if (filteredStructured) {
|
|
250
251
|
if (filterBy?.length)
|
|
251
|
-
filteredStructured =
|
|
252
|
+
filteredStructured =
|
|
253
|
+
applyFilterBy(filteredStructured, filterBy) ?? filteredStructured;
|
|
252
254
|
if (effectiveIncludeFields?.length)
|
|
253
|
-
filteredStructured =
|
|
255
|
+
filteredStructured =
|
|
256
|
+
filterIncludedFields(filteredStructured, effectiveIncludeFields) ??
|
|
257
|
+
filteredStructured;
|
|
254
258
|
}
|
|
255
|
-
return {
|
|
259
|
+
return {
|
|
260
|
+
...result,
|
|
261
|
+
content: filteredContent,
|
|
262
|
+
structuredContent: filteredStructured,
|
|
263
|
+
};
|
|
256
264
|
}
|
|
257
265
|
/**
|
|
258
266
|
* Returns a Proxy over an McpServer that intercepts every `registerTool` call to:
|
|
@@ -272,7 +280,7 @@ export function createFilteringProxy(server, blacklist = new Set()) {
|
|
|
272
280
|
return Reflect.get(target, prop, receiver);
|
|
273
281
|
}
|
|
274
282
|
// biome-ignore lint/suspicious/noExplicitAny: proxy intercept
|
|
275
|
-
return
|
|
283
|
+
return (name, config, handler) => {
|
|
276
284
|
if (blacklist.has(name)) {
|
|
277
285
|
return target.registerTool(name, config, handler);
|
|
278
286
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { postApi } from "./network.js";
|
|
2
|
+
import createUuidMap from "./postApiMap.js";
|
|
3
|
+
/**
|
|
4
|
+
* Get a list of locations from the API.
|
|
5
|
+
*
|
|
6
|
+
* @param requestModifiers
|
|
7
|
+
* @param sessionId
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export async function getLocations(requestModifiers, sessionId) {
|
|
11
|
+
const res = await postApi({
|
|
12
|
+
route: "/location/getLocationsV2",
|
|
13
|
+
body: {},
|
|
14
|
+
modifiers: requestModifiers,
|
|
15
|
+
sessionId,
|
|
16
|
+
});
|
|
17
|
+
if (res.error) {
|
|
18
|
+
throw new Error(JSON.stringify(res));
|
|
19
|
+
}
|
|
20
|
+
return res.locations ?? [];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get a map of locations by UUID from the API.
|
|
24
|
+
*
|
|
25
|
+
* @param requestModifiers
|
|
26
|
+
* @param sessionId
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
export async function getLocationsMap(requestModifiers, sessionId) {
|
|
30
|
+
const locations = await getLocations(requestModifiers, sessionId);
|
|
31
|
+
return createUuidMap(locations, "uuid");
|
|
32
|
+
}
|
|
33
|
+
export async function resolveLocationFromDoorUuids(doorUuids, requestModifiers, sessionId) {
|
|
34
|
+
if (doorUuids.length === 0)
|
|
35
|
+
return {};
|
|
36
|
+
const res = await postApi({
|
|
37
|
+
route: "/component/findAccessControlledDoors",
|
|
38
|
+
body: {},
|
|
39
|
+
modifiers: requestModifiers,
|
|
40
|
+
sessionId,
|
|
41
|
+
});
|
|
42
|
+
if (res.error) {
|
|
43
|
+
throw new Error(`Failed to resolve door locations: ${JSON.stringify(res)}`);
|
|
44
|
+
}
|
|
45
|
+
const requestedDoorUuidSet = new Set(doorUuids);
|
|
46
|
+
const locationToDoorsMap = {};
|
|
47
|
+
for (const door of res.accessControlledDoors ?? []) {
|
|
48
|
+
if (!door?.uuid || !requestedDoorUuidSet.has(door.uuid) || !door.locationUuid)
|
|
49
|
+
continue;
|
|
50
|
+
if (!locationToDoorsMap[door.locationUuid]) {
|
|
51
|
+
locationToDoorsMap[door.locationUuid] = [];
|
|
52
|
+
}
|
|
53
|
+
locationToDoorsMap[door.locationUuid].push(door.uuid);
|
|
54
|
+
}
|
|
55
|
+
const locationUuids = Object.keys(locationToDoorsMap);
|
|
56
|
+
return {
|
|
57
|
+
locationUuid: locationUuids.length === 1 ? locationUuids[0] : undefined,
|
|
58
|
+
locationToDoorsMap: locationUuids.length > 0 ? locationToDoorsMap : undefined,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { logger } from "
|
|
2
|
-
import { authStore } from "
|
|
1
|
+
import { logger } from "../logger.js";
|
|
2
|
+
import { authStore } from "../transports/streamable-http.js";
|
|
3
3
|
export const RHOMBUS_API_KEY = process.env.RHOMBUS_API_KEY;
|
|
4
4
|
export const serverUrl = process.env.RHOMBUS_API_SERVER || "api2.rhombussystems.com";
|
|
5
5
|
export const BASE_URL = `https://${serverUrl}/api`;
|
|
@@ -120,7 +120,12 @@ export async function postApi({ route, body, modifiers, sessionId, }) {
|
|
|
120
120
|
logger.error(`[POSTAPI] ERROR - ${JSON.stringify(error || {}, null, 4)}`);
|
|
121
121
|
return {
|
|
122
122
|
error: true,
|
|
123
|
-
status: `Request Error: ${error}`,
|
|
123
|
+
status: `Request Error: ${JSON.stringify(error)}`,
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
export function throwIfApiError(res) {
|
|
128
|
+
if (res.error) {
|
|
129
|
+
throw new Error(res.status ?? "API request failed.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getCountReportsForDevicesAtLocation, getRunningAverage, getLineCrossingEnabledCameras, getBatchThresholdCrossingCountReport, getSummaryCountReport, triggerScenePrompt, } from "../api/report-tool-api.js";
|
|
2
2
|
import { AnalyticsRequestType, OUTPUT_SCHEMA, TOOL_ARGS, } from "../types/analytics-tool-types.js";
|
|
3
3
|
import { createToolStructuredContent, extractFromToolExtra } from "../util.js";
|
|
4
|
-
import { postApi } from "../network.js";
|
|
4
|
+
import { postApi } from "../network/network.js";
|
|
5
5
|
import { DateTime } from "luxon";
|
|
6
6
|
const TOOL_NAME = "analytics-tool";
|
|
7
7
|
const TOOL_DESCRIPTION = `
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { createCameraPolicy } from "../api/create-camera-policy-tool-api.js";
|
|
3
3
|
import { ApiPayloadSchema, OUTPUT_SCHEMA } from "../types/create-camera-policy-tool-types.js";
|
|
4
|
-
import { postApi } from "../network.js";
|
|
4
|
+
import { postApi } from "../network/network.js";
|
|
5
5
|
const TOOL_NAME = "create-camera-policy-tool";
|
|
6
6
|
const TOOL_DESCRIPTION = `
|
|
7
7
|
A tool for creating a camera policy that walks users through a multi-step process.
|