@onekeyfe/hd-core 1.2.0-alpha.82 → 1.2.0-alpha.85

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 (53) hide show
  1. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +285 -13
  2. package/__tests__/check-firmware-release-protocol-v2.test.ts +6 -0
  3. package/__tests__/firmware-memory-host.test.ts +105 -0
  4. package/__tests__/firmware-update/firmware-update-plan.test.ts +15 -70
  5. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +53 -1
  6. package/__tests__/protocol-v2-resources.test.ts +0 -38
  7. package/__tests__/protocol-v2.test.ts +212 -320
  8. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  9. package/dist/api/FirmwareUpdateV4.d.ts +1 -2
  10. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  11. package/dist/api/firmware/FirmwareMemoryHost.d.ts +27 -0
  12. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -0
  13. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +33 -1
  14. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  15. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
  16. package/dist/api/firmware/getBinary.d.ts +0 -1
  17. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  18. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
  19. package/dist/index.d.ts +25 -64
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +546 -387
  22. package/dist/inject.d.ts.map +1 -1
  23. package/dist/protocols/protocol-v2/resources.d.ts +0 -17
  24. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  25. package/dist/types/api/checkAllFirmwareRelease.d.ts +1 -0
  26. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  27. package/dist/types/api/export.d.ts +0 -1
  28. package/dist/types/api/export.d.ts.map +1 -1
  29. package/dist/types/api/firmwareUpdate.d.ts +0 -10
  30. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  31. package/dist/types/api/index.d.ts +0 -2
  32. package/dist/types/api/index.d.ts.map +1 -1
  33. package/dist/types/settings.d.ts +0 -11
  34. package/dist/types/settings.d.ts.map +1 -1
  35. package/package.json +4 -4
  36. package/src/api/CheckAllFirmwareRelease.ts +72 -5
  37. package/src/api/FirmwareUpdateV4.ts +154 -165
  38. package/src/api/firmware/FirmwareMemoryHost.ts +171 -0
  39. package/src/api/firmware/FirmwareUpdatePlan.ts +176 -79
  40. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +8 -1
  41. package/src/api/firmware/protocolV2Release.ts +2 -0
  42. package/src/index.ts +6 -1
  43. package/src/inject.ts +0 -2
  44. package/src/protocols/protocol-v2/resources.ts +0 -47
  45. package/src/types/api/checkAllFirmwareRelease.ts +1 -0
  46. package/src/types/api/export.ts +0 -4
  47. package/src/types/api/firmwareUpdate.ts +0 -15
  48. package/src/types/api/index.ts +0 -2
  49. package/src/types/settings.ts +0 -20
  50. package/src/utils/deviceFeaturesUtils.ts +2 -2
  51. package/dist/types/api/protocolV2ResourceManifest.d.ts +0 -17
  52. package/dist/types/api/protocolV2ResourceManifest.d.ts.map +0 -1
  53. package/src/types/api/protocolV2ResourceManifest.ts +0 -19
@@ -4,10 +4,8 @@ import { HardwareErrorCode } from '@onekeyfe/hd-shared';
4
4
 
5
5
  import { DataManager } from '../src/data-manager';
6
6
  import {
7
- isProtocolV2ResourceFileValid,
8
7
  parseProtocolV2ResourceManifest,
9
8
  parseProtocolV2Resources,
10
- prepareProtocolV2ResourceFiles,
11
9
  } from '../src/protocols/protocol-v2/resources';
12
10
 
13
11
  import type { ConnectSettings, RemoteConfigResponse } from '../src/types';
@@ -151,42 +149,6 @@ describe('Pro2 resource configuration', () => {
151
149
  ).toThrow('archive_path');
152
150
  });
153
151
 
154
- test('verifies selected manifest files and preserves manifest device paths', () => {
155
- const prepared = prepareProtocolV2ResourceFiles({
156
- manifest: resourceManifest,
157
- files: manifestFiles.map(file => ({
158
- archivePath: file.archive_path,
159
- binary: file.binary,
160
- })),
161
- targetsToUpdate: ['resource'],
162
- });
163
- expect(prepared.map(file => file.devicePath)).toEqual(
164
- manifestFiles.map(file => file.device_path)
165
- );
166
- expect(() =>
167
- prepareProtocolV2ResourceFiles({
168
- manifest: resourceManifest,
169
- files: manifestFiles.map((file, index) => ({
170
- archivePath: file.archive_path,
171
- binary: index === 0 ? new Uint8Array([0]).buffer : file.binary,
172
- })),
173
- targetsToUpdate: ['resource'],
174
- })
175
- ).toThrow('verification failed');
176
- });
177
-
178
- test('verifies both full file size and SHA-256 before transfer', () => {
179
- const bytes = new Uint8Array([1, 2, 3]);
180
- const binary = bytes.buffer;
181
- const identity = { size: bytes.byteLength, fileHash: bytesToHex(sha256(bytes)) };
182
-
183
- expect(isProtocolV2ResourceFileValid(binary, identity)).toBe(true);
184
- expect(isProtocolV2ResourceFileValid(binary, { ...identity, size: 4 })).toBe(false);
185
- expect(isProtocolV2ResourceFileValid(binary, { ...identity, fileHash: '0'.repeat(64) })).toBe(
186
- false
187
- );
188
- });
189
-
190
152
  test('applies a validated pre-release config and exposes its archive source', async () => {
191
153
  const configFetcher = jest.fn().mockResolvedValue(createRemoteConfig());
192
154
 
@@ -100,6 +100,12 @@ import {
100
100
  } from '../src/utils';
101
101
  import { getDeviceFirmwareVersion } from '../src/utils/deviceVersionUtils';
102
102
  import { openFirmwareByteSource } from '../src/api/firmware/FirmwareArtifactSource';
103
+ import {
104
+ registerFirmwareUpdateHostBinding,
105
+ unregisterFirmwareUpdateHostBinding,
106
+ } from '../src/api/firmware/FirmwareHostBinding';
107
+ import { prepareFirmwareUpdatePlan } from '../src/api/firmware/FirmwareUpdatePreparedPlan';
108
+ import { digestFirmwareUpdateContract } from '../src/api/firmware/FirmwareUpdatePlan';
103
109
  import {
104
110
  getPassphraseState,
105
111
  getPassphraseStateWithRefreshDeviceInfo,
@@ -2778,9 +2784,12 @@ describe('Protocol V2 feature adapter', () => {
2778
2784
  expect(checkedTypes).toEqual(['pro2', 'model_pro2']);
2779
2785
  });
2780
2786
 
2781
- test('uses firmware-v1 as the Pro2 remote firmware config field', () => {
2787
+ test.each([
2788
+ ['Pro2', DeviceType.PRO2],
2789
+ ['Neo', DeviceType.NEO],
2790
+ ] as const)('uses firmware-v1 as the %s remote firmware config field', (_name, deviceType) => {
2782
2791
  const features = normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any, {
2783
- hw: { Device_type: DeviceType.PRO2 },
2792
+ hw: { Device_type: deviceType },
2784
2793
  });
2785
2794
 
2786
2795
  expect(
@@ -5576,23 +5585,31 @@ describe('Protocol V2 firmware update targets', () => {
5576
5585
  .mockResolvedValue(undefined);
5577
5586
  (method as any).isProtocolV2ResourceBundleUpToDate = jest.fn().mockResolvedValue(false);
5578
5587
 
5579
- await (method as any).executeProtocolV2Update({
5580
- resourceBundles: [
5588
+ await (method as any).executeProtocolV2SourceUpdate({
5589
+ resourceSources: [
5581
5590
  {
5582
5591
  name: 'images.okpkg',
5583
- binary: new Uint8Array([1, 2]).buffer,
5592
+ source: {
5593
+ size: 2,
5594
+ readAt: jest.fn(),
5595
+ close: jest.fn(),
5596
+ },
5584
5597
  devicePath: 'vol0:/bundles/images/images.okpkg',
5585
5598
  version: [1, 2, 3],
5586
5599
  payloadHash: '11'.repeat(64),
5587
5600
  headerHash: '22'.repeat(64),
5588
5601
  },
5589
5602
  ],
5590
- bootloaderBinary: null,
5591
- fwBinaryMap: [
5603
+ installSources: [
5592
5604
  {
5593
5605
  fileName: 'application_p1.bin',
5594
- binary: new Uint8Array([3]).buffer,
5606
+ source: {
5607
+ size: 1,
5608
+ readAt: jest.fn(),
5609
+ close: jest.fn(),
5610
+ },
5595
5611
  targetId: 4,
5612
+ kind: 'firmware',
5596
5613
  },
5597
5614
  ],
5598
5615
  });
@@ -6098,56 +6115,193 @@ describe('Protocol V2 firmware update targets', () => {
6098
6115
  });
6099
6116
  });
6100
6117
 
6101
- test('rejects prepared RESC bundle paths before opening an artifact source', async () => {
6118
+ test('maps a prepared resource archive manifest to artifact-backed resource sources', async () => {
6102
6119
  const method = new FirmwareUpdateV4({
6103
6120
  id: 1,
6104
6121
  payload: {
6105
6122
  method: 'firmwareUpdateV4',
6106
6123
  },
6107
6124
  });
6108
- const openPreparedSource = jest.fn();
6125
+ const imagesBinary = createProtocolV2OkppBinary();
6126
+ const bootBinary = createProtocolV2OkppBinary({ payloadHashByte: 0x33 });
6127
+ const imagesSha256 = '1'.repeat(64);
6128
+ const bootSha256 = '2'.repeat(64);
6129
+ const manifest = {
6130
+ schema: 1,
6131
+ artifact_name: 'pro2-resource',
6132
+ release_name: 'test-release',
6133
+ variant: 'resource',
6134
+ commit: 'abc123',
6135
+ short_sha: 'abc123',
6136
+ timestamp_utc: '2026-08-09T00:00:00Z',
6137
+ core_version: '1.0.0',
6138
+ key_set: 'production',
6139
+ device_root: 'vol0:',
6140
+ restore_mode: 'bootloader_update',
6141
+ trees: [{ path: 'bundles', device: 'pro2' }],
6142
+ files: [
6143
+ {
6144
+ archive_path: 'bundles/images/images.okpkg',
6145
+ original_name: 'images.okpkg',
6146
+ device_path: 'vol0:/bundles/images/images.okpkg',
6147
+ size: imagesBinary.byteLength,
6148
+ sha256: imagesSha256,
6149
+ signed: true,
6150
+ sig_algo: 'ed25519',
6151
+ payload_version: '1.2.3',
6152
+ },
6153
+ {
6154
+ archive_path: 'loaders/bootloader/boot_resource.okpkg',
6155
+ original_name: 'boot_resource.okpkg',
6156
+ device_path: 'vol0:/loaders/bootloader/boot_resource.okpkg',
6157
+ size: bootBinary.byteLength,
6158
+ sha256: bootSha256,
6159
+ signed: true,
6160
+ sig_algo: 'ed25519',
6161
+ payload_version: '1.2.3',
6162
+ },
6163
+ ],
6164
+ };
6165
+ const manifestBinary = new TextEncoder().encode(JSON.stringify(manifest)).buffer;
6166
+ const artifacts = new Map([
6167
+ ['manifest', manifestBinary],
6168
+ ['images', imagesBinary],
6169
+ ['boot', bootBinary],
6170
+ ]);
6109
6171
  (method as any).params = {
6110
6172
  targetsToUpdate: ['resource'],
6111
- resourceBundleArtifacts: [
6173
+ preparedPlan: {
6174
+ artifacts: [
6175
+ {
6176
+ artifactId: 'resource:archive',
6177
+ role: 'resourceBundle',
6178
+ target: 'resource',
6179
+ container: 'zip',
6180
+ materializedEntries: [
6181
+ {
6182
+ entryName: 'manifest.json',
6183
+ artifact: {
6184
+ artifactRef: 'manifest',
6185
+ size: manifestBinary.byteLength,
6186
+ sha256: '0'.repeat(64),
6187
+ },
6188
+ },
6189
+ {
6190
+ entryName: 'bundles/images/images.okpkg',
6191
+ artifact: {
6192
+ artifactRef: 'images',
6193
+ size: imagesBinary.byteLength,
6194
+ sha256: imagesSha256,
6195
+ },
6196
+ },
6197
+ {
6198
+ entryName: 'loaders/bootloader/boot_resource.okpkg',
6199
+ artifact: {
6200
+ artifactRef: 'boot',
6201
+ size: bootBinary.byteLength,
6202
+ sha256: bootSha256,
6203
+ },
6204
+ },
6205
+ ],
6206
+ },
6207
+ ],
6208
+ },
6209
+ };
6210
+ (method as any).openProtocolV2PreparedSource = jest.fn(async artifact => {
6211
+ const binary = artifacts.get(artifact.artifactRef);
6212
+ if (!binary) throw new Error(`Unknown artifact: ${artifact.artifactRef}`);
6213
+ return openFirmwareByteSource({ binary });
6214
+ });
6215
+
6216
+ const sources = await (method as any).prepareProtocolV2ResourceArchiveSources();
6217
+
6218
+ expect(sources).toHaveLength(2);
6219
+ expect(sources).toEqual([
6220
+ expect.objectContaining({
6221
+ name: 'images.okpkg',
6222
+ devicePath: 'vol0:/bundles/images/images.okpkg',
6223
+ version: [1, 2, 3],
6224
+ }),
6225
+ expect.objectContaining({
6226
+ name: 'boot_resource.okpkg',
6227
+ devicePath: 'vol0:/loaders/bootloader/boot_resource.okpkg',
6228
+ version: [1, 2, 3],
6229
+ }),
6230
+ ]);
6231
+ await Promise.all(sources.map(source => source.source.close()));
6232
+ });
6233
+
6234
+ test('accepts a prepared resource archive host binding', () => {
6235
+ const planWithoutDigest = {
6236
+ schemaVersion: 2 as const,
6237
+ executor: 'v4' as const,
6238
+ deviceIdentity: 'PRO2-SERIAL',
6239
+ deviceModel: 'pro2',
6240
+ firmwareType: EFirmwareType.Universal,
6241
+ platform: 'web' as const,
6242
+ targetsToUpdate: ['resource' as const],
6243
+ artifacts: [
6112
6244
  {
6113
- name: 'images',
6245
+ artifactId: 'resource:archive',
6246
+ role: 'resourceBundle' as const,
6247
+ target: 'resource' as const,
6248
+ url: 'https://example.com/resource.zip',
6249
+ container: 'zip' as const,
6250
+ logicalName: 'protocol-v2-resource-archive',
6251
+ },
6252
+ ],
6253
+ };
6254
+ const plan = {
6255
+ ...planWithoutDigest,
6256
+ planDigest: digestFirmwareUpdateContract(planWithoutDigest),
6257
+ };
6258
+ const preparedPlan = prepareFirmwareUpdatePlan({
6259
+ plan,
6260
+ leaseRef: 'resource-archive-test',
6261
+ artifacts: [
6262
+ {
6263
+ artifactId: 'resource:archive',
6114
6264
  artifact: {
6115
- artifactRef: `fw:${'a'.repeat(64)}`,
6116
- size: 1,
6265
+ artifactRef: 'resource-archive',
6266
+ size: 3,
6117
6267
  sha256: 'a'.repeat(64),
6118
6268
  },
6269
+ materializedEntries: [
6270
+ {
6271
+ entryName: 'manifest.json',
6272
+ artifact: {
6273
+ artifactRef: 'resource-manifest',
6274
+ size: 2,
6275
+ sha256: 'b'.repeat(64),
6276
+ },
6277
+ },
6278
+ ],
6119
6279
  },
6120
6280
  ],
6121
- };
6122
- (method as any).openProtocolV2PreparedSource = openPreparedSource;
6123
- const getFirmwareLatestReleaseSpy = jest
6124
- .spyOn(DataManager, 'getFirmwareLatestRelease')
6125
- .mockReturnValue({
6126
- required: false,
6127
- version: [1, 0, 0],
6128
- url: '',
6129
- resourceBundles: [
6130
- {
6131
- name: 'images',
6132
- url: 'https://example.com/images.okpkg',
6133
- devicePath: 'vol0:/resource/../images.okpkg',
6134
- },
6135
- ],
6136
- fingerprint: '',
6137
- changelog: {
6138
- 'zh-CN': '',
6139
- 'en-US': '',
6281
+ });
6282
+ const hostBindingGeneration = registerFirmwareUpdateHostBinding({
6283
+ artifactReader: {
6284
+ open: jest.fn(),
6285
+ read: jest.fn(),
6286
+ close: jest.fn(),
6287
+ },
6288
+ });
6289
+ try {
6290
+ const method = new FirmwareUpdateV4({
6291
+ id: 1,
6292
+ payload: {
6293
+ method: 'firmwareUpdateV4',
6294
+ platform: 'web',
6295
+ targetsToUpdate: ['resource'],
6296
+ preparedPlan,
6297
+ hostBindingGeneration,
6140
6298
  },
6141
6299
  });
6142
6300
 
6143
- await expect(
6144
- (method as any).prepareProtocolV2ResourceSources('universal', {
6145
- deviceType: 'pro2',
6146
- })
6147
- ).rejects.toThrow('resourceBundles[].devicePath');
6148
- expect(openPreparedSource).not.toHaveBeenCalled();
6149
-
6150
- getFirmwareLatestReleaseSpy.mockRestore();
6301
+ expect(() => method.init()).not.toThrow();
6302
+ } finally {
6303
+ unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
6304
+ }
6151
6305
  });
6152
6306
 
6153
6307
  test('stops a remote update before reboot when the latest config cannot be refreshed', async () => {
@@ -6216,252 +6370,7 @@ describe('Protocol V2 firmware update targets', () => {
6216
6370
  });
6217
6371
  });
6218
6372
 
6219
- test('treats manual resource files as authoritative payload for resource', async () => {
6220
- const resourceBundle = createProtocolV2OkppBinary();
6221
- const method = new FirmwareUpdateV4({
6222
- id: 1,
6223
- payload: {
6224
- method: 'firmwareUpdateV4',
6225
- platform: 'web',
6226
- targetsToUpdate: ['resource'],
6227
- resourceFiles: [
6228
- {
6229
- binary: resourceBundle,
6230
- devicePath: ' VOL0:/resource/images/images.okpkg ',
6231
- },
6232
- ],
6233
- },
6234
- });
6235
- method.init();
6236
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6237
- (method as any).device = stubDevice({
6238
- originalDescriptor: { protocolType: 'V2' },
6239
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6240
- });
6241
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn();
6242
- (method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(true);
6243
- (method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
6244
- (method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
6245
- (method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({
6246
- bootloaderVersion: '1.0.0',
6247
- bleVersion: '0.0.0',
6248
- firmwareVersion: '1.0.0',
6249
- });
6250
- method.postTipMessage = jest.fn();
6251
-
6252
- await method.run();
6253
-
6254
- expect(forceReloadDataSpy).not.toHaveBeenCalled();
6255
- expect((method as any).prepareRemoteProtocolV2Binaries).not.toHaveBeenCalled();
6256
- expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith(
6257
- expect.objectContaining({
6258
- resourceBundles: [
6259
- {
6260
- name: 'images.okpkg',
6261
- binary: resourceBundle,
6262
- devicePath: 'vol0:/resource/images/images.okpkg',
6263
- version: [1, 2, 3],
6264
- payloadHash: '11'.repeat(64),
6265
- headerHash: '22'.repeat(64),
6266
- },
6267
- ],
6268
- })
6269
- );
6270
- });
6271
-
6272
- test('downloads every missing firmware target when manifest resources are already prepared', async () => {
6273
- const resourceBundle = createProtocolV2OkppBinary();
6274
- const applicationBinary = new Uint8Array([7]).buffer;
6275
- const remoteBinaries = {
6276
- bootloaderBinary: null,
6277
- fwBinaryMap: [
6278
- {
6279
- fileName: 'application_p1.bin',
6280
- binary: applicationBinary,
6281
- targetId: 4,
6282
- },
6283
- ],
6284
- installItems: [
6285
- {
6286
- fileName: 'application_p1.bin',
6287
- binary: applicationBinary,
6288
- targetId: 4,
6289
- kind: 'firmware',
6290
- },
6291
- ],
6292
- };
6293
- const method = new FirmwareUpdateV4({
6294
- id: 1,
6295
- payload: {
6296
- method: 'firmwareUpdateV4',
6297
- platform: 'web',
6298
- targetsToUpdate: ['app_v1', 'resource'],
6299
- resourceFiles: [
6300
- {
6301
- binary: resourceBundle,
6302
- devicePath: 'vol0:/bundles/images/images.okpkg',
6303
- },
6304
- ],
6305
- },
6306
- });
6307
- method.init();
6308
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6309
- (method as any).device = stubDevice({
6310
- originalDescriptor: { protocolType: 'V2' },
6311
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6312
- });
6313
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn().mockResolvedValue(remoteBinaries);
6314
- (method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
6315
- method.postTipMessage = jest.fn();
6316
-
6317
- await method.run();
6318
-
6319
- expect(forceReloadDataSpy).toHaveBeenCalledTimes(1);
6320
- expect((method as any).prepareRemoteProtocolV2Binaries).toHaveBeenCalledWith(
6321
- 'universal',
6322
- expect.objectContaining({ deviceType: 'pro2' }),
6323
- []
6324
- );
6325
- expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
6326
- bootloaderBinary: null,
6327
- fwBinaryMap: remoteBinaries.fwBinaryMap,
6328
- installItems: remoteBinaries.installItems,
6329
- resourceBundles: [
6330
- {
6331
- name: 'images.okpkg',
6332
- binary: resourceBundle,
6333
- devicePath: 'vol0:/bundles/images/images.okpkg',
6334
- version: [1, 2, 3],
6335
- payloadHash: '11'.repeat(64),
6336
- headerHash: '22'.repeat(64),
6337
- },
6338
- ],
6339
- });
6340
- });
6341
-
6342
- test('rejects a mixed resource plan when the requested firmware release is unavailable', async () => {
6343
- const resourceBundle = createProtocolV2OkppBinary();
6344
- const method = new FirmwareUpdateV4({
6345
- id: 1,
6346
- payload: {
6347
- method: 'firmwareUpdateV4',
6348
- platform: 'web',
6349
- targetsToUpdate: ['app_v1', 'resource'],
6350
- resourceFiles: [
6351
- {
6352
- binary: resourceBundle,
6353
- devicePath: 'vol0:/bundles/images/images.okpkg',
6354
- },
6355
- ],
6356
- },
6357
- });
6358
- method.init();
6359
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6360
- (method as any).device = stubDevice({
6361
- originalDescriptor: { protocolType: 'V2' },
6362
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6363
- });
6364
- jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(undefined);
6365
- (method as any).executeProtocolV2Update = jest.fn();
6366
- method.postTipMessage = jest.fn();
6367
-
6368
- await expect(method.run()).rejects.toThrow(
6369
- 'Protocol V2 firmware release is unavailable for requested targets: app_v1'
6370
- );
6371
- expect((method as any).executeProtocolV2Update).not.toHaveBeenCalled();
6372
- });
6373
-
6374
- test('combines prepared firmware components with explicit manifest resource files', async () => {
6375
- const resourceBundle = createProtocolV2OkppBinary();
6376
- const method = new FirmwareUpdateV4({
6377
- id: 1,
6378
- payload: {
6379
- method: 'firmwareUpdateV4',
6380
- platform: 'web',
6381
- },
6382
- });
6383
- method.init();
6384
- (method as any).params = {
6385
- targetsToUpdate: ['app_v1', 'resource'],
6386
- resourceFiles: [
6387
- {
6388
- binary: resourceBundle,
6389
- devicePath: 'vol0:/bundles/images/images.okpkg',
6390
- },
6391
- ],
6392
- };
6393
- const firmwareSource = { size: 10 };
6394
- const resourceSource = { size: resourceBundle.byteLength };
6395
- (method as any).prepareProtocolV2InstallSources = jest.fn().mockResolvedValue([
6396
- {
6397
- fileName: 'application_p1.bin',
6398
- source: firmwareSource,
6399
- targetId: 4,
6400
- kind: 'firmware',
6401
- },
6402
- ]);
6403
- (method as any).prepareProtocolV2ResourceSources = jest.fn();
6404
- (method as any).openProtocolV2MemorySource = jest.fn().mockResolvedValue(resourceSource);
6405
- (method as any).executeProtocolV2SourceUpdate = jest.fn().mockResolvedValue(undefined);
6406
- (method as any).closeProtocolV2PreparedSources = jest.fn().mockResolvedValue(undefined);
6407
- method.postTipMessage = jest.fn();
6408
-
6409
- await (method as any).runProtocolV2PreparedArtifacts({ deviceType: 'pro2' }, 'universal');
6410
-
6411
- expect((method as any).prepareProtocolV2ResourceSources).not.toHaveBeenCalled();
6412
- expect((method as any).executeProtocolV2SourceUpdate).toHaveBeenCalledWith({
6413
- installSources: [
6414
- {
6415
- fileName: 'application_p1.bin',
6416
- source: firmwareSource,
6417
- targetId: 4,
6418
- kind: 'firmware',
6419
- },
6420
- ],
6421
- resourceSources: [
6422
- {
6423
- name: 'images.okpkg',
6424
- source: resourceSource,
6425
- devicePath: 'vol0:/bundles/images/images.okpkg',
6426
- version: [1, 2, 3],
6427
- payloadHash: '11'.repeat(64),
6428
- headerHash: '22'.repeat(64),
6429
- },
6430
- ],
6431
- });
6432
- });
6433
-
6434
- test('rejects manual RESC bundle paths before bootloader entry', async () => {
6435
- const method = new FirmwareUpdateV4({
6436
- id: 1,
6437
- payload: {
6438
- method: 'firmwareUpdateV4',
6439
- platform: 'web',
6440
- resourceFiles: [
6441
- {
6442
- binary: new Uint8Array([1, 2, 3]).buffer,
6443
- devicePath: 'vol2:/resource/images/images.okpkg',
6444
- },
6445
- ],
6446
- },
6447
- });
6448
- method.init();
6449
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6450
-
6451
- (method as any).device = stubDevice({
6452
- originalDescriptor: { protocolType: 'V2' },
6453
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6454
- });
6455
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn();
6456
- (method as any).enterProtocolV2BootloaderMode = jest.fn();
6457
- method.postTipMessage = jest.fn();
6458
-
6459
- await expect(method.run()).rejects.toThrow('resourceFiles[0].devicePath');
6460
- expect((method as any).prepareRemoteProtocolV2Binaries).not.toHaveBeenCalled();
6461
- expect((method as any).enterProtocolV2BootloaderMode).not.toHaveBeenCalled();
6462
- });
6463
-
6464
- test('syncs resource bundles without sending a firmware install request', async () => {
6373
+ test('syncs prepared resource sources without sending a firmware install request', async () => {
6465
6374
  const method = new FirmwareUpdateV4({
6466
6375
  id: 1,
6467
6376
  payload: {
@@ -6478,16 +6387,19 @@ describe('Protocol V2 firmware update targets', () => {
6478
6387
  (method as any).protocolV2StartFirmwareUpdate = jest.fn();
6479
6388
  (method as any).waitForProtocolV2FirmwareUpdateComplete = jest.fn();
6480
6389
 
6481
- await (method as any).executeProtocolV2Update({
6482
- resourceBundles: [
6390
+ await (method as any).executeProtocolV2SourceUpdate({
6391
+ installSources: [],
6392
+ resourceSources: [
6483
6393
  {
6484
6394
  name: 'images.okpkg',
6485
- binary: new Uint8Array([1, 2, 3]).buffer,
6395
+ source: {
6396
+ size: 3,
6397
+ readAt: jest.fn(),
6398
+ close: jest.fn(),
6399
+ },
6486
6400
  devicePath: 'vol0:/resource/images/images.okpkg',
6487
6401
  },
6488
6402
  ],
6489
- bootloaderBinary: null,
6490
- fwBinaryMap: [],
6491
6403
  });
6492
6404
 
6493
6405
  expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenCalledTimes(1);
@@ -6517,16 +6429,19 @@ describe('Protocol V2 firmware update targets', () => {
6517
6429
  (method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
6518
6430
  (method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
6519
6431
 
6520
- await (method as any).executeProtocolV2Update({
6521
- resourceBundles: [
6432
+ await (method as any).executeProtocolV2SourceUpdate({
6433
+ installSources: [],
6434
+ resourceSources: [
6522
6435
  {
6523
6436
  name: 'boot_resource.okpkg',
6524
- binary: new Uint8Array([1, 2, 3]).buffer,
6437
+ source: {
6438
+ size: 3,
6439
+ readAt: jest.fn(),
6440
+ close: jest.fn(),
6441
+ },
6525
6442
  devicePath: 'vol0:/loaders/bootloader/boot_resource.okpkg',
6526
6443
  },
6527
6444
  ],
6528
- bootloaderBinary: null,
6529
- fwBinaryMap: [],
6530
6445
  });
6531
6446
 
6532
6447
  const stagingPath = 'vol0:/loaders/bootloader/boot_resource.okpkg.staging';
@@ -7407,29 +7322,6 @@ describe('Protocol V2 firmware reconnect identity', () => {
7407
7322
  });
7408
7323
  expect((method as any).protocolV2SourceUpdateProcess).not.toHaveBeenCalled();
7409
7324
  });
7410
-
7411
- test('rejects a manually supplied resource file when its manifest hash does not match', () => {
7412
- const method = new FirmwareUpdateV4({
7413
- id: 1,
7414
- payload: {
7415
- method: 'firmwareUpdateV4',
7416
- platform: 'web',
7417
- resourceFiles: [
7418
- {
7419
- binary: new Uint8Array([1, 2, 3]).buffer,
7420
- devicePath: 'vol0:/assets/loaders/boot.staging/graphics/bootloader_crest.bin',
7421
- size: 3,
7422
- fileHash: '00'.repeat(32),
7423
- },
7424
- ],
7425
- },
7426
- });
7427
- method.init();
7428
-
7429
- expect(() => (method as any).prepareExplicitProtocolV2ResourceFiles()).toThrow(
7430
- 'SHA-256 mismatch'
7431
- );
7432
- });
7433
7325
  });
7434
7326
 
7435
7327
  describe('Protocol V2 explicit USB device selection', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA8B1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AAgIlB,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,iBAAyB,EACzB,mBAAwB,EACxB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B,GAAG,6BAA6B,CAiFhC;AAID,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuFK,aAAa;CA+D5B"}
1
+ {"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AAgIlB,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,iBAAyB,EACzB,mBAAwB,EACxB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B,GAAG,6BAA6B,CAiFhC;AAID,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuFK,aAAa;CA+H5B"}