{"version":3,"file":"components/Opener/ide.mjs","sources":["../../../src/components/Opener/ide.tsx"],"sourcesContent":["import { Lodash } from '@rsdoctor/utils/common';\nimport { SDK } from '@rsdoctor/types';\nimport React from 'react';\nimport VSCodeIcon from '../../common/svg/vscode.svg';\n\ninterface VSCodeProps {\n  file: string;\n  line?: number | string;\n  column?: number | string;\n  windowId?: number;\n  style?: React.CSSProperties;\n}\n\nconst OPEN_IN_EDITOR_PATH = '/__open-in-editor';\n\nlet openInEditorTokenTask: Promise<string | undefined> | undefined;\n\nfunction clearOpenInEditorTokenTask(task = openInEditorTokenTask) {\n  if (openInEditorTokenTask === task) {\n    openInEditorTokenTask = undefined;\n  }\n}\n\nfunction getOpenInEditorTokenFromSocketUrl(socketUrl?: string) {\n  if (!socketUrl) return undefined;\n  try {\n    return (\n      new URL(socketUrl, window.location.origin).searchParams.get('token') ||\n      undefined\n    );\n  } catch {\n    return undefined;\n  }\n}\n\nasync function getOpenInEditorToken(base: string) {\n  if (!base) return undefined;\n  if (!openInEditorTokenTask) {\n    const task = fetch(`${base}${SDK.ServerAPI.API.Manifest}`)\n      .then((res) => (res.ok ? res.json() : undefined))\n      .then((manifest) => {\n        const token = getOpenInEditorTokenFromSocketUrl(\n          manifest?.__SOCKET__URL__,\n        );\n        if (!token) {\n          clearOpenInEditorTokenTask(task);\n        }\n        return token;\n      })\n      .catch(() => {\n        clearOpenInEditorTokenTask(task);\n        return undefined;\n      });\n    openInEditorTokenTask = task;\n  }\n\n  return openInEditorTokenTask;\n}\n\nasync function openInEditor(\n  file: string,\n  line: number | string,\n  column: number | string,\n  editor: SDK.OpenInEditorKind,\n  urlSchemeFallback: () => void,\n) {\n  const fileSpec = `${file}:${line}:${column}`;\n  try {\n    const base =\n      typeof window !== 'undefined' && window.location?.origin\n        ? window.location.origin\n        : '';\n    const token = await getOpenInEditorToken(base);\n    if (!token) {\n      urlSchemeFallback();\n      return;\n    }\n    const params = new URLSearchParams({\n      file: fileSpec,\n      editor,\n      token,\n    });\n    const res = await fetch(`${base}${OPEN_IN_EDITOR_PATH}?${params}`, {\n      method: 'GET',\n    });\n    if (res.status === 403) {\n      clearOpenInEditorTokenTask();\n    }\n    if (!res.ok) {\n      urlSchemeFallback();\n    }\n  } catch {\n    urlSchemeFallback();\n  }\n}\n\nexport function openVSCode({\n  file,\n  line = 1,\n  column = 1,\n  windowId,\n}: VSCodeProps) {\n  const query: Record<string, unknown> = { windowId };\n  const queryString = Object.keys(query)\n    .map((k) => {\n      const v = query[k];\n      if (Lodash.isNil(v) || v === '') return null;\n      return `${k}=${v}`;\n    })\n    .filter(Boolean)\n    .join('&');\n\n  const fallback = () => {\n    let url = `vscode://file/${file}:${line}:${column}`;\n    if (queryString) url += `?${queryString}`;\n    window.open(url);\n  };\n\n  openInEditor(file, line, column, 'code', fallback);\n}\n\nexport function openCursor({\n  file,\n  line = 1,\n  column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n  const fallback = () => {\n    window.open(`cursor://file/${file}:${line}:${column}`);\n  };\n  openInEditor(file, line, column, 'cursor', fallback);\n}\n\nexport function openTrae({\n  file,\n  line = 1,\n  column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n  const fallback = () => {\n    window.open(`trae://file/${file}:${line}:${column}`);\n  };\n\n  openInEditor(file, line, column, 'trae', fallback);\n}\n\nexport const VSCode = (props: VSCodeProps): React.JSX.Element => {\n  return (\n    <VSCodeIcon\n      onClick={() => {\n        openVSCode(props);\n      }}\n      style={{\n        width: 14,\n        cursor: 'pointer',\n        verticalAlign: 'middle',\n        display: 'inline',\n        transform: 'translateY(-1.5px)',\n        ...props.style,\n      }}\n    />\n  );\n};\n"],"names":["OPEN_IN_EDITOR_PATH","openInEditorTokenTask","clearOpenInEditorTokenTask","task","undefined","getOpenInEditorTokenFromSocketUrl","socketUrl","URL","window","getOpenInEditorToken","base","fetch","SDK","res","manifest","token","openInEditor","file","line","column","editor","urlSchemeFallback","fileSpec","params","URLSearchParams","openVSCode","windowId","query","queryString","Object","k","v","Lodash","Boolean","fallback","url","openCursor","openTrae","VSCode","props","VSCodeIcon"],"mappings":";;;;;AAaA,MAAMA,sBAAsB;AAE5B,IAAIC;AAEJ,SAASC,2BAA2BC,OAAOF,qBAAqB;IAC9D,IAAIA,0BAA0BE,MAC5BF,wBAAwBG;AAE5B;AAEA,SAASC,kCAAkCC,SAAkB;IAC3D,IAAI,CAACA,WAAW;IAChB,IAAI;QACF,OACE,IAAIC,IAAID,WAAWE,OAAO,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,YAC5DJ;IAEJ,EAAE,OAAM;QACN;IACF;AACF;AAEA,eAAeK,qBAAqBC,IAAY;IAC9C,IAAI,CAACA,MAAM;IACX,IAAI,CAACT,uBAAuB;QAC1B,MAAME,OAAOQ,MAAM,GAAGD,OAAOE,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EACtD,IAAI,CAAC,CAACC,MAASA,IAAI,EAAE,GAAGA,IAAI,IAAI,KAAKT,QACrC,IAAI,CAAC,CAACU;YACL,MAAMC,QAAQV,kCACZS,UAAU;YAEZ,IAAI,CAACC,OACHb,2BAA2BC;YAE7B,OAAOY;QACT,GACC,KAAK,CAAC;YACLb,2BAA2BC;QAE7B;QACFF,wBAAwBE;IAC1B;IAEA,OAAOF;AACT;AAEA,eAAee,aACbC,IAAY,EACZC,IAAqB,EACrBC,MAAuB,EACvBC,MAA4B,EAC5BC,iBAA6B;IAE7B,MAAMC,WAAW,GAAGL,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IAC5C,IAAI;QACF,MAAMT,OACJ,AAAkB,MAAlB,OAAOF,UAA0BA,OAAO,QAAQ,EAAE,SAC9CA,OAAO,QAAQ,CAAC,MAAM,GACtB;QACN,MAAMO,QAAQ,MAAMN,qBAAqBC;QACzC,IAAI,CAACK,OAAO,YACVM;QAGF,MAAME,SAAS,IAAIC,gBAAgB;YACjC,MAAMF;YACNF;YACAL;QACF;QACA,MAAMF,MAAM,MAAMF,MAAM,GAAGD,OAAOV,oBAAoB,CAAC,EAAEuB,QAAQ,EAAE;YACjE,QAAQ;QACV;QACA,IAAIV,AAAe,QAAfA,IAAI,MAAM,EACZX;QAEF,IAAI,CAACW,IAAI,EAAE,EACTQ;IAEJ,EAAE,OAAM;QACNA;IACF;AACF;AAEO,SAASI,WAAW,EACzBR,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACVO,QAAQ,EACI;IACZ,MAAMC,QAAiC;QAAED;IAAS;IAClD,MAAME,cAAcC,OAAO,IAAI,CAACF,OAC7B,GAAG,CAAC,CAACG;QACJ,MAAMC,IAAIJ,KAAK,CAACG,EAAE;QAClB,IAAIE,OAAO,KAAK,CAACD,MAAMA,AAAM,OAANA,GAAU,OAAO;QACxC,OAAO,GAAGD,EAAE,CAAC,EAAEC,GAAG;IACpB,GACC,MAAM,CAACE,SACP,IAAI,CAAC;IAER,MAAMC,WAAW;QACf,IAAIC,MAAM,CAAC,cAAc,EAAElB,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;QACnD,IAAIS,aAAaO,OAAO,CAAC,CAAC,EAAEP,aAAa;QACzCpB,OAAO,IAAI,CAAC2B;IACd;IAEAnB,aAAaC,MAAMC,MAAMC,QAAQ,QAAQe;AAC3C;AAEO,SAASE,WAAW,EACzBnB,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACoC;IAC9C,MAAMe,WAAW;QACf1B,OAAO,IAAI,CAAC,CAAC,cAAc,EAAES,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IACvD;IACAH,aAAaC,MAAMC,MAAMC,QAAQ,UAAUe;AAC7C;AAEO,SAASG,SAAS,EACvBpB,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACoC;IAC9C,MAAMe,WAAW;QACf1B,OAAO,IAAI,CAAC,CAAC,YAAY,EAAES,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IACrD;IAEAH,aAAaC,MAAMC,MAAMC,QAAQ,QAAQe;AAC3C;AAEO,MAAMI,SAAS,CAACC,QACd,WAAP,GACE,IAACC,QAAUA;QACT,SAAS;YACPf,WAAWc;QACb;QACA,OAAO;YACL,OAAO;YACP,QAAQ;YACR,eAAe;YACf,SAAS;YACT,WAAW;YACX,GAAGA,MAAM,KAAK;QAChB"}