systeminformation 5.8.8 → 5.9.2

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/CHANGELOG.md CHANGED
@@ -77,6 +77,10 @@ For major (breaking) changes - **version 4, 3 and 2** - see end of page.
77
77
 
78
78
  | Version | Date | Comment |
79
79
  | -------------- | -------------- | -------- |
80
+ | 5.9.2 | 2021-09-16 | `graohics()` (macOS), `memLayout()` (win) improvements |
81
+ | 5.9.1 | 2021-09-15 | `diskLayout()` fix size (macOS) |
82
+ | 5.9.0 | 2021-09-15 | `graphics()` new XML parser, added properties (macOS) |
83
+ | 5.8.9 | 2021-09-13 | `battery()` fix linux |
80
84
  | 5.8.8 | 2021-09-11 | `wifiConnections()`, `wifiInterfaces()`, `wifiNetworks()` fix windows |
81
85
  | 5.8.7 | 2021-09-01 | `processes()` fix alpine linux |
82
86
  | 5.8.6 | 2021-08-26 | `cpu()` improved detection (win) |
package/README.md CHANGED
@@ -95,14 +95,13 @@ si.cpu()
95
95
  .catch(error => console.error(error));
96
96
  ```
97
97
 
98
- **Callback, Promises, Async / Await**
99
-
100
98
  ## News and Changes
101
99
 
102
100
  ### Latest Activity
103
101
 
104
102
  (last 7 major and minor version releases)
105
103
 
104
+ - Version 5.9.0: `graphics()` added properties (macOS)
106
105
  - Version 5.8.0: `disksIO()` added waitTime, waitPercent (linux)
107
106
  - Version 5.7.0: `diskLayout()` added S.M.A.R.T for Windows (if installed)
108
107
  - Version 5.6.0: `cpuTemperature()` added added socket and chipset temp (linux)
@@ -288,20 +287,29 @@ Full function reference with examples can be found at [https://systeminformation
288
287
  | --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
289
288
  | si.graphics(cb) | {...} | X | | X | X | | arrays of graphics controllers and displays |
290
289
  | | controllers[]| X | | X | X | | graphics controllers array |
291
- | | ...[0].model | X | | X | X | | graphics controller model |
292
290
  | | ...[0].vendor | X | | X | X | | e.g. ATI |
293
- | | ...[0].deviceName | | | | X | | e.g. \\\\.\\DISPLAY1 |
291
+ | | ...[0].vendorId | | | X | | | vendor ID |
292
+ | | ...[0].model | X | | X | X | | graphics controller model |
293
+ | | ...[0].deviceId | | | X | | | device ID |
294
294
  | | ...[0].bus | X | | X | X | | on which bus (e.g. PCIe) |
295
295
  | | ...[0].vram | X | | X | X | | VRAM size (in MB) |
296
296
  | | ...[0].vramDynamic | X | | X | X | | true if dynamicly allocated ram |
297
+ | | ...[0].external | | | X | | | is external GPU |
298
+ | | ...[0].cores | | | X | | | Apple silicon only |
299
+ | | ...[0].metalVersion | | | X | | | Apple Metal Version |
297
300
  | | displays[] | X | | X | X | | monitor/display array |
298
301
  | | ...[0].vendor | | | | X | | monitor/display vendor |
302
+ | | ...[0].vendorId | | | X | | | vendor ID |
303
+ | | ...[0].deviceName | | | | X | | e.g. \\\\.\\DISPLAY1 |
299
304
  | | ...[0].model | X | | X | X | | monitor/display model |
305
+ | | ...[0].productionYear | | | X | | | production year |
306
+ | | ...[0].serial | | | X | | | serial number |
307
+ | | ...[0].displayId | | | X | | | display ID |
300
308
  | | ...[0].main | X | | X | X| | true if main monitor |
301
309
  | | ...[0].builtin | X | | X | | | true if built in monitor |
302
310
  | | ...[0].connection | X | | X | X | | e.g. DisplayPort or HDMI |
303
- | | ...[0].sizeX | X | | X | X | | size in mm horizontal |
304
- | | ...[0].sizeY | X | | X | X | | size in mm vertical |
311
+ | | ...[0].sizeX | X | | | X | | size in mm horizontal |
312
+ | | ...[0].sizeY | X | | | X | | size in mm vertical |
305
313
  | | ...[0].pixelDepth | X | | X | X | | color depth in bits |
306
314
  | | ...[0].resolutionX | X | | X | X | | pixel horizontal |
307
315
  | | ...[0].resolutionY | X | | X | X | | pixel vertical |
package/lib/battery.js CHANGED
@@ -114,12 +114,13 @@ module.exports = function (callback) {
114
114
  result.voltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_NOW', '='), 10) / 1000000.0;
115
115
  result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
116
116
  result.cycleCount = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CYCLE_COUNT', '='), 10);
117
- result.maxCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '='), 10) / 1000.0 * (result.voltage || 1));
118
- result.designedCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '='), 10) / 1000.0 * (result.voltage || 1));
117
+ result.maxCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '=', true, true), 10) / 1000.0 * (result.voltage || 1));
118
+ const desingedMinVoltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_MIN_DESIGN', '='), 10) / 1000000.0;
119
+ result.designedCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '=', true, true), 10) / 1000.0 * (desingedMinVoltage || result.voltage || 1));
119
120
  result.currentCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10) / 1000.0 * (result.voltage || 1));
120
121
  if (!result.maxCapacity) {
121
- result.maxCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '='), 10) / 1000.0;
122
- result.designedCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', '='), 10) / 1000.0 | result.maxCapacity;
122
+ result.maxCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '=', true, true), 10) / 1000.0;
123
+ result.designedCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', true, true, '='), 10) / 1000.0 | result.maxCapacity;
123
124
  result.currentCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10) / 1000.0;
124
125
  }
125
126
  const percent = util.getValue(lines, 'POWER_SUPPLY_CAPACITY', '=');
package/lib/filesystem.js CHANGED
@@ -989,7 +989,7 @@ function diskLayout(callback) {
989
989
  if (sizeStr) {
990
990
  let sizeValue = 0;
991
991
  if (sizeStr.indexOf('(') >= 0) {
992
- sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, ''));
992
+ sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, '').replace(/\s/g, ''));
993
993
  }
994
994
  if (!sizeValue) {
995
995
  sizeValue = parseInt(sizeStr);
@@ -1037,7 +1037,7 @@ function diskLayout(callback) {
1037
1037
  if (sizeStr) {
1038
1038
  let sizeValue = 0;
1039
1039
  if (sizeStr.indexOf('(') >= 0) {
1040
- sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, ''));
1040
+ sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, '').replace(/\s/g, ''));
1041
1041
  }
1042
1042
  if (!sizeValue) {
1043
1043
  sizeValue = parseInt(sizeStr);
@@ -1082,7 +1082,7 @@ function diskLayout(callback) {
1082
1082
  if (sizeStr) {
1083
1083
  let sizeValue = 0;
1084
1084
  if (sizeStr.indexOf('(') >= 0) {
1085
- sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, ''));
1085
+ sizeValue = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, '').replace(/,/g, '').replace(/\s/g, ''));
1086
1086
  }
1087
1087
  if (!sizeValue) {
1088
1088
  sizeValue = parseInt(sizeStr);
package/lib/graphics.js CHANGED
@@ -57,7 +57,7 @@ const videoTypes = {
57
57
  };
58
58
 
59
59
  function getVendorFromModel(model) {
60
- const diskManufacturers = [
60
+ const manufacturers = [
61
61
  { pattern: '^LG.+', manufacturer: 'LG' },
62
62
  { pattern: '^BENQ.+', manufacturer: 'BenQ' },
63
63
  { pattern: '^ASUS.+', manufacturer: 'Asus' },
@@ -68,20 +68,23 @@ function getVendorFromModel(model) {
68
68
  { pattern: '^ACER.+', manufacturer: 'Acer' },
69
69
  { pattern: '^AOC.+', manufacturer: 'AOC Monitors' },
70
70
  { pattern: '^HP.+', manufacturer: 'HP' },
71
- { pattern: '^EIZO.+', manufacturer: 'Eizo' },
72
- { pattern: '^PHILIPS.+', manufacturer: 'Philips' },
73
- { pattern: '^IIYAMA.+', manufacturer: 'Iiyama' },
74
- { pattern: '^SHARP.+', manufacturer: 'Sharp' },
75
- { pattern: '^NEC.+', manufacturer: 'NEC' },
76
- { pattern: '^LENOVO.+', manufacturer: 'Lenovo' },
77
- { pattern: 'COMPAQ.+', manufacturer: 'Compaq' },
78
- { pattern: 'APPLE.+', manufacturer: 'Apple' },
71
+ { pattern: '^EIZO.?', manufacturer: 'Eizo' },
72
+ { pattern: '^PHILIPS.?', manufacturer: 'Philips' },
73
+ { pattern: '^IIYAMA.?', manufacturer: 'Iiyama' },
74
+ { pattern: '^SHARP.?', manufacturer: 'Sharp' },
75
+ { pattern: '^NEC.?', manufacturer: 'NEC' },
76
+ { pattern: '^LENOVO.?', manufacturer: 'Lenovo' },
77
+ { pattern: 'COMPAQ.?', manufacturer: 'Compaq' },
78
+ { pattern: 'APPLE.?', manufacturer: 'Apple' },
79
+ { pattern: 'INTEL.?', manufacturer: 'Intel' },
80
+ { pattern: 'AMD.?', manufacturer: 'AMD' },
81
+ { pattern: 'NVIDIA.?', manufacturer: 'NVDIA' },
79
82
  ];
80
83
 
81
84
  let result = '';
82
85
  if (model) {
83
86
  model = model.toUpperCase();
84
- diskManufacturers.forEach((manufacturer) => {
87
+ manufacturers.forEach((manufacturer) => {
85
88
  const re = RegExp(manufacturer.pattern);
86
89
  if (re.test(model)) { result = manufacturer.manufacturer; }
87
90
  });
@@ -89,166 +92,113 @@ function getVendorFromModel(model) {
89
92
  return result;
90
93
  }
91
94
 
95
+ function getVendorFromId(id) {
96
+ const vendors = {
97
+ '610': 'Apple',
98
+ '1e6d': 'LG',
99
+ '10ac': 'DELL',
100
+ '4dd9': 'Sony',
101
+ '38a3': 'NEC',
102
+ };
103
+ return vendors[id] || '';
104
+ }
105
+
106
+ function vendorToId(str) {
107
+ let result = '';
108
+ str = (str || '').toLowerCase();
109
+ if (str.indexOf('apple') >= 0) { result = '0x05ac'; }
110
+ else if (str.indexOf('nvidia') >= 0) { result = '0x10de'; }
111
+ else if (str.indexOf('intel') >= 0) { result = '0x8086'; }
112
+ else if (str.indexOf('ati') >= 0 || str.indexOf('amd') >= 0) { result = '0x1002'; }
113
+
114
+ return result;
115
+ }
116
+
117
+ function getMetalVersion(id) {
118
+ const families = {
119
+ 'spdisplays_mtlgpufamilymac1': 'mac1',
120
+ 'spdisplays_mtlgpufamilymac2': 'mac2',
121
+ 'spdisplays_mtlgpufamilyapple1': 'apple1',
122
+ 'spdisplays_mtlgpufamilyapple2': 'apple2',
123
+ 'spdisplays_mtlgpufamilyapple3': 'apple3',
124
+ 'spdisplays_mtlgpufamilyapple4': 'apple4',
125
+ 'spdisplays_mtlgpufamilyapple5': 'apple5',
126
+ 'spdisplays_mtlgpufamilyapple6': 'apple6',
127
+ 'spdisplays_mtlgpufamilyapple7': 'apple7',
128
+ 'spdisplays_metalfeaturesetfamily11': 'family1_v1',
129
+ 'spdisplays_metalfeaturesetfamily12': 'family1_v2',
130
+ 'spdisplays_metalfeaturesetfamily13': 'family1_v3',
131
+ 'spdisplays_metalfeaturesetfamily14': 'family1_v4',
132
+ 'spdisplays_metalfeaturesetfamily21': 'family2_v1'
133
+ };
134
+ return families[id] || '';
135
+ }
136
+
92
137
  function graphics(callback) {
93
138
 
94
- function parseLinesDarwin(lines) {
95
- let starts = [];
96
- let level = -1;
97
- let lastlevel = -1;
98
- let controllers = [];
99
- let displays = [];
100
- let currentController = {
101
- vendor: '',
102
- model: '',
103
- bus: '',
104
- vram: null,
105
- vramDynamic: false
139
+ function parseLinesDarwin(graphicsArr) {
140
+ const res = {
141
+ controllers: [],
142
+ displays: []
106
143
  };
107
- let currentDisplay = {
108
- vendor: '',
109
- model: '',
110
- deviceName: '',
111
- main: false,
112
- builtin: false,
113
- connection: '',
114
- sizeX: null,
115
- sizeY: null,
116
- pixelDepth: null,
117
- resolutionX: null,
118
- resolutionY: null,
119
- currentResX: null,
120
- currentResY: null,
121
- positionX: 0,
122
- positionY: 0,
123
- currentRefreshRate: null
124
- };
125
- for (let i = 0; i < lines.length; i++) {
126
- if ('' !== lines[i].trim()) {
127
- let start = lines[i].search(/\S|$/);
128
- if (-1 === starts.indexOf(start)) {
129
- starts.push(start);
130
- }
131
- level = starts.indexOf(start);
132
- if (level < lastlevel) {
133
- if (Object.keys(currentController).length > 0 && (currentController.vendor || currentController.model)) {// just changed to Displays
134
- controllers.push(currentController);
135
- currentController = {
136
- vendor: '',
137
- model: '',
138
- bus: '',
139
- vram: null,
140
- vramDynamic: false
141
- };
142
- }
143
- if (Object.keys(currentDisplay).length > 0) {// just changed to Displays
144
- if (currentDisplay.resolutionX && currentDisplay.resolutionY) { displays.push(currentDisplay); }
145
- currentDisplay = {
146
- vendor: '',
147
- model: '',
148
- deviceName: '',
149
- main: false,
150
- builtin: false,
151
- connection: '',
144
+ try {
145
+ graphicsArr.forEach(function (item) {
146
+ // controllers
147
+ const bus = ((item.sppci_bus || '').indexOf('builtin') > -1 ? 'Built-In' : ((item.sppci_bus || '').indexOf('pcie') > -1 ? 'PCIe' : ''));
148
+ const vram = (parseInt((item.spdisplays_vram || ''), 10) || 0) * (((item.spdisplays_vram || '').indexOf('GB') > -1) ? 1024 : 1);
149
+ const vramDyn = (parseInt((item.spdisplays_vram_shared || ''), 10) || 0) * (((item.spdisplays_vram_shared || '').indexOf('GB') > -1) ? 1024 : 1);
150
+ let metalVersion = getMetalVersion(item.spdisplays_metal || item.spdisplays_metalfamily || '');
151
+ res.controllers.push({
152
+ vendor: getVendorFromModel(item.spdisplays_vendor || '') || item.spdisplays_vendor || '',
153
+ model: item.sppci_model || '',
154
+ bus,
155
+ vramDynamic: bus === 'Built-In',
156
+ vram: vram || vramDyn || null,
157
+ deviceId: item['spdisplays_device-id'] || '',
158
+ vendorId: item['spdisplays_vendor-id'] || vendorToId((item['spdisplays_vendor'] || '') + (item.sppci_model || '')),
159
+ external: (item.sppci_device_type === 'spdisplays_egpu'),
160
+ cores: item['sppci_cores'] || null,
161
+ metalVersion
162
+ });
163
+
164
+ // displays
165
+ if (item.spdisplays_ndrvs && item.spdisplays_ndrvs.length) {
166
+ item.spdisplays_ndrvs.forEach(function (displayItem) {
167
+ const connectionType = displayItem['spdisplays_connection_type'] || '';
168
+ const currentResolutionParts = (displayItem['_spdisplays_resolution'] || '').split('@');
169
+ const currentResolution = currentResolutionParts[0].split('x');
170
+ const pixelParts = (displayItem['_spdisplays_pixels'] || '').split('x');
171
+ const pixelDepthString = displayItem['spdisplays_depth'] || '';
172
+ const serial = displayItem['_spdisplays_display-serial-number'] || displayItem['_spdisplays_display-serial-number2'] || null;
173
+ res.displays.push({
174
+ vendor: getVendorFromId(displayItem['_spdisplays_display-vendor-id'] || '') || getVendorFromModel(displayItem['_name'] || ''),
175
+ vendorId: displayItem['_spdisplays_display-vendor-id'] || '',
176
+ model: displayItem['_name'] || '',
177
+ productionYear: displayItem['_spdisplays_display-year'] || null,
178
+ serial: serial !== '0' ? serial : null,
179
+ displayId: displayItem['_spdisplays_displayID'] || null,
180
+ main: displayItem['spdisplays_main'] ? displayItem['spdisplays_main'] === 'spdisplays_yes' : false,
181
+ builtin: (displayItem['spdisplays_display_type'] || '').indexOf('built-in') > -1,
182
+ connection: ((connectionType.indexOf('_internal') > -1) ? 'Internal' : ((connectionType.indexOf('_displayport') > -1) ? 'Display Port' : ((connectionType.indexOf('_hdmi') > -1) ? 'HDMI' : null))),
152
183
  sizeX: null,
153
184
  sizeY: null,
154
- pixelDepth: null,
155
- resolutionX: null,
156
- resolutionY: null,
157
- currentResX: null,
158
- currentResY: null,
185
+ pixelDepth: (pixelDepthString === 'CGSThirtyBitColor' ? 30 : (pixelDepthString === 'CGSThirtytwoBitColor' ? 32 : (pixelDepthString === 'CGSTwentyfourBitColor' ? 24 : ''))),
186
+ resolutionX: pixelParts.length > 1 ? parseInt(pixelParts[0], 10) : null,
187
+ resolutionY: pixelParts.length > 1 ? parseInt(pixelParts[1], 10) : null,
188
+ currentResX: currentResolution.length > 1 ? parseInt(currentResolution[0], 10) : null,
189
+ currentResY: currentResolution.length > 1 ? parseInt(currentResolution[1], 10) : null,
159
190
  positionX: 0,
160
191
  positionY: 0,
161
- currentRefreshRate: null
162
- };
163
- }
164
- }
165
- lastlevel = level;
166
- let parts = lines[i].split(':');
167
- if (2 === level) { // grafics controller level
168
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('chipsetmodel') !== -1) { currentController.model = parts[1].trim(); }
169
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vendor') !== -1) { currentController.vendor = parts[1].split('(')[0].trim(); }
170
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vram(total)') !== -1) {
171
- currentController.vram = parseInt(parts[1]); // in MB
172
- if (parts[1].toLowerCase().indexOf('gb') !== -1) {
173
- currentController.vram = currentController.vram * 1024;
174
- }
175
- currentController.vramDynamic = false;
176
- }
177
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vram(dynamic,max)') !== -1) {
178
- currentController.vram = parseInt(parts[1]); // in MB
179
- if (parts[1].toLowerCase().indexOf('gb') !== -1) {
180
- currentController.vram = currentController.vram * 1024;
181
- }
182
- currentController.vramDynamic = true;
183
- }
184
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('bus') !== -1) {
185
- currentController.bus = parts[1].trim();
186
- if (currentController.bus.toLowerCase() === 'built-in') {
187
- currentController.vramDynamic = true;
188
- }
189
- }
190
- }
191
- if (3 === level) { // display controller level
192
- if (parts.length > 1 && '' === parts[1]) {
193
- currentDisplay.vendor = getVendorFromModel(parts[0].trim());
194
- currentDisplay.model = parts[0].trim();
195
- currentDisplay.main = false;
196
- currentDisplay.builtin = false;
197
- currentDisplay.connection = '';
198
- currentDisplay.sizeX = null;
199
- currentDisplay.sizeY = null;
200
- currentDisplay.positionX = 0;
201
- currentDisplay.positionY = 0;
202
- currentDisplay.pixelDepth = null;
203
- }
204
- }
205
- if (4 === level) { // display controller details level
206
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('resolution') !== -1) {
207
- let resolution = parts[1].split('x');
208
- if (resolution.length > 1) {
209
- let xpart = resolution[0];
210
- if (xpart.indexOf('(') !== -1) {
211
- xpart = xpart.split('(').slice(-1)[0];
212
- }
213
- let ypart = resolution[1];
214
- if (ypart.indexOf(')') !== -1) {
215
- ypart = ypart.split(')')[0];
216
- }
217
- currentDisplay.resolutionX = parseInt(xpart) || 0;
218
- currentDisplay.resolutionY = parseInt(ypart) || 0;
219
- currentDisplay.currentResX = currentDisplay.resolutionX;
220
- currentDisplay.currentResY = currentDisplay.resolutionY;
221
- }
222
- }
223
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('pixeldepth') !== -1) { currentDisplay.pixelDepth = parseInt(parts[1]); } // in BIT
224
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('framebufferdepth') !== -1) { currentDisplay.pixelDepth = parseInt(parts[1]); } // in BIT
225
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('maindisplay') !== -1 && parts[1].replace(/ +/g, '').toLowerCase() === 'yes') { currentDisplay.main = true; }
226
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('built-in') !== -1 && parts[1].replace(/ +/g, '').toLowerCase() === 'yes') {
227
- currentDisplay.vendor = 'Apple';
228
- currentDisplay.builtin = true;
229
- currentDisplay.connection = '';
230
- }
231
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('connectiontype') !== -1) {
232
- currentDisplay.builtin = false;
233
- currentDisplay.connection = parts[1].trim();
234
- if (currentDisplay.connection === 'Internal') {
235
- currentDisplay.vendor = 'Apple';
236
- currentDisplay.builtin = true;
237
- }
238
- }
192
+ currentRefreshRate: currentResolutionParts.length > 1 ? parseInt(currentResolutionParts[1], 10) : null,
193
+
194
+ });
195
+ });
239
196
  }
240
- }
241
- }
242
- if (Object.keys(currentController).length > 0 && (currentController.vendor || currentController.model)) {// just changed to Displays
243
- controllers.push(currentController);
244
- }
245
- if (Object.keys(currentDisplay).length > 0) {// just changed to Displays
246
- if (currentDisplay.resolutionX && currentDisplay.resolutionY) { displays.push(currentDisplay); }
197
+ });
198
+ return res;
199
+ } catch (e) {
200
+ return res;
247
201
  }
248
- return ({
249
- controllers: controllers,
250
- displays: displays
251
- });
252
202
  }
253
203
 
254
204
  function parseLinesLinuxControllers(lines) {
@@ -706,11 +656,15 @@ function graphics(callback) {
706
656
  displays: []
707
657
  };
708
658
  if (_darwin) {
709
- let cmd = 'system_profiler SPDisplaysDataType';
659
+ let cmd = 'system_profiler -xml -detailLevel full SPDisplaysDataType';
710
660
  exec(cmd, function (error, stdout) {
711
661
  if (!error) {
712
- let lines = stdout.toString().split('\n');
713
- result = parseLinesDarwin(lines);
662
+ try {
663
+ let output = stdout.toString();
664
+ result = parseLinesDarwin(util.plistParser(output)[0]._items);
665
+ } catch (e) {
666
+ util.noop();
667
+ }
714
668
  }
715
669
  if (callback) {
716
670
  callback(result);
package/lib/index.d.ts CHANGED
@@ -151,16 +151,16 @@ export namespace Systeminformation {
151
151
  info_name: string;
152
152
  type: string;
153
153
  protocol: string;
154
- }
154
+ };
155
155
  model_family?: string,
156
156
  model_name?: string,
157
157
  serial_number?: string,
158
158
  firmware_version?: string,
159
159
  smart_status: {
160
160
  passed: boolean;
161
- }
161
+ };
162
162
  trim?: {
163
- supported: boolean
163
+ supported: boolean;
164
164
  },
165
165
  ata_smart_attributes?: {
166
166
  revision: number;
@@ -181,7 +181,7 @@ export namespace Systeminformation {
181
181
  event_count: boolean;
182
182
  auto_keep: boolean;
183
183
  };
184
- raw: { value: number; string: string }
184
+ raw: { value: number; string: string; };
185
185
  }[];
186
186
  };
187
187
  ata_smart_error_log?: {
@@ -209,10 +209,10 @@ export namespace Systeminformation {
209
209
  error_count_total: number;
210
210
  error_count_outdated: number;
211
211
  };
212
- }
212
+ };
213
213
  nvme_pci_vendor?: {
214
214
  id: number,
215
- subsystem_id: number
215
+ subsystem_id: number;
216
216
  },
217
217
  nvme_smart_health_information_log?: {
218
218
  critical_warning?: number,
@@ -232,11 +232,11 @@ export namespace Systeminformation {
232
232
  num_err_log_entries?: number,
233
233
  warning_temp_time?: number,
234
234
  critical_comp_time?: number,
235
- temperature_sensors?: number[]
235
+ temperature_sensors?: number[];
236
236
  },
237
237
  user_capacity?: {
238
238
  blocks: number,
239
- bytes: number
239
+ bytes: number;
240
240
  },
241
241
  logical_block_size?: number,
242
242
  temperature: {
@@ -294,11 +294,16 @@ export namespace Systeminformation {
294
294
 
295
295
  interface GraphicsControllerData {
296
296
  vendor: string;
297
+ vendorId?: string;
297
298
  model: string;
299
+ deviceId?: string;
298
300
  bus: string;
299
301
  busAddress?: string;
300
302
  vram: number;
301
303
  vramDynamic: boolean;
304
+ external?: boolean;
305
+ cores?: number;
306
+ metalVersion?: string;
302
307
  subDeviceId?: string;
303
308
  driverVersion?: string;
304
309
  name?: string;
package/lib/memory.js CHANGED
@@ -508,7 +508,7 @@ function memLayout(callback) {
508
508
  result.push({
509
509
  size: parseInt(util.getValue(lines, 'Capacity', '='), 10) || 0,
510
510
  bank: util.getValue(lines, 'abel', '='), // BankLabel
511
- type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='), 10)],
511
+ type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='), 10) || parseInt(util.getValue(lines, 'SMBIOSMemoryType', '='), 10)],
512
512
  ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
513
513
  clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', '='), 10) || parseInt(util.getValue(lines, 'Speed', '='), 10) || 0,
514
514
  formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', '='), 10) || 0],
package/lib/util.js CHANGED
@@ -103,16 +103,17 @@ function cores() {
103
103
  return _cores;
104
104
  }
105
105
 
106
- function getValue(lines, property, separator, trimmed) {
106
+ function getValue(lines, property, separator, trimmed, lineMatch) {
107
107
  separator = separator || ':';
108
108
  property = property.toLowerCase();
109
109
  trimmed = trimmed || false;
110
+ lineMatch = lineMatch || false;
110
111
  for (let i = 0; i < lines.length; i++) {
111
112
  let line = lines[i].toLowerCase().replace(/\t/g, '');
112
113
  if (trimmed) {
113
114
  line = line.trim();
114
115
  }
115
- if (line.startsWith(property)) {
116
+ if (line.startsWith(property) && (lineMatch ? (line.match(property + separator)) : true)) {
116
117
  const parts = trimmed ? lines[i].trim().split(separator) : lines[i].split(separator);
117
118
  if (parts.length >= 2) {
118
119
  parts.shift();
@@ -984,6 +985,94 @@ function linuxVersion() {
984
985
  return result;
985
986
  }
986
987
 
988
+ function plistParser(xmlStr) {
989
+ const tags = ['array', 'dict', 'key', 'string', 'integer', 'date', 'real', 'data'];
990
+
991
+ function getNextTagPos() {
992
+ let result = {
993
+ pos: 999999,
994
+ tag: ''
995
+ };
996
+ tags.forEach((tag) => {
997
+ const ii = xmlStr.indexOf(`<${tag}>`);
998
+ if (ii !== -1 && ii < result.pos) {
999
+ result = {
1000
+ pos: ii,
1001
+ tag
1002
+ };
1003
+ }
1004
+ });
1005
+ return result;
1006
+ }
1007
+
1008
+ function getNextClosingTagPos(tag) {
1009
+ return xmlStr.indexOf(`</${tag}>`);
1010
+ }
1011
+
1012
+ function parseXmlTree(isArray, closingTag) {
1013
+ // start parsing
1014
+ let obj = {};
1015
+ let arr = [];
1016
+ let cpos = getNextTagPos();
1017
+ let key = '';
1018
+ let valueStr = null;
1019
+
1020
+ while (cpos.pos >= 0 && cpos.tag) {
1021
+ let nextTagPos = getNextTagPos();
1022
+ // let nextClosePos = getNextClosingTagPos(cpos.tag);
1023
+ let nextClosePosBlock = closingTag ? getNextClosingTagPos(closingTag) : 999999;
1024
+ if (nextClosePosBlock <= nextTagPos.pos) {
1025
+ return (isArray ? arr : obj);
1026
+ }
1027
+ xmlStr = xmlStr.substring((cpos.pos + cpos.tag.length + 2));
1028
+ if (cpos.tag === 'array') {
1029
+ const res = parseXmlTree(true, cpos.tag);
1030
+ if (key) {
1031
+ obj[key] = res;
1032
+ } else {
1033
+ obj = res;
1034
+ }
1035
+ } else if (cpos.tag === 'dict') {
1036
+ const res = parseXmlTree(false, cpos.tag);
1037
+ if (!isArray) {
1038
+ obj[key] = res;
1039
+ } else {
1040
+ arr.push(res);
1041
+ }
1042
+ xmlStr = xmlStr.substring((cpos.pos + cpos.tag.length + 3));
1043
+ } else {
1044
+ let nextTagPos = getNextTagPos();
1045
+ let nextClosePos = getNextClosingTagPos(cpos.tag);
1046
+ // nextClosePosBlock = closingTag ? getNextClosingTagPos(closingTag) : 999999;
1047
+ if (nextClosePos < nextTagPos.pos) {
1048
+ if (cpos.tag === 'key') {
1049
+ key = xmlStr.substring(0, nextClosePos);
1050
+ xmlStr = xmlStr.substring(key.length + cpos.tag.length + 3); // key done
1051
+ } else {
1052
+ valueStr = xmlStr.substring(0, nextClosePos).replace(/\t/g, '');
1053
+ if (cpos.tag === 'string') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
1054
+ if (cpos.tag === 'integer') { if (!isArray) { obj[key] = parseInt(valueStr); } else { arr.push(parseInt(valueStr)); } }
1055
+ if (cpos.tag === 'date') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
1056
+ if (cpos.tag === 'data') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
1057
+ if (cpos.tag === 'real') { if (!isArray) { obj[key] = parseFloat(valueStr); } else { arr.push(parseFloat(valueStr)); } }
1058
+
1059
+ key = '';
1060
+ xmlStr = xmlStr.substring(valueStr.length + cpos.tag.length + 3); // property done
1061
+ }
1062
+ }
1063
+ }
1064
+ cpos = getNextTagPos();
1065
+ }
1066
+ return (isArray ? arr : obj);
1067
+ }
1068
+ try {
1069
+ const result = parseXmlTree(false, '');
1070
+ return result;
1071
+ } catch (e) {
1072
+ return {};
1073
+ }
1074
+ }
1075
+
987
1076
  function noop() { }
988
1077
 
989
1078
  exports.toInt = toInt;
@@ -1019,6 +1108,7 @@ exports.promisify = promisify;
1019
1108
  exports.promisifySave = promisifySave;
1020
1109
  exports.smartMonToolsInstalled = smartMonToolsInstalled;
1021
1110
  exports.linuxVersion = linuxVersion;
1111
+ exports.plistParser = plistParser;
1022
1112
  exports.stringReplace = stringReplace;
1023
1113
  exports.stringToLower = stringToLower;
1024
1114
  exports.stringToString = stringToString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "systeminformation",
3
- "version": "5.8.8",
3
+ "version": "5.9.2",
4
4
  "description": "Simple system and OS information library",
5
5
  "license": "MIT",
6
6
  "author": "Sebastian Hildebrandt <hildebrandt@plus-innovations.com> (https://plus-innovations.com)",