UNPKG

rhombus-node-mcp

Version:
207 lines (206 loc) 7.96 kB
import z from "zod"; import { postApi, throwIfApiError } from "../network/network.js"; import createUuidMap from "../network/postApiMap.js"; import { getAccessControlledDoors } from "./get-entity-tool-api.js"; export const DateRangeFilter = z.object({ localStartDateRangeStart: z.iso.datetime({ offset: true }).optional(), localStartDateRangeEnd: z.iso.datetime({ offset: true }).optional(), localEndDateRangeStart: z.iso.datetime({ offset: true }).optional(), localEndDateRangeEnd: z.iso.datetime({ offset: true }).optional(), }); function mapException(exception) { const doorUuids = exception?.doorUuids?.filter((value) => value !== null) ?? []; const intervalCount = Array.isArray(exception?.intervals) ? exception.intervals.length : 0; return { uuid: exception?.uuid ?? undefined, name: exception?.name ?? undefined, description: exception?.description ?? undefined, locationUuid: exception?.locationUuid ?? undefined, localStartDate: exception?.localStartDate ?? undefined, localEndDate: exception?.localEndDate ?? undefined, defaultState: exception?.defaultState ?? undefined, doorUuids, intervalCount, createdAtMillis: exception?.createdAtMillis ?? undefined, updatedAtMillis: exception?.updatedAtMillis ?? undefined, }; } function buildDateRangeFilter(filter) { if (!filter) return undefined; const { localStartDateRangeStart, localStartDateRangeEnd, localEndDateRangeStart, localEndDateRangeEnd, } = filter; const hasAnyFilter = Boolean(localStartDateRangeStart || localStartDateRangeEnd || localEndDateRangeStart || localEndDateRangeEnd); if (!hasAnyFilter) return undefined; return { localStartDateRangeStart, localStartDateRangeEnd, localEndDateRangeStart, localEndDateRangeEnd, }; } async function verifyExceptionConfig(exception, options, requestModifiers, sessionId) { const verified = { ...exception, }; const doorUuidsProvided = Array.isArray(exception.doorUuids); const cleanedDoorUuids = doorUuidsProvided ? (exception.doorUuids?.filter((doorUuid) => !!doorUuid) ?? []) : undefined; if (cleanedDoorUuids !== undefined) { verified.doorUuids = cleanedDoorUuids; } if ((!Array.isArray(exception.intervals) || exception.intervals.length === 0) && exception.defaultState && exception.localStartDate && exception.localEndDate) { verified.intervals = [ { localStartDateTime: `${exception.localStartDate}T00:00:00`, localEndDateTime: `${exception.localEndDate}T23:59:59`, state: exception.defaultState, }, ]; } // construct locationToDoorsMap only when doors are explicitly provided. // For update, omitting doorUuids should preserve the existing map. if (cleanedDoorUuids !== undefined) { const locationToDoorsMap = {}; if (cleanedDoorUuids.length > 0) { const doors = await getAccessControlledDoors(requestModifiers, sessionId); const doorsMap = await createUuidMap(doors.accessControlledDoors ?? [], "uuid"); for (const doorUuid of cleanedDoorUuids) { const door = doorsMap.get(doorUuid); const locationUuid = door?.locationUuid; if (locationUuid) { if (!locationToDoorsMap[locationUuid]) { locationToDoorsMap[locationUuid] = []; } locationToDoorsMap[locationUuid].push(doorUuid); } } } verified.locationToDoorsMap = locationToDoorsMap; } else if (!options.isUpdate) { verified.locationToDoorsMap = {}; } return verified; } export async function createDoorScheduleException(exception, requestModifiers, sessionId) { const normalizedException = await verifyExceptionConfig(exception, { isUpdate: false }, requestModifiers, sessionId); const res = await postApi({ route: "/accesscontrol/doorScheduleException/createExceptionV2", body: { exception: normalizedException, }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exception: res.exception ? mapException(res.exception) : undefined, warningMsg: res.warningMsg ?? undefined, }; } export async function updateDoorScheduleException(exception, requestModifiers, sessionId) { const normalizedException = await verifyExceptionConfig(exception, { isUpdate: true }, requestModifiers, sessionId); const res = await postApi({ route: "/accesscontrol/doorScheduleException/updateExceptionV2", body: { exception: normalizedException, }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exception: res.exception ? mapException(res.exception) : undefined, expiredACDLicensesDoorUuids: res.expiredACDLicensesDoorUuids?.filter((value) => value !== null) ?? [], unassignedACDLicensesDoorUuids: res.unassignedACDLicensesDoorUuids?.filter((value) => value !== null) ?? [], warningMsg: res.warningMsg ?? undefined, }; } export async function deleteDoorScheduleException(exceptionUuid, requestModifiers, sessionId) { const res = await postApi({ route: "/accesscontrol/doorScheduleException/deleteExceptionV2", body: { exceptionUuid, }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { deleted: { success: true, exceptionUuid }, warningMsg: res.warningMsg ?? undefined, }; } export async function getDoorScheduleException(exceptionUuid, requestModifiers, sessionId) { const res = await postApi({ route: "/accesscontrol/doorScheduleException/getExceptionV2", body: { exceptionUuid, }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exception: res.exception ? mapException(res.exception) : undefined, warningMsg: res.warningMsg ?? undefined, }; } export async function findDoorScheduleExceptions(filter, requestModifiers, sessionId) { const res = await postApi({ route: "/accesscontrol/doorScheduleException/findExceptionsV2", body: { dateRangeFilter: buildDateRangeFilter(filter), }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exceptions: res.exceptions?.map(mapException) ?? [], warningMsg: res.warningMsg ?? undefined, }; } export async function findDoorScheduleExceptionsForLocation(locationUuid, filter, requestModifiers, sessionId) { const res = await postApi({ route: "/accesscontrol/doorScheduleException/findExceptionsForLocationV2", body: { locationUuid, dateRangeFilter: buildDateRangeFilter(filter), }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exceptions: res.exceptions?.map(mapException) ?? [], warningMsg: res.warningMsg ?? undefined, }; } export async function findDoorScheduleExceptionsForDoor(doorUuid, filter, requestModifiers, sessionId) { const res = await postApi({ route: "/accesscontrol/doorScheduleException/findExceptionsForDoor", body: { doorUuid, dateRangeFilter: buildDateRangeFilter(filter), }, modifiers: requestModifiers, sessionId, }); throwIfApiError(res); return { exceptions: res.exceptions?.map(mapException) ?? [], warningMsg: res.warningMsg ?? undefined, }; }