{"version":3,"sources":["../../src/protocol/personal-server-error-body.ts"],"sourcesContent":["/**\n * Reader for the error bodies a Personal Server (or the gateway) answers\n * with. Protocol errors use `{ error: { code, errorCode, message, details? } }`;\n * contract-level rejections use `{ error: \"CODE\", message }`; the gateway\n * uses `{ success: false, error: \"<message>\", code: \"CODE\" }` with lineage\n * detail fields (`unknown`, `scope`, `sourceScope`) at the top level; older\n * clients saw `{ code, message }`. All four are accepted.\n *\n * @internal\n */\n\nexport interface PersonalServerErrorBody {\n  errorCode: string | null;\n  message: string | null;\n  details?: Record<string, unknown>;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n  return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/** Read a non-2xx response body; never throws. */\nexport async function readPersonalServerErrorBody(\n  response: Response,\n): Promise<PersonalServerErrorBody> {\n  let body: unknown;\n  try {\n    body = await response.json();\n  } catch {\n    return { errorCode: null, message: null };\n  }\n  if (!isRecord(body)) return { errorCode: null, message: null };\n  const nested = isRecord(body.error) ? body.error : null;\n  // Gateway bodies are `{ success: false, error: <message>, code: <CODE> }`;\n  // the Personal Server's contract rejections are `{ error: <CODE>, message }`.\n  const gatewayShape =\n    typeof body.error === \"string\" && typeof body.code === \"string\";\n  const code =\n    nested?.errorCode ??\n    nested?.code ??\n    body.errorCode ??\n    (gatewayShape ? body.code : undefined) ??\n    (typeof body.error === \"string\" ? body.error : undefined) ??\n    body.code;\n  const message =\n    nested?.message ?? body.message ?? (gatewayShape ? body.error : undefined);\n  // Gateway lineage rejections carry their detail fields at the top level.\n  const gatewayDetails: Record<string, unknown> = {};\n  for (const key of [\"unknown\", \"scope\", \"sourceScope\"]) {\n    if (gatewayShape && body[key] !== undefined)\n      gatewayDetails[key] = body[key];\n  }\n  const details =\n    nested?.details ??\n    body.details ??\n    (Object.keys(gatewayDetails).length > 0 ? gatewayDetails : undefined);\n  return {\n    errorCode: typeof code === \"string\" ? code : null,\n    message: typeof message === \"string\" ? message : null,\n    ...(isRecord(details) ? { details } : {}),\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBO,SAAS,SAAS,OAAkD;AACzE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGA,eAAsB,4BACpB,UACkC;AAClC,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,EAAE,WAAW,MAAM,SAAS,KAAK;AAAA,EAC1C;AACA,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO,EAAE,WAAW,MAAM,SAAS,KAAK;AAC7D,QAAM,SAAS,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ;AAGnD,QAAM,eACJ,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,SAAS;AACzD,QAAM,OACJ,QAAQ,aACR,QAAQ,QACR,KAAK,cACJ,eAAe,KAAK,OAAO,YAC3B,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,WAC/C,KAAK;AACP,QAAM,UACJ,QAAQ,WAAW,KAAK,YAAY,eAAe,KAAK,QAAQ;AAElE,QAAM,iBAA0C,CAAC;AACjD,aAAW,OAAO,CAAC,WAAW,SAAS,aAAa,GAAG;AACrD,QAAI,gBAAgB,KAAK,GAAG,MAAM;AAChC,qBAAe,GAAG,IAAI,KAAK,GAAG;AAAA,EAClC;AACA,QAAM,UACJ,QAAQ,WACR,KAAK,YACJ,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;AAC7D,SAAO;AAAA,IACL,WAAW,OAAO,SAAS,WAAW,OAAO;AAAA,IAC7C,SAAS,OAAO,YAAY,WAAW,UAAU;AAAA,IACjD,GAAI,SAAS,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzC;AACF;","names":[]}