{"version":3,"file":"derive-BvtWyo5B.cjs","names":["TYPE","TYPE"],"sources":["../src/utils/isSupportedFileFormatTransform.ts","../src/utils/base64.ts","../src/derive/utils/traverseIcu.ts","../src/derive/utils/constants.ts","../src/derive/utils/regex.ts","../src/derive/utils/traverseHelpers.ts","../src/derive/decodeVars.ts","../src/derive/utils/sanitizeVar.ts","../src/derive/declareVar.ts","../src/derive/derive.ts"],"sourcesContent":["import type { FileFormat } from '../types-dir/api/file';\n\nconst SUPPORTED_TRANSFORMATIONS = {\n  GTJSON: ['GTJSON'],\n  JSON: ['JSON'],\n  PO: ['PO'],\n  // POT templates can produce translated PO catalog files.\n  POT: ['POT', 'PO'],\n  YAML: ['YAML'],\n  MDX: ['MDX'],\n  MD: ['MD'],\n  TS: ['TS'],\n  JS: ['JS'],\n  HTML: ['HTML'],\n  TXT: ['TXT'],\n  TWILIO_CONTENT_JSON: ['TWILIO_CONTENT_JSON'],\n} as const satisfies Record<FileFormat, FileFormat[]>;\n\n/**\n * This function checks if a file format transformation is supported during translation\n * @param from - The source file format.\n * @param to - The target file format.\n * @returns True if the transformation is supported, false otherwise\n */\nexport function isSupportedFileFormatTransform(\n  from: FileFormat,\n  to: FileFormat\n): boolean {\n  const toFormats: FileFormat[] | undefined = SUPPORTED_TRANSFORMATIONS[from];\n  return toFormats?.includes(to) ?? false;\n}\n","// Encode a string to base64\nexport function encode(data: string): string {\n  if (typeof Buffer !== 'undefined') {\n    // Node.js path.\n    return Buffer.from(data, 'utf8').toString('base64');\n  }\n  // Browser path.\n  const bytes = new TextEncoder().encode(data);\n  let binary = '';\n  for (let i = 0; i < bytes.length; i++) {\n    binary += String.fromCharCode(bytes[i]);\n  }\n  return btoa(binary);\n}\n\n// Decode a base64 string to a string\nexport function decode(base64: string): string {\n  if (typeof Buffer !== 'undefined') {\n    // Node.js path.\n    return Buffer.from(base64, 'base64').toString('utf8');\n  }\n  // Browser path.\n  const binary = atob(base64);\n  const bytes = new Uint8Array(binary.length);\n  for (let i = 0; i < binary.length; i++) {\n    bytes[i] = binary.charCodeAt(i);\n  }\n  return new TextDecoder().decode(bytes);\n}\n","import {\n  MessageFormatElement,\n  parse,\n  ParserOptions,\n  TYPE,\n} from '@formatjs/icu-messageformat-parser';\n\ntype TraverseIcuOptions = ParserOptions & {\n  recurseIntoVisited?: boolean;\n};\n\n/**\n * Given an ICU string, traverse the AST and call the visitor function for each element that matches the type T\n * @param icu - The ICU string to traverse\n * @param shouldVisit - A function that returns true if the element should be visited\n * @param visitor - A function that is called for each element that matches the type T\n * @returns The modified AST of the ICU string.\n *\n * @note This function is a heavy operation, use sparingly\n */\nexport function traverseIcu<T extends MessageFormatElement>({\n  icuString,\n  shouldVisit,\n  visitor,\n  options: { recurseIntoVisited = true, ...otherOptions },\n}: {\n  icuString: string;\n  shouldVisit: (element: MessageFormatElement) => element is T;\n  visitor: (element: T) => void;\n  options: TraverseIcuOptions;\n}): MessageFormatElement[] {\n  const ast = parse(icuString, otherOptions);\n  handleChildren(ast);\n  return ast;\n\n  function handleChildren(children: MessageFormatElement[]): void {\n    children.map(handleChild);\n  }\n\n  function handleChild(child: MessageFormatElement) {\n    // handle select var\n    let visited = false;\n    if (shouldVisit(child)) {\n      visitor(child);\n      visited = true;\n    }\n    // recurse on children\n    if (!visited || recurseIntoVisited) {\n      if (child.type === TYPE.select || child.type === TYPE.plural) {\n        Object.values(child.options)\n          .map((option) => option.value)\n          .map(handleChildren);\n      } else if (child.type === TYPE.tag) {\n        handleChildren(child.children);\n      }\n    }\n  }\n}\n","export const VAR_IDENTIFIER = '_gt_';\nexport const VAR_NAME_IDENTIFIER = '_gt_var_name';\n","import { VAR_IDENTIFIER } from './constants';\n\n// Regex  for _gt_# select\nexport const GT_INDEXED_IDENTIFIER_REGEX = new RegExp(\n  `^${VAR_IDENTIFIER}\\\\d+$`\n);\n\nexport const GT_UNINDEXED_IDENTIFIER_REGEX = new RegExp(`^${VAR_IDENTIFIER}$`);\n","import {\n  GT_INDEXED_IDENTIFIER_REGEX,\n  GT_UNINDEXED_IDENTIFIER_REGEX,\n} from './regex';\nimport { GTIndexedSelectElement, GTUnindexedSelectElement } from './types';\nimport { TYPE } from '@formatjs/icu-messageformat-parser';\nimport type { MessageFormatElement } from '@formatjs/icu-messageformat-parser/types.js';\n\n// Visit any _gt_# select\nexport function isGTIndexedSelectElement(\n  child: MessageFormatElement\n): child is GTIndexedSelectElement {\n  return (\n    child.type === TYPE.select &&\n    GT_INDEXED_IDENTIFIER_REGEX.test(child.value) &&\n    !!child.options.other &&\n    (child.options.other.value.length === 0 ||\n      (child.options.other.value.length > 0 &&\n        child.options.other.value[0]?.type === TYPE.literal))\n  );\n}\n\n// Visit any _gt_ select\nexport function isGTUnindexedSelectElement(\n  child: MessageFormatElement\n): child is GTUnindexedSelectElement {\n  return (\n    child.type === TYPE.select &&\n    GT_UNINDEXED_IDENTIFIER_REGEX.test(child.value) &&\n    !!child.options.other &&\n    (child.options.other.value.length === 0 ||\n      (child.options.other.value.length > 0 &&\n        child.options.other.value[0]?.type === TYPE.literal))\n  );\n}\n","import { traverseIcu } from './utils/traverseIcu';\nimport { VAR_IDENTIFIER } from './utils/constants';\nimport { GTUnindexedSelectElement } from './utils/types';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\n\ntype Location = {\n  start: number;\n  end: number;\n  value: string;\n};\n\n/**\n * Given an encoded ICU string, interpolate only _gt_ variables that have been marked with declareVar()\n * @example\n * const encodedIcu = \"Hi\" + declareVar(\"Brian\") + \", my name is {name}\"\n * // 'Hi {_gt_, select, other {Brian}}, my name is {name}'\n * decodeVars(encodedIcu)\n * // 'Hi Brian, my name is {name}'\n */\nexport function decodeVars(icuString: string): string {\n  // Check if the string contains _gt_\n  if (!icuString.includes(VAR_IDENTIFIER)) {\n    return icuString;\n  }\n\n  // Record the location of the variable\n  const variableLocations: Location[] = [];\n  function visitor(child: GTUnindexedSelectElement): void {\n    variableLocations.push({\n      start: child.location?.start.offset ?? 0,\n      end: child.location?.end.offset ?? 0,\n      value:\n        child.options.other.value.length > 0\n          ? child.options.other.value[0].value\n          : '',\n    });\n  }\n\n  // Find all variable identifiers.\n  traverseIcu({\n    icuString,\n    shouldVisit: isGTUnindexedSelectElement,\n    visitor,\n    options: {\n      recurseIntoVisited: false,\n      captureLocation: true,\n    },\n  });\n\n  // Construct output string\n  let previousIndex = 0;\n  const outputList = [];\n  for (let i = 0; i < variableLocations.length; i++) {\n    outputList.push(icuString.slice(previousIndex, variableLocations[i].start));\n    outputList.push(variableLocations[i].value);\n    previousIndex = variableLocations[i].end;\n  }\n  if (previousIndex < icuString.length) {\n    outputList.push(icuString.slice(previousIndex));\n  }\n  const outputString = outputList.join('');\n\n  return outputString;\n}\n","/**\n * Sanitizes string by escaping ICU syntax\n *\n * Sanitize arbitrary string so it does not break the following ICU message syntax:\n * {_gt_, select, other {string_here}}\n *\n * Escapes ICU special characters by:\n * 1. Doubling all single quotes (U+0027 ')\n * 2. Adding a single quote before the first special character ({}<>)\n * 3. Adding a single quote after the last special character ({}<>)\n */\nexport function sanitizeVar(string: string): string {\n  // First, double all single quotes (both ASCII and Unicode).\n  let result = string.replace(/'/g, \"''\");\n\n  // Find first and last positions of special characters\n  const specialChars = /[{}<>]/;\n  const firstSpecialIndex = result.search(specialChars);\n\n  if (firstSpecialIndex === -1) {\n    // No special characters; return with just doubled quotes.\n    return result;\n  }\n\n  // Find last special character position\n  let lastSpecialIndex = -1;\n  for (let i = result.length - 1; i >= 0; i--) {\n    if (specialChars.test(result[i])) {\n      lastSpecialIndex = i;\n      break;\n    }\n  }\n\n  // Insert quotes around the special character region.\n  result =\n    result.slice(0, firstSpecialIndex) +\n    \"'\" +\n    result.slice(firstSpecialIndex, lastSpecialIndex + 1) +\n    \"'\" +\n    result.slice(lastSpecialIndex + 1);\n\n  return result;\n}\n","import { VAR_IDENTIFIER, VAR_NAME_IDENTIFIER } from './utils/constants';\nimport { sanitizeVar } from './utils/sanitizeVar';\n\n/**\n * Mark as a non-translatable string. Use within a derive() call to mark content as not derivable (e.g., not possible to statically analyze).\n *\n * @example\n * function nonDerivableFunction() {\n *   return Math.random();\n * }\n *\n * function derivableFunction() {\n *   if (condition) {\n *     return declareVar(nonDerivableFunction())\n *   }\n *   return 'John Doe';\n * }\n *\n * const gt = useGT();\n * gt(`My name is ${derive(derivableFunction())}`);\n *\n * @param {string | number | boolean | null | undefined} variable - The variable to sanitize.\n * @param {Object} [options] - The options for the sanitization.\n * @param {string} [options.$name] - The name of the variable.\n * @returns {string} The sanitized value.\n */\nexport function declareVar(\n  variable: string | number | boolean | null | undefined,\n  options?: { $name?: string }\n): string {\n  // Variable section.\n  const sanitizedVariable = sanitizeVar(String(variable ?? ''));\n  const variableSection = ` other {${sanitizedVariable}}`;\n\n  // Name section.\n  let nameSection = '';\n  if (options?.$name) {\n    const sanitizedName = sanitizeVar(options.$name);\n    nameSection = ` ${VAR_NAME_IDENTIFIER} {${sanitizedName}}`;\n  }\n\n  // interpolate\n  return `{${VAR_IDENTIFIER}, select,${variableSection}${nameSection}}`;\n}\n","/**\n * Marks content as derivable by the GT compiler and CLI.\n *\n * Use `derive()` when a translation string or context needs content that is\n * computed from source code, but should still be discovered during extraction\n * instead of treated as a runtime interpolation variable. The CLI attempts to\n * resolve the derivable expression into every possible static value and\n * includes those values in the source content that gets translated.\n *\n * `derive()` returns its argument unchanged at runtime.\n *\n * Run `gt validate` after adding or changing `derive()` calls to verify that\n * each derivable expression can be resolved by the CLI before translating or\n * building.\n *\n * @example\n * ```jsx\n * function getSubject() {\n *   return (Math.random() > 0.5) ? \"Alice\" : \"Brian\";\n * }\n * ...\n * gt(`My name is ${derive(getSubject())}`);\n * ```\n *\n * @param {T extends string | boolean | number | null | undefined} content - Content to derive for translation extraction.\n * @returns {T} The same content, unchanged at runtime.\n */\nexport function derive<T extends string | boolean | number | null | undefined>(\n  content: T\n): T {\n  return content;\n}\n"],"mappings":"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"}