@wix/himalaya-cli 0.1096.0 → 0.1098.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/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/display.d.ts +11 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/extensions.d.ts +1 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/stores-v1/src/options.d.ts +74 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-stores.mjs +132 -0
- package/dist/cli.mjs +106 -27
- package/guides/headless-loop.md +5 -5
- package/guides/sdk-reference.json +61 -1
- package/guides/skill.md +5 -5
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +215 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +214 -7
- package/templates/branded-lite/dev/index.ts +215 -1
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +214 -7
- package/templates/gym-fitness/dev/index.ts +215 -1
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +214 -7
- package/templates/portfolio-creative/dev/index.ts +215 -1
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +214 -7
- package/templates/retail-store/dev/index.ts +215 -1
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +214 -7
|
@@ -66,6 +66,17 @@ export interface StoreProduct {
|
|
|
66
66
|
currency?: string;
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
|
+
/** Option groups, both spellings: V1 `productOptions`, V3 `options`. Declared
|
|
70
|
+
* because the wire carries them on BOTH catalogs and this type denying them is
|
|
71
|
+
* what let every template product screen drop the colour/size picker. Shapes
|
|
72
|
+
* differ per catalog, so read them with `productOptions()` from ./options. */
|
|
73
|
+
productOptions?: unknown[];
|
|
74
|
+
options?: unknown[];
|
|
75
|
+
/** V3 purchasable variants. The cart addresses a V3 option choice by `variantId`,
|
|
76
|
+
* which `cartOptionsPayload()` resolves out of this. */
|
|
77
|
+
variantsInfo?: {
|
|
78
|
+
variants?: unknown[];
|
|
79
|
+
};
|
|
69
80
|
}
|
|
70
81
|
export interface StoreProductsResponse {
|
|
71
82
|
products?: StoreProduct[];
|
|
@@ -43,6 +43,7 @@ export declare function queryInventory(productId: string): Promise<WixQueryInven
|
|
|
43
43
|
* Only the supplied fields change (e.g. trackQuantity + a variant's quantity). */
|
|
44
44
|
export declare function updateInventory(inventoryItemId: string, inventoryItem: WixInventoryItemWrite): Promise<WixUpdateInventoryResponse>;
|
|
45
45
|
export * from "./display.js";
|
|
46
|
+
export * from "./options.js";
|
|
46
47
|
/** Forget the resolved Stores catalog version, in this worker and app-wide.
|
|
47
48
|
* Call this when the app points itself at a DIFFERENT Wix site. */
|
|
48
49
|
export declare function forgetCatalogVersion(): void;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { StoreProduct } from "./display.js";
|
|
2
|
+
import { type WixImageSize } from "@wix/himalaya/wix-media";
|
|
3
|
+
/** One selectable choice inside an option group. */
|
|
4
|
+
export interface StoreOptionChoice {
|
|
5
|
+
/** Stable id within the group. V3: the `choiceId`. V1: the choice's own label,
|
|
6
|
+
* which is what V1 has and what its cart payload carries. */
|
|
7
|
+
id: string;
|
|
8
|
+
/** What the shopper reads on the chip — "BEIGE", "M". */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Is at least one variant carrying this choice in stock? */
|
|
11
|
+
inStock: boolean;
|
|
12
|
+
/** HEX swatch the site configured for this choice ("#e1bfc5"), or "" — a colour
|
|
13
|
+
* group carries one, a size group does not. */
|
|
14
|
+
colorCode: string;
|
|
15
|
+
/** Choice-linked image, sized, or "" when the choice has none. */
|
|
16
|
+
image: string;
|
|
17
|
+
}
|
|
18
|
+
/** One option group, e.g. `COLOR` with `BEIGE` / `PINK`. */
|
|
19
|
+
export interface StoreOption {
|
|
20
|
+
/** V3: the option id, used to resolve the variant. V1: the option name. */
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
/** `color` groups are the ones worth rendering as swatches — the choices carry
|
|
24
|
+
* a `colorCode`. Everything else is a list of words. */
|
|
25
|
+
kind: "color" | "list";
|
|
26
|
+
choices: StoreOptionChoice[];
|
|
27
|
+
}
|
|
28
|
+
/** The shopper's pick: option id → choice id. A group the shopper has not chosen
|
|
29
|
+
* yet is absent (or maps to ""). */
|
|
30
|
+
export type StoreOptionSelection = Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Every offerable option group on a product, in site order, from either catalog.
|
|
33
|
+
*
|
|
34
|
+
* `[]` for a product with no options — the common case, so a caller must render
|
|
35
|
+
* nothing rather than an empty picker.
|
|
36
|
+
*
|
|
37
|
+
* `size` sizes the per-choice swatch image, like `productImage`; pass `null` for
|
|
38
|
+
* the stored original.
|
|
39
|
+
*/
|
|
40
|
+
export declare function productOptions(product: StoreProduct | undefined, size?: WixImageSize | null): StoreOption[];
|
|
41
|
+
/** The choice to preselect for a group: the only one when there is exactly one,
|
|
42
|
+
* otherwise "" so the shopper picks deliberately. */
|
|
43
|
+
export declare function defaultChoice(option: StoreOption): string;
|
|
44
|
+
/** A selection with every single-choice group pre-filled — what a product screen
|
|
45
|
+
* starts from. */
|
|
46
|
+
export declare function defaultSelection(options: StoreOption[]): StoreOptionSelection;
|
|
47
|
+
/** Has the shopper chosen in EVERY group? Add to cart stays disabled until this
|
|
48
|
+
* is true — a half-chosen product is the unfulfillable order. */
|
|
49
|
+
export declare function isSelectionComplete(options: StoreOption[], selection: StoreOptionSelection): boolean;
|
|
50
|
+
/** Human summary of the current selection, e.g. "BEIGE · M" ("" when nothing is
|
|
51
|
+
* chosen). Labels, not ids — this is shopper-facing text. */
|
|
52
|
+
export declare function selectionSummary(options: StoreOption[], selection: StoreOptionSelection): string;
|
|
53
|
+
/**
|
|
54
|
+
* The V3 variant matching the shopper's choices, or "" when none does.
|
|
55
|
+
*
|
|
56
|
+
* Set equality on `{optionId, choiceId}` pairs, not order — V3 does not promise
|
|
57
|
+
* the variant's `choices` array is in the product's option order, and a positional
|
|
58
|
+
* compare passes on a two-option product until the day the site reorders it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveVariantId(product: StoreProduct | undefined, selection: StoreOptionSelection): string;
|
|
61
|
+
/**
|
|
62
|
+
* The `catalogReference.options` value for `addToCurrentCart`, built for whichever
|
|
63
|
+
* catalog this product came from — V3 `{ variantId }`, V1 `{ options: {…} }`.
|
|
64
|
+
*
|
|
65
|
+
* `undefined` for a product with no options at all, which is what the cart wants
|
|
66
|
+
* (the line needs no `options` object).
|
|
67
|
+
*
|
|
68
|
+
* THROWS on V3 when the selection matches no variant, rather than returning a
|
|
69
|
+
* payload that adds an un-fulfillable line. The two ways to get here are a
|
|
70
|
+
* selection that is still incomplete (guard with `isSelectionComplete`) and a read
|
|
71
|
+
* whose `variantsInfo` did not come back — both are the caller's to fix, and both
|
|
72
|
+
* are invisible if this returns a plausible-looking payload instead.
|
|
73
|
+
*/
|
|
74
|
+
export declare function cartOptionsPayload(product: StoreProduct | undefined, options: StoreOption[], selection: StoreOptionSelection): Record<string, unknown> | undefined;
|
|
@@ -577,6 +577,131 @@ function plainText(value) {
|
|
|
577
577
|
return (value || "").replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
+
// ../../stdlib/wix-sdk/stores-v1/src/options.ts
|
|
581
|
+
function str(v) {
|
|
582
|
+
return typeof v === "string" ? v.trim() : "";
|
|
583
|
+
}
|
|
584
|
+
function choiceImage(raw, size) {
|
|
585
|
+
const m = raw;
|
|
586
|
+
const slot = m?.mainMedia ?? m?.items?.[0] ?? raw;
|
|
587
|
+
return slot ? mediaSlotUrl(slot, size) : "";
|
|
588
|
+
}
|
|
589
|
+
function hex(raw) {
|
|
590
|
+
const v = str(raw);
|
|
591
|
+
return /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(v) ? v.toLowerCase() : "";
|
|
592
|
+
}
|
|
593
|
+
function v1Choices(raw, size) {
|
|
594
|
+
const out = [];
|
|
595
|
+
for (const c of Array.isArray(raw) ? raw : []) {
|
|
596
|
+
const o = c;
|
|
597
|
+
if (o.visible === false) continue;
|
|
598
|
+
const label = str(o.description) || str(o.value);
|
|
599
|
+
if (!label || out.some((x) => x.id === label)) continue;
|
|
600
|
+
out.push({
|
|
601
|
+
id: label,
|
|
602
|
+
label,
|
|
603
|
+
inStock: o.inStock !== false,
|
|
604
|
+
colorCode: hex(o.value),
|
|
605
|
+
image: choiceImage(o.media, size)
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
return out;
|
|
609
|
+
}
|
|
610
|
+
function v3Choices(raw, size) {
|
|
611
|
+
const settings = raw;
|
|
612
|
+
const out = [];
|
|
613
|
+
for (const c of Array.isArray(settings?.choices) ? settings.choices : []) {
|
|
614
|
+
const o = c;
|
|
615
|
+
if (o.visible === false) continue;
|
|
616
|
+
const label = str(o.name) || str(o.key);
|
|
617
|
+
const id = str(o.choiceId);
|
|
618
|
+
if (!id || !label || out.some((x) => x.id === id)) continue;
|
|
619
|
+
const linked = Array.isArray(o.linkedMedia) ? o.linkedMedia[0] : void 0;
|
|
620
|
+
out.push({
|
|
621
|
+
id,
|
|
622
|
+
label,
|
|
623
|
+
inStock: o.inStock !== false,
|
|
624
|
+
colorCode: hex(o.colorCode) || hex(o.value?.colorCode),
|
|
625
|
+
image: choiceImage(o.displayImage ?? linked, size)
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
return out;
|
|
629
|
+
}
|
|
630
|
+
function kindOf(raw) {
|
|
631
|
+
const v = str(raw).toUpperCase();
|
|
632
|
+
return v.includes("COLOR") || v.includes("COLOUR") || v === "SWATCH_CHOICES" ? "color" : "list";
|
|
633
|
+
}
|
|
634
|
+
function productOptions(product, size = WIX_LIST_IMAGE) {
|
|
635
|
+
const p = product;
|
|
636
|
+
const out = [];
|
|
637
|
+
for (const raw of Array.isArray(p?.productOptions) ? p.productOptions : []) {
|
|
638
|
+
const o = raw;
|
|
639
|
+
const name = str(o.name);
|
|
640
|
+
const choices = v1Choices(o.choices, size);
|
|
641
|
+
if (name) out.push({ id: name, name, kind: kindOf(o.optionType), choices });
|
|
642
|
+
}
|
|
643
|
+
if (out.length) return out;
|
|
644
|
+
for (const raw of Array.isArray(p?.options) ? p.options : []) {
|
|
645
|
+
const o = raw;
|
|
646
|
+
const name = str(o.name);
|
|
647
|
+
const id = str(o.id) || name;
|
|
648
|
+
const choices = v3Choices(o.choicesSettings, size);
|
|
649
|
+
if (name) out.push({ id, name, kind: kindOf(o.optionRenderType), choices });
|
|
650
|
+
}
|
|
651
|
+
return out;
|
|
652
|
+
}
|
|
653
|
+
function defaultChoice(option) {
|
|
654
|
+
return option.choices.length === 1 ? option.choices[0].id : "";
|
|
655
|
+
}
|
|
656
|
+
function defaultSelection(options) {
|
|
657
|
+
const out = {};
|
|
658
|
+
for (const o of options) {
|
|
659
|
+
const choice = defaultChoice(o);
|
|
660
|
+
if (choice) out[o.id] = choice;
|
|
661
|
+
}
|
|
662
|
+
return out;
|
|
663
|
+
}
|
|
664
|
+
function isSelectionComplete(options, selection) {
|
|
665
|
+
return options.every((o) => !!selection[o.id]);
|
|
666
|
+
}
|
|
667
|
+
function selectionSummary(options, selection) {
|
|
668
|
+
return options.map((o) => o.choices.find((c) => c.id === selection[o.id])?.label ?? "").filter(Boolean).join(" \xB7 ");
|
|
669
|
+
}
|
|
670
|
+
function isV3(p) {
|
|
671
|
+
return Array.isArray(p.options) || !!p.variantsInfo;
|
|
672
|
+
}
|
|
673
|
+
function resolveVariantId(product, selection) {
|
|
674
|
+
const p = product;
|
|
675
|
+
const variants = p?.variantsInfo?.variants ?? [];
|
|
676
|
+
const want = Object.entries(selection).filter(([, choice]) => !!choice);
|
|
677
|
+
for (const v of variants) {
|
|
678
|
+
if (v.visible === false) continue;
|
|
679
|
+
const pairs = (v.choices ?? []).map((c) => [str(c.optionChoiceIds?.optionId), str(c.optionChoiceIds?.choiceId)]);
|
|
680
|
+
if (pairs.length !== want.length) continue;
|
|
681
|
+
if (want.every(([optionId, choiceId]) => pairs.some(([o, c]) => o === optionId && c === choiceId))) {
|
|
682
|
+
return str(v.id);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return "";
|
|
686
|
+
}
|
|
687
|
+
function cartOptionsPayload(product, options, selection) {
|
|
688
|
+
const p = product ?? {};
|
|
689
|
+
if (isV3(p)) {
|
|
690
|
+
const variantId = resolveVariantId(product, selection);
|
|
691
|
+
if (variantId) return { variantId };
|
|
692
|
+
if (options.length === 0) return void 0;
|
|
693
|
+
throw new Error(
|
|
694
|
+
"cartOptionsPayload: no Catalog V3 variant matches the chosen options \u2014 check every option group has a choice (isSelectionComplete) and that the product was read with its variantsInfo."
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
const picked = {};
|
|
698
|
+
for (const o of options) {
|
|
699
|
+
const choice = selection[o.id];
|
|
700
|
+
if (choice) picked[o.name] = choice;
|
|
701
|
+
}
|
|
702
|
+
return Object.keys(picked).length ? { options: picked } : void 0;
|
|
703
|
+
}
|
|
704
|
+
|
|
580
705
|
// ../../stdlib/wix-sdk/stores-v1/src/extensions.ts
|
|
581
706
|
function queryProducts(req = {}) {
|
|
582
707
|
return readWithCatalogFallback(async (v) => {
|
|
@@ -685,21 +810,28 @@ export {
|
|
|
685
810
|
WIX_DETAIL_IMAGE,
|
|
686
811
|
WIX_LIST_IMAGE,
|
|
687
812
|
addProductMedia,
|
|
813
|
+
cartOptionsPayload,
|
|
688
814
|
createProduct,
|
|
815
|
+
defaultChoice,
|
|
816
|
+
defaultSelection,
|
|
689
817
|
deleteProduct,
|
|
690
818
|
forgetCatalogVersion2 as forgetCatalogVersion,
|
|
691
819
|
getProduct,
|
|
692
820
|
getStoreProduct,
|
|
821
|
+
isSelectionComplete,
|
|
693
822
|
isUnsizedWixMedia,
|
|
694
823
|
mediaSlotUrl,
|
|
695
824
|
plainText,
|
|
696
825
|
productGallery,
|
|
697
826
|
productImage,
|
|
827
|
+
productOptions,
|
|
698
828
|
productPrice,
|
|
699
829
|
queryInventory,
|
|
700
830
|
queryProducts,
|
|
701
831
|
queryStoreProducts,
|
|
832
|
+
resolveVariantId,
|
|
702
833
|
searchStoreProducts,
|
|
834
|
+
selectionSummary,
|
|
703
835
|
updateInventory,
|
|
704
836
|
updateProduct,
|
|
705
837
|
wixCall,
|