@depup/systeminformation 5.31.4-depup.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.
package/lib/system.js ADDED
@@ -0,0 +1,856 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // system.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2026
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 2. System (Hardware, BIOS, Base Board)
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const fs = require('fs');
17
+ const os = require('os');
18
+ const util = require('./util');
19
+ const { uuid } = require('./osinfo');
20
+ const exec = require('child_process').exec;
21
+ const execSync = require('child_process').execSync;
22
+ const execPromise = util.promisify(require('child_process').exec);
23
+
24
+ const _platform = process.platform;
25
+
26
+ const _linux = _platform === 'linux' || _platform === 'android';
27
+ const _darwin = _platform === 'darwin';
28
+ const _windows = _platform === 'win32';
29
+ const _freebsd = _platform === 'freebsd';
30
+ const _openbsd = _platform === 'openbsd';
31
+ const _netbsd = _platform === 'netbsd';
32
+ const _sunos = _platform === 'sunos';
33
+
34
+ function system(callback) {
35
+ return new Promise((resolve) => {
36
+ process.nextTick(() => {
37
+ let result = {
38
+ manufacturer: '',
39
+ model: 'Computer',
40
+ version: '',
41
+ serial: '-',
42
+ uuid: '-',
43
+ sku: '-',
44
+ virtual: false
45
+ };
46
+
47
+ if (_linux || _freebsd || _openbsd || _netbsd) {
48
+ exec('export LC_ALL=C; dmidecode -t system 2>/dev/null; unset LC_ALL', (error, stdout) => {
49
+ let lines = stdout.toString().split('\n');
50
+ result.manufacturer = cleanDefaults(util.getValue(lines, 'manufacturer'));
51
+ result.model = cleanDefaults(util.getValue(lines, 'product name'));
52
+ result.version = cleanDefaults(util.getValue(lines, 'version'));
53
+ result.serial = cleanDefaults(util.getValue(lines, 'serial number'));
54
+ result.uuid = cleanDefaults(util.getValue(lines, 'uuid')).toLowerCase();
55
+ result.sku = cleanDefaults(util.getValue(lines, 'sku number'));
56
+ // Non-Root values
57
+ const cmd = `echo -n "product_name: "; cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null; echo;
58
+ echo -n "product_serial: "; cat /sys/devices/virtual/dmi/id/product_serial 2>/dev/null; echo;
59
+ echo -n "product_uuid: "; cat /sys/devices/virtual/dmi/id/product_uuid 2>/dev/null; echo;
60
+ echo -n "product_version: "; cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null; echo;
61
+ echo -n "sys_vendor: "; cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null; echo;`;
62
+ try {
63
+ lines = execSync(cmd, util.execOptsLinux).toString().split('\n');
64
+ result.manufacturer = cleanDefaults(result.manufacturer === '' ? util.getValue(lines, 'sys_vendor') : result.manufacturer);
65
+ result.model = cleanDefaults(result.model === '' ? util.getValue(lines, 'product_name') : result.model);
66
+ result.version = cleanDefaults(result.version === '' ? util.getValue(lines, 'product_version') : result.version);
67
+ result.serial = cleanDefaults(result.serial === '' ? util.getValue(lines, 'product_serial') : result.serial);
68
+ result.uuid = cleanDefaults(result.uuid === '' ? util.getValue(lines, 'product_uuid').toLowerCase() : result.uuid);
69
+ } catch {
70
+ util.noop();
71
+ }
72
+ if (!result.serial) {
73
+ result.serial = '-';
74
+ }
75
+ if (!result.manufacturer) {
76
+ result.manufacturer = '';
77
+ }
78
+ if (!result.model) {
79
+ result.model = 'Computer';
80
+ }
81
+ if (!result.version) {
82
+ result.version = '';
83
+ }
84
+ if (!result.sku) {
85
+ result.sku = '-';
86
+ }
87
+
88
+ // detect virtual (1)
89
+ if (
90
+ result.model.toLowerCase() === 'virtualbox' ||
91
+ result.model.toLowerCase() === 'kvm' ||
92
+ result.model.toLowerCase() === 'virtual machine' ||
93
+ result.model.toLowerCase() === 'bochs' ||
94
+ result.model.toLowerCase().startsWith('vmware') ||
95
+ result.model.toLowerCase().startsWith('droplet')
96
+ ) {
97
+ result.virtual = true;
98
+ switch (result.model.toLowerCase()) {
99
+ case 'virtualbox':
100
+ result.virtualHost = 'VirtualBox';
101
+ break;
102
+ case 'vmware':
103
+ result.virtualHost = 'VMware';
104
+ break;
105
+ case 'kvm':
106
+ result.virtualHost = 'KVM';
107
+ break;
108
+ case 'bochs':
109
+ result.virtualHost = 'bochs';
110
+ break;
111
+ }
112
+ }
113
+ if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
114
+ result.virtual = true;
115
+ switch (result.manufacturer.toLowerCase()) {
116
+ case 'vmware':
117
+ result.virtualHost = 'VMware';
118
+ break;
119
+ case 'xen':
120
+ result.virtualHost = 'Xen';
121
+ break;
122
+ }
123
+ }
124
+ if (!result.virtual) {
125
+ try {
126
+ const disksById = execSync('ls -1 /dev/disk/by-id/ 2>/dev/null; pciconf -lv 2>/dev/null', util.execOptsLinux).toString();
127
+ if (disksById.indexOf('_QEMU_') >= 0 || disksById.indexOf('QEMU ') >= 0) {
128
+ result.virtual = true;
129
+ result.virtualHost = 'QEMU';
130
+ }
131
+ if (disksById.indexOf('_VBOX_') >= 0) {
132
+ result.virtual = true;
133
+ result.virtualHost = 'VirtualBox';
134
+ }
135
+ } catch {
136
+ util.noop();
137
+ }
138
+ }
139
+ if (_freebsd || _openbsd || _netbsd) {
140
+ try {
141
+ const lines = execSync('sysctl -i kern.hostuuid kern.hostid hw.model', util.execOptsLinux).toString().split('\n');
142
+ if (!result.uuid) {
143
+ result.uuid = util.getValue(lines, 'kern.hostuuid', ':').toLowerCase();
144
+ }
145
+ if (!result.serial || result.serial === '-') {
146
+ result.serial = util.getValue(lines, 'kern.hostid', ':').toLowerCase();
147
+ }
148
+ if (!result.model || result.model === 'Computer') {
149
+ result.model = util.getValue(lines, 'hw.model', ':').trim();
150
+ }
151
+ } catch {
152
+ util.noop();
153
+ }
154
+ }
155
+ if (!result.virtual && (os.release().toLowerCase().indexOf('microsoft') >= 0 || os.release().toLowerCase().endsWith('wsl2'))) {
156
+ const kernelVersion = parseFloat(os.release().toLowerCase());
157
+ result.virtual = true;
158
+ result.manufacturer = 'Microsoft';
159
+ result.model = 'WSL';
160
+ result.version = kernelVersion < 4.19 ? '1' : '2';
161
+ }
162
+ if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
163
+ try {
164
+ const procInfo = execSync('dmidecode -t 4', util.execOptsLinux);
165
+ const procLines = procInfo.toString().split('\n');
166
+ const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
167
+ switch (procManufacturer.toLowerCase()) {
168
+ case 'virtualbox':
169
+ result.virtualHost = 'VirtualBox';
170
+ break;
171
+ case 'vmware':
172
+ result.virtualHost = 'VMware';
173
+ break;
174
+ case 'kvm':
175
+ result.virtualHost = 'KVM';
176
+ break;
177
+ case 'bochs':
178
+ result.virtualHost = 'bochs';
179
+ break;
180
+ }
181
+ } catch {
182
+ util.noop();
183
+ }
184
+ }
185
+ // detect docker
186
+ if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
187
+ result.model = 'Docker Container';
188
+ }
189
+ try {
190
+ const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
191
+ // detect virtual machines
192
+ const lines = stdout.toString().split('\n');
193
+ if (lines.length > 0) {
194
+ if (result.model === 'Computer') {
195
+ result.model = 'Virtual machine';
196
+ }
197
+ result.virtual = true;
198
+ if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
199
+ result.virtualHost = 'VMware';
200
+ }
201
+ if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
202
+ result.virtualHost = 'QEMU';
203
+ }
204
+ if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
205
+ result.virtualHost = 'Xen';
206
+ }
207
+ if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
208
+ result.virtualHost = 'KVM';
209
+ }
210
+ }
211
+ } catch {
212
+ util.noop();
213
+ }
214
+
215
+ if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
216
+ // Check Raspberry Pi
217
+ fs.readFile('/proc/cpuinfo', (error, stdout) => {
218
+ if (!error) {
219
+ let lines = stdout.toString().split('\n');
220
+ result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
221
+ result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
222
+ result.serial = util.getValue(lines, 'serial', ':', true);
223
+ const model = util.getValue(lines, 'model:', ':', true);
224
+ // reference values: https://elinux.org/RPi_HardwareHistory
225
+ // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
226
+ if (util.isRaspberry(lines)) {
227
+ const rPIRevision = util.decodePiCpuinfo(lines);
228
+ result.model = rPIRevision.model;
229
+ result.version = rPIRevision.revisionCode;
230
+ result.manufacturer = 'Raspberry Pi Foundation';
231
+ result.raspberry = {
232
+ manufacturer: rPIRevision.manufacturer,
233
+ processor: rPIRevision.processor,
234
+ type: rPIRevision.type,
235
+ revision: rPIRevision.revision
236
+ };
237
+ }
238
+ }
239
+ if (callback) {
240
+ callback(result);
241
+ }
242
+ resolve(result);
243
+ });
244
+ } else {
245
+ if (callback) {
246
+ callback(result);
247
+ }
248
+ resolve(result);
249
+ }
250
+ });
251
+ }
252
+ if (_darwin) {
253
+ exec('ioreg -c IOPlatformExpertDevice -d 2', (error, stdout) => {
254
+ if (!error) {
255
+ const lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
256
+
257
+ const model = util.getAppleModel(util.getValue(lines, 'model', '=', true));
258
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
259
+ result.model = model.key;
260
+ result.type = macOsChassisType(model.version);
261
+ result.version = model.version;
262
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
263
+ result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
264
+ result.sku = util.getValue(lines, 'board-id', '=', true) || util.getValue(lines, 'target-sub-type', '=', true);
265
+ }
266
+ if (callback) {
267
+ callback(result);
268
+ }
269
+ resolve(result);
270
+ });
271
+ }
272
+ if (_sunos) {
273
+ if (callback) {
274
+ callback(result);
275
+ }
276
+ resolve(result);
277
+ }
278
+ if (_windows) {
279
+ try {
280
+ util.powerShell('Get-CimInstance Win32_ComputerSystemProduct | select Name,Vendor,Version,IdentifyingNumber,UUID | fl').then((stdout, error) => {
281
+ if (!error) {
282
+ const lines = stdout.split('\r\n');
283
+ result.manufacturer = util.getValue(lines, 'vendor', ':');
284
+ result.model = util.getValue(lines, 'name', ':');
285
+ result.version = util.getValue(lines, 'version', ':');
286
+ result.serial = util.getValue(lines, 'identifyingnumber', ':');
287
+ result.uuid = util.getValue(lines, 'uuid', ':').toLowerCase();
288
+ // detect virtual (1)
289
+ const model = result.model.toLowerCase();
290
+ if (
291
+ model === 'virtualbox' ||
292
+ model === 'kvm' ||
293
+ model === 'virtual machine' ||
294
+ model === 'bochs' ||
295
+ model.startsWith('vmware') ||
296
+ model.startsWith('qemu') ||
297
+ model.startsWith('parallels')
298
+ ) {
299
+ result.virtual = true;
300
+ if (model.startsWith('virtualbox')) {
301
+ result.virtualHost = 'VirtualBox';
302
+ }
303
+ if (model.startsWith('vmware')) {
304
+ result.virtualHost = 'VMware';
305
+ }
306
+ if (model.startsWith('kvm')) {
307
+ result.virtualHost = 'KVM';
308
+ }
309
+ if (model.startsWith('bochs')) {
310
+ result.virtualHost = 'bochs';
311
+ }
312
+ if (model.startsWith('qemu')) {
313
+ result.virtualHost = 'KVM';
314
+ }
315
+ if (model.startsWith('parallels')) {
316
+ result.virtualHost = 'Parallels';
317
+ }
318
+ }
319
+ const manufacturer = result.manufacturer.toLowerCase();
320
+ if (manufacturer.startsWith('vmware') || manufacturer.startsWith('qemu') || manufacturer === 'xen' || manufacturer.startsWith('parallels')) {
321
+ result.virtual = true;
322
+ if (manufacturer.startsWith('vmware')) {
323
+ result.virtualHost = 'VMware';
324
+ }
325
+ if (manufacturer.startsWith('xen')) {
326
+ result.virtualHost = 'Xen';
327
+ }
328
+ if (manufacturer.startsWith('qemu')) {
329
+ result.virtualHost = 'KVM';
330
+ }
331
+ if (manufacturer.startsWith('parallels')) {
332
+ result.virtualHost = 'Parallels';
333
+ }
334
+ }
335
+ util.powerShell('Get-CimInstance MS_Systeminformation -Namespace "root/wmi" | select systemsku | fl ').then((stdout, error) => {
336
+ if (!error) {
337
+ const lines = stdout.split('\r\n');
338
+ result.sku = util.getValue(lines, 'systemsku', ':');
339
+ }
340
+ if (!result.virtual) {
341
+ util.powerShell('Get-CimInstance Win32_bios | select Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
342
+ if (!error) {
343
+ let lines = stdout.toString();
344
+ if (
345
+ lines.indexOf('VRTUAL') >= 0 ||
346
+ lines.indexOf('A M I ') >= 0 ||
347
+ lines.indexOf('VirtualBox') >= 0 ||
348
+ lines.indexOf('VMWare') >= 0 ||
349
+ lines.indexOf('Xen') >= 0 ||
350
+ lines.indexOf('Parallels') >= 0
351
+ ) {
352
+ result.virtual = true;
353
+ if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
354
+ result.virtualHost = 'VirtualBox';
355
+ }
356
+ if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
357
+ result.virtualHost = 'VMware';
358
+ }
359
+ if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
360
+ result.virtualHost = 'Xen';
361
+ }
362
+ if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
363
+ result.virtualHost = 'Hyper-V';
364
+ }
365
+ if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
366
+ result.virtualHost = 'Virtual PC';
367
+ }
368
+ if (lines.indexOf('Parallels') >= 0 && !result.virtualHost) {
369
+ result.virtualHost = 'Parallels';
370
+ }
371
+ }
372
+ if (callback) {
373
+ callback(result);
374
+ }
375
+ resolve(result);
376
+ } else {
377
+ if (callback) {
378
+ callback(result);
379
+ }
380
+ resolve(result);
381
+ }
382
+ });
383
+ } else {
384
+ if (callback) {
385
+ callback(result);
386
+ }
387
+ resolve(result);
388
+ }
389
+ });
390
+ } else {
391
+ if (callback) {
392
+ callback(result);
393
+ }
394
+ resolve(result);
395
+ }
396
+ });
397
+ } catch {
398
+ if (callback) {
399
+ callback(result);
400
+ }
401
+ resolve(result);
402
+ }
403
+ }
404
+ });
405
+ });
406
+ }
407
+
408
+ exports.system = system;
409
+
410
+ function cleanDefaults(s) {
411
+ const cmpStr = s.toLowerCase();
412
+ if (cmpStr.indexOf('o.e.m.') === -1 && cmpStr.indexOf('default string') === -1 && cmpStr !== 'default') {
413
+ return s || '';
414
+ }
415
+ return '';
416
+ }
417
+ function bios(callback) {
418
+ return new Promise((resolve) => {
419
+ process.nextTick(() => {
420
+ let result = {
421
+ vendor: '',
422
+ version: '',
423
+ releaseDate: '',
424
+ revision: ''
425
+ };
426
+ let cmd = '';
427
+ if (_linux || _freebsd || _openbsd || _netbsd) {
428
+ if (process.arch === 'arm') {
429
+ cmd = 'cat /proc/cpuinfo | grep Serial';
430
+ } else {
431
+ cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
432
+ }
433
+ exec(cmd, (error, stdout) => {
434
+ let lines = stdout.toString().split('\n');
435
+ result.vendor = util.getValue(lines, 'Vendor');
436
+ result.version = util.getValue(lines, 'Version');
437
+ let datetime = util.getValue(lines, 'Release Date');
438
+ result.releaseDate = util.parseDateTime(datetime).date;
439
+ result.revision = util.getValue(lines, 'BIOS Revision');
440
+ result.serial = util.getValue(lines, 'SerialNumber');
441
+ let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
442
+ if (language) {
443
+ result.language = language;
444
+ }
445
+ if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
446
+ const features = [];
447
+ lines.forEach((line) => {
448
+ if (line.indexOf(' is supported') >= 0) {
449
+ const feature = line.split(' is supported')[0].trim();
450
+ features.push(feature);
451
+ }
452
+ });
453
+ result.features = features;
454
+ }
455
+ // Non-Root values
456
+ const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
457
+ echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
458
+ echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
459
+ try {
460
+ lines = execSync(cmd, util.execOptsLinux).toString().split('\n');
461
+ result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
462
+ result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
463
+ datetime = util.getValue(lines, 'bios_date');
464
+ result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
465
+ } catch (e) {
466
+ util.noop();
467
+ }
468
+ if (callback) {
469
+ callback(result);
470
+ }
471
+ resolve(result);
472
+ });
473
+ }
474
+ if (_darwin) {
475
+ result.vendor = 'Apple Inc.';
476
+ exec('system_profiler SPHardwareDataType -json', (error, stdout) => {
477
+ try {
478
+ const hardwareData = JSON.parse(stdout.toString());
479
+ if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
480
+ let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
481
+ bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
482
+ result.version = bootRomVersion;
483
+ }
484
+ } catch (e) {
485
+ util.noop();
486
+ }
487
+ if (callback) {
488
+ callback(result);
489
+ }
490
+ resolve(result);
491
+ });
492
+ }
493
+ if (_sunos) {
494
+ result.vendor = 'Sun Microsystems';
495
+ if (callback) {
496
+ callback(result);
497
+ }
498
+ resolve(result);
499
+ }
500
+ if (_windows) {
501
+ try {
502
+ util
503
+ .powerShell(
504
+ 'Get-CimInstance Win32_bios | select Description,Version,Manufacturer,@{n="ReleaseDate";e={$_.ReleaseDate.ToString("yyyy-MM-dd")}},BuildNumber,SerialNumber,SMBIOSBIOSVersion | fl'
505
+ )
506
+ .then((stdout, error) => {
507
+ if (!error) {
508
+ let lines = stdout.toString().split('\r\n');
509
+ const description = util.getValue(lines, 'description', ':');
510
+ const version = util.getValue(lines, 'SMBIOSBIOSVersion', ':');
511
+ if (description.indexOf(' Version ') !== -1) {
512
+ // ... Phoenix ROM BIOS PLUS Version 1.10 A04
513
+ result.vendor = description.split(' Version ')[0].trim();
514
+ result.version = description.split(' Version ')[1].trim();
515
+ } else if (description.indexOf(' Ver: ') !== -1) {
516
+ // ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
517
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
518
+ result.version = description.split(' Ver: ')[1].trim();
519
+ } else {
520
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
521
+ result.version = version || util.getValue(lines, 'version', ':');
522
+ }
523
+ result.releaseDate = util.getValue(lines, 'releasedate', ':');
524
+ result.revision = util.getValue(lines, 'buildnumber', ':');
525
+ result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
526
+ }
527
+
528
+ if (callback) {
529
+ callback(result);
530
+ }
531
+ resolve(result);
532
+ });
533
+ } catch (e) {
534
+ if (callback) {
535
+ callback(result);
536
+ }
537
+ resolve(result);
538
+ }
539
+ }
540
+ });
541
+ });
542
+ }
543
+
544
+ exports.bios = bios;
545
+
546
+ function baseboard(callback) {
547
+ return new Promise((resolve) => {
548
+ process.nextTick(() => {
549
+ const result = {
550
+ manufacturer: '',
551
+ model: '',
552
+ version: '',
553
+ serial: '-',
554
+ assetTag: '-',
555
+ memMax: null,
556
+ memSlots: null
557
+ };
558
+ let cmd = '';
559
+ if (_linux || _freebsd || _openbsd || _netbsd) {
560
+ if (process.arch === 'arm') {
561
+ cmd = 'cat /proc/cpuinfo | grep Serial';
562
+ // 'BCM2709', 'BCM2835', 'BCM2708' -->
563
+ } else {
564
+ cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL';
565
+ }
566
+ const workload = [];
567
+ workload.push(execPromise(cmd));
568
+ workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null'));
569
+ util.promiseAll(workload).then((data) => {
570
+ let lines = data.results[0] ? data.results[0].toString().split('\n') : [''];
571
+ result.manufacturer = cleanDefaults(util.getValue(lines, 'Manufacturer'));
572
+ result.model = cleanDefaults(util.getValue(lines, 'Product Name'));
573
+ result.version = cleanDefaults(util.getValue(lines, 'Version'));
574
+ result.serial = cleanDefaults(util.getValue(lines, 'Serial Number'));
575
+ result.assetTag = cleanDefaults(util.getValue(lines, 'Asset Tag'));
576
+ // Non-Root values
577
+ const cmd = `echo -n "board_asset_tag: "; cat /sys/devices/virtual/dmi/id/board_asset_tag 2>/dev/null; echo;
578
+ echo -n "board_name: "; cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null; echo;
579
+ echo -n "board_serial: "; cat /sys/devices/virtual/dmi/id/board_serial 2>/dev/null; echo;
580
+ echo -n "board_vendor: "; cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null; echo;
581
+ echo -n "board_version: "; cat /sys/devices/virtual/dmi/id/board_version 2>/dev/null; echo;`;
582
+ try {
583
+ lines = execSync(cmd, util.execOptsLinux).toString().split('\n');
584
+ result.manufacturer = cleanDefaults(!result.manufacturer ? util.getValue(lines, 'board_vendor') : result.manufacturer);
585
+ result.model = cleanDefaults(!result.model ? util.getValue(lines, 'board_name') : result.model);
586
+ result.version = cleanDefaults(!result.version ? util.getValue(lines, 'board_version') : result.version);
587
+ result.serial = cleanDefaults(!result.serial ? util.getValue(lines, 'board_serial') : result.serial);
588
+ result.assetTag = cleanDefaults(!result.assetTag ? util.getValue(lines, 'board_asset_tag') : result.assetTag);
589
+ } catch {
590
+ util.noop();
591
+ }
592
+
593
+ // mem
594
+ lines = data.results[1] ? data.results[1].toString().split('\n') : [''];
595
+ result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null;
596
+ result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null;
597
+
598
+ // raspberry
599
+ if (util.isRaspberry()) {
600
+ const rpi = util.decodePiCpuinfo();
601
+ result.manufacturer = rpi.manufacturer;
602
+ result.model = 'Raspberry Pi';
603
+ result.serial = rpi.serial;
604
+ result.version = rpi.type + ' - ' + rpi.revision;
605
+ result.memMax = os.totalmem();
606
+ result.memSlots = 0;
607
+ }
608
+
609
+ if (callback) {
610
+ callback(result);
611
+ }
612
+ resolve(result);
613
+ });
614
+ }
615
+ if (_darwin) {
616
+ const workload = [];
617
+ workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2'));
618
+ workload.push(execPromise('system_profiler SPMemoryDataType'));
619
+ util.promiseAll(workload).then((data) => {
620
+ const lines = data.results[0] ? data.results[0].toString().replace(/[<>"]/g, '').split('\n') : [''];
621
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
622
+ result.model = util.getValue(lines, 'model', '=', true);
623
+ result.version = util.getValue(lines, 'version', '=', true);
624
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
625
+ result.assetTag = util.getValue(lines, 'board-id', '=', true);
626
+
627
+ // mem
628
+ let devices = data.results[1] ? data.results[1].toString().split(' BANK ') : [''];
629
+ if (devices.length === 1) {
630
+ devices = data.results[1] ? data.results[1].toString().split(' DIMM') : [''];
631
+ }
632
+ devices.shift();
633
+ result.memSlots = devices.length;
634
+
635
+ if (os.arch() === 'arm64') {
636
+ result.memSlots = 0;
637
+ result.memMax = os.totalmem();
638
+ }
639
+
640
+ if (callback) {
641
+ callback(result);
642
+ }
643
+ resolve(result);
644
+ });
645
+ }
646
+ if (_sunos) {
647
+ if (callback) {
648
+ callback(result);
649
+ }
650
+ resolve(result);
651
+ }
652
+ if (_windows) {
653
+ try {
654
+ const workload = [];
655
+ const win10plus = parseInt(os.release()) >= 10;
656
+ const maxCapacityAttribute = win10plus ? 'MaxCapacityEx' : 'MaxCapacity';
657
+ workload.push(util.powerShell('Get-CimInstance Win32_baseboard | select Model,Manufacturer,Product,Version,SerialNumber,PartNumber,SKU | fl'));
658
+ workload.push(util.powerShell(`Get-CimInstance Win32_physicalmemoryarray | select ${maxCapacityAttribute}, MemoryDevices | fl`));
659
+ util.promiseAll(workload).then((data) => {
660
+ let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
661
+
662
+ result.manufacturer = cleanDefaults(util.getValue(lines, 'manufacturer', ':'));
663
+ result.model = cleanDefaults(util.getValue(lines, 'model', ':'));
664
+ if (!result.model) {
665
+ result.model = cleanDefaults(util.getValue(lines, 'product', ':'));
666
+ }
667
+ result.version = cleanDefaults(util.getValue(lines, 'version', ':'));
668
+ result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
669
+ result.assetTag = cleanDefaults(util.getValue(lines, 'partnumber', ':'));
670
+ if (!result.assetTag) {
671
+ result.assetTag = cleanDefaults(util.getValue(lines, 'sku', ':'));
672
+ }
673
+
674
+ // memphysical
675
+ lines = data.results[1] ? data.results[1].toString().split('\r\n') : [''];
676
+ result.memMax = util.toInt(util.getValue(lines, maxCapacityAttribute, ':')) * (win10plus ? 1024 : 1) || null;
677
+ result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', ':')) || null;
678
+
679
+ if (callback) {
680
+ callback(result);
681
+ }
682
+ resolve(result);
683
+ });
684
+ } catch {
685
+ if (callback) {
686
+ callback(result);
687
+ }
688
+ resolve(result);
689
+ }
690
+ }
691
+ });
692
+ });
693
+ }
694
+
695
+ exports.baseboard = baseboard;
696
+
697
+ function macOsChassisType(model) {
698
+ model = model.toLowerCase();
699
+ if (model.indexOf('macbookair') >= 0 || model.indexOf('macbook air') >= 0) {
700
+ return 'Notebook';
701
+ }
702
+ if (model.indexOf('macbookpro') >= 0 || model.indexOf('macbook pro') >= 0) {
703
+ return 'Notebook';
704
+ }
705
+ if (model.indexOf('macbook') >= 0) {
706
+ return 'Notebook';
707
+ }
708
+ if (model.indexOf('macmini') >= 0 || model.indexOf('mac mini') >= 0) {
709
+ return 'Desktop';
710
+ }
711
+ if (model.indexOf('imac') >= 0) {
712
+ return 'Desktop';
713
+ }
714
+ if (model.indexOf('macstudio') >= 0 || model.indexOf('mac studio') >= 0) {
715
+ return 'Desktop';
716
+ }
717
+ if (model.indexOf('macpro') >= 0 || model.indexOf('mac pro') >= 0) {
718
+ return 'Tower';
719
+ }
720
+ return 'Other';
721
+ }
722
+
723
+ function chassis(callback) {
724
+ const chassisTypes = [
725
+ 'Other',
726
+ 'Unknown',
727
+ 'Desktop',
728
+ 'Low Profile Desktop',
729
+ 'Pizza Box',
730
+ 'Mini Tower',
731
+ 'Tower',
732
+ 'Portable',
733
+ 'Laptop',
734
+ 'Notebook',
735
+ 'Hand Held',
736
+ 'Docking Station',
737
+ 'All in One',
738
+ 'Sub Notebook',
739
+ 'Space-Saving',
740
+ 'Lunch Box',
741
+ 'Main System Chassis',
742
+ 'Expansion Chassis',
743
+ 'SubChassis',
744
+ 'Bus Expansion Chassis',
745
+ 'Peripheral Chassis',
746
+ 'Storage Chassis',
747
+ 'Rack Mount Chassis',
748
+ 'Sealed-Case PC',
749
+ 'Multi-System Chassis',
750
+ 'Compact PCI',
751
+ 'Advanced TCA',
752
+ 'Blade',
753
+ 'Blade Enclosure',
754
+ 'Tablet',
755
+ 'Convertible',
756
+ 'Detachable',
757
+ 'IoT Gateway ',
758
+ 'Embedded PC',
759
+ 'Mini PC',
760
+ 'Stick PC'
761
+ ];
762
+
763
+ return new Promise((resolve) => {
764
+ process.nextTick(() => {
765
+ let result = {
766
+ manufacturer: '',
767
+ model: '',
768
+ type: '',
769
+ version: '',
770
+ serial: '-',
771
+ assetTag: '-',
772
+ sku: ''
773
+ };
774
+ if (_linux || _freebsd || _openbsd || _netbsd) {
775
+ const cmd = `echo -n "chassis_asset_tag: "; cat /sys/devices/virtual/dmi/id/chassis_asset_tag 2>/dev/null; echo;
776
+ echo -n "chassis_serial: "; cat /sys/devices/virtual/dmi/id/chassis_serial 2>/dev/null; echo;
777
+ echo -n "chassis_type: "; cat /sys/devices/virtual/dmi/id/chassis_type 2>/dev/null; echo;
778
+ echo -n "chassis_vendor: "; cat /sys/devices/virtual/dmi/id/chassis_vendor 2>/dev/null; echo;
779
+ echo -n "chassis_version: "; cat /sys/devices/virtual/dmi/id/chassis_version 2>/dev/null; echo;`;
780
+ exec(cmd, (error, stdout) => {
781
+ let lines = stdout.toString().split('\n');
782
+ result.manufacturer = cleanDefaults(util.getValue(lines, 'chassis_vendor'));
783
+ const ctype = parseInt(util.getValue(lines, 'chassis_type').replace(/\D/g, ''));
784
+ result.type = cleanDefaults(ctype && !isNaN(ctype) && ctype < chassisTypes.length ? chassisTypes[ctype - 1] : '');
785
+ result.version = cleanDefaults(util.getValue(lines, 'chassis_version'));
786
+ result.serial = cleanDefaults(util.getValue(lines, 'chassis_serial'));
787
+ result.assetTag = cleanDefaults(util.getValue(lines, 'chassis_asset_tag'));
788
+
789
+ if (callback) {
790
+ callback(result);
791
+ }
792
+ resolve(result);
793
+ });
794
+ }
795
+ if (_darwin) {
796
+ exec('ioreg -c IOPlatformExpertDevice -d 2', (error, stdout) => {
797
+ if (!error) {
798
+ const lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
799
+ const model = util.getAppleModel(util.getValue(lines, 'model', '=', true));
800
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
801
+ result.model = model.key;
802
+ result.type = macOsChassisType(model.model);
803
+ result.version = model.version;
804
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
805
+ result.assetTag = util.getValue(lines, 'board-id', '=', true) || util.getValue(lines, 'target-type', '=', true);
806
+ result.sku = util.getValue(lines, 'target-sub-type', '=', true);
807
+ }
808
+
809
+ if (callback) {
810
+ callback(result);
811
+ }
812
+ resolve(result);
813
+ });
814
+ }
815
+ if (_sunos) {
816
+ if (callback) {
817
+ callback(result);
818
+ }
819
+ resolve(result);
820
+ }
821
+ if (_windows) {
822
+ try {
823
+ util.powerShell('Get-CimInstance Win32_SystemEnclosure | select Model,Manufacturer,ChassisTypes,Version,SerialNumber,PartNumber,SKU,SMBIOSAssetTag | fl').then((stdout, error) => {
824
+ if (!error) {
825
+ let lines = stdout.toString().split('\r\n');
826
+
827
+ result.manufacturer = cleanDefaults(util.getValue(lines, 'manufacturer', ':'));
828
+ result.model = cleanDefaults(util.getValue(lines, 'model', ':'));
829
+ const ctype = parseInt(util.getValue(lines, 'ChassisTypes', ':').replace(/\D/g, ''));
830
+ result.type = ctype && !isNaN(ctype) && ctype < chassisTypes.length ? chassisTypes[ctype - 1] : '';
831
+ result.version = cleanDefaults(util.getValue(lines, 'version', ':'));
832
+ result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
833
+ result.assetTag = cleanDefaults(util.getValue(lines, 'partnumber', ':'));
834
+ if (!result.assetTag) {
835
+ result.assetTag = cleanDefaults(util.getValue(lines, 'SMBIOSAssetTag', ':'));
836
+ }
837
+ result.sku = cleanDefaults(util.getValue(lines, 'sku', ':'));
838
+ }
839
+
840
+ if (callback) {
841
+ callback(result);
842
+ }
843
+ resolve(result);
844
+ });
845
+ } catch {
846
+ if (callback) {
847
+ callback(result);
848
+ }
849
+ resolve(result);
850
+ }
851
+ }
852
+ });
853
+ });
854
+ }
855
+
856
+ exports.chassis = chassis;