@onekeyfe/hd-core 1.2.0-alpha.56 → 1.2.0-alpha.58

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 (36) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +84 -2
  2. package/__tests__/DeviceCommands.test.ts +17 -6
  3. package/__tests__/core-initialization.test.ts +23 -0
  4. package/__tests__/device-connector-protocol.test.ts +81 -0
  5. package/__tests__/device-settings.test.ts +39 -18
  6. package/__tests__/protocol-v2-resources.test.ts +24 -0
  7. package/__tests__/protocol-v2.test.ts +46 -1
  8. package/__tests__/protocolV2FileWrite.test.ts +113 -0
  9. package/dist/api/FirmwareUpdateV4.d.ts +0 -1
  10. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  11. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  12. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  13. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -2
  14. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  15. package/dist/api/helpers/protocolV2FileWrite.d.ts +7 -0
  16. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/data-manager/DataManager.d.ts +1 -0
  19. package/dist/data-manager/DataManager.d.ts.map +1 -1
  20. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  21. package/dist/device/DeviceCommands.d.ts.map +1 -1
  22. package/dist/device/DeviceConnector.d.ts +2 -1
  23. package/dist/device/DeviceConnector.d.ts.map +1 -1
  24. package/dist/index.d.ts +3 -1
  25. package/dist/index.js +448 -336
  26. package/package.json +4 -4
  27. package/src/api/FirmwareUpdateV4.ts +39 -69
  28. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +3 -1
  29. package/src/api/device/DeviceSettings.ts +5 -4
  30. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +12 -1
  31. package/src/api/helpers/protocolV2FileWrite.ts +192 -73
  32. package/src/core/index.ts +9 -6
  33. package/src/data-manager/DataManager.ts +25 -4
  34. package/src/data-manager/TransportManager.ts +6 -0
  35. package/src/device/DeviceCommands.ts +20 -2
  36. package/src/device/DeviceConnector.ts +33 -13
@@ -91,11 +91,93 @@ describe('AllNetworkGetAddressBase tracing', () => {
91
91
  0
92
92
  );
93
93
 
94
- expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined);
94
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith(
95
+ 'hidden-state',
96
+ false,
97
+ undefined,
98
+ false
99
+ );
95
100
  expect(calls).toEqual(['resume-hidden-session', 'run-chain-method']);
96
101
  expect(typedCall).not.toHaveBeenCalled();
97
102
  });
98
103
 
104
+ test('resumes a Protocol V2 Cardano hidden wallet with the Cardano seed domain', async () => {
105
+ const calls: string[] = [];
106
+ const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
107
+ calls.push('resume-cardano-session');
108
+ return Promise.resolve(true);
109
+ });
110
+ const innerMethod = {
111
+ checkSafetyLevelOnTestNet: jest.fn().mockResolvedValue(false),
112
+ connectId: 'connect-id',
113
+ deviceId: 'device-id',
114
+ getVersionRange: jest.fn().mockReturnValue({}),
115
+ assertProtocolSupported: jest.fn(),
116
+ init: jest.fn(),
117
+ name: 'cardanoGetAddress',
118
+ responseID: 45,
119
+ unlockPolicy: 'unlock-before-run',
120
+ run: jest.fn().mockImplementation(() => {
121
+ calls.push('run-cardano-method');
122
+ return Promise.resolve([{ address: 'addr1hidden' }]);
123
+ }),
124
+ setDevice: jest.fn(),
125
+ strictCheckDeviceSupport: false,
126
+ };
127
+ (findMethod as jest.Mock).mockReturnValue(innerMethod);
128
+ const method = new TestAllNetworkMethod({
129
+ id: 5,
130
+ payload: {
131
+ method: 'allNetworkGetAddress',
132
+ connectId: 'connect-id',
133
+ deviceId: 'device-id',
134
+ passphraseState: 'hidden-state',
135
+ bundle: [],
136
+ },
137
+ });
138
+ method.protocolV2UnlockContext = { preflightCompleted: true };
139
+ const typedCall = jest.fn();
140
+ method.device = {
141
+ checkPassphraseStateSafety,
142
+ commands: {
143
+ typedCall,
144
+ },
145
+ getCurrentFirmwareType: jest.fn(),
146
+ getProtocol: jest.fn().mockReturnValue('V2'),
147
+ getCurrentFirmwareVersionString: jest.fn().mockReturnValue('1.0.0'),
148
+ getCurrentMethodVersionRange: jest
149
+ .fn()
150
+ .mockImplementation((getRange: (type: string) => unknown) => getRange('pro2')),
151
+ instanceId: 'device-instance',
152
+ isProtocolV2: jest.fn().mockReturnValue(true),
153
+ isBootloader: jest.fn().mockReturnValue(false),
154
+ isRomloader: jest.fn().mockReturnValue(false),
155
+ off: jest.fn(),
156
+ on: jest.fn(),
157
+ state: { status: { unlocked: true } },
158
+ updateProtocolV2Status: jest.fn(),
159
+ } as any;
160
+
161
+ await method.callMethod(
162
+ 'cardanoGetAddress',
163
+ {
164
+ bundle: [
165
+ {
166
+ _originRequestParams: {
167
+ network: 'ada',
168
+ path: "m/1852'/1815'/0'/0/0",
169
+ },
170
+ },
171
+ ],
172
+ },
173
+ 0
174
+ );
175
+
176
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith('hidden-state', false, undefined, true);
177
+ expect(calls).toEqual(['resume-cardano-session', 'run-cardano-method']);
178
+ expect(typedCall).not.toHaveBeenCalled();
179
+ });
180
+
99
181
  test('resumes a Protocol V2 standard wallet before running a nested chain method', async () => {
100
182
  const calls: string[] = [];
101
183
  const checkPassphraseStateSafety = jest.fn().mockImplementation(() => {
@@ -168,7 +250,7 @@ describe('AllNetworkGetAddressBase tracing', () => {
168
250
  0
169
251
  );
170
252
 
171
- expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined);
253
+ expect(checkPassphraseStateSafety).toHaveBeenCalledWith(undefined, true, undefined, false);
172
254
  expect(calls).toEqual(['resume-standard-session', 'run-chain-method']);
173
255
  expect(typedCall).not.toHaveBeenCalled();
174
256
  });
@@ -363,9 +363,14 @@ describe('DeviceCommands failure mapping', () => {
363
363
  }
364
364
  );
365
365
 
366
- it.each(['Cancelled', 'User cancelled typed data signing'])(
367
- 'maps the Protocol V2 MP engine cancellation response "%s" to ActionCancelled',
368
- async message => {
366
+ it.each([
367
+ ['SignTx', 'Rejected by the user'],
368
+ ['EthereumSignTypedDataOneKey', ''],
369
+ ['SolanaSignTx', 'Localized cancellation message'],
370
+ ['GetAddress', 'Address confirmation rejected'],
371
+ ] as const)(
372
+ 'maps Protocol V2 cancellation subcode 1 for %s regardless of message',
373
+ async (callType, message) => {
369
374
  const commands = createCommands();
370
375
 
371
376
  await expect(
@@ -378,7 +383,7 @@ describe('DeviceCommands failure mapping', () => {
378
383
  message,
379
384
  },
380
385
  } as any,
381
- 'SignTx'
386
+ callType
382
387
  )
383
388
  ).rejects.toMatchObject({
384
389
  errorCode: HardwareErrorCode.ActionCancelled,
@@ -401,6 +406,7 @@ describe('DeviceCommands failure mapping', () => {
401
406
  type: 'Failure',
402
407
  message: {
403
408
  code: 'Failure_ProcessError',
409
+ subcode: 1,
404
410
  message: 'Cancelled on device',
405
411
  },
406
412
  } as any,
@@ -411,7 +417,7 @@ describe('DeviceCommands failure mapping', () => {
411
417
  });
412
418
  });
413
419
 
414
- it('keeps an unrecognized Protocol V2 process subcode generic', async () => {
420
+ it('maps the DeviceError subcode 1 exception to DeviceBusy', async () => {
415
421
  const commands = createCommands();
416
422
 
417
423
  await expect(
@@ -427,7 +433,12 @@ describe('DeviceCommands failure mapping', () => {
427
433
  'DeviceSettingsPageShow'
428
434
  )
429
435
  ).rejects.toMatchObject({
430
- errorCode: HardwareErrorCode.RuntimeError,
436
+ errorCode: HardwareErrorCode.DeviceBusy,
437
+ params: {
438
+ failureCode: 'Failure_ProcessError',
439
+ subcode: 1,
440
+ firmwareMessage: 'Another process error',
441
+ },
431
442
  });
432
443
  });
433
444
 
@@ -0,0 +1,23 @@
1
+ import { DataManager } from '../src/data-manager';
2
+ import { init } from '../src/core';
3
+
4
+ import type { ConnectSettings } from '../src/types';
5
+
6
+ jest.mock('../src/data/config', () => ({
7
+ getSDKVersion: jest.fn(() => '1.0.0-test'),
8
+ DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0-test/',
9
+ }));
10
+
11
+ describe('Core initialization', () => {
12
+ afterEach(() => {
13
+ jest.restoreAllMocks();
14
+ });
15
+
16
+ it('does not create a partially initialized core when settings loading fails', async () => {
17
+ jest.spyOn(DataManager, 'load').mockRejectedValue(new Error('settings load failed'));
18
+
19
+ await expect(init({} as ConnectSettings, class TestTransport {})).rejects.toThrow(
20
+ 'settings load failed'
21
+ );
22
+ });
23
+ });
@@ -0,0 +1,81 @@
1
+ import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+
3
+ import DeviceConnector from '../src/device/DeviceConnector';
4
+
5
+ jest.mock('../src/data-manager/TransportManager', () => ({
6
+ __esModule: true,
7
+ default: {
8
+ load: jest.fn(),
9
+ getTransport: jest.fn(),
10
+ },
11
+ }));
12
+
13
+ jest.mock('../src/data-manager', () => ({
14
+ DataManager: {
15
+ getSettings: jest.fn(() => 'desktop-web-ble'),
16
+ isBleConnect: jest.fn(() => true),
17
+ },
18
+ }));
19
+
20
+ jest.mock('../src/device/DevicePool', () => ({
21
+ DevicePool: {
22
+ setConnector: jest.fn(),
23
+ },
24
+ }));
25
+
26
+ const transportManagerMock: {
27
+ default: {
28
+ getTransport: jest.Mock;
29
+ };
30
+ } = jest.requireMock('../src/data-manager/TransportManager');
31
+
32
+ describe('DeviceConnector protocol validation', () => {
33
+ beforeEach(() => {
34
+ jest.clearAllMocks();
35
+ });
36
+
37
+ it('reports an explicit transport error when connector initialization ran too early', async () => {
38
+ transportManagerMock.default.getTransport.mockReturnValue(undefined);
39
+ const connector = new DeviceConnector();
40
+
41
+ await expect(connector.enumerate()).rejects.toMatchObject({
42
+ errorCode: HardwareErrorCode.TransportNotConfigured,
43
+ });
44
+ });
45
+
46
+ it('uses the actively probed protocol returned by acquire when the cache was cleared', async () => {
47
+ const acquire = jest.fn().mockResolvedValue({
48
+ id: 'pro2-id',
49
+ path: 'pro2-id',
50
+ protocolType: 'V2',
51
+ });
52
+ transportManagerMock.default.getTransport.mockReturnValue({
53
+ acquire,
54
+ getProtocolType: jest.fn(() => undefined),
55
+ });
56
+ const connector = new DeviceConnector();
57
+
58
+ await expect(connector.acquire('pro2-id', undefined, undefined, 'V2')).resolves.toEqual(
59
+ expect.objectContaining({ protocolType: 'V2' })
60
+ );
61
+ expect(acquire).toHaveBeenCalledWith(
62
+ expect.objectContaining({ uuid: 'pro2-id', expectedProtocol: 'V2' })
63
+ );
64
+ });
65
+
66
+ it('still rejects a real mismatch reported by the active protocol probe', async () => {
67
+ transportManagerMock.default.getTransport.mockReturnValue({
68
+ acquire: jest.fn().mockResolvedValue({
69
+ id: 'classic-id',
70
+ path: 'classic-id',
71
+ protocolType: 'V1',
72
+ }),
73
+ getProtocolType: jest.fn(() => 'V1'),
74
+ });
75
+ const connector = new DeviceConnector();
76
+
77
+ await expect(connector.acquire('classic-id', undefined, undefined, 'V2')).rejects.toThrow(
78
+ 'Device protocol mismatch: expected V2, detected V1'
79
+ );
80
+ });
81
+ });
@@ -115,8 +115,8 @@ describe('DeviceSettings protocol routing', () => {
115
115
  );
116
116
  });
117
117
 
118
- it('uses DeviceSettingsSet and commits the confirmed patch for Protocol V2', async () => {
119
- const { device, typedCall, updateState } = createDevice({ protocol: 'V2' });
118
+ it('uses DeviceSettingsSet and reloads Protocol V2 status and settings from the device', async () => {
119
+ const { device, typedCall, updateState, getDeviceState } = createDevice({ protocol: 'V2' });
120
120
  const method = new DeviceSettings({
121
121
  id: 2,
122
122
  payload: {
@@ -141,21 +141,10 @@ describe('DeviceSettings protocol routing', () => {
141
141
  haptic_feedback: true,
142
142
  },
143
143
  });
144
- expect(updateState).toHaveBeenCalledWith(
145
- {
146
- identity: { label: 'Shared Label' },
147
- settings: {
148
- language: 'ja',
149
- bleEnabled: true,
150
- autoLockDelayMs: 60_000,
151
- hapticFeedback: true,
152
- },
153
- },
154
- 'settings-write'
155
- );
156
- expect(typedCall.mock.calls.map(call => call[0])).not.toEqual(
157
- expect.arrayContaining(['DeviceInfoGet', 'DeviceStatusGet', 'DeviceSettingsGet'])
158
- );
144
+ expect(getDeviceState).toHaveBeenCalledWith({
145
+ refreshSections: ['status', 'settings'],
146
+ });
147
+ expect(updateState).not.toHaveBeenCalled();
159
148
  });
160
149
 
161
150
  it('uses the Pro2 passphrase page as a device-side toggle and verifies the target state', async () => {
@@ -183,7 +172,39 @@ describe('DeviceSettings protocol routing', () => {
183
172
  });
184
173
  expect(typedCall).not.toHaveBeenCalledWith('DeviceSettingsSet', 'Success', expect.anything());
185
174
  expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['status'] });
186
- expect(getDeviceState).toHaveBeenNthCalledWith(2, { refreshSections: ['status'] });
175
+ expect(getDeviceState).toHaveBeenNthCalledWith(2, {
176
+ refreshSections: ['status', 'settings'],
177
+ });
178
+ });
179
+
180
+ it('reloads Protocol V2 status and settings after changing air-gap mode', async () => {
181
+ const { device, typedCall, getDeviceState } = createDevice({ protocol: 'V2' });
182
+ getDeviceState
183
+ .mockResolvedValueOnce({
184
+ settings: { airgapMode: false },
185
+ })
186
+ .mockResolvedValueOnce({
187
+ status: { unlocked: true },
188
+ settings: { airgapMode: true },
189
+ });
190
+ const method = new DeviceSettings({
191
+ id: 4,
192
+ payload: {
193
+ method: 'deviceSettings',
194
+ airgapMode: true,
195
+ },
196
+ });
197
+ method.init();
198
+ (method as any).device = device;
199
+
200
+ await expect(method.run()).resolves.toEqual({ message: 'Success' });
201
+ expect(typedCall).toHaveBeenCalledWith('DeviceSettingsPageShow', 'Success', {
202
+ page: DeviceSettingsPage.DeviceAirgap,
203
+ });
204
+ expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['settings'] });
205
+ expect(getDeviceState).toHaveBeenNthCalledWith(2, {
206
+ refreshSections: ['status', 'settings'],
207
+ });
187
208
  });
188
209
 
189
210
  it('does not open a Pro2 settings page when the hardware already matches the target', async () => {
@@ -269,6 +269,30 @@ describe('Pro2 resource configuration', () => {
269
269
  expect(DataManager.getProtocolV2BootResources()).toEqual(bootResources);
270
270
  });
271
271
 
272
+ test('keeps base SDK initialization available when remote Pro2 resources are invalid', async () => {
273
+ const remoteConfig = createRemoteConfig();
274
+ (remoteConfig.pro2 as { resources?: unknown }).resources = { stable: [] };
275
+ const configFetcher = jest.fn().mockResolvedValue(remoteConfig);
276
+
277
+ await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
278
+
279
+ expect(DataManager.getProtocolV2Resources()).toBeUndefined();
280
+ expect(DataManager.getProtocolV2BootResources()).toBeUndefined();
281
+ });
282
+
283
+ test('still blocks firmware mutation when the refreshed Pro2 resources are invalid', async () => {
284
+ const remoteConfig = createRemoteConfig();
285
+ (remoteConfig.pro2 as { resources?: unknown }).resources = { stable: [] };
286
+ const settings = createSettings(jest.fn().mockResolvedValue(remoteConfig));
287
+ DataManager.settings = settings;
288
+
289
+ await expect(DataManager.forceReloadData()).rejects.toMatchObject({
290
+ errorCode: HardwareErrorCode.NetworkError,
291
+ message: expect.stringContaining('Invalid Pro2 resources config'),
292
+ });
293
+ expect(DataManager.lastCheckTimestamp).toBe(0);
294
+ });
295
+
272
296
  test('does not advance the cache timestamp when refresh fails', async () => {
273
297
  jest.spyOn(axios, 'get').mockRejectedValue(new Error('offline'));
274
298
  const settings = createSettings(jest.fn().mockResolvedValue(null));
@@ -4092,6 +4092,38 @@ describe('Protocol V2 firmware update targets', () => {
4092
4092
  expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
4093
4093
  });
4094
4094
 
4095
+ test('announces bootloader success only after Protocol V2 bootloader mode is confirmed', async () => {
4096
+ const method = new FirmwareUpdateV4({
4097
+ id: 1,
4098
+ payload: {
4099
+ method: 'firmwareUpdateV4',
4100
+ },
4101
+ });
4102
+ (method as any).device = stubDevice({
4103
+ features: { bootloader_mode: false, capabilities: [] },
4104
+ isBootloader: () => false,
4105
+ isRomloader: () => false,
4106
+ });
4107
+ (method as any).protocolV2Reboot = jest.fn().mockResolvedValue({
4108
+ message: 'Device rebooted successfully',
4109
+ });
4110
+
4111
+ const tipMessages: string[] = [];
4112
+ method.postTipMessage = jest.fn((message: string) => {
4113
+ tipMessages.push(message);
4114
+ });
4115
+ let successWasAnnouncedBeforeConfirmation = false;
4116
+ (method as any).waitForProtocolV2BootloaderMode = jest.fn().mockImplementation(() => {
4117
+ successWasAnnouncedBeforeConfirmation = tipMessages.includes('GoToBootloaderSuccess');
4118
+ return Promise.resolve({ mode: 'bootloader' });
4119
+ });
4120
+
4121
+ await (method as any).enterProtocolV2BootloaderMode();
4122
+
4123
+ expect(successWasAnnouncedBeforeConfirmation).toBe(false);
4124
+ expect(tipMessages).toEqual(['AutoRebootToBootloader', 'GoToBootloaderSuccess']);
4125
+ });
4126
+
4095
4127
  test('keeps Protocol V2 bootloader active before firmware transfer', async () => {
4096
4128
  const method = new FirmwareUpdateV4({
4097
4129
  id: 1,
@@ -4117,6 +4149,7 @@ describe('Protocol V2 firmware update targets', () => {
4117
4149
 
4118
4150
  expect((method as any).protocolV2Reboot).not.toHaveBeenCalled();
4119
4151
  expect(method.postTipMessage).not.toHaveBeenCalledWith('AutoRebootToBootloader');
4152
+ expect(method.postTipMessage).toHaveBeenCalledWith('GoToBootloaderSuccess');
4120
4153
  });
4121
4154
 
4122
4155
  test('keeps Protocol V2 romloader active before firmware transfer', async () => {
@@ -5913,8 +5946,9 @@ describe('Protocol V2 firmware update targets', () => {
5913
5946
 
5914
5947
  (method as any).device = stubDevice({
5915
5948
  getCommands: () => ({ typedCall }),
5949
+ toMessageObject: () => ({ connectId: 'firmware-device' }),
5916
5950
  });
5917
- method.postProgressMessage = jest.fn();
5951
+ method.postMessage = jest.fn();
5918
5952
 
5919
5953
  await (method as any).protocolV2CommonUpdateProcess({
5920
5954
  payload: new Uint8Array(4097).buffer,
@@ -5929,6 +5963,17 @@ describe('Protocol V2 firmware update targets', () => {
5929
5963
  expect(writePayloads.map(payload => payload.overwrite)).toEqual([true, false]);
5930
5964
  expect(writePayloads.every(payload => payload.append === false)).toBe(true);
5931
5965
  expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 100]);
5966
+ expect(method.postMessage).toHaveBeenLastCalledWith({
5967
+ event: 'UI_EVENT',
5968
+ type: UI_REQUEST.FIRMWARE_PROGRESS,
5969
+ payload: expect.objectContaining({
5970
+ progress: 99,
5971
+ progressType: 'transferData',
5972
+ transferredBytes: 4097,
5973
+ totalBytes: 4097,
5974
+ elapsedMs: expect.any(Number),
5975
+ }),
5976
+ });
5932
5977
  });
5933
5978
 
5934
5979
  test('restarts the whole file from offset zero after an ambiguous chunk write failure', async () => {
@@ -1,6 +1,8 @@
1
1
  import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
2
 
3
3
  import { writeProtocolV2File } from '../src/api/helpers/protocolV2FileWrite';
4
+ import { DataManager } from '../src/data-manager';
5
+ import { LoggerNames, getLogger } from '../src/utils/logger';
4
6
 
5
7
  jest.mock('../src/data/config', () => ({
6
8
  getSDKVersion: jest.fn(() => '1.0.0'),
@@ -65,6 +67,24 @@ describe('writeProtocolV2File', () => {
65
67
  ).rejects.toMatchObject({ errorCode: HardwareErrorCode.RuntimeError });
66
68
  });
67
69
 
70
+ test('拒绝非 FilesystemFile 响应', async () => {
71
+ const typedCall = jest.fn().mockResolvedValue({
72
+ type: 'CallMethodError',
73
+ message: { error: 'unexpected response' },
74
+ });
75
+
76
+ await expect(
77
+ writeProtocolV2File({
78
+ commands: { typedCall } as any,
79
+ path: 'vol1:/wallpapers/test.bin',
80
+ data: new Uint8Array([1]),
81
+ })
82
+ ).rejects.toMatchObject({
83
+ errorCode: HardwareErrorCode.RuntimeError,
84
+ message: 'FilesystemFileWrite received unexpected response CallMethodError',
85
+ });
86
+ });
87
+
68
88
  test('BLE 响应超时时原偏移重试且不重复上报进度', async () => {
69
89
  const timeoutError = Object.assign(new Error('Lowlevel response timeout'), {
70
90
  errorCode: HardwareErrorCode.BleTimeoutError,
@@ -90,6 +110,31 @@ describe('writeProtocolV2File', () => {
90
110
  expect(onProgress).toHaveBeenCalledTimes(1);
91
111
  });
92
112
 
113
+ test('支持固件上传的响应写入选项和全局设备进度', async () => {
114
+ const typedCall = jest.fn().mockResolvedValue({ message: { processed_byte: 3 } });
115
+ const getUiPercentage = jest.fn().mockReturnValue(42);
116
+
117
+ await writeProtocolV2File({
118
+ commands: { typedCall } as any,
119
+ path: 'vol0:/firmware.bin',
120
+ data: new Uint8Array([1, 2, 3]),
121
+ writeWithResponse: true,
122
+ getUiPercentage,
123
+ });
124
+
125
+ expect(getUiPercentage).toHaveBeenCalledWith({
126
+ offset: 0,
127
+ chunkLength: 3,
128
+ totalSize: 3,
129
+ });
130
+ expect(typedCall).toHaveBeenCalledWith(
131
+ 'FilesystemFileWrite',
132
+ 'FilesystemFile',
133
+ expect.objectContaining({ ui_percentage: 42 }),
134
+ { writeWithResponse: true }
135
+ );
136
+ });
137
+
93
138
  test('按确认分片的时间窗口记录实时传输速率', async () => {
94
139
  const data = new Uint8Array(4097);
95
140
  const typedCall = jest.fn().mockResolvedValue({ message: {} });
@@ -128,4 +173,72 @@ describe('writeProtocolV2File', () => {
128
173
  })
129
174
  );
130
175
  });
176
+
177
+ test('通过 Core Log 每十秒输出一次 BLE 传输关键指标', async () => {
178
+ const log = getLogger(LoggerNames.Method);
179
+ const logSpy = jest.spyOn(log, 'log').mockImplementation(() => undefined);
180
+ const getSettingsSpy = jest
181
+ .spyOn(DataManager, 'getSettings')
182
+ .mockReturnValue('react-native' as any);
183
+ const isBleConnectSpy = jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(true);
184
+ const data = new Uint8Array(5400);
185
+ const typedCall = jest.fn().mockResolvedValue({ message: {} });
186
+ const dateNowSpy = jest
187
+ .spyOn(Date, 'now')
188
+ .mockReturnValueOnce(1_000)
189
+ .mockReturnValueOnce(5_000)
190
+ .mockReturnValueOnce(11_000)
191
+ .mockReturnValueOnce(15_000);
192
+
193
+ try {
194
+ await writeProtocolV2File({
195
+ commands: { typedCall } as any,
196
+ path: 'vol1:/wallpapers/test.bin',
197
+ data,
198
+ });
199
+
200
+ expect(logSpy).toHaveBeenCalledTimes(2);
201
+ expect(logSpy).toHaveBeenNthCalledWith(
202
+ 1,
203
+ '[FileWrite] metrics transport=BLE status=progress bytes=3600/5400 elapsed=10.00s speed=0.35 KiB/s'
204
+ );
205
+ expect(logSpy).toHaveBeenNthCalledWith(
206
+ 2,
207
+ '[FileWrite] metrics transport=BLE status=completed bytes=5400/5400 elapsed=14.00s speed=0.44 KiB/s'
208
+ );
209
+ } finally {
210
+ dateNowSpy.mockRestore();
211
+ getSettingsSpy.mockRestore();
212
+ isBleConnectSpy.mockRestore();
213
+ logSpy.mockRestore();
214
+ }
215
+ });
216
+
217
+ test('写入失败时通过 Core Log 输出已传输字节和平均速率', async () => {
218
+ const log = getLogger(LoggerNames.Method);
219
+ const logSpy = jest.spyOn(log, 'log').mockImplementation(() => undefined);
220
+ const typedCall = jest.fn().mockRejectedValue(new Error('write failed'));
221
+ const dateNowSpy = jest
222
+ .spyOn(Date, 'now')
223
+ .mockReturnValueOnce(1_000)
224
+ .mockReturnValueOnce(2_000);
225
+
226
+ try {
227
+ await expect(
228
+ writeProtocolV2File({
229
+ commands: { typedCall } as any,
230
+ path: 'vol1:/wallpapers/test.bin',
231
+ data: new Uint8Array(4000),
232
+ })
233
+ ).rejects.toThrow('write failed');
234
+
235
+ expect(logSpy).toHaveBeenNthCalledWith(
236
+ 1,
237
+ '[FileWrite] metrics transport=unknown status=failed bytes=0/4000 elapsed=1.00s speed=0.00 KiB/s'
238
+ );
239
+ } finally {
240
+ dateNowSpy.mockRestore();
241
+ logSpy.mockRestore();
242
+ }
243
+ });
131
244
  });
@@ -55,7 +55,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
55
55
  private protocolV2CommonUpdateProcess;
56
56
  private protocolV2WriteWholeFile;
57
57
  private getProtocolV2FirmwareTransferTransport;
58
- private fileWriteChunk;
59
58
  private recoverProtocolV2FileTransfer;
60
59
  private acquireProtocolV2BleDevice;
61
60
  private protocolV2StartFirmwareUpdate;
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkB/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAmUlG,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,SAa5B,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,qBAAqB;IAIrB,IAAI;IA6DJ,OAAO,CAAC,8BAA8B;IAiBhC,GAAG;;;;;YAKK,aAAa;YAwGb,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAO1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAOjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IAqD7C,OAAO,CAAC,qCAAqC;YAuB/B,8BAA8B;IAyB5C,OAAO,CAAC,wCAAwC;YAgBlC,gCAAgC;YAqChC,0BAA0B;YAe1B,6BAA6B;IAkC3C,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAU3B,6BAA6B;YA4BrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,uBAAuB;IA4GrC,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAgEpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YAoJvC,gCAAgC;YAchC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAiBpB,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAI5B,6BAA6B;YAwB7B,wBAAwB;IAoDtC,OAAO,CAAC,sCAAsC;YAchC,cAAc;YAoCd,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
1
+ {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkB/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAkUlG,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,SAa5B,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,qBAAqB;IAIrB,IAAI;IA6DJ,OAAO,CAAC,8BAA8B;IAiBhC,GAAG;;;;;YAKK,aAAa;YAwGb,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAO1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAOjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IAqD7C,OAAO,CAAC,qCAAqC;YAuB/B,8BAA8B;IAyB5C,OAAO,CAAC,wCAAwC;YAgBlC,gCAAgC;YAqChC,0BAA0B;YAe1B,6BAA6B;IAkC3C,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAU3B,6BAA6B;YA6BrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,uBAAuB;IA4GrC,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAgEpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YAoJvC,gCAAgC;YAchC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAiBpB,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAI5B,6BAA6B;YAwB7B,wBAAwB;IAyDtC,OAAO,CAAC,sCAAsC;YAchC,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IAoIzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAyBV"}
1
+ {"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IAsIzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAyBV"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAgB3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAuD5D,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU,CAAC,aAAa,CAAC;IACnE,qBAAqB;IAIrB,IAAI;IAwEJ,eAAe;;;;;;;IAWT,GAAG;CA8HV"}
1
+ {"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAuD5D,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU,CAAC,aAAa,CAAC;IACnE,qBAAqB;IAIrB,IAAI;IAwEJ,eAAe;;;;;;;IAWT,GAAG;CAgIV"}
@@ -1,10 +1,11 @@
1
1
  /// <reference types="node" />
2
2
  import { BaseMethod } from '../BaseMethod';
3
- import type { IFirmwareUpdateProgressType, IFirmwareUpdateTipMessage } from '../../events/ui-request';
3
+ import type { FirmwareProgress, IFirmwareUpdateProgressType, IFirmwareUpdateTipMessage } from '../../events/ui-request';
4
4
  import type { PROTO } from '../../constants';
5
5
  import type { RebootType } from '@onekeyfe/hd-transport';
6
6
  import type { Deferred } from '@onekeyfe/hd-shared';
7
7
  import type { TypedResponseMessage } from '../../device/DeviceCommands';
8
+ type FirmwareTransferMetrics = Pick<FirmwareProgress['payload'], 'transferredBytes' | 'totalBytes' | 'rateBytesPerSecond' | 'elapsedMs'>;
8
9
  export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
9
10
  checkPromise: Deferred<any> | null;
10
11
  init(): void;
@@ -12,7 +13,7 @@ export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params>
12
13
  isBleReconnect(): boolean;
13
14
  postTipMessage: (message: IFirmwareUpdateTipMessage) => void;
14
15
  postProcessingMessage: (type: 'firmware' | 'ble' | 'bootloader' | 'resource') => void;
15
- postProgressMessage: (progress: number, progressType: IFirmwareUpdateProgressType) => void;
16
+ postProgressMessage: (progress: number, progressType: IFirmwareUpdateProgressType, metrics?: FirmwareTransferMetrics) => void;
16
17
  protected _promptDeviceInBootloaderForWebDevice(): Promise<unknown>;
17
18
  protected _promptDeviceForSwitchFirmwareWebDevice(): Promise<unknown>;
18
19
  checkDeviceToBootloader(connectId: string | undefined): void;
@@ -30,4 +31,5 @@ export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params>
30
31
  emmcFileWriteWithRetry(filePath: string, chunkLength: number, offset: number, chunk: ArrayBuffer | Buffer, overwrite: boolean, progress: number | null): Promise<TypedResponseMessage<"EmmcFile"> | undefined>;
31
32
  reboot(rebootType: RebootType): Promise<import("@onekeyfe/hd-transport").Success>;
32
33
  }
34
+ export {};
33
35
  //# sourceMappingURL=FirmwareUpdateBaseMethod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAexE,qBAAa,wBAAwB,CAAC,MAAM,CAAE,SAAQ,UAAU,CAAC,MAAM,CAAC;IACtE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI,IAAI,IAAI;IAEZ,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAInB,cAAc,IAAI,OAAO;IASzB,cAAc,YAAa,yBAAyB,UASlD;IAMF,qBAAqB,SAAU,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU,UAM3E;IAMF,mBAAmB,aAAc,MAAM,gBAAgB,2BAA2B,UAQhF;cAEc,qCAAqC;cAkBrC,uCAAuC;IAkBvD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;YA2FvC,4BAA4B;IAyBpC,mBAAmB;IA8CnB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IA6BlD,8BAA8B,CAAC,IAAI,EAAE,MAAM;IAW3C,uBAAuB,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,KAAK,CAAC,cAAc,GAAG;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IA4CK,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GAAG,MAAM,EAC3B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgFnB,MAAM,CAAC,UAAU,EAAE,UAAU;CAsBpC"}
1
+ {"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,gBAAgB,EAChB,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAMxE,KAAK,uBAAuB,GAAG,IAAI,CACjC,gBAAgB,CAAC,SAAS,CAAC,EAC3B,kBAAkB,GAAG,YAAY,GAAG,oBAAoB,GAAG,WAAW,CACvE,CAAC;AAWF,qBAAa,wBAAwB,CAAC,MAAM,CAAE,SAAQ,UAAU,CAAC,MAAM,CAAC;IACtE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI,IAAI,IAAI;IAEZ,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAInB,cAAc,IAAI,OAAO;IASzB,cAAc,YAAa,yBAAyB,UASlD;IAMF,qBAAqB,SAAU,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU,UAM3E;IAMF,mBAAmB,aACP,MAAM,gBACF,2BAA2B,YAC/B,uBAAuB,UAUjC;cAEc,qCAAqC;cAkBrC,uCAAuC;IAkBvD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;YA2FvC,4BAA4B;IAyBpC,mBAAmB;IA8CnB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IA6BlD,8BAA8B,CAAC,IAAI,EAAE,MAAM;IAW3C,uBAAuB,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,KAAK,CAAC,cAAc,GAAG;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IA4CK,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GAAG,MAAM,EAC3B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgFnB,MAAM,CAAC,UAAU,EAAE,UAAU;CAsBpC"}