@onekeyfe/hd-core 1.2.0-alpha.84 → 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 (46) hide show
  1. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +24 -18
  2. package/__tests__/firmware-memory-host.test.ts +105 -0
  3. package/__tests__/firmware-update/firmware-update-plan.test.ts +15 -70
  4. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +53 -1
  5. package/__tests__/protocol-v2-resources.test.ts +0 -38
  6. package/__tests__/protocol-v2.test.ts +207 -318
  7. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  8. package/dist/api/FirmwareUpdateV4.d.ts +1 -2
  9. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  10. package/dist/api/firmware/FirmwareMemoryHost.d.ts +27 -0
  11. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -0
  12. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +3 -4
  13. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  14. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
  15. package/dist/api/firmware/getBinary.d.ts +0 -1
  16. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  17. package/dist/index.d.ts +24 -64
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +406 -367
  20. package/dist/inject.d.ts.map +1 -1
  21. package/dist/protocols/protocol-v2/resources.d.ts +0 -17
  22. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  23. package/dist/types/api/export.d.ts +0 -1
  24. package/dist/types/api/export.d.ts.map +1 -1
  25. package/dist/types/api/firmwareUpdate.d.ts +0 -10
  26. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  27. package/dist/types/api/index.d.ts +0 -2
  28. package/dist/types/api/index.d.ts.map +1 -1
  29. package/dist/types/settings.d.ts +0 -11
  30. package/dist/types/settings.d.ts.map +1 -1
  31. package/package.json +4 -4
  32. package/src/api/CheckAllFirmwareRelease.ts +2 -6
  33. package/src/api/FirmwareUpdateV4.ts +154 -165
  34. package/src/api/firmware/FirmwareMemoryHost.ts +171 -0
  35. package/src/api/firmware/FirmwareUpdatePlan.ts +28 -48
  36. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +8 -1
  37. package/src/index.ts +6 -1
  38. package/src/inject.ts +0 -2
  39. package/src/protocols/protocol-v2/resources.ts +0 -47
  40. package/src/types/api/export.ts +0 -4
  41. package/src/types/api/firmwareUpdate.ts +0 -15
  42. package/src/types/api/index.ts +0 -2
  43. package/src/types/settings.ts +0 -20
  44. package/dist/types/api/protocolV2ResourceManifest.d.ts +0 -17
  45. package/dist/types/api/protocolV2ResourceManifest.d.ts.map +0 -1
  46. package/src/types/api/protocolV2ResourceManifest.ts +0 -19
@@ -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,
@@ -5579,23 +5585,31 @@ describe('Protocol V2 firmware update targets', () => {
5579
5585
  .mockResolvedValue(undefined);
5580
5586
  (method as any).isProtocolV2ResourceBundleUpToDate = jest.fn().mockResolvedValue(false);
5581
5587
 
5582
- await (method as any).executeProtocolV2Update({
5583
- resourceBundles: [
5588
+ await (method as any).executeProtocolV2SourceUpdate({
5589
+ resourceSources: [
5584
5590
  {
5585
5591
  name: 'images.okpkg',
5586
- binary: new Uint8Array([1, 2]).buffer,
5592
+ source: {
5593
+ size: 2,
5594
+ readAt: jest.fn(),
5595
+ close: jest.fn(),
5596
+ },
5587
5597
  devicePath: 'vol0:/bundles/images/images.okpkg',
5588
5598
  version: [1, 2, 3],
5589
5599
  payloadHash: '11'.repeat(64),
5590
5600
  headerHash: '22'.repeat(64),
5591
5601
  },
5592
5602
  ],
5593
- bootloaderBinary: null,
5594
- fwBinaryMap: [
5603
+ installSources: [
5595
5604
  {
5596
5605
  fileName: 'application_p1.bin',
5597
- binary: new Uint8Array([3]).buffer,
5606
+ source: {
5607
+ size: 1,
5608
+ readAt: jest.fn(),
5609
+ close: jest.fn(),
5610
+ },
5598
5611
  targetId: 4,
5612
+ kind: 'firmware',
5599
5613
  },
5600
5614
  ],
5601
5615
  });
@@ -6101,56 +6115,193 @@ describe('Protocol V2 firmware update targets', () => {
6101
6115
  });
6102
6116
  });
6103
6117
 
6104
- 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 () => {
6105
6119
  const method = new FirmwareUpdateV4({
6106
6120
  id: 1,
6107
6121
  payload: {
6108
6122
  method: 'firmwareUpdateV4',
6109
6123
  },
6110
6124
  });
6111
- 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
+ ]);
6112
6171
  (method as any).params = {
6113
6172
  targetsToUpdate: ['resource'],
6114
- 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: [
6115
6244
  {
6116
- 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',
6117
6264
  artifact: {
6118
- artifactRef: `fw:${'a'.repeat(64)}`,
6119
- size: 1,
6265
+ artifactRef: 'resource-archive',
6266
+ size: 3,
6120
6267
  sha256: 'a'.repeat(64),
6121
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
+ ],
6122
6279
  },
6123
6280
  ],
6124
- };
6125
- (method as any).openProtocolV2PreparedSource = openPreparedSource;
6126
- const getFirmwareLatestReleaseSpy = jest
6127
- .spyOn(DataManager, 'getFirmwareLatestRelease')
6128
- .mockReturnValue({
6129
- required: false,
6130
- version: [1, 0, 0],
6131
- url: '',
6132
- resourceBundles: [
6133
- {
6134
- name: 'images',
6135
- url: 'https://example.com/images.okpkg',
6136
- devicePath: 'vol0:/resource/../images.okpkg',
6137
- },
6138
- ],
6139
- fingerprint: '',
6140
- changelog: {
6141
- 'zh-CN': '',
6142
- '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,
6143
6298
  },
6144
6299
  });
6145
6300
 
6146
- await expect(
6147
- (method as any).prepareProtocolV2ResourceSources('universal', {
6148
- deviceType: 'pro2',
6149
- })
6150
- ).rejects.toThrow('resourceBundles[].devicePath');
6151
- expect(openPreparedSource).not.toHaveBeenCalled();
6152
-
6153
- getFirmwareLatestReleaseSpy.mockRestore();
6301
+ expect(() => method.init()).not.toThrow();
6302
+ } finally {
6303
+ unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
6304
+ }
6154
6305
  });
6155
6306
 
6156
6307
  test('stops a remote update before reboot when the latest config cannot be refreshed', async () => {
@@ -6219,252 +6370,7 @@ describe('Protocol V2 firmware update targets', () => {
6219
6370
  });
6220
6371
  });
6221
6372
 
6222
- test('treats manual resource files as authoritative payload for resource', async () => {
6223
- const resourceBundle = createProtocolV2OkppBinary();
6224
- const method = new FirmwareUpdateV4({
6225
- id: 1,
6226
- payload: {
6227
- method: 'firmwareUpdateV4',
6228
- platform: 'web',
6229
- targetsToUpdate: ['resource'],
6230
- resourceFiles: [
6231
- {
6232
- binary: resourceBundle,
6233
- devicePath: ' VOL0:/resource/images/images.okpkg ',
6234
- },
6235
- ],
6236
- },
6237
- });
6238
- method.init();
6239
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6240
- (method as any).device = stubDevice({
6241
- originalDescriptor: { protocolType: 'V2' },
6242
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6243
- });
6244
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn();
6245
- (method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(true);
6246
- (method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
6247
- (method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
6248
- (method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({
6249
- bootloaderVersion: '1.0.0',
6250
- bleVersion: '0.0.0',
6251
- firmwareVersion: '1.0.0',
6252
- });
6253
- method.postTipMessage = jest.fn();
6254
-
6255
- await method.run();
6256
-
6257
- expect(forceReloadDataSpy).not.toHaveBeenCalled();
6258
- expect((method as any).prepareRemoteProtocolV2Binaries).not.toHaveBeenCalled();
6259
- expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith(
6260
- expect.objectContaining({
6261
- resourceBundles: [
6262
- {
6263
- name: 'images.okpkg',
6264
- binary: resourceBundle,
6265
- devicePath: 'vol0:/resource/images/images.okpkg',
6266
- version: [1, 2, 3],
6267
- payloadHash: '11'.repeat(64),
6268
- headerHash: '22'.repeat(64),
6269
- },
6270
- ],
6271
- })
6272
- );
6273
- });
6274
-
6275
- test('downloads every missing firmware target when manifest resources are already prepared', async () => {
6276
- const resourceBundle = createProtocolV2OkppBinary();
6277
- const applicationBinary = new Uint8Array([7]).buffer;
6278
- const remoteBinaries = {
6279
- bootloaderBinary: null,
6280
- fwBinaryMap: [
6281
- {
6282
- fileName: 'application_p1.bin',
6283
- binary: applicationBinary,
6284
- targetId: 4,
6285
- },
6286
- ],
6287
- installItems: [
6288
- {
6289
- fileName: 'application_p1.bin',
6290
- binary: applicationBinary,
6291
- targetId: 4,
6292
- kind: 'firmware',
6293
- },
6294
- ],
6295
- };
6296
- const method = new FirmwareUpdateV4({
6297
- id: 1,
6298
- payload: {
6299
- method: 'firmwareUpdateV4',
6300
- platform: 'web',
6301
- targetsToUpdate: ['app_v1', 'resource'],
6302
- resourceFiles: [
6303
- {
6304
- binary: resourceBundle,
6305
- devicePath: 'vol0:/bundles/images/images.okpkg',
6306
- },
6307
- ],
6308
- },
6309
- });
6310
- method.init();
6311
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6312
- (method as any).device = stubDevice({
6313
- originalDescriptor: { protocolType: 'V2' },
6314
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6315
- });
6316
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn().mockResolvedValue(remoteBinaries);
6317
- (method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
6318
- method.postTipMessage = jest.fn();
6319
-
6320
- await method.run();
6321
-
6322
- expect(forceReloadDataSpy).toHaveBeenCalledTimes(1);
6323
- expect((method as any).prepareRemoteProtocolV2Binaries).toHaveBeenCalledWith(
6324
- 'universal',
6325
- expect.objectContaining({ deviceType: 'pro2' }),
6326
- []
6327
- );
6328
- expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
6329
- bootloaderBinary: null,
6330
- fwBinaryMap: remoteBinaries.fwBinaryMap,
6331
- installItems: remoteBinaries.installItems,
6332
- resourceBundles: [
6333
- {
6334
- name: 'images.okpkg',
6335
- binary: resourceBundle,
6336
- devicePath: 'vol0:/bundles/images/images.okpkg',
6337
- version: [1, 2, 3],
6338
- payloadHash: '11'.repeat(64),
6339
- headerHash: '22'.repeat(64),
6340
- },
6341
- ],
6342
- });
6343
- });
6344
-
6345
- test('rejects a mixed resource plan when the requested firmware release is unavailable', async () => {
6346
- const resourceBundle = createProtocolV2OkppBinary();
6347
- const method = new FirmwareUpdateV4({
6348
- id: 1,
6349
- payload: {
6350
- method: 'firmwareUpdateV4',
6351
- platform: 'web',
6352
- targetsToUpdate: ['app_v1', 'resource'],
6353
- resourceFiles: [
6354
- {
6355
- binary: resourceBundle,
6356
- devicePath: 'vol0:/bundles/images/images.okpkg',
6357
- },
6358
- ],
6359
- },
6360
- });
6361
- method.init();
6362
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6363
- (method as any).device = stubDevice({
6364
- originalDescriptor: { protocolType: 'V2' },
6365
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6366
- });
6367
- jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(undefined);
6368
- (method as any).executeProtocolV2Update = jest.fn();
6369
- method.postTipMessage = jest.fn();
6370
-
6371
- await expect(method.run()).rejects.toThrow(
6372
- 'Protocol V2 firmware release is unavailable for requested targets: app_v1'
6373
- );
6374
- expect((method as any).executeProtocolV2Update).not.toHaveBeenCalled();
6375
- });
6376
-
6377
- test('combines prepared firmware components with explicit manifest resource files', async () => {
6378
- const resourceBundle = createProtocolV2OkppBinary();
6379
- const method = new FirmwareUpdateV4({
6380
- id: 1,
6381
- payload: {
6382
- method: 'firmwareUpdateV4',
6383
- platform: 'web',
6384
- },
6385
- });
6386
- method.init();
6387
- (method as any).params = {
6388
- targetsToUpdate: ['app_v1', 'resource'],
6389
- resourceFiles: [
6390
- {
6391
- binary: resourceBundle,
6392
- devicePath: 'vol0:/bundles/images/images.okpkg',
6393
- },
6394
- ],
6395
- };
6396
- const firmwareSource = { size: 10 };
6397
- const resourceSource = { size: resourceBundle.byteLength };
6398
- (method as any).prepareProtocolV2InstallSources = jest.fn().mockResolvedValue([
6399
- {
6400
- fileName: 'application_p1.bin',
6401
- source: firmwareSource,
6402
- targetId: 4,
6403
- kind: 'firmware',
6404
- },
6405
- ]);
6406
- (method as any).prepareProtocolV2ResourceSources = jest.fn();
6407
- (method as any).openProtocolV2MemorySource = jest.fn().mockResolvedValue(resourceSource);
6408
- (method as any).executeProtocolV2SourceUpdate = jest.fn().mockResolvedValue(undefined);
6409
- (method as any).closeProtocolV2PreparedSources = jest.fn().mockResolvedValue(undefined);
6410
- method.postTipMessage = jest.fn();
6411
-
6412
- await (method as any).runProtocolV2PreparedArtifacts({ deviceType: 'pro2' }, 'universal');
6413
-
6414
- expect((method as any).prepareProtocolV2ResourceSources).not.toHaveBeenCalled();
6415
- expect((method as any).executeProtocolV2SourceUpdate).toHaveBeenCalledWith({
6416
- installSources: [
6417
- {
6418
- fileName: 'application_p1.bin',
6419
- source: firmwareSource,
6420
- targetId: 4,
6421
- kind: 'firmware',
6422
- },
6423
- ],
6424
- resourceSources: [
6425
- {
6426
- name: 'images.okpkg',
6427
- source: resourceSource,
6428
- devicePath: 'vol0:/bundles/images/images.okpkg',
6429
- version: [1, 2, 3],
6430
- payloadHash: '11'.repeat(64),
6431
- headerHash: '22'.repeat(64),
6432
- },
6433
- ],
6434
- });
6435
- });
6436
-
6437
- test('rejects manual RESC bundle paths before bootloader entry', async () => {
6438
- const method = new FirmwareUpdateV4({
6439
- id: 1,
6440
- payload: {
6441
- method: 'firmwareUpdateV4',
6442
- platform: 'web',
6443
- resourceFiles: [
6444
- {
6445
- binary: new Uint8Array([1, 2, 3]).buffer,
6446
- devicePath: 'vol2:/resource/images/images.okpkg',
6447
- },
6448
- ],
6449
- },
6450
- });
6451
- method.init();
6452
- (method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
6453
-
6454
- (method as any).device = stubDevice({
6455
- originalDescriptor: { protocolType: 'V2' },
6456
- features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
6457
- });
6458
- (method as any).prepareRemoteProtocolV2Binaries = jest.fn();
6459
- (method as any).enterProtocolV2BootloaderMode = jest.fn();
6460
- method.postTipMessage = jest.fn();
6461
-
6462
- await expect(method.run()).rejects.toThrow('resourceFiles[0].devicePath');
6463
- expect((method as any).prepareRemoteProtocolV2Binaries).not.toHaveBeenCalled();
6464
- expect((method as any).enterProtocolV2BootloaderMode).not.toHaveBeenCalled();
6465
- });
6466
-
6467
- test('syncs resource bundles without sending a firmware install request', async () => {
6373
+ test('syncs prepared resource sources without sending a firmware install request', async () => {
6468
6374
  const method = new FirmwareUpdateV4({
6469
6375
  id: 1,
6470
6376
  payload: {
@@ -6481,16 +6387,19 @@ describe('Protocol V2 firmware update targets', () => {
6481
6387
  (method as any).protocolV2StartFirmwareUpdate = jest.fn();
6482
6388
  (method as any).waitForProtocolV2FirmwareUpdateComplete = jest.fn();
6483
6389
 
6484
- await (method as any).executeProtocolV2Update({
6485
- resourceBundles: [
6390
+ await (method as any).executeProtocolV2SourceUpdate({
6391
+ installSources: [],
6392
+ resourceSources: [
6486
6393
  {
6487
6394
  name: 'images.okpkg',
6488
- binary: new Uint8Array([1, 2, 3]).buffer,
6395
+ source: {
6396
+ size: 3,
6397
+ readAt: jest.fn(),
6398
+ close: jest.fn(),
6399
+ },
6489
6400
  devicePath: 'vol0:/resource/images/images.okpkg',
6490
6401
  },
6491
6402
  ],
6492
- bootloaderBinary: null,
6493
- fwBinaryMap: [],
6494
6403
  });
6495
6404
 
6496
6405
  expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenCalledTimes(1);
@@ -6520,16 +6429,19 @@ describe('Protocol V2 firmware update targets', () => {
6520
6429
  (method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
6521
6430
  (method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
6522
6431
 
6523
- await (method as any).executeProtocolV2Update({
6524
- resourceBundles: [
6432
+ await (method as any).executeProtocolV2SourceUpdate({
6433
+ installSources: [],
6434
+ resourceSources: [
6525
6435
  {
6526
6436
  name: 'boot_resource.okpkg',
6527
- binary: new Uint8Array([1, 2, 3]).buffer,
6437
+ source: {
6438
+ size: 3,
6439
+ readAt: jest.fn(),
6440
+ close: jest.fn(),
6441
+ },
6528
6442
  devicePath: 'vol0:/loaders/bootloader/boot_resource.okpkg',
6529
6443
  },
6530
6444
  ],
6531
- bootloaderBinary: null,
6532
- fwBinaryMap: [],
6533
6445
  });
6534
6446
 
6535
6447
  const stagingPath = 'vol0:/loaders/bootloader/boot_resource.okpkg.staging';
@@ -7410,29 +7322,6 @@ describe('Protocol V2 firmware reconnect identity', () => {
7410
7322
  });
7411
7323
  expect((method as any).protocolV2SourceUpdateProcess).not.toHaveBeenCalled();
7412
7324
  });
7413
-
7414
- test('rejects a manually supplied resource file when its manifest hash does not match', () => {
7415
- const method = new FirmwareUpdateV4({
7416
- id: 1,
7417
- payload: {
7418
- method: 'firmwareUpdateV4',
7419
- platform: 'web',
7420
- resourceFiles: [
7421
- {
7422
- binary: new Uint8Array([1, 2, 3]).buffer,
7423
- devicePath: 'vol0:/assets/loaders/boot.staging/graphics/bootloader_crest.bin',
7424
- size: 3,
7425
- fileHash: '00'.repeat(32),
7426
- },
7427
- ],
7428
- },
7429
- });
7430
- method.init();
7431
-
7432
- expect(() => (method as any).prepareExplicitProtocolV2ResourceFiles()).toThrow(
7433
- 'SHA-256 mismatch'
7434
- );
7435
- });
7436
7325
  });
7437
7326
 
7438
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;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;CAmI5B"}
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"}
@@ -26,6 +26,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
26
26
  private closeProtocolV2PreparedSources;
27
27
  private prepareProtocolV2InstallSources;
28
28
  private prepareProtocolV2ResourceSources;
29
+ private prepareProtocolV2ResourceArchiveSources;
29
30
  private runProtocolV2PreparedArtifacts;
30
31
  private validateExpectedTargetVersions;
31
32
  private getExpectedProtocolV2TargetVersion;
@@ -39,14 +40,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
39
40
  private captureProtocolV2PhysicalIdentity;
40
41
  private verifyProtocolV2ReconnectIdentity;
41
42
  private prepareBootloaderBinary;
42
- private hasExplicitProtocolV2Payload;
43
43
  private getMissingProtocolV2FirmwareTargets;
44
44
  private buildProtocolV2InstallItems;
45
45
  private getRemoteComponentEntries;
46
46
  private getRemoteComponentTarget;
47
47
  private downloadRemoteProtocolV2Component;
48
48
  private prepareRemoteProtocolV2Binaries;
49
- private prepareExplicitProtocolV2ResourceFiles;
50
49
  private getProtocolV2ResourceFilePath;
51
50
  private readProtocolV2DeviceFileHeader;
52
51
  private isProtocolV2ResourceBundleUpToDate;
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AAyBlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAmB/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AA6CrC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,QAgB/B;AA6UD,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,iBACZ,MAAM,eACR,MAAM,SAsBpB,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,sBAAsB,CAAC,CAAS;IAExC,qBAAqB;IAIrB,OAAO,CAAC,yBAAyB,CAA4B;IAE7D,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,6BAA6B,CAAS;IAE9C,IAAI;IAoHJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YAgHb,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqD/B,gCAAgC;YAmDhC,8BAA8B;IAkC5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;IAsDxC,OAAO,CAAC,6BAA6B;YAsBvB,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAS1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAkBjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,mCAAmC;IAY3C,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IA6E7C,OAAO,CAAC,sCAAsC;IA0C9C,OAAO,CAAC,6BAA6B;YAMvB,8BAA8B;YA8C9B,kCAAkC;IA4BhD,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAc3B,6BAA6B;YAgCrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;IAkCrC,OAAO,CAAC,8BAA8B;YA8CxB,uBAAuB;YAiCvB,6BAA6B;YAa7B,uBAAuB;YA6CvB,8BAA8B;YA8D9B,6BAA6B;IAuE3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAyGpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YA0JvC,gCAAgC;YAehC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,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":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AAwBlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AA2B/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAgDrC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,QAgB/B;AAoUD,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,iBACZ,MAAM,eACR,MAAM,SAsBpB,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,sBAAsB,CAAC,CAAS;IAExC,qBAAqB;IAIrB,OAAO,CAAC,yBAAyB,CAA4B;IAE7D,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,6BAA6B,CAAS;IAE9C,IAAI;IAsGJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YAmGb,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqD/B,gCAAgC;YAgBhC,uCAAuC;YAwHvC,8BAA8B;IAsB5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;IAsDxC,OAAO,CAAC,6BAA6B;YAsBvB,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAS1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAkBjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,mCAAmC;IAY3C,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IA6E7C,OAAO,CAAC,6BAA6B;YAMvB,8BAA8B;YA8C9B,kCAAkC;IA4BhD,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAc3B,6BAA6B;YAgCrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;IAkCrC,OAAO,CAAC,8BAA8B;YA8CxB,uBAAuB;YAiCvB,6BAA6B;YAa7B,uBAAuB;YAiCvB,8BAA8B;YA8D9B,6BAA6B;IAuE3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAyGpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YA0JvC,gCAAgC;YAehC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
@@ -0,0 +1,27 @@
1
+ import type { CoreApi } from '../../types/api';
2
+ import type { FirmwareArtifactReference, FirmwareUpdateV4Target } from '../../types/api/firmwareUpdate';
3
+ import type { FirmwareUpdatePlan } from '../../types/api/firmwareUpdatePlan';
4
+ export type FirmwareMemoryArtifactEntry = {
5
+ entryName: string;
6
+ binary: ArrayBuffer;
7
+ };
8
+ export type FirmwareMemoryArtifact = {
9
+ artifactId: string;
10
+ binary: ArrayBuffer;
11
+ materializedEntries?: FirmwareMemoryArtifactEntry[];
12
+ };
13
+ export type FirmwareUpdateV4MemoryHost = {
14
+ preparedPlan: ReturnType<CoreApi['prepareFirmwareUpdatePlan']>;
15
+ hostBindingGeneration: number;
16
+ targetsToUpdate: FirmwareUpdateV4Target[];
17
+ expectedDeviceId: string;
18
+ expectedTargetVersions: Partial<Record<FirmwareUpdateV4Target, string>>;
19
+ componentArtifacts: Partial<Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>>;
20
+ release: () => void;
21
+ };
22
+ export declare function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }: {
23
+ sdk: Pick<CoreApi, 'prepareFirmwareUpdatePlan' | 'registerFirmwareUpdateHostBinding' | 'unregisterFirmwareUpdateHostBinding'>;
24
+ plan: FirmwareUpdatePlan;
25
+ artifacts: FirmwareMemoryArtifact[];
26
+ }): FirmwareUpdateV4MemoryHost;
27
+ //# sourceMappingURL=FirmwareMemoryHost.d.ts.map