diff --git a/.changeset/light-spiders-move.md b/.changeset/light-spiders-move.md
new file mode 100644
index 000000000..9679ef656
--- /dev/null
+++ b/.changeset/light-spiders-move.md
@@ -0,0 +1,6 @@
+---
+'@openfn/language-common': minor
+---
+
+Common util functions `encode` and `decode` can now take a JavaScript object and
+stringify
diff --git a/packages/common/src/util/base64.js b/packages/common/src/util/base64.js
index 810f8cea0..86db0ff9d 100644
--- a/packages/common/src/util/base64.js
+++ b/packages/common/src/util/base64.js
@@ -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
Encode a string
- * const encoded = encode('Hello World');
+ * const encodedString = encode('Hello World');
* console.log(encoded); // Output: SGVsbG8gV29ybGQ=
+ * @example Encode an object
+ * const encodedObject = encode({name: 'Jane Doe'})
+ * console.log(encodedObject); //output eyJuYW1lIjoiSmFuZSBEb2UifQ==
+ * @example To skip the JSON stringification step
+ * 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 Decode a Base64 string
* const decoded = decode('SGVsbG8gV29ybGQ=');
- * console.log(decoded); // Output: Hello World
+ * @example Decode a Base64 JSON object to a standard JavaScript object
+ * const decoded = decode('eyJuYW1lIjoiSmFuZSBEb2UifQ==');
+ * console.log(decoded); // Output: {name: 'Jane Doe'}
+ * @example To skip the JSON stringification step
+ * 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;
+}
+
diff --git a/packages/common/test/util/index.test.js b/packages/common/test/util/index.test.js
index eb7f91ddc..cea484550 100644
--- a/packages/common/test/util/index.test.js
+++ b/packages/common/test/util/index.test.js
@@ -22,6 +22,9 @@ 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('');
@@ -29,13 +32,13 @@ describe('encode', () => {
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', () => {
+ const obj = {"name": "Jane Doe"}
+ expect(encode(obj)).to.eql("eyJuYW1lIjoiSmFuZSBEb2UifQ==");
+ });
});
describe('decode', () => {
@@ -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);
+ });
});