@jay-framework/wix-stores 0.19.7 → 0.21.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/README.md +14 -12
- package/agent-kit/aiditor/add-menu.template.yaml +109 -0
- package/agent-kit/aiditor/thumbnails/wix-stores/category-list.svg +12 -0
- package/agent-kit/aiditor/thumbnails/wix-stores/category-products.svg +15 -0
- package/agent-kit/aiditor/thumbnails/wix-stores/product-page.svg +12 -0
- package/agent-kit/aiditor/thumbnails/wix-stores/product-search.svg +17 -0
- package/agent-kit/aiditor/thumbnails/wix-stores/related-products.svg +15 -0
- package/agent-kit/designer/related-products.md +123 -0
- package/dist/agent-kit/aiditor/add-menu.template.yaml +54 -12
- package/dist/agent-kit/aiditor/thumbnails/wix-stores/category-list.svg +12 -0
- package/dist/agent-kit/aiditor/thumbnails/wix-stores/category-products.svg +15 -0
- package/dist/agent-kit/aiditor/thumbnails/wix-stores/product-page.svg +12 -0
- package/dist/agent-kit/aiditor/thumbnails/wix-stores/product-search.svg +17 -0
- package/dist/agent-kit/aiditor/thumbnails/wix-stores/related-products.svg +15 -0
- package/dist/index.client.js +130 -14
- package/dist/index.d.ts +38 -10
- package/dist/index.js +433 -135
- package/package.json +18 -21
package/dist/index.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { WIX_CART_CONTEXT, WIX_CART_SERVICE, cartIndicator, cartPage, provideWixCartContext, provideWixCartService } from "@jay-framework/wix-cart";
|
|
2
2
|
import { createJayService, makeJayQuery, ActionError, RenderPipeline, makeJayStackComponent, makeJayInit, makeContractGenerator } from "@jay-framework/fullstack-component";
|
|
3
|
-
import { customizationsV3, inventoryItemsV3, productsV3 } from "@wix/stores";
|
|
4
|
-
import { categories } from "@wix/categories";
|
|
5
3
|
import { registerService, getService } from "@jay-framework/stack-server-runtime";
|
|
6
|
-
import {
|
|
4
|
+
import { wixFetch, WIX_CLIENT_SERVICE } from "@jay-framework/wix-server-client";
|
|
7
5
|
import { createJayContext } from "@jay-framework/runtime";
|
|
8
6
|
import "@jay-framework/component";
|
|
9
|
-
import { WIX_CLIENT_SERVICE } from "@jay-framework/wix-server-client";
|
|
10
7
|
import * as fs from "fs";
|
|
11
8
|
import * as path from "path";
|
|
12
9
|
import * as yaml from "js-yaml";
|
|
@@ -25,48 +22,72 @@ var CurrentSort = /* @__PURE__ */ ((CurrentSort2) => {
|
|
|
25
22
|
CurrentSort2[CurrentSort2["nameDesc"] = 5] = "nameDesc";
|
|
26
23
|
return CurrentSort2;
|
|
27
24
|
})(CurrentSort || {});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!
|
|
36
|
-
|
|
25
|
+
function normalizeCategory(cat) {
|
|
26
|
+
if (!cat) return cat;
|
|
27
|
+
const normalized = { ...cat };
|
|
28
|
+
if (normalized.id && !normalized._id) {
|
|
29
|
+
normalized._id = normalized.id;
|
|
30
|
+
}
|
|
31
|
+
const parentCategory = normalized.parentCategory;
|
|
32
|
+
if (parentCategory?.id && !parentCategory?._id) {
|
|
33
|
+
normalized.parentCategory = { ...parentCategory, _id: parentCategory.id };
|
|
34
|
+
}
|
|
35
|
+
return normalized;
|
|
36
|
+
}
|
|
37
|
+
async function queryCategories(client, options) {
|
|
38
|
+
const result = await wixFetch(
|
|
39
|
+
client,
|
|
40
|
+
"/categories/v1/categories/query",
|
|
41
|
+
{
|
|
42
|
+
method: "POST",
|
|
43
|
+
body: {
|
|
44
|
+
query: {
|
|
45
|
+
filter: options?.filter,
|
|
46
|
+
sort: options?.sort,
|
|
47
|
+
cursorPaging: options?.cursorPaging || { limit: 100 }
|
|
48
|
+
},
|
|
49
|
+
treeReference: options?.treeReference || { appNamespace: "@wix/stores" }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
if (result.categories) {
|
|
54
|
+
result.categories = result.categories.map(
|
|
55
|
+
(c) => normalizeCategory(c)
|
|
56
|
+
);
|
|
37
57
|
}
|
|
38
|
-
return
|
|
58
|
+
return result;
|
|
39
59
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
async function queryCustomizations(client, options) {
|
|
61
|
+
return wixFetch(client, "/stores/v3/customizations/query", {
|
|
62
|
+
method: "POST",
|
|
63
|
+
body: {
|
|
64
|
+
query: {
|
|
65
|
+
filter: options?.filter,
|
|
66
|
+
paging: options?.paging
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
45
70
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
71
|
+
async function querySchemas(client, options) {
|
|
72
|
+
const namespace = options?.filter?.namespace || "";
|
|
73
|
+
const params = namespace ? `?fqdn=${encodeURIComponent(namespace)}` : "";
|
|
74
|
+
return wixFetch(client, `/schema-service/v1/schemas${params}`, {
|
|
75
|
+
method: "GET"
|
|
76
|
+
});
|
|
51
77
|
}
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
return instances.customizationsV3ClientInstance;
|
|
78
|
+
async function getAllProductsCategory(client) {
|
|
79
|
+
return wixFetch(client, "/stores/v3/all-products-category", {
|
|
80
|
+
method: "GET"
|
|
81
|
+
});
|
|
57
82
|
}
|
|
58
83
|
const WIX_STORES_SERVICE_MARKER = createJayService("Wix Store Service");
|
|
59
84
|
function provideWixStoresService(wixClient, options) {
|
|
60
85
|
let cachedTree = null;
|
|
61
86
|
let cachedCustomizations = null;
|
|
62
87
|
let cachedExtensionSchemas = null;
|
|
63
|
-
|
|
64
|
-
const customizationsClient = getCustomizationsV3Client(wixClient);
|
|
88
|
+
let cachedAllProductsCategoryId;
|
|
65
89
|
const service = {
|
|
66
|
-
|
|
67
|
-
categories: categoriesClient,
|
|
68
|
-
inventory: getInventoryClient(wixClient),
|
|
69
|
-
customizations: customizationsClient,
|
|
90
|
+
wixClient,
|
|
70
91
|
urls: options?.urls ?? { product: "/products/{slug}", category: null },
|
|
71
92
|
defaultCategory: options?.defaultCategory ?? null,
|
|
72
93
|
async getCategoryTree() {
|
|
@@ -91,11 +112,16 @@ function provideWixStoresService(wixClient, options) {
|
|
|
91
112
|
}
|
|
92
113
|
}
|
|
93
114
|
};
|
|
94
|
-
let
|
|
95
|
-
|
|
96
|
-
while (
|
|
97
|
-
result = await
|
|
98
|
-
|
|
115
|
+
let cursor;
|
|
116
|
+
let hasMore = true;
|
|
117
|
+
while (hasMore) {
|
|
118
|
+
const result = await queryCategories(
|
|
119
|
+
wixClient,
|
|
120
|
+
cursor ? { cursorPaging: { cursor } } : { filter: { visible: true }, cursorPaging: { limit: 100 } }
|
|
121
|
+
);
|
|
122
|
+
processItems(result.categories || []);
|
|
123
|
+
cursor = result.pagingMetadata?.cursors?.next;
|
|
124
|
+
hasMore = !!cursor;
|
|
99
125
|
}
|
|
100
126
|
} catch (error) {
|
|
101
127
|
console.error("[wix-stores] Failed to build category tree:", error);
|
|
@@ -106,8 +132,11 @@ function provideWixStoresService(wixClient, options) {
|
|
|
106
132
|
async getCustomizations() {
|
|
107
133
|
if (cachedCustomizations) return cachedCustomizations;
|
|
108
134
|
try {
|
|
109
|
-
const result = await
|
|
110
|
-
|
|
135
|
+
const result = await queryCustomizations(wixClient, {
|
|
136
|
+
filter: { customizationType: "PRODUCT_OPTION" },
|
|
137
|
+
paging: { limit: 100 }
|
|
138
|
+
});
|
|
139
|
+
cachedCustomizations = result.customizations || [];
|
|
111
140
|
} catch (error) {
|
|
112
141
|
console.error("[wix-stores] Failed to load customizations:", error);
|
|
113
142
|
cachedCustomizations = [];
|
|
@@ -117,10 +146,9 @@ function provideWixStoresService(wixClient, options) {
|
|
|
117
146
|
async getDataExtensionSchemas() {
|
|
118
147
|
if (cachedExtensionSchemas) return cachedExtensionSchemas;
|
|
119
148
|
try {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
);
|
|
149
|
+
const result = await querySchemas(wixClient, {
|
|
150
|
+
filter: { namespace: "wix.stores.catalog.v3.product" }
|
|
151
|
+
});
|
|
124
152
|
cachedExtensionSchemas = result?.dataExtensionSchemas ?? [];
|
|
125
153
|
const fieldCount = cachedExtensionSchemas.reduce(
|
|
126
154
|
(n, s) => n + Object.keys(s.jsonSchema?.properties ?? {}).length,
|
|
@@ -134,6 +162,17 @@ function provideWixStoresService(wixClient, options) {
|
|
|
134
162
|
cachedExtensionSchemas = [];
|
|
135
163
|
}
|
|
136
164
|
return cachedExtensionSchemas;
|
|
165
|
+
},
|
|
166
|
+
async getAllProductsCategoryId() {
|
|
167
|
+
if (cachedAllProductsCategoryId !== void 0) return cachedAllProductsCategoryId;
|
|
168
|
+
try {
|
|
169
|
+
const result = await getAllProductsCategory(wixClient);
|
|
170
|
+
cachedAllProductsCategoryId = result.categoryId ?? null;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error("[wix-stores] Failed to get All Products category:", error);
|
|
173
|
+
cachedAllProductsCategoryId = null;
|
|
174
|
+
}
|
|
175
|
+
return cachedAllProductsCategoryId;
|
|
137
176
|
}
|
|
138
177
|
};
|
|
139
178
|
registerService(WIX_STORES_SERVICE_MARKER, service);
|
|
@@ -178,6 +217,9 @@ var ChoiceType$1 = /* @__PURE__ */ ((ChoiceType2) => {
|
|
|
178
217
|
ChoiceType2[ChoiceType2["ONE_COLOR"] = 1] = "ONE_COLOR";
|
|
179
218
|
return ChoiceType2;
|
|
180
219
|
})(ChoiceType$1 || {});
|
|
220
|
+
function stripWixMediaResize(url) {
|
|
221
|
+
return url.replace(/\/v1\/(?:fit|fill|crop)\/[^/]+\/file\.\w+$/, "");
|
|
222
|
+
}
|
|
181
223
|
function parseWixMediaUrl(url) {
|
|
182
224
|
if (!url) return null;
|
|
183
225
|
const match = url.match(
|
|
@@ -214,7 +256,7 @@ function formatWixMediaUrl(_id, url, resize) {
|
|
|
214
256
|
}
|
|
215
257
|
}
|
|
216
258
|
if ((url == null ? void 0 : url.startsWith("http://")) || (url == null ? void 0 : url.startsWith("https://"))) {
|
|
217
|
-
return url;
|
|
259
|
+
return stripWixMediaResize(url) + resizeFragment;
|
|
218
260
|
}
|
|
219
261
|
if (_id) {
|
|
220
262
|
return `https://static.wixstatic.com/media/${_id}${resizeFragment}`;
|
|
@@ -456,6 +498,220 @@ function mapProductToCard(product, urls, tree) {
|
|
|
456
498
|
...mapQuickAddOptions(product)
|
|
457
499
|
};
|
|
458
500
|
}
|
|
501
|
+
function raw(value) {
|
|
502
|
+
return value;
|
|
503
|
+
}
|
|
504
|
+
function rawArray(value) {
|
|
505
|
+
return value;
|
|
506
|
+
}
|
|
507
|
+
function str(value) {
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
510
|
+
function normalizeProduct(product) {
|
|
511
|
+
if (!product) return product;
|
|
512
|
+
const normalized = { ...product };
|
|
513
|
+
if (normalized.id && !normalized._id) {
|
|
514
|
+
normalized._id = normalized.id;
|
|
515
|
+
}
|
|
516
|
+
const media = raw(normalized.media);
|
|
517
|
+
if (media?.main) {
|
|
518
|
+
const main = raw(media.main);
|
|
519
|
+
const mainImage = raw(main.image);
|
|
520
|
+
normalized.media = {
|
|
521
|
+
...media,
|
|
522
|
+
main: {
|
|
523
|
+
_id: main.id || main._id,
|
|
524
|
+
url: mainImage?.url || main.url,
|
|
525
|
+
altText: mainImage?.altText || main.altText,
|
|
526
|
+
mediaType: main.mediaType,
|
|
527
|
+
width: mainImage?.width,
|
|
528
|
+
height: mainImage?.height
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const updatedMedia = raw(normalized.media);
|
|
533
|
+
const itemsInfo = raw(updatedMedia?.itemsInfo);
|
|
534
|
+
if (itemsInfo?.items) {
|
|
535
|
+
itemsInfo.items = rawArray(itemsInfo.items).map((item) => {
|
|
536
|
+
const image = raw(item.image);
|
|
537
|
+
return {
|
|
538
|
+
_id: item.id || item._id,
|
|
539
|
+
url: image?.url || item.url,
|
|
540
|
+
altText: image?.altText || item.altText,
|
|
541
|
+
mediaType: item.mediaType,
|
|
542
|
+
width: image?.width,
|
|
543
|
+
height: image?.height
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
if (normalized.options) {
|
|
548
|
+
normalized.options = rawArray(normalized.options).map((opt) => {
|
|
549
|
+
const choicesSettings = raw(opt.choicesSettings);
|
|
550
|
+
return {
|
|
551
|
+
...opt,
|
|
552
|
+
_id: opt.id || opt._id,
|
|
553
|
+
choices: choicesSettings?.choices ? rawArray(choicesSettings.choices).map((c) => {
|
|
554
|
+
const linkedMedia = c.linkedMedia;
|
|
555
|
+
const firstMedia = linkedMedia?.[0];
|
|
556
|
+
const firstMediaImage = firstMedia ? raw(firstMedia.image) : void 0;
|
|
557
|
+
return {
|
|
558
|
+
...c,
|
|
559
|
+
_id: c.choiceId || c._id,
|
|
560
|
+
value: c.name || c.value,
|
|
561
|
+
media: firstMedia ? {
|
|
562
|
+
_id: firstMedia.id,
|
|
563
|
+
url: str(firstMediaImage?.url) || firstMedia.url,
|
|
564
|
+
mediaType: firstMedia.mediaType
|
|
565
|
+
} : void 0
|
|
566
|
+
};
|
|
567
|
+
}) : void 0
|
|
568
|
+
};
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
if (normalized.modifiers) {
|
|
572
|
+
normalized.modifiers = rawArray(normalized.modifiers).map((mod) => {
|
|
573
|
+
const choicesSettings = raw(mod.choicesSettings);
|
|
574
|
+
return {
|
|
575
|
+
...mod,
|
|
576
|
+
_id: mod.id || mod._id,
|
|
577
|
+
choices: choicesSettings?.choices ? rawArray(choicesSettings.choices).map((c) => ({
|
|
578
|
+
...c,
|
|
579
|
+
_id: c.choiceId || c._id,
|
|
580
|
+
value: c.name || c.value
|
|
581
|
+
})) : void 0
|
|
582
|
+
};
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
if (normalized.infoSections) {
|
|
586
|
+
normalized.infoSections = rawArray(normalized.infoSections).map((s) => ({
|
|
587
|
+
...s,
|
|
588
|
+
_id: s.id || s._id
|
|
589
|
+
}));
|
|
590
|
+
}
|
|
591
|
+
const variantsInfo = raw(normalized.variantsInfo);
|
|
592
|
+
if (variantsInfo?.variants) {
|
|
593
|
+
variantsInfo.variants = rawArray(variantsInfo.variants).map((v) => ({
|
|
594
|
+
...v,
|
|
595
|
+
_id: v.id || v._id
|
|
596
|
+
}));
|
|
597
|
+
}
|
|
598
|
+
if (normalized.ribbon) {
|
|
599
|
+
const ribbon = raw(normalized.ribbon);
|
|
600
|
+
normalized.ribbon = {
|
|
601
|
+
...ribbon,
|
|
602
|
+
_id: ribbon.id || ribbon._id
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
return normalized;
|
|
606
|
+
}
|
|
607
|
+
function normalizeProducts(products) {
|
|
608
|
+
return products.map(normalizeProduct);
|
|
609
|
+
}
|
|
610
|
+
async function queryProducts(client, query) {
|
|
611
|
+
const result = await wixFetch(client, "/stores/v3/products/query", {
|
|
612
|
+
method: "POST",
|
|
613
|
+
body: {
|
|
614
|
+
query: {
|
|
615
|
+
filter: query.filter,
|
|
616
|
+
sort: query.sort,
|
|
617
|
+
paging: query.paging
|
|
618
|
+
},
|
|
619
|
+
...query.fields ? { fields: query.fields } : {}
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
if (result.products) {
|
|
623
|
+
result.products = normalizeProducts(result.products);
|
|
624
|
+
}
|
|
625
|
+
return result;
|
|
626
|
+
}
|
|
627
|
+
async function searchProducts$1(client, search, options) {
|
|
628
|
+
const result = await wixFetch(client, "/stores/v3/products/search", {
|
|
629
|
+
method: "POST",
|
|
630
|
+
body: {
|
|
631
|
+
search,
|
|
632
|
+
...options?.fields ? { fields: options.fields } : {}
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
if (result.products) {
|
|
636
|
+
result.products = normalizeProducts(result.products);
|
|
637
|
+
}
|
|
638
|
+
return result;
|
|
639
|
+
}
|
|
640
|
+
const searchProducts$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
641
|
+
__proto__: null,
|
|
642
|
+
searchProducts: searchProducts$1
|
|
643
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
644
|
+
async function getProduct(client, productId, options) {
|
|
645
|
+
const params = new URLSearchParams();
|
|
646
|
+
{
|
|
647
|
+
params.set("includeMerchantSpecificData", "true");
|
|
648
|
+
}
|
|
649
|
+
if (options?.fields) {
|
|
650
|
+
for (const f of options.fields) {
|
|
651
|
+
params.append("fields", f);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const qs = params.toString();
|
|
655
|
+
const result = await wixFetch(
|
|
656
|
+
client,
|
|
657
|
+
`/stores/v3/products/${productId}${qs ? "?" + qs : ""}`,
|
|
658
|
+
{
|
|
659
|
+
method: "GET"
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
if (result.product) {
|
|
663
|
+
result.product = normalizeProduct(result.product);
|
|
664
|
+
}
|
|
665
|
+
return result;
|
|
666
|
+
}
|
|
667
|
+
async function getProductBySlug$1(client, slug, options) {
|
|
668
|
+
const params = new URLSearchParams();
|
|
669
|
+
if (options?.includeMerchantSpecificData) {
|
|
670
|
+
params.set("includeMerchantSpecificData", "true");
|
|
671
|
+
}
|
|
672
|
+
if (options?.fields) {
|
|
673
|
+
for (const f of options.fields) {
|
|
674
|
+
params.append("fields", f);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
const qs = params.toString();
|
|
678
|
+
const result = await wixFetch(
|
|
679
|
+
client,
|
|
680
|
+
`/stores/v3/products/slug/${slug}${qs ? "?" + qs : ""}`,
|
|
681
|
+
{
|
|
682
|
+
method: "GET"
|
|
683
|
+
}
|
|
684
|
+
);
|
|
685
|
+
if (result.product) {
|
|
686
|
+
result.product = normalizeProduct(result.product);
|
|
687
|
+
}
|
|
688
|
+
return result;
|
|
689
|
+
}
|
|
690
|
+
async function getCategory(client, categoryId) {
|
|
691
|
+
const result = await wixFetch(
|
|
692
|
+
client,
|
|
693
|
+
`/categories/v1/categories/${categoryId}`,
|
|
694
|
+
{
|
|
695
|
+
method: "GET"
|
|
696
|
+
}
|
|
697
|
+
);
|
|
698
|
+
if (result.category) {
|
|
699
|
+
const raw2 = result.category;
|
|
700
|
+
if (raw2.id && !result.category._id) {
|
|
701
|
+
result.category._id = raw2.id;
|
|
702
|
+
}
|
|
703
|
+
if (result.category.parentCategory) {
|
|
704
|
+
const rawParent = result.category.parentCategory;
|
|
705
|
+
if (rawParent.id && !result.category.parentCategory._id) {
|
|
706
|
+
result.category.parentCategory = {
|
|
707
|
+
...result.category.parentCategory,
|
|
708
|
+
_id: rawParent.id
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return result;
|
|
714
|
+
}
|
|
459
715
|
function needsCategoryInfo(wixStores) {
|
|
460
716
|
const template = wixStores.urls.product;
|
|
461
717
|
return template.includes("{category}") || template.includes("{prefix}");
|
|
@@ -630,7 +886,8 @@ const searchProducts = makeJayQuery("wixStores.searchProducts").withServices(WIX
|
|
|
630
886
|
}
|
|
631
887
|
}
|
|
632
888
|
];
|
|
633
|
-
const searchResult = await
|
|
889
|
+
const searchResult = await searchProducts$1(
|
|
890
|
+
wixStores.wixClient,
|
|
634
891
|
{
|
|
635
892
|
filter,
|
|
636
893
|
sort: sort.length > 0 ? sort : void 0,
|
|
@@ -719,7 +976,8 @@ const getProductBySlug = makeJayQuery("wixStores.getProductBySlug").withServices
|
|
|
719
976
|
"CURRENCY",
|
|
720
977
|
...needsCategoryInfo(wixStores) ? ["ALL_CATEGORIES_INFO"] : []
|
|
721
978
|
];
|
|
722
|
-
const result = await wixStores.
|
|
979
|
+
const result = await getProductBySlug$1(wixStores.wixClient, slug, {
|
|
980
|
+
includeMerchantSpecificData: true,
|
|
723
981
|
fields: [...fields]
|
|
724
982
|
});
|
|
725
983
|
const product = result.product;
|
|
@@ -737,10 +995,12 @@ const getProductBySlug = makeJayQuery("wixStores.getProductBySlug").withServices
|
|
|
737
995
|
const getVariantStock = makeJayQuery("wixStores.getVariantStock").withServices(WIX_STORES_SERVICE_MARKER).withHandler(
|
|
738
996
|
async (input, wixStores) => {
|
|
739
997
|
try {
|
|
740
|
-
const
|
|
998
|
+
const result = await getProduct(wixStores.wixClient, input.productId, {
|
|
999
|
+
includeMerchantSpecificData: true,
|
|
741
1000
|
fields: ["VARIANT_OPTION_CHOICE_NAMES"]
|
|
742
1001
|
});
|
|
743
|
-
|
|
1002
|
+
if (!result.product) return {};
|
|
1003
|
+
return buildVariantStockMap(result.product);
|
|
744
1004
|
} catch (error) {
|
|
745
1005
|
console.error("[wixStores.getVariantStock] Failed:", error);
|
|
746
1006
|
return {};
|
|
@@ -750,12 +1010,10 @@ const getVariantStock = makeJayQuery("wixStores.getVariantStock").withServices(W
|
|
|
750
1010
|
const getCategories = makeJayQuery("wixStores.getCategories").withServices(WIX_STORES_SERVICE_MARKER).withCaching({ maxAge: 3600 }).withHandler(
|
|
751
1011
|
async (_input, wixStores) => {
|
|
752
1012
|
try {
|
|
753
|
-
const result = await wixStores.
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
}).eq("visible", true).find();
|
|
758
|
-
return (result.items || []).map((cat) => ({
|
|
1013
|
+
const result = await queryCategories(wixStores.wixClient, {
|
|
1014
|
+
filter: { visible: true }
|
|
1015
|
+
});
|
|
1016
|
+
return (result.categories || []).map((cat) => ({
|
|
759
1017
|
categoryId: cat._id || "",
|
|
760
1018
|
categoryName: cat.name || ""
|
|
761
1019
|
}));
|
|
@@ -877,21 +1135,25 @@ const EMPTY_CATEGORY_HEADER = {
|
|
|
877
1135
|
breadcrumbs: [],
|
|
878
1136
|
seoData: { tags: [], settings: { preventAutoRedirect: false, keywords: [] } }
|
|
879
1137
|
};
|
|
880
|
-
async function findCategoryBySlug$1(
|
|
881
|
-
const result = await
|
|
882
|
-
|
|
1138
|
+
async function findCategoryBySlug$1(wixClient, slug) {
|
|
1139
|
+
const result = await queryCategories(wixClient, {
|
|
1140
|
+
filter: { slug, visible: true },
|
|
1141
|
+
cursorPaging: { limit: 1 }
|
|
1142
|
+
});
|
|
1143
|
+
return result.categories?.[0] ?? null;
|
|
883
1144
|
}
|
|
884
|
-
async function loadCategoryDetails(
|
|
1145
|
+
async function loadCategoryDetails(wixClient, categoryId) {
|
|
885
1146
|
try {
|
|
886
|
-
|
|
1147
|
+
const result = await getCategory(wixClient, categoryId);
|
|
1148
|
+
return result.category ?? null;
|
|
887
1149
|
} catch {
|
|
888
1150
|
return null;
|
|
889
1151
|
}
|
|
890
1152
|
}
|
|
891
1153
|
async function buildCategoryHeader(wixStoreService, category, categoryUrlTemplate) {
|
|
892
|
-
const details = await loadCategoryDetails(wixStoreService.
|
|
1154
|
+
const details = await loadCategoryDetails(wixStoreService.wixClient, category._id);
|
|
893
1155
|
const cat = details || category;
|
|
894
|
-
const imageUrl = cat.image ? formatWixMediaUrl("", cat.image) : "";
|
|
1156
|
+
const imageUrl = cat.image?.url ? formatWixMediaUrl(cat.image.id || "", cat.image.url) : "";
|
|
895
1157
|
const description = cat.description || "";
|
|
896
1158
|
const categoryTree = await wixStoreService.getCategoryTree();
|
|
897
1159
|
const breadcrumbs = [
|
|
@@ -941,13 +1203,13 @@ async function buildCategoryHeader(wixStoreService, category, categoryUrlTemplat
|
|
|
941
1203
|
seoData
|
|
942
1204
|
};
|
|
943
1205
|
if ((!description || !imageUrl) && cat.parentCategory?._id) {
|
|
944
|
-
const parent = await loadCategoryDetails(wixStoreService.
|
|
1206
|
+
const parent = await loadCategoryDetails(wixStoreService.wixClient, cat.parentCategory._id);
|
|
945
1207
|
if (parent) {
|
|
946
1208
|
if (!header.description && parent.description) {
|
|
947
1209
|
header = { ...header, description: parent.description };
|
|
948
1210
|
}
|
|
949
1211
|
if (!header.imageUrl) {
|
|
950
|
-
const parentImage = parent.image ? formatWixMediaUrl("", parent.image) : "";
|
|
1212
|
+
const parentImage = parent.image?.url ? formatWixMediaUrl(parent.image.id || "", parent.image.url) : "";
|
|
951
1213
|
if (parentImage) {
|
|
952
1214
|
header = { ...header, imageUrl: parentImage, hasImage: true };
|
|
953
1215
|
}
|
|
@@ -964,26 +1226,25 @@ async function renderSlowlyChanging$4(props, wixStores) {
|
|
|
964
1226
|
let activeCategory = null;
|
|
965
1227
|
let baseCategoryId = null;
|
|
966
1228
|
if (categorySlug) {
|
|
967
|
-
activeCategory = await findCategoryBySlug$1(wixStores.
|
|
1229
|
+
activeCategory = await findCategoryBySlug$1(wixStores.wixClient, categorySlug);
|
|
968
1230
|
baseCategoryId = activeCategory?._id ?? null;
|
|
969
1231
|
} else if (prefixSlug) {
|
|
970
|
-
activeCategory = await findCategoryBySlug$1(wixStores.
|
|
1232
|
+
activeCategory = await findCategoryBySlug$1(wixStores.wixClient, prefixSlug);
|
|
971
1233
|
baseCategoryId = activeCategory?._id ?? null;
|
|
972
1234
|
} else if (defaultCategorySlug) {
|
|
973
|
-
activeCategory = await findCategoryBySlug$1(wixStores.
|
|
1235
|
+
activeCategory = await findCategoryBySlug$1(wixStores.wixClient, defaultCategorySlug);
|
|
974
1236
|
}
|
|
975
1237
|
const tree = await wixStores.getCategoryTree();
|
|
976
1238
|
const categoryHeader = activeCategory ? await buildCategoryHeader(wixStores, activeCategory, wixStores.urls.category) : EMPTY_CATEGORY_HEADER;
|
|
1239
|
+
const allProductsCategoryId = await wixStores.getAllProductsCategoryId();
|
|
977
1240
|
return Pipeline.try(async () => {
|
|
978
|
-
|
|
979
|
-
treeReference: { appNamespace: "@wix/stores" }
|
|
980
|
-
}).eq("visible", true);
|
|
1241
|
+
const categoryFilter = { visible: true };
|
|
981
1242
|
if (baseCategoryId) {
|
|
982
|
-
|
|
1243
|
+
categoryFilter["parentCategory.id"] = baseCategoryId;
|
|
983
1244
|
}
|
|
984
1245
|
const baseCategoryIds = baseCategoryId ? [baseCategoryId] : [];
|
|
985
1246
|
const [categoriesResult, productsResult] = await Promise.all([
|
|
986
|
-
|
|
1247
|
+
queryCategories(wixStores.wixClient, { filter: categoryFilter }),
|
|
987
1248
|
searchProducts({
|
|
988
1249
|
query: "",
|
|
989
1250
|
filters: {
|
|
@@ -992,14 +1253,15 @@ async function renderSlowlyChanging$4(props, wixStores) {
|
|
|
992
1253
|
pageSize: PAGE_SIZE
|
|
993
1254
|
})
|
|
994
1255
|
]);
|
|
1256
|
+
const categories = (categoriesResult.categories || []).filter((cat) => cat._id !== allProductsCategoryId);
|
|
995
1257
|
return {
|
|
996
|
-
categories
|
|
1258
|
+
categories,
|
|
997
1259
|
productsResult
|
|
998
1260
|
};
|
|
999
1261
|
}).recover((error) => {
|
|
1000
1262
|
return handleError(error);
|
|
1001
|
-
}).toPhaseOutput(({ categories
|
|
1002
|
-
const categoryInfos =
|
|
1263
|
+
}).toPhaseOutput(({ categories, productsResult }) => {
|
|
1264
|
+
const categoryInfos = categories.map((cat) => ({
|
|
1003
1265
|
categoryId: cat._id || "",
|
|
1004
1266
|
categoryName: cat.name || "",
|
|
1005
1267
|
categorySlug: cat.slug || "",
|
|
@@ -1156,20 +1418,21 @@ async function* loadSearchParams([wixStores]) {
|
|
|
1156
1418
|
if (rootSlug) {
|
|
1157
1419
|
params.push({ prefix: rootSlug, category: node.slug });
|
|
1158
1420
|
} else {
|
|
1159
|
-
params.push({
|
|
1421
|
+
params.push({ category: node.slug });
|
|
1160
1422
|
}
|
|
1161
1423
|
for (const child of node.children) {
|
|
1162
1424
|
collectParams(child, rootSlug ?? node.slug);
|
|
1163
1425
|
}
|
|
1164
1426
|
};
|
|
1427
|
+
const allProductsCategoryId = await wixStores.getAllProductsCategoryId();
|
|
1165
1428
|
const allCategories = [];
|
|
1166
|
-
let
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1429
|
+
let cursor;
|
|
1430
|
+
let hasMore = true;
|
|
1431
|
+
while (hasMore) {
|
|
1432
|
+
const result = await queryCategories(wixStores.wixClient, cursor ? { cursorPaging: { cursor } } : { filter: { visible: true }, cursorPaging: { limit: 100 } });
|
|
1433
|
+
allCategories.push(...result.categories || []);
|
|
1434
|
+
cursor = result.pagingMetadata?.cursors?.next;
|
|
1435
|
+
hasMore = !!cursor;
|
|
1173
1436
|
}
|
|
1174
1437
|
const nodeById = /* @__PURE__ */ new Map();
|
|
1175
1438
|
const roots = [];
|
|
@@ -1177,6 +1440,8 @@ async function* loadSearchParams([wixStores]) {
|
|
|
1177
1440
|
for (const cat of allCategories) {
|
|
1178
1441
|
if (!cat._id)
|
|
1179
1442
|
continue;
|
|
1443
|
+
if (cat._id === allProductsCategoryId)
|
|
1444
|
+
continue;
|
|
1180
1445
|
const node = {
|
|
1181
1446
|
slug: cat.slug || "",
|
|
1182
1447
|
itemCount: cat.itemCounter ?? 0,
|
|
@@ -1206,7 +1471,7 @@ async function* loadSearchParams([wixStores]) {
|
|
|
1206
1471
|
for (const root of roots) {
|
|
1207
1472
|
sumItems(root);
|
|
1208
1473
|
}
|
|
1209
|
-
const params = [];
|
|
1474
|
+
const params = [{}];
|
|
1210
1475
|
for (const root of roots) {
|
|
1211
1476
|
collectParams(root, null);
|
|
1212
1477
|
}
|
|
@@ -1259,9 +1524,9 @@ var MediaType = /* @__PURE__ */ ((MediaType2) => {
|
|
|
1259
1524
|
return MediaType2;
|
|
1260
1525
|
})(MediaType || {});
|
|
1261
1526
|
function mapExtendedFields(product) {
|
|
1262
|
-
const
|
|
1527
|
+
const raw2 = product.extendedFields?.namespaces?.["_user_fields"] ?? {};
|
|
1263
1528
|
const result = {};
|
|
1264
|
-
for (const [key, value] of Object.entries(
|
|
1529
|
+
for (const [key, value] of Object.entries(raw2)) {
|
|
1265
1530
|
if (Array.isArray(value)) {
|
|
1266
1531
|
result[key] = value.map((item, i) => typeof item === "object" && item !== null ? { ...item, _index: i } : { value: item, _index: i });
|
|
1267
1532
|
} else {
|
|
@@ -1278,7 +1543,7 @@ async function* loadProductParams([wixStores]) {
|
|
|
1278
1543
|
const fields = needsCategories ? ["ALL_CATEGORIES_INFO"] : [];
|
|
1279
1544
|
try {
|
|
1280
1545
|
const tree = needsCategories ? await wixStores.getCategoryTree() : null;
|
|
1281
|
-
let result = await wixStores.
|
|
1546
|
+
let result = await queryProducts(wixStores.wixClient, { fields: [...fields] });
|
|
1282
1547
|
const mapProduct = (product) => {
|
|
1283
1548
|
const slug = product.slug ?? "";
|
|
1284
1549
|
if (!slug)
|
|
@@ -1294,11 +1559,7 @@ async function* loadProductParams([wixStores]) {
|
|
|
1294
1559
|
}
|
|
1295
1560
|
return params;
|
|
1296
1561
|
};
|
|
1297
|
-
yield result.
|
|
1298
|
-
while (result.hasNext()) {
|
|
1299
|
-
result = await result.next();
|
|
1300
|
-
yield result.items.map(mapProduct).filter((p) => p !== null);
|
|
1301
|
-
}
|
|
1562
|
+
yield (result.products || []).map(mapProduct).filter((p) => p !== null);
|
|
1302
1563
|
} catch (error) {
|
|
1303
1564
|
console.error("Failed to load product slugs:", error);
|
|
1304
1565
|
yield [];
|
|
@@ -1464,7 +1725,8 @@ async function renderSlowlyChanging$3(props, wixStores) {
|
|
|
1464
1725
|
...needsCategories ? ["ALL_CATEGORIES_INFO"] : []
|
|
1465
1726
|
];
|
|
1466
1727
|
const [response, tree] = await Promise.all([
|
|
1467
|
-
wixStores.
|
|
1728
|
+
getProductBySlug$1(wixStores.wixClient, props.slug, {
|
|
1729
|
+
includeMerchantSpecificData: true,
|
|
1468
1730
|
fields: [...fields]
|
|
1469
1731
|
}),
|
|
1470
1732
|
wixStores.getCategoryTree()
|
|
@@ -1583,15 +1845,18 @@ async function renderSlowlyChanging$2(props, wixStores) {
|
|
|
1583
1845
|
return { categoryName: "", products: [] };
|
|
1584
1846
|
}
|
|
1585
1847
|
const [categoryResult, searchResult] = await Promise.all([
|
|
1586
|
-
|
|
1848
|
+
queryCategories(wixStores.wixClient, {
|
|
1849
|
+
filter: { _id: categoryId },
|
|
1850
|
+
cursorPaging: { limit: 1 }
|
|
1851
|
+
}).catch(() => null),
|
|
1587
1852
|
searchProducts({
|
|
1588
1853
|
query: "",
|
|
1589
1854
|
filters: { categoryIds: [categoryId] },
|
|
1590
1855
|
pageSize: limit + 1
|
|
1591
1856
|
})
|
|
1592
1857
|
]);
|
|
1593
|
-
if (categoryResult?.
|
|
1594
|
-
categoryName = categoryResult.
|
|
1858
|
+
if (categoryResult?.categories?.[0]?.name) {
|
|
1859
|
+
categoryName = categoryResult.categories[0].name;
|
|
1595
1860
|
}
|
|
1596
1861
|
const products = searchResult.products.filter((p) => p._id !== props.productId).slice(0, limit);
|
|
1597
1862
|
return { categoryName, products };
|
|
@@ -1699,34 +1964,33 @@ async function renderFastChanging(_props, carryForward, _wixStores) {
|
|
|
1699
1964
|
});
|
|
1700
1965
|
}
|
|
1701
1966
|
const productSpotlight = makeJayStackComponent().withProps().withServices(WIX_STORES_SERVICE_MARKER).withSlowlyRender(renderSlowlyChanging$1).withFastRender(renderFastChanging);
|
|
1702
|
-
async function findCategoryBySlug(
|
|
1703
|
-
const result = await
|
|
1704
|
-
|
|
1967
|
+
async function findCategoryBySlug(wixClient, slug) {
|
|
1968
|
+
const result = await queryCategories(wixClient, {
|
|
1969
|
+
filter: { slug, visible: true },
|
|
1970
|
+
cursorPaging: { limit: 1 }
|
|
1971
|
+
});
|
|
1972
|
+
return result.categories?.[0] ?? null;
|
|
1705
1973
|
}
|
|
1706
1974
|
async function renderSlowlyChanging(props, wixStores) {
|
|
1707
1975
|
const Pipeline = RenderPipeline.for();
|
|
1708
1976
|
const parentCategorySlug = props.parentCategory ?? wixStores.defaultCategory;
|
|
1709
1977
|
let parentCategoryId = null;
|
|
1710
1978
|
if (parentCategorySlug) {
|
|
1711
|
-
const parentCat = await findCategoryBySlug(wixStores.
|
|
1979
|
+
const parentCat = await findCategoryBySlug(wixStores.wixClient, parentCategorySlug);
|
|
1712
1980
|
parentCategoryId = parentCat?._id ?? null;
|
|
1713
1981
|
}
|
|
1714
1982
|
return Pipeline.try(async () => {
|
|
1715
|
-
|
|
1716
|
-
treeReference: {
|
|
1717
|
-
appNamespace: "@wix/stores"
|
|
1718
|
-
}
|
|
1719
|
-
}).eq("visible", true);
|
|
1983
|
+
const filter = { visible: true };
|
|
1720
1984
|
if (parentCategoryId) {
|
|
1721
|
-
|
|
1985
|
+
filter["parentCategory.id"] = parentCategoryId;
|
|
1722
1986
|
}
|
|
1723
|
-
const result = await
|
|
1724
|
-
return result.
|
|
1987
|
+
const result = await queryCategories(wixStores.wixClient, { filter });
|
|
1988
|
+
return result.categories || [];
|
|
1725
1989
|
}).recover((error) => {
|
|
1726
1990
|
console.error("Failed to load categories:", error);
|
|
1727
1991
|
return Pipeline.ok([]);
|
|
1728
|
-
}).toPhaseOutput((
|
|
1729
|
-
const categoryItems =
|
|
1992
|
+
}).toPhaseOutput((categories) => {
|
|
1993
|
+
const categoryItems = categories.map((cat) => ({
|
|
1730
1994
|
_id: cat._id || "",
|
|
1731
1995
|
name: cat.name || "",
|
|
1732
1996
|
slug: cat.slug || "",
|
|
@@ -1756,17 +2020,17 @@ function loadWixStoresConfig(projectRoot) {
|
|
|
1756
2020
|
return defaults;
|
|
1757
2021
|
}
|
|
1758
2022
|
const fileContents = fs.readFileSync(configPath, "utf8");
|
|
1759
|
-
const
|
|
1760
|
-
if (!
|
|
2023
|
+
const raw2 = yaml.load(fileContents);
|
|
2024
|
+
if (!raw2) {
|
|
1761
2025
|
return defaults;
|
|
1762
2026
|
}
|
|
1763
|
-
const urls =
|
|
2027
|
+
const urls = raw2.urls;
|
|
1764
2028
|
return {
|
|
1765
2029
|
urls: {
|
|
1766
2030
|
product: typeof urls?.product === "string" ? urls.product : defaults.urls.product,
|
|
1767
2031
|
category: typeof urls?.category === "string" ? urls.category : null
|
|
1768
2032
|
},
|
|
1769
|
-
defaultCategory: typeof
|
|
2033
|
+
defaultCategory: typeof raw2.defaultCategory === "string" ? raw2.defaultCategory : null
|
|
1770
2034
|
};
|
|
1771
2035
|
}
|
|
1772
2036
|
const init = makeJayInit().withServer(async () => {
|
|
@@ -1787,6 +2051,9 @@ const init = makeJayInit().withServer(async () => {
|
|
|
1787
2051
|
enableClientSearch: true
|
|
1788
2052
|
};
|
|
1789
2053
|
});
|
|
2054
|
+
function wixStoresStaticContractPath(contractName) {
|
|
2055
|
+
return `node_modules/@jay-framework/wix-stores/dist/contracts/${contractName}.jay-contract`;
|
|
2056
|
+
}
|
|
1790
2057
|
function flattenCategoryTree(roots, parentNames = [], parentSlugs = [], rootSlug = null, rootName = null, rootHasChildren = null) {
|
|
1791
2058
|
const entries = [];
|
|
1792
2059
|
for (const node of roots) {
|
|
@@ -1899,9 +2166,10 @@ function buildCategoryPrompt(config, entry) {
|
|
|
1899
2166
|
` category-products — pass categorySlug="${node.slug}" to show products from this category; optionally pass productId to exclude a product`,
|
|
1900
2167
|
"",
|
|
1901
2168
|
"Contracts:",
|
|
1902
|
-
"
|
|
1903
|
-
"
|
|
1904
|
-
"
|
|
2169
|
+
` ${wixStoresStaticContractPath("product-search")}`,
|
|
2170
|
+
` ${wixStoresStaticContractPath("category-list")}`,
|
|
2171
|
+
` ${wixStoresStaticContractPath("category-products")}`,
|
|
2172
|
+
" Related products on a product page: agent-kit/designer/related-products.md",
|
|
1905
2173
|
"",
|
|
1906
2174
|
"Bind ViewState and refs per agent-kit/designer/INSTRUCTIONS.md."
|
|
1907
2175
|
);
|
|
@@ -1932,16 +2200,39 @@ function buildCategoryAddMenuItems(roots, config) {
|
|
|
1932
2200
|
prompt: buildCategoryPrompt(config, entry)
|
|
1933
2201
|
}));
|
|
1934
2202
|
}
|
|
2203
|
+
const PUBLIC_THUMBNAIL_ROOT = path.join("public", "aiditor-add-menu-thumbnails");
|
|
2204
|
+
function copyAiditorAddMenuThumbnails(ctx, resolvePackagePath, pluginName) {
|
|
2205
|
+
const sourceDir = resolvePackagePath(
|
|
2206
|
+
path.join("agent-kit", "aiditor", "thumbnails", pluginName)
|
|
2207
|
+
);
|
|
2208
|
+
if (!fs.existsSync(sourceDir)) return [];
|
|
2209
|
+
const destDir = path.join(ctx.projectRoot, PUBLIC_THUMBNAIL_ROOT, pluginName);
|
|
2210
|
+
const created = [];
|
|
2211
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
2212
|
+
for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
|
|
2213
|
+
if (!entry.isFile()) continue;
|
|
2214
|
+
const src = path.join(sourceDir, entry.name);
|
|
2215
|
+
const dest = path.join(destDir, entry.name);
|
|
2216
|
+
if (!fs.existsSync(dest) || ctx.force) {
|
|
2217
|
+
fs.copyFileSync(src, dest);
|
|
2218
|
+
created.push(path.posix.join(PUBLIC_THUMBNAIL_ROOT, pluginName, entry.name));
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
return created;
|
|
2222
|
+
}
|
|
1935
2223
|
const CONFIG_FILE_NAME = ".wix-stores.yaml";
|
|
1936
2224
|
const ADD_MENU_OUTPUT_REL = "agent-kit/aiditor/add-menu/wix-stores.yaml";
|
|
1937
2225
|
const ADD_MENU_GENERATED_REL = "agent-kit/aiditor/add-menu/wix-stores.generated.yaml";
|
|
1938
|
-
function
|
|
2226
|
+
function resolvePackageAgentKitPath(relativePath) {
|
|
1939
2227
|
const thisDir = path.dirname(fileURLToPath(import.meta.url));
|
|
1940
|
-
const fromDist = path.join(thisDir,
|
|
2228
|
+
const fromDist = path.join(thisDir, relativePath);
|
|
1941
2229
|
if (fs.existsSync(fromDist)) {
|
|
1942
2230
|
return fromDist;
|
|
1943
2231
|
}
|
|
1944
|
-
return path.join(thisDir, "..",
|
|
2232
|
+
return path.join(thisDir, "..", relativePath);
|
|
2233
|
+
}
|
|
2234
|
+
function resolveAddMenuTemplatePath() {
|
|
2235
|
+
return resolvePackageAgentKitPath("agent-kit/aiditor/add-menu.template.yaml");
|
|
1945
2236
|
}
|
|
1946
2237
|
function writeAddMenuCatalog(ctx) {
|
|
1947
2238
|
const outputPath = path.join(ctx.projectRoot, ADD_MENU_OUTPUT_REL);
|
|
@@ -2009,7 +2300,8 @@ async function setupWixStores(ctx) {
|
|
|
2009
2300
|
}
|
|
2010
2301
|
const service = getService(WIX_STORES_SERVICE_MARKER);
|
|
2011
2302
|
try {
|
|
2012
|
-
await
|
|
2303
|
+
const { searchProducts: searchProductsApi } = await Promise.resolve().then(() => searchProducts$2);
|
|
2304
|
+
await searchProductsApi(service.wixClient, {});
|
|
2013
2305
|
} catch (e) {
|
|
2014
2306
|
const msg = e.message || "";
|
|
2015
2307
|
const hint = msg.includes("404") || msg.includes("not found") ? "Wix Stores may not be installed on this site" : msg.includes("403") || msg.includes("permission") ? "API key may lack Wix Stores permissions" : "This package requires the Stores Catalog V3 API — if using Catalog V1, use @jay-framework/wix-stores-v1 instead";
|
|
@@ -2022,6 +2314,9 @@ async function setupWixStores(ctx) {
|
|
|
2022
2314
|
if (addMenuCreated) {
|
|
2023
2315
|
configCreated.push(addMenuCreated);
|
|
2024
2316
|
}
|
|
2317
|
+
configCreated.push(
|
|
2318
|
+
...copyAiditorAddMenuThumbnails(ctx, resolvePackageAgentKitPath, "wix-stores")
|
|
2319
|
+
);
|
|
2025
2320
|
const message = `Wix Stores configured (product URL: ${service.urls.product})`;
|
|
2026
2321
|
return {
|
|
2027
2322
|
status: "configured",
|
|
@@ -2041,13 +2336,16 @@ async function generateWixStoresReferences(ctx) {
|
|
|
2041
2336
|
}
|
|
2042
2337
|
fs.mkdirSync(ctx.referencesDir, { recursive: true });
|
|
2043
2338
|
const allCategories = [];
|
|
2044
|
-
let
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2339
|
+
let cursor;
|
|
2340
|
+
let hasMore = true;
|
|
2341
|
+
while (hasMore) {
|
|
2342
|
+
const result = await queryCategories(
|
|
2343
|
+
storesService.wixClient,
|
|
2344
|
+
cursor ? { cursorPaging: { cursor } } : { filter: { visible: true }, cursorPaging: { limit: 100 } }
|
|
2345
|
+
);
|
|
2346
|
+
allCategories.push(...result.categories || []);
|
|
2347
|
+
cursor = result.pagingMetadata?.cursors?.next;
|
|
2348
|
+
hasMore = !!cursor;
|
|
2051
2349
|
}
|
|
2052
2350
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
2053
2351
|
for (const cat of allCategories) {
|
|
@@ -2214,8 +2512,8 @@ function jsonSchemaToContractTags(properties, indent = 4) {
|
|
|
2214
2512
|
}
|
|
2215
2513
|
return tags;
|
|
2216
2514
|
}
|
|
2217
|
-
function buildExtendedFieldsSubContract(
|
|
2218
|
-
const userFieldsSchema =
|
|
2515
|
+
function buildExtendedFieldsSubContract(schemas, indent = 2) {
|
|
2516
|
+
const userFieldsSchema = schemas.find((s) => s.namespace === "_user_fields");
|
|
2219
2517
|
const properties = userFieldsSchema?.jsonSchema?.properties;
|
|
2220
2518
|
if (!properties || Object.keys(properties).length === 0) {
|
|
2221
2519
|
return null;
|
|
@@ -2336,8 +2634,8 @@ tags:
|
|
|
2336
2634
|
|
|
2337
2635
|
# SEO data is injected into <head> via headTags (Design Log #127), not part of the contract view state.`;
|
|
2338
2636
|
const generator = makeContractGenerator().withServices(WIX_STORES_SERVICE_MARKER).generateWith(async (wixStoresService) => {
|
|
2339
|
-
const
|
|
2340
|
-
const extendedFieldsBlock = buildExtendedFieldsSubContract(
|
|
2637
|
+
const schemas = await wixStoresService.getDataExtensionSchemas();
|
|
2638
|
+
const extendedFieldsBlock = buildExtendedFieldsSubContract(schemas);
|
|
2341
2639
|
let yaml2 = BASE_CONTRACT_YAML;
|
|
2342
2640
|
if (extendedFieldsBlock) {
|
|
2343
2641
|
yaml2 = yaml2 + "\n\n" + extendedFieldsBlock;
|
|
@@ -2347,7 +2645,7 @@ const generator = makeContractGenerator().withServices(WIX_STORES_SERVICE_MARKER
|
|
|
2347
2645
|
yaml: yaml2,
|
|
2348
2646
|
description: "Product page with data extension fields",
|
|
2349
2647
|
metadata: {
|
|
2350
|
-
extendedFieldCount:
|
|
2648
|
+
extendedFieldCount: schemas.reduce(
|
|
2351
2649
|
(count, s) => count + Object.keys(s.jsonSchema?.properties ?? {}).length,
|
|
2352
2650
|
0
|
|
2353
2651
|
)
|