sveltejs / prettier-plugin-svelte

Format your svelte components using prettier.
MIT License
714 stars 95 forks source link

Remove Buffer usage for Browser Environments #423

Closed curran closed 4 months ago

curran commented 5 months ago

Closes https://github.com/sveltejs/prettier-plugin-svelte/issues/418

Conduitry commented 5 months ago

Are there concerns with atob/btoa's handling of non-ascii characters?

curran commented 5 months ago

That would be great to add test cases for.

For example

const str = "Hello, world! 😊 Привет, мир! こんにちは世界";

Here's one way that could be solved.

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)));

In order to actually test that code path, the tests would need to run in a browser environment.

curran commented 5 months ago

I added the handling of non-ASCII characters. I haven't tested this yet in an actual browser environment. I hope to do that soon.

curran commented 5 months ago

It works!

Before

image

After

image

I tested it by merging the browser build branch and this one into a local build, then used npm link to include it in my local build of https://github.com/vizhub-core/vzcode , which thanks to this new work will shortly have Prettier support for Svelte files!

Thanks all for the reviews and comments. This is the magic of open source right here.

curran commented 5 months ago

I've addressed all the feedback and I believe this is ready to go. Thanks!

curran commented 5 months ago

Some alternative implementations:

function base64Encode(str) {
  const encoder = new TextEncoder();
  const encoded = encoder.encode(str);
  return btoa(String.fromCharCode(...encoded));
}

function base64Decode(str) {
  const decoder = new TextDecoder();
  const bytes = Uint8Array.from(atob(str), c => c.charCodeAt(0));
  return decoder.decode(bytes);
}
curran commented 4 months ago

My pleasure! Thanks for reviewing and merging!