@decocms/apps-vtex 7.66.1 → 7.66.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/apps-vtex",
3
- "version": "7.66.1",
3
+ "version": "7.66.3",
4
4
  "type": "module",
5
5
  "description": "Deco commerce app: VTEX integration",
6
6
  "repository": {
@@ -51,10 +51,10 @@
51
51
  "lint:unused": "knip"
52
52
  },
53
53
  "dependencies": {
54
- "@decocms/blocks": "7.66.1",
55
- "@decocms/apps-commerce": "7.66.1",
56
- "@decocms/apps-website": "7.66.1",
57
- "@decocms/tanstack": "7.66.1"
54
+ "@decocms/blocks": "7.66.3",
55
+ "@decocms/apps-commerce": "7.66.3",
56
+ "@decocms/apps-website": "7.66.3",
57
+ "@decocms/tanstack": "7.66.3"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@tanstack/react-query": ">=5.0.0",
@@ -649,17 +649,19 @@ describe("toProductVariant", () => {
649
649
  expect(offer.inventoryLevel?.value).toBe(0);
650
650
  });
651
651
 
652
- it("filters additionalProperty to variant-differentiating names only", () => {
652
+ it("filters spec additionalProperty to variant-differentiating names only", () => {
653
653
  const product = makeISProduct({ items: [makeISSku()] });
654
654
  const sku = makeISSku();
655
655
  const result = toProductVariant(product, sku, baseOptions);
656
656
 
657
- const propNames = result.additionalProperty?.map((p) => p.name) ?? [];
657
+ const specNames = (result.additionalProperty ?? [])
658
+ .filter((p) => p.valueReference !== "ReferenceID")
659
+ .map((p) => p.name);
658
660
  // Should only contain Cor, Voltagem, Tamanho (from VARIANT_PROPERTY_NAMES)
659
- for (const name of propNames) {
661
+ for (const name of specNames) {
660
662
  expect(["Cor", "Voltagem", "Tamanho"]).toContain(name);
661
663
  }
662
- expect(propNames.length).toBeGreaterThan(0);
664
+ expect(specNames.length).toBeGreaterThan(0);
663
665
  });
664
666
 
665
667
  it("respects custom variantPropertyNames", () => {
@@ -670,8 +672,32 @@ describe("toProductVariant", () => {
670
672
  variantPropertyNames: new Set(["Cor"]),
671
673
  });
672
674
 
673
- const propNames = result.additionalProperty?.map((p) => p.name) ?? [];
674
- expect(propNames).toEqual(["Cor"]);
675
+ const specNames = (result.additionalProperty ?? [])
676
+ .filter((p) => p.valueReference !== "ReferenceID")
677
+ .map((p) => p.name);
678
+ expect(specNames).toEqual(["Cor"]);
679
+ });
680
+
681
+ // Analytics reads the SKU RefId off additionalProperty for GA4 dimension2
682
+ // (view_item_list / select_item) and its productImpression / productClick
683
+ // equivalents. It lives in `referenceId`, not `variations`, so the
684
+ // variantProps filter used to drop it and blank the dimension.
685
+ it("keeps the SKU reference ids (RefId) alongside the variant specs", () => {
686
+ const product = makeISProduct({ items: [makeISSku()] });
687
+ const sku = { ...makeISSku(), referenceId: [{ Key: "RefId", Value: "010276949803" }] };
688
+ const result = toProductVariant(product, sku, baseOptions);
689
+
690
+ const refId = result.additionalProperty?.find((p) => p.name === "RefId");
691
+ expect(refId?.value).toBe("010276949803");
692
+ expect(refId?.valueReference).toBe("ReferenceID");
693
+ });
694
+
695
+ it("omits RefId when the SKU carries no referenceId", () => {
696
+ const product = makeISProduct({ items: [makeISSku()] });
697
+ const sku = { ...makeISSku(), referenceId: undefined };
698
+ const result = toProductVariant(product, sku, baseOptions);
699
+
700
+ expect(result.additionalProperty?.some((p) => p.name === "RefId")).toBe(false);
675
701
  });
676
702
 
677
703
  it("produces lean offers with availability but no priceSpecification details", () => {
@@ -767,6 +793,31 @@ describe("toProductShelf", () => {
767
793
  );
768
794
  expect(result.isVariantOf?.additionalProperty).toEqual([]);
769
795
  });
796
+
797
+ // Analytics reads the product reference off isVariantOf.model for GA4
798
+ // dimension1 (view_item_list / select_item) and its productImpression /
799
+ // productClick equivalents. toProductShelf used to drop it, blanking the
800
+ // dimension on every shelf, PLP and search result.
801
+ it("carries productReference on isVariantOf.model (analytics dimension1)", () => {
802
+ const result = toProductShelf(
803
+ makeProduct({ productReference: "0102769498" }),
804
+ makeSku(),
805
+ 0,
806
+ options,
807
+ );
808
+ expect(result.isVariantOf?.model).toBe("0102769498");
809
+ });
810
+
811
+ it("keeps the SKU RefId reachable on the complete-variants shelf (dimension2)", () => {
812
+ const result = toProductShelf(makeProduct(), makeSku(), 0, {
813
+ ...options,
814
+ shelfCompleteVariants: true,
815
+ });
816
+ const variantProps = result.isVariantOf?.hasVariant?.[0]?.additionalProperty ?? [];
817
+ expect(variantProps).toEqual(
818
+ expect.arrayContaining([expect.objectContaining({ name: "RefId", value: "REF-SKU1" })]),
819
+ );
820
+ });
770
821
  });
771
822
 
772
823
  // ---------------------------------------------------------------------------
@@ -678,7 +678,7 @@ const SHELF_PROPERTY_NAMES = new Set([
678
678
  * - Offers: best seller only (in-stock first, then cheapest), stripped installments (keeps ListPrice, SalePrice, SRP, PIX, best no-interest)
679
679
  * - isVariantOf: single in-stock variant at level 0
680
680
  * - additionalProperty: filtered to known-used property names
681
- * - Drops: description, video, isAccessoryOrSparePartFor, alternateName, gtin, releaseDate, model
681
+ * - Drops: description, video, isAccessoryOrSparePartFor, alternateName, gtin, releaseDate
682
682
  */
683
683
  export const toProductShelf = <P extends LegacyProductVTEX | ProductVTEX>(
684
684
  product: P,
@@ -687,7 +687,7 @@ export const toProductShelf = <P extends LegacyProductVTEX | ProductVTEX>(
687
687
  options: ProductOptions,
688
688
  ): Product => {
689
689
  const { baseUrl, priceCurrency } = options;
690
- const { productId, items } = product;
690
+ const { productId, items, productReference } = product;
691
691
  const { name, itemId: skuId } = sku;
692
692
 
693
693
  // Images: cap at 2
@@ -762,6 +762,12 @@ export const toProductShelf = <P extends LegacyProductVTEX | ProductVTEX>(
762
762
  // flags that read isVariantOf.additionalProperty (e.g. ReleaseFlag ->
763
763
  // "Lançamento") still fire on shelf/carousel cards.
764
764
  additionalProperty: groupAdditionalProperty,
765
+ // The product reference (VTEX `productReference`). Analytics reads it
766
+ // off `isVariantOf.model` — GA4 `dimension1` on view_item_list /
767
+ // select_item, and the equivalent on productImpression /
768
+ // productClick. Dropping it silently blanked that dimension on every
769
+ // shelf, PLP and search result. One short string per product.
770
+ model: productReference,
765
771
  } satisfies ProductGroup;
766
772
  })()
767
773
  : undefined;
@@ -828,13 +834,19 @@ export const toProductVariant = <P extends LegacyProductVTEX | ProductVTEX>(
828
834
  const includeImage = options.variantIncludeImage !== false;
829
835
  const includeInventory = options.variantIncludeInventory !== false;
830
836
 
831
- // additionalProperty: only variant-differentiating specs
837
+ // additionalProperty: variant-differentiating specs, plus the SKU reference
838
+ // ids. Analytics reads the SKU's `RefId` off this list — GA4 `dimension2` on
839
+ // view_item_list / select_item, and the equivalent on productImpression /
840
+ // productClick. It lives in `referenceId`, not in `variations`, so the
841
+ // `variantProps` filter dropped it and blanked that dimension on every shelf
842
+ // card rendered with `shelfCompleteVariants`. One short string per SKU.
832
843
  const specificationsAdditionalProperty = isLegacySku(sku)
833
844
  ? toAdditionalPropertiesLegacy(sku)
834
845
  : toAdditionalProperties(sku);
835
- const additionalProperty = specificationsAdditionalProperty.filter((prop) =>
836
- variantProps.has(prop.name ?? ""),
837
- );
846
+ const additionalProperty = [
847
+ ...specificationsAdditionalProperty.filter((prop) => variantProps.has(prop.name ?? "")),
848
+ ...(toAdditionalPropertyReferenceIds(sku.referenceId ?? []) ?? []),
849
+ ];
838
850
 
839
851
  // Offers: best seller, lean (availability + seller; optional inventoryLevel)
840
852
  const offerConverter = isLegacyProduct(product) ? toOfferLegacy : toOffer;