Skip to content

Commit 2edb435

Browse files
Add new setters to variable: setFloat, setInteger and setString (#378)
1 parent 93fea04 commit 2edb435

File tree

3 files changed

+96
-7
lines changed

3 files changed

+96
-7
lines changed

__TESTS__/unit/actions/Variable.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {createNewImage} from "../../TestUtils/createCloudinaryImage";
2-
import {Variable} from "../../../src/actions/variable";
2+
import {setFloat, setInteger, setString, Variable} from "../../../src/actions/variable";
33
import {Expression} from "../../../src/qualifiers/expression";
44

55
const {set} = Variable;
@@ -12,6 +12,29 @@ describe('Tests for Transformation Action -- Variable', () => {
1212
expect(set('a', '30').toString()).toBe('$a_!30!');
1313
});
1414

15+
it('tests setFloat with common variable values', () => {
16+
expect(setFloat('a', -1).toString()).toBe(`$a_-1.0`);
17+
expect(setFloat('a', 0).toString()).toBe(`$a_0.0`);
18+
expect(setFloat('a', 1).toString()).toBe(`$a_1.0`);
19+
expect(setFloat('a', 0.01).toString()).toBe(`$a_0.01`);
20+
});
21+
22+
it('tests setInteger with common variable values', () => {
23+
expect(setInteger('a', -1).toString()).toBe(`$a_-1`);
24+
expect(setInteger('a', 0).toString()).toBe(`$a_0`);
25+
expect(setInteger('a', 0.9).toString()).toBe(`$a_1`);
26+
expect(setInteger('a', 1).toString()).toBe(`$a_1`);
27+
expect(setInteger('a', 0.01).toString()).toBe(`$a_0`); // Round down
28+
});
29+
30+
it('tests setString with common variable values', () => {
31+
// Strings are trivially supported, so this test tests for numbers
32+
expect(setString('a', -1).toString()).toBe(`$a_!-1!`);
33+
expect(setString('a', 0).toString()).toBe(`$a_!0!`);
34+
expect(setString('a', 1).toString()).toBe(`$a_!1!`);
35+
expect(setString('a', 0.01).toString()).toBe(`$a_!0.01!`);
36+
});
37+
1538
it('Creates a cloudinaryURL with number variable', () => {
1639
const url = createNewImage('sample')
1740
.addVariable(set('a', 30))

src/actions/variable.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import SetAssetReferenceAction from "./variable/SetAssetReferenceAction";
33
import SetFromContextAction from "./variable/SetFromContextAction";
44
import SetFromMetadataAction from "./variable/SetFromMetadataAction";
55
import {ExpressionQualifier} from "../qualifiers/expression/ExpressionQualifier";
6+
import {toFloatAsString} from "../internal/utils/toFloatAsString";
67

78
/**
89
* Defines a new user variable with the given value.
@@ -34,14 +35,67 @@ import {ExpressionQualifier} from "../qualifiers/expression/ExpressionQualifier"
3435
* @summary action
3536
* @description Sets a new user variable with the given value.
3637
* @memberOf Actions.Variable
37-
* @param name Variable name
38+
* @param {string} name Variable name
3839
* @param {number | string | number[] | string[]} value Variable value
3940
* @return {Actions.Variable.SetAction}
4041
*/
4142
function set(name: string, value: number | string | number[] | string[] | ExpressionQualifier): SetAction {
43+
if (Object.prototype.hasOwnProperty.call(value, 'push')) {
44+
return new SetAction(name, value);
45+
}
46+
4247
return new SetAction(name, value);
4348
}
4449

50+
/**
51+
* @summary action
52+
* @description Same as 'set', but forces the end value to be a float setFloat(1) will result in $foo_1.0
53+
* @memberOf Actions.Variable
54+
* @param {string} name Variable name
55+
* @param {number} value Variable value
56+
* @return {Actions.Variable.SetAction}
57+
*/
58+
function setFloat(name: string, value: number): SetAction {
59+
return new SetAction(name, toFloatAsString(value), '');
60+
}
61+
62+
/**
63+
* @summary action
64+
* @description Same as 'set', but forces the end value to be an integer setInteger(1.1) will result in $foo_1, input is rounded down
65+
* @memberOf Actions.Variable
66+
* @param {string} name Variable name
67+
* @param {number} value Variable value
68+
* @return {Actions.Variable.SetAction}
69+
*/
70+
function setInteger(name: string, value: number): SetAction {
71+
let val = value;
72+
if (typeof value === 'string') {
73+
val = parseInt(value);
74+
}
75+
76+
if (isNaN(val)) {
77+
val = 0;
78+
}
79+
80+
return new SetAction(name, Math.round(val));
81+
}
82+
83+
84+
/**
85+
* @summary action
86+
* @description Same as 'set', but forces the end value to be a string setString(1) will result in $foo_!1!
87+
* @memberOf Actions.Variable
88+
* @param {string, number} name Variable name
89+
* @param {number} value Variable value
90+
* @return {Actions.Variable.SetAction}
91+
*/
92+
function setString(name: string, value: string | number): SetAction {
93+
return new SetAction(name, value.toString());
94+
}
95+
96+
97+
98+
4599
/**
46100
* @summary action
47101
* @description Allows adding a variable by sending a key and value which is a reference to an asset.
@@ -82,12 +136,18 @@ function setFromMetadata(name: string, value: string): SetFromMetadataAction {
82136

83137
const Variable = {
84138
set,
139+
setFloat,
140+
setString,
141+
setInteger,
85142
setAssetReference,
86143
setFromContext,
87144
setFromMetadata
88145
};
89146
export {
90147
set,
148+
setFloat,
149+
setString,
150+
setInteger,
91151
setAssetReference,
92152
setFromContext,
93153
setFromMetadata,

src/actions/variable/SetAction.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@ import {ExpressionQualifier} from "../../qualifiers/expression/ExpressionQualifi
99
* @see Visit {@link Actions.Variable|Variable} for an example
1010
*/
1111
class SetAction extends VariableAction {
12-
constructor(name: string, value: number | string | string[] | number[] | ExpressionQualifier) {
13-
const parsedValue = Array.isArray(value) ? value.join(':') : value;
12+
constructor(name: string, value: number | string | string[] | number[] | ExpressionQualifier, wrapper = '!') {
13+
let finalValue: string | number | ExpressionQualifier;
1414

15+
const parsedValue = Array.isArray(value) ? value.join(':') : value;
1516

16-
let finalValue: string | number | ExpressionQualifier;
1717
if (isString(parsedValue)) {
18-
finalValue = `!${parsedValue
18+
/*
19+
* Encoding needed to make the Variable value Cloudinary Safe
20+
* If a string, we also determine what wrapper is used (wrapper variable)
21+
* The wrapper variable is needed because floats are passed as strings ('1.0') - in those case
22+
* we don't need to treat them as URL strings ($foo_!1.0!), but instead as foo_1.0
23+
*/
24+
finalValue = `${wrapper}${parsedValue
1925
.replace(/,/g, '%2C')
2026
.replace(/\//g, '%2F')
21-
.replace(/!/g, '%21')}!`;
27+
.replace(/!/g, '%21')}${wrapper}`;
2228
} else {
2329
finalValue = parsedValue;
2430
}

0 commit comments

Comments
 (0)