@porulle/adapter-woocommerce 0.74.2 → 0.74.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/catalog.js CHANGED
@@ -59,8 +59,49 @@ function status(value) {
59
59
  return "draft";
60
60
  return undefined;
61
61
  }
62
- function variant(row, currency) {
63
- const optionValues = Object.fromEntries(row.attributes.flatMap((attribute) => (attribute.option ? [[attribute.name, attribute.option]] : [])));
62
+ /** "pa_color", "Color" and "color" are one attribute; "Blue" and the term slug "blue" one value. */
63
+ function attributeKey(value) {
64
+ return value.trim().toLowerCase().replace(/^pa_/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
65
+ }
66
+ /**
67
+ * The option axes a variable product sells along. WooCommerce lets a variation use a global
68
+ * attribute (`pa_color`) by its term SLUG ("blue") while the product lists the term NAME ("Blue") —
69
+ * or does not list that attribute at all (measured on WooCommerce's own sample catalogue). The axes
70
+ * are the product's declared variation attributes plus any its variations use, and each value is
71
+ * spelled as the product spells it where it declares one, so every variant's values are among them.
72
+ */
73
+ function optionAxes(product, variations) {
74
+ const axes = new Map();
75
+ for (const attribute of product.attributes.filter((candidate) => candidate.variation === true)) {
76
+ axes.set(attributeKey(attribute.name), { name: attribute.name, values: [...attribute.options] });
77
+ }
78
+ const resolve = (name, option) => {
79
+ const key = attributeKey(name);
80
+ let axis = axes.get(key);
81
+ if (!axis) {
82
+ axis = { name: name.replace(/^pa_/, "").replace(/^./, (first) => first.toUpperCase()), values: [] };
83
+ axes.set(key, axis);
84
+ }
85
+ const declared = axis.values.find((value) => attributeKey(value) === attributeKey(option));
86
+ if (declared)
87
+ return { name: axis.name, value: declared };
88
+ const shown = option.replace(/^./, (first) => first.toUpperCase());
89
+ axis.values.push(shown);
90
+ return { name: axis.name, value: shown };
91
+ };
92
+ for (const row of variations)
93
+ for (const attribute of row.attributes)
94
+ if (attribute.option)
95
+ resolve(attribute.name, attribute.option);
96
+ return { axes: [...axes.values()], resolve };
97
+ }
98
+ function variant(row, currency, resolve) {
99
+ const optionValues = Object.fromEntries(row.attributes.flatMap((attribute) => {
100
+ if (!attribute.option)
101
+ return [];
102
+ const resolved = resolve(attribute.name, attribute.option);
103
+ return [[resolved.name, resolved.value]];
104
+ }));
64
105
  const rowPrices = prices(row, currency);
65
106
  return {
66
107
  externalId: row.id,
@@ -94,15 +135,17 @@ export function catalogItem(product, variations, currency) {
94
135
  images.push({ externalId: row.image.id, url: row.image.src, ...(row.image.alt ? { alt: row.image.alt } : {}), role: "gallery", sortOrder: images.length, variantExternalIds: [row.id] });
95
136
  }
96
137
  }
97
- const options = product.attributes.filter((attribute) => attribute.variation === true).map((attribute, index) => ({
98
- name: attribute.name,
99
- displayName: attribute.name,
100
- sortOrder: attribute.position ?? index,
101
- values: attribute.options.map((value, valueIndex) => ({ value, displayValue: value, sortOrder: valueIndex })),
102
- }));
138
+ const sellable = product.type === "simple" ? [] : variations.filter((row) => row.status !== "private");
139
+ const { axes, resolve } = optionAxes(product, sellable);
103
140
  const variants = product.type === "simple"
104
- ? [variant({ id: product.id, sku: product.sku, price: product.price, regular_price: product.regular_price, sale_price: product.sale_price, attributes: [] }, currency)]
105
- : variations.filter((row) => row.status !== "private").map((row) => variant(row, currency));
141
+ ? [variant({ id: product.id, sku: product.sku, price: product.price, regular_price: product.regular_price, sale_price: product.sale_price, attributes: [] }, currency, resolve)]
142
+ : sellable.map((row) => variant(row, currency, resolve));
143
+ const options = product.type === "simple" ? [] : axes.map((axis, index) => ({
144
+ name: axis.name,
145
+ displayName: axis.name,
146
+ sortOrder: index,
147
+ values: axis.values.map((value, valueIndex) => ({ value, displayValue: value, sortOrder: valueIndex })),
148
+ }));
106
149
  const itemStatus = status(product.status);
107
150
  return {
108
151
  externalId: product.id,