You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
encodeToBase64 / decodeFromBase64 depend on Buffer, which forces a polyfill in browser bundles #276
encodeToBase64 and decodeFromBase64 use Buffer, which does not exist in browsers, so any bundler that includes utils/base64.ts injects a Buffer polyfill:
#274 removed the crypto import from this file, which was the part pulling the 555 KB crypto-browserify chain. Buffer is the remaining browser-hostile dependency in the encode path.
Why it matters
It keeps a polyfill in the bundle of every browser consumer that reaches this file, and @sasjs/utils is a browser-facing package. The function is otherwise pure - the prefix is obfuscation padding and the encoding is plain base64.
Proposed fix
Use the platform APIs, keeping the output byte-identical:
encode: btoa(String.fromCharCode(...new TextEncoder().encode(s)))
decode: new TextDecoder().decode(Uint8Array.from(atob(str), (c) => c.charCodeAt(0)))
TextEncoder/TextDecoder matter rather than a bare btoa: this function stores CLI credentials, and btoa is latin1, so a naive swap corrupts non-ASCII passwords. The spread also needs care for long strings - build the binary string in chunks rather than spreading a large array.
Keep the Node Buffer path if the extra branch is wanted, or drop it now that the floor is node >= 22, where btoa/atob/TextEncoder are globals.
Note on scope
This does not by itself remove the Buffer polyfill from sasjs/adapter - the adapter uses Buffer.from directly in getAccessTokenForViya.ts and refreshTokensForViya.ts. It is worth doing so this file is browser-clean on its own merits, and so the encode path carries no dependency a bundler has to shim.
Verification
round-trip a non-ASCII password (for example passwoerd-日本語) through encode then decode, and assert equality
assert the emitted value still matches ^{sasjs_encoded}, and that decode still strips a fixed 200-character offset, so stored credentials keep decoding
Activity
fix(utils): encode and decode base64 without Buffer (#282)
sasjs-gha commentedon Oct 15, 2026
🎉 This issue has been resolved in version 3.7.4 🎉
The release is available on GitHub release
Your semantic-release bot 📦🚀