@laioutr/app-shopware 0.15.2 → 0.15.4

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/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laioutr/app-shopware",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "configKey": "@laioutr/app-shopware",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
package/dist/module.mjs CHANGED
@@ -4,7 +4,7 @@ import { CHECKOUT_ENDPOINT_PATH, ADOPT_SESSION_ENDPOINT_PATH } from '../dist/run
4
4
  import { registerLaioutrApp } from '@laioutr-core/kit';
5
5
 
6
6
  const name = "@laioutr/app-shopware";
7
- const version = "0.15.2";
7
+ const version = "0.15.4";
8
8
 
9
9
  const module$1 = defineNuxtModule({
10
10
  meta: {
@@ -7,7 +7,7 @@ export default defineShopwareQuery({
7
7
  implements: MenuByAliasQuery,
8
8
  run: async ({ input, context, passthrough }) => {
9
9
  const { alias } = input;
10
- const criteria = await context.resolveCriteria("menu", { includes: {}, associations: { seoUrls: {} } });
10
+ const criteria = await context.resolveCriteria("menu", { includes: {}, associations: {} });
11
11
  const response = await context.storefrontClient.invoke("readNavigation post /navigation/{activeId}/{rootId}", {
12
12
  pathParams: {
13
13
  activeId: alias,
@@ -35,28 +35,30 @@ export default defineShopwareComponentResolver({
35
35
  const parentIdToDefaultVariantId = passthrough.get(parentIdToDefaultVariantIdToken);
36
36
  const variantIds = entityIds.map((id) => parentIdToDefaultVariantId?.[id] ?? id);
37
37
  const loadedVariants = passthrough.get(productVariantsToken) ?? [];
38
- const missingVariantIds = variantIds.filter((id) => !loadedVariants.some((variant) => variant.id === id));
39
- if (missingVariantIds.length > 0) {
38
+ const missingIds = [.../* @__PURE__ */ new Set([...variantIds, ...entityIds])].filter((id) => !loadedVariants.some((variant) => variant.id === id));
39
+ if (missingIds.length > 0) {
40
40
  const response = await fetchAllProducts(context.storefrontClient, {
41
- productIds: missingVariantIds,
41
+ productIds: missingIds,
42
42
  loadVariants: false,
43
43
  resolveCriteria: context.resolveCriteria
44
44
  });
45
45
  loadedVariants.push(...response);
46
46
  }
47
- const shopwareProducts = variantIds.map((id) => {
48
- const rawVariant = loadedVariants.find((variant) => variant.id === id);
47
+ const shopwareProducts = entityIds.map((entityId) => {
48
+ const rawVariant = loadedVariants.find((variant) => variant.id === (parentIdToDefaultVariantId?.[entityId] ?? entityId));
49
49
  if (!rawVariant) return void 0;
50
50
  return {
51
+ entityId,
51
52
  rawVariant,
52
- rawProduct: loadedVariants.find((variant) => variant.id === variant.parentId) ?? rawVariant
53
+ rawProduct: loadedVariants.find((variant) => variant.id === entityId) ?? rawVariant
53
54
  };
54
55
  }).filter((product) => !!product);
55
- const entities = shopwareProducts.map(({ rawProduct, rawVariant }) => {
56
+ const entities = shopwareProducts.map(({ entityId, rawProduct, rawVariant }) => {
56
57
  const mappedCover = rawProduct.cover?.media ? mapMedia(rawVariant.cover?.media ?? rawProduct.cover.media) : FALLBACK_IMAGE;
57
58
  return $entity({
58
- // The parent-id is the actual product-id, even if the product has variants.
59
- id: rawProduct.id,
59
+ // Answer under the id that was asked for: the queries hand over parent-ids, while the data
60
+ // below is read off the variant they selected.
61
+ id: entityId,
60
62
  base: {
61
63
  name: swTranslated(rawProduct, "name"),
62
64
  slug: entitySlug(rawProduct)
@@ -29,7 +29,7 @@ export default defineShopwareQuery(
29
29
  "shipping-free": swBuiltInFilters?.["shipping-free"]
30
30
  }
31
31
  });
32
- const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations);
32
+ const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations, context.swCurrency);
33
33
  const availableSortings = mapShopwareSortingToOrchestr(response.data.availableSortings);
34
34
  const parentIdToDefaultVariantId = Object.fromEntries(
35
35
  response.data.elements.map((product) => [product.parentId ?? product.id, product.id])
@@ -36,7 +36,7 @@ export default defineShopwareQuery(
36
36
  "shipping-free": swBuiltInFilters?.["shipping-free"]
37
37
  }
38
38
  });
39
- const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations);
39
+ const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations, context.swCurrency);
40
40
  const availableSortings = mapShopwareSortingToOrchestr(response.data.availableSortings);
41
41
  const parentIdToDefaultVariantId = Object.fromEntries(
42
42
  response.data.elements.map((product) => [product.parentId ?? product.id, product.id])
@@ -26,7 +26,7 @@ export default defineShopwareQuery(ProductSearchQuery, async ({ context, input,
26
26
  "shipping-free": swBuiltInFilters?.["shipping-free"]
27
27
  }
28
28
  });
29
- const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations);
29
+ const availableFilters = mapShopwareAggregationToAvailableFilters(response.data.aggregations, context.swCurrency);
30
30
  const availableSortings = mapShopwareSortingToOrchestr(response.data.availableSortings ?? []);
31
31
  const parentIdToDefaultVariantId = Object.fromEntries(
32
32
  response.data.elements.map((product) => [product.parentId ?? product.id, product.id])
@@ -40,6 +40,7 @@ export const mapCartItem = (lineItem, currency) => {
40
40
  const listPrice = price?.listPrice?.price;
41
41
  const parentId = payload.parentId ?? lineItem.referencedId ?? lineItem.id;
42
42
  const slug = getEntitySeoSlug(payload) ?? createFallbackSlug(lineItem.label ?? "", lineItem.referencedId ?? lineItem.id);
43
+ const cover = lineItem.cover;
43
44
  const availableStock = payload.availableStock;
44
45
  const inStock = availableStock === void 0 ? payload.available !== false : availableStock > 0;
45
46
  return {
@@ -48,8 +49,10 @@ export const mapCartItem = (lineItem, currency) => {
48
49
  quantity: lineItem.quantity,
49
50
  title: lineItem.label ?? "",
50
51
  code: payload.productNumber,
52
+ // The generated schema types `cover` as ProductMedia, but the store-api serializes
53
+ // the media entity directly (core sets `LineItem::$cover` to the ProductMedia's media).
51
54
  // Cart covers are product images (never video), so the narrowing cast is safe.
52
- cover: lineItem.cover?.media ? mapMedia(lineItem.cover.media) : void 0,
55
+ cover: cover ? mapMedia(cover) : void 0,
53
56
  link: {
54
57
  type: "reference",
55
58
  reference: { type: "Product", id: parentId, slug }
@@ -2,15 +2,16 @@ import { AvailableFilter, QueryWireRequestFilter } from '#orchestr/types';
2
2
  export type ShopwareAggregationKey = 'price' | 'shipping-free' | 'manufacturer';
3
3
  export interface ShopwareAggregation {
4
4
  name: string;
5
- min?: number;
6
- max?: number;
5
+ /** A decimal, serialized as a string on some instances and as a number on others. */
6
+ min?: number | string;
7
+ max?: number | string;
7
8
  entities?: Array<{
8
9
  id: string;
9
10
  name: string;
10
11
  }>;
11
12
  }
12
13
  export type ShopwareAggregations = Record<ShopwareAggregationKey, ShopwareAggregation>;
13
- export declare const mapShopwareAggregationToAvailableFilters: (facets: ShopwareAggregations) => AvailableFilter[];
14
+ export declare const mapShopwareAggregationToAvailableFilters: (facets: ShopwareAggregations, currency: string) => AvailableFilter[];
14
15
  export declare const mapSelectedFiltersToShopwareFilters: (filters: QueryWireRequestFilter, currency: string) => {
15
16
  swFilters: ({
16
17
  field: string;
@@ -1,6 +1,7 @@
1
1
  import { isRangeFilter } from "#orchestr/types";
2
2
  import { Money } from "@screeny05/ts-money";
3
- export const mapShopwareAggregationToAvailableFilters = (facets) => {
3
+ const toMoney = (decimal, currency) => Money.fromDecimal(Number(decimal ?? 0), currency, Math.round);
4
+ export const mapShopwareAggregationToAvailableFilters = (facets, currency) => {
4
5
  const filters = [];
5
6
  const listFacets = ["manufacturer"];
6
7
  const rangeFacets = ["price"];
@@ -21,8 +22,8 @@ export const mapShopwareAggregationToAvailableFilters = (facets) => {
21
22
  id: facetObj.name,
22
23
  label: facetObj.name,
23
24
  type: "range",
24
- min: 0,
25
- max: facetObj.max ?? 0
25
+ min: toMoney(facetObj.min, currency),
26
+ max: toMoney(facetObj.max, currency)
26
27
  });
27
28
  } else if (booleanFacets.includes(facetKey)) {
28
29
  filters.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laioutr/app-shopware",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "description": "Laioutr integration with Shopware 6",
5
5
  "repository": "github:laioutr/app-shopware",
6
6
  "license": "MIT",