{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA+CA,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IAEnC,YAAY,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAGxD;IAED,QAAQ,IAAI,MAAM,CAIjB;CACF;AAED,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,cAAc,GACd,SAAS,GACT,IAAI,GACJ,SAAS,EAAE,CAAC;AAEhB,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAE,SAAc,GAAG,cAAc,CAEvF","sourcesContent":["const ENCODE_HTML_RULES: Record<string, string> = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&#34;',\n  \"'\": '&#39;',\n};\nconst MATCH_HTML = /[&<>'\"]/g;\n\nfunction encodeCharacter(c: string) {\n  return ENCODE_HTML_RULES[c] || c;\n}\n\n/**\n * Based on the `escapeXML` function from the `ejs` library.\n */\nfunction escapeHtmlRaw(value: string): string {\n  return value == null ? '' : String(value).replaceAll(MATCH_HTML, encodeCharacter);\n}\n\nfunction escapeValue(value: unknown): string {\n  if (value instanceof HtmlSafeString) {\n    // Already escaped!\n    return value.toString();\n  } else if (Array.isArray(value)) {\n    return value.map((val) => escapeValue(val)).join('');\n  } else if (\n    typeof value === 'string' ||\n    typeof value === 'number' ||\n    typeof value === 'bigint' ||\n    typeof value === 'boolean'\n  ) {\n    return escapeHtmlRaw(String(value));\n  } else if (value == null) {\n    // undefined or null -- render nothing\n    return '';\n  } else if (typeof value === 'object') {\n    throw new Error(`Cannot interpolate object in template: ${JSON.stringify(value)}`);\n  } else {\n    // There shouldn't be any other types\n    throw new Error(\n      `Unexpected type in template: ${typeof value} for value ${JSON.stringify(value)}`,\n    );\n  }\n}\n\n// Based on https://github.com/Janpot/escape-html-template-tag\nexport class HtmlSafeString {\n  private readonly strings: readonly string[];\n  private readonly values: unknown[];\n\n  constructor(strings: readonly string[], values: unknown[]) {\n    this.strings = strings;\n    this.values = values;\n  }\n\n  toString(): string {\n    return this.values.reduce<string>((acc, val, i) => {\n      return acc + escapeValue(val) + this.strings[i + 1];\n    }, this.strings[0]);\n  }\n}\n\nexport type HtmlValue =\n  | string\n  | number\n  | boolean\n  | bigint\n  | HtmlSafeString\n  | undefined\n  | null\n  | HtmlValue[];\n\nexport function html(strings: TemplateStringsArray, ...values: HtmlValue[]): HtmlSafeString {\n  return new HtmlSafeString(strings, values);\n}\n\n/**\n * Pre-escapes the rendered HTML. Useful for when you want to inline the HTML\n * in something else, for instance in a `data-bs-content` attribute for a Bootstrap\n * popover.\n */\nexport function escapeHtml(html: HtmlSafeString): HtmlSafeString {\n  return unsafeHtml(escapeHtmlRaw(html.toString()));\n}\n\n/**\n * Will render the provided value without any additional escaping. Use carefully\n * with user-provided data.\n *\n * @param value The value to render.\n * @returns An {@link HtmlSafeString} representing the provided value.\n */\nexport function unsafeHtml(value: string): HtmlSafeString {\n  return new HtmlSafeString([value], []);\n}\n\n/**\n * Joins a list of HTML values with a separator.\n *\n * @param values The values to join.\n * @param separator The separator to use between values.\n */\nexport function joinHtml(values: HtmlValue[], separator: HtmlValue = ''): HtmlSafeString {\n  return unsafeHtml(values.map(escapeValue).join(escapeValue(separator)));\n}\n"]}