@wix/himalaya-cli 0.1303.0 → 0.1304.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/cli.mjs +99 -12
- package/fixtures/wix-canned.json +19 -20
- package/package.json +2 -2
- package/templates/branded-lite/config.ts +4 -2
- package/templates/branded-lite/dev/index.ts +83 -78
- package/templates/branded-lite/tier5-src/himi-branded-lite-galleries/index.ts +139 -30
- package/templates/branded-lite/tier5-src/wix-spaces-photo-albums/index.ts +0 -21
package/dist/cli.mjs
CHANGED
|
@@ -16589,7 +16589,6 @@ function resolveIdiom(tokens2, ctx = {}) {
|
|
|
16589
16589
|
var IDIOM_CONTEXTS, UNSAFE_KEYS;
|
|
16590
16590
|
var init_idiom = __esm({
|
|
16591
16591
|
"../../core/ts/src/idiom.ts"() {
|
|
16592
|
-
"use strict";
|
|
16593
16592
|
IDIOM_CONTEXTS = {
|
|
16594
16593
|
ios: { native: ["ios"] },
|
|
16595
16594
|
android: { native: ["material"] },
|
|
@@ -25183,7 +25182,7 @@ function serializeAt(node, src, open) {
|
|
|
25183
25182
|
const indent = lineIndent(src, open);
|
|
25184
25183
|
return JSON.stringify(node, null, 2).split("\n").map((line, i2) => i2 === 0 ? line : indent + line).join("\n");
|
|
25185
25184
|
}
|
|
25186
|
-
function patchGrids(src, installed, patch, keepFaq = false, dropFaq = false) {
|
|
25185
|
+
function patchGrids(src, installed, patch, keepFaq = false, dropFaq = false, dropGalleries = false) {
|
|
25187
25186
|
const OPEN = /"id": "([A-Za-z_0-9]+(?:\.[A-Za-z_0-9]+)*\.verticals)"/g;
|
|
25188
25187
|
let out2 = "";
|
|
25189
25188
|
let cursor = 0;
|
|
@@ -25237,9 +25236,10 @@ function patchGrids(src, installed, patch, keepFaq = false, dropFaq = false) {
|
|
|
25237
25236
|
faqCell = cloneCell(shape, prefix, "faq", FAQ_CARD);
|
|
25238
25237
|
}
|
|
25239
25238
|
if (!installed.size) {
|
|
25240
|
-
if (dropFaq) {
|
|
25241
|
-
const kept = items.filter((item) => claimOf(item)
|
|
25242
|
-
if (kept.
|
|
25239
|
+
if (dropFaq || dropGalleries) {
|
|
25240
|
+
const kept = items.filter((item) => !(dropFaq && claimOf(item) === "faq") && !(dropGalleries && claimOf(item) === "galleries"));
|
|
25241
|
+
if (keepFaq && faqCell && !kept.some((item) => claimOf(item) === "faq") && kept.length < EXPLORE_MAX_CELLS) kept.push(faqCell);
|
|
25242
|
+
if (kept.length !== items.length && (kept.length > 0 || dropGalleries)) {
|
|
25243
25243
|
node.body.props.items = kept;
|
|
25244
25244
|
out2 += src.slice(cursor, open) + serializeAt(node, src, open);
|
|
25245
25245
|
cursor = close;
|
|
@@ -25396,7 +25396,9 @@ function patchHomeForVerticals(src, verticals, homeActionId, opts = {}) {
|
|
|
25396
25396
|
const installed = new Set(verticals.filter(isKnown));
|
|
25397
25397
|
const patch = { src, cells: [], added: [], droppedModules: [], droppedCtas: [], unreachable: [] };
|
|
25398
25398
|
if (!installed.size) {
|
|
25399
|
-
if (opts.keepFaq || opts.dropFaq
|
|
25399
|
+
if (opts.keepFaq || opts.dropFaq || opts.dropGalleries) {
|
|
25400
|
+
patch.src = patchGrids(src, installed, patch, !!opts.keepFaq, !opts.keepFaq && !!opts.dropFaq, !!opts.dropGalleries);
|
|
25401
|
+
}
|
|
25400
25402
|
return patch;
|
|
25401
25403
|
}
|
|
25402
25404
|
const ctas = patchStoreCtas(patchModules(patchGrids(src, installed, patch, opts.keepFaq), installed, patch), [...installed], homeActionId);
|
|
@@ -162746,6 +162748,7 @@ async function writeBusinessBook(result, opts) {
|
|
|
162746
162748
|
screenshotUrl: p2.screenshotUrl,
|
|
162747
162749
|
headings: p2.headings,
|
|
162748
162750
|
heroCopy: p2.heroCopy,
|
|
162751
|
+
galleryImageUrls: p2.galleryImageUrls,
|
|
162749
162752
|
sections: p2.sections,
|
|
162750
162753
|
ctaLabels: p2.ctaLabels,
|
|
162751
162754
|
faq: p2.faq,
|
|
@@ -166893,16 +166896,21 @@ async function createPlaywrightBrowser(load3 = () => import("playwright"), siteF
|
|
|
166893
166896
|
let mainPageId;
|
|
166894
166897
|
let seededFromMap = false;
|
|
166895
166898
|
let sitePages = [];
|
|
166899
|
+
let skippedPage = false;
|
|
166896
166900
|
while (queue.length && pages.length < budget) {
|
|
166897
166901
|
const url = queue.shift();
|
|
166898
166902
|
if (seen.has(url)) continue;
|
|
166899
166903
|
seen.add(url);
|
|
166900
|
-
if (!await navigated(page, url, url === siteUrl))
|
|
166904
|
+
if (!await navigated(page, url, url === siteUrl)) {
|
|
166905
|
+
skippedPage = true;
|
|
166906
|
+
continue;
|
|
166907
|
+
}
|
|
166901
166908
|
const title = await page.title();
|
|
166902
166909
|
let evaled;
|
|
166903
166910
|
try {
|
|
166904
166911
|
evaled = await page.evaluate(PAGE_EVAL);
|
|
166905
166912
|
} catch {
|
|
166913
|
+
skippedPage = true;
|
|
166906
166914
|
continue;
|
|
166907
166915
|
}
|
|
166908
166916
|
let pageId2 = evaled.velo?.pageId || void 0;
|
|
@@ -166942,6 +166950,7 @@ async function createPlaywrightBrowser(load3 = () => import("playwright"), siteF
|
|
|
166942
166950
|
headings: evaled.headings,
|
|
166943
166951
|
heroCopy: evaled.hero || void 0,
|
|
166944
166952
|
imageUrls: evaled.imgs,
|
|
166953
|
+
...evaled.galleryImgs?.length ? { galleryImageUrls: evaled.galleryImgs } : {},
|
|
166945
166954
|
wst: evaled.wst,
|
|
166946
166955
|
layout: {
|
|
166947
166956
|
hero: !!evaled.hero,
|
|
@@ -166980,6 +166989,7 @@ async function createPlaywrightBrowser(load3 = () => import("playwright"), siteF
|
|
|
166980
166989
|
const veloHint = mergeVeloHints(veloHints);
|
|
166981
166990
|
return {
|
|
166982
166991
|
pages,
|
|
166992
|
+
complete: !skippedPage && pages.length > 0 && pages.length < budget && !queue.some((url) => !seen.has(url)) && (!sitePages.length || sitePages.length <= pages.length),
|
|
166983
166993
|
navLabels: navAll,
|
|
166984
166994
|
...navLinksAll.length ? { navLinks: navLinksAll } : {},
|
|
166985
166995
|
theme: Object.keys(wst).length ? {
|
|
@@ -167144,6 +167154,12 @@ var init_crawl_look = __esm({
|
|
|
167144
167154
|
ogDescription: attrOf('meta[property="og:description"]'),
|
|
167145
167155
|
};
|
|
167146
167156
|
const imgs = Array.from(document.querySelectorAll("img[src]")).map((i) => i.src).filter((s) => /^https?:/.test(s)).slice(0, 16);
|
|
167157
|
+
// A Gallery page can also contain its logo, header art and footer images. Only media
|
|
167158
|
+
// inside a gallery widget is safe to carry into a customer app as gallery content.
|
|
167159
|
+
const galleryImgs = Array.from(document.querySelectorAll(
|
|
167160
|
+
'img.wixui-gallery__image,.wixui-gallery img,.pro-gallery img,[data-hook*="gallery"] img,[data-testid*="gallery"] img,img[class*="gallery__image"]'
|
|
167161
|
+
)).filter((i) => !i.closest('header,footer,nav,[role="banner"],[role="contentinfo"]'))
|
|
167162
|
+
.map((i) => i.src).filter((s) => /^https?:/.test(s)).slice(0, 100);
|
|
167147
167163
|
const hrefs = Array.from(document.querySelectorAll("a[href]")).map((a) => a.href);
|
|
167148
167164
|
const buttons = Array.from(document.querySelectorAll("a,button")).map((el) => (el.textContent || "").trim()).filter(Boolean).slice(0, 40);
|
|
167149
167165
|
const html = document.documentElement.outerHTML.slice(0, 80000);
|
|
@@ -167199,7 +167215,7 @@ var init_crawl_look = __esm({
|
|
|
167199
167215
|
if (pid) velo.pageId = pid[1];
|
|
167200
167216
|
}
|
|
167201
167217
|
} catch (e4) {}
|
|
167202
|
-
return { wst, nav, navLinks, headings, hero, imgs, hrefs, buttons, html, htmlLang, velo, sections, ctaLabels, faq, testimonials, about, meta };
|
|
167218
|
+
return { wst, nav, navLinks, headings, hero, imgs, galleryImgs, hrefs, buttons, html, htmlLang, velo, sections, ctaLabels, faq, testimonials, about, meta };
|
|
167203
167219
|
})()`;
|
|
167204
167220
|
CAP2 = {
|
|
167205
167221
|
heading: 120,
|
|
@@ -167601,7 +167617,37 @@ function deriveStaticFaq(faq) {
|
|
|
167601
167617
|
}
|
|
167602
167618
|
return out2;
|
|
167603
167619
|
}
|
|
167604
|
-
|
|
167620
|
+
function deriveStaticGalleries(pages) {
|
|
167621
|
+
if (!Array.isArray(pages)) return [];
|
|
167622
|
+
const galleries = [];
|
|
167623
|
+
const seenPhotoSets = /* @__PURE__ */ new Set();
|
|
167624
|
+
let totalPhotos = 0;
|
|
167625
|
+
for (const raw of pages) {
|
|
167626
|
+
if (galleries.length >= STATIC_GALLERY_LIMITS.galleries || totalPhotos >= STATIC_GALLERY_LIMITS.totalPhotos) break;
|
|
167627
|
+
const page = raw && typeof raw === "object" ? raw : {};
|
|
167628
|
+
if (!Array.isArray(page.galleryImageUrls)) continue;
|
|
167629
|
+
const photos = [];
|
|
167630
|
+
for (const image of page.galleryImageUrls) {
|
|
167631
|
+
if (photos.length >= STATIC_GALLERY_LIMITS.photos || totalPhotos + photos.length >= STATIC_GALLERY_LIMITS.totalPhotos) break;
|
|
167632
|
+
if (typeof image !== "string") continue;
|
|
167633
|
+
const match = /^https:\/\/static\.wixstatic\.com\/media\/([A-Za-z0-9_~.-]+)(?:\/.*)?$/.exec(image);
|
|
167634
|
+
if (!match) continue;
|
|
167635
|
+
const url = `https://static.wixstatic.com/media/${match[1]}`;
|
|
167636
|
+
if (!photos.includes(url)) photos.push(url);
|
|
167637
|
+
}
|
|
167638
|
+
if (!photos.length) continue;
|
|
167639
|
+
const photoSet = photos.join("\n");
|
|
167640
|
+
if (seenPhotoSets.has(photoSet)) continue;
|
|
167641
|
+
seenPhotoSets.add(photoSet);
|
|
167642
|
+
totalPhotos += photos.length;
|
|
167643
|
+
const heading = Array.isArray(page.headings) ? page.headings.find((h2) => typeof h2 === "string" && !!h2.trim()) : void 0;
|
|
167644
|
+
const pageTitle = typeof page.title === "string" ? page.title.split(/\s+[|–—]\s+/)[0] : "";
|
|
167645
|
+
const title = bounded(oneLine(page.role === "gallery" ? pageTitle || heading || "Gallery" : "Gallery"), STATIC_GALLERY_LIMITS.title);
|
|
167646
|
+
galleries.push({ id: `site-gallery-${galleries.length + 1}`, title, photos });
|
|
167647
|
+
}
|
|
167648
|
+
return galleries;
|
|
167649
|
+
}
|
|
167650
|
+
var clean, ID_MAX, NAME_MAX, TYPE_MAX, CONTROL_CHARS2, HAS_CONTROL_CHAR, plain, shown, STATIC_FAQ_LIMITS, oneLine, STATIC_GALLERY_LIMITS;
|
|
167605
167651
|
var init_derive = __esm({
|
|
167606
167652
|
"src/site-analyze/derive.ts"() {
|
|
167607
167653
|
init_types2();
|
|
@@ -167615,6 +167661,7 @@ var init_derive = __esm({
|
|
|
167615
167661
|
shown = (value) => (typeof value === "string" ? JSON.stringify(value) : String(value)).slice(0, 64);
|
|
167616
167662
|
STATIC_FAQ_LIMITS = { pairs: 20, question: 200, answer: 1500 };
|
|
167617
167663
|
oneLine = (s2) => typeof s2 === "string" ? s2.replace(/[\u0000-\u001F\u007F\s]+/g, " ").trim() : "";
|
|
167664
|
+
STATIC_GALLERY_LIMITS = { galleries: 10, photos: 50, totalPhotos: 50, title: 120 };
|
|
167618
167665
|
}
|
|
167619
167666
|
});
|
|
167620
167667
|
|
|
@@ -168584,6 +168631,7 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
168584
168631
|
"wix",
|
|
168585
168632
|
"copy",
|
|
168586
168633
|
"faq",
|
|
168634
|
+
"galleries",
|
|
168587
168635
|
"site",
|
|
168588
168636
|
"goals"
|
|
168589
168637
|
];
|
|
@@ -168592,6 +168640,9 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
168592
168640
|
const value = overlay[key2];
|
|
168593
168641
|
if (value !== void 0) customer[key2] = value;
|
|
168594
168642
|
}
|
|
168643
|
+
if (customer.galleries === void 0 && !sameKnownSite(committed, overlay)) {
|
|
168644
|
+
customer.galleries = [];
|
|
168645
|
+
}
|
|
168595
168646
|
if (committed.site === void 0) delete customer.site;
|
|
168596
168647
|
customer.site = keepSiteLayout(committed.site, customer.site);
|
|
168597
168648
|
const overlayBranding = { ...customer.branding ?? {} };
|
|
@@ -168623,6 +168674,10 @@ function siteKeyOf(overlay) {
|
|
|
168623
168674
|
const url = overlay.wix?.siteUrl;
|
|
168624
168675
|
return typeof url === "string" && url.trim() ? `url:${url.trim().replace(/\/+$/, "").toLowerCase()}` : "";
|
|
168625
168676
|
}
|
|
168677
|
+
function sameKnownSite(previous, next) {
|
|
168678
|
+
const key2 = siteKeyOf(next);
|
|
168679
|
+
return key2 !== "" && key2 === siteKeyOf(previous);
|
|
168680
|
+
}
|
|
168626
168681
|
function buildMergedContract(options) {
|
|
168627
168682
|
const { appDir: appDir3, packageDir, overlay } = options;
|
|
168628
168683
|
const committedPath = join78(appDir3, "provisioning.json");
|
|
@@ -168739,6 +168794,21 @@ function staticFaqFor(overlay, overlayPath) {
|
|
|
168739
168794
|
return void 0;
|
|
168740
168795
|
}
|
|
168741
168796
|
}
|
|
168797
|
+
function staticGalleriesFor(overlay, overlayPath) {
|
|
168798
|
+
if (overlay.galleries !== void 0) return deriveStaticGalleries(
|
|
168799
|
+
overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
|
|
168800
|
+
);
|
|
168801
|
+
const bookPath = join78(dirname42(resolve58(overlayPath)), "book.json");
|
|
168802
|
+
if (!existsSync76(bookPath)) return void 0;
|
|
168803
|
+
try {
|
|
168804
|
+
const book = JSON.parse(readFileSync92(bookPath, "utf8"));
|
|
168805
|
+
if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
|
|
168806
|
+
const galleries = deriveStaticGalleries(book.look.pages);
|
|
168807
|
+
return galleries.length || book.look.complete === true ? galleries : void 0;
|
|
168808
|
+
} catch {
|
|
168809
|
+
return void 0;
|
|
168810
|
+
}
|
|
168811
|
+
}
|
|
168742
168812
|
async function applyOverlays(input) {
|
|
168743
168813
|
const cwd = resolve58(input.cwd);
|
|
168744
168814
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
@@ -168747,6 +168817,11 @@ async function applyOverlays(input) {
|
|
|
168747
168817
|
const tokens2 = JSON.parse(readFileSync92(input.tokensPath, "utf8"));
|
|
168748
168818
|
const faq = staticFaqFor(overlay, input.overlayPath);
|
|
168749
168819
|
if (faq !== void 0) overlay.faq = faq;
|
|
168820
|
+
const galleries = staticGalleriesFor(overlay, input.overlayPath);
|
|
168821
|
+
if (galleries !== void 0) {
|
|
168822
|
+
overlay.galleries = galleries;
|
|
168823
|
+
if (galleries.length && !overlay.installedVerticals.includes("galleries")) overlay.installedVerticals.push("galleries");
|
|
168824
|
+
}
|
|
168750
168825
|
const wrote = [];
|
|
168751
168826
|
const notes = [];
|
|
168752
168827
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -168788,16 +168863,22 @@ async function applyOverlays(input) {
|
|
|
168788
168863
|
const pkgProv = join78(cwd, "provisioning.json");
|
|
168789
168864
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
168790
168865
|
let packageFaq = faq;
|
|
168866
|
+
let packageGalleries = galleries;
|
|
168791
168867
|
if (existsSync76(pkgProv)) {
|
|
168792
168868
|
const cur = JSON.parse(readFileSync92(pkgProv, "utf8"));
|
|
168869
|
+
if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
|
|
168793
168870
|
const merged = deepMerge4(cur, overlay);
|
|
168794
168871
|
packageFaq = merged.faq;
|
|
168872
|
+
packageGalleries = merged.galleries;
|
|
168795
168873
|
writeFileSync35(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
168796
168874
|
wrote.push(pkgProv);
|
|
168797
168875
|
} else {
|
|
168798
168876
|
writeFileSync35(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
168799
168877
|
wrote.push(pkgProv);
|
|
168800
168878
|
}
|
|
168879
|
+
if (Array.isArray(packageGalleries) && packageGalleries.length && !overlay.installedVerticals.includes("galleries")) {
|
|
168880
|
+
overlay.installedVerticals.push("galleries");
|
|
168881
|
+
}
|
|
168801
168882
|
const pkgTokens = join78(cwd, "tokens.json");
|
|
168802
168883
|
if (existsSync76(pkgTokens) && (tokens2.colors || tokens2.typography)) {
|
|
168803
168884
|
const cur = JSON.parse(readFileSync92(pkgTokens, "utf8"));
|
|
@@ -168835,11 +168916,15 @@ async function applyOverlays(input) {
|
|
|
168835
168916
|
"the site's FAQ pairs were saved to provisioning.json, but this package's FAQ screen predates the site-FAQ fallback and will not show them \u2014 re-scaffold from the current template to pick it up"
|
|
168836
168917
|
);
|
|
168837
168918
|
}
|
|
168919
|
+
if (!patched.foreign && galleries?.length && prev.includes('"tier5.himiBrandedGalleries.load"') && !prev.includes('"staticGalleries"')) {
|
|
168920
|
+
notes.push("the site's Gallery photos were saved to provisioning.json, but this package predates the page-gallery viewer \u2014 re-scaffold from the current template");
|
|
168921
|
+
}
|
|
168838
168922
|
const keepFaq = Array.isArray(packageFaq) && packageFaq.length > 0;
|
|
168839
168923
|
const dropFaq = Array.isArray(faq) && faq.length === 0;
|
|
168924
|
+
const dropGalleries = Array.isArray(packageGalleries) && packageGalleries.length === 0 && !overlay.installedVerticals.includes("galleries");
|
|
168840
168925
|
const ownsHome = prev.includes(`"actionId": "${homeAction}"`);
|
|
168841
|
-
if (ownsHome && !patched.foreign && (overlay.installedVerticals?.length || keepFaq || dropFaq)) {
|
|
168842
|
-
const home = patchHomeForVerticals(next, overlay.installedVerticals ?? [], homeAction, { keepFaq, dropFaq });
|
|
168926
|
+
if (ownsHome && !patched.foreign && (overlay.installedVerticals?.length || keepFaq || dropFaq || dropGalleries)) {
|
|
168927
|
+
const home = patchHomeForVerticals(next, overlay.installedVerticals ?? [], homeAction, { keepFaq, dropFaq, dropGalleries });
|
|
168843
168928
|
next = home.src;
|
|
168844
168929
|
if (home.droppedCtas.length) {
|
|
168845
168930
|
notes.push(`removed the home's store call(s) to action (${home.droppedCtas.join(", ")}) \u2014 this site has no store`);
|
|
@@ -168886,6 +168971,7 @@ function patchBrandParams(src, overlay, homeActionId) {
|
|
|
168886
168971
|
const accent = overlay.branding?.primaryColor;
|
|
168887
168972
|
const verts = overlay.installedVerticals;
|
|
168888
168973
|
const faq = overlay.faq;
|
|
168974
|
+
const galleries = overlay.galleries;
|
|
168889
168975
|
const edits = [
|
|
168890
168976
|
...layout ? [{ pattern: /"ownerDefaultLayout": "[^"]*"/g, replacement: `"ownerDefaultLayout": ${JSON.stringify(layout)}` }] : [],
|
|
168891
168977
|
...accent ? [{ pattern: /"brandAccent": "[^"]*"/g, replacement: `"brandAccent": ${JSON.stringify(accent)}` }] : [],
|
|
@@ -168896,7 +168982,8 @@ function patchBrandParams(src, overlay, homeActionId) {
|
|
|
168896
168982
|
// replacement, because the pairs are customer text and may contain `$&`. Patched whenever
|
|
168897
168983
|
// the analysis SAID something, `[]` included, so a re-apply clears pairs an earlier one
|
|
168898
168984
|
// baked in rather than leaving the worker another site's FAQ.
|
|
168899
|
-
...faq ? [{ pattern: /"staticFaq": "(?:[^"\\]|\\.)*"/g, replacement: `"staticFaq": ${JSON.stringify(JSON.stringify(faq))}` }] : []
|
|
168985
|
+
...faq ? [{ pattern: /"staticFaq": "(?:[^"\\]|\\.)*"/g, replacement: `"staticFaq": ${JSON.stringify(JSON.stringify(faq))}` }] : [],
|
|
168986
|
+
...galleries ? [{ pattern: /"staticGalleries": "(?:[^"\\]|\\.)*"/g, replacement: `"staticGalleries": ${JSON.stringify(JSON.stringify(galleries))}` }] : []
|
|
168900
168987
|
];
|
|
168901
168988
|
if (!edits.length) return { src, applied: 0, unparsed: 0, foreign: false };
|
|
168902
168989
|
if (!src.includes(`"actionId": "${homeActionId}"`)) {
|
package/fixtures/wix-canned.json
CHANGED
|
@@ -860,27 +860,26 @@
|
|
|
860
860
|
"total": 2
|
|
861
861
|
}
|
|
862
862
|
},
|
|
863
|
-
"GET
|
|
864
|
-
"
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
}
|
|
873
|
-
},
|
|
874
|
-
{
|
|
875
|
-
"id": "gal-0002",
|
|
876
|
-
"name": "Harvest 2026",
|
|
877
|
-
"totalItemsCount": 48,
|
|
878
|
-
"coverImage": {
|
|
879
|
-
"url": "https://static.wixstatic.com/media/example-harvest-gallery.jpg"
|
|
880
|
-
}
|
|
863
|
+
"GET /progallery/v2/galleries": {
|
|
864
|
+
"totalGalleries": 2,
|
|
865
|
+
"galleries": [
|
|
866
|
+
{
|
|
867
|
+
"id": "gal-0001",
|
|
868
|
+
"name": "The Roastery",
|
|
869
|
+
"totalItems": 24,
|
|
870
|
+
"coverImage": {
|
|
871
|
+
"url": "https://static.wixstatic.com/media/example-roastery.jpg"
|
|
881
872
|
}
|
|
882
|
-
|
|
883
|
-
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
"id": "gal-0002",
|
|
876
|
+
"name": "Harvest 2026",
|
|
877
|
+
"totalItems": 48,
|
|
878
|
+
"coverImage": {
|
|
879
|
+
"url": "https://static.wixstatic.com/media/example-harvest-gallery.jpg"
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
]
|
|
884
883
|
},
|
|
885
884
|
"GET /inbox/v2/conversations": {
|
|
886
885
|
"conversations": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1304.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"artifactId": "himalaya-cli"
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
|
-
"falconPackageHash": "
|
|
73
|
+
"falconPackageHash": "fd1140c9356d5a4d1715c4b39f8804830e3e4f36114d7a006cd4530e"
|
|
74
74
|
}
|
|
@@ -639,9 +639,11 @@ export default defineApp({
|
|
|
639
639
|
},
|
|
640
640
|
{
|
|
641
641
|
"screenId": "himi_photo_album",
|
|
642
|
-
"isPublic":
|
|
642
|
+
"isPublic": true,
|
|
643
643
|
"paramKeys": [
|
|
644
|
-
"id"
|
|
644
|
+
"id",
|
|
645
|
+
"url",
|
|
646
|
+
"name"
|
|
645
647
|
],
|
|
646
648
|
"parentScreenId": "himi_gallery",
|
|
647
649
|
"tabId": ""
|
|
@@ -76632,7 +76632,10 @@ const SCREENS = runtimeSetting({
|
|
|
76632
76632
|
"bottom": 28
|
|
76633
76633
|
},
|
|
76634
76634
|
"onAppear": {
|
|
76635
|
-
"actionId": "tier5.himiBrandedGalleries.load"
|
|
76635
|
+
"actionId": "tier5.himiBrandedGalleries.load",
|
|
76636
|
+
"params": {
|
|
76637
|
+
"staticGalleries": "[]"
|
|
76638
|
+
}
|
|
76636
76639
|
}
|
|
76637
76640
|
}
|
|
76638
76641
|
},
|
|
@@ -76641,7 +76644,8 @@ const SCREENS = runtimeSetting({
|
|
|
76641
76644
|
"integrity": "",
|
|
76642
76645
|
"contentType": "application/javascript+ts-bundle",
|
|
76643
76646
|
"declaredCapabilities": [
|
|
76644
|
-
"wix_api"
|
|
76647
|
+
"wix_api",
|
|
76648
|
+
"app_info"
|
|
76645
76649
|
],
|
|
76646
76650
|
"minBinaryVersion": "0.1.0",
|
|
76647
76651
|
"bundleVersion": "0.0.1"
|
|
@@ -76662,7 +76666,7 @@ const SCREENS = runtimeSetting({
|
|
|
76662
76666
|
"package": "himalaya",
|
|
76663
76667
|
"type": "VStack",
|
|
76664
76668
|
"props": {
|
|
76665
|
-
"spacing":
|
|
76669
|
+
"spacing": 16,
|
|
76666
76670
|
"alignment": "leading",
|
|
76667
76671
|
"children": [
|
|
76668
76672
|
{
|
|
@@ -76671,49 +76675,60 @@ const SCREENS = runtimeSetting({
|
|
|
76671
76675
|
"package": "himalaya",
|
|
76672
76676
|
"type": "VStack",
|
|
76673
76677
|
"props": {
|
|
76674
|
-
"spacing":
|
|
76678
|
+
"spacing": 16,
|
|
76675
76679
|
"alignment": "leading",
|
|
76676
76680
|
"children": [
|
|
76677
76681
|
{
|
|
76678
|
-
"id": "himi_gallery.
|
|
76682
|
+
"id": "himi_gallery.title",
|
|
76679
76683
|
"body": {
|
|
76680
76684
|
"package": "himalaya",
|
|
76681
76685
|
"type": "Text",
|
|
76682
76686
|
"props": {
|
|
76683
|
-
"text": "$service:
|
|
76687
|
+
"text": "$service:himiBrandedGalleries.galleryTitle",
|
|
76684
76688
|
"style": "title1"
|
|
76685
76689
|
}
|
|
76686
76690
|
}
|
|
76687
76691
|
},
|
|
76688
76692
|
{
|
|
76689
|
-
"id": "",
|
|
76693
|
+
"id": "himi_gallery.photos",
|
|
76690
76694
|
"body": {
|
|
76691
76695
|
"package": "himalaya",
|
|
76692
|
-
"type": "
|
|
76693
|
-
"props": {
|
|
76694
|
-
"text": "$service:himiBrandedSimpleDetail.subtitle",
|
|
76695
|
-
"style": "body",
|
|
76696
|
-
"color": "textSecondary",
|
|
76697
|
-
"collapseWhenEmpty": true
|
|
76698
|
-
}
|
|
76699
|
-
}
|
|
76700
|
-
},
|
|
76701
|
-
{
|
|
76702
|
-
"id": "himi_gallery.cta",
|
|
76703
|
-
"body": {
|
|
76704
|
-
"package": "himalaya",
|
|
76705
|
-
"type": "Button",
|
|
76696
|
+
"type": "Grid",
|
|
76706
76697
|
"props": {
|
|
76707
|
-
"
|
|
76708
|
-
"
|
|
76709
|
-
"
|
|
76710
|
-
"
|
|
76711
|
-
|
|
76712
|
-
|
|
76713
|
-
"
|
|
76714
|
-
"
|
|
76698
|
+
"columns": 2,
|
|
76699
|
+
"columnsMedium": 3,
|
|
76700
|
+
"spacing": 10,
|
|
76701
|
+
"itemsPath": "$service:himiBrandedGalleries.photos",
|
|
76702
|
+
"items": [
|
|
76703
|
+
{
|
|
76704
|
+
"id": "",
|
|
76705
|
+
"body": {
|
|
76706
|
+
"package": "himalaya",
|
|
76707
|
+
"type": "Image",
|
|
76708
|
+
"props": {
|
|
76709
|
+
"url": "$item.url",
|
|
76710
|
+
"fillWidth": true,
|
|
76711
|
+
"height": 180,
|
|
76712
|
+
"contentMode": "fill",
|
|
76713
|
+
"contentDescription": "$item.title"
|
|
76714
|
+
}
|
|
76715
|
+
},
|
|
76716
|
+
"modifiers": {
|
|
76717
|
+
"cornerRadius": 8,
|
|
76718
|
+
"fillMaxWidth": true,
|
|
76719
|
+
"onTap": {
|
|
76720
|
+
"actionId": "himi.open",
|
|
76721
|
+
"params": {
|
|
76722
|
+
"screenId": "himi_photo_album",
|
|
76723
|
+
"id": "$item.id",
|
|
76724
|
+
"url": "$item.url",
|
|
76725
|
+
"name": "$item.title"
|
|
76726
|
+
}
|
|
76727
|
+
},
|
|
76728
|
+
"accessibilityLabel": "$item.title"
|
|
76729
|
+
}
|
|
76715
76730
|
}
|
|
76716
|
-
|
|
76731
|
+
]
|
|
76717
76732
|
}
|
|
76718
76733
|
}
|
|
76719
76734
|
},
|
|
@@ -76723,18 +76738,20 @@ const SCREENS = runtimeSetting({
|
|
|
76723
76738
|
"package": "himalaya",
|
|
76724
76739
|
"type": "Text",
|
|
76725
76740
|
"props": {
|
|
76726
|
-
"text": "
|
|
76727
|
-
"style": "
|
|
76728
|
-
"color": "
|
|
76729
|
-
"collapseWhenEmpty": true
|
|
76741
|
+
"text": "Photos added to this album will appear here.",
|
|
76742
|
+
"style": "body",
|
|
76743
|
+
"color": "textSecondary"
|
|
76730
76744
|
}
|
|
76745
|
+
},
|
|
76746
|
+
"modifiers": {
|
|
76747
|
+
"hiddenPath": "$service:himiBrandedGalleries.hasPhotos"
|
|
76731
76748
|
}
|
|
76732
76749
|
}
|
|
76733
76750
|
]
|
|
76734
76751
|
}
|
|
76735
76752
|
},
|
|
76736
76753
|
"modifiers": {
|
|
76737
|
-
"hiddenPath": "$service:
|
|
76754
|
+
"hiddenPath": "$service:himiBrandedGalleries.noEntity"
|
|
76738
76755
|
}
|
|
76739
76756
|
},
|
|
76740
76757
|
{
|
|
@@ -76758,7 +76775,7 @@ const SCREENS = runtimeSetting({
|
|
|
76758
76775
|
}
|
|
76759
76776
|
},
|
|
76760
76777
|
"modifiers": {
|
|
76761
|
-
"hiddenPath": "$service:
|
|
76778
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideLoading"
|
|
76762
76779
|
}
|
|
76763
76780
|
},
|
|
76764
76781
|
{
|
|
@@ -76773,7 +76790,7 @@ const SCREENS = runtimeSetting({
|
|
|
76773
76790
|
}
|
|
76774
76791
|
},
|
|
76775
76792
|
"modifiers": {
|
|
76776
|
-
"hiddenPath": "$service:
|
|
76793
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideLoadError"
|
|
76777
76794
|
}
|
|
76778
76795
|
},
|
|
76779
76796
|
{
|
|
@@ -76791,7 +76808,7 @@ const SCREENS = runtimeSetting({
|
|
|
76791
76808
|
"package": "himalaya",
|
|
76792
76809
|
"type": "Icon",
|
|
76793
76810
|
"props": {
|
|
76794
|
-
"name": "
|
|
76811
|
+
"name": "photo",
|
|
76795
76812
|
"size": 32,
|
|
76796
76813
|
"tint": "textTertiary"
|
|
76797
76814
|
}
|
|
@@ -76862,7 +76879,7 @@ const SCREENS = runtimeSetting({
|
|
|
76862
76879
|
"bottom": 20
|
|
76863
76880
|
},
|
|
76864
76881
|
"fillMaxWidth": true,
|
|
76865
|
-
"hiddenPath": "$service:
|
|
76882
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideNotFound"
|
|
76866
76883
|
}
|
|
76867
76884
|
}
|
|
76868
76885
|
]
|
|
@@ -76883,15 +76900,21 @@ const SCREENS = runtimeSetting({
|
|
|
76883
76900
|
"bottom": 28
|
|
76884
76901
|
},
|
|
76885
76902
|
"onAppear": {
|
|
76886
|
-
"actionId": "tier5.
|
|
76903
|
+
"actionId": "tier5.himiBrandedGalleries.open",
|
|
76904
|
+
"params": {
|
|
76905
|
+
"staticGalleries": "[]"
|
|
76906
|
+
}
|
|
76887
76907
|
}
|
|
76888
76908
|
}
|
|
76889
76909
|
},
|
|
76890
76910
|
"logicBundle": {
|
|
76891
|
-
"url": "http://localhost:8190/v1/bundles/himi-branded-lite-
|
|
76911
|
+
"url": "http://localhost:8190/v1/bundles/himi-branded-lite-galleries?integrity=",
|
|
76892
76912
|
"integrity": "",
|
|
76893
76913
|
"contentType": "application/javascript+ts-bundle",
|
|
76894
|
-
"declaredCapabilities": [
|
|
76914
|
+
"declaredCapabilities": [
|
|
76915
|
+
"wix_api",
|
|
76916
|
+
"app_info"
|
|
76917
|
+
],
|
|
76895
76918
|
"minBinaryVersion": "0.1.0",
|
|
76896
76919
|
"bundleVersion": "0.0.1"
|
|
76897
76920
|
}
|
|
@@ -76911,46 +76934,25 @@ const SCREENS = runtimeSetting({
|
|
|
76911
76934
|
"package": "himalaya",
|
|
76912
76935
|
"type": "VStack",
|
|
76913
76936
|
"props": {
|
|
76914
|
-
"spacing":
|
|
76937
|
+
"spacing": 12,
|
|
76915
76938
|
"alignment": "leading",
|
|
76916
76939
|
"children": [
|
|
76917
76940
|
{
|
|
76918
76941
|
"id": "",
|
|
76919
76942
|
"body": {
|
|
76920
76943
|
"package": "himalaya",
|
|
76921
|
-
"type": "
|
|
76944
|
+
"type": "Image",
|
|
76922
76945
|
"props": {
|
|
76923
|
-
"
|
|
76924
|
-
"
|
|
76925
|
-
"
|
|
76926
|
-
|
|
76927
|
-
|
|
76928
|
-
"body": {
|
|
76929
|
-
"package": "himalaya",
|
|
76930
|
-
"type": "Text",
|
|
76931
|
-
"props": {
|
|
76932
|
-
"text": "No photos yet",
|
|
76933
|
-
"style": "title2"
|
|
76934
|
-
}
|
|
76935
|
-
}
|
|
76936
|
-
},
|
|
76937
|
-
{
|
|
76938
|
-
"id": "",
|
|
76939
|
-
"body": {
|
|
76940
|
-
"package": "himalaya",
|
|
76941
|
-
"type": "Text",
|
|
76942
|
-
"props": {
|
|
76943
|
-
"text": "Photos added to this album will appear here.",
|
|
76944
|
-
"style": "body",
|
|
76945
|
-
"color": "textSecondary"
|
|
76946
|
-
}
|
|
76947
|
-
}
|
|
76948
|
-
}
|
|
76949
|
-
]
|
|
76946
|
+
"url": "$service:himiBrandedGalleries.photoUrl",
|
|
76947
|
+
"fillWidth": true,
|
|
76948
|
+
"height": 500,
|
|
76949
|
+
"contentMode": "fit",
|
|
76950
|
+
"contentDescription": "$service:himiBrandedGalleries.photoTitle"
|
|
76950
76951
|
}
|
|
76951
76952
|
},
|
|
76952
76953
|
"modifiers": {
|
|
76953
|
-
"
|
|
76954
|
+
"fillMaxWidth": true,
|
|
76955
|
+
"hiddenPath": "$service:himiBrandedGalleries.noEntity"
|
|
76954
76956
|
}
|
|
76955
76957
|
},
|
|
76956
76958
|
{
|
|
@@ -76974,7 +76976,7 @@ const SCREENS = runtimeSetting({
|
|
|
76974
76976
|
}
|
|
76975
76977
|
},
|
|
76976
76978
|
"modifiers": {
|
|
76977
|
-
"hiddenPath": "$service:
|
|
76979
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideLoading"
|
|
76978
76980
|
}
|
|
76979
76981
|
},
|
|
76980
76982
|
{
|
|
@@ -76989,7 +76991,7 @@ const SCREENS = runtimeSetting({
|
|
|
76989
76991
|
}
|
|
76990
76992
|
},
|
|
76991
76993
|
"modifiers": {
|
|
76992
|
-
"hiddenPath": "$service:
|
|
76994
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideLoadError"
|
|
76993
76995
|
}
|
|
76994
76996
|
},
|
|
76995
76997
|
{
|
|
@@ -77078,7 +77080,7 @@ const SCREENS = runtimeSetting({
|
|
|
77078
77080
|
"bottom": 20
|
|
77079
77081
|
},
|
|
77080
77082
|
"fillMaxWidth": true,
|
|
77081
|
-
"hiddenPath": "$service:
|
|
77083
|
+
"hiddenPath": "$service:himiBrandedGalleries.hideNotFound"
|
|
77082
77084
|
}
|
|
77083
77085
|
}
|
|
77084
77086
|
]
|
|
@@ -77099,15 +77101,18 @@ const SCREENS = runtimeSetting({
|
|
|
77099
77101
|
"bottom": 28
|
|
77100
77102
|
},
|
|
77101
77103
|
"onAppear": {
|
|
77102
|
-
"actionId": "tier5.
|
|
77104
|
+
"actionId": "tier5.himiBrandedGalleries.view"
|
|
77103
77105
|
}
|
|
77104
77106
|
}
|
|
77105
77107
|
},
|
|
77106
77108
|
"logicBundle": {
|
|
77107
|
-
"url": "http://localhost:8190/v1/bundles/
|
|
77109
|
+
"url": "http://localhost:8190/v1/bundles/himi-branded-lite-galleries?integrity=",
|
|
77108
77110
|
"integrity": "",
|
|
77109
77111
|
"contentType": "application/javascript+ts-bundle",
|
|
77110
|
-
"declaredCapabilities": [
|
|
77112
|
+
"declaredCapabilities": [
|
|
77113
|
+
"wix_api",
|
|
77114
|
+
"app_info"
|
|
77115
|
+
],
|
|
77111
77116
|
"minBinaryVersion": "0.1.0",
|
|
77112
77117
|
"bundleVersion": "0.0.1"
|
|
77113
77118
|
}
|
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
// himi-branded-lite-galleries — branded-lite
|
|
1
|
+
// himi-branded-lite-galleries — branded-lite page galleries and Wix Pro Gallery.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// GETs the site's galleries from that endpoint through the raw wixApi bridge (absolute
|
|
7
|
-
// URL + the app's WixApiCapability auth). a failed query is an error with
|
|
8
|
-
// Retry (or Sign in), an empty one a real empty state; sample galleries appear only
|
|
9
|
-
// in the host's explicit sample preview (_shared/branded-load-state.ts).
|
|
3
|
+
// Published Gallery page photos are carried by site analyze in the descriptor and
|
|
4
|
+
// displayed without a Pro Gallery request. Sites with no page gallery use the Wix
|
|
5
|
+
// API gateway. Failed reads remain errors; sample data is explicit preview only.
|
|
10
6
|
//
|
|
11
|
-
// Endpoint verbatim from wix-one-app-pro-gallery/src/constants (API_BASE_URL) +
|
|
12
|
-
// api/photo-gallery-api.js (fetchGalleries).
|
|
13
7
|
import { defineService } from "../_shared/collection-service.js";
|
|
8
|
+
import { get as getAppInfo } from "@himalaya/app-info";
|
|
14
9
|
import { LOADING, loaded, loadFailed, type LoadCopy, type LoadFlags } from "../_shared/branded-load-state.js";
|
|
10
|
+
import { presence, type PresenceFlags } from "../_shared/detail-presence.js";
|
|
15
11
|
|
|
16
|
-
const
|
|
12
|
+
const GALLERIES_PATH = "/progallery/v2/galleries";
|
|
13
|
+
const LEGACY_GALLERIES_URL =
|
|
17
14
|
"https://www.wix.com/_api/photography-one-app-viewer/galleries?itemsPerGallery=1&offset=0&limit=30&withHidden=false&useNew=true";
|
|
15
|
+
const PAGE_SIZE = 10; // API maximum. Keep the prior screen's 30-gallery cap.
|
|
16
|
+
const MAX_GALLERIES = 30;
|
|
18
17
|
|
|
19
18
|
type WixApi = { call: (m: string, p: string, b?: unknown, h?: Record<string, string>) => Promise<unknown> };
|
|
20
19
|
function wixApi(): WixApi | null {
|
|
21
20
|
return (globalThis as { himalaya?: { wixApi?: WixApi } }).himalaya?.wixApi ?? null;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
interface RawGallery { id
|
|
25
|
-
interface
|
|
26
|
-
interface
|
|
23
|
+
interface RawGallery { id: string; name?: string; totalItems?: number; totalItemsCount?: number }
|
|
24
|
+
interface StaticGallery { id: string; title: string; photos: string[] }
|
|
25
|
+
interface Row { id: string; title: string; subtitle: string; name: string; description: string; image: string; noCover: boolean }
|
|
26
|
+
interface PhotoRow { id: string; url: string; title: string }
|
|
27
|
+
interface S extends LoadFlags, PresenceFlags {
|
|
27
28
|
galleries: Row[]; emptyText: string;
|
|
29
|
+
galleryTitle: string; photos: PhotoRow[]; photoUrl: string; photoTitle: string; noGallery: boolean; hasPhotos: boolean; hasPhoto: boolean; noPhoto: boolean;
|
|
28
30
|
isMock: boolean; notMock: boolean; /** #2849 — hiddenWhen() hides on TRUE, so these are inverted: the empty-state banner
|
|
29
31
|
* shows only when the site really has none, and the unavailable one only when the
|
|
30
32
|
* query failed. A failed query must never render the sentence that claims the
|
|
@@ -32,17 +34,93 @@ interface S extends LoadFlags {
|
|
|
32
34
|
notMockEmpty: boolean; notMockUnavailable: boolean;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
function input(key: string): string {
|
|
38
|
+
const value = (globalThis as { himalaya?: { input?: Record<string, unknown> } }).himalaya?.input?.[key];
|
|
39
|
+
return typeof value === "string" ? value : "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function parseStaticGalleries(raw: unknown): StaticGallery[] {
|
|
43
|
+
const parsed: unknown = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
44
|
+
if (parsed == null) return [];
|
|
45
|
+
if (!Array.isArray(parsed)) throw new Error("Malformed imported galleries");
|
|
46
|
+
let remaining = 50;
|
|
47
|
+
return parsed.slice(0, 10).flatMap((item): StaticGallery[] => {
|
|
48
|
+
if (!remaining) return [];
|
|
49
|
+
if (!item || typeof item !== "object") return [];
|
|
50
|
+
const gallery = item as Partial<StaticGallery>;
|
|
51
|
+
if (typeof gallery.id !== "string" || typeof gallery.title !== "string" || !Array.isArray(gallery.photos)) return [];
|
|
52
|
+
const photos = gallery.photos.filter((url): url is string => typeof url === "string" && /^https:\/\/static\.wixstatic\.com\/media\/[A-Za-z0-9_~.-]+$/.test(url)).slice(0, remaining);
|
|
53
|
+
remaining -= photos.length;
|
|
54
|
+
return photos.length ? [{ id: gallery.id, title: gallery.title, photos }] : [];
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let staticGalleries: StaticGallery[] = [];
|
|
59
|
+
|
|
35
60
|
function norm(g: RawGallery, i: number): Row {
|
|
36
61
|
const title = (g.name || "").trim() || `Gallery ${i + 1}`;
|
|
37
|
-
const n = g.totalItemsCount ?? 0;
|
|
62
|
+
const n = g.totalItems ?? g.totalItemsCount ?? 0;
|
|
38
63
|
const subtitle = n ? (n === 1 ? "1 photo" : `${n} photos`) : "";
|
|
39
|
-
return { id: g.id
|
|
64
|
+
return { id: g.id, title, subtitle, name: title, description: subtitle, image: "", noCover: true };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function readGalleries(api: WixApi): Promise<RawGallery[]> {
|
|
68
|
+
const all: RawGallery[] = [];
|
|
69
|
+
for (let offset = 0; offset < MAX_GALLERIES; offset += PAGE_SIZE) {
|
|
70
|
+
const res = await api.call("GET", `${GALLERIES_PATH}?itemLimit=1&offset=${offset}&limit=${PAGE_SIZE}`) as unknown;
|
|
71
|
+
const page = (res as { galleries?: unknown } | null)?.galleries;
|
|
72
|
+
if (!Array.isArray(page) || page.some((g) => !g || typeof g.id !== "string" || !g.id)) {
|
|
73
|
+
throw new Error("Malformed Pro Gallery list response");
|
|
74
|
+
}
|
|
75
|
+
all.push(...page as RawGallery[]);
|
|
76
|
+
const total = (res as { totalGalleries?: unknown }).totalGalleries;
|
|
77
|
+
if (page.length < PAGE_SIZE || (typeof total === "number" && all.length >= total)) break;
|
|
78
|
+
}
|
|
79
|
+
return all;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function readLegacyGalleries(api: WixApi): Promise<RawGallery[]> {
|
|
83
|
+
const res = await api.call("GET", LEGACY_GALLERIES_URL) as unknown;
|
|
84
|
+
const raw = Array.isArray(res) ? res :
|
|
85
|
+
(res as { galleries?: unknown; data?: { galleries?: unknown } } | null)?.galleries ??
|
|
86
|
+
(res as { data?: { galleries?: unknown } } | null)?.data?.galleries;
|
|
87
|
+
if (!Array.isArray(raw)) throw new Error("Malformed legacy Pro Gallery list response");
|
|
88
|
+
return raw.map((gallery, index) => {
|
|
89
|
+
if (!gallery || typeof gallery !== "object") throw new Error("Malformed legacy Pro Gallery row");
|
|
90
|
+
const row = gallery as Partial<RawGallery>;
|
|
91
|
+
return { ...row, id: typeof row.id === "string" && row.id ? row.id : `gallery-${index}` };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function readCompatibleGalleries(api: WixApi): Promise<RawGallery[]> {
|
|
96
|
+
// The old absolute host is supported by native Wix transports, but the
|
|
97
|
+
// published web bridge refuses it as webwix_owner_only.
|
|
98
|
+
const nativeLegacyAvailable = async (): Promise<boolean> => {
|
|
99
|
+
const info = await getAppInfo().catch(() => undefined);
|
|
100
|
+
return info?.platform === "ios" || info?.platform === "android" ||
|
|
101
|
+
info?.platform === "macos" || info?.platform === "react-native";
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
const galleries = await readGalleries(api);
|
|
105
|
+
if (galleries.length) return galleries;
|
|
106
|
+
if (!(await nativeLegacyAvailable())) return galleries;
|
|
107
|
+
// A native site's older Pro Gallery app can have content even when the gateway
|
|
108
|
+
// reports none. Keep the gateway's honest empty result if the old route is blocked.
|
|
109
|
+
try {
|
|
110
|
+
const legacy = await readLegacyGalleries(api);
|
|
111
|
+
return legacy.length ? legacy : galleries;
|
|
112
|
+
} catch { return galleries; }
|
|
113
|
+
} catch (gatewayError) {
|
|
114
|
+
if (!(await nativeLegacyAvailable())) throw gatewayError;
|
|
115
|
+
try { return await readLegacyGalleries(api); }
|
|
116
|
+
catch { throw gatewayError; }
|
|
117
|
+
}
|
|
40
118
|
}
|
|
41
119
|
|
|
42
120
|
const MOCK: Row[] = [
|
|
43
|
-
{ id: "sample-work", title: "Our Work", subtitle: "24 photos" },
|
|
44
|
-
{ id: "sample-events", title: "Events", subtitle: "48 photos" },
|
|
45
|
-
{ id: "sample-team", title: "The Team", subtitle: "9 photos" },
|
|
121
|
+
{ id: "sample-work", title: "Our Work", subtitle: "24 photos", name: "Our Work", description: "24 photos", image: "", noCover: true },
|
|
122
|
+
{ id: "sample-events", title: "Events", subtitle: "48 photos", name: "Events", description: "48 photos", image: "", noCover: true },
|
|
123
|
+
{ id: "sample-team", title: "The Team", subtitle: "9 photos", name: "The Team", description: "9 photos", image: "", noCover: true },
|
|
46
124
|
];
|
|
47
125
|
|
|
48
126
|
/** sample rows reach the screen ONLY in the host's explicit sample preview;
|
|
@@ -55,27 +133,58 @@ const COPY: LoadCopy<Row> = {
|
|
|
55
133
|
sample: () => MOCK.map((r) => ({ ...r })),
|
|
56
134
|
};
|
|
57
135
|
|
|
58
|
-
const svc = defineService<S, {
|
|
59
|
-
|
|
136
|
+
const svc = defineService<S, {
|
|
137
|
+
load: (s: S, arg?: { staticGalleries?: unknown }) => Promise<S>;
|
|
138
|
+
open: (s: S, arg?: { staticGalleries?: unknown }) => S;
|
|
139
|
+
view: (s: S) => S;
|
|
140
|
+
}>("himiBrandedGalleries", {
|
|
141
|
+
state: { ...LOADING, ...presence("loading"), galleries: [], emptyText: "", galleryTitle: "", photos: [], photoUrl: "", photoTitle: "", noGallery: true, hasPhotos: false, hasPhoto: false, noPhoto: true },
|
|
60
142
|
actions: {
|
|
61
|
-
load: async (s) => {
|
|
143
|
+
load: async (s, arg) => {
|
|
62
144
|
try {
|
|
145
|
+
if (arg && "staticGalleries" in arg) {
|
|
146
|
+
staticGalleries = [];
|
|
147
|
+
staticGalleries = parseStaticGalleries(arg.staticGalleries);
|
|
148
|
+
}
|
|
149
|
+
if (staticGalleries.length) {
|
|
150
|
+
const rows = staticGalleries.map((gallery) => {
|
|
151
|
+
const subtitle = gallery.photos.length === 1 ? "1 photo" : `${gallery.photos.length} photos`;
|
|
152
|
+
return { id: gallery.id, title: gallery.title, subtitle, name: gallery.title, description: subtitle, image: gallery.photos[0], noCover: false };
|
|
153
|
+
});
|
|
154
|
+
return { ...s, ...loaded("galleries", rows, COPY) };
|
|
155
|
+
}
|
|
63
156
|
const api = wixApi();
|
|
64
157
|
if (!api) return { ...s, ...loadFailed("galleries", new Error("Wix bridge unavailable"), COPY) };
|
|
65
|
-
const
|
|
66
|
-
{ galleries?: RawGallery[] } | RawGallery[] | { data?: { galleries?: RawGallery[] } };
|
|
67
|
-
// Accept {galleries:[...]}, a top-level array, or a {data:{galleries}} envelope.
|
|
68
|
-
const raw: RawGallery[] =
|
|
69
|
-
(res as { galleries?: RawGallery[] })?.galleries ??
|
|
70
|
-
(Array.isArray(res) ? (res as RawGallery[]) : undefined) ??
|
|
71
|
-
(res as { data?: { galleries?: RawGallery[] } })?.data?.galleries ?? [];
|
|
158
|
+
const raw = await readCompatibleGalleries(api);
|
|
72
159
|
const galleries = raw.map(norm);
|
|
73
160
|
return { ...s, ...loaded("galleries", galleries, COPY) };
|
|
74
161
|
} catch (err) {
|
|
75
162
|
return { ...s, ...loadFailed("galleries", err, COPY) };
|
|
76
163
|
}
|
|
77
164
|
},
|
|
165
|
+
open: (s, arg) => {
|
|
166
|
+
try {
|
|
167
|
+
if (arg && "staticGalleries" in arg) {
|
|
168
|
+
staticGalleries = [];
|
|
169
|
+
staticGalleries = parseStaticGalleries(arg.staticGalleries);
|
|
170
|
+
}
|
|
171
|
+
} catch (err) {
|
|
172
|
+
return { ...s, ...loadFailed("galleries", err, COPY), ...presence("failed"), galleryTitle: "", photos: [],
|
|
173
|
+
noGallery: true, hasPhotos: false, photoUrl: "", photoTitle: "", hasPhoto: false, noPhoto: true };
|
|
174
|
+
}
|
|
175
|
+
const id = input("id");
|
|
176
|
+
const gallery = staticGalleries.find((entry) => entry.id === id);
|
|
177
|
+
const missing = !id || (staticGalleries.length > 0 && !gallery);
|
|
178
|
+
return { ...s, ...loaded("galleries", s.galleries, COPY), ...presence(missing ? "missing" : "found"), galleryTitle: gallery?.title || input("name"),
|
|
179
|
+
photos: (gallery?.photos ?? []).map((url, index) => ({ id: `${id}-${index}`, url, title: `Photo ${index + 1}` })),
|
|
180
|
+
noGallery: missing, hasPhotos: !!gallery?.photos.length, noPhoto: true };
|
|
181
|
+
},
|
|
182
|
+
view: (s) => {
|
|
183
|
+
const photoUrl = input("url");
|
|
184
|
+
const valid = /^https:\/\/static\.wixstatic\.com\/media\/[A-Za-z0-9_~.-]+$/.test(photoUrl);
|
|
185
|
+
return { ...s, ...loaded("galleries", s.galleries, COPY), ...presence(valid ? "found" : "missing"),
|
|
186
|
+
photoUrl: valid ? photoUrl : "", photoTitle: valid ? input("name") || "Gallery photo" : "", hasPhoto: valid, noPhoto: !valid };
|
|
187
|
+
},
|
|
78
188
|
},
|
|
79
189
|
});
|
|
80
|
-
svc.load();
|
|
81
190
|
export { svc };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Tier-5 bundle: Wix Spaces clone — Photo Albums (ON-DEVICE, site-scoped).
|
|
2
|
-
// No albums API wired yet → renders the real empty state, never fabricated rows.
|
|
3
|
-
// The emptyTitle/emptyBody copy is the Spaces clone's LIST screen. An app that opens
|
|
4
|
-
// this for ONE album (branded-lite's gallery "Open album", which passes the album id)
|
|
5
|
-
// renders its own single-album copy and gates it on `noEntity`; opened with no id at
|
|
6
|
-
// all it shows the shared not-found state.
|
|
7
|
-
import { defineService } from "@himalaya/state";
|
|
8
|
-
import { presence, detailInputId, type PresenceFlags } from "../_shared/detail-presence.js";
|
|
9
|
-
|
|
10
|
-
interface S extends PresenceFlags { status: "ready"; emptyTitle: string; emptyBody: string }
|
|
11
|
-
|
|
12
|
-
const svc = defineService<S, { load: (s: S) => S }>("spacesPhotoAlbums", {
|
|
13
|
-
state: {
|
|
14
|
-
status: "ready",
|
|
15
|
-
emptyTitle: "No albums yet",
|
|
16
|
-
emptyBody: "Photo albums shared on this site will appear here.",
|
|
17
|
-
...presence("loading"),
|
|
18
|
-
},
|
|
19
|
-
actions: { load: (s) => ({ ...s, ...presence(detailInputId() ? "found" : "missing") }) },
|
|
20
|
-
});
|
|
21
|
-
export { svc };
|