Skip to content

Commit d45437e

Browse files
RTLcoilstrausr
authored andcommitted
Add support for remote/local function invocation (fn:remote and fn:wasm) (#261)
1 parent 50dddd0 commit d45437e

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

lib-es5/utils/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,23 @@ function normalize_expression(expression) {
209209
return expression.replace(/[ _]+/g, '_');
210210
}
211211

212+
/**
213+
* Parse custom_function options
214+
* @private
215+
* @param {object|*} customFunction a custom function object containing function_type and source values
216+
* @return {string|*} custom_function transformation string
217+
*/
218+
function process_custom_function(customFunction) {
219+
if (!isObject(customFunction)) {
220+
return customFunction;
221+
}
222+
if (customFunction.function_type === "remote") {
223+
return [customFunction.function_type, base64EncodeURL(customFunction.source)].join(":");
224+
} else {
225+
return [customFunction.function_type, customFunction.source].join(":");
226+
}
227+
}
228+
212229
/**
213230
* Parse "if" parameter
214231
* Translates the condition if provided.
@@ -530,6 +547,7 @@ function generate_transformation_string(options) {
530547
var underlay = process_layer(utils.option_consume(options, "underlay"));
531548
var ifValue = process_if(utils.option_consume(options, "if"));
532549
var fps = utils.option_consume(options, 'fps');
550+
var custom_function = process_custom_function(utils.option_consume(options, "custom_function"));
533551
if (isArray(fps)) {
534552
fps = fps.join('-');
535553
}
@@ -543,6 +561,7 @@ function generate_transformation_string(options) {
543561
dpr: normalize_expression(dpr),
544562
e: normalize_expression(effect),
545563
fl: flags,
564+
fn: custom_function,
546565
fps: fps,
547566
h: normalize_expression(height),
548567
ki: normalize_expression(utils.option_consume(options, "keyframe_interval")),

lib/utils/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,23 @@ function normalize_expression(expression) {
201201
return expression.replace(/[ _]+/g, '_');
202202
}
203203

204+
/**
205+
* Parse custom_function options
206+
* @private
207+
* @param {object|*} customFunction a custom function object containing function_type and source values
208+
* @return {string|*} custom_function transformation string
209+
*/
210+
function process_custom_function(customFunction) {
211+
if (!isObject(customFunction)) {
212+
return customFunction;
213+
}
214+
if (customFunction.function_type === "remote") {
215+
return [customFunction.function_type, base64EncodeURL(customFunction.source)].join(":");
216+
} else {
217+
return [customFunction.function_type, customFunction.source].join(":");
218+
}
219+
}
220+
204221
/**
205222
* Parse "if" parameter
206223
* Translates the condition if provided.
@@ -525,6 +542,7 @@ function generate_transformation_string(options) {
525542
let overlay = process_layer(utils.option_consume(options, "overlay"));
526543
let underlay = process_layer(utils.option_consume(options, "underlay"));
527544
let ifValue = process_if(utils.option_consume(options, "if"));
545+
let custom_function = process_custom_function(utils.option_consume(options, "custom_function"));
528546
let fps = utils.option_consume(options, 'fps');
529547
if (isArray(fps)) {
530548
fps = fps.join('-');
@@ -539,6 +557,7 @@ function generate_transformation_string(options) {
539557
dpr: normalize_expression(dpr),
540558
e: normalize_expression(effect),
541559
fl: flags,
560+
fn: custom_function,
542561
fps: fps,
543562
h: normalize_expression(height),
544563
ki: normalize_expression(utils.option_consume(options, "keyframe_interval")),

test/cloudinary_spec.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,78 @@ describe("cloudinary", function () {
421421
signature: "123515adfa151",
422422
})).to.eql("image/upload/v1251251251/abcd.jpg#123515adfa151");
423423
});
424+
it('should support custom function of type wasm with a source', function () {
425+
var options, result;
426+
options = {
427+
custom_function: {function_type: 'wasm', source: 'blur.wasm'}
428+
};
429+
result = cloudinary.utils.url("test", options);
430+
expect(options).to.eql({});
431+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_wasm:blur.wasm/test");
432+
});
433+
it('should support arbitrary custom function types', function () {
434+
var options, result;
435+
options = {
436+
custom_function: {function_type: 'amazing', source: 'awesome'}
437+
};
438+
result = cloudinary.utils.url("test", options);
439+
expect(options).to.eql({});
440+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_amazing:awesome/test");
441+
});
442+
it('should support custom function with no source', function () {
443+
var options, result;
444+
options = {
445+
custom_function: {function_type: 'wasm'}
446+
};
447+
result = cloudinary.utils.url("test", options);
448+
expect(options).to.eql({});
449+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_wasm:/test");
450+
});
451+
it('should support custom function with no function_type', function () {
452+
var options, result;
453+
options = {
454+
custom_function: {source: 'blur.wasm'}
455+
};
456+
result = cloudinary.utils.url("test", options);
457+
expect(options).to.eql({});
458+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:blur.wasm/test");
459+
});
460+
it('should support custom function that is not an object', function () {
461+
var options, result;
462+
options = {
463+
custom_function: []
464+
};
465+
result = cloudinary.utils.url("test", options);
466+
expect(options).to.eql({});
467+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:/test");
468+
});
469+
it('should support custom function with no function_type or source', function () {
470+
var options, result;
471+
options = {
472+
custom_function: {}
473+
};
474+
result = cloudinary.utils.url("test", options);
475+
expect(options).to.eql({});
476+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_:/test");
477+
});
478+
it('should support custom function of type remote', function() {
479+
var options, result;
480+
options = {
481+
custom_function: {function_type: 'remote', source: 'https://df34ra4a.execute-api.us-west-2.amazonaws.com/default/cloudinaryFunction'}
482+
};
483+
result = cloudinary.utils.url("test", options);
484+
expect(options).to.eql({});
485+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/fn_remote:aHR0cHM6Ly9kZjM0cmE0YS5leGVjdXRlLWFwaS51cy13ZXN0LTIuYW1hem9uYXdzLmNvbS9kZWZhdWx0L2Nsb3VkaW5hcnlGdW5jdGlvbg==/test");
486+
});
487+
it('should should not include custom function with undefined value', function() {
488+
var options, result;
489+
options = {
490+
custom_function: undefined
491+
};
492+
result = cloudinary.utils.url("test", options);
493+
expect(options).to.eql({});
494+
expect(result).to.eql("http://res.cloudinary.com/test123/image/upload/test");
495+
});
424496
it("should support density", function () {
425497
var options, result;
426498
options = {

0 commit comments

Comments
 (0)