From 28b96752b90d4a9e58875cdf44bdb7bfcf624ce6 Mon Sep 17 00:00:00 2001 From: RTLcoil <oleg@rtl.co.il> Date: Thu, 25 Apr 2019 19:46:08 +0300 Subject: [PATCH] Add support for remote/local function invocation (fn:remote and fn:wasm) --- lib-es5/utils/index.js | 19 +++++++++++ lib/utils/index.js | 19 +++++++++++ test/cloudinary_spec.js | 72 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/lib-es5/utils/index.js b/lib-es5/utils/index.js index e9498c1d..7ffa24e4 100644 --- a/lib-es5/utils/index.js +++ b/lib-es5/utils/index.js @@ -210,6 +210,23 @@ function normalize_expression(expression) { return expression.replace(/[ _]+/g, '_'); } +/** + * Parse custom_function options + * @private + * @param {object|*} customFunction a custom function object containing function_type and source values + * @return {string|*} custom_function transformation string + */ +function process_custom_function(customFunction) { + if (!isObject(customFunction)) { + return customFunction; + } + if (customFunction.function_type === "remote") { + return [customFunction.function_type, base64EncodeURL(customFunction.source)].join(":"); + } else { + return [customFunction.function_type, customFunction.source].join(":"); + } +} + /** * Parse "if" parameter * Translates the condition if provided. @@ -546,6 +563,7 @@ exports.generate_transformation_string = function generate_transformation_string var underlay = process_layer(utils.option_consume(options, "underlay")); var ifValue = process_if(utils.option_consume(options, "if")); var fps = utils.option_consume(options, 'fps'); + var custom_function = process_custom_function(utils.option_consume(options, "custom_function")); if (isArray(fps)) { fps = fps.join('-'); } @@ -559,6 +577,7 @@ exports.generate_transformation_string = function generate_transformation_string dpr: normalize_expression(dpr), e: normalize_expression(effect), fl: flags, + fn: custom_function, fps: fps, h: normalize_expression(height), ki: normalize_expression(utils.option_consume(options, "keyframe_interval")), diff --git a/lib/utils/index.js b/lib/utils/index.js index 4c09f498..19ce7e8b 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -206,6 +206,23 @@ function normalize_expression(expression) { return expression.replace(/[ _]+/g, '_'); } +/** + * Parse custom_function options + * @private + * @param {object|*} customFunction a custom function object containing function_type and source values + * @return {string|*} custom_function transformation string + */ +function process_custom_function(customFunction) { + if (!isObject(customFunction)) { + return customFunction; + } + if (customFunction.function_type === "remote") { + return [customFunction.function_type, base64EncodeURL(customFunction.source)].join(":"); + } else { + return [customFunction.function_type, customFunction.source].join(":"); + } +} + /** * Parse "if" parameter * Translates the condition if provided. @@ -553,6 +570,7 @@ exports.generate_transformation_string = function generate_transformation_string let underlay = process_layer(utils.option_consume(options, "underlay")); let ifValue = process_if(utils.option_consume(options, "if")); let fps = utils.option_consume(options, 'fps'); + let custom_function = process_custom_function(utils.option_consume(options, "custom_function")); if(isArray(fps)){ fps = fps.join('-'); } @@ -566,6 +584,7 @@ exports.generate_transformation_string = function generate_transformation_string dpr: normalize_expression(dpr), e: normalize_expression(effect), fl: flags, + fn: custom_function, fps: fps, h: normalize_expression(height), ki: normalize_expression(utils.option_consume(options, "keyframe_interval")), diff --git a/test/cloudinary_spec.js b/test/cloudinary_spec.js index 8120be8d..22f75599 100644 --- a/test/cloudinary_spec.js +++ b/test/cloudinary_spec.js @@ -423,6 +423,78 @@ describe("cloudinary", function() { signature: "123515adfa151" })).to.eql("image/upload/v1251251251/abcd.jpg#123515adfa151"); }); + it('should support custom function of type wasm with a source', function () { + var options, result; + options = { + custom_function: {function_type: 'wasm', source: 'blur.wasm'} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_wasm:blur.wasm/test"); + }); + it('should support arbitrary custom function types', function () { + var options, result; + options = { + custom_function: {function_type: 'amazing', source: 'awesome'} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_amazing:awesome/test"); + }); + it('should support custom function with no source', function () { + var options, result; + options = { + custom_function: {function_type: 'wasm'} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_wasm:/test"); + }); + it('should support custom function with no function_type', function () { + var options, result; + options = { + custom_function: {source: 'blur.wasm'} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:blur.wasm/test"); + }); + it('should support custom function that is not an object', function () { + var options, result; + options = { + custom_function: [] + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:/test"); + }); + it('should support custom function with no function_type or source', function () { + var options, result; + options = { + custom_function: {} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:/test"); + }); + it('should support custom function of type remote', function() { + var options, result; + options = { + custom_function: {function_type: 'remote', source: 'https://df34ra4a.execute-api.us-west-2.amazonaws.com/default/cloudinaryFunction'} + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_remote:aHR0cHM6Ly9kZjM0cmE0YS5leGVjdXRlLWFwaS51cy13ZXN0LTIuYW1hem9uYXdzLmNvbS9kZWZhdWx0L2Nsb3VkaW5hcnlGdW5jdGlvbg==/test"); + }); + it('should should not include custom function with undefined value', function() { + var options, result; + options = { + custom_function: undefined + }; + result = cloudinary.utils.url("test", options); + expect(options).to.eql({}); + expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/test"); + }); it("should support density", function() { var options, result; options = {