πŸ“„ File detail

utils/controlMessageCompat.ts

🧩 .tsπŸ“ 33 linesπŸ’Ύ 1,216 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œutils/”, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, …). On the API surface it exposes normalizeControlMessageKeys β€” mainly functions, hooks, or classes. What the file header says: Normalize camelCase `requestId` β†’ snake_case `request_id` on incoming control messages (control_request, control_response). Older iOS app builds send `requestId` due to a missing Swift CodingKeys mapping. Without this shim, `isSDKControlRequest` in replBridge.ts rejects the messa.

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

Normalize camelCase `requestId` β†’ snake_case `request_id` on incoming control messages (control_request, control_response). Older iOS app builds send `requestId` due to a missing Swift CodingKeys mapping. Without this shim, `isSDKControlRequest` in replBridge.ts rejects the message (it checks `'request_id' in value`), and structuredIO.ts reads `message.response.request_id` as undefined β€” both silently drop the message. If both `request_id` and `requestId` are present, snake_case wins. Mutates the object in place.

πŸ“€ Exports (heuristic)

  • normalizeControlMessageKeys

πŸ–₯️ Source preview

/**
 * Normalize camelCase `requestId` β†’ snake_case `request_id` on incoming
 * control messages (control_request, control_response).
 *
 * Older iOS app builds send `requestId` due to a missing Swift CodingKeys
 * mapping. Without this shim, `isSDKControlRequest` in replBridge.ts rejects
 * the message (it checks `'request_id' in value`), and structuredIO.ts reads
 * `message.response.request_id` as undefined β€” both silently drop the message.
 *
 * If both `request_id` and `requestId` are present, snake_case wins.
 * Mutates the object in place.
 */
export function normalizeControlMessageKeys(obj: unknown): unknown {
  if (obj === null || typeof obj !== 'object') return obj
  const record = obj as Record<string, unknown>
  if ('requestId' in record && !('request_id' in record)) {
    record.request_id = record.requestId
    delete record.requestId
  }
  if (
    'response' in record &&
    record.response !== null &&
    typeof record.response === 'object'
  ) {
    const response = record.response as Record<string, unknown>
    if ('requestId' in response && !('request_id' in response)) {
      response.request_id = response.requestId
      delete response.requestId
    }
  }
  return obj
}