@wocart/storefront 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/USAGE.md +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/utils/image.d.ts +21 -1
- package/dist/utils/image.js +28 -21
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ follows [semantic versioning](https://semver.org/): breaking changes ship only
|
|
|
5
5
|
in a new major version, and an export is marked `@deprecated` for at least one
|
|
6
6
|
minor release before a major removes it.
|
|
7
7
|
|
|
8
|
+
## 1.14.0 — 2026-10-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `mediaImageUrl(url, params, mediaDomain)` (`MediaImageParams`): the
|
|
13
|
+
Cloudflare resizing URL of a media-domain image, served by the media domain
|
|
14
|
+
itself, so it works wherever the storefront is hosted; `null` for any other
|
|
15
|
+
image. Every image helper builds its URL with it, and so does
|
|
16
|
+
`@wocart/theme/image-service`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Every resizing URL starts with `onerror=redirect`: when a resize fails,
|
|
21
|
+
Cloudflare redirects to the original image instead of answering with an
|
|
22
|
+
error.
|
|
23
|
+
|
|
8
24
|
## 1.13.0 — 2026-10-17
|
|
9
25
|
|
|
10
26
|
### Added
|
package/USAGE.md
CHANGED
|
@@ -214,6 +214,7 @@ server directly.
|
|
|
214
214
|
| Export | Use it for |
|
|
215
215
|
| --- | --- |
|
|
216
216
|
| `formatMoney`, `optimizeImage`, `generateSrcSet` | Money text and image URLs |
|
|
217
|
+
| `mediaImageUrl` | The Cloudflare resizing URL of a media-domain image, served by the media domain itself (any storefront host); `null` for any other image — the builder behind every image helper and `@wocart/theme/image-service` |
|
|
217
218
|
| `createImageHelpers(mediaDomain)`, `getCardImage`, `getGalleryImage`, `getThumbnailImage`, `getHeroImage`, `getCategoryImage`, `getLogoImage` | The bound image toolkit (`IMAGE_SIZES` holds the presets) |
|
|
218
219
|
| `WILAYAS`, `ALGERIA_COMMUNES`, `communesForWilaya` | Reference data: 58 wilayas, 1,551 communes, one wilaya's rows |
|
|
219
220
|
| `normalizeAlgerianPhone`, `toLocalAlgerianMobile` | The one Algerian phone rule (accept/format) |
|
package/dist/index.d.ts
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export { formatMoney } from "./utils/money.js";
|
|
13
13
|
export type { MoneyFormatOptions } from "./utils/money.js";
|
|
14
|
-
export { optimizeImage, generateSrcSet, IMAGE_SIZES, getCardImage, getGalleryImage, getThumbnailImage, getHeroImage, getCategoryImage, getLogoImage, createImageHelpers, } from "./utils/image.js";
|
|
15
|
-
export type { ImageHelpers, ImageResizeOptions } from "./utils/image.js";
|
|
14
|
+
export { optimizeImage, generateSrcSet, IMAGE_SIZES, getCardImage, getGalleryImage, getThumbnailImage, getHeroImage, getCategoryImage, getLogoImage, createImageHelpers, mediaImageUrl, } from "./utils/image.js";
|
|
15
|
+
export type { ImageHelpers, ImageResizeOptions, MediaImageParams } from "./utils/image.js";
|
|
16
16
|
export { productImageSource } from "./utils/product-image.js";
|
|
17
17
|
export type { ProductImageSourceInput } from "./utils/product-image.js";
|
|
18
18
|
export { MAX_RESOLVED_PREFILL_LENGTH, PREFILL_TOKENS, stripTrackingParams, truncateAtWordBoundary, resolvePrefillText, buildWhatsAppHref, } from "./whatsapp.js";
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Internal modules stay reachable only through their intentional entry points.
|
|
11
11
|
*/
|
|
12
12
|
export { formatMoney } from "./utils/money.js";
|
|
13
|
-
export { optimizeImage, generateSrcSet, IMAGE_SIZES, getCardImage, getGalleryImage, getThumbnailImage, getHeroImage, getCategoryImage, getLogoImage, createImageHelpers, } from "./utils/image.js";
|
|
13
|
+
export { optimizeImage, generateSrcSet, IMAGE_SIZES, getCardImage, getGalleryImage, getThumbnailImage, getHeroImage, getCategoryImage, getLogoImage, createImageHelpers, mediaImageUrl, } from "./utils/image.js";
|
|
14
14
|
export { productImageSource } from "./utils/product-image.js";
|
|
15
15
|
export { MAX_RESOLVED_PREFILL_LENGTH, PREFILL_TOKENS, stripTrackingParams, truncateAtWordBoundary, resolvePrefillText, buildWhatsAppHref, } from "./whatsapp.js";
|
|
16
16
|
export { STOREFRONT_PAGE_PATHS, STOREFRONT_ROUTES, matchStorefrontPath, showsWidgetOn, storefrontPath } from "./routes.js";
|
package/dist/utils/image.d.ts
CHANGED
|
@@ -29,10 +29,30 @@ export interface ImageResizeOptions {
|
|
|
29
29
|
* { width: 400, height: 400 },
|
|
30
30
|
* 'media.example.com'
|
|
31
31
|
* );
|
|
32
|
-
* // Returns: https://media.example.com/cdn-cgi/image/width=400,height=400,format=webp,quality=85,fit=cover/products/image.jpg
|
|
32
|
+
* // Returns: https://media.example.com/cdn-cgi/image/onerror=redirect,width=400,height=400,format=webp,quality=85,fit=cover/products/image.jpg
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export declare function optimizeImage(originalUrl: string, options: ImageResizeOptions, mediaDomain?: string): string;
|
|
36
|
+
/** What `mediaImageUrl` can ask Cloudflare for; an omitted value is left to Cloudflare's default. */
|
|
37
|
+
export interface MediaImageParams {
|
|
38
|
+
width?: number;
|
|
39
|
+
height?: number;
|
|
40
|
+
quality?: number;
|
|
41
|
+
format?: string;
|
|
42
|
+
fit?: "scale-down" | "contain" | "cover" | "crop" | "pad" | "squeeze";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The Cloudflare Image Resizing URL of an image on the media domain, served
|
|
46
|
+
* by the media domain itself (`https://<media>/cdn-cgi/image/<options>/<path>`)
|
|
47
|
+
* — so it works wherever the storefront is hosted, as long as the media
|
|
48
|
+
* domain's zone has Image Transformations on.
|
|
49
|
+
*
|
|
50
|
+
* `onerror=redirect` comes first: when a resize fails, Cloudflare redirects to
|
|
51
|
+
* the original image instead of answering with an error.
|
|
52
|
+
*
|
|
53
|
+
* @returns `null` when there is no media domain, or the URL is not on it.
|
|
54
|
+
*/
|
|
55
|
+
export declare function mediaImageUrl(originalUrl: string, params: MediaImageParams, mediaDomain?: string): string | null;
|
|
36
56
|
/**
|
|
37
57
|
* Predefined image sizes for common use cases
|
|
38
58
|
*/
|
package/dist/utils/image.js
CHANGED
|
@@ -22,39 +22,46 @@
|
|
|
22
22
|
* { width: 400, height: 400 },
|
|
23
23
|
* 'media.example.com'
|
|
24
24
|
* );
|
|
25
|
-
* // Returns: https://media.example.com/cdn-cgi/image/width=400,height=400,format=webp,quality=85,fit=cover/products/image.jpg
|
|
25
|
+
* // Returns: https://media.example.com/cdn-cgi/image/onerror=redirect,width=400,height=400,format=webp,quality=85,fit=cover/products/image.jpg
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export function optimizeImage(originalUrl, options, mediaDomain) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
const { width, height, quality = 85, format = "webp", fit = "cover" } = options;
|
|
30
|
+
return mediaImageUrl(originalUrl, { width, height, format, quality, fit }, mediaDomain) ?? originalUrl;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The Cloudflare Image Resizing URL of an image on the media domain, served
|
|
34
|
+
* by the media domain itself (`https://<media>/cdn-cgi/image/<options>/<path>`)
|
|
35
|
+
* — so it works wherever the storefront is hosted, as long as the media
|
|
36
|
+
* domain's zone has Image Transformations on.
|
|
37
|
+
*
|
|
38
|
+
* `onerror=redirect` comes first: when a resize fails, Cloudflare redirects to
|
|
39
|
+
* the original image instead of answering with an error.
|
|
40
|
+
*
|
|
41
|
+
* @returns `null` when there is no media domain, or the URL is not on it.
|
|
42
|
+
*/
|
|
43
|
+
export function mediaImageUrl(originalUrl, params, mediaDomain) {
|
|
44
|
+
if (!mediaDomain || !originalUrl)
|
|
45
|
+
return null;
|
|
34
46
|
let mediaOrigin;
|
|
35
47
|
let original;
|
|
36
48
|
try {
|
|
37
|
-
mediaOrigin = new URL(
|
|
49
|
+
mediaOrigin = new URL(`https://${mediaDomain.replace(/^https?:\/\//, "")}`).origin;
|
|
38
50
|
original = new URL(originalUrl);
|
|
39
51
|
}
|
|
40
52
|
catch {
|
|
41
|
-
return
|
|
53
|
+
return null;
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
if (original.origin !== mediaOrigin)
|
|
56
|
+
return null;
|
|
57
|
+
const options = ["onerror=redirect"];
|
|
58
|
+
for (const key of ["width", "height", "format", "quality", "fit"]) {
|
|
59
|
+
const value = params[key];
|
|
60
|
+
if (value !== undefined && value !== "")
|
|
61
|
+
options.push(`${key}=${value}`);
|
|
46
62
|
}
|
|
47
|
-
const { width, height, quality = 85, format = "webp", fit = "cover" } = options;
|
|
48
63
|
const imagePath = `${original.pathname.replace(/^\/+/, "")}${original.search}${original.hash}`;
|
|
49
|
-
|
|
50
|
-
const resizeParams = [
|
|
51
|
-
`width=${width}`,
|
|
52
|
-
`height=${height}`,
|
|
53
|
-
`format=${format}`,
|
|
54
|
-
`quality=${quality}`,
|
|
55
|
-
`fit=${fit}`,
|
|
56
|
-
].join(",");
|
|
57
|
-
return `${mediaOrigin}/cdn-cgi/image/${resizeParams}/${imagePath}`;
|
|
64
|
+
return `${mediaOrigin}/cdn-cgi/image/${options.join(",")}/${imagePath}`;
|
|
58
65
|
}
|
|
59
66
|
/**
|
|
60
67
|
* Predefined image sizes for common use cases
|
package/package.json
CHANGED