Skip to content

Commit b46f693

Browse files
xsynapticascorbic
andauthored
feat(ipx): improve ipx provider typing and test coverage (#185)
* feat: improve ipx provider typing and test coverage * chore: add changeset * Change unpic version from patch to minor --------- Co-authored-by: Matt Kane <m@mk.gg>
1 parent eefd617 commit b46f693

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

.changeset/full-plums-attend.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"unpic": minor
3+
---
4+
5+
feat(ipx): improve ipx provider typing and test coverage

src/providers/ipx.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ Deno.test("ipx extract", async (t) => {
3232
format: "webp",
3333
});
3434
});
35+
36+
await t.step("should extract crop with URL-encoded underscores", () => {
37+
const url = `${baseURL}/crop_100%5F50%5F300%5F200,f_auto/images/test.jpg`;
38+
const result = extract(url);
39+
assertEquals(result?.src, "/images/test.jpg");
40+
assertEquals(result?.operations.crop, "100_50_300_200");
41+
});
42+
43+
await t.step("should extract fit and position", () => {
44+
const url =
45+
`${baseURL}/s_800x600,fit_cover,position_top,f_auto/images/test.jpg`;
46+
const result = extract(url);
47+
assertEquals(result?.operations.fit, "cover");
48+
assertEquals(result?.operations.position, "top");
49+
});
3550
});
3651

3752
Deno.test("ipx generate", async (t) => {
@@ -139,3 +154,36 @@ Deno.test("ipx transform", async (t) => {
139154
);
140155
});
141156
});
157+
158+
Deno.test("ipx generate with extended operations", async (t) => {
159+
await t.step("should generate URL with crop", () => {
160+
const result = generate(
161+
img,
162+
{ width: 800, height: 600, crop: "100_50_300_200" },
163+
{ baseURL },
164+
);
165+
assertEquals(result.includes("crop_100%5F50%5F300%5F200"), true);
166+
assertEquals(result.includes("s_800x600"), true);
167+
});
168+
169+
await t.step("should generate URL with fit and position", () => {
170+
const result = generate(
171+
img,
172+
{ width: 800, height: 600, fit: "cover", position: "top" },
173+
{ baseURL },
174+
);
175+
assertEquals(result.includes("fit_cover"), true);
176+
assertEquals(result.includes("position_top"), true);
177+
});
178+
179+
await t.step("should generate URL with effects", () => {
180+
const result = generate(
181+
img,
182+
{ width: 300, rotate: 90, blur: 5, grayscale: true },
183+
{ baseURL },
184+
);
185+
assertEquals(result.includes("rotate_90"), true);
186+
assertEquals(result.includes("blur_5"), true);
187+
assertEquals(result.includes("grayscale_true"), true);
188+
});
189+
});

src/providers/ipx.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,78 @@ export interface IPXOperations extends Operations {
3838
* Output format of the image.
3939
*/
4040
f?: ImageFormat | "auto";
41+
42+
/**
43+
* Resize fit mode. Only applies when both width and height are specified.
44+
*/
45+
fit?: "contain" | "cover" | "fill" | "inside" | "outside";
46+
47+
/**
48+
* Position/gravity for resize. Only applies when both width and height are specified.
49+
* @example "top"
50+
*/
51+
position?: string;
52+
53+
/**
54+
* Alias for position.
55+
*/
56+
pos?: string;
57+
58+
/**
59+
* Extract/crop a region of the image.
60+
* Format: "left_top_width_height"
61+
* @example "100_50_300_200"
62+
*/
63+
extract?: string;
64+
65+
/**
66+
* Alias for extract.
67+
*/
68+
crop?: string;
69+
70+
/**
71+
* Rotation angle in degrees.
72+
* @example 90
73+
*/
74+
rotate?: number;
75+
76+
/**
77+
* Flip image vertically.
78+
*/
79+
flip?: boolean;
80+
81+
/**
82+
* Flip image horizontally.
83+
*/
84+
flop?: boolean;
85+
86+
/**
87+
* Blur sigma value.
88+
* @example 5
89+
*/
90+
blur?: number;
91+
92+
/**
93+
* Sharpen sigma value.
94+
* @example 30
95+
*/
96+
sharpen?: number;
97+
98+
/**
99+
* Convert to grayscale.
100+
*/
101+
grayscale?: boolean;
102+
103+
/**
104+
* Background color (hex without #).
105+
* @example "ff0000"
106+
*/
107+
background?: string;
108+
109+
/**
110+
* Alias for background.
111+
*/
112+
b?: string;
41113
}
42114

43115
export interface IPXOptions {

0 commit comments

Comments
 (0)