π File detail
utils/controlMessageCompat.ts
π― 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
}