{"version":3,"file":"cscLink.js","sourceRoot":"","sources":["../src/cscLink.ts"],"names":[],"mappings":";;AAMA,kDAMC;AAGD,gDAmBC;AASD,kCAgBC;AA3DD,0CAAsC;AACtC,2BAA4B;AAC5B,6BAA4B;AAC5B,6BAAiC;AAEjC,yFAAyF;AACzF,SAAgB,mBAAmB,CAAC,IAAY;;IAC9C,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/C,IAAI,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAG,CAAC,EAAE,MAAM,mCAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,kGAAkG;AAClG,SAAgB,kBAAkB,CAAC,OAAe,EAAE,YAAgC;IAClF,IAAI,IAAI,GAAG,OAAO,CAAA;IAClB,IAAI,OAAO,GAAG,YAAY,CAAA;IAC1B,MAAM,UAAU,GAAG,SAAS,CAAA;IAE5B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,GAAG,IAAA,YAAO,GAAE,CAAA;QACnB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACtB,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,qDAAqD;QACrD,MAAM,IAAI,KAAK,CAAC,6DAA6D,OAAO,EAAE,CAAC,CAAA;IACzF,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,YAAgC;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE3B,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAC1D,MAAM,IAAI,GAAG,MAAM,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAA;IACvC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,gBAAgB,CAAC,CAAA;IAC9C,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,aAAa,CAAC,CAAA;IAC3C,CAAC;IACD,OAAO,IAAA,mBAAQ,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AACnC,CAAC","sourcesContent":["import { readFile } from \"fs/promises\"\nimport { homedir } from \"os\"\nimport * as path from \"path\"\nimport { statOrNull } from \"./fs\"\n\n/** Decodes a base64 CSC link to a Buffer, or returns null if the value is not base64. */\nexport function decodeCscLinkBase64(link: string): Buffer | null {\n  const mimeMatch = /^data:.*;base64,/.exec(link)\n  if (mimeMatch || link.length > 2048 || link.endsWith(\"=\")) {\n    return Buffer.from(link.substring(mimeMatch?.[0].length ?? 0), \"base64\")\n  }\n  return null\n}\n\n/** Resolves a CSC link file path, expanding `~/`, `file://`, and relative paths against `cwd`. */\nexport function resolveCscLinkPath(cscLink: string, resourcesDir: string | undefined): string {\n  let link = cscLink\n  let baseDir = resourcesDir\n  const filePrefix = \"file://\"\n\n  if (link.startsWith(\"~/\")) {\n    baseDir = homedir()\n    link = link.slice(2)\n  } else if (cscLink.startsWith(filePrefix)) {\n    link = cscLink.slice(filePrefix.length)\n  }\n  if (path.isAbsolute(link)) {\n    return link\n  }\n  if (baseDir == null) {\n    // No base directory to resolve relative path against\n    throw new Error(`CSC link is a relative path but no resourcesDir provided: ${cscLink}`)\n  }\n  return path.resolve(baseDir, link)\n}\n\n/**\n * Resolves a CSC link to its text content.\n *\n * Formats accepted:\n * - Base64: detected by `data:…;base64,` prefix, length > 2048, or trailing `=`\n * - File path: `~/…`, `file://…`, absolute, or relative to `cwd`\n */\nexport async function loadCscLink(link: string, resourcesDir: string | undefined): Promise<string> {\n  const trimmed = link.trim()\n\n  const decoded = decodeCscLinkBase64(trimmed)\n  if (decoded) {\n    return decoded.toString(\"utf8\")\n  }\n\n  const filePath = resolveCscLinkPath(trimmed, resourcesDir)\n  const stat = await statOrNull(filePath)\n  if (stat == null) {\n    throw new Error(`${filePath} doesn't exist`)\n  } else if (!stat.isFile()) {\n    throw new Error(`${filePath} not a file`)\n  }\n  return readFile(filePath, \"utf8\")\n}\n"]}