@shopware/helpers 1.6.0 → 1.7.1
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/README.md +95 -18
- package/dist/index.d.mts +58 -3
- package/dist/index.d.ts +58 -3
- package/dist/index.mjs +85 -3
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -30,31 +30,108 @@ export default defineConfig({
|
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## `getBackgroundImageUrl` helper
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
The `getBackgroundImageUrl` function generates optimized CSS `url()` values for CMS background images. It extracts the raw URL, calculates the appropriate dimensions based on the media metadata, and applies image transformation parameters.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
### Usage
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { getBackgroundImageUrl } from "@shopware/helpers";
|
|
41
|
+
|
|
42
|
+
const optimizedUrl = getBackgroundImageUrl(
|
|
43
|
+
"url(https://cdn.shopware.store/.../image.jpg)",
|
|
44
|
+
cmsBlockOrSection, // object with backgroundMedia.metaData.width/height
|
|
45
|
+
{ format: "webp", quality: 85 }, // optional
|
|
46
|
+
);
|
|
47
|
+
// => 'url("https://cdn.shopware.store/.../image.jpg?width=1000&fit=crop,smart&format=webp&quality=85")'
|
|
48
|
+
```
|
|
38
49
|
|
|
39
|
-
###
|
|
50
|
+
### Parameters
|
|
40
51
|
|
|
41
|
-
|
|
52
|
+
| Parameter | Type | Description |
|
|
53
|
+
|-----------|------|-------------|
|
|
54
|
+
| `url` | `string` | CSS `url()` string containing the background image URL |
|
|
55
|
+
| `element` | `{ backgroundMedia?: { metaData?: { width?: number; height?: number } } }` | CMS section or block object with media metadata |
|
|
56
|
+
| `options` | `BackgroundImageOptions` (optional) | Format and quality settings |
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
- `isProductOnSale`
|
|
45
|
-
- `isProductTopSeller`
|
|
46
|
-
- `getProductManufacturerName`
|
|
58
|
+
### `BackgroundImageOptions`
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
```ts
|
|
61
|
+
type BackgroundImageOptions = {
|
|
62
|
+
format?: string; // "webp" | "avif" | "jpg" | "png"
|
|
63
|
+
quality?: number; // 0-100
|
|
64
|
+
};
|
|
65
|
+
```
|
|
50
66
|
|
|
51
|
-
|
|
67
|
+
When `format` or `quality` are provided, they are appended as query parameters to the image URL. If omitted, only the dimension and fit parameters are applied.
|
|
68
|
+
|
|
69
|
+
## `generateCdnSrcSet` helper
|
|
70
|
+
|
|
71
|
+
Generates an HTML `srcset` string using CDN width-based resizing. Useful as a fallback when media has no pre-generated thumbnails — the CDN handles on-the-fly resizing via query parameters.
|
|
72
|
+
|
|
73
|
+
### Usage
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { generateCdnSrcSet } from "@shopware/helpers";
|
|
77
|
+
|
|
78
|
+
const srcset = generateCdnSrcSet(
|
|
79
|
+
"https://cdn.shopware.store/.../image.jpg",
|
|
80
|
+
[400, 800, 1200, 1600], // optional, these are the defaults
|
|
81
|
+
{ format: "webp", quality: 85 }, // optional
|
|
82
|
+
);
|
|
83
|
+
// => "https://cdn.shopware.store/.../image.jpg?width=400&fit=crop,smart&format=webp&quality=85 400w, ...800w, ...1200w, ...1600w"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Parameters
|
|
87
|
+
|
|
88
|
+
| Parameter | Type | Description |
|
|
89
|
+
|-----------|------|-------------|
|
|
90
|
+
| `src` | `string \| undefined` | Base image URL |
|
|
91
|
+
| `widths` | `number[]` (optional) | Array of widths to generate (default: `[400, 800, 1200, 1600]`) |
|
|
92
|
+
| `options` | `{ format?: string; quality?: number }` (optional) | Format and quality settings |
|
|
93
|
+
|
|
94
|
+
Returns `undefined` if `src` is falsy or URL parsing fails.
|
|
52
95
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
96
|
+
## `buildCdnImageUrl` helper
|
|
97
|
+
|
|
98
|
+
Builds an optimized CDN image URL with size parameters based on rendered element dimensions. Adds `width` or `height` (whichever is larger) rounded up to the nearest 100px, plus `fit=crop,smart`.
|
|
99
|
+
|
|
100
|
+
### Usage
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { buildCdnImageUrl } from "@shopware/helpers";
|
|
104
|
+
|
|
105
|
+
const url = buildCdnImageUrl(
|
|
106
|
+
"https://cdn.shopware.store/.../image.jpg",
|
|
107
|
+
{ width: 724, height: 760 },
|
|
108
|
+
);
|
|
109
|
+
// => "https://cdn.shopware.store/.../image.jpg?height=800&fit=crop,smart"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Parameters
|
|
113
|
+
|
|
114
|
+
| Parameter | Type | Description |
|
|
115
|
+
|-----------|------|-------------|
|
|
116
|
+
| `src` | `string \| undefined` | Base image URL |
|
|
117
|
+
| `dimensions` | `{ width: number; height: number }` | Rendered element dimensions in pixels |
|
|
118
|
+
| `options` | `{ format?: string; quality?: number }` (optional) | Format and quality settings |
|
|
119
|
+
|
|
120
|
+
Returns an empty string if `src` is falsy. Returns the original `src` if URL parsing fails.
|
|
121
|
+
|
|
122
|
+
<!-- AUTO GENERATED CHANGELOG -->
|
|
123
|
+
|
|
124
|
+
## Changelog
|
|
125
|
+
|
|
126
|
+
Full changelog for stable version is available [here](https://github.com/shopware/frontends/blob/main/packages/helpers/CHANGELOG.md)
|
|
127
|
+
|
|
128
|
+
### Latest changes: 1.7.1
|
|
129
|
+
|
|
130
|
+
### Patch Changes
|
|
57
131
|
|
|
58
|
-
- [#
|
|
132
|
+
- [#2372](https://github.com/shopware/frontends/pull/2372) [`22fc8a7`](https://github.com/shopware/frontends/commit/22fc8a7301f6a7d2612d907ab73555978b651c00) Thanks [@patzick](https://github.com/patzick)! - Improve technical URL resolution for SSR and CSR page rendering.
|
|
59
133
|
|
|
60
|
-
|
|
134
|
+
This adds helpers to detect and normalize technical Shopware paths and updates
|
|
135
|
+
`useNavigationSearch` to resolve `/navigation/*`, `/detail/*`, and
|
|
136
|
+
`/landingPage/*` routes more reliably, including fallback behavior when no SEO
|
|
137
|
+
mapping row is returned.
|
package/dist/index.d.mts
CHANGED
|
@@ -397,6 +397,10 @@ type LayoutConfiguration = {
|
|
|
397
397
|
*/
|
|
398
398
|
declare function getCmsLayoutConfiguration<T extends CmsBlock | CmsSection | CmsSlot>(content: T): LayoutConfiguration;
|
|
399
399
|
|
|
400
|
+
type BackgroundImageOptions = {
|
|
401
|
+
format?: string;
|
|
402
|
+
quality?: number;
|
|
403
|
+
};
|
|
400
404
|
declare function getBackgroundImageUrl<T extends {
|
|
401
405
|
backgroundMedia?: {
|
|
402
406
|
metaData?: {
|
|
@@ -404,7 +408,7 @@ declare function getBackgroundImageUrl<T extends {
|
|
|
404
408
|
height?: number;
|
|
405
409
|
};
|
|
406
410
|
};
|
|
407
|
-
}>(url: string, element: T): string;
|
|
411
|
+
}>(url: string, element: T, options?: BackgroundImageOptions): string;
|
|
408
412
|
|
|
409
413
|
type UrlRoute = {
|
|
410
414
|
path?: string;
|
|
@@ -522,6 +526,20 @@ declare function isLandingPage<T extends {
|
|
|
522
526
|
apiAlias: string;
|
|
523
527
|
}>(entity: T | LandingPage): entity is LandingPage;
|
|
524
528
|
|
|
529
|
+
declare const TECHNICAL_ROUTE_MAP: {
|
|
530
|
+
readonly "/navigation/": "frontend.navigation.page";
|
|
531
|
+
readonly "/detail/": "frontend.detail.page";
|
|
532
|
+
readonly "/landingPage/": "frontend.landing.page";
|
|
533
|
+
};
|
|
534
|
+
type RouteNameFromPathInfo = (typeof TECHNICAL_ROUTE_MAP)[keyof typeof TECHNICAL_ROUTE_MAP];
|
|
535
|
+
type RouteInfoFromPathInfo = {
|
|
536
|
+
routeName: RouteNameFromPathInfo;
|
|
537
|
+
foreignKey: string;
|
|
538
|
+
};
|
|
539
|
+
declare function normalizePath(path: string): string;
|
|
540
|
+
declare function isTechnicalPath(path: string): boolean;
|
|
541
|
+
declare function getRouteFromPathInfo(path: string): RouteInfoFromPathInfo | null;
|
|
542
|
+
|
|
525
543
|
/**
|
|
526
544
|
* Get translated property from the given object.
|
|
527
545
|
*
|
|
@@ -616,7 +634,7 @@ declare function getMedia<T extends {
|
|
|
616
634
|
}>(lineItem: T): ProductMedia[];
|
|
617
635
|
|
|
618
636
|
/**
|
|
619
|
-
* Returns the smallest thumbnail url from the media object
|
|
637
|
+
* Returns the smallest thumbnail url from the media object or the media.url if no thumbnails are available
|
|
620
638
|
*
|
|
621
639
|
* @param media image object
|
|
622
640
|
*
|
|
@@ -628,6 +646,7 @@ declare function getSmallestThumbnailUrl<T extends {
|
|
|
628
646
|
width: number;
|
|
629
647
|
url: string;
|
|
630
648
|
}>;
|
|
649
|
+
url?: string;
|
|
631
650
|
}>(media?: T): string | undefined;
|
|
632
651
|
|
|
633
652
|
/**
|
|
@@ -640,6 +659,41 @@ declare function getSmallestThumbnailUrl<T extends {
|
|
|
640
659
|
* @category Media
|
|
641
660
|
*/
|
|
642
661
|
declare function encodeUrlPath(urlString: string): string;
|
|
662
|
+
/**
|
|
663
|
+
* Generates a srcset string using CDN width-based resizing.
|
|
664
|
+
* Useful as a fallback when media has no pre-generated thumbnails.
|
|
665
|
+
*
|
|
666
|
+
* @param src - Base image URL
|
|
667
|
+
* @param widths - Array of widths to generate (default: [400, 800, 1200, 1600])
|
|
668
|
+
* @param options - Optional format and quality params
|
|
669
|
+
* @returns srcset string or undefined if src is invalid
|
|
670
|
+
*
|
|
671
|
+
* @public
|
|
672
|
+
* @category Media
|
|
673
|
+
*/
|
|
674
|
+
declare function generateCdnSrcSet(src: string | undefined, widths?: number[], options?: {
|
|
675
|
+
format?: string;
|
|
676
|
+
quality?: number;
|
|
677
|
+
}): string | undefined;
|
|
678
|
+
/**
|
|
679
|
+
* Builds an optimized CDN image URL with size parameters.
|
|
680
|
+
* Adds width or height (whichever is larger, width if equal)
|
|
681
|
+
* rounded up to the nearest 100px.
|
|
682
|
+
*
|
|
683
|
+
* @param src - Base image URL
|
|
684
|
+
* @param dimensions - Rendered element dimensions (width and height)
|
|
685
|
+
* @returns Optimized image URL string
|
|
686
|
+
*
|
|
687
|
+
* @public
|
|
688
|
+
* @category Media
|
|
689
|
+
*/
|
|
690
|
+
declare function buildCdnImageUrl(src: string | undefined, dimensions: {
|
|
691
|
+
width: number;
|
|
692
|
+
height: number;
|
|
693
|
+
}, options?: {
|
|
694
|
+
format?: string;
|
|
695
|
+
quality?: number;
|
|
696
|
+
}): string;
|
|
643
697
|
/**
|
|
644
698
|
* Returns the srcset attribute for the image, for available breakpoints
|
|
645
699
|
*
|
|
@@ -715,4 +769,5 @@ declare function canUseQuoteActions<T extends {
|
|
|
715
769
|
};
|
|
716
770
|
}>(quote: T): boolean;
|
|
717
771
|
|
|
718
|
-
export {
|
|
772
|
+
export { buildCdnImageUrl, buildUrlPrefix, canUseQuoteActions, downloadFile, encodeUrlPath, generateCdnSrcSet, getBackgroundImageUrl, getBiggestThumbnailUrl, getCategoryBreadcrumbs, getCategoryImageUrl, getCategoryRoute, getCategoryUrl, getCmsBreadcrumbs, getCmsEntityObject, getCmsLayoutConfiguration, getCmsTranslate, getFormattedPrice, getLanguageName, getListingFilters, getMainImageUrl, getMedia, getPaymentMethodIcon, getProductCalculatedListingPrice, getProductFreeShipping, getProductFromPrice, getProductListingFromCmsPage, getProductManufacturerName, getProductName, getProductRatingAverage, getProductReviews, getProductRoute, getProductTierPrices, getProductUrl, getRouteFromPathInfo, getShippingMethodDeliveryTime, getShippingMethodIcon, getSmallestThumbnailUrl, getSrcSetForMedia, getTranslatedProperty, helpersCssClasses, isCategory, isLandingPage, isMaintenanceMode, isProduct, isProductOnSale, isProductTopSeller, isTechnicalPath, normalizePath, relativeUrlSlash, urlIsAbsolute };
|
|
773
|
+
export type { BackgroundImageOptions, HelpersCssClasses, LayoutConfiguration, RouteInfoFromPathInfo, RouteNameFromPathInfo, TierPrice, UiMediaGalleryItem, UiMediaGalleryItemUrl, UiProductOption, UiProductProperty, UiProductReview, UrlRouteOutput };
|
package/dist/index.d.ts
CHANGED
|
@@ -397,6 +397,10 @@ type LayoutConfiguration = {
|
|
|
397
397
|
*/
|
|
398
398
|
declare function getCmsLayoutConfiguration<T extends CmsBlock | CmsSection | CmsSlot>(content: T): LayoutConfiguration;
|
|
399
399
|
|
|
400
|
+
type BackgroundImageOptions = {
|
|
401
|
+
format?: string;
|
|
402
|
+
quality?: number;
|
|
403
|
+
};
|
|
400
404
|
declare function getBackgroundImageUrl<T extends {
|
|
401
405
|
backgroundMedia?: {
|
|
402
406
|
metaData?: {
|
|
@@ -404,7 +408,7 @@ declare function getBackgroundImageUrl<T extends {
|
|
|
404
408
|
height?: number;
|
|
405
409
|
};
|
|
406
410
|
};
|
|
407
|
-
}>(url: string, element: T): string;
|
|
411
|
+
}>(url: string, element: T, options?: BackgroundImageOptions): string;
|
|
408
412
|
|
|
409
413
|
type UrlRoute = {
|
|
410
414
|
path?: string;
|
|
@@ -522,6 +526,20 @@ declare function isLandingPage<T extends {
|
|
|
522
526
|
apiAlias: string;
|
|
523
527
|
}>(entity: T | LandingPage): entity is LandingPage;
|
|
524
528
|
|
|
529
|
+
declare const TECHNICAL_ROUTE_MAP: {
|
|
530
|
+
readonly "/navigation/": "frontend.navigation.page";
|
|
531
|
+
readonly "/detail/": "frontend.detail.page";
|
|
532
|
+
readonly "/landingPage/": "frontend.landing.page";
|
|
533
|
+
};
|
|
534
|
+
type RouteNameFromPathInfo = (typeof TECHNICAL_ROUTE_MAP)[keyof typeof TECHNICAL_ROUTE_MAP];
|
|
535
|
+
type RouteInfoFromPathInfo = {
|
|
536
|
+
routeName: RouteNameFromPathInfo;
|
|
537
|
+
foreignKey: string;
|
|
538
|
+
};
|
|
539
|
+
declare function normalizePath(path: string): string;
|
|
540
|
+
declare function isTechnicalPath(path: string): boolean;
|
|
541
|
+
declare function getRouteFromPathInfo(path: string): RouteInfoFromPathInfo | null;
|
|
542
|
+
|
|
525
543
|
/**
|
|
526
544
|
* Get translated property from the given object.
|
|
527
545
|
*
|
|
@@ -616,7 +634,7 @@ declare function getMedia<T extends {
|
|
|
616
634
|
}>(lineItem: T): ProductMedia[];
|
|
617
635
|
|
|
618
636
|
/**
|
|
619
|
-
* Returns the smallest thumbnail url from the media object
|
|
637
|
+
* Returns the smallest thumbnail url from the media object or the media.url if no thumbnails are available
|
|
620
638
|
*
|
|
621
639
|
* @param media image object
|
|
622
640
|
*
|
|
@@ -628,6 +646,7 @@ declare function getSmallestThumbnailUrl<T extends {
|
|
|
628
646
|
width: number;
|
|
629
647
|
url: string;
|
|
630
648
|
}>;
|
|
649
|
+
url?: string;
|
|
631
650
|
}>(media?: T): string | undefined;
|
|
632
651
|
|
|
633
652
|
/**
|
|
@@ -640,6 +659,41 @@ declare function getSmallestThumbnailUrl<T extends {
|
|
|
640
659
|
* @category Media
|
|
641
660
|
*/
|
|
642
661
|
declare function encodeUrlPath(urlString: string): string;
|
|
662
|
+
/**
|
|
663
|
+
* Generates a srcset string using CDN width-based resizing.
|
|
664
|
+
* Useful as a fallback when media has no pre-generated thumbnails.
|
|
665
|
+
*
|
|
666
|
+
* @param src - Base image URL
|
|
667
|
+
* @param widths - Array of widths to generate (default: [400, 800, 1200, 1600])
|
|
668
|
+
* @param options - Optional format and quality params
|
|
669
|
+
* @returns srcset string or undefined if src is invalid
|
|
670
|
+
*
|
|
671
|
+
* @public
|
|
672
|
+
* @category Media
|
|
673
|
+
*/
|
|
674
|
+
declare function generateCdnSrcSet(src: string | undefined, widths?: number[], options?: {
|
|
675
|
+
format?: string;
|
|
676
|
+
quality?: number;
|
|
677
|
+
}): string | undefined;
|
|
678
|
+
/**
|
|
679
|
+
* Builds an optimized CDN image URL with size parameters.
|
|
680
|
+
* Adds width or height (whichever is larger, width if equal)
|
|
681
|
+
* rounded up to the nearest 100px.
|
|
682
|
+
*
|
|
683
|
+
* @param src - Base image URL
|
|
684
|
+
* @param dimensions - Rendered element dimensions (width and height)
|
|
685
|
+
* @returns Optimized image URL string
|
|
686
|
+
*
|
|
687
|
+
* @public
|
|
688
|
+
* @category Media
|
|
689
|
+
*/
|
|
690
|
+
declare function buildCdnImageUrl(src: string | undefined, dimensions: {
|
|
691
|
+
width: number;
|
|
692
|
+
height: number;
|
|
693
|
+
}, options?: {
|
|
694
|
+
format?: string;
|
|
695
|
+
quality?: number;
|
|
696
|
+
}): string;
|
|
643
697
|
/**
|
|
644
698
|
* Returns the srcset attribute for the image, for available breakpoints
|
|
645
699
|
*
|
|
@@ -715,4 +769,5 @@ declare function canUseQuoteActions<T extends {
|
|
|
715
769
|
};
|
|
716
770
|
}>(quote: T): boolean;
|
|
717
771
|
|
|
718
|
-
export {
|
|
772
|
+
export { buildCdnImageUrl, buildUrlPrefix, canUseQuoteActions, downloadFile, encodeUrlPath, generateCdnSrcSet, getBackgroundImageUrl, getBiggestThumbnailUrl, getCategoryBreadcrumbs, getCategoryImageUrl, getCategoryRoute, getCategoryUrl, getCmsBreadcrumbs, getCmsEntityObject, getCmsLayoutConfiguration, getCmsTranslate, getFormattedPrice, getLanguageName, getListingFilters, getMainImageUrl, getMedia, getPaymentMethodIcon, getProductCalculatedListingPrice, getProductFreeShipping, getProductFromPrice, getProductListingFromCmsPage, getProductManufacturerName, getProductName, getProductRatingAverage, getProductReviews, getProductRoute, getProductTierPrices, getProductUrl, getRouteFromPathInfo, getShippingMethodDeliveryTime, getShippingMethodIcon, getSmallestThumbnailUrl, getSrcSetForMedia, getTranslatedProperty, helpersCssClasses, isCategory, isLandingPage, isMaintenanceMode, isProduct, isProductOnSale, isProductTopSeller, isTechnicalPath, normalizePath, relativeUrlSlash, urlIsAbsolute };
|
|
773
|
+
export type { BackgroundImageOptions, HelpersCssClasses, LayoutConfiguration, RouteInfoFromPathInfo, RouteNameFromPathInfo, TierPrice, UiMediaGalleryItem, UiMediaGalleryItemUrl, UiProductOption, UiProductProperty, UiProductReview, UrlRouteOutput };
|
package/dist/index.mjs
CHANGED
|
@@ -260,12 +260,18 @@ const getUrlFromBackgroundImage = (url) => {
|
|
|
260
260
|
const match = url.match(regex);
|
|
261
261
|
return !match ? url : match[1];
|
|
262
262
|
};
|
|
263
|
-
function getBackgroundImageUrl(url, element) {
|
|
263
|
+
function getBackgroundImageUrl(url, element, options) {
|
|
264
264
|
const backgroundImage = getUrlFromBackgroundImage(url);
|
|
265
265
|
const width = element.backgroundMedia?.metaData?.width ?? 0;
|
|
266
266
|
const height = element.backgroundMedia?.metaData?.height ?? 0;
|
|
267
267
|
const biggestParam = width > height ? `width=${roundUp(width > 1920 ? 1900 : width)}` : `height=${roundUp(height > 1920 ? 1900 : height)}`;
|
|
268
|
-
|
|
268
|
+
let srcPath = `${backgroundImage}?${biggestParam}&fit=crop,smart`;
|
|
269
|
+
if (options?.format) {
|
|
270
|
+
srcPath += `&format=${options.format}`;
|
|
271
|
+
}
|
|
272
|
+
if (options?.quality) {
|
|
273
|
+
srcPath += `&quality=${options.quality}`;
|
|
274
|
+
}
|
|
269
275
|
return `url("${srcPath}")`;
|
|
270
276
|
}
|
|
271
277
|
|
|
@@ -346,6 +352,34 @@ function isLandingPage(entity) {
|
|
|
346
352
|
return entity.apiAlias === "landing_page";
|
|
347
353
|
}
|
|
348
354
|
|
|
355
|
+
const TECHNICAL_ROUTE_MAP = {
|
|
356
|
+
"/navigation/": "frontend.navigation.page",
|
|
357
|
+
"/detail/": "frontend.detail.page",
|
|
358
|
+
"/landingPage/": "frontend.landing.page"
|
|
359
|
+
};
|
|
360
|
+
function normalizePath(path) {
|
|
361
|
+
return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
|
|
362
|
+
}
|
|
363
|
+
function isTechnicalPath(path) {
|
|
364
|
+
const normalizedPath = normalizePath(path);
|
|
365
|
+
return Object.keys(TECHNICAL_ROUTE_MAP).some(
|
|
366
|
+
(prefix) => normalizedPath.startsWith(prefix)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function getRouteFromPathInfo(path) {
|
|
370
|
+
const normalizedPath = normalizePath(path);
|
|
371
|
+
for (const [prefix, routeName] of Object.entries(TECHNICAL_ROUTE_MAP)) {
|
|
372
|
+
if (!normalizedPath.startsWith(prefix)) continue;
|
|
373
|
+
const foreignKey = normalizedPath.slice(prefix.length);
|
|
374
|
+
if (!foreignKey || foreignKey.includes("/")) return null;
|
|
375
|
+
return {
|
|
376
|
+
routeName,
|
|
377
|
+
foreignKey
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
|
|
349
383
|
const getFilter = (code, aggregation) => {
|
|
350
384
|
return {
|
|
351
385
|
label: getTranslatedProperty(aggregation, "name") || code,
|
|
@@ -428,6 +462,9 @@ function getMedia(lineItem) {
|
|
|
428
462
|
|
|
429
463
|
function getSmallestThumbnailUrl(media) {
|
|
430
464
|
if (!media || !media?.thumbnails?.length) {
|
|
465
|
+
if (media?.url) {
|
|
466
|
+
return media.url;
|
|
467
|
+
}
|
|
431
468
|
return;
|
|
432
469
|
}
|
|
433
470
|
const lowest = media.thumbnails.reduce((previous, current) => {
|
|
@@ -445,6 +482,51 @@ function encodeUrlPath(urlString) {
|
|
|
445
482
|
return urlString;
|
|
446
483
|
}
|
|
447
484
|
}
|
|
485
|
+
function generateCdnSrcSet(src, widths = [400, 800, 1200, 1600], options) {
|
|
486
|
+
if (!src) return void 0;
|
|
487
|
+
try {
|
|
488
|
+
return widths.map((w) => {
|
|
489
|
+
const url = new URL(encodeUrlPath(src));
|
|
490
|
+
url.searchParams.set("width", String(w));
|
|
491
|
+
url.searchParams.set("fit", "crop,smart");
|
|
492
|
+
if (options?.format) {
|
|
493
|
+
url.searchParams.set("format", options.format);
|
|
494
|
+
}
|
|
495
|
+
if (options?.quality) {
|
|
496
|
+
url.searchParams.set("quality", String(options.quality));
|
|
497
|
+
}
|
|
498
|
+
return `${url.toString()} ${w}w`;
|
|
499
|
+
}).join(", ");
|
|
500
|
+
} catch {
|
|
501
|
+
return void 0;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function buildCdnImageUrl(src, dimensions, options) {
|
|
505
|
+
if (!src) return "";
|
|
506
|
+
try {
|
|
507
|
+
const url = new URL(encodeUrlPath(src));
|
|
508
|
+
const DEFAULT_SIZE = 10;
|
|
509
|
+
const w = dimensions.width ? Math.ceil(dimensions.width / 100) * 100 : DEFAULT_SIZE;
|
|
510
|
+
const h = dimensions.height ? Math.ceil(dimensions.height / 100) * 100 : DEFAULT_SIZE;
|
|
511
|
+
if (w > DEFAULT_SIZE || h > DEFAULT_SIZE) {
|
|
512
|
+
if (dimensions.width >= dimensions.height) {
|
|
513
|
+
url.searchParams.set("width", String(w));
|
|
514
|
+
} else {
|
|
515
|
+
url.searchParams.set("height", String(h));
|
|
516
|
+
}
|
|
517
|
+
url.searchParams.set("fit", "crop,smart");
|
|
518
|
+
}
|
|
519
|
+
if (options?.format) {
|
|
520
|
+
url.searchParams.set("format", options.format);
|
|
521
|
+
}
|
|
522
|
+
if (options?.quality) {
|
|
523
|
+
url.searchParams.set("quality", String(options.quality));
|
|
524
|
+
}
|
|
525
|
+
return url.toString();
|
|
526
|
+
} catch {
|
|
527
|
+
return src;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
448
530
|
function getSrcSetForMedia(media) {
|
|
449
531
|
if (!media?.thumbnails?.length) {
|
|
450
532
|
return;
|
|
@@ -482,4 +564,4 @@ function canUseQuoteActions(quote) {
|
|
|
482
564
|
return ["replied"].includes(quote.stateMachineState?.technicalName ?? "");
|
|
483
565
|
}
|
|
484
566
|
|
|
485
|
-
export { buildUrlPrefix, canUseQuoteActions, downloadFile, encodeUrlPath, getBackgroundImageUrl, getBiggestThumbnailUrl, getCategoryBreadcrumbs, getCategoryImageUrl, getCategoryRoute, getCategoryUrl, getCmsBreadcrumbs, getCmsEntityObject, getCmsLayoutConfiguration, getCmsTranslate, getFormattedPrice, getLanguageName, getListingFilters, getMainImageUrl, getMedia, getPaymentMethodIcon, getProductCalculatedListingPrice, getProductFreeShipping, getProductFromPrice, getProductListingFromCmsPage, getProductManufacturerName, getProductName, getProductRatingAverage, getProductReviews, getProductRoute, getProductTierPrices, getProductUrl, getShippingMethodDeliveryTime, getShippingMethodIcon, getSmallestThumbnailUrl, getSrcSetForMedia, getTranslatedProperty, helpersCssClasses, isCategory, isLandingPage, isMaintenanceMode, isProduct, isProductOnSale, isProductTopSeller, relativeUrlSlash, urlIsAbsolute };
|
|
567
|
+
export { buildCdnImageUrl, buildUrlPrefix, canUseQuoteActions, downloadFile, encodeUrlPath, generateCdnSrcSet, getBackgroundImageUrl, getBiggestThumbnailUrl, getCategoryBreadcrumbs, getCategoryImageUrl, getCategoryRoute, getCategoryUrl, getCmsBreadcrumbs, getCmsEntityObject, getCmsLayoutConfiguration, getCmsTranslate, getFormattedPrice, getLanguageName, getListingFilters, getMainImageUrl, getMedia, getPaymentMethodIcon, getProductCalculatedListingPrice, getProductFreeShipping, getProductFromPrice, getProductListingFromCmsPage, getProductManufacturerName, getProductName, getProductRatingAverage, getProductReviews, getProductRoute, getProductTierPrices, getProductUrl, getRouteFromPathInfo, getShippingMethodDeliveryTime, getShippingMethodIcon, getSmallestThumbnailUrl, getSrcSetForMedia, getTranslatedProperty, helpersCssClasses, isCategory, isLandingPage, isMaintenanceMode, isProduct, isProductOnSale, isProductTopSeller, isTechnicalPath, normalizePath, relativeUrlSlash, urlIsAbsolute };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopware/helpers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Shopware helpers for accessing API data",
|
|
5
5
|
"author": "Shopware",
|
|
6
6
|
"type": "module",
|
|
@@ -33,19 +33,20 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@biomejs/biome": "1.8.3",
|
|
36
|
-
"@
|
|
37
|
-
"
|
|
36
|
+
"@typescript/native-preview": "7.0.0-dev.20260205.1",
|
|
37
|
+
"@vitest/coverage-v8": "4.1.5",
|
|
38
|
+
"happy-dom": "20.9.0",
|
|
38
39
|
"unbuild": "2.0.0",
|
|
39
|
-
"vitest": "
|
|
40
|
+
"vitest": "4.1.5",
|
|
40
41
|
"tsconfig": "0.0.0"
|
|
41
42
|
},
|
|
42
43
|
"scripts": {
|
|
43
44
|
"build": "unbuild && pnpm build:types",
|
|
44
|
-
"build:types": "
|
|
45
|
+
"build:types": "tsgo ./src/*.ts --ignoreConfig --declaration --allowJs --emitDeclarationOnly --outDir ./temp --skipLibCheck",
|
|
45
46
|
"dev": "unbuild --stub",
|
|
46
47
|
"lint": "biome check .",
|
|
47
48
|
"lint:fix": "biome check . --write && pnpm run typecheck",
|
|
48
|
-
"typecheck": "
|
|
49
|
+
"typecheck": "tsgo --noEmit",
|
|
49
50
|
"test": "vitest run",
|
|
50
51
|
"test:watch": "vitest"
|
|
51
52
|
}
|