Updates to potentially resolve devicesclient.
All checks were successful
Deploy Frontend / deploy (push) Successful in 24s
All checks were successful
Deploy Frontend / deploy (push) Successful in 24s
This commit is contained in:
@@ -33,16 +33,89 @@ interface InstalledApp {
|
||||
|
||||
type RawRecord = Record<string, unknown>;
|
||||
|
||||
const pick = (source: RawRecord | null | undefined, keys: string[]): unknown => {
|
||||
const normalizeKey = (key: string): string =>
|
||||
key.toLowerCase().replace(/[^a-z0-9]/g, '');
|
||||
|
||||
const getDirectValue = (source: RawRecord | null | undefined, keys: string[]): unknown => {
|
||||
if (!source) return undefined;
|
||||
for (const key of keys) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
return source[key];
|
||||
const value = source[key];
|
||||
if (value !== undefined && value !== null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const findValueDeep = (
|
||||
source: unknown,
|
||||
normalizedTargets: string[],
|
||||
seen = new WeakSet<object>()
|
||||
): unknown => {
|
||||
if (!source || typeof source !== 'object') return undefined;
|
||||
|
||||
const stack: unknown[] = [source];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const current = stack.pop();
|
||||
if (!current || typeof current !== 'object') continue;
|
||||
|
||||
if (seen.has(current as object)) continue;
|
||||
seen.add(current as object);
|
||||
|
||||
if (Array.isArray(current)) {
|
||||
for (const item of current) {
|
||||
if (item && (typeof item === 'object' || typeof item === 'string')) {
|
||||
stack.push(item);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(current as RawRecord)) {
|
||||
const normalizedKey = normalizeKey(key);
|
||||
if (normalizedTargets.includes(normalizedKey) && value !== undefined && value !== null) {
|
||||
return value;
|
||||
}
|
||||
if (value && typeof value === 'object') {
|
||||
stack.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const resolveValue = (
|
||||
source: RawRecord | null | undefined,
|
||||
keys: string[],
|
||||
fallbackKeys: string[] = keys
|
||||
): unknown => {
|
||||
if (!source) return undefined;
|
||||
|
||||
const direct = getDirectValue(source, keys);
|
||||
if (direct !== undefined && direct !== null) {
|
||||
return direct;
|
||||
}
|
||||
|
||||
const normalizedTargets = Array.from(new Set(fallbackKeys.map(normalizeKey))).filter(Boolean);
|
||||
return findValueDeep(source, normalizedTargets);
|
||||
};
|
||||
|
||||
const resolveArray = <T = unknown>(
|
||||
source: RawRecord | null | undefined,
|
||||
keys: string[],
|
||||
fallbackKeys?: string[]
|
||||
): T[] | undefined => {
|
||||
const value = resolveValue(source, keys, fallbackKeys ?? keys);
|
||||
if (Array.isArray(value)) {
|
||||
return value as T[];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const toOptionalString = (value: unknown): string | undefined => {
|
||||
if (value === null || value === undefined) return undefined;
|
||||
if (typeof value === 'string') return value;
|
||||
@@ -94,33 +167,71 @@ const normalizeDrive = (driveInput: unknown, index: number): DriveInfo | null =>
|
||||
const drive = driveInput as RawRecord;
|
||||
|
||||
const name = toNonEmptyString(
|
||||
pick(drive, ['name', 'driveName', 'label', 'volume']) ?? `Drive ${index + 1}`,
|
||||
resolveValue(drive, ['name', 'driveName', 'label', 'volume'], [
|
||||
'name',
|
||||
'driveName',
|
||||
'label',
|
||||
'volume',
|
||||
'drive_letter',
|
||||
'driveletter',
|
||||
'mount_point',
|
||||
'mountpoint',
|
||||
'logicaldisk',
|
||||
'deviceid',
|
||||
]) ?? `Drive ${index + 1}`,
|
||||
`Drive ${index + 1}`
|
||||
);
|
||||
const driveType = toNonEmptyString(pick(drive, ['driveType', 'drive_type', 'type']), 'Unknown');
|
||||
const driveType = toNonEmptyString(
|
||||
resolveValue(drive, ['driveType', 'drive_type', 'type'], [
|
||||
'driveType',
|
||||
'drive_type',
|
||||
'type',
|
||||
'drivetype',
|
||||
'mediatype',
|
||||
'busType',
|
||||
]),
|
||||
'Unknown'
|
||||
);
|
||||
const totalSizeGB = parseSizeToGB(
|
||||
pick(drive, [
|
||||
'totalSizeGB',
|
||||
'total_size_gb',
|
||||
'totalSize',
|
||||
'total_size',
|
||||
'size',
|
||||
'capacity',
|
||||
'totalBytes',
|
||||
'total_bytes',
|
||||
])
|
||||
resolveValue(
|
||||
drive,
|
||||
['totalSizeGB', 'total_size_gb', 'totalSize', 'total_size', 'size', 'capacity', 'totalBytes', 'total_bytes'],
|
||||
[
|
||||
'totalSizeGB',
|
||||
'total_size_gb',
|
||||
'totalSize',
|
||||
'total_size',
|
||||
'size',
|
||||
'capacity',
|
||||
'totalBytes',
|
||||
'total_bytes',
|
||||
'size_bytes',
|
||||
'capacity_bytes',
|
||||
'totalsize',
|
||||
'totalspace',
|
||||
'totalspacebytes',
|
||||
]
|
||||
)
|
||||
);
|
||||
const freeSpaceGB = parseSizeToGB(
|
||||
pick(drive, [
|
||||
'freeSpaceGB',
|
||||
'free_space_gb',
|
||||
'freeSpace',
|
||||
'free_space',
|
||||
'free',
|
||||
'freeBytes',
|
||||
'free_bytes',
|
||||
'availableBytes',
|
||||
])
|
||||
resolveValue(
|
||||
drive,
|
||||
['freeSpaceGB', 'free_space_gb', 'freeSpace', 'free_space', 'free', 'freeBytes', 'free_bytes', 'availableBytes'],
|
||||
[
|
||||
'freeSpaceGB',
|
||||
'free_space_gb',
|
||||
'freeSpace',
|
||||
'free_space',
|
||||
'free',
|
||||
'freeBytes',
|
||||
'free_bytes',
|
||||
'availableBytes',
|
||||
'available_bytes',
|
||||
'freespace',
|
||||
'freespacebytes',
|
||||
'remaining',
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
if (!name && !totalSizeGB && !freeSpaceGB) return null;
|
||||
@@ -138,12 +249,17 @@ const extractDrives = (rawInput: unknown): DriveInfo[] => {
|
||||
const raw = rawInput as RawRecord;
|
||||
|
||||
const potentialArrays = [
|
||||
pick(raw, ['drives']),
|
||||
pick(raw, ['driveInfo']),
|
||||
pick(raw, ['drive_info']),
|
||||
pick(raw, ['storageDevices']),
|
||||
pick(raw, ['drive_details']),
|
||||
pick(raw, ['storage']),
|
||||
resolveArray(raw, ['drives']),
|
||||
resolveArray(raw, ['driveInfo']),
|
||||
resolveArray(raw, ['drive_info']),
|
||||
resolveArray(raw, ['storageDevices']),
|
||||
resolveArray(raw, ['drive_details']),
|
||||
resolveArray(raw, ['storage']),
|
||||
resolveArray(raw, ['logicalDrives']),
|
||||
resolveArray(raw, ['logical_drives']),
|
||||
resolveArray(raw, ['volumes']),
|
||||
resolveArray(raw, ['volume_info']),
|
||||
resolveArray(raw, ['disks']),
|
||||
];
|
||||
|
||||
for (const candidate of potentialArrays) {
|
||||
@@ -155,8 +271,26 @@ const extractDrives = (rawInput: unknown): DriveInfo[] => {
|
||||
}
|
||||
|
||||
const aggregatedDrive = {
|
||||
totalSize: pick(raw, ['total_disk_space', 'totalDiskSpace', 'total_storage']),
|
||||
freeSpace: pick(raw, ['free_disk_space', 'freeDiskSpace', 'available_storage']),
|
||||
totalSize: resolveValue(raw, ['total_disk_space', 'totalDiskSpace', 'total_storage'], [
|
||||
'total_disk_space',
|
||||
'totalDiskSpace',
|
||||
'total_storage',
|
||||
'totalSpace',
|
||||
'total_space',
|
||||
'storage_total',
|
||||
'disk_total',
|
||||
]),
|
||||
freeSpace: resolveValue(raw, ['free_disk_space', 'freeDiskSpace', 'available_storage'], [
|
||||
'free_disk_space',
|
||||
'freeDiskSpace',
|
||||
'available_storage',
|
||||
'free_storage',
|
||||
'freeSpace',
|
||||
'free_space',
|
||||
'availableSpace',
|
||||
'available_space',
|
||||
'storage_free',
|
||||
]),
|
||||
};
|
||||
|
||||
if (aggregatedDrive.totalSize || aggregatedDrive.freeSpace) {
|
||||
@@ -181,19 +315,45 @@ const normalizeIpAddress = (entryInput: unknown, index: number): IpAddress | nul
|
||||
const entry = entryInput as RawRecord;
|
||||
|
||||
const ipAddress = toNonEmptyString(
|
||||
pick(entry, ['ipAddress', 'ip_address', 'address', 'ip', 'ipv4', 'ipv6']) ?? '',
|
||||
resolveValue(entry, ['ipAddress', 'ip_address', 'address', 'ip', 'ipv4', 'ipv6'], [
|
||||
'ipAddress',
|
||||
'ip_address',
|
||||
'address',
|
||||
'ip',
|
||||
'ipv4',
|
||||
'ipv6',
|
||||
'primary_ip',
|
||||
'primaryIp',
|
||||
'lan_ip',
|
||||
]) ?? '',
|
||||
''
|
||||
);
|
||||
|
||||
const interfaceName = toNonEmptyString(
|
||||
pick(entry, ['interfaceName', 'interface_name', 'adapter', 'name', 'nic']) ?? '',
|
||||
resolveValue(entry, ['interfaceName', 'interface_name', 'adapter', 'name', 'nic'], [
|
||||
'interfaceName',
|
||||
'interface_name',
|
||||
'adapter',
|
||||
'name',
|
||||
'nic',
|
||||
'network_adapter',
|
||||
'interface',
|
||||
'description',
|
||||
]) ?? '',
|
||||
ipAddress ? `Interface ${index + 1}` : ''
|
||||
);
|
||||
|
||||
if (!ipAddress && !interfaceName) return null;
|
||||
|
||||
const macAddress = toOptionalString(
|
||||
pick(entry, ['macAddress', 'mac_address', 'mac', 'physicalAddress'])
|
||||
resolveValue(entry, ['macAddress', 'mac_address', 'mac', 'physicalAddress'], [
|
||||
'macAddress',
|
||||
'mac_address',
|
||||
'mac',
|
||||
'physicalAddress',
|
||||
'physical_address',
|
||||
'hw_address',
|
||||
])
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -208,11 +368,14 @@ const extractIpAddresses = (rawInput: unknown): IpAddress[] => {
|
||||
const raw = rawInput as RawRecord;
|
||||
|
||||
const potentialArrays = [
|
||||
pick(raw, ['ipAddresses']),
|
||||
pick(raw, ['ip_addresses']),
|
||||
pick(raw, ['networkInterfaces']),
|
||||
pick(raw, ['network_interfaces']),
|
||||
pick(raw, ['interfaces']),
|
||||
resolveArray(raw, ['ipAddresses']),
|
||||
resolveArray(raw, ['ip_addresses']),
|
||||
resolveArray(raw, ['networkInterfaces']),
|
||||
resolveArray(raw, ['network_interfaces']),
|
||||
resolveArray(raw, ['interfaces']),
|
||||
resolveArray(raw, ['networkAdapters']),
|
||||
resolveArray(raw, ['network_adapters']),
|
||||
resolveArray(raw, ['network']),
|
||||
];
|
||||
|
||||
for (const candidate of potentialArrays) {
|
||||
@@ -223,14 +386,14 @@ const extractIpAddresses = (rawInput: unknown): IpAddress[] => {
|
||||
}
|
||||
}
|
||||
|
||||
const singleIp = pick(raw, ['ipAddress', 'ip_address']);
|
||||
const singleIp = resolveValue(raw, ['ipAddress', 'ip_address', 'primary_ip', 'primaryIp']);
|
||||
if (singleIp) {
|
||||
return [
|
||||
normalizeIpAddress(
|
||||
{
|
||||
ipAddress: singleIp,
|
||||
interfaceName: pick(raw, ['interfaceName', 'interface_name', 'adapter']),
|
||||
macAddress: pick(raw, ['macAddress', 'mac_address']),
|
||||
interfaceName: resolveValue(raw, ['interfaceName', 'interface_name', 'adapter']),
|
||||
macAddress: resolveValue(raw, ['macAddress', 'mac_address']),
|
||||
},
|
||||
0
|
||||
) as IpAddress,
|
||||
@@ -244,13 +407,34 @@ const normalizeInstalledApp = (appInput: unknown): InstalledApp | null => {
|
||||
if (!appInput || typeof appInput !== 'object') return null;
|
||||
const app = appInput as RawRecord;
|
||||
|
||||
const appName = toNonEmptyString(pick(app, ['app_name', 'name', 'title']) ?? '', '');
|
||||
const appName = toNonEmptyString(
|
||||
resolveValue(app, ['app_name', 'name', 'title'], [
|
||||
'app_name',
|
||||
'name',
|
||||
'title',
|
||||
'display_name',
|
||||
'product_name',
|
||||
]) ?? '',
|
||||
''
|
||||
);
|
||||
if (!appName) return null;
|
||||
|
||||
return {
|
||||
app_name: appName,
|
||||
app_version: toNonEmptyString(pick(app, ['app_version', 'version']) ?? '', ''),
|
||||
publisher: toNonEmptyString(pick(app, ['publisher', 'manufacturer', 'vendor']) ?? '', ''),
|
||||
app_version: toNonEmptyString(
|
||||
resolveValue(app, ['app_version', 'version'], ['app_version', 'version', 'display_version', 'product_version']) ?? '',
|
||||
''
|
||||
),
|
||||
publisher: toNonEmptyString(
|
||||
resolveValue(app, ['publisher', 'manufacturer', 'vendor'], [
|
||||
'publisher',
|
||||
'manufacturer',
|
||||
'vendor',
|
||||
'company',
|
||||
'publisher_name',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -259,11 +443,14 @@ const extractInstalledApps = (rawInput: unknown): InstalledApp[] => {
|
||||
const raw = rawInput as RawRecord;
|
||||
|
||||
const potentialArrays = [
|
||||
pick(raw, ['installedApplications']),
|
||||
pick(raw, ['installed_applications']),
|
||||
pick(raw, ['software']),
|
||||
pick(raw, ['applications']),
|
||||
pick(raw, ['apps']),
|
||||
resolveArray(raw, ['installedApplications']),
|
||||
resolveArray(raw, ['installed_applications']),
|
||||
resolveArray(raw, ['software']),
|
||||
resolveArray(raw, ['applications']),
|
||||
resolveArray(raw, ['apps']),
|
||||
resolveArray(raw, ['installedPrograms']),
|
||||
resolveArray(raw, ['installed_programs']),
|
||||
resolveArray(raw, ['programs']),
|
||||
];
|
||||
|
||||
for (const candidate of potentialArrays) {
|
||||
@@ -279,18 +466,32 @@ const extractInstalledApps = (rawInput: unknown): InstalledApp[] => {
|
||||
const extractMacAddresses = (rawInput: unknown, ipAddresses: IpAddress[]): MacAddress[] => {
|
||||
if (!rawInput || typeof rawInput !== 'object') return [];
|
||||
const raw = rawInput as RawRecord;
|
||||
const potentialArrays = pick(raw, ['macAddresses', 'mac_addresses']);
|
||||
const potentialArrays = resolveArray(raw, ['macAddresses', 'mac_addresses', 'macs', 'mac_list']);
|
||||
|
||||
if (Array.isArray(potentialArrays)) {
|
||||
return potentialArrays
|
||||
.map((entry, idx: number) => {
|
||||
if (!entry || typeof entry !== 'object') return null;
|
||||
const record = entry as RawRecord;
|
||||
const macAddress = toOptionalString(pick(record, ['macAddress', 'mac_address', 'mac']));
|
||||
const macAddress = toOptionalString(
|
||||
resolveValue(record, ['macAddress', 'mac_address', 'mac'], [
|
||||
'macAddress',
|
||||
'mac_address',
|
||||
'mac',
|
||||
'physicalAddress',
|
||||
'hw_address',
|
||||
])
|
||||
);
|
||||
if (!macAddress) return null;
|
||||
return {
|
||||
interfaceName: toNonEmptyString(
|
||||
pick(record, ['interfaceName', 'interface_name', 'adapter']) ?? `Interface ${idx + 1}`,
|
||||
resolveValue(record, ['interfaceName', 'interface_name', 'adapter'], [
|
||||
'interfaceName',
|
||||
'interface_name',
|
||||
'adapter',
|
||||
'network_adapter',
|
||||
'name',
|
||||
]) ?? `Interface ${idx + 1}`,
|
||||
`Interface ${idx + 1}`
|
||||
),
|
||||
macAddress: macAddress.trim(),
|
||||
@@ -329,47 +530,159 @@ const normalizeDevice = (rawInput: unknown): DetailedDevice => {
|
||||
rawInput && typeof rawInput === 'object' ? (rawInput as RawRecord) : {};
|
||||
|
||||
const deviceId = Number(
|
||||
pick(raw, ['deviceId', 'device_id', 'id', 'deviceID', 'device_id_pk']) ?? 0
|
||||
resolveValue(raw, ['deviceId', 'device_id', 'id', 'deviceID', 'device_id_pk'], [
|
||||
'deviceId',
|
||||
'device_id',
|
||||
'id',
|
||||
'deviceID',
|
||||
'device_id_pk',
|
||||
]) ?? 0
|
||||
);
|
||||
|
||||
const drives = extractDrives(raw);
|
||||
const ipAddresses = extractIpAddresses(raw);
|
||||
const macAddresses = extractMacAddresses(raw, ipAddresses);
|
||||
const clientEntry = pick(raw, ['client']);
|
||||
const clientEntry = resolveValue(raw, ['client'], ['client', 'clientInfo', 'customer']);
|
||||
const clientNameFromNested =
|
||||
clientEntry && typeof clientEntry === 'object'
|
||||
? pick(clientEntry as RawRecord, ['name'])
|
||||
? resolveValue(clientEntry as RawRecord, ['name', 'clientName', 'client_name'])
|
||||
: undefined;
|
||||
|
||||
const hostname = toNonEmptyString(
|
||||
pick(raw, ['hostname', 'hostName', 'computerName', 'deviceName']) ?? `Device ${deviceId}`,
|
||||
resolveValue(raw, ['hostname', 'hostName', 'computerName', 'deviceName'], [
|
||||
'hostname',
|
||||
'hostName',
|
||||
'computerName',
|
||||
'deviceName',
|
||||
'host',
|
||||
'machineName',
|
||||
]) ?? `Device ${deviceId}`,
|
||||
deviceId ? `Device ${deviceId}` : 'Unknown Device'
|
||||
);
|
||||
|
||||
return {
|
||||
deviceId,
|
||||
hostname,
|
||||
osName: toNonEmptyString(pick(raw, ['osName', 'os_name', 'operatingSystem', 'os']) ?? '', ''),
|
||||
osVersion: toNonEmptyString(pick(raw, ['osVersion', 'os_version', 'osVersionString']) ?? '', ''),
|
||||
windowsVersion: toNonEmptyString(pick(raw, ['windowsVersion', 'windows_version', 'osRelease']) ?? '', ''),
|
||||
windowsBuild: toNonEmptyString(pick(raw, ['windowsBuild', 'windows_build', 'buildNumber']) ?? '', ''),
|
||||
osArchitecture: toNonEmptyString(pick(raw, ['osArchitecture', 'os_architecture', 'architecture']) ?? '', ''),
|
||||
processorName: toNonEmptyString(pick(raw, ['processorName', 'processor_name', 'cpuName']) ?? '', ''),
|
||||
processorArchitecture: toNonEmptyString(
|
||||
pick(raw, ['processorArchitecture', 'processor_architecture', 'cpuArchitecture']) ?? '',
|
||||
osName: toNonEmptyString(
|
||||
resolveValue(
|
||||
raw,
|
||||
['osName', 'os_name', 'operatingSystem', 'os'],
|
||||
[
|
||||
'osName',
|
||||
'os_name',
|
||||
'operatingSystem',
|
||||
'operating_system',
|
||||
'operatingSystemName',
|
||||
'operating_system_name',
|
||||
'osFriendlyName',
|
||||
'os_caption',
|
||||
'oscaption',
|
||||
'os',
|
||||
]
|
||||
) ?? '',
|
||||
''
|
||||
),
|
||||
gpuNames: splitGpuNames(pick(raw, ['gpuNames', 'gpu_names', 'gpu_name', 'gpus'])),
|
||||
osVersion: toNonEmptyString(
|
||||
resolveValue(raw, ['osVersion', 'os_version', 'osVersionString'], [
|
||||
'osVersion',
|
||||
'os_version',
|
||||
'osVersionString',
|
||||
'operatingSystemVersion',
|
||||
'osversion',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
windowsVersion: toNonEmptyString(
|
||||
resolveValue(raw, ['windowsVersion', 'windows_version', 'osRelease'], [
|
||||
'windowsVersion',
|
||||
'windows_version',
|
||||
'osRelease',
|
||||
'windowsRelease',
|
||||
'windows_release',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
windowsBuild: toNonEmptyString(
|
||||
resolveValue(raw, ['windowsBuild', 'windows_build', 'buildNumber'], [
|
||||
'windowsBuild',
|
||||
'windows_build',
|
||||
'buildNumber',
|
||||
'build_number',
|
||||
'windowsBuildNumber',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
osArchitecture: toNonEmptyString(
|
||||
resolveValue(raw, ['osArchitecture', 'os_architecture', 'architecture'], [
|
||||
'osArchitecture',
|
||||
'os_architecture',
|
||||
'architecture',
|
||||
'platform',
|
||||
'osarch',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
processorName: toNonEmptyString(
|
||||
resolveValue(raw, ['processorName', 'processor_name', 'cpuName'], [
|
||||
'processorName',
|
||||
'processor_name',
|
||||
'cpuName',
|
||||
'cpu_name',
|
||||
'processor',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
processorArchitecture: toNonEmptyString(
|
||||
resolveValue(raw, ['processorArchitecture', 'processor_architecture', 'cpuArchitecture'], [
|
||||
'processorArchitecture',
|
||||
'processor_architecture',
|
||||
'cpuArchitecture',
|
||||
'cpu_architecture',
|
||||
'cpuArch',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
gpuNames: splitGpuNames(
|
||||
resolveValue(raw, ['gpuNames', 'gpu_names', 'gpu_name', 'gpus', 'graphics']) ?? []
|
||||
),
|
||||
totalMemory: toNonEmptyString(
|
||||
pick(raw, ['totalMemory', 'total_memory', 'memory', 'totalMemoryMb', 'totalMemoryMB']) ?? '',
|
||||
resolveValue(
|
||||
raw,
|
||||
['totalMemory', 'total_memory', 'memory', 'totalMemoryMb', 'totalMemoryMB'],
|
||||
[
|
||||
'totalMemory',
|
||||
'total_memory',
|
||||
'memory',
|
||||
'totalMemoryMb',
|
||||
'totalMemoryMB',
|
||||
'memory_total',
|
||||
'ram_total',
|
||||
'physicalMemory',
|
||||
]
|
||||
) ?? '',
|
||||
''
|
||||
),
|
||||
lastBootTime: toNonEmptyString(
|
||||
pick(raw, ['lastBootTime', 'last_boot_time', 'bootTime', 'lastBoot']) ?? '',
|
||||
resolveValue(raw, ['lastBootTime', 'last_boot_time', 'bootTime', 'lastBoot', 'lastBootUpTime'], [
|
||||
'lastBootTime',
|
||||
'last_boot_time',
|
||||
'bootTime',
|
||||
'lastBoot',
|
||||
'lastBootUpTime',
|
||||
'last_boot',
|
||||
'boot_time',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
lastCheckedIn: toNonEmptyString(
|
||||
pick(raw, ['lastCheckedIn', 'last_checked_in', 'lastSeen', 'checked_in_at']) ?? '',
|
||||
resolveValue(raw, ['lastCheckedIn', 'last_checked_in', 'lastSeen', 'checked_in_at'], [
|
||||
'lastCheckedIn',
|
||||
'last_checked_in',
|
||||
'lastSeen',
|
||||
'checked_in_at',
|
||||
'lastSeenAt',
|
||||
'last_seen',
|
||||
]) ?? '',
|
||||
''
|
||||
),
|
||||
drives,
|
||||
@@ -378,7 +691,9 @@ const normalizeDevice = (rawInput: unknown): DetailedDevice => {
|
||||
installedApplications: extractInstalledApps(raw),
|
||||
clientName:
|
||||
toOptionalString(
|
||||
pick(raw, ['clientName', 'client_name']) ?? clientNameFromNested ?? pick(raw, ['clientIdentifier'])
|
||||
resolveValue(raw, ['clientName', 'client_name'], ['clientName', 'client_name', 'client']) ??
|
||||
clientNameFromNested ??
|
||||
resolveValue(raw, ['clientIdentifier', 'client_identifier'])
|
||||
) ?? undefined,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user