Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions __TESTS__/unit/actions/CustomFunction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import {createNewImage} from "../../TestUtils/createCloudinaryImage";
describe('Tests for Transformation Action -- NamedTransformation', () => {
it ('Works with wasm', () => {
const url = createNewImage('sample')
.customFunction(CustomFunction.wasm('my_example.wasm')).toURL();
.customFunction(CustomFunction.wasm('my/example.wasm')).toURL();

expect(url).toContain('fn_wasm:my_example.wasm');
expect(url).toContain('fn_wasm:my:example.wasm');
});

it ('Works with remote', () => {
Expand All @@ -28,6 +28,6 @@ describe('Tests for Transformation Action -- NamedTransformation', () => {
const url = createNewImage('sample')
.customFunction(CustomFunction.remote('https://opengraphimg.com/.netlify/functions/generate-opengraph?author=opengraphimg&title=Hey%20Chris%20this%20is%20working').preprocess()).toURL();

expect(url).toContain('fn_pre:remote:aHR0cHM6Ly9vcGVuZ3JhcGhpbWcuY29tLy5uZXRsaWZ5L2Z1bmN0aW9ucy9nZW5lcmF0ZS1vcGVuZ3JhcGg_YXV0aG9yPW9wZW5ncmFwaGltZyZ0aXRsZT1IZXklMjBDaHJpcyUyMHRoaXMlMjBpcyUyMHdvcmtpbmc');
expect(url).toContain('fn_pre:remote:aHR0cHM6Ly9vcGVuZ3JhcGhpbWcuY29tLy5uZXRsaWZ5L2Z1bmN0aW9ucy9nZW5lcmF0ZS1vcGVuZ3JhcGg_YXV0aG9yPW9wZW5ncmFwaGltZyZ0aXRsZT1IZXklMjBDaHJpcyUyMHRoaXMlMjBpcyUyMHdvcmtpbmc%3D');
});
});
68 changes: 66 additions & 2 deletions __TESTS__/unit/url/encoding.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {image, text} from "../../../src/qualifiers/source";
import {fetch, image, subtitles, text, video} from "../../../src/qualifiers/source";
import {Transformation} from "../../../src/transformation/Transformation";
import {Overlay} from "../../../src/actions/overlay";
import {sampleTextStyle} from "../../TestUtils/transformations/sampleTextStyle";
import {sampleEmptyTextStyle} from "../../TestUtils/transformations/sampleEmptyTextStyle";
import {createNewImage} from "../../TestUtils/createCloudinaryImage";
import {Variable} from "../../../src/actions/variable";
import {Flag} from "../../../src/qualifiers/flag";


describe('Tests for Encoding the URL', () => {
Expand Down Expand Up @@ -68,7 +70,7 @@ describe('Tests for Encoding the URL', () => {
.toBe('https://res.cloudinary.com/demo/image/fetch/https://res.cloudinary.com/demo/image/upload/sample%3Fa%3Db');
});

it('Should ', () => {
it('Should correctly encode youtube URLs', () => {
const img = createNewImage('https://www.youtube.com/watch?v=d9NF2edxy-M');
img.storageType = 'youtube';

Expand Down Expand Up @@ -101,4 +103,66 @@ describe('Tests for Encoding the URL', () => {
expect(cldImage.toURL())
.toBe(`https://res.cloudinary.com/demo/image/upload/l_sample/l_text:arial_50:he%252C%252Fllo/fl_layer_apply/fl_layer_apply/woman`);
});

it('Should correctly encode a path of a subtitle with /', () => {
const cldImage = createNewImage('woman')
.overlay(Overlay.source(
subtitles('my/path')
));

expect(cldImage.toString())
.toBe(`l_subtitles:my:path/fl_layer_apply`);
});

it('Should correctly encode a path of an image with /', () => {
const cldImage = createNewImage('woman')
.overlay(Overlay.source(
image('my/path')
));

expect(cldImage.toString())
.toBe(`l_my:path/fl_layer_apply`);
});

it('Should correctly encode a path of an video with /', () => {
const cldImage = createNewImage('woman')
.overlay(Overlay.source(
video('my/path')
));

expect(cldImage.toString())
.toBe(`l_video:my:path/fl_layer_apply`);
});

it('Fetch: base64 encode remote URL', () => {
const cldImage = createNewImage('woman')
.overlay(Overlay.source(
fetch('https://opengraphimg.com/.netlify/functions/generate-opengraph?author=opengraphimg&title=Hey%20Chris%20this%20is%20working')
));

expect(cldImage.toString())
.toBe(`l_fetch:aHR0cHM6Ly9vcGVuZ3JhcGhpbWcuY29tLy5uZXRsaWZ5L2Z1bmN0aW9ucy9nZW5lcmF0ZS1vcGVuZ3JhcGg_YXV0aG9yPW9wZW5ncmFwaGltZyZ0aXRsZT1IZXklMjBDaHJpcyUyMHRoaXMlMjBpcyUyMHdvcmtpbmc=/fl_layer_apply`);
});

it('Correctly encode variables', () => {
const cldImage = createNewImage('woman')
.addVariable(Variable.set('foo', 'some,,, amazing/text!!'));

expect(cldImage.toString()).toBe('$foo_!some%2C%2C%2C amazing%2Ftext%21%21!');
});

it('Correctly encode variable references', () => {
const cldImage = createNewImage('woman')
.addVariable(Variable.setAssetReference('foo', 'path/to/image'));

expect(cldImage.toString()).toBe('$foo_ref:!path:to:image!');
});

it('Encode flags with dots', () => {
// fl_streaming_attachment:my_streaming_video.mp4
const cldImage = createNewImage('woman')
.addFlag(Flag.streamingAttachment('my_streaming_video.mp4'));

expect(cldImage.toString()).toBe('fl_streaming_attachment:my_streaming_video%2Emp4');
});
});
9 changes: 6 additions & 3 deletions src/actions/customFunction/CustomFunctionAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ class CustomFunctionAction extends Action {
}

private encodeCustomFunctionString(fn:string):string {
const encodedSource = base64Encode(fn)
.replace(/\+/g, '-') // Convert '+' to '-'
.replace(/\//g, '_'); // Convert '/' to '_'
const encodedSource = base64Encode(fn);
return encodedSource;
}

Expand All @@ -40,6 +38,11 @@ class CustomFunctionAction extends Action {
}
return this.addQualifier(new Qualifier('fn', new QualifierValue([this.pre, this.mode, this.encodedFn])));
}

toString() {
return super.toString()
.replace(/\//g, ':');
}
}


Expand Down
20 changes: 13 additions & 7 deletions src/actions/variable/SetAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ import {ExpressionQualifier} from "../../qualifiers/expression/ExpressionQualifi
*/
class SetAction extends VariableAction {
constructor(name: string, value: number | string | string[] | number[] | ExpressionQualifier) {
let normalizedValue;
const parsedValue = Array.isArray(value) ? value.join(':') : value;
if(isString(parsedValue)){
normalizedValue = `!${parsedValue}!`;
//is number
}else{
normalizedValue = parsedValue;


let finalValue: string | number | ExpressionQualifier;
if (isString(parsedValue)) {
finalValue = `!${parsedValue
.replace(/,/g, '%2C')
.replace(/\//g, '%2F')
.replace(/!/g, '%21')}!`;
} else {
finalValue = parsedValue;
}


// Required due to https://github.com/microsoft/TypeScript/issues/13029
/* istanbul ignore next */
super(name, normalizedValue);
super(name, finalValue);
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/actions/variable/SetAssetReferenceAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ class SetAssetReferenceAction extends VariableAction {
constructor(name: string, value: string) {
// Required due to https://github.com/microsoft/TypeScript/issues/13029
/* istanbul ignore next */
super(name, `ref:!${value}!`);

const parsedValue = value
.replace(/\//g, ':');

super(name, `ref:!${parsedValue}!`);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/actions/variable/VariableAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type TypeVariableValue = number | string | ExpressionQualifier;
class VariableAction extends Action {
private isFloat = false;
private isNumber = false;
private readonly value: TypeVariableValue;
private readonly name: string;
protected readonly value: TypeVariableValue;
protected readonly name: string;
constructor(name: string, value: TypeVariableValue) {
super();
this.value = value;
Expand Down
4 changes: 3 additions & 1 deletion src/internal/utils/base64Encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ function base64Encode(input: string):string {
encodedResult = global.Buffer.from(input).toString('base64');
}

return encodedResult;
return encodedResult
.replace(/\+/g, '-') // Convert '+' to '-'
.replace(/\//g, '_'); // Convert '/' to '_';
}

export {base64Encode};
2 changes: 1 addition & 1 deletion src/internal/utils/dataStructureUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function mapToSortedArray<T>(map: Map<string, T | FlagQualifier>, flags: FlagQua
* @param {*} value The value to check.
* @return {boolean} `true` if `value` is a string, else `false`.
*/
function isString(value: any): boolean {
function isString(value: any): value is string {
return (typeof value === 'string' || value instanceof String);
}

Expand Down
4 changes: 4 additions & 0 deletions src/qualifiers/flag/FlagQualifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class FlagQualifier extends Qualifier {
}
super('fl', qualifierValue);
}

toString() {
return super.toString().replace(/\./, '%2E');
}
}

export {FlagQualifier};