@nordicsemiconductor/pc-nrfconnect-shared 121.0.0 → 123.0.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.
Files changed (174) hide show
  1. package/Changelog.md +85 -0
  2. package/coverage/cobertura-coverage.xml +2276 -1778
  3. package/ipc/launcherConfig.ts +25 -0
  4. package/ipc/openWindow.ts +17 -1
  5. package/ipc/schema/packageJson.ts +26 -22
  6. package/main/index.ts +11 -5
  7. package/mocks/packageJsonMock.ts +1 -1
  8. package/nrfutil/device/__mocks__/device.ts +2 -0
  9. package/nrfutil/device/batch.ts +19 -9
  10. package/nrfutil/device/common.ts +32 -46
  11. package/nrfutil/device/device.ts +2 -0
  12. package/nrfutil/device/deviceInfo.ts +70 -0
  13. package/nrfutil/device/erase.ts +2 -2
  14. package/nrfutil/device/firmwareRead.ts +2 -2
  15. package/nrfutil/device/getCoreInfo.ts +2 -2
  16. package/nrfutil/device/getFwInfo.ts +2 -2
  17. package/nrfutil/device/getProtectionStatus.ts +2 -2
  18. package/nrfutil/device/list.ts +5 -31
  19. package/nrfutil/device/program.ts +4 -4
  20. package/nrfutil/device/recover.ts +2 -2
  21. package/nrfutil/device/reset.ts +2 -2
  22. package/nrfutil/device/setMcuState.ts +2 -5
  23. package/nrfutil/device/setProtectionStatus.ts +2 -2
  24. package/nrfutil/index.ts +1 -1
  25. package/nrfutil/moduleVersion.ts +22 -2
  26. package/nrfutil/sandbox.ts +52 -32
  27. package/nrfutil/sandboxTypes.ts +15 -1
  28. package/package.json +3 -2
  29. package/scripts/check-app-properties.ts +6 -6
  30. package/scripts/esbuild.ts +3 -3
  31. package/scripts/nordic-publish.js +23 -23
  32. package/scripts/nordic-publish.ts +3 -3
  33. package/scripts/release-shared.ts +2 -2
  34. package/src/About/ApplicationCard.tsx +3 -5
  35. package/src/About/DeviceCard.tsx +6 -5
  36. package/src/About/SupportCard.tsx +2 -2
  37. package/src/App/App.test.tsx +7 -0
  38. package/src/App/App.tsx +14 -27
  39. package/src/Device/DeviceSelector/BasicDeviceInfo.tsx +12 -6
  40. package/src/Device/DeviceSelector/DeviceList/AnimatedList.tsx +1 -1
  41. package/src/Device/DeviceSelector/DeviceList/Device.tsx +7 -5
  42. package/src/Device/DeviceSelector/DeviceList/DeviceList.tsx +23 -5
  43. package/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.tsx +7 -6
  44. package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +26 -30
  45. package/src/Device/DeviceSelector/DeviceList/edit-device-buttons.scss +1 -2
  46. package/src/Device/DeviceSelector/DeviceSelector.test.tsx +17 -37
  47. package/src/Device/DeviceSelector/DeviceSelector.tsx +64 -21
  48. package/src/Device/DeviceSelector/Favorite.tsx +10 -10
  49. package/src/Device/DeviceSelector/basic-device-info.scss +0 -12
  50. package/src/Device/deviceInfo/deviceInfo.ts +2 -2
  51. package/src/Device/deviceLister.ts +111 -59
  52. package/src/Device/deviceSetup.ts +30 -13
  53. package/src/Device/deviceSlice.ts +157 -84
  54. package/src/Device/jprogOperations.ts +56 -27
  55. package/src/Device/sdfuOperations.ts +25 -31
  56. package/src/ErrorBoundary/ErrorBoundary.tsx +7 -13
  57. package/src/Feedback/sendFeedback.ts +2 -4
  58. package/src/InlineInput/NumberInlineInput.tsx +1 -1
  59. package/src/InlineInput/NumberInputWithDropdown.tsx +1 -2
  60. package/src/index.ts +4 -0
  61. package/src/logging/sendInitialLogMessages.ts +15 -13
  62. package/src/utils/appDetails.ts +22 -0
  63. package/src/utils/appDirs.ts +4 -4
  64. package/src/utils/launcherConfig.ts +17 -0
  65. package/src/utils/logLibVersions.ts +1 -1
  66. package/src/utils/packageJson.ts +52 -10
  67. package/src/utils/persistentStore.ts +21 -14
  68. package/src/utils/systemReport.ts +4 -6
  69. package/src/utils/usageData.ts +75 -167
  70. package/src/utils/usageDataCommon.ts +59 -0
  71. package/src/utils/usageDataMain.ts +117 -0
  72. package/src/utils/usageDataRenderer.ts +126 -0
  73. package/src/utils/useHotKey.ts +2 -2
  74. package/typings/generated/ipc/launcherConfig.d.ts +14 -0
  75. package/typings/generated/ipc/launcherConfig.d.ts.map +1 -0
  76. package/typings/generated/ipc/openWindow.d.ts +10 -4
  77. package/typings/generated/ipc/openWindow.d.ts.map +1 -1
  78. package/typings/generated/ipc/schema/packageJson.d.ts +34 -52
  79. package/typings/generated/ipc/schema/packageJson.d.ts.map +1 -1
  80. package/typings/generated/main/index.d.ts +8 -2
  81. package/typings/generated/main/index.d.ts.map +1 -1
  82. package/typings/generated/nrfutil/device/__mocks__/device.d.ts +1 -0
  83. package/typings/generated/nrfutil/device/__mocks__/device.d.ts.map +1 -1
  84. package/typings/generated/nrfutil/device/batch.d.ts +3 -2
  85. package/typings/generated/nrfutil/device/batch.d.ts.map +1 -1
  86. package/typings/generated/nrfutil/device/common.d.ts +7 -34
  87. package/typings/generated/nrfutil/device/common.d.ts.map +1 -1
  88. package/typings/generated/nrfutil/device/device.d.ts +14 -13
  89. package/typings/generated/nrfutil/device/device.d.ts.map +1 -1
  90. package/typings/generated/nrfutil/device/deviceInfo.d.ts +40 -0
  91. package/typings/generated/nrfutil/device/deviceInfo.d.ts.map +1 -0
  92. package/typings/generated/nrfutil/device/erase.d.ts +2 -2
  93. package/typings/generated/nrfutil/device/erase.d.ts.map +1 -1
  94. package/typings/generated/nrfutil/device/firmwareRead.d.ts +2 -2
  95. package/typings/generated/nrfutil/device/firmwareRead.d.ts.map +1 -1
  96. package/typings/generated/nrfutil/device/getCoreInfo.d.ts +2 -2
  97. package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -1
  98. package/typings/generated/nrfutil/device/getFwInfo.d.ts +2 -2
  99. package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -1
  100. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +2 -2
  101. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -1
  102. package/typings/generated/nrfutil/device/list.d.ts +3 -3
  103. package/typings/generated/nrfutil/device/list.d.ts.map +1 -1
  104. package/typings/generated/nrfutil/device/program.d.ts +2 -2
  105. package/typings/generated/nrfutil/device/program.d.ts.map +1 -1
  106. package/typings/generated/nrfutil/device/recover.d.ts +2 -2
  107. package/typings/generated/nrfutil/device/recover.d.ts.map +1 -1
  108. package/typings/generated/nrfutil/device/reset.d.ts +2 -2
  109. package/typings/generated/nrfutil/device/reset.d.ts.map +1 -1
  110. package/typings/generated/nrfutil/device/setMcuState.d.ts +2 -2
  111. package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -1
  112. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +2 -2
  113. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -1
  114. package/typings/generated/nrfutil/index.d.ts +2 -1
  115. package/typings/generated/nrfutil/index.d.ts.map +1 -1
  116. package/typings/generated/nrfutil/moduleVersion.d.ts +4 -0
  117. package/typings/generated/nrfutil/moduleVersion.d.ts.map +1 -1
  118. package/typings/generated/nrfutil/sandbox.d.ts +2 -2
  119. package/typings/generated/nrfutil/sandbox.d.ts.map +1 -1
  120. package/typings/generated/nrfutil/sandboxTypes.d.ts +10 -1
  121. package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -1
  122. package/typings/generated/src/About/ApplicationCard.d.ts.map +1 -1
  123. package/typings/generated/src/About/DeviceCard.d.ts.map +1 -1
  124. package/typings/generated/src/App/App.d.ts +0 -1
  125. package/typings/generated/src/App/App.d.ts.map +1 -1
  126. package/typings/generated/src/Device/DeviceSelector/BasicDeviceInfo.d.ts.map +1 -1
  127. package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts +0 -1
  128. package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts.map +1 -1
  129. package/typings/generated/src/Device/DeviceSelector/DeviceList/DeviceList.d.ts.map +1 -1
  130. package/typings/generated/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.d.ts.map +1 -1
  131. package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts +0 -1
  132. package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts.map +1 -1
  133. package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
  134. package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts +0 -1
  135. package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts.map +1 -1
  136. package/typings/generated/src/Device/deviceLister.d.ts +1 -15
  137. package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
  138. package/typings/generated/src/Device/deviceSetup.d.ts +7 -6
  139. package/typings/generated/src/Device/deviceSetup.d.ts.map +1 -1
  140. package/typings/generated/src/Device/deviceSlice.d.ts +16 -15
  141. package/typings/generated/src/Device/deviceSlice.d.ts.map +1 -1
  142. package/typings/generated/src/Device/jprogOperations.d.ts.map +1 -1
  143. package/typings/generated/src/Device/sdfuOperations.d.ts.map +1 -1
  144. package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts.map +1 -1
  145. package/typings/generated/src/Feedback/sendFeedback.d.ts.map +1 -1
  146. package/typings/generated/src/InlineInput/NumberInlineInput.d.ts +1 -1
  147. package/typings/generated/src/InlineInput/NumberInlineInput.d.ts.map +1 -1
  148. package/typings/generated/src/InlineInput/NumberInputWithDropdown.d.ts.map +1 -1
  149. package/typings/generated/src/index.d.ts +3 -1
  150. package/typings/generated/src/index.d.ts.map +1 -1
  151. package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
  152. package/typings/generated/src/utils/appDetails.d.ts +4 -0
  153. package/typings/generated/src/utils/appDetails.d.ts.map +1 -0
  154. package/typings/generated/src/utils/appDirs.d.ts +1 -1
  155. package/typings/generated/src/utils/appDirs.d.ts.map +1 -1
  156. package/typings/generated/src/utils/launcherConfig.d.ts +4 -0
  157. package/typings/generated/src/utils/launcherConfig.d.ts.map +1 -0
  158. package/typings/generated/src/utils/packageJson.d.ts +30 -7
  159. package/typings/generated/src/utils/packageJson.d.ts.map +1 -1
  160. package/typings/generated/src/utils/persistentStore.d.ts +3 -2
  161. package/typings/generated/src/utils/persistentStore.d.ts.map +1 -1
  162. package/typings/generated/src/utils/systemReport.d.ts +1 -1
  163. package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
  164. package/typings/generated/src/utils/usageData.d.ts +8 -65
  165. package/typings/generated/src/utils/usageData.d.ts.map +1 -1
  166. package/typings/generated/src/utils/usageDataCommon.d.ts +27 -0
  167. package/typings/generated/src/utils/usageDataCommon.d.ts.map +1 -0
  168. package/typings/generated/src/utils/usageDataMain.d.ts +10 -0
  169. package/typings/generated/src/utils/usageDataMain.d.ts.map +1 -0
  170. package/typings/generated/src/utils/usageDataRenderer.d.ts +10 -0
  171. package/typings/generated/src/utils/usageDataRenderer.d.ts.map +1 -0
  172. package/src/Device/DeviceSelector/DeviceList/device.scss +0 -28
  173. package/src/Device/DeviceSelector/DeviceList/more-device-info.scss +0 -33
  174. package/src/Device/DeviceSelector/favorite.scss +0 -17
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import React, { useState } from 'react';
8
- import FormLabel from 'react-bootstrap/esm/FormLabel';
9
8
 
10
9
  import { DropdownItem } from '../Dropdown/Dropdown';
11
10
  import { RangeOrValues } from '../Slider/range';
@@ -66,7 +65,7 @@ export default ({
66
65
  }}
67
66
  title={title}
68
67
  >
69
- <FormLabel className="tw-mb-1 tw-text-xs">{label}</FormLabel>
68
+ <div className="tw-mb-1 tw-text-xs">{label}</div>
70
69
  <div className="tw-flex tw-h-8 tw-w-full">
71
70
  <NumberInlineInput
72
71
  value={inlineValue}
package/src/index.ts CHANGED
@@ -77,6 +77,7 @@ export { openUrl } from './utils/open';
77
77
  export { default as systemReport } from './utils/systemReport';
78
78
 
79
79
  export { default as usageData } from './utils/usageData';
80
+ export { type Metadata as UsageDataMetadata } from './utils/usageDataCommon';
80
81
  export { default as classNames } from './utils/classNames';
81
82
  export { truncateMiddle } from './utils/truncateMiddle';
82
83
 
@@ -97,12 +98,15 @@ export {
97
98
  persistApiKey,
98
99
  } from './utils/persistentStore';
99
100
 
101
+ export { default as launcherConfig } from './utils/launcherConfig';
102
+
100
103
  export { jprogDeviceSetup } from './Device/jprogOperations';
101
104
 
102
105
  export { sdfuDeviceSetup } from './Device/sdfuOperations';
103
106
 
104
107
  export {
105
108
  selectedDevice,
109
+ selectedDeviceInfo,
106
110
  getReadbackProtection,
107
111
  persistSerialPortOptions,
108
112
  type Device,
@@ -4,12 +4,12 @@
4
4
  * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
5
5
  */
6
6
 
7
- import { inMain as appDetails } from '../../ipc/appDetails';
8
7
  import NrfutilDeviceLib from '../../nrfutil/device/device';
9
8
  import {
10
- describeVersion,
9
+ getExpectedVersion,
11
10
  resolveModuleVersion,
12
11
  } from '../../nrfutil/moduleVersion';
12
+ import appDetails from '../utils/appDetails';
13
13
  import { getAppDataDir } from '../utils/appDirs';
14
14
  import logLibVersions from '../utils/logLibVersions';
15
15
  import udevInstalled from '../utils/udevInstalled';
@@ -23,8 +23,6 @@ export default async () => {
23
23
  logLibVersions();
24
24
  logger.debug(`Application data folder: ${getAppDataDir()}`);
25
25
 
26
- const details = await appDetails.getAppDetails();
27
-
28
26
  const {
29
27
  name,
30
28
  currentVersion,
@@ -34,9 +32,8 @@ export default async () => {
34
32
  installed,
35
33
  homeDir,
36
34
  tmpDir,
37
- bundledJlink,
38
35
  source,
39
- } = details;
36
+ } = await appDetails();
40
37
 
41
38
  logger.debug(`App ${name} v${currentVersion} (${source})`);
42
39
  logger.debug(`App path: ${installed.path}`);
@@ -47,16 +44,21 @@ export default async () => {
47
44
  logger.debug(`HomeDir: ${homeDir}`);
48
45
  logger.debug(`TmpDir: ${tmpDir}`);
49
46
 
50
- if (bundledJlink) {
51
- const dependencies = (await NrfutilDeviceLib.getModuleVersion())
52
- .dependencies;
53
- const jlinkVersion = resolveModuleVersion('JlinkARM', dependencies);
47
+ const dependencies = (await NrfutilDeviceLib.getModuleVersion())
48
+ .dependencies;
49
+ const jlinkVersion = resolveModuleVersion('JlinkARM', dependencies);
54
50
 
55
- if (!describeVersion(jlinkVersion).includes(bundledJlink)) {
56
- logger.info(
57
- `Installed JLink version does not match the provided version (${bundledJlink})`
51
+ if (jlinkVersion) {
52
+ const result = getExpectedVersion(jlinkVersion);
53
+ if (!result.isExpectedVersion) {
54
+ logger.warn(
55
+ `Installed JLink version does not match the expected version (${result.expectedVersion})`
58
56
  );
59
57
  }
58
+ } else {
59
+ logger.warn(
60
+ `JLink is not installed. Please install JLink from: https://www.segger.com/downloads/jlink`
61
+ );
60
62
  }
61
63
 
62
64
  if (!udevInstalled()) {
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2023 Nordic Semiconductor ASA
3
+ *
4
+ * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
5
+ */
6
+
7
+ import { type AppDetailsFromLauncher, inMain } from '../../ipc/appDetails';
8
+ import { isLauncher } from './packageJson';
9
+
10
+ let cached: AppDetailsFromLauncher;
11
+
12
+ export default async () => {
13
+ if (isLauncher()) {
14
+ throw new Error('Must not be called by the launcher.');
15
+ }
16
+
17
+ if (cached == null) {
18
+ cached = await inMain.getAppDetails();
19
+ }
20
+
21
+ return cached;
22
+ };
@@ -4,12 +4,12 @@
4
4
  * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
5
5
  */
6
6
 
7
- import { getGlobal } from '@electron/remote';
8
7
  import path from 'path';
9
8
 
10
- import packageJson from './packageJson';
9
+ import launcherConfig from './launcherConfig';
10
+ import { packageJsonApp } from './packageJson';
11
11
 
12
- const getUserDataDir = () => getGlobal('userDataDir');
12
+ const getUserDataDir = () => launcherConfig().userDataDir;
13
13
 
14
14
  /**
15
15
  * Get the filesystem path of the currently loaded app.
@@ -17,7 +17,7 @@ const getUserDataDir = () => getGlobal('userDataDir');
17
17
  * @returns {string|undefined} Absolute path of current app.
18
18
  */
19
19
  const getAppDir = () => {
20
- const html = packageJson().nrfConnectForDesktop.html;
20
+ const html = packageJsonApp().nrfConnectForDesktop.html;
21
21
  const dir = path.parse(html).dir;
22
22
  return path.parse(__filename).dir.replace(dir, '');
23
23
  };
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) 2023 Nordic Semiconductor ASA
3
+ *
4
+ * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
5
+ */
6
+
7
+ import { type Configuration, inMain } from '../../ipc/launcherConfig';
8
+
9
+ let cachedConfig: Configuration;
10
+
11
+ export default () => {
12
+ if (cachedConfig == null) {
13
+ cachedConfig = inMain.getConfig();
14
+ }
15
+
16
+ return cachedConfig;
17
+ };
@@ -91,7 +91,7 @@ export default async () => {
91
91
  `It looks like you have installed JLink using ${JLinkInstallerVersion}, but currently we only support their Universal Installer for your system.`
92
92
  );
93
93
  logger.warn(
94
- `Please install JLink: https://www.segger.com/downloads/jlink/JLink_MacOSX_V780c_universal.pkg`
94
+ `Please install JLink: https://www.segger.com/downloads/jlink/JLink_MacOSX_V788j_universal.pkg`
95
95
  );
96
96
  }
97
97
  }
@@ -6,26 +6,68 @@
6
6
 
7
7
  import {
8
8
  type PackageJson,
9
+ type PackageJsonApp,
9
10
  parsePackageJson,
11
+ parsePackageJsonApp,
10
12
  } from '../../ipc/schema/packageJson';
11
13
 
12
- let cache: PackageJson | undefined;
14
+ let cache:
15
+ | undefined
16
+ | { type: 'launcher'; data: PackageJson }
17
+ | { type: 'app'; data: PackageJsonApp };
13
18
 
14
- const parsedPackageJson = () => {
19
+ export const isLauncher = (packageJson = parsedPackageJson()) =>
20
+ packageJson.name === 'nrfconnect';
21
+
22
+ const parsedPackageJson = (): PackageJson | PackageJsonApp => {
15
23
  if (cache != null) {
16
- return cache;
24
+ return cache.data;
17
25
  }
18
26
 
19
- const parsed = parsePackageJson(process.env.PACKAGE_JSON_OF_APP ?? 'null');
20
- if (parsed.success) {
21
- cache = parsed.data;
22
- } else {
27
+ const unparsed = process.env.PACKAGE_JSON ?? 'null';
28
+
29
+ const parsed = parsePackageJson(unparsed);
30
+
31
+ if (!parsed.success) {
23
32
  throw new Error(
24
- `The env variable PACKAGE_JSON_OF_APP must be defined during bundling (through the bundler settings) with a valid package.json but wasn't. Fix this. Error: ${parsed.error.message}`
33
+ `The env variable PACKAGE_JSON must be defined during bundling (through the bundler settings) with a valid package.json but wasn't. Error: ${parsed.error.message}`
25
34
  );
26
35
  }
27
36
 
28
- return cache;
37
+ if (isLauncher(parsed.data)) {
38
+ cache = {
39
+ type: 'launcher',
40
+ data: parsed.data,
41
+ };
42
+ } else {
43
+ const parsedAppPackageJson = parsePackageJsonApp(unparsed);
44
+ if (!parsedAppPackageJson.success) {
45
+ throw new Error(
46
+ `The package.json must contain all values required for an app. Error: ${parsedAppPackageJson.error.message}`
47
+ );
48
+ }
49
+
50
+ cache = {
51
+ type: 'app',
52
+ data: parsedAppPackageJson.data,
53
+ };
54
+ }
55
+
56
+ return cache.data;
29
57
  };
30
58
 
31
- export default () => parsedPackageJson();
59
+ export const packageJson = parsedPackageJson;
60
+
61
+ export const packageJsonApp = () => {
62
+ parsedPackageJson();
63
+
64
+ if (cache?.type !== 'app') {
65
+ throw new Error(
66
+ `Required the package.json of an app. Actual content: ${JSON.stringify(
67
+ cache
68
+ )}`
69
+ );
70
+ }
71
+
72
+ return cache.data;
73
+ };
@@ -10,8 +10,9 @@ import { SerialPortOpenOptions } from 'serialport';
10
10
  import { v4 as uuid } from 'uuid';
11
11
 
12
12
  import { inMain as safeStorage } from '../../ipc/safeStorage';
13
+ import { type Device } from '../Device/deviceSlice';
13
14
  import logger from '../logging';
14
- import packageJson from './packageJson';
15
+ import { packageJson } from './packageJson';
15
16
 
16
17
  export interface SerialSettings {
17
18
  serialPortOptions: Omit<SerialPortOpenOptions<AutoDetectTypes>, 'path'>;
@@ -89,24 +90,30 @@ export const getPersistedSerialPortSettings = (
89
90
  return sharedStore.get(`${serialNumber}.${appName}`);
90
91
  };
91
92
  export const persistTerminalSettings = (
92
- serialNumber: string,
93
+ device: Device,
93
94
  vComIndex: number,
94
95
  terminalSettings: TerminalSettings
95
- ) =>
96
- sharedStore.set(
97
- `${serialNumber}.vCom-${vComIndex}.TerminalSettings`,
98
- terminalSettings
99
- );
96
+ ) => {
97
+ if (device.serialNumber) {
98
+ sharedStore.set(
99
+ `${device.serialNumber}.vCom-${vComIndex}.TerminalSettings`,
100
+ terminalSettings
101
+ );
102
+ }
103
+ };
100
104
  export const getPersistedTerminalSettings = (
101
- serialNumber: string,
105
+ device: Device,
102
106
  vComIndex: number
103
107
  ): TerminalSettings | undefined => {
104
- logger.info(
105
- `Get terminal settings from persistent store ${serialNumber}.vCom-${vComIndex}.TerminalSettings`
106
- );
107
- return sharedStore.get(
108
- `${serialNumber}.vCom-${vComIndex}.TerminalSettings`
109
- );
108
+ if (device.serialNumber) {
109
+ logger.info(
110
+ `Get terminal settings from persistent store ${device.serialNumber}.vCom-${vComIndex}.TerminalSettings`
111
+ );
112
+ return sharedStore.get(
113
+ `${device.serialNumber}.vCom-${vComIndex}.TerminalSettings`
114
+ );
115
+ }
116
+ return undefined;
110
117
  };
111
118
 
112
119
  export const persistIsSendingUsageData = (value: boolean) =>
@@ -8,7 +8,7 @@ import fs from 'fs';
8
8
  import { EOL } from 'os';
9
9
  import path from 'path';
10
10
  import pretty from 'prettysize';
11
- import type Systeminformation from 'systeminformation';
11
+ import si from 'systeminformation';
12
12
 
13
13
  import NrfutilDeviceLib from '../../nrfutil/device/device';
14
14
  import {
@@ -25,8 +25,6 @@ import { getAppDataDir } from './appDirs';
25
25
  import { openFile } from './open';
26
26
 
27
27
  const generalInfoReport = async () => {
28
- // eslint-disable-next-line global-require
29
- const si = require('systeminformation') as typeof Systeminformation;
30
28
  const [
31
29
  { manufacturer, model },
32
30
  { vendor, version },
@@ -89,7 +87,7 @@ const allDevicesReport = (allDevices: Device[] = []) => [
89
87
  ...allDevices.map(
90
88
  d =>
91
89
  ` - ${d.serialNumber} ${
92
- d.jlink?.boardVersion || ''
90
+ d.devkit?.boardVersion || ''
93
91
  }: ${d.serialPorts?.map(s => s.comName).join(', ')}`
94
92
  ),
95
93
  '',
@@ -129,14 +127,14 @@ export const generateSystemReport = async (
129
127
  export default async (
130
128
  allDevices: Device[],
131
129
  currentSerialNumber: string,
132
- currentDevice: Device | null
130
+ currentDevice?: Device
133
131
  ) => {
134
132
  logger.info('Generating system report...');
135
133
  const timestamp = new Date().toISOString().replace(/:/g, '-');
136
134
  const report = await generateSystemReport(
137
135
  timestamp,
138
136
  allDevices,
139
- currentDevice ?? undefined,
137
+ currentDevice,
140
138
  currentSerialNumber
141
139
  );
142
140
 
@@ -4,206 +4,114 @@
4
4
  * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
5
5
  */
6
6
 
7
- import { ApplicationInsights } from '@microsoft/applicationinsights-web';
8
- import type Systeminformation from 'systeminformation';
9
- import winston from 'winston';
7
+ import si from 'systeminformation';
10
8
 
11
- import { isDevelopment } from './environment';
9
+ import { packageJson } from './packageJson';
12
10
  import {
13
11
  deleteIsSendingUsageData,
14
- getIsSendingUsageData,
15
- getUsageDataClientId,
16
12
  persistIsSendingUsageData,
17
13
  } from './persistentStore';
18
-
19
- const instrumentationKey = '4b8b1a39-37c7-479e-a684-d4763c7c647c';
20
-
21
- interface EventAction {
22
- action: string;
23
- label?: string;
24
- }
25
-
26
- let eventQueue: EventAction[] = [];
27
- let insights: ApplicationInsights | undefined;
28
-
29
- /**
30
- * Initialize instance to send user data
31
- * @param {*} packageJson the app's package json
32
- *
33
- * @returns {Promise<void>} void
34
- */
35
- export const init = (packageJson: { name: string; version: string }) => {
36
- const applicationName = isDevelopment
37
- ? `${packageJson.name}-dev`
38
- : packageJson.name;
39
- const applicationVersion = packageJson.version;
40
-
41
- if (!getIsSendingUsageData()) return;
42
-
43
- const accountId = getUsageDataClientId();
44
-
45
- insights = new ApplicationInsights({
46
- config: {
47
- instrumentationKey,
48
- accountId,
49
- },
50
- });
51
-
52
- insights.loadAppInsights();
53
- insights.trackPageView({ name: applicationName });
54
-
55
- // Add app name and version to every event
56
- insights.addTelemetryInitializer(envelope => {
57
- const trace = {
58
- ...(envelope.ext?.trace ?? {}),
59
- name: applicationName,
60
- };
61
- envelope.ext = { ...envelope.ext, trace };
62
- envelope.data = {
63
- ...envelope.data,
64
- applicationName,
65
- applicationVersion,
66
- };
14
+ import usageDataCommon, { Metadata } from './usageDataCommon';
15
+ import usageDataMain from './usageDataMain';
16
+ import usageDataRenderer from './usageDataRenderer';
17
+
18
+ const getFriendlyAppName = () =>
19
+ packageJson().name.replace('pc-nrfconnect-', '');
20
+
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ const flattenObject = (obj?: any, parentKey?: string) => {
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ let result: any = {};
25
+
26
+ if (!obj) return result;
27
+
28
+ Object.keys(obj).forEach(key => {
29
+ const value = obj[key];
30
+ const newKey = parentKey ? `${parentKey}.${key}` : key;
31
+ if (typeof value === 'object') {
32
+ result = { ...result, ...flattenObject(value, newKey) };
33
+ } else {
34
+ result[newKey] = value;
35
+ }
67
36
  });
68
37
 
69
- logger?.debug(
70
- `Application Insights for category ${applicationName} has initialized`
71
- );
72
-
73
- // Add 5 second delay to prevent inital rendering from beeing frozen.
74
- setTimeout(async () => {
75
- // eslint-disable-next-line global-require
76
- const si = require('systeminformation') as typeof Systeminformation;
77
- sendUsageData('architecture', (await si.osInfo()).arch);
78
- }, 5_000);
79
- };
80
-
81
- /**
82
- * Checks if usage report instance is initialized and ready to be sent
83
- *
84
- * @returns {Boolean} returns whether the setting is on, off or undefined
85
- */
86
- export const isInitialized = () => {
87
- logger?.debug(
88
- `Usage report instance is${
89
- insights !== undefined ? '' : ' not'
90
- } initialized`
91
- );
92
- return insights !== undefined;
93
- };
94
-
95
- /**
96
- * Check the status of usage data
97
- *
98
- * @returns {Boolean | undefined} returns whether the setting is on, off or undefined
99
- */
100
- export const isEnabled = () => {
101
- const isSendingUsageData = getIsSendingUsageData();
102
- logger?.debug(`Usage data is ${isSendingUsageData}`);
103
- return isSendingUsageData;
38
+ return result;
104
39
  };
105
40
 
106
- /**
107
- * Enable sending usage data
108
- *
109
- * @returns {void}
110
- */
111
- export const enable = () => {
41
+ const enable = () => {
112
42
  persistIsSendingUsageData(true);
113
- logger?.debug('Usage data has been enabled');
43
+ si.osInfo().then(({ platform, arch }) =>
44
+ getUsageData().sendUsageData('Report OS info', { platform, arch })
45
+ );
46
+ getUsageData().sendUsageData('Data Usage Opt-In', undefined);
47
+ usageDataCommon.getLogger()?.debug('Usage data has been enabled');
114
48
  };
115
49
 
116
- /**
117
- * Disable sending usage data
118
- *
119
- * @returns {void}
120
- */
121
- export const disable = () => {
50
+ const disable = () => {
51
+ getUsageData().sendUsageData('Data Usage Opt-Out', undefined, true);
122
52
  persistIsSendingUsageData(false);
123
- logger?.debug('Usage data has been disabled');
53
+ usageDataCommon.getLogger()?.debug('Usage data has been disabled');
124
54
  };
125
55
 
126
- /**
127
- * Reset settings so that launcher is able to
128
- * ask the user to enable or disable sending usage data
129
- *
130
- * @returns {void}
131
- */
132
- export const reset = () => {
56
+ const reset = () => {
57
+ getUsageData().sendUsageData('Data Usage Opt-Reset', undefined, true);
133
58
  deleteIsSendingUsageData();
134
- logger?.debug('Usage data setting has been reset');
59
+ usageDataCommon.getLogger()?.debug('Usage data setting has been reset');
135
60
  };
136
61
 
137
- /**
138
- * Send event
139
- * @param {EventAction} event the event to send
140
- *
141
- * @returns {void}
142
- */
143
- const sendEvent = ({ action, label }: EventAction) => {
144
- const isSendingUsageData = getIsSendingUsageData();
145
-
146
- if (isSendingUsageData && insights !== undefined) {
147
- logger?.debug(`Sending usage data ${action} ${label}`);
148
- insights.trackEvent({
149
- name: action,
150
- properties: label ? { label } : undefined,
151
- });
62
+ const isRenderer = process && process.type === 'renderer';
63
+
64
+ const getUsageData = () => {
65
+ if (isRenderer) {
66
+ return usageDataRenderer;
152
67
  }
68
+
69
+ return usageDataMain;
153
70
  };
154
71
 
155
- /**
156
- * Send usage data event to Application Insights
157
- * @param {string} action The event action
158
- * @param {string} label The event label
159
- * @returns {void}
160
- */
161
- export const sendUsageData = <T extends string>(action: T, label?: string) => {
162
- eventQueue.push({ action, label });
163
- if (!isInitialized()) {
164
- return;
72
+ const sendUsageData = async (
73
+ action: string,
74
+ metadata?: Metadata,
75
+ forceSend?: boolean
76
+ ) => {
77
+ if (
78
+ await getUsageData().sendUsageData(
79
+ `${getFriendlyAppName()}: ${action}`,
80
+ flattenObject(metadata),
81
+ forceSend
82
+ )
83
+ ) {
84
+ usageDataCommon
85
+ .getLogger()
86
+ ?.debug(`Sending usage data ${JSON.stringify(action)}`);
165
87
  }
166
- eventQueue.forEach(sendEvent);
167
- eventQueue = [];
168
88
  };
169
89
 
170
- export const sendMetric = (name: string, average: number) => {
171
- insights?.trackMetric({
172
- name,
173
- average,
174
- });
175
- };
90
+ const sendPageView = (pageName: string) =>
91
+ getUsageData().sendPageView(`${getFriendlyAppName()} - ${pageName}`);
176
92
 
177
- export const sendTrace = (message: string) => {
178
- insights?.trackTrace({
179
- message,
180
- });
181
- };
93
+ const sendMetric = (name: string, average: number) =>
94
+ getUsageData().sendMetric(name, average);
182
95
 
183
- /**
184
- * Send error usage data event to Application Insights and also show it in the logger view
185
- * @param {string} error The event action
186
- * @returns {void}
187
- */
188
- export const sendErrorReport = (error: string) => {
189
- logger?.error(error);
190
- insights?.trackException({
191
- exception: new Error(error),
192
- });
193
- };
96
+ const sendTrace = (message: string) => getUsageData().sendTrace(message);
194
97
 
195
- let logger: winston.Logger | undefined;
196
- export const setUsageLogger = (log: winston.Logger) => {
197
- logger = log;
98
+ const sendErrorReport = (error: string | Error) => {
99
+ usageDataCommon.getLogger()?.error(error);
100
+ return getUsageData().sendErrorReport(
101
+ typeof error === 'string' ? new Error(error) : error
102
+ );
198
103
  };
199
104
 
200
105
  export default {
106
+ setLogger: usageDataCommon.setLogger,
201
107
  disable,
202
108
  enable,
203
- init,
204
- isEnabled,
205
- isInitialized,
109
+ isEnabled: usageDataCommon.isEnabled,
206
110
  reset,
207
111
  sendErrorReport,
208
112
  sendUsageData,
113
+ sendPageView,
114
+ sendMetric,
115
+ sendTrace,
116
+ enableTelemetry: usageDataCommon.enableTelemetry,
209
117
  };