diff --git a/src/core/operations/Jsonata.mjs b/src/core/operations/Jsonata.mjs index 82cc4d39..04259343 100644 --- a/src/core/operations/Jsonata.mjs +++ b/src/core/operations/Jsonata.mjs @@ -51,6 +51,18 @@ class JsonataQuery extends Operation { try { const expression = jsonata(query); + // Override built-in base64 functions which fail in Web Worker + // context where `window` is undefined. The jsonata library falls + // back to `global.Buffer` which also does not exist in workers. + // `atob`/`btoa` are available in both browser and worker scopes. + expression.registerFunction("base64decode", (str) => { + if (typeof str === "undefined") return undefined; + return atob(str); + }, ""); + expression.registerFunction("base64encode", (str) => { + if (typeof str === "undefined") return undefined; + return btoa(str); + }, ""); result = await expression.evaluate(jsonObj); } catch (err) { throw new OperationError( diff --git a/tests/operations/tests/Jsonata.mjs b/tests/operations/tests/Jsonata.mjs index fb46a961..54ecf34c 100644 --- a/tests/operations/tests/Jsonata.mjs +++ b/tests/operations/tests/Jsonata.mjs @@ -548,4 +548,27 @@ TestRegister.addTests([ }, ], }, + // Base64 functions (issue #2063) + { + name: "Jsonata: $base64decode", + input: "{}", + expectedOutput: '"Hello World!"', + recipeConfig: [ + { + op: "Jsonata Query", + args: ['$base64decode("SGVsbG8gV29ybGQh")'], + }, + ], + }, + { + name: "Jsonata: $base64encode", + input: "{}", + expectedOutput: '"SGVsbG8gV29ybGQh"', + recipeConfig: [ + { + op: "Jsonata Query", + args: ['$base64encode("Hello World!")'], + }, + ], + }, ]);