/ src / utils / controlMessageCompat.ts
controlMessageCompat.ts
 1  /**
 2   * Normalize camelCase `requestId` → snake_case `request_id` on incoming
 3   * control messages (control_request, control_response).
 4   *
 5   * Older iOS app builds send `requestId` due to a missing Swift CodingKeys
 6   * mapping. Without this shim, `isSDKControlRequest` in replBridge.ts rejects
 7   * the message (it checks `'request_id' in value`), and structuredIO.ts reads
 8   * `message.response.request_id` as undefined — both silently drop the message.
 9   *
10   * If both `request_id` and `requestId` are present, snake_case wins.
11   * Mutates the object in place.
12   */
13  export function normalizeControlMessageKeys(obj: unknown): unknown {
14    if (obj === null || typeof obj !== 'object') return obj
15    const record = obj as Record<string, unknown>
16    if ('requestId' in record && !('request_id' in record)) {
17      record.request_id = record.requestId
18      delete record.requestId
19    }
20    if (
21      'response' in record &&
22      record.response !== null &&
23      typeof record.response === 'object'
24    ) {
25      const response = record.response as Record<string, unknown>
26      if ('requestId' in response && !('request_id' in response)) {
27        response.request_id = response.requestId
28        delete response.requestId
29      }
30    }
31    return obj
32  }