{"version":3,"sources":["../src/index.ts","../src/runtime.ts"],"sourcesContent":["import { base64ToUtf8, utf8ToBase64 } from \"./runtime\";\n\n/**\n * Encodes a string as base64url\n *\n * @param input string to encode\n * @returns base64url-encoded string\n * @throws {Error} If input is not a string\n */\nexport const encodeBase64Url = (input: string): string => {\n  if (typeof input !== \"string\") {\n    throw new Error(\"encodeBase64Url: input must be a string\");\n  }\n\n  return toBase64Url(utf8ToBase64(input));\n};\n\n/**\n * Decodes a base64url-encoded string to plain text\n *\n * @param input base64url-encoded string to decode\n * @returns decoded plain text string\n * @throws {Error} If input is not a string\n */\nexport const decodeBase64Url = (input: string): string => {\n  if (typeof input !== \"string\") {\n    throw new Error(\"decodeBase64Url: input must be a string\");\n  }\n\n  return base64ToUtf8(fromBase64Url(input));\n};\n\n/** Converts standard Base64 into a URL-safe version (RFC 4648, Section 5) */\nconst toBase64Url = (base64: string): string =>\n  base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n\n/** Converts URL-safe Base64 back to standard form (RFC 4648, Section 4: restores `+` and `/`) */\nconst fromBase64Url = (base64Url: string): string => base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n","type Runtime = \"buffer\" | \"text-encoding\";\n\nlet cachedRuntime: Runtime | null = null;\n\n/** Picks the fastest available base64 path */\nconst detectRuntime = (): Runtime => {\n  if (typeof Buffer !== \"undefined\" && typeof Buffer.from === \"function\") {\n    return \"buffer\";\n  }\n\n  if (\n    typeof TextEncoder !== \"undefined\" &&\n    typeof TextDecoder !== \"undefined\" &&\n    typeof btoa === \"function\" &&\n    typeof atob === \"function\"\n  ) {\n    return \"text-encoding\";\n  }\n\n  throw new Error(\"No UTF-8 base64 implementation available\");\n};\n\n/** Detects the runtime once, reuses the cached result */\nconst getRuntime = (): Runtime => {\n  if (cachedRuntime === null) {\n    cachedRuntime = detectRuntime();\n  }\n\n  return cachedRuntime;\n};\n\n/** @internal Resets lazy runtime detection (for tests). */\nexport const resetRuntimeForTesting = (): void => {\n  cachedRuntime = null;\n};\n\n/** Converts raw bytes to a \"binary string\" (one char code per byte - the format that `btoa` expects) */\nconst bytesToBinaryString = (bytes: Uint8Array): string => {\n  let binary = \"\";\n\n  for (let i = 0; i < bytes.length; i++) {\n    binary += String.fromCharCode(bytes[i]);\n  }\n\n  return binary;\n};\n\n/** Converts an `atob` \"binary string\" back to raw bytes for `TextDecoder` */\nconst binaryStringToBytes = (binary: string): Uint8Array => {\n  const bytes = new Uint8Array(binary.length);\n\n  for (let i = 0; i < binary.length; i++) {\n    bytes[i] = binary.charCodeAt(i);\n  }\n\n  return bytes;\n};\n\n/** Restores `=` padding that base64url strips, since `atob` requires a padded input */\nconst padBase64 = (base64: string): string => {\n  const remainder = base64.length % 4;\n\n  if (remainder === 0) {\n    return base64;\n  }\n\n  return base64 + \"=\".repeat(4 - remainder);\n};\n\n// Node path: Buffer handles UTF-8 → base64 directly, no manual byte conversion needed\nconst encodeWithBuffer = (input: string): string => Buffer.from(input, \"utf8\").toString(\"base64\");\n\nconst decodeWithBuffer = (input: string): string => Buffer.from(input, \"base64\").toString(\"utf8\");\n\n// Browser/worker path: encode to UTF-8 bytes, then to a binary string btoa can base64-encode\nconst encodeWithTextEncoding = (input: string): string =>\n  btoa(bytesToBinaryString(new TextEncoder().encode(input)));\n\nconst decodeWithTextEncoding = (input: string): string =>\n  new TextDecoder().decode(binaryStringToBytes(atob(padBase64(input))));\n\n/** @internal UTF-8 string → standard Base64. */\nexport const utf8ToBase64 = (input: string): string => {\n  switch (getRuntime()) {\n    case \"buffer\":\n      return encodeWithBuffer(input);\n    case \"text-encoding\":\n      return encodeWithTextEncoding(input);\n  }\n};\n\n/** @internal Standard Base64 → UTF-8 string. */\nexport const base64ToUtf8 = (input: string): string => {\n  switch (getRuntime()) {\n    case \"buffer\":\n      return decodeWithBuffer(input);\n    case \"text-encoding\":\n      return decodeWithTextEncoding(input);\n  }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAI,gBAAgC;AAGpC,IAAM,gBAAgB,MAAe;AACnC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,SAAS,YAAY;AACtE,WAAO;AAAA,EACT;AAEA,MACE,OAAO,gBAAgB,eACvB,OAAO,gBAAgB,eACvB,OAAO,SAAS,cAChB,OAAO,SAAS,YAChB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,0CAA0C;AAC5D;AAGA,IAAM,aAAa,MAAe;AAChC,MAAI,kBAAkB,MAAM;AAC1B,oBAAgB,cAAc;AAAA,EAChC;AAEA,SAAO;AACT;AAQA,IAAM,sBAAsB,CAAC,UAA8B;AACzD,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AAEA,SAAO;AACT;AAGA,IAAM,sBAAsB,CAAC,WAA+B;AAC1D,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAE1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AAEA,SAAO;AACT;AAGA,IAAM,YAAY,CAAC,WAA2B;AAC5C,QAAM,YAAY,OAAO,SAAS;AAElC,MAAI,cAAc,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO,SAAS,IAAI,OAAO,IAAI,SAAS;AAC1C;AAGA,IAAM,mBAAmB,CAAC,UAA0B,OAAO,KAAK,OAAO,MAAM,EAAE,SAAS,QAAQ;AAEhG,IAAM,mBAAmB,CAAC,UAA0B,OAAO,KAAK,OAAO,QAAQ,EAAE,SAAS,MAAM;AAGhG,IAAM,yBAAyB,CAAC,UAC9B,KAAK,oBAAoB,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC,CAAC;AAE3D,IAAM,yBAAyB,CAAC,UAC9B,IAAI,YAAY,EAAE,OAAO,oBAAoB,KAAK,UAAU,KAAK,CAAC,CAAC,CAAC;AAG/D,IAAM,eAAe,CAAC,UAA0B;AACrD,UAAQ,WAAW,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,iBAAiB,KAAK;AAAA,IAC/B,KAAK;AACH,aAAO,uBAAuB,KAAK;AAAA,EACvC;AACF;AAGO,IAAM,eAAe,CAAC,UAA0B;AACrD,UAAQ,WAAW,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,iBAAiB,KAAK;AAAA,IAC/B,KAAK;AACH,aAAO,uBAAuB,KAAK;AAAA,EACvC;AACF;;;AD1FO,IAAM,kBAAkB,CAAC,UAA0B;AACxD,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,SAAO,YAAY,aAAa,KAAK,CAAC;AACxC;AASO,IAAM,kBAAkB,CAAC,UAA0B;AACxD,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,SAAO,aAAa,cAAc,KAAK,CAAC;AAC1C;AAGA,IAAM,cAAc,CAAC,WACnB,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAGlE,IAAM,gBAAgB,CAAC,cAA8B,UAAU,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;","names":[]}