@wix/himalaya-cli 0.1046.0 → 0.1048.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
CHANGED
|
@@ -21498,6 +21498,7 @@ function shouldRevealError(args) {
|
|
|
21498
21498
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
21499
21499
|
var init_validation = __esm({
|
|
21500
21500
|
"../../core/ts/src/validation.ts"() {
|
|
21501
|
+
"use strict";
|
|
21501
21502
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
21502
21503
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
21503
21504
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -25098,6 +25099,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
25098
25099
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
25099
25100
|
var init_worker_subtree = __esm({
|
|
25100
25101
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
25102
|
+
"use strict";
|
|
25101
25103
|
init_worker_subtree_safe_types_generated();
|
|
25102
25104
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
25103
25105
|
maxEncodedBytes: 65536,
|
|
@@ -39707,7 +39709,8 @@ function hydrationServices(tier5Dir, bundleName, input = {}) {
|
|
|
39707
39709
|
return js ? servicesFromBundleJs(js, input) : null;
|
|
39708
39710
|
}
|
|
39709
39711
|
function releaseIdFor(sha, content) {
|
|
39710
|
-
|
|
39712
|
+
if (sha === "dev") return contentReleaseId(content);
|
|
39713
|
+
return `${sha}-${contentReleaseId(content).slice(0, 12)}`;
|
|
39711
39714
|
}
|
|
39712
39715
|
function shellSha(root = REPO_ROOT7) {
|
|
39713
39716
|
if (!isMonorepoCheckout(root)) return "";
|
|
@@ -42838,7 +42841,7 @@ function serializeAt(node, src, open) {
|
|
|
42838
42841
|
const indent = lineIndent(src, open);
|
|
42839
42842
|
return JSON.stringify(node, null, 2).split("\n").map((line, i) => i === 0 ? line : indent + line).join("\n");
|
|
42840
42843
|
}
|
|
42841
|
-
function patchGrids(src, installed, patch) {
|
|
42844
|
+
function patchGrids(src, installed, patch, keepFaq = false, dropFaq = false) {
|
|
42842
42845
|
const OPEN = /"id": "([A-Za-z_0-9]+(?:\.[A-Za-z_0-9]+)*\.verticals)"/g;
|
|
42843
42846
|
let out = "";
|
|
42844
42847
|
let cursor = 0;
|
|
@@ -42859,12 +42862,17 @@ function patchGrids(src, installed, patch) {
|
|
|
42859
42862
|
const prefix = m[1].slice(0, -".verticals".length);
|
|
42860
42863
|
const baked = /* @__PURE__ */ new Map();
|
|
42861
42864
|
const foreignCells = [];
|
|
42862
|
-
|
|
42863
|
-
|
|
42864
|
-
const
|
|
42865
|
+
let faqCell;
|
|
42866
|
+
const claimOf = (item) => {
|
|
42867
|
+
const id = item?.id;
|
|
42868
|
+
const legacy = item?.modifiers?.accessibilityLabel;
|
|
42865
42869
|
const claim = typeof id === "string" && id ? id : typeof legacy === "string" ? legacy : "";
|
|
42866
|
-
|
|
42870
|
+
return claim.startsWith(`${prefix}.`) ? claim.slice(prefix.length + 1) : "";
|
|
42871
|
+
};
|
|
42872
|
+
for (const item of items) {
|
|
42873
|
+
const vertical = claimOf(item);
|
|
42867
42874
|
if (isKnown(vertical)) baked.set(vertical, item);
|
|
42875
|
+
else if (vertical === "faq" && keepFaq) faqCell = item;
|
|
42868
42876
|
else if (!GRID_VERTICAL_LABELS.has(vertical)) foreignCells.push(item);
|
|
42869
42877
|
}
|
|
42870
42878
|
const wanted = [];
|
|
@@ -42882,10 +42890,36 @@ function patchGrids(src, installed, patch) {
|
|
|
42882
42890
|
wanted.push(vertical);
|
|
42883
42891
|
}
|
|
42884
42892
|
const shape = baked.values().next().value ?? items[0];
|
|
42893
|
+
const bakedFaq = faqCell;
|
|
42894
|
+
if (keepFaq && !faqCell && hasScreen(src, FAQ_CARD.screenId)) {
|
|
42895
|
+
faqCell = cloneCell(shape, prefix, "faq", FAQ_CARD);
|
|
42896
|
+
}
|
|
42897
|
+
if (!installed.size) {
|
|
42898
|
+
if (dropFaq) {
|
|
42899
|
+
const kept = items.filter((item) => claimOf(item) !== "faq");
|
|
42900
|
+
if (kept.length !== items.length && kept.length > 0) {
|
|
42901
|
+
node.body.props.items = kept;
|
|
42902
|
+
out += src.slice(cursor, open) + serializeAt(node, src, open);
|
|
42903
|
+
cursor = close;
|
|
42904
|
+
OPEN.lastIndex = close;
|
|
42905
|
+
}
|
|
42906
|
+
continue;
|
|
42907
|
+
}
|
|
42908
|
+
const lastIsVertical = GRID_VERTICAL_LABELS.has(claimOf(items[items.length - 1]));
|
|
42909
|
+
if (!bakedFaq && faqCell && (items.length < EXPLORE_MAX_CELLS || lastIsVertical)) {
|
|
42910
|
+
if (items.length >= EXPLORE_MAX_CELLS) items.pop();
|
|
42911
|
+
items.push(faqCell);
|
|
42912
|
+
out += src.slice(cursor, open) + serializeAt(node, src, open);
|
|
42913
|
+
cursor = close;
|
|
42914
|
+
OPEN.lastIndex = close;
|
|
42915
|
+
}
|
|
42916
|
+
continue;
|
|
42917
|
+
}
|
|
42918
|
+
const cap = faqCell ? EXPLORE_MAX_CELLS - 1 : EXPLORE_MAX_CELLS;
|
|
42885
42919
|
const next = [...foreignCells];
|
|
42886
42920
|
const cells = [];
|
|
42887
42921
|
for (const vertical of wanted) {
|
|
42888
|
-
if (next.length >=
|
|
42922
|
+
if (next.length >= cap) break;
|
|
42889
42923
|
const bakedCell = baked.get(vertical);
|
|
42890
42924
|
if (bakedCell) {
|
|
42891
42925
|
next.push(bakedCell);
|
|
@@ -42901,6 +42935,7 @@ function patchGrids(src, installed, patch) {
|
|
|
42901
42935
|
cells.push(vertical);
|
|
42902
42936
|
patch.added.push(vertical);
|
|
42903
42937
|
}
|
|
42938
|
+
if (faqCell && next.length < EXPLORE_MAX_CELLS) next.push(faqCell);
|
|
42904
42939
|
if (!cells.length) continue;
|
|
42905
42940
|
patch.cells = cells;
|
|
42906
42941
|
node.body.props.items = next;
|
|
@@ -43015,16 +43050,19 @@ function patchStoreCtas(src, verticals, homeActionId) {
|
|
|
43015
43050
|
dropped
|
|
43016
43051
|
};
|
|
43017
43052
|
}
|
|
43018
|
-
function patchHomeForVerticals(src, verticals, homeActionId) {
|
|
43053
|
+
function patchHomeForVerticals(src, verticals, homeActionId, opts = {}) {
|
|
43019
43054
|
const installed = new Set(verticals.filter(isKnown));
|
|
43020
43055
|
const patch = { src, cells: [], added: [], droppedModules: [], droppedCtas: [], unreachable: [] };
|
|
43021
|
-
if (!installed.size)
|
|
43022
|
-
|
|
43056
|
+
if (!installed.size) {
|
|
43057
|
+
if (opts.keepFaq || opts.dropFaq) patch.src = patchGrids(src, installed, patch, !!opts.keepFaq, !opts.keepFaq && !!opts.dropFaq);
|
|
43058
|
+
return patch;
|
|
43059
|
+
}
|
|
43060
|
+
const ctas = patchStoreCtas(patchModules(patchGrids(src, installed, patch, opts.keepFaq), installed, patch), [...installed], homeActionId);
|
|
43023
43061
|
patch.src = ctas.src;
|
|
43024
43062
|
patch.droppedCtas = ctas.dropped;
|
|
43025
43063
|
return patch;
|
|
43026
43064
|
}
|
|
43027
|
-
var EXPLORE_CARDS, EXPLORE_ORDER, EXPLORE_MAX_CELLS, MODULE_SOURCE_VERTICALS, isKnown, GRID_VERTICAL_LABELS, escapeRe2, textProps, STORE_SCREENS, isStoreScreen, screenDeclarations, isNode2;
|
|
43065
|
+
var EXPLORE_CARDS, EXPLORE_ORDER, EXPLORE_MAX_CELLS, MODULE_SOURCE_VERTICALS, isKnown, GRID_VERTICAL_LABELS, FAQ_CARD, escapeRe2, textProps, STORE_SCREENS, isStoreScreen, screenDeclarations, isNode2;
|
|
43028
43066
|
var init_home_descriptor = __esm({
|
|
43029
43067
|
"src/site-analyze/home-descriptor.ts"() {
|
|
43030
43068
|
init_types2();
|
|
@@ -43096,6 +43134,7 @@ var init_home_descriptor = __esm({
|
|
|
43096
43134
|
};
|
|
43097
43135
|
isKnown = (v) => KNOWN_VERTICALS.includes(v);
|
|
43098
43136
|
GRID_VERTICAL_LABELS = /* @__PURE__ */ new Set([...KNOWN_VERTICALS, "faq"]);
|
|
43137
|
+
FAQ_CARD = { icon: "help", screenId: "himi_faq", title: "FAQ", body: "Find answers to common questions." };
|
|
43099
43138
|
escapeRe2 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
43100
43139
|
textProps = (n) => n?.body?.props;
|
|
43101
43140
|
STORE_SCREENS = /* @__PURE__ */ new Set([
|
|
@@ -54141,7 +54180,28 @@ function deriveTailoring(ctx, overrides = {}, revision = "site-derived") {
|
|
|
54141
54180
|
};
|
|
54142
54181
|
return { appName, iconSource: deriveIconSource(ctx), provisioning, missing };
|
|
54143
54182
|
}
|
|
54144
|
-
|
|
54183
|
+
function bounded(s, max) {
|
|
54184
|
+
if (s.length <= max) return s;
|
|
54185
|
+
const cut = s.slice(0, max - 1);
|
|
54186
|
+
const space = cut.lastIndexOf(" ");
|
|
54187
|
+
return `${(space > max * 0.6 ? cut.slice(0, space) : cut).trimEnd()}\u2026`;
|
|
54188
|
+
}
|
|
54189
|
+
function deriveStaticFaq(faq) {
|
|
54190
|
+
if (!Array.isArray(faq)) return [];
|
|
54191
|
+
const out = [];
|
|
54192
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54193
|
+
for (const raw of faq) {
|
|
54194
|
+
if (out.length >= STATIC_FAQ_LIMITS.pairs) break;
|
|
54195
|
+
const pair = raw && typeof raw === "object" ? raw : {};
|
|
54196
|
+
const q = bounded(oneLine(pair.q), STATIC_FAQ_LIMITS.question);
|
|
54197
|
+
const a = bounded(oneLine(pair.a), STATIC_FAQ_LIMITS.answer);
|
|
54198
|
+
if (!q || !a || seen.has(q.toLowerCase())) continue;
|
|
54199
|
+
seen.add(q.toLowerCase());
|
|
54200
|
+
out.push({ q, a });
|
|
54201
|
+
}
|
|
54202
|
+
return out;
|
|
54203
|
+
}
|
|
54204
|
+
var clean, ID_MAX, NAME_MAX, TYPE_MAX, CONTROL_CHARS, HAS_CONTROL_CHAR, plain, shown, STATIC_FAQ_LIMITS, oneLine;
|
|
54145
54205
|
var init_derive = __esm({
|
|
54146
54206
|
"src/site-analyze/derive.ts"() {
|
|
54147
54207
|
init_types2();
|
|
@@ -54153,6 +54213,8 @@ var init_derive = __esm({
|
|
|
54153
54213
|
HAS_CONTROL_CHAR = /[\u0000-\u001F\u007F]/;
|
|
54154
54214
|
plain = (value, max) => (value ?? "").replace(CONTROL_CHARS, "").trim().slice(0, max);
|
|
54155
54215
|
shown = (value) => (typeof value === "string" ? JSON.stringify(value) : String(value)).slice(0, 64);
|
|
54216
|
+
STATIC_FAQ_LIMITS = { pairs: 20, question: 200, answer: 1500 };
|
|
54217
|
+
oneLine = (s) => typeof s === "string" ? s.replace(/[\u0000-\u001F\u007F\s]+/g, " ").trim() : "";
|
|
54156
54218
|
}
|
|
54157
54219
|
});
|
|
54158
54220
|
|
|
@@ -57211,7 +57273,8 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
57211
57273
|
"navigation",
|
|
57212
57274
|
"locale",
|
|
57213
57275
|
"wix",
|
|
57214
|
-
"copy"
|
|
57276
|
+
"copy",
|
|
57277
|
+
"faq"
|
|
57215
57278
|
];
|
|
57216
57279
|
const customer = {};
|
|
57217
57280
|
for (const key2 of CUSTOMER_OWNED) {
|
|
@@ -57305,12 +57368,56 @@ function buildMergedContract(options) {
|
|
|
57305
57368
|
staged.push(localPath);
|
|
57306
57369
|
return { path: path2, staged };
|
|
57307
57370
|
}
|
|
57371
|
+
function catalogTypography(overlay, template) {
|
|
57372
|
+
const typography = {};
|
|
57373
|
+
const notes = [];
|
|
57374
|
+
const base = template && typeof template === "object" ? template : {};
|
|
57375
|
+
const usable = (family) => typeof family === "string" && family.trim() !== "" && (family === SYSTEM_FONT_FAMILY || canonicalFamilyName(family) !== void 0);
|
|
57376
|
+
for (const [role, token] of Object.entries(overlay ?? {})) {
|
|
57377
|
+
const family = token?.family;
|
|
57378
|
+
if (typeof family !== "string" || family.trim() === "") {
|
|
57379
|
+
typography[role] = token;
|
|
57380
|
+
continue;
|
|
57381
|
+
}
|
|
57382
|
+
if (family === SYSTEM_FONT_FAMILY) {
|
|
57383
|
+
typography[role] = token;
|
|
57384
|
+
continue;
|
|
57385
|
+
}
|
|
57386
|
+
const canonical3 = canonicalFamilyName(family.trim());
|
|
57387
|
+
if (canonical3) {
|
|
57388
|
+
typography[role] = { ...token, family: canonical3 };
|
|
57389
|
+
continue;
|
|
57390
|
+
}
|
|
57391
|
+
const kept = base[role]?.family;
|
|
57392
|
+
const using = usable(kept) ? `the template's ${kept}` : `the template's default (${TIER1_FLOOR[0]})`;
|
|
57393
|
+
notes.push(`site font "${family}" (${role}) isn't in the font catalog; using ${using}`);
|
|
57394
|
+
}
|
|
57395
|
+
return { typography, notes };
|
|
57396
|
+
}
|
|
57397
|
+
function staticFaqFor(overlay, overlayPath) {
|
|
57398
|
+
const own3 = overlay.faq;
|
|
57399
|
+
if (own3 !== void 0) return deriveStaticFaq(own3);
|
|
57400
|
+
const bookPath = join59(dirname32(resolve45(overlayPath)), "book.json");
|
|
57401
|
+
if (!existsSync61(bookPath)) return void 0;
|
|
57402
|
+
try {
|
|
57403
|
+
const book = JSON.parse(readFileSync72(bookPath, "utf8"));
|
|
57404
|
+
const copy = book?.copy;
|
|
57405
|
+
if (!copy || typeof copy !== "object" || copy.unavailable) return void 0;
|
|
57406
|
+
const pairs = deriveStaticFaq(copy.faq);
|
|
57407
|
+
if (!pairs.length && copy.partial) return void 0;
|
|
57408
|
+
return pairs;
|
|
57409
|
+
} catch {
|
|
57410
|
+
return void 0;
|
|
57411
|
+
}
|
|
57412
|
+
}
|
|
57308
57413
|
async function applyOverlays(input) {
|
|
57309
57414
|
const cwd = resolve45(input.cwd);
|
|
57310
57415
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
57311
57416
|
assertKnownShell(shell);
|
|
57312
57417
|
const overlay = JSON.parse(readFileSync72(input.overlayPath, "utf8"));
|
|
57313
57418
|
const tokens = JSON.parse(readFileSync72(input.tokensPath, "utf8"));
|
|
57419
|
+
const faq = staticFaqFor(overlay, input.overlayPath);
|
|
57420
|
+
if (faq !== void 0) overlay.faq = faq;
|
|
57314
57421
|
const wrote = [];
|
|
57315
57422
|
const notes = [];
|
|
57316
57423
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -57344,9 +57451,11 @@ async function applyOverlays(input) {
|
|
|
57344
57451
|
}
|
|
57345
57452
|
const pkgProv = join59(cwd, "provisioning.json");
|
|
57346
57453
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
57454
|
+
let packageFaq = faq;
|
|
57347
57455
|
if (existsSync61(pkgProv)) {
|
|
57348
57456
|
const cur = JSON.parse(readFileSync72(pkgProv, "utf8"));
|
|
57349
57457
|
const merged = deepMerge4(cur, overlay);
|
|
57458
|
+
packageFaq = merged.faq;
|
|
57350
57459
|
writeFileSync27(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
57351
57460
|
wrote.push(pkgProv);
|
|
57352
57461
|
} else {
|
|
@@ -57356,7 +57465,13 @@ async function applyOverlays(input) {
|
|
|
57356
57465
|
const pkgTokens = join59(cwd, "tokens.json");
|
|
57357
57466
|
if (existsSync61(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
57358
57467
|
const cur = JSON.parse(readFileSync72(pkgTokens, "utf8"));
|
|
57359
|
-
|
|
57468
|
+
let tokensIn = tokens;
|
|
57469
|
+
if (tokens.typography) {
|
|
57470
|
+
const fonts = catalogTypography(tokens.typography, cur.typography);
|
|
57471
|
+
notes.push(...fonts.notes);
|
|
57472
|
+
tokensIn = { ...tokens, typography: fonts.typography };
|
|
57473
|
+
}
|
|
57474
|
+
const merged = deepMerge4(cur, tokensIn);
|
|
57360
57475
|
const mergedColors = merged.colors;
|
|
57361
57476
|
if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
|
|
57362
57477
|
merged.colors = alignAccentsToSurfaces(mergedColors, tokens.colors);
|
|
@@ -57379,8 +57494,16 @@ async function applyOverlays(input) {
|
|
|
57379
57494
|
const prev = readFileSync72(homeSrc, "utf8");
|
|
57380
57495
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
57381
57496
|
let next = patched.src;
|
|
57382
|
-
if (!patched.foreign &&
|
|
57383
|
-
|
|
57497
|
+
if (!patched.foreign && faq?.length && prev.includes('"tier5.himiBrandedFaq.load"') && !prev.includes('"staticFaq"')) {
|
|
57498
|
+
notes.push(
|
|
57499
|
+
"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"
|
|
57500
|
+
);
|
|
57501
|
+
}
|
|
57502
|
+
const keepFaq = Array.isArray(packageFaq) && packageFaq.length > 0;
|
|
57503
|
+
const dropFaq = Array.isArray(faq) && faq.length === 0;
|
|
57504
|
+
const ownsHome = prev.includes(`"actionId": "${homeAction}"`);
|
|
57505
|
+
if (ownsHome && !patched.foreign && (overlay.installedVerticals?.length || keepFaq || dropFaq)) {
|
|
57506
|
+
const home = patchHomeForVerticals(next, overlay.installedVerticals ?? [], homeAction, { keepFaq, dropFaq });
|
|
57384
57507
|
next = home.src;
|
|
57385
57508
|
if (home.droppedCtas.length) {
|
|
57386
57509
|
notes.push(`removed the home's store call(s) to action (${home.droppedCtas.join(", ")}) \u2014 this site has no store`);
|
|
@@ -57426,10 +57549,18 @@ function patchBrandParams(src, overlay, homeActionId) {
|
|
|
57426
57549
|
const layout = overlay.appearance?.homeLayout;
|
|
57427
57550
|
const accent = overlay.branding?.primaryColor;
|
|
57428
57551
|
const verts = overlay.installedVerticals;
|
|
57552
|
+
const faq = overlay.faq;
|
|
57429
57553
|
const edits = [
|
|
57430
57554
|
...layout ? [{ pattern: /"ownerDefaultLayout": "[^"]*"/g, replacement: `"ownerDefaultLayout": ${JSON.stringify(layout)}` }] : [],
|
|
57431
57555
|
...accent ? [{ pattern: /"brandAccent": "[^"]*"/g, replacement: `"brandAccent": ${JSON.stringify(accent)}` }] : [],
|
|
57432
|
-
...verts?.length ? [{ pattern: /"verticals": "\[[^\]]*\]"/g, replacement: `"verticals": ${JSON.stringify(JSON.stringify(verts))}` }] : []
|
|
57556
|
+
...verts?.length ? [{ pattern: /"verticals": "\[[^\]]*\]"/g, replacement: `"verticals": ${JSON.stringify(JSON.stringify(verts))}` }] : [],
|
|
57557
|
+
// The FAQ screen's fallback pairs (#3276), a JSON STRING like `verticals` because action
|
|
57558
|
+
// params are string-valued. The pattern matches any escaped string, so re-applying a
|
|
57559
|
+
// package whose pairs are already written replaces them instead of missing. A function
|
|
57560
|
+
// replacement, because the pairs are customer text and may contain `$&`. Patched whenever
|
|
57561
|
+
// the analysis SAID something, `[]` included, so a re-apply clears pairs an earlier one
|
|
57562
|
+
// baked in rather than leaving the worker another site's FAQ.
|
|
57563
|
+
...faq ? [{ pattern: /"staticFaq": "(?:[^"\\]|\\.)*"/g, replacement: `"staticFaq": ${JSON.stringify(JSON.stringify(faq))}` }] : []
|
|
57433
57564
|
];
|
|
57434
57565
|
if (!edits.length) return { src, applied: 0, unparsed: 0, foreign: false };
|
|
57435
57566
|
if (!src.includes(`"actionId": "${homeActionId}"`)) {
|
|
@@ -57474,7 +57605,7 @@ function patchBrandParams(src, overlay, homeActionId) {
|
|
|
57474
57605
|
pattern.lastIndex = 0;
|
|
57475
57606
|
if (!pattern.test(block)) continue;
|
|
57476
57607
|
pattern.lastIndex = 0;
|
|
57477
|
-
block = block.replace(pattern, replacement);
|
|
57608
|
+
block = block.replace(pattern, () => replacement);
|
|
57478
57609
|
applied += 1;
|
|
57479
57610
|
}
|
|
57480
57611
|
out += src.slice(cursor, open) + block;
|
|
@@ -57492,6 +57623,10 @@ var init_apply2 = __esm({
|
|
|
57492
57623
|
init_branding_derive();
|
|
57493
57624
|
init_brand_color_math();
|
|
57494
57625
|
init_home_descriptor();
|
|
57626
|
+
init_derive();
|
|
57627
|
+
init_catalog();
|
|
57628
|
+
init_plan_fonts();
|
|
57629
|
+
init_tokens();
|
|
57495
57630
|
STAGED = ".himi/brand";
|
|
57496
57631
|
}
|
|
57497
57632
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1048.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": [
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"artifactId": "himalaya-cli"
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
"falconPackageHash": "
|
|
68
|
+
"falconPackageHash": "dc270534070a6b5e662ac7738098c1328a07b027779bddf2a5d71a20"
|
|
69
69
|
}
|
|
@@ -58239,7 +58239,8 @@ const SCREENS = runtimeSetting({
|
|
|
58239
58239
|
"onAppear": {
|
|
58240
58240
|
"actionId": "tier5.himiBrandedFaq.load",
|
|
58241
58241
|
"params": {
|
|
58242
|
-
"otherCategory": "Other"
|
|
58242
|
+
"otherCategory": "Other",
|
|
58243
|
+
"staticFaq": "[]"
|
|
58243
58244
|
}
|
|
58244
58245
|
}
|
|
58245
58246
|
}
|
|
@@ -58,6 +58,55 @@ interface FaqState {
|
|
|
58
58
|
|
|
59
59
|
const PAGE_SIZE = 100;
|
|
60
60
|
|
|
61
|
+
/** Caps on the static pairs, matching `BRANDED_LITE_FAQ_LIMITS` in the app contract. The
|
|
62
|
+
* param is re-bounded here because a worker must not trust a descriptor it did not build. */
|
|
63
|
+
const STATIC_LIMITS = { pairs: 20, question: 200, answer: 1500 } as const;
|
|
64
|
+
const STATIC_CATEGORY: FaqCategory = { id: "himi-static-faq", title: "" };
|
|
65
|
+
|
|
66
|
+
/** The site's own FAQ pairs — questions it publishes as page sections rather than
|
|
67
|
+
* through the Wix FAQ app, carried in by `site analyze --apply` as the `staticFaq` onAppear
|
|
68
|
+
* param (a JSON string: action params are string-valued). They are the FALLBACK: shown only
|
|
69
|
+
* when the FAQ app yields no visible question, so an owner-edited Wix FAQ always wins. */
|
|
70
|
+
let staticQuestions: FaqQuestion[] = [];
|
|
71
|
+
|
|
72
|
+
function parseStaticFaq(raw: unknown): FaqQuestion[] {
|
|
73
|
+
let pairs: unknown = raw;
|
|
74
|
+
if (typeof raw === "string") {
|
|
75
|
+
try {
|
|
76
|
+
pairs = JSON.parse(raw);
|
|
77
|
+
} catch {
|
|
78
|
+
// A malformed param is a DESCRIPTOR bug, not an empty FAQ: there is no fallback to
|
|
79
|
+
// offer, so the screen shows exactly what the Wix FAQ read says — its content, its
|
|
80
|
+
// empty card, or its error card — rather than pretending the site has no questions.
|
|
81
|
+
pairs = undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!Array.isArray(pairs)) return [];
|
|
85
|
+
const out: FaqQuestion[] = [];
|
|
86
|
+
for (const pair of pairs) {
|
|
87
|
+
if (out.length >= STATIC_LIMITS.pairs) break;
|
|
88
|
+
const row = pair && typeof pair === "object" ? pair as { q?: unknown; a?: unknown } : {};
|
|
89
|
+
const question = typeof row.q === "string" ? row.q.trim().slice(0, STATIC_LIMITS.question) : "";
|
|
90
|
+
const answer = typeof row.a === "string" ? row.a.trim().slice(0, STATIC_LIMITS.answer) : "";
|
|
91
|
+
if (!question || !answer) continue;
|
|
92
|
+
out.push({
|
|
93
|
+
id: `himi-static-faq-${out.length}`,
|
|
94
|
+
categoryId: STATIC_CATEGORY.id,
|
|
95
|
+
question,
|
|
96
|
+
answer,
|
|
97
|
+
sortOrder: out.length,
|
|
98
|
+
status: "VISIBLE",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The site's pairs as a ready state, or undefined when there are none to fall back to. */
|
|
105
|
+
function staticFallback(state: FaqState): FaqState | undefined {
|
|
106
|
+
if (!staticQuestions.length) return undefined;
|
|
107
|
+
return ready({ ...state, categories: [STATIC_CATEGORY], questions: staticQuestions });
|
|
108
|
+
}
|
|
109
|
+
|
|
61
110
|
function sortByWixOrder<T extends { id: string; sortOrder?: number }>(left: T, right: T): number {
|
|
62
111
|
const a = Number.isFinite(left.sortOrder) ? left.sortOrder! : Number.POSITIVE_INFINITY;
|
|
63
112
|
const b = Number.isFinite(right.sortOrder) ? right.sortOrder! : Number.POSITIVE_INFINITY;
|
|
@@ -101,7 +150,8 @@ function ready(state: FaqState): FaqState {
|
|
|
101
150
|
const rows = sections.flatMap((section) => section.questions.map((question, index) => ({
|
|
102
151
|
...question,
|
|
103
152
|
categoryTitle: section.title,
|
|
104
|
-
|
|
153
|
+
// An untitled section (the static fallback's) has no header to show.
|
|
154
|
+
categoryHeaderHidden: index !== 0 || !section.title,
|
|
105
155
|
})));
|
|
106
156
|
return {
|
|
107
157
|
...state,
|
|
@@ -218,17 +268,28 @@ function commit(state: FaqState): FaqState {
|
|
|
218
268
|
return state;
|
|
219
269
|
}
|
|
220
270
|
|
|
221
|
-
async function loadFaq(state: FaqState, arg?: { otherCategory?: string }): Promise<FaqState> {
|
|
271
|
+
async function loadFaq(state: FaqState, arg?: { otherCategory?: string; staticFaq?: unknown }): Promise<FaqState> {
|
|
222
272
|
latestState = state;
|
|
273
|
+
// Only when the caller passed the param: `retry` is dispatched with no params and must keep
|
|
274
|
+
// the pairs the screen's onAppear delivered.
|
|
275
|
+
if (arg && "staticFaq" in arg) staticQuestions = parseStaticFaq(arg.staticFaq);
|
|
223
276
|
const generation = ++loadGeneration;
|
|
224
277
|
try {
|
|
225
278
|
const [categories, questions] = await Promise.all([allCategories(), allQuestions()]);
|
|
226
279
|
if (generation !== loadGeneration) return latestState;
|
|
227
280
|
const otherTitle = String(arg?.otherCategory ?? latestState.otherTitle).trim() || latestState.otherTitle;
|
|
228
|
-
|
|
281
|
+
const live = ready({ ...latestState, categories, questions, otherTitle });
|
|
282
|
+
// The Wix FAQ app answered but holds nothing a visitor can see — the site's own pairs,
|
|
283
|
+
// when it has any, instead of an empty state over a site whose FAQ is right there.
|
|
284
|
+
if (questions.length === 0) return commit(staticFallback(live) ?? live);
|
|
285
|
+
return commit(live);
|
|
229
286
|
} catch (error) {
|
|
230
287
|
if (generation !== loadGeneration) return latestState;
|
|
231
288
|
const status = httpStatus(error);
|
|
289
|
+
// No FAQ app (428), no visitor access (403) or a failed read: a site whose FAQ is page
|
|
290
|
+
// content still has an FAQ to show, so its pairs replace the failure card.
|
|
291
|
+
const fallback = staticFallback(latestState);
|
|
292
|
+
if (fallback) return commit(fallback);
|
|
232
293
|
return commit(failure(latestState, status === 403 ? "forbidden" : status === 428 ? "notInstalled" : "error"));
|
|
233
294
|
}
|
|
234
295
|
}
|
|
@@ -250,4 +311,4 @@ const svc = defineService("himiBrandedFaq", {
|
|
|
250
311
|
},
|
|
251
312
|
});
|
|
252
313
|
|
|
253
|
-
export { svc, sectionsFor, httpStatus };
|
|
314
|
+
export { svc, sectionsFor, httpStatus, parseStaticFaq };
|