Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common util encode should take an object and stringify #904

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/light-spiders-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@openfn/language-common': minor
---

Common util functions `encode` and `decode` can now take a JavaScript object and
stringify
55 changes: 46 additions & 9 deletions packages/common/src/util/base64.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
import _ from 'lodash';

/**
* Encodes a given string into Base64 format.
* Encodes a given string or Javascript object into Base64 format.
* @function
* @public
* @namespace util
* @param {string} data - The string to be encoded.
* @param {string | object} data - The string or object to be encoded.
* @param {object} options - Options.
* @returns {string} - The Base64 encoded string.
* @example <caption>Encode a string</caption>
* const encoded = encode('Hello World');
* const encodedString = encode('Hello World');
* console.log(encoded); // Output: SGVsbG8gV29ybGQ=
* @example <caption>Encode an object</caption>
* const encodedObject = encode({name: 'Jane Doe'})
PiusKariuki marked this conversation as resolved.
Show resolved Hide resolved
* console.log(encodedObject); //output eyJuYW1lIjoiSmFuZSBEb2UifQ==
* @example <caption>To skip the JSON stringification step</caption>
* const encodedObject = encode('Hello World', {parseJson: false})
*/
export const encode = data => Buffer.from(data, 'utf-8').toString('base64');
export const encode = (data, options = {parseJson: true}) => {
let str = data;

/**
if(typeof data !== "string" && options.parseJson){
try {
str = JSON.stringify(str);
} catch (e){
console.log(e.message);
}
}

return Buffer.from(str, 'utf-8').toString('base64');
}

/**4
* Decodes a Base64 encoded string back to its original format.
* @function
* @public
* @namespace util
* @param {string} base64Data - The Base64 encoded string.
* @returns {string} - The decoded string.
* @param {object} options - Options.
* @returns {string | object} - The decoded string or JavaScript Object.
* @example <caption>Decode a Base64 string</caption>
* const decoded = decode('SGVsbG8gV29ybGQ=');
* console.log(decoded); // Output: Hello World
* @example <caption>Decode a Base64 JSON object to a standard JavaScript object</caption>
* const decoded = decode('eyJuYW1lIjoiSmFuZSBEb2UifQ==');
* console.log(decoded); // Output: {name: 'Jane Doe'}
* @example <caption>To skip the JSON stringification step</caption>
* const decodedString = decode('Hello World', {parseJson: false})
*/
export const decode = base64Data =>
Buffer.from(base64Data, 'base64').toString('utf-8');
export const decode = (base64Data, options = {parseJson: true}) =>{
let decodedValue = Buffer.from(base64Data, 'base64').toString('utf-8');

if((_.startsWith(decodedValue, '[') || _.startsWith(decodedValue, '{')) && options.parseJson) {
try {
decodedValue = JSON.parse(decodedValue);
} catch (e) {
console.log(e.message);
}
}

return decodedValue;
}

20 changes: 15 additions & 5 deletions packages/common/test/util/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,23 @@ describe('encode', () => {
it('should encode a string to Base64', () => {
expect(encode('Hello World')).to.eql('SGVsbG8gV29ybGQ=');
});
it('should encode a string to Base64 while skipping the JSON stringification step', () => {
expect(encode('Hello World', {parseJson: false})).to.eql('SGVsbG8gV29ybGQ=');
});

it('should encode an empty string to Base64', () => {
expect(encode('')).to.eql('');
});
it('should encode emoji to Base64', () => {
expect(encode('😀')).to.eql('8J+YgA==');
});
it('should throw an error if the string is not a string', () => {
expect(() => encode(123)).to.throw(errorMsg);
expect(() => encode(true)).to.throw(errorMsg);
expect(() => encode(null)).to.throw(errorMsg);
expect(() => encode({})).to.throw(errorMsg);
it('should throw an error if a function is passed', () => {
expect(() => encode(() => {})).to.throw(errorMsg);
});
it('should encode a javascript object', () => {
PiusKariuki marked this conversation as resolved.
Show resolved Hide resolved
const obj = {"name": "Jane Doe"}
expect(encode(obj)).to.eql("eyJuYW1lIjoiSmFuZSBEb2UifQ==");
});
});

describe('decode', () => {
Expand All @@ -52,8 +55,15 @@ describe('decode', () => {
it('should decode a Base64 string back to its original string', () => {
expect(decode('SGVsbG8gV29ybGQ=')).to.eql('Hello World');
});
it('should decode a Base64 string back to its original string without needing to JSON parse', () => {
expect(decode('SGVsbG8gV29ybGQ=', {parseJson: false})).to.eql('Hello World');
});

it('should decode an empty Base64 string', () => {
expect(decode('')).to.eql('');
});
it('should decode a JSON object into a standard javascript object', () => {
const obj = {name: "Jane Doe"}
expect(decode('eyJuYW1lIjoiSmFuZSBEb2UifQ==')).to.eql(obj);
});
});