Skip to content

Commit 04ef343

Browse files
tofikwestclaude
andauthored
fix(api): inline mergeDeviceLists to fix production runtime crash (#2146)
The @trycompai/utils package exports raw TypeScript files (.ts), which works for Next.js apps that transpile on the fly, but breaks NestJS which compiles to JavaScript with tsc. Node.js cannot parse TypeScript generics (<T>) at runtime, causing SyntaxError: Unexpected token '<'. Inlined the mergeDeviceLists function directly into devices.service.ts to resolve the production crash. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 45035e9 commit 04ef343

1 file changed

Lines changed: 33 additions & 1 deletion

File tree

apps/api/src/devices/devices.service.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
11
import { Injectable, NotFoundException, Logger } from '@nestjs/common';
22
import { db } from '@trycompai/db';
3-
import { mergeDeviceLists } from '@trycompai/utils/devices';
43
import { FleetService } from '../lib/fleet.service';
54
import { DeviceResponseDto } from './dto/device-responses.dto';
65
import type { MemberResponseDto } from './dto/member-responses.dto';
76

7+
/**
8+
* Merges two device lists, deduplicating by serial number and hostname.
9+
* Priority devices (first argument) take precedence over secondary devices.
10+
*/
11+
function mergeDeviceLists<T>(
12+
priorityDevices: T[],
13+
secondaryDevices: T[],
14+
accessors: {
15+
getSerialNumber: (device: T) => string | null | undefined;
16+
getHostname: (device: T) => string | null | undefined;
17+
},
18+
): T[] {
19+
const knownSerials = new Set<string>();
20+
const knownHostnames = new Set<string>();
21+
22+
for (const device of priorityDevices) {
23+
const serial = accessors.getSerialNumber(device);
24+
const hostname = accessors.getHostname(device);
25+
if (serial) knownSerials.add(serial.toLowerCase());
26+
if (hostname) knownHostnames.add(hostname.toLowerCase());
27+
}
28+
29+
const uniqueSecondaryDevices = secondaryDevices.filter((device) => {
30+
const serial = accessors.getSerialNumber(device);
31+
const hostname = accessors.getHostname(device);
32+
if (serial && knownSerials.has(serial.toLowerCase())) return false;
33+
if (hostname && knownHostnames.has(hostname.toLowerCase())) return false;
34+
return true;
35+
});
36+
37+
return [...priorityDevices, ...uniqueSecondaryDevices];
38+
}
39+
840
/**
941
* Hybrid device service that fetches from both FleetDM and the Device Agent database.
1042
* FleetDM is the legacy system; Device Agent is the new system.

0 commit comments

Comments
 (0)