Skip to content

Commit 82b5f63

Browse files
committed
test cases and logic for overlay handling
1 parent 2298a72 commit 82b5f63

File tree

5 files changed

+339
-17
lines changed

5 files changed

+339
-17
lines changed

src/constants/supportedTransforms.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ export const supportedTransforms: { [key: string]: string } = {
6666
zoom: "z",
6767
page: "pg",
6868

69+
// Text overlay transformations which are not defined yet
70+
fontSize: "fs",
71+
fontFamily: "ff",
72+
fontColor: "co",
73+
innerAlignment: "ia",
74+
padding: "pa",
75+
alpha: "al",
76+
typography: "tg",
77+
lineHeight: "lh",
78+
79+
// Subtitles transformations which are not defined
80+
fontOutline: "fol",
81+
fontShadow: "fsh",
82+
6983
// Raw pass-through
7084
raw: "raw",
7185
};

src/interfaces/Transformation.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ export interface TextOverlay extends BaseOverlay {
526526
/**
527527
* Control styling of the text overlay.
528528
*/
529-
transformations?: TextOverlayTransformation[];
529+
transformation?: TextOverlayTransformation[];
530530
}
531531

532532
export interface ImageOverlay extends BaseOverlay {
@@ -538,11 +538,11 @@ export interface ImageOverlay extends BaseOverlay {
538538
input: string;
539539

540540
/**
541-
* List of transformations to be applied to the overlay image. Supported transformations depends on the base/parent asset.
541+
* Array of transformations to be applied to the overlay image. Supported transformations depends on the base/parent asset.
542542
*
543543
* {@link https://imagekit.io/docs/add-overlays-on-images#list-of-supported-image-transformations-in-image-layers|Image} | {@link https://imagekit.io/docs/add-overlays-on-videos#list-of-transformations-supported-on-image-overlay|Video}
544544
*/
545-
transformations?: Transformation[];
545+
transformation?: Transformation[];
546546
}
547547

548548
export interface VideoOverlay extends BaseOverlay {
@@ -553,11 +553,11 @@ export interface VideoOverlay extends BaseOverlay {
553553
input: string;
554554

555555
/**
556-
* List of transformations to be applied to the overlay video. Except `streamingResolutions`, all other video transformations are supported.
556+
* Array of transformation to be applied to the overlay video. Except `streamingResolutions`, all other video transformations are supported.
557557
*
558558
* {@link https://imagekit.io/docs/video-transformation|Video Transformations}
559559
*/
560-
transformations?: Transformation[];
560+
transformation?: Transformation[];
561561
}
562562

563563
export interface SubtitleOverlay extends BaseOverlay {
@@ -572,7 +572,7 @@ export interface SubtitleOverlay extends BaseOverlay {
572572
*
573573
* {@link https://imagekit.io/docs/add-overlays-on-videos#styling-controls-for-subtitles-layer|Styling subtitles}
574574
*/
575-
transformations?: SubtitleOverlayTransformation[];
575+
transformation?: SubtitleOverlayTransformation[];
576576
}
577577

578578
export interface SolidColorOverlay extends BaseOverlay {
@@ -588,7 +588,7 @@ export interface SolidColorOverlay extends BaseOverlay {
588588
*
589589
* {@link https://imagekit.io/docs/add-overlays-on-images#apply-transformation-on-solid-color-overlay|Image} | {@link https://imagekit.io/docs/add-overlays-on-videos#apply-transformations-on-solid-color-block-overlay|Video}
590590
*/
591-
transformations?: SolidColorOverlayTransformation[];
591+
transformation?: SolidColorOverlayTransformation[];
592592
}
593593

594594
export type TextOverlayTransformation = {

src/url/builder.ts

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ImageKitOptions, UrlOptions } from "../interfaces";
22
import { Transformation } from "../interfaces/Transformation";
33
import transformationUtils from "../utils/transformation";
4+
import { safeBtoa } from "../utils/transformation";
45
const TRANSFORMATION_PARAMETER = "tr";
56

67
function removeTrailingSlash(str: string) {
@@ -73,20 +74,106 @@ export const buildURL = (opts: UrlOptions & ImageKitOptions) => {
7374
return urlObj.href;
7475
};
7576

77+
78+
function processOverlay(overlay: Transformation["overlay"]): string | undefined {
79+
const entries = [];
80+
if (!overlay) {
81+
return;
82+
}
83+
const { type, position = {}, timing = {}, transformation = [] } = overlay;
84+
85+
if (!type) {
86+
throw new Error("Overlay type is required");
87+
}
88+
89+
switch (type) {
90+
case "text":
91+
entries.push("l-text");
92+
if (overlay.text) {
93+
entries.push(`ie-${encodeURIComponent(safeBtoa(overlay.text))}`);
94+
}
95+
break;
96+
case "image":
97+
entries.push("l-image");
98+
if (overlay.input) {
99+
entries.push(`i-${overlay.input}`);
100+
}
101+
break;
102+
case "video":
103+
entries.push("l-video");
104+
if (overlay.input) {
105+
entries.push(`i-${overlay.input}`);
106+
}
107+
break;
108+
case "subtitle":
109+
entries.push("l-subtitle");
110+
if (overlay.input) {
111+
entries.push(`i-${overlay.input}`);
112+
}
113+
break;
114+
case "solidColor":
115+
entries.push("l-image");
116+
entries.push(`i-ik_canvas`);
117+
if (overlay.color) {
118+
entries.push(`bg-${overlay.color}`);
119+
}
120+
break;
121+
}
122+
123+
const { x, y, focus } = position;
124+
if (x) {
125+
entries.push(`lxo-${x}`);
126+
}
127+
if (y) {
128+
entries.push(`lyo-${y}`);
129+
}
130+
if (focus) {
131+
entries.push(`lfo-${focus}`);
132+
}
133+
134+
const { start, end, duration } = timing;
135+
136+
if (start) {
137+
entries.push(`lso-${start}`);
138+
}
139+
if (end) {
140+
entries.push(`leo-${end}`);
141+
}
142+
if (duration) {
143+
entries.push(`ldu-${duration}`);
144+
}
145+
146+
const transformationString = constructTransformationString(transformation);
147+
148+
if (transformationString && transformationString.trim() !== "") entries.push(transformationString);
149+
150+
entries.push("l-end");
151+
152+
return entries.join(transformationUtils.getTransformDelimiter());
153+
}
154+
76155
function constructTransformationString(transformation: Transformation[] | undefined) {
77156
if (!Array.isArray(transformation)) {
78157
return "";
79158
}
80159

81-
var parsedTransforms = [];
160+
var parsedTransforms: string[] = [];
82161
for (var i = 0, l = transformation.length; i < l; i++) {
83-
var parsedTransformStep = [];
162+
var parsedTransformStep: string[] = [];
84163
for (var key in transformation[i]) {
85164
let value = transformation[i][key as keyof Transformation];
86165
if (value === undefined || value === null) {
87166
continue;
88167
}
89168

169+
if (key === "overlay" && typeof value === "object") {
170+
var rawString = processOverlay(value as Transformation["overlay"]);
171+
if (rawString) {
172+
parsedTransformStep.push(rawString);
173+
continue;
174+
}
175+
}
176+
90177
var transformKey = transformationUtils.getTransformKey(key);
91178
if (!transformKey) {
92179
transformKey = key;
@@ -111,7 +198,7 @@ function constructTransformationString(transformation: Transformation[] | undefi
111198
) {
112199
parsedTransformStep.push(transformKey);
113200
} else if (key === "raw") {
114-
parsedTransformStep.push(transformation[i][key]);
201+
parsedTransformStep.push(transformation[i][key] as string);
115202
} else {
116203
if (transformKey === "di") {
117204
value = removeTrailingSlash(removeLeadingSlash(value as string || ""));

src/utils/transformation.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import supportedTransforms from "../constants/supportedTransforms";
22
import { ImageKitOptions, TransformationPosition } from "../interfaces";
33

4-
const DEFAULT_TRANSFORMATION_POSITION : TransformationPosition = "path";
5-
const QUERY_TRANSFORMATION_POSITION : TransformationPosition = "query";
4+
const DEFAULT_TRANSFORMATION_POSITION: TransformationPosition = "path";
5+
const QUERY_TRANSFORMATION_POSITION: TransformationPosition = "query";
66
const VALID_TRANSFORMATION_POSITIONS = [DEFAULT_TRANSFORMATION_POSITION, QUERY_TRANSFORMATION_POSITION];
7-
const CHAIN_TRANSFORM_DELIMITER : string = ":";
8-
const TRANSFORM_DELIMITER : string = ",";
9-
const TRANSFORM_KEY_VALUE_DELIMITER : string = "-";
7+
const CHAIN_TRANSFORM_DELIMITER: string = ":";
8+
const TRANSFORM_DELIMITER: string = ",";
9+
const TRANSFORM_KEY_VALUE_DELIMITER: string = "-";
1010

1111
export default {
1212
getDefault: (): TransformationPosition => {
@@ -15,8 +15,8 @@ export default {
1515
addAsQueryParameter: (options: ImageKitOptions) => {
1616
return options.transformationPosition === QUERY_TRANSFORMATION_POSITION;
1717
},
18-
validParameters: (options: ImageKitOptions) => {
19-
if(typeof options.transformationPosition == "undefined") return false;
18+
validParameters: (options: ImageKitOptions) => {
19+
if (typeof options.transformationPosition == "undefined") return false;
2020
return VALID_TRANSFORMATION_POSITIONS.indexOf(options.transformationPosition) != -1;
2121
},
2222
getTransformKey: function (transform: string) {
@@ -33,4 +33,13 @@ export default {
3333
getTransformKeyValueDelimiter: function () {
3434
return TRANSFORM_KEY_VALUE_DELIMITER;
3535
}
36+
}
37+
38+
export const safeBtoa = function (str: string): string {
39+
if (typeof btoa !== "undefined") {
40+
return btoa(str);
41+
} else {
42+
// Node fallback
43+
return Buffer.from(str, "utf8").toString("base64");
44+
}
3645
}

0 commit comments

Comments
 (0)