diff --git a/src/base64-string.ts b/src/base64-string.ts new file mode 100644 index 0000000..887084f --- /dev/null +++ b/src/base64-string.ts @@ -0,0 +1,20 @@ +// Base64 string encoding and decoding module. +// Uses Buffer for Node.js and btoa/atob for browser environments. +// We use TextEncoder/TextDecoder for browser environments because +// they can handle non-ASCII characters, unlike btoa/atob. + +export const stringToBase64 = + typeof Buffer !== 'undefined' + ? (str: string) => Buffer.from(str).toString('base64') + : (str: string) => + btoa( + new TextEncoder() + .encode(str) + .reduce((acc, byte) => acc + String.fromCharCode(byte), ''), + ); + +export const base64ToString = + typeof Buffer !== 'undefined' + ? (str: string) => Buffer.from(str, 'base64').toString() + : (str: string) => + new TextDecoder().decode(Uint8Array.from(atob(str), (c) => c.charCodeAt(0))); diff --git a/src/embed.ts b/src/embed.ts index e3aab56..c04a953 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -21,6 +21,7 @@ import { } from './print/node-helpers'; import { CommentNode, ElementNode, Node, ScriptNode, StyleNode } from './print/nodes'; import { extractAttributes } from './lib/extractAttributes'; +import { base64ToString } from './base64-string'; const { builders: { group, hardline, softline, indent, dedent, literalline }, @@ -253,7 +254,7 @@ function getSnippedContent(node: Node) { const encodedContent = getAttributeTextValue(snippedTagContentAttribute, node); if (encodedContent) { - return Buffer.from(encodedContent, 'base64').toString('utf-8'); + return base64ToString(encodedContent); } else { return ''; } diff --git a/src/lib/snipTagContent.ts b/src/lib/snipTagContent.ts index 8933726..cb02d8d 100644 --- a/src/lib/snipTagContent.ts +++ b/src/lib/snipTagContent.ts @@ -1,3 +1,5 @@ +import { base64ToString, stringToBase64 } from '../base64-string'; + export const snippedTagContentAttribute = '✂prettier:content✂'; const scriptRegex = @@ -42,7 +44,7 @@ export function snipScriptAndStyleTagContent(source: string): string { if (match.startsWith('