@wix/himalaya-cli 0.1110.0 → 0.1112.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 +908 -663
- package/guides/getting-started.md +18 -3
- package/guides/himi-skill.md +18 -3
- package/guides/push-cli-onboarding.md +58 -4
- package/guides/skill.md +4 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -994,8 +994,8 @@ function mobileUxDocumentBody(mobile) {
|
|
|
994
994
|
}
|
|
995
995
|
return out2 + mobile.slice(last);
|
|
996
996
|
}
|
|
997
|
-
function mobileUxSection(
|
|
998
|
-
const match = new RegExp(`(?:^|\\n)##[ \\t]+${heading}\\b[^\\n]*([\\s\\S]*?)(?=\\n##[ \\t]|$)`, "i").exec(
|
|
997
|
+
function mobileUxSection(text8, heading) {
|
|
998
|
+
const match = new RegExp(`(?:^|\\n)##[ \\t]+${heading}\\b[^\\n]*([\\s\\S]*?)(?=\\n##[ \\t]|$)`, "i").exec(text8);
|
|
999
999
|
return match ? match[1] : null;
|
|
1000
1000
|
}
|
|
1001
1001
|
function sectionTables(markdown) {
|
|
@@ -1024,8 +1024,8 @@ function namesOneCta(cell) {
|
|
|
1024
1024
|
if (!cell) return false;
|
|
1025
1025
|
return !/[,;]|\s\/\s/.test(cell);
|
|
1026
1026
|
}
|
|
1027
|
-
function declaredStates(
|
|
1028
|
-
const contract = section(
|
|
1027
|
+
function declaredStates(text8) {
|
|
1028
|
+
const contract = section(text8, "Screen contract");
|
|
1029
1029
|
if (!contract) return [];
|
|
1030
1030
|
const states = [];
|
|
1031
1031
|
for (const bullet of contract.matchAll(/^[ \t]*[-*][ \t]*[^:\n]*\bstates?[ \t]*:[ \t]*(\S.*)$/gim)) {
|
|
@@ -1035,8 +1035,8 @@ function declaredStates(text6) {
|
|
|
1035
1035
|
}
|
|
1036
1036
|
return [...new Set(states.map((state) => state.toLowerCase()))];
|
|
1037
1037
|
}
|
|
1038
|
-
function primaryCtaStructureGap(
|
|
1039
|
-
const acceptance = section(
|
|
1038
|
+
function primaryCtaStructureGap(text8) {
|
|
1039
|
+
const acceptance = section(text8, "Implementation acceptance");
|
|
1040
1040
|
if (acceptance === null) return "There is no `## Implementation acceptance` section to read it from.";
|
|
1041
1041
|
const tables = sectionTables(acceptance).filter((table) => table.data.length > 0);
|
|
1042
1042
|
if (!tables.length) return "Its acceptance table has no rows.";
|
|
@@ -1049,7 +1049,7 @@ function primaryCtaStructureGap(text6) {
|
|
|
1049
1049
|
const data = ctaTables.flatMap(({ table }) => table.data);
|
|
1050
1050
|
const flat = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
1051
1051
|
const rowText = data.map((row) => flat(row.join(" ")));
|
|
1052
|
-
const missing = declaredStates(
|
|
1052
|
+
const missing = declaredStates(text8).filter((state) => !rowText.some((row) => row.includes(flat(state))));
|
|
1053
1053
|
if (missing.length) return `The acceptance table has no row for the declared state(s): ${missing.join(", ")}.`;
|
|
1054
1054
|
return null;
|
|
1055
1055
|
}
|
|
@@ -1064,16 +1064,16 @@ function hasUnterminatedComment(mobile) {
|
|
|
1064
1064
|
}
|
|
1065
1065
|
}
|
|
1066
1066
|
function mobileUxMarkerFindings(mobile, renderedWidths = []) {
|
|
1067
|
-
const
|
|
1067
|
+
const text8 = mobileUxDocumentBody(mobile);
|
|
1068
1068
|
const findings = [];
|
|
1069
|
-
if (!/^## Implementation acceptance\b/im.test(
|
|
1069
|
+
if (!/^## Implementation acceptance\b/im.test(text8)) {
|
|
1070
1070
|
findings.push({ code: "missing-acceptance-matrix", message: "MOBILE-UX.md must contain the heading `## Implementation acceptance` at the start of a line. Case is not checked, but use this spelling: other tooling addresses the document by it." });
|
|
1071
1071
|
}
|
|
1072
|
-
if (!/^## Evidence\b/im.test(
|
|
1072
|
+
if (!/^## Evidence\b/im.test(text8)) {
|
|
1073
1073
|
findings.push({ code: "missing-evidence-section", message: "MOBILE-UX.md must contain the heading `## Evidence` at the start of a line. Case is not checked, but use this spelling: other tooling addresses the document by it." });
|
|
1074
1074
|
}
|
|
1075
|
-
if (!/one primary CTA per state/i.test(
|
|
1076
|
-
const gap = primaryCtaStructureGap(
|
|
1075
|
+
if (!/one primary CTA per state/i.test(text8)) {
|
|
1076
|
+
const gap = primaryCtaStructureGap(text8);
|
|
1077
1077
|
if (gap) {
|
|
1078
1078
|
findings.push({
|
|
1079
1079
|
code: "missing-primary-cta-rule",
|
|
@@ -1081,8 +1081,8 @@ function mobileUxMarkerFindings(mobile, renderedWidths = []) {
|
|
|
1081
1081
|
});
|
|
1082
1082
|
}
|
|
1083
1083
|
}
|
|
1084
|
-
if (!hasWidthEvidence(
|
|
1085
|
-
findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(
|
|
1084
|
+
if (!hasWidthEvidence(text8, renderedWidths)) {
|
|
1085
|
+
findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(text8, renderedWidths) });
|
|
1086
1086
|
}
|
|
1087
1087
|
if (findings.length && hasUnterminatedComment(mobile)) {
|
|
1088
1088
|
return [{
|
|
@@ -1092,15 +1092,15 @@ function mobileUxMarkerFindings(mobile, renderedWidths = []) {
|
|
|
1092
1092
|
}
|
|
1093
1093
|
return findings;
|
|
1094
1094
|
}
|
|
1095
|
-
function widthMentions(
|
|
1095
|
+
function widthMentions(text8) {
|
|
1096
1096
|
const mentions = [];
|
|
1097
|
-
for (const match of
|
|
1097
|
+
for (const match of text8.matchAll(/\d+/g)) {
|
|
1098
1098
|
const value = Number(match[0]);
|
|
1099
1099
|
const start = match.index ?? 0;
|
|
1100
1100
|
if (!inRange(value)) continue;
|
|
1101
1101
|
const end = start + match[0].length;
|
|
1102
|
-
const after =
|
|
1103
|
-
const before =
|
|
1102
|
+
const after = text8.slice(end, end + EDGE_WINDOW);
|
|
1103
|
+
const before = text8.slice(Math.max(0, start - EDGE_WINDOW), start);
|
|
1104
1104
|
if (looksLikeYear(value) && !(UNIT_ATTACHED.test(after) || UNIT_WORD_ATTACHED.test(after))) continue;
|
|
1105
1105
|
const spelledAsWidth = UNIT_ATTACHED.test(after) || UNIT_WORD_ATTACHED.test(after) || FILENAME_AFTER.test(after);
|
|
1106
1106
|
const vetoed = spelledAsWidth && (ANTI_CUE_BEFORE.test(before) || PAIR_HEIGHT_BEFORE.test(before) || ANTI_CUE_AFTER.test(after));
|
|
@@ -2093,7 +2093,7 @@ function foldLegacyReport(legacy, seed2) {
|
|
|
2093
2093
|
...arrayField(legacy.failures),
|
|
2094
2094
|
...arrayField(legacy.warnings)
|
|
2095
2095
|
];
|
|
2096
|
-
const
|
|
2096
|
+
const report3 = emptyReport({
|
|
2097
2097
|
...seed2,
|
|
2098
2098
|
ok: typeof legacy.ok === "boolean" ? legacy.ok : seed2.ok,
|
|
2099
2099
|
app: seed2.app ?? stringField(legacy.app),
|
|
@@ -2104,12 +2104,12 @@ function foldLegacyReport(legacy, seed2) {
|
|
|
2104
2104
|
const oldCounts = recordField(legacy.counts);
|
|
2105
2105
|
return {
|
|
2106
2106
|
...legacy,
|
|
2107
|
-
...
|
|
2107
|
+
...report3,
|
|
2108
2108
|
counts: {
|
|
2109
2109
|
...oldCounts,
|
|
2110
|
-
errors: numberField(oldCounts.errors) ??
|
|
2111
|
-
warnings: numberField(oldCounts.warnings) ??
|
|
2112
|
-
gaps:
|
|
2110
|
+
errors: numberField(oldCounts.errors) ?? report3.counts.errors,
|
|
2111
|
+
warnings: numberField(oldCounts.warnings) ?? report3.counts.warnings,
|
|
2112
|
+
gaps: report3.counts.gaps
|
|
2113
2113
|
}
|
|
2114
2114
|
};
|
|
2115
2115
|
}
|
|
@@ -2773,8 +2773,8 @@ function isAttestationV2(value) {
|
|
|
2773
2773
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
2774
2774
|
const a = value;
|
|
2775
2775
|
const coverage = a.coverage;
|
|
2776
|
-
const
|
|
2777
|
-
return a.attestation === 2 && typeof a.runId === "string" && ["himi-test", "himi-render", "himi-shots"].includes(a.tool) && [a.app, a.contentDir, a.gitDiffHash, a.gitUntrackedHash, a.releaseId, a.releaseHash, a.selfHash].every((item) => typeof item === "string" && item.length > 0) && stringRecord(a.descriptorHashes) && stringRecord(a.screenshots) && !!coverage && [coverage.screens, coverage.actionsDispatched, coverage.uncoveredFns, coverage.gaps].every((count2) => typeof count2 === "number" && Number.isFinite(count2) && count2 >= 0) && typeof
|
|
2776
|
+
const report3 = a.report;
|
|
2777
|
+
return a.attestation === 2 && typeof a.runId === "string" && ["himi-test", "himi-render", "himi-shots"].includes(a.tool) && [a.app, a.contentDir, a.gitDiffHash, a.gitUntrackedHash, a.releaseId, a.releaseHash, a.selfHash].every((item) => typeof item === "string" && item.length > 0) && stringRecord(a.descriptorHashes) && stringRecord(a.screenshots) && !!coverage && [coverage.screens, coverage.actionsDispatched, coverage.uncoveredFns, coverage.gaps].every((count2) => typeof count2 === "number" && Number.isFinite(count2) && count2 >= 0) && typeof report3?.ok === "boolean" && !!report3.counts && [report3.counts.errors, report3.counts.warnings, report3.counts.gaps].every((count2) => typeof count2 === "number" && Number.isFinite(count2) && count2 >= 0) && (a.prev === null || typeof a.prev === "string");
|
|
2778
2778
|
}
|
|
2779
2779
|
function readLatestAttestation(contentDir2) {
|
|
2780
2780
|
try {
|
|
@@ -3170,8 +3170,8 @@ function penalty(m, size) {
|
|
|
3170
3170
|
score += Math.floor(Math.abs(dark * 20 - total * 10) / total) * 10;
|
|
3171
3171
|
return score;
|
|
3172
3172
|
}
|
|
3173
|
-
function encodeQr(
|
|
3174
|
-
const bytes2 = [...new TextEncoder().encode(
|
|
3173
|
+
function encodeQr(text8) {
|
|
3174
|
+
const bytes2 = [...new TextEncoder().encode(text8)];
|
|
3175
3175
|
const version2 = fitVersion(bytes2.length);
|
|
3176
3176
|
if (!version2) {
|
|
3177
3177
|
throw new RangeError(`QR payload too long: ${bytes2.length} bytes exceeds version ${QR_MAX_VERSION} at EC level L`);
|
|
@@ -3742,7 +3742,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
3742
3742
|
tokenCache.set(cacheKey, fromEnv);
|
|
3743
3743
|
return fromEnv;
|
|
3744
3744
|
}
|
|
3745
|
-
const token = await new Promise((
|
|
3745
|
+
const token = await new Promise((resolve53, reject) => {
|
|
3746
3746
|
let child;
|
|
3747
3747
|
try {
|
|
3748
3748
|
child = spawnImpl("wix", [...args]);
|
|
@@ -3771,12 +3771,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
3771
3771
|
child.stdout?.on("data", (d) => {
|
|
3772
3772
|
out2 += String(d);
|
|
3773
3773
|
const m = out2.match(TOKEN_RE);
|
|
3774
|
-
if (m) done(() =>
|
|
3774
|
+
if (m) done(() => resolve53(m[0]));
|
|
3775
3775
|
});
|
|
3776
3776
|
child.stderr?.on("data", (d) => {
|
|
3777
3777
|
out2 += String(d);
|
|
3778
3778
|
const m = out2.match(TOKEN_RE);
|
|
3779
|
-
if (m) done(() =>
|
|
3779
|
+
if (m) done(() => resolve53(m[0]));
|
|
3780
3780
|
});
|
|
3781
3781
|
child.on("error", (e) => done(() => reject(new Error(mintHelp(label2, e.message)))));
|
|
3782
3782
|
child.on("exit", (code) => done(() => reject(new Error(
|
|
@@ -3821,10 +3821,10 @@ function ownerTransport(msid, fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS2
|
|
|
3821
3821
|
}
|
|
3822
3822
|
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
3823
3823
|
}
|
|
3824
|
-
const
|
|
3825
|
-
let parsed =
|
|
3824
|
+
const text8 = await res.text();
|
|
3825
|
+
let parsed = text8;
|
|
3826
3826
|
try {
|
|
3827
|
-
parsed =
|
|
3827
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
3828
3828
|
} catch {
|
|
3829
3829
|
}
|
|
3830
3830
|
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
@@ -4486,18 +4486,18 @@ function confinementPlugin(contentRoot) {
|
|
|
4486
4486
|
}
|
|
4487
4487
|
function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
4488
4488
|
const seen = /* @__PURE__ */ new Set();
|
|
4489
|
-
const
|
|
4489
|
+
const refuse5 = (p, why) => {
|
|
4490
4490
|
throw new Error(
|
|
4491
4491
|
`refused to read ${p}: ${why}. A tsconfig may extend a file from its own package or an installed dependency \u2014 nothing else.`
|
|
4492
4492
|
);
|
|
4493
4493
|
};
|
|
4494
|
-
const stripJsonc = (
|
|
4495
|
-
if (
|
|
4494
|
+
const stripJsonc = (text8) => {
|
|
4495
|
+
if (text8.charCodeAt(0) === 65279) text8 = text8.slice(1);
|
|
4496
4496
|
let out2 = "";
|
|
4497
4497
|
let inStr = false;
|
|
4498
4498
|
let esc = false;
|
|
4499
|
-
for (let i = 0; i <
|
|
4500
|
-
const c =
|
|
4499
|
+
for (let i = 0; i < text8.length; i++) {
|
|
4500
|
+
const c = text8[i];
|
|
4501
4501
|
if (inStr) {
|
|
4502
4502
|
out2 += c;
|
|
4503
4503
|
if (esc) esc = false;
|
|
@@ -4510,13 +4510,13 @@ function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
|
4510
4510
|
out2 += c;
|
|
4511
4511
|
continue;
|
|
4512
4512
|
}
|
|
4513
|
-
if (c === "/" &&
|
|
4514
|
-
while (i <
|
|
4513
|
+
if (c === "/" && text8[i + 1] === "/") {
|
|
4514
|
+
while (i < text8.length && text8[i] !== "\n") i++;
|
|
4515
4515
|
continue;
|
|
4516
4516
|
}
|
|
4517
|
-
if (c === "/" &&
|
|
4517
|
+
if (c === "/" && text8[i + 1] === "*") {
|
|
4518
4518
|
i += 2;
|
|
4519
|
-
while (i <
|
|
4519
|
+
while (i < text8.length && !(text8[i] === "*" && text8[i + 1] === "/")) i++;
|
|
4520
4520
|
i++;
|
|
4521
4521
|
continue;
|
|
4522
4522
|
}
|
|
@@ -4552,7 +4552,7 @@ function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
|
4552
4552
|
try {
|
|
4553
4553
|
manifest = JSON.parse(stripJsonc(readFileSync10(pj, "utf8")));
|
|
4554
4554
|
} catch {
|
|
4555
|
-
|
|
4555
|
+
refuse5(pj, "its package.json could not be parsed, so its `tsconfig` field cannot be checked");
|
|
4556
4556
|
}
|
|
4557
4557
|
const field = manifest?.tsconfig;
|
|
4558
4558
|
if (typeof field === "string" && field) {
|
|
@@ -4568,7 +4568,7 @@ function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
|
4568
4568
|
const real = realpathOrSelf(file);
|
|
4569
4569
|
if (seen.has(real)) return;
|
|
4570
4570
|
seen.add(real);
|
|
4571
|
-
if (!allows(real))
|
|
4571
|
+
if (!allows(real)) refuse5(file, "it is outside this content package");
|
|
4572
4572
|
let raw;
|
|
4573
4573
|
try {
|
|
4574
4574
|
raw = readFileSync10(real, "utf8");
|
|
@@ -4579,7 +4579,7 @@ function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
|
4579
4579
|
try {
|
|
4580
4580
|
parsed = JSON.parse(stripJsonc(raw));
|
|
4581
4581
|
} catch {
|
|
4582
|
-
|
|
4582
|
+
refuse5(file, "its tsconfig could not be parsed, so its `extends` cannot be checked");
|
|
4583
4583
|
}
|
|
4584
4584
|
const ext = parsed?.extends;
|
|
4585
4585
|
for (const one of Array.isArray(ext) ? ext : ext ? [ext] : []) {
|
|
@@ -8420,8 +8420,8 @@ function pushSpan(out2, s) {
|
|
|
8420
8420
|
else out2.push(s);
|
|
8421
8421
|
}
|
|
8422
8422
|
function spanOf(textNode) {
|
|
8423
|
-
const
|
|
8424
|
-
if (
|
|
8423
|
+
const text8 = str(at(textNode, "textData", "text"));
|
|
8424
|
+
if (text8 === "") return null;
|
|
8425
8425
|
let bold = false, italic = false, underline = false;
|
|
8426
8426
|
let link;
|
|
8427
8427
|
const decorations = at(textNode, "textData", "decorations");
|
|
@@ -8448,7 +8448,7 @@ function spanOf(textNode) {
|
|
|
8448
8448
|
}
|
|
8449
8449
|
}
|
|
8450
8450
|
}
|
|
8451
|
-
const span = { text:
|
|
8451
|
+
const span = { text: text8 };
|
|
8452
8452
|
if (bold) span.bold = true;
|
|
8453
8453
|
if (italic) span.italic = true;
|
|
8454
8454
|
if (underline) span.underline = true;
|
|
@@ -8670,8 +8670,8 @@ function blockOf(ids, n, path2) {
|
|
|
8670
8670
|
const { title, url } = cardFields(n, type);
|
|
8671
8671
|
return [card(ids.claim(n, path2), type, title, url)];
|
|
8672
8672
|
}
|
|
8673
|
-
const
|
|
8674
|
-
return
|
|
8673
|
+
const text8 = plainText(n);
|
|
8674
|
+
return text8.trim() !== "" ? [{ kind: "paragraph", id: ids.claim(n, path2), spans: [{ text: text8 }] }] : [];
|
|
8675
8675
|
}
|
|
8676
8676
|
}
|
|
8677
8677
|
}
|
|
@@ -9942,26 +9942,26 @@ function serviceOnlyBindingValues(props, key2) {
|
|
|
9942
9942
|
});
|
|
9943
9943
|
return out2;
|
|
9944
9944
|
}
|
|
9945
|
-
function matchBraceSafe(
|
|
9945
|
+
function matchBraceSafe(text8, open) {
|
|
9946
9946
|
let depth = 0;
|
|
9947
|
-
for (let i = open; i <
|
|
9948
|
-
const c =
|
|
9947
|
+
for (let i = open; i < text8.length; i++) {
|
|
9948
|
+
const c = text8[i];
|
|
9949
9949
|
if (c === '"' || c === "'" || c === "`") {
|
|
9950
9950
|
const q = c;
|
|
9951
9951
|
i++;
|
|
9952
|
-
while (i <
|
|
9953
|
-
if (
|
|
9952
|
+
while (i < text8.length && text8[i] !== q) {
|
|
9953
|
+
if (text8[i] === "\\") i++;
|
|
9954
9954
|
i++;
|
|
9955
9955
|
}
|
|
9956
9956
|
continue;
|
|
9957
9957
|
}
|
|
9958
|
-
if (c === "/" &&
|
|
9959
|
-
while (i <
|
|
9958
|
+
if (c === "/" && text8[i + 1] === "/") {
|
|
9959
|
+
while (i < text8.length && text8[i] !== "\n") i++;
|
|
9960
9960
|
continue;
|
|
9961
9961
|
}
|
|
9962
|
-
if (c === "/" &&
|
|
9962
|
+
if (c === "/" && text8[i + 1] === "*") {
|
|
9963
9963
|
i += 2;
|
|
9964
|
-
while (i <
|
|
9964
|
+
while (i < text8.length && !(text8[i] === "*" && text8[i + 1] === "/")) i++;
|
|
9965
9965
|
i++;
|
|
9966
9966
|
continue;
|
|
9967
9967
|
}
|
|
@@ -12909,8 +12909,8 @@ var init_owner_claim = __esm({
|
|
|
12909
12909
|
|
|
12910
12910
|
// ../native-config/car.ts
|
|
12911
12911
|
function parseCarConfig(configTs) {
|
|
12912
|
-
const { text:
|
|
12913
|
-
for (const m of
|
|
12912
|
+
const { text: text8, inString } = scanConfig(configTs);
|
|
12913
|
+
for (const m of text8.matchAll(/\bcar\s*[:=]\s*\{([^}]*)\}/g)) {
|
|
12914
12914
|
if (inString[m.index]) continue;
|
|
12915
12915
|
return { category: /category\s*:\s*["']([^"']+)["']/.exec(m[1])?.[1] };
|
|
12916
12916
|
}
|
|
@@ -17996,12 +17996,12 @@ function hostAppliesDeferredWidgetActions(app) {
|
|
|
17996
17996
|
}
|
|
17997
17997
|
return false;
|
|
17998
17998
|
}
|
|
17999
|
-
function hasMarkers(
|
|
18000
|
-
const lines =
|
|
17999
|
+
function hasMarkers(text8, kind, label2) {
|
|
18000
|
+
const lines = text8.split("\n");
|
|
18001
18001
|
return lines.some((l) => isBegin(l, kind, label2)) && lines.some((l) => isEnd(l, kind, label2));
|
|
18002
18002
|
}
|
|
18003
|
-
function injectBlock(
|
|
18004
|
-
const lines =
|
|
18003
|
+
function injectBlock(text8, kind, label2, render) {
|
|
18004
|
+
const lines = text8.split("\n");
|
|
18005
18005
|
const beginIdx = lines.findIndex((l) => isBegin(l, kind, label2));
|
|
18006
18006
|
const endIdx = lines.findIndex((l) => isEnd(l, kind, label2));
|
|
18007
18007
|
if (beginIdx === -1 || endIdx === -1 || endIdx < beginIdx) {
|
|
@@ -18116,8 +18116,8 @@ function genNativeConfig(app, opts = {}) {
|
|
|
18116
18116
|
];
|
|
18117
18117
|
const rce = declaresRichContentEditor(configTs);
|
|
18118
18118
|
for (const yml of [iosYml, macosProjectYml(app)]) {
|
|
18119
|
-
const
|
|
18120
|
-
const r = applyToFile(yml, "yaml", LABEL_LOCALWEB, renderLocalWebYaml(resourcesDirOf(
|
|
18119
|
+
const text8 = existsSync26(yml) ? readFileSync26(yml, "utf8") : "";
|
|
18120
|
+
const r = applyToFile(yml, "yaml", LABEL_LOCALWEB, renderLocalWebYaml(resourcesDirOf(text8), rce), check);
|
|
18121
18121
|
if (existsSync26(yml)) assertLocalWebBlockLanded(app, rce, yml, r.outcome);
|
|
18122
18122
|
files.push(r);
|
|
18123
18123
|
}
|
|
@@ -18527,21 +18527,21 @@ function carryPlanningJournal(parentDir, appDir3) {
|
|
|
18527
18527
|
return carried;
|
|
18528
18528
|
}
|
|
18529
18529
|
function formatBrief(input) {
|
|
18530
|
-
const { summary, open } = input;
|
|
18530
|
+
const { summary: summary2, open } = input;
|
|
18531
18531
|
const who = `himi \u2014 ${input.appName ?? "this folder"}`;
|
|
18532
18532
|
const lines = [];
|
|
18533
|
-
if (!
|
|
18533
|
+
if (!summary2.count) {
|
|
18534
18534
|
lines.push(`${who}: no journey journal yet (${PROGRESS_FILE.split(sep6).join("/")}).`);
|
|
18535
18535
|
lines.push(
|
|
18536
18536
|
'A new app starts with discovery (step 1). An app built before journaling existed continues from its current state instead: confirm with the customer that its SPEC.md was approved rather than re-running discovery. Either way, journal each milestone with `himi progress "<what changed>" --step <n>` so the next session can pick up from it.'
|
|
18537
18537
|
);
|
|
18538
18538
|
} else {
|
|
18539
|
-
const at2 =
|
|
18540
|
-
lines.push(`${who}: ${at2} \xB7 ${
|
|
18541
|
-
if (
|
|
18542
|
-
const pastPlan = (
|
|
18539
|
+
const at2 = summary2.current ? `journey step ${summary2.current.stepNumber}/${summary2.current.of} (${summary2.current.step})` : "no journey step recorded yet";
|
|
18540
|
+
lines.push(`${who}: ${at2} \xB7 ${summary2.count} postcard${summary2.count === 1 ? "" : "s"} since ${minute(summary2.startedAt)}.`);
|
|
18541
|
+
if (summary2.last) lines.push(`Last postcard (${minute(summary2.last.ts)}): ${summary2.last.message}`);
|
|
18542
|
+
const pastPlan = (summary2.current?.stepNumber ?? 0) > JOURNEY_STEPS.indexOf("plan") + 1;
|
|
18543
18543
|
lines.push(
|
|
18544
|
-
!
|
|
18544
|
+
!summary2.current ? "No journey step recorded yet: a new app starts with discovery (step 1); one whose SPEC.md the customer approved continues from its current state. `himi progress` prints every postcard." : pastPlan ? `Resume at step ${summary2.current.stepNumber}. Do not restart discovery: the approved plan is SPEC.md + MOBILE-UX.md.` : `Resume at step ${summary2.current.stepNumber}. Implementation has not started: treat SPEC.md + MOBILE-UX.md as a draft unless the journal records the customer approving them.`
|
|
18545
18545
|
);
|
|
18546
18546
|
}
|
|
18547
18547
|
if (open.length) {
|
|
@@ -19465,10 +19465,10 @@ var init_preview = __esm({
|
|
|
19465
19465
|
}
|
|
19466
19466
|
},
|
|
19467
19467
|
kill: (pid, signal) => process.kill(pid, signal),
|
|
19468
|
-
portFree: (port) => new Promise((
|
|
19468
|
+
portFree: (port) => new Promise((resolve53) => {
|
|
19469
19469
|
const s = createServer2();
|
|
19470
|
-
s.once("error", () =>
|
|
19471
|
-
s.listen(port, "127.0.0.1", () => s.close(() =>
|
|
19470
|
+
s.once("error", () => resolve53(false));
|
|
19471
|
+
s.listen(port, "127.0.0.1", () => s.close(() => resolve53(true)));
|
|
19472
19472
|
}),
|
|
19473
19473
|
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
19474
19474
|
servingIdentity: async (origin) => {
|
|
@@ -19652,17 +19652,17 @@ ${BLOCK_END}`;
|
|
|
19652
19652
|
${block}
|
|
19653
19653
|
`;
|
|
19654
19654
|
}
|
|
19655
|
-
function markersIntact(
|
|
19656
|
-
const begins =
|
|
19657
|
-
const ends =
|
|
19655
|
+
function markersIntact(text8) {
|
|
19656
|
+
const begins = text8.split(BLOCK_BEGIN).length - 1;
|
|
19657
|
+
const ends = text8.split(BLOCK_END).length - 1;
|
|
19658
19658
|
if (begins === 0 && ends === 0) return true;
|
|
19659
|
-
return begins === 1 && ends === 1 &&
|
|
19659
|
+
return begins === 1 && ends === 1 && text8.indexOf(BLOCK_BEGIN) < text8.indexOf(BLOCK_END) && BLOCK_RE.test(text8);
|
|
19660
19660
|
}
|
|
19661
|
-
function withoutBlock(
|
|
19662
|
-
const m = BLOCK_RE.exec(
|
|
19663
|
-
if (!m) return
|
|
19664
|
-
const before =
|
|
19665
|
-
const after =
|
|
19661
|
+
function withoutBlock(text8) {
|
|
19662
|
+
const m = BLOCK_RE.exec(text8);
|
|
19663
|
+
if (!m) return text8;
|
|
19664
|
+
const before = text8.slice(0, m.index).replace(/\n+$/, "");
|
|
19665
|
+
const after = text8.slice(m.index + m[0].length).replace(/^\n+/, "");
|
|
19666
19666
|
if (!before) return after;
|
|
19667
19667
|
if (!after) return `${before}
|
|
19668
19668
|
`;
|
|
@@ -19670,8 +19670,8 @@ function withoutBlock(text6) {
|
|
|
19670
19670
|
|
|
19671
19671
|
${after}`;
|
|
19672
19672
|
}
|
|
19673
|
-
function blockVersion(
|
|
19674
|
-
return STAMP_RE.exec(
|
|
19673
|
+
function blockVersion(text8) {
|
|
19674
|
+
return STAMP_RE.exec(text8)?.[1] ?? null;
|
|
19675
19675
|
}
|
|
19676
19676
|
function agentsMdBody(appName2) {
|
|
19677
19677
|
const gates = APPROVAL_GATES.map((g) => `- \`${g.id}\` \u2014 ${g.label}`).join("\n");
|
|
@@ -20612,7 +20612,7 @@ async function injectRequest(listener, request) {
|
|
|
20612
20612
|
req.headers.host ??= url.host;
|
|
20613
20613
|
if (body && body.length > 0) req.push(body);
|
|
20614
20614
|
req.push(null);
|
|
20615
|
-
return await new Promise((
|
|
20615
|
+
return await new Promise((resolve53, reject) => {
|
|
20616
20616
|
const streamed = () => {
|
|
20617
20617
|
queueMicrotask(() => {
|
|
20618
20618
|
req.emit("close");
|
|
@@ -20628,7 +20628,7 @@ async function injectRequest(listener, request) {
|
|
|
20628
20628
|
else headers2.set(name, value);
|
|
20629
20629
|
}
|
|
20630
20630
|
const bodyless = out2.status === 204 || out2.status === 304 || request.method === "HEAD";
|
|
20631
|
-
|
|
20631
|
+
resolve53(new Response(bodyless ? null : out2.body, { status: out2.status, headers: headers2 }));
|
|
20632
20632
|
}, streamed);
|
|
20633
20633
|
res.on("inject-error", reject);
|
|
20634
20634
|
try {
|
|
@@ -21166,8 +21166,8 @@ async function postJson(path2, body, auth) {
|
|
|
21166
21166
|
headers: { "Content-Type": "application/json", ...auth ? { Authorization: auth } : {} },
|
|
21167
21167
|
body: JSON.stringify(body)
|
|
21168
21168
|
});
|
|
21169
|
-
const
|
|
21170
|
-
return { status: res.status, json:
|
|
21169
|
+
const text8 = await res.text();
|
|
21170
|
+
return { status: res.status, json: text8 ? JSON.parse(text8) : {} };
|
|
21171
21171
|
}
|
|
21172
21172
|
async function mintVisitor(clientId) {
|
|
21173
21173
|
const r = await postJson("/oauth2/token", { clientId, grantType: "anonymous" });
|
|
@@ -21413,13 +21413,13 @@ function recordWixTraffic(gw, app, adminUrl, ev) {
|
|
|
21413
21413
|
full.respBody = truncate(redactBodyString(full.respBody));
|
|
21414
21414
|
gw.traffic.push(full);
|
|
21415
21415
|
if (gw.traffic.length > TRAFFIC_CAP) gw.traffic.splice(0, gw.traffic.length - TRAFFIC_CAP);
|
|
21416
|
-
const
|
|
21416
|
+
const text8 = `event: wix.traffic
|
|
21417
21417
|
data: ${JSON.stringify(full)}
|
|
21418
21418
|
|
|
21419
21419
|
`;
|
|
21420
21420
|
for (const res of [...gw.clients]) {
|
|
21421
21421
|
try {
|
|
21422
|
-
res.write(
|
|
21422
|
+
res.write(text8);
|
|
21423
21423
|
} catch {
|
|
21424
21424
|
gw.clients.delete(res);
|
|
21425
21425
|
}
|
|
@@ -21781,10 +21781,10 @@ async function mintAnonymousVisitor(clientId, fetchImpl = fetch) {
|
|
|
21781
21781
|
headers: { "Content-Type": "application/json" },
|
|
21782
21782
|
body: JSON.stringify({ clientId, grantType: "anonymous" })
|
|
21783
21783
|
});
|
|
21784
|
-
const
|
|
21784
|
+
const text8 = await res.text();
|
|
21785
21785
|
let j = {};
|
|
21786
21786
|
try {
|
|
21787
|
-
j =
|
|
21787
|
+
j = text8 ? JSON.parse(text8) : {};
|
|
21788
21788
|
} catch {
|
|
21789
21789
|
}
|
|
21790
21790
|
if (res.status !== 200 || !j.access_token) throw new Error(`visitor mint failed (${res.status})`);
|
|
@@ -21948,10 +21948,10 @@ ${session}`);
|
|
|
21948
21948
|
}),
|
|
21949
21949
|
timedOut
|
|
21950
21950
|
]);
|
|
21951
|
-
const
|
|
21951
|
+
const text8 = await Promise.race([res.text(), timedOut]);
|
|
21952
21952
|
let j = {};
|
|
21953
21953
|
try {
|
|
21954
|
-
j =
|
|
21954
|
+
j = text8 ? JSON.parse(text8) : {};
|
|
21955
21955
|
} catch {
|
|
21956
21956
|
}
|
|
21957
21957
|
if (res.status < 200 || res.status >= 300 || !j.signedInstance)
|
|
@@ -22302,9 +22302,9 @@ var init_images = __esm({
|
|
|
22302
22302
|
});
|
|
22303
22303
|
|
|
22304
22304
|
// ../../core/dev-server/src/l10n-catalog.ts
|
|
22305
|
-
function parseCatalog(
|
|
22305
|
+
function parseCatalog(text8) {
|
|
22306
22306
|
try {
|
|
22307
|
-
const c = JSON.parse(
|
|
22307
|
+
const c = JSON.parse(text8);
|
|
22308
22308
|
return c && typeof c === "object" && c.messages && typeof c.messages === "object" ? c : void 0;
|
|
22309
22309
|
} catch {
|
|
22310
22310
|
return void 0;
|
|
@@ -22785,9 +22785,9 @@ async function getAndroidPixelDims(serial) {
|
|
|
22785
22785
|
try {
|
|
22786
22786
|
const args = serial ? ["-s", serial, "shell", "wm", "size"] : ["shell", "wm", "size"];
|
|
22787
22787
|
const out2 = await runner.capture(ADB_BIN, args);
|
|
22788
|
-
const
|
|
22789
|
-
const override = /Override size:\s*(\d+)x(\d+)/.exec(
|
|
22790
|
-
const physical = /Physical size:\s*(\d+)x(\d+)/.exec(
|
|
22788
|
+
const text8 = out2.toString("utf8");
|
|
22789
|
+
const override = /Override size:\s*(\d+)x(\d+)/.exec(text8);
|
|
22790
|
+
const physical = /Physical size:\s*(\d+)x(\d+)/.exec(text8);
|
|
22791
22791
|
const m = override ?? physical;
|
|
22792
22792
|
if (!m) throw new Error("could not parse wm size");
|
|
22793
22793
|
const dims = { width: parseInt(m[1], 10), height: parseInt(m[2], 10) };
|
|
@@ -23162,12 +23162,12 @@ function finalizeRecording(key2, rec) {
|
|
|
23162
23162
|
if (rec.finalize) return rec.finalize;
|
|
23163
23163
|
rec.finalize = (async () => {
|
|
23164
23164
|
clearTimeout(rec.autoStop);
|
|
23165
|
-
await new Promise((
|
|
23165
|
+
await new Promise((resolve53) => {
|
|
23166
23166
|
let done = false;
|
|
23167
23167
|
const finish2 = () => {
|
|
23168
23168
|
if (!done) {
|
|
23169
23169
|
done = true;
|
|
23170
|
-
|
|
23170
|
+
resolve53();
|
|
23171
23171
|
}
|
|
23172
23172
|
};
|
|
23173
23173
|
rec.child.once("close", finish2);
|
|
@@ -23278,7 +23278,7 @@ var init_preview2 = __esm({
|
|
|
23278
23278
|
DEVICE_LIST_TIMEOUT_MS = 5e3;
|
|
23279
23279
|
defaultRunner2 = {
|
|
23280
23280
|
capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
|
|
23281
|
-
return new Promise((
|
|
23281
|
+
return new Promise((resolve53, reject) => {
|
|
23282
23282
|
const child = spawn4(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
23283
23283
|
const out2 = [];
|
|
23284
23284
|
const err = [];
|
|
@@ -23300,7 +23300,7 @@ var init_preview2 = __esm({
|
|
|
23300
23300
|
child.stderr.on("data", (b) => err.push(b));
|
|
23301
23301
|
child.on("error", (e) => settle(reject, e));
|
|
23302
23302
|
child.on("close", (code) => {
|
|
23303
|
-
if (code === 0) settle(
|
|
23303
|
+
if (code === 0) settle(resolve53, Buffer.concat(out2));
|
|
23304
23304
|
else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
|
|
23305
23305
|
});
|
|
23306
23306
|
});
|
|
@@ -23720,7 +23720,7 @@ function buildOpenApi(descriptors) {
|
|
|
23720
23720
|
// Widgets
|
|
23721
23721
|
"/__dev/widget/preview": ["get", "Render a frozen widget snapshot."]
|
|
23722
23722
|
};
|
|
23723
|
-
for (const [p, [method,
|
|
23723
|
+
for (const [p, [method, summary2]] of Object.entries(control)) {
|
|
23724
23724
|
const responses = p === "/__dev/render" ? {
|
|
23725
23725
|
"200": { description: "completed render (legacy mode, or clean envelope verdict)" },
|
|
23726
23726
|
"400": { description: "invalid_json" },
|
|
@@ -23728,7 +23728,7 @@ function buildOpenApi(descriptors) {
|
|
|
23728
23728
|
"422": { description: "completed render with a failing envelope:1 verdict" },
|
|
23729
23729
|
"503": { description: "dev plane unavailable" }
|
|
23730
23730
|
} : { "200": { description: "ok" } };
|
|
23731
|
-
paths[p] = { [method]: { summary, responses } };
|
|
23731
|
+
paths[p] = { [method]: { summary: summary2, responses } };
|
|
23732
23732
|
}
|
|
23733
23733
|
for (const scope of ["net", "wix"]) {
|
|
23734
23734
|
paths[`/__dev/${scope}/rules`] = {
|
|
@@ -24156,9 +24156,9 @@ function mdScan(src, linkStyle = "") {
|
|
|
24156
24156
|
}
|
|
24157
24157
|
return out2 + mdEsc(src.slice(last));
|
|
24158
24158
|
}
|
|
24159
|
-
function mdInline(
|
|
24159
|
+
function mdInline(text8, linkColor) {
|
|
24160
24160
|
const safe = typeof linkColor === "string" && /^[#a-zA-Z0-9(),.%\s-]+$/.test(linkColor) ? linkColor : "";
|
|
24161
|
-
return { __html: mdScan(
|
|
24161
|
+
return { __html: mdScan(text8, safe ? ` style="color:${safe}"` : "") };
|
|
24162
24162
|
}
|
|
24163
24163
|
function sevColor(ctx, sev) {
|
|
24164
24164
|
switch (sev) {
|
|
@@ -27527,9 +27527,9 @@ function createRicosHostSession(o) {
|
|
|
27527
27527
|
if (!state.ready || state.unavailable) return;
|
|
27528
27528
|
o.send({ v: 1, type: "command", name, ...arg?.level ? { level: arg.level } : {}, ...arg?.value ? { value: arg.value } : {} });
|
|
27529
27529
|
},
|
|
27530
|
-
insertLink(url,
|
|
27530
|
+
insertLink(url, text8) {
|
|
27531
27531
|
if (!state.ready || state.unavailable || !isSafeEditorLink(url)) return false;
|
|
27532
|
-
o.send({ v: 1, type: "insertLink", url: url.trim(), ...
|
|
27532
|
+
o.send({ v: 1, type: "insertLink", url: url.trim(), ...text8 ? { text: text8 } : {} });
|
|
27533
27533
|
return true;
|
|
27534
27534
|
},
|
|
27535
27535
|
removeLink() {
|
|
@@ -27552,12 +27552,12 @@ function createRicosHostSession(o) {
|
|
|
27552
27552
|
flush() {
|
|
27553
27553
|
if (!state.ready || state.unavailable || disposed) return Promise.resolve(null);
|
|
27554
27554
|
const requestId2 = newId();
|
|
27555
|
-
return new Promise((
|
|
27555
|
+
return new Promise((resolve53) => {
|
|
27556
27556
|
const timer = t.setTimeout(() => {
|
|
27557
27557
|
flushes.delete(requestId2);
|
|
27558
|
-
|
|
27558
|
+
resolve53(null);
|
|
27559
27559
|
}, flushMs);
|
|
27560
|
-
flushes.set(requestId2, { resolve:
|
|
27560
|
+
flushes.set(requestId2, { resolve: resolve53, timer });
|
|
27561
27561
|
o.send({ v: 1, type: "requestContent", requestId: requestId2 });
|
|
27562
27562
|
});
|
|
27563
27563
|
},
|
|
@@ -27610,7 +27610,7 @@ async function runRicosImageUpload(o) {
|
|
|
27610
27610
|
};
|
|
27611
27611
|
session.insertMediaPlaceholder(requestId2);
|
|
27612
27612
|
try {
|
|
27613
|
-
const entry = await new Promise((
|
|
27613
|
+
const entry = await new Promise((resolve53) => {
|
|
27614
27614
|
let done = false;
|
|
27615
27615
|
let unsub = () => {
|
|
27616
27616
|
};
|
|
@@ -27619,7 +27619,7 @@ async function runRicosImageUpload(o) {
|
|
|
27619
27619
|
done = true;
|
|
27620
27620
|
t.clearTimeout(timer);
|
|
27621
27621
|
queueMicrotask(() => unsub());
|
|
27622
|
-
|
|
27622
|
+
resolve53(v);
|
|
27623
27623
|
};
|
|
27624
27624
|
const timer = t.setTimeout(() => finish2(null), o.timeoutMs ?? RICOS_UPLOAD_TIMEOUT_MS);
|
|
27625
27625
|
unsub = deps.subscribe(`${svc}.uploads.${requestId2}`, (v) => {
|
|
@@ -29226,13 +29226,13 @@ function NamedImage({ node, alt, env }) {
|
|
|
29226
29226
|
}
|
|
29227
29227
|
function Block({ b, env, depth }) {
|
|
29228
29228
|
const { ctx } = env;
|
|
29229
|
-
const
|
|
29229
|
+
const text8 = ctx.color("textPrimary", "#13171e");
|
|
29230
29230
|
const secondary = ctx.color("textSecondary", "#5c6370");
|
|
29231
29231
|
const border = ctx.color("border", "#e5e5e5");
|
|
29232
29232
|
switch (b.kind) {
|
|
29233
29233
|
case "paragraph":
|
|
29234
29234
|
return /* @__PURE__ */ jsx7("p", { ...tid(env, b.id, b.kind), style: {
|
|
29235
|
-
...textStyle(ctx, "body",
|
|
29235
|
+
...textStyle(ctx, "body", text8),
|
|
29236
29236
|
textAlign: b.align,
|
|
29237
29237
|
paddingInlineStart: b.indent ? Math.min(b.indent, 8) * 16 : void 0,
|
|
29238
29238
|
minHeight: b.spans.length ? void 0 : "1.5em"
|
|
@@ -29240,7 +29240,7 @@ function Block({ b, env, depth }) {
|
|
|
29240
29240
|
case "heading":
|
|
29241
29241
|
return React6.createElement(
|
|
29242
29242
|
`h${b.level}`,
|
|
29243
|
-
{ ...tid(env, b.id, b.kind), style: textStyle(ctx, RICH_CONTENT_HEADING_TOKENS[b.level - 1],
|
|
29243
|
+
{ ...tid(env, b.id, b.kind), style: textStyle(ctx, RICH_CONTENT_HEADING_TOKENS[b.level - 1], text8) },
|
|
29244
29244
|
/* @__PURE__ */ jsx7(Spans, { spans: b.spans, env })
|
|
29245
29245
|
);
|
|
29246
29246
|
case "list": {
|
|
@@ -29250,7 +29250,7 @@ function Block({ b, env, depth }) {
|
|
|
29250
29250
|
{
|
|
29251
29251
|
...tid(env, b.id, b.kind),
|
|
29252
29252
|
start: b.ordered ? b.start : void 0,
|
|
29253
|
-
style: { ...textStyle(ctx, "body",
|
|
29253
|
+
style: { ...textStyle(ctx, "body", text8), paddingInlineStart: 24, listStyleType: b.ordered ? "decimal" : depth % 2 ? "circle" : "disc" },
|
|
29254
29254
|
children: b.items.map((item, i) => /* @__PURE__ */ jsx7("li", { "data-component-id": `${env.componentId}/${item.id}`, id: `${env.componentId}/${item.id}`, style: { marginBottom: 6 }, children: /* @__PURE__ */ jsx7("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: item.blocks.map((child, j) => /* @__PURE__ */ jsx7(Block, { b: child, env, depth: depth + 1 }, `${j}:${child.id}`)) }) }, `${i}:${item.id}`))
|
|
29255
29255
|
}
|
|
29256
29256
|
);
|
|
@@ -29264,7 +29264,7 @@ function Block({ b, env, depth }) {
|
|
|
29264
29264
|
overflowWrap: "anywhere",
|
|
29265
29265
|
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
29266
29266
|
fontSize: "0.9em",
|
|
29267
|
-
color:
|
|
29267
|
+
color: text8,
|
|
29268
29268
|
background: ctx.color("surfaceSecondary", "#f5f5f7"),
|
|
29269
29269
|
padding: 10,
|
|
29270
29270
|
borderRadius: 6
|
|
@@ -29283,11 +29283,11 @@ function Block({ b, env, depth }) {
|
|
|
29283
29283
|
case "button":
|
|
29284
29284
|
return /* @__PURE__ */ jsx7(LinkButton, { label: b.label, url: b.url, env, testId: `${env.componentId}/${b.id}` });
|
|
29285
29285
|
case "table":
|
|
29286
|
-
return /* @__PURE__ */ jsx7("table", { ...tid(env, b.id, b.kind), style: { width: "100%", borderCollapse: "collapse", ...textStyle(ctx, "body",
|
|
29286
|
+
return /* @__PURE__ */ jsx7("table", { ...tid(env, b.id, b.kind), style: { width: "100%", borderCollapse: "collapse", ...textStyle(ctx, "body", text8) }, children: /* @__PURE__ */ jsx7("tbody", { children: b.rows.map((row, r) => /* @__PURE__ */ jsx7("tr", { children: row.map((cell, c) => /* @__PURE__ */ jsx7("td", { style: { border: `1px solid ${border}`, padding: 6, whiteSpace: "pre-wrap", verticalAlign: "top" }, children: cell }, c)) }, r)) }) });
|
|
29287
29287
|
case "card": {
|
|
29288
29288
|
const title = richContentCardTitle(b);
|
|
29289
29289
|
return /* @__PURE__ */ jsxs4("div", { ...tid(env, b.id, b.kind), role: "group", "aria-label": title, style: { border: `1px solid ${border}`, borderRadius: 8, padding: 12, display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
29290
|
-
/* @__PURE__ */ jsx7("div", { style: textStyle(ctx, "bodyEmphasis",
|
|
29290
|
+
/* @__PURE__ */ jsx7("div", { style: textStyle(ctx, "bodyEmphasis", text8), children: title }),
|
|
29291
29291
|
b.url ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
29292
29292
|
/* @__PURE__ */ jsx7("div", { style: textStyle(ctx, "caption", secondary), children: richContentHost(b.url) }),
|
|
29293
29293
|
/* @__PURE__ */ jsx7(LinkButton, { label: RICH_CONTENT_OPEN_LABEL, url: b.url, env, testId: `${env.componentId}/${b.id}/open` })
|
|
@@ -30883,8 +30883,8 @@ function applyA11ySemantics(node, ctx, extra) {
|
|
|
30883
30883
|
extra["aria-live"] = str9(announce.politeness) === "assertive" ? "assertive" : "polite";
|
|
30884
30884
|
extra["aria-atomic"] = "true";
|
|
30885
30885
|
extra["aria-relevant"] = trigger === "on_appear" ? "additions" : trigger === "both" ? "additions text" : "text";
|
|
30886
|
-
const
|
|
30887
|
-
if (
|
|
30886
|
+
const text8 = str9(announce.text);
|
|
30887
|
+
if (text8 && extra["aria-label"] == null) extra["aria-label"] = text8;
|
|
30888
30888
|
}
|
|
30889
30889
|
}
|
|
30890
30890
|
return hint;
|
|
@@ -32474,13 +32474,13 @@ var init_renderNode = __esm({
|
|
|
32474
32474
|
const C = ctx.color;
|
|
32475
32475
|
const isBoundText = typeof props.textPath === "string" && isBinding(props.textPath);
|
|
32476
32476
|
const bound = useResolvedScalar(isBoundText ? props.textPath : void 0, ctx);
|
|
32477
|
-
const
|
|
32477
|
+
const text8 = isBoundText ? typeof bound === "string" || typeof bound === "number" ? String(bound) : "" : literalErrorText;
|
|
32478
32478
|
if (props.visible === false) return null;
|
|
32479
|
-
if (isBoundText && !
|
|
32479
|
+
if (isBoundText && !text8) return null;
|
|
32480
32480
|
const c = (props.severity ?? "error") === "warning" ? C("warning", "#E89F00") : C("danger", "#E62214");
|
|
32481
32481
|
return /* @__PURE__ */ jsxs5("div", { role: "alert", style: { display: "flex", gap: 6, alignItems: "center", color: c, fontSize: 13, fontFamily: bodyFont(ctx), ...wrap }, children: [
|
|
32482
32482
|
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: "\u26A0" }),
|
|
32483
|
-
|
|
32483
|
+
text8
|
|
32484
32484
|
] });
|
|
32485
32485
|
});
|
|
32486
32486
|
FormView = withExtras("FormView", ({ props, ctx, wrap }) => {
|
|
@@ -33967,8 +33967,8 @@ var init_renderNode = __esm({
|
|
|
33967
33967
|
const base = invalidIcon ? ICON_FALLBACK : (typeof props.icon === "string" && props.icon ? props.icon : "star").replace(/_fill$/, "");
|
|
33968
33968
|
const filledCount = Math.round(val);
|
|
33969
33969
|
const onClickStar = (i) => ctx.onAction && props.interactive && props.onChange ? () => ctx.onAction({ ...props.onChange, params: { ...props.onChange?.params ?? {}, value: String(i + 1) } }) : void 0;
|
|
33970
|
-
const cv = Number.isFinite(val) ? Math.max(0, Math.min(max, val)) : 0,
|
|
33971
|
-
return /* @__PURE__ */ jsx8("span", { style: { display: "inline-flex", alignItems: "center", gap: m.gap, ...wrap }, role: props.interactive ? "group" : "img", "aria-label": `Rating, ${
|
|
33970
|
+
const cv = Number.isFinite(val) ? Math.max(0, Math.min(max, val)) : 0, summary2 = `${Number.isInteger(cv) ? cv : cv.toFixed(1)} of ${max}`;
|
|
33971
|
+
return /* @__PURE__ */ jsx8("span", { style: { display: "inline-flex", alignItems: "center", gap: m.gap, ...wrap }, role: props.interactive ? "group" : "img", "aria-label": `Rating, ${summary2}`, "data-a11y-value": summary2, children: Array.from({ length: max }).map((_, i) => {
|
|
33972
33972
|
const filled = i < filledCount;
|
|
33973
33973
|
return /* @__PURE__ */ jsx8("span", { onClick: onClickStar(i), style: { display: "inline-grid", placeItems: "center", width: m.cell, height: m.cell, cursor: props.interactive ? "pointer" : "default", opacity: filled ? 1 : 0.28 }, children: iconSvg(filled ? `${base}_fill` : base, { size: m.glyph, color: col }) }, i);
|
|
33974
33974
|
}) });
|
|
@@ -35720,8 +35720,8 @@ function buildRenderTree(node, path2 = "$", provider = null, itemScope = void 0,
|
|
|
35720
35720
|
const asText3 = VALUE_PATH_TEXT.get(type);
|
|
35721
35721
|
if (typeof valuePath === "string" && asText3 && (valuePath.startsWith("$service:") || /^\$item\.[^.]/.test(valuePath))) {
|
|
35722
35722
|
const r = resolveTreeScalar(valuePath, provider, itemScope);
|
|
35723
|
-
const
|
|
35724
|
-
if (
|
|
35723
|
+
const text8 = asText3(r, props);
|
|
35724
|
+
if (text8 !== void 0) values.value = text8;
|
|
35725
35725
|
else if (r !== void 0 && r !== null) {
|
|
35726
35726
|
delete values.value;
|
|
35727
35727
|
}
|
|
@@ -35902,7 +35902,7 @@ async function stabilizePngPage(page, scheme) {
|
|
|
35902
35902
|
const browser = globalThis;
|
|
35903
35903
|
browser.document.documentElement.style.colorScheme = selected;
|
|
35904
35904
|
await browser.document.fonts?.ready;
|
|
35905
|
-
await new Promise((
|
|
35905
|
+
await new Promise((resolve53) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve53())));
|
|
35906
35906
|
}, scheme);
|
|
35907
35907
|
}
|
|
35908
35908
|
async function renderPngBatch(items) {
|
|
@@ -37916,14 +37916,14 @@ function discoverNativeActions(appDir3) {
|
|
|
37916
37916
|
const roots = NATIVE_SOURCE_ROOTS.filter(({ directory }) => existsSync38(resolve31(appDir3, directory)));
|
|
37917
37917
|
const sources = roots.flatMap(({ directory, extension, buildDirMaxDepth }) => nativeSourceFiles(resolve31(appDir3, directory), extension, buildDirMaxDepth));
|
|
37918
37918
|
const registered = sources.flatMap((source) => {
|
|
37919
|
-
let
|
|
37919
|
+
let text8;
|
|
37920
37920
|
try {
|
|
37921
|
-
|
|
37921
|
+
text8 = readFileSync40(source, "utf8");
|
|
37922
37922
|
} catch (err) {
|
|
37923
37923
|
if (!vanished(err)) throw err;
|
|
37924
37924
|
return [];
|
|
37925
37925
|
}
|
|
37926
|
-
return registeredActions(
|
|
37926
|
+
return registeredActions(text8);
|
|
37927
37927
|
});
|
|
37928
37928
|
return {
|
|
37929
37929
|
registered: new Set(registered),
|
|
@@ -38022,11 +38022,11 @@ function strip(line) {
|
|
|
38022
38022
|
function scalar(v) {
|
|
38023
38023
|
return v.trim().replace(/^["']|["']$/g, "");
|
|
38024
38024
|
}
|
|
38025
|
-
function parseRolloutYaml(
|
|
38025
|
+
function parseRolloutYaml(text8) {
|
|
38026
38026
|
const cfg = { app: "", rings: [] };
|
|
38027
38027
|
let cur = null;
|
|
38028
38028
|
let inRings = false;
|
|
38029
|
-
for (const raw of
|
|
38029
|
+
for (const raw of text8.split("\n")) {
|
|
38030
38030
|
const line = strip(raw);
|
|
38031
38031
|
if (!line.trim()) continue;
|
|
38032
38032
|
const top = /^([a-zA-Z_]+):\s*(.*)$/.exec(line);
|
|
@@ -38057,10 +38057,10 @@ function assignRing(r, key2, val) {
|
|
|
38057
38057
|
else if (key2 === "percent") r.percent = Number(v);
|
|
38058
38058
|
else if (key2 === "minBinaryVersion") r.minBinaryVersion = v;
|
|
38059
38059
|
}
|
|
38060
|
-
function parseRevocationsYaml(
|
|
38060
|
+
function parseRevocationsYaml(text8) {
|
|
38061
38061
|
const out2 = { app: "", revoked: [] };
|
|
38062
38062
|
let inList = false;
|
|
38063
|
-
for (const raw of
|
|
38063
|
+
for (const raw of text8.split("\n")) {
|
|
38064
38064
|
const line = strip(raw);
|
|
38065
38065
|
if (!line.trim()) continue;
|
|
38066
38066
|
const top = /^([a-zA-Z_]+):\s*(.*)$/.exec(line);
|
|
@@ -38417,7 +38417,7 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
38417
38417
|
state.app?.module.config,
|
|
38418
38418
|
state.tier5Dir ?? TIER5_ROOT2
|
|
38419
38419
|
);
|
|
38420
|
-
const
|
|
38420
|
+
const report3 = validateScreenDescriptor2(screenId, descriptor, {
|
|
38421
38421
|
tokens,
|
|
38422
38422
|
allowedComponents,
|
|
38423
38423
|
bundleJs,
|
|
@@ -38430,7 +38430,7 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
38430
38430
|
});
|
|
38431
38431
|
const telemetry = state.telemetryEvents.filter((e) => e.screenId === screenId && (/^worker_/.test(e.type) || e.type === "bundle_load_revoked")).slice(-20);
|
|
38432
38432
|
const lastError = [...telemetry].reverse().find((e) => /crash|revoked|error|fail/i.test(e.type)) ?? null;
|
|
38433
|
-
const legacy = { ...
|
|
38433
|
+
const legacy = { ...report3, bundle: bundleName ?? null, telemetry, lastError };
|
|
38434
38434
|
return foldLegacyReport(legacy, {
|
|
38435
38435
|
source: "diagnostics",
|
|
38436
38436
|
screenId,
|
|
@@ -38639,11 +38639,11 @@ async function handleOwnerChatRequest(req, res) {
|
|
|
38639
38639
|
return sendJson(res, 400, { error: "invalid_json" }, cors);
|
|
38640
38640
|
}
|
|
38641
38641
|
const chatroomId = (parsed.chatroomId ?? "").trim();
|
|
38642
|
-
const
|
|
38643
|
-
if (!chatroomId || !
|
|
38642
|
+
const text8 = (parsed.text ?? "").trim();
|
|
38643
|
+
if (!chatroomId || !text8) return sendJson(res, 400, { error: "chatroomId_and_text_required" }, cors);
|
|
38644
38644
|
const metaSiteId = (parsed.metaSiteId ?? "").trim() || await resolveMetaSiteId();
|
|
38645
38645
|
if (!metaSiteId) return sendJson(res, 400, { error: "no_meta_site" }, cors);
|
|
38646
|
-
const result = await sendChatMessageLive(metaSiteId, chatroomId,
|
|
38646
|
+
const result = await sendChatMessageLive(metaSiteId, chatroomId, text8);
|
|
38647
38647
|
if (result.ok) return sendJson(res, 200, { ok: true, message: result.message }, cors);
|
|
38648
38648
|
return sendJson(res, result.status >= 400 && result.status < 600 ? result.status : 502, { ok: false, status: result.status, error: result.error }, cors);
|
|
38649
38649
|
}
|
|
@@ -38904,13 +38904,13 @@ function invalidate(state, ...screenIds) {
|
|
|
38904
38904
|
publishSSE(state, "screen.invalidated", { screenIds });
|
|
38905
38905
|
}
|
|
38906
38906
|
function publishSSE(state, type, payload) {
|
|
38907
|
-
const
|
|
38907
|
+
const text8 = `event: ${type}
|
|
38908
38908
|
data: ${JSON.stringify(payload)}
|
|
38909
38909
|
|
|
38910
38910
|
`;
|
|
38911
38911
|
for (const res of [...state.sseClients]) {
|
|
38912
38912
|
try {
|
|
38913
|
-
res.write(
|
|
38913
|
+
res.write(text8);
|
|
38914
38914
|
} catch {
|
|
38915
38915
|
state.sseClients.delete(res);
|
|
38916
38916
|
}
|
|
@@ -38926,13 +38926,13 @@ function publishAdminSSE(state, type, payload) {
|
|
|
38926
38926
|
state.lastDeviceScreen.set(key2, screenId);
|
|
38927
38927
|
}
|
|
38928
38928
|
}
|
|
38929
|
-
const
|
|
38929
|
+
const text8 = `event: ${type}
|
|
38930
38930
|
data: ${JSON.stringify(payload)}
|
|
38931
38931
|
|
|
38932
38932
|
`;
|
|
38933
38933
|
for (const res of [...state.adminClients]) {
|
|
38934
38934
|
try {
|
|
38935
|
-
res.write(
|
|
38935
|
+
res.write(text8);
|
|
38936
38936
|
} catch {
|
|
38937
38937
|
state.adminClients.delete(res);
|
|
38938
38938
|
}
|
|
@@ -38953,12 +38953,12 @@ function publishDevReady(state, res, extra = {}) {
|
|
|
38953
38953
|
hotReloadEnabled: state.hotReloadEnabled,
|
|
38954
38954
|
...extra
|
|
38955
38955
|
};
|
|
38956
|
-
const
|
|
38956
|
+
const text8 = `event: dev.ready
|
|
38957
38957
|
data: ${JSON.stringify(payload)}
|
|
38958
38958
|
|
|
38959
38959
|
`;
|
|
38960
38960
|
if (res) {
|
|
38961
|
-
res.write(
|
|
38961
|
+
res.write(text8);
|
|
38962
38962
|
} else {
|
|
38963
38963
|
publishSSE(state, "dev.ready", payload);
|
|
38964
38964
|
}
|
|
@@ -39543,7 +39543,7 @@ async function handleWebWix(req, res, state) {
|
|
|
39543
39543
|
}
|
|
39544
39544
|
if (match) {
|
|
39545
39545
|
const mocked = match.rule.response;
|
|
39546
|
-
if (mocked.delayMs) await new Promise((
|
|
39546
|
+
if (mocked.delayMs) await new Promise((resolve53) => setTimeout(resolve53, mocked.delayMs));
|
|
39547
39547
|
const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
39548
39548
|
record2("mock", mocked.status, responseBody, match.rule.id, mocked.headers);
|
|
39549
39549
|
return reply(200, { status: mocked.status, body: responseBody ?? "" });
|
|
@@ -39709,7 +39709,7 @@ async function handleDev(req, res, state) {
|
|
|
39709
39709
|
idiomContext
|
|
39710
39710
|
);
|
|
39711
39711
|
const legacy = { screenId, scheme, ...render, diagnostics };
|
|
39712
|
-
const
|
|
39712
|
+
const report3 = foldLegacyReport(legacy, {
|
|
39713
39713
|
source: "render",
|
|
39714
39714
|
screenId,
|
|
39715
39715
|
ok: diagnostics.ok !== false && render.renderable !== false,
|
|
@@ -39721,8 +39721,8 @@ async function handleDev(req, res, state) {
|
|
|
39721
39721
|
],
|
|
39722
39722
|
evidence: { runId: `dev:${state.startedAt}:${screenId}`, ts: (/* @__PURE__ */ new Date()).toISOString() }
|
|
39723
39723
|
});
|
|
39724
|
-
const status = body.envelope === 1 && !
|
|
39725
|
-
return sendJson(res, status,
|
|
39724
|
+
const status = body.envelope === 1 && !report3.ok ? 422 : 200;
|
|
39725
|
+
return sendJson(res, status, report3);
|
|
39726
39726
|
}
|
|
39727
39727
|
{
|
|
39728
39728
|
const diagMatch = /^\/__dev\/screen\/(.+?)\/diagnostics(?:\?|$)/.exec(url);
|
|
@@ -40183,7 +40183,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
40183
40183
|
state.app?.module.config,
|
|
40184
40184
|
state.tier5Dir ?? TIER5_ROOT2
|
|
40185
40185
|
);
|
|
40186
|
-
const
|
|
40186
|
+
const report3 = validateScreenDescriptor2(screenId, descriptor, {
|
|
40187
40187
|
tokens,
|
|
40188
40188
|
allowedComponents,
|
|
40189
40189
|
bundleJs,
|
|
@@ -40193,7 +40193,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
40193
40193
|
workerSubtreeScreens: new Set(uiConfig(state.app?.module.config).workerSubtreeScreens ?? []),
|
|
40194
40194
|
a11y: uiConfig(state.app?.module.config).a11y
|
|
40195
40195
|
});
|
|
40196
|
-
return sendJson(res,
|
|
40196
|
+
return sendJson(res, report3.ok ? 200 : 422, report3);
|
|
40197
40197
|
}
|
|
40198
40198
|
const detailMatch = /^\/v1\/admin\/screens\/([^/]+)$/.exec(path2);
|
|
40199
40199
|
if (detailMatch && req.method === "GET") {
|
|
@@ -40648,9 +40648,9 @@ async function handleLiveSubscription(req, res, state) {
|
|
|
40648
40648
|
},
|
|
40649
40649
|
body: JSON.stringify({ ...body, app })
|
|
40650
40650
|
});
|
|
40651
|
-
const
|
|
40651
|
+
const text8 = await upstream.text();
|
|
40652
40652
|
res.writeHead(upstream.status, { "Content-Type": "application/json", ...cors });
|
|
40653
|
-
res.end(
|
|
40653
|
+
res.end(text8 || JSON.stringify({ ok: upstream.ok }));
|
|
40654
40654
|
} catch (error) {
|
|
40655
40655
|
sendJson(res, 502, { error: "admin_server_unreachable", detail: String(error) }, cors);
|
|
40656
40656
|
}
|
|
@@ -41642,12 +41642,12 @@ var init_query = __esm({
|
|
|
41642
41642
|
});
|
|
41643
41643
|
|
|
41644
41644
|
// ../../core/dev-server/src/crawl-input.ts
|
|
41645
|
-
function resolved(v,
|
|
41646
|
-
if (typeof v === "string") return v.startsWith("$service:") ?
|
|
41645
|
+
function resolved(v, resolve53) {
|
|
41646
|
+
if (typeof v === "string") return v.startsWith("$service:") ? resolve53(v) : v;
|
|
41647
41647
|
if (Array.isArray(v)) {
|
|
41648
41648
|
const out2 = v.flatMap((el) => {
|
|
41649
41649
|
if (typeof el !== "string" || !el.startsWith("$service:")) return [el];
|
|
41650
|
-
const r =
|
|
41650
|
+
const r = resolve53(el);
|
|
41651
41651
|
return Array.isArray(r) ? r : [r];
|
|
41652
41652
|
});
|
|
41653
41653
|
return out2;
|
|
@@ -41661,9 +41661,9 @@ function hasRowBinding(props) {
|
|
|
41661
41661
|
return itemToken(v) || Array.isArray(v) && v.some(itemToken);
|
|
41662
41662
|
});
|
|
41663
41663
|
}
|
|
41664
|
-
function declaredOptionIds(props,
|
|
41664
|
+
function declaredOptionIds(props, resolve53) {
|
|
41665
41665
|
const literal = props.options ?? props.tabs ?? props.chips;
|
|
41666
|
-
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath,
|
|
41666
|
+
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve53) : void 0;
|
|
41667
41667
|
const raw = Array.isArray(bound) ? bound : literal;
|
|
41668
41668
|
if (!Array.isArray(raw)) return [];
|
|
41669
41669
|
const out2 = [];
|
|
@@ -41706,24 +41706,24 @@ function seedTokens(state, limit = 48) {
|
|
|
41706
41706
|
walk2(state, 0);
|
|
41707
41707
|
return out2;
|
|
41708
41708
|
}
|
|
41709
|
-
function synthesizeInput(control,
|
|
41709
|
+
function synthesizeInput(control, resolve53, tokens) {
|
|
41710
41710
|
const id = `${control.type}.${control.callback}`;
|
|
41711
41711
|
const row = SYNTHESIZED_CONTROLS[id];
|
|
41712
41712
|
if (!row) return null;
|
|
41713
41713
|
const props = control.props;
|
|
41714
41714
|
if (hasRowBinding(props)) return null;
|
|
41715
41715
|
if (row.from === "declared-options") {
|
|
41716
|
-
const ids = declaredOptionIds(props,
|
|
41716
|
+
const ids = declaredOptionIds(props, resolve53);
|
|
41717
41717
|
if (!ids.length) return null;
|
|
41718
41718
|
if (row.encoding === "string-array") {
|
|
41719
|
-
const currentRaw2 = resolved(props.selectedIds,
|
|
41719
|
+
const currentRaw2 = resolved(props.selectedIds, resolve53);
|
|
41720
41720
|
const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x) => typeof x === "string");
|
|
41721
41721
|
const pick4 = ids.find((o) => !current3.includes(o));
|
|
41722
41722
|
if (pick4 === void 0) return null;
|
|
41723
41723
|
const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
|
|
41724
41724
|
return { key: row.key, value, from: row.from, current: current3, control: id };
|
|
41725
41725
|
}
|
|
41726
|
-
const currentRaw = resolved(props.selectedId,
|
|
41726
|
+
const currentRaw = resolved(props.selectedId, resolve53);
|
|
41727
41727
|
const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
|
|
41728
41728
|
const pick3 = ids.find((o) => o !== current2);
|
|
41729
41729
|
if (pick3 === void 0) return null;
|
|
@@ -41731,7 +41731,7 @@ function synthesizeInput(control, resolve52, tokens) {
|
|
|
41731
41731
|
}
|
|
41732
41732
|
if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
|
|
41733
41733
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
|
|
41734
|
-
const bound = binding2 === void 0 ? void 0 :
|
|
41734
|
+
const bound = binding2 === void 0 ? void 0 : resolve53(binding2);
|
|
41735
41735
|
const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
|
|
41736
41736
|
const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
|
|
41737
41737
|
const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
|
|
@@ -42095,10 +42095,10 @@ function netTransport(rules) {
|
|
|
42095
42095
|
if (res.needsUpstream) {
|
|
42096
42096
|
throw new Error(`net fixture rule ${res.ruleId} is a \`transform\` rule, which needs a real upstream \u2014 not usable in a hermetic crawl`);
|
|
42097
42097
|
}
|
|
42098
|
-
const { status, body:
|
|
42098
|
+
const { status, body: text8 } = res.resolved;
|
|
42099
42099
|
if (status < 200 || status >= 300) throw new Error(`Wix ${status} for ${method} ${bare}`);
|
|
42100
42100
|
try {
|
|
42101
|
-
return
|
|
42101
|
+
return text8 ? JSON.parse(text8) : {};
|
|
42102
42102
|
} catch {
|
|
42103
42103
|
return {};
|
|
42104
42104
|
}
|
|
@@ -42142,10 +42142,10 @@ function layeredTransport(layers2) {
|
|
|
42142
42142
|
});
|
|
42143
42143
|
if (res.matched) {
|
|
42144
42144
|
if (res.needsUpstream) throw new Error(`net fixture rule ${res.ruleId} is a \`transform\` rule, which needs a real upstream \u2014 not usable in a hermetic crawl`);
|
|
42145
|
-
const { status, body:
|
|
42145
|
+
const { status, body: text8 } = res.resolved;
|
|
42146
42146
|
if (status < 200 || status >= 300) throw new Error(`Wix ${status} for ${m} ${bare}`);
|
|
42147
42147
|
try {
|
|
42148
|
-
return
|
|
42148
|
+
return text8 ? JSON.parse(text8) : {};
|
|
42149
42149
|
} catch {
|
|
42150
42150
|
return {};
|
|
42151
42151
|
}
|
|
@@ -44167,13 +44167,13 @@ var init_build2 = __esm({
|
|
|
44167
44167
|
});
|
|
44168
44168
|
|
|
44169
44169
|
// ../mobile-dist/release-pin.ts
|
|
44170
|
-
function withPinnedRelease(
|
|
44171
|
-
if (!releaseId) return
|
|
44170
|
+
function withPinnedRelease(text8, releaseId) {
|
|
44171
|
+
if (!releaseId) return text8;
|
|
44172
44172
|
let cfg;
|
|
44173
44173
|
try {
|
|
44174
|
-
cfg = JSON.parse(
|
|
44174
|
+
cfg = JSON.parse(text8);
|
|
44175
44175
|
} catch {
|
|
44176
|
-
return
|
|
44176
|
+
return text8;
|
|
44177
44177
|
}
|
|
44178
44178
|
cfg.releaseId = releaseId;
|
|
44179
44179
|
cfg.releasePinned = true;
|
|
@@ -44291,10 +44291,10 @@ async function bakeCatalogs(app, locale, fetchCatalog, putDoc) {
|
|
|
44291
44291
|
if (!declared.length) return out2;
|
|
44292
44292
|
const tags = [.../* @__PURE__ */ new Set([...locale?.default ? [locale.default] : [], ...declared])];
|
|
44293
44293
|
for (const tag of tags) {
|
|
44294
|
-
const
|
|
44295
|
-
if (!
|
|
44296
|
-
const hash = sha2564(
|
|
44297
|
-
await putDoc(app, hash,
|
|
44294
|
+
const text8 = await fetchCatalog(tag);
|
|
44295
|
+
if (!text8) continue;
|
|
44296
|
+
const hash = sha2564(text8);
|
|
44297
|
+
await putDoc(app, hash, text8);
|
|
44298
44298
|
out2[tag] = hash;
|
|
44299
44299
|
}
|
|
44300
44300
|
return out2;
|
|
@@ -44386,9 +44386,9 @@ async function snapshotTokens(app, base, fetchTokens, put) {
|
|
|
44386
44386
|
}
|
|
44387
44387
|
};
|
|
44388
44388
|
}
|
|
44389
|
-
const
|
|
44390
|
-
await put(
|
|
44391
|
-
return { hash: sha2564(
|
|
44389
|
+
const text8 = await res.text();
|
|
44390
|
+
await put(text8);
|
|
44391
|
+
return { hash: sha2564(text8) };
|
|
44392
44392
|
}
|
|
44393
44393
|
function tokensSnapshotMessage(app, base, status) {
|
|
44394
44394
|
const why = status === 400 ? `the dev-server rejected the app id as malformed (400 bad_app). It must be lowercase letters, digits and hyphens, starting with a letter or digit, at most 63 characters, with at most one interior dot \u2014 so a leading underscore or an uppercase letter fails, on every build of that app. A single dot is FINE (an owner-namespaced slug), so do not remove one to get past this` : `${status} from the tokens route`;
|
|
@@ -44482,23 +44482,23 @@ function maximumBinaryVersion(current, candidate) {
|
|
|
44482
44482
|
}
|
|
44483
44483
|
return current;
|
|
44484
44484
|
}
|
|
44485
|
-
async function withStoreNavBundle(
|
|
44485
|
+
async function withStoreNavBundle(text8, address) {
|
|
44486
44486
|
let cfg;
|
|
44487
44487
|
try {
|
|
44488
|
-
cfg = JSON.parse(
|
|
44488
|
+
cfg = JSON.parse(text8);
|
|
44489
44489
|
} catch {
|
|
44490
|
-
return
|
|
44490
|
+
return text8;
|
|
44491
44491
|
}
|
|
44492
44492
|
const refs = [cfg?.navigation?.navLogicBundle, cfg?.navLogicBundle].filter(
|
|
44493
44493
|
(r) => !!r && typeof r === "object" && typeof r.url === "string"
|
|
44494
44494
|
);
|
|
44495
|
-
if (refs.length === 0) return
|
|
44495
|
+
if (refs.length === 0) return text8;
|
|
44496
44496
|
const resolved2 = [];
|
|
44497
44497
|
for (const ref of refs) {
|
|
44498
44498
|
const name = bundleNameFromUrl(ref.url);
|
|
44499
|
-
if (!name) return
|
|
44499
|
+
if (!name) return text8;
|
|
44500
44500
|
const addressed = await address(name);
|
|
44501
|
-
if (!addressed) return
|
|
44501
|
+
if (!addressed) return text8;
|
|
44502
44502
|
resolved2.push({ ref, url: addressed.url, sri: addressed.sri });
|
|
44503
44503
|
}
|
|
44504
44504
|
for (const { ref, url, sri: integrity2 } of resolved2) {
|
|
@@ -44507,10 +44507,10 @@ async function withStoreNavBundle(text6, address) {
|
|
|
44507
44507
|
}
|
|
44508
44508
|
return JSON.stringify(cfg);
|
|
44509
44509
|
}
|
|
44510
|
-
function linkableScreenIdsFrom(
|
|
44510
|
+
function linkableScreenIdsFrom(text8) {
|
|
44511
44511
|
let cfg;
|
|
44512
44512
|
try {
|
|
44513
|
-
cfg = JSON.parse(
|
|
44513
|
+
cfg = JSON.parse(text8);
|
|
44514
44514
|
} catch {
|
|
44515
44515
|
return [];
|
|
44516
44516
|
}
|
|
@@ -44522,24 +44522,24 @@ function linkableScreenIdsFrom(text6) {
|
|
|
44522
44522
|
}
|
|
44523
44523
|
return [...ids];
|
|
44524
44524
|
}
|
|
44525
|
-
function withoutDevOnlyAppConfig(
|
|
44525
|
+
function withoutDevOnlyAppConfig(text8) {
|
|
44526
44526
|
let cfg;
|
|
44527
44527
|
try {
|
|
44528
|
-
cfg = JSON.parse(
|
|
44528
|
+
cfg = JSON.parse(text8);
|
|
44529
44529
|
} catch {
|
|
44530
|
-
return
|
|
44530
|
+
return text8;
|
|
44531
44531
|
}
|
|
44532
|
-
if (!cfg || typeof cfg !== "object" || !("devGatewayConfig" in cfg)) return
|
|
44532
|
+
if (!cfg || typeof cfg !== "object" || !("devGatewayConfig" in cfg)) return text8;
|
|
44533
44533
|
delete cfg.devGatewayConfig;
|
|
44534
44534
|
return JSON.stringify(cfg);
|
|
44535
44535
|
}
|
|
44536
|
-
function withProdServeAppConfig(
|
|
44537
|
-
if (!prod?.serve) return
|
|
44536
|
+
function withProdServeAppConfig(text8, prod) {
|
|
44537
|
+
if (!prod?.serve) return text8;
|
|
44538
44538
|
let cfg;
|
|
44539
44539
|
try {
|
|
44540
|
-
cfg = JSON.parse(
|
|
44540
|
+
cfg = JSON.parse(text8);
|
|
44541
44541
|
} catch {
|
|
44542
|
-
return
|
|
44542
|
+
return text8;
|
|
44543
44543
|
}
|
|
44544
44544
|
cfg.useProdServe = true;
|
|
44545
44545
|
cfg.prodServeBaseUrl = prod.serve;
|
|
@@ -44760,10 +44760,10 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
44760
44760
|
if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
|
|
44761
44761
|
throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
|
|
44762
44762
|
}
|
|
44763
|
-
const
|
|
44764
|
-
if (!Buffer.from(
|
|
44763
|
+
const text8 = bytes2.toString("utf8");
|
|
44764
|
+
if (!Buffer.from(text8, "utf8").equals(bytes2)) throw new Error(`${file} must be canonical UTF-8 Markdown.`);
|
|
44765
44765
|
const hash = sha2564(bytes2);
|
|
44766
|
-
await store.putDoc(app, hash,
|
|
44766
|
+
await store.putDoc(app, hash, text8);
|
|
44767
44767
|
authoringDocs[name] = { sha256: hash, sri: sri2(bytes2), bytes: bytes2.length, contentType: "text/markdown; charset=utf-8" };
|
|
44768
44768
|
}
|
|
44769
44769
|
}
|
|
@@ -44962,7 +44962,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
44962
44962
|
}
|
|
44963
44963
|
if (collect2?.lint) {
|
|
44964
44964
|
const bundleJs = bundleName ? readBuiltBundle(tier5Dir, bundleName) : void 0;
|
|
44965
|
-
const
|
|
44965
|
+
const report3 = validateScreenDescriptor(screenId, descriptor, {
|
|
44966
44966
|
tokens: lintTokens,
|
|
44967
44967
|
allowedComponents,
|
|
44968
44968
|
allowedIcons: KNOWN_ICONS,
|
|
@@ -44976,7 +44976,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
44976
44976
|
// default, "error"; an in-repo app with ratcheted debt declares "warn".
|
|
44977
44977
|
a11y: config.a11y
|
|
44978
44978
|
});
|
|
44979
|
-
lint.push({ screenId, ok:
|
|
44979
|
+
lint.push({ screenId, ok: report3.ok, issues: report3.issues });
|
|
44980
44980
|
}
|
|
44981
44981
|
if (collect2?.render && (!collect2.render.screenId || collect2.render.screenId === screenId)) {
|
|
44982
44982
|
const { services, liveCalls, liveReturned, liveErrors } = await renderServicesFor(bundleName, descriptor);
|
|
@@ -44994,7 +44994,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
44994
44994
|
const bundleName = lb ? bundleNameFromUrl(lb.url) : null;
|
|
44995
44995
|
if (collect2?.lint) {
|
|
44996
44996
|
const bundleJs = bundleName ? readBuiltBundle(tier5Dir, bundleName) : void 0;
|
|
44997
|
-
const
|
|
44997
|
+
const report3 = validateScreenDescriptor(wantedRender, descriptor, {
|
|
44998
44998
|
tokens: lintTokens,
|
|
44999
44999
|
allowedComponents,
|
|
45000
45000
|
allowedIcons: KNOWN_ICONS,
|
|
@@ -45005,7 +45005,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
45005
45005
|
workerSubtreeScreens: new Set(config.workerSubtreeScreens ?? []),
|
|
45006
45006
|
a11y: config.a11y
|
|
45007
45007
|
});
|
|
45008
|
-
lint.push({ screenId: wantedRender, ok:
|
|
45008
|
+
lint.push({ screenId: wantedRender, ok: report3.ok, issues: report3.issues });
|
|
45009
45009
|
}
|
|
45010
45010
|
const { services, liveCalls, liveReturned, liveErrors } = await renderServicesFor(bundleName, descriptor);
|
|
45011
45011
|
const rr = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true);
|
|
@@ -45123,11 +45123,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
45123
45123
|
ok: res.ok,
|
|
45124
45124
|
status: res.status,
|
|
45125
45125
|
text: async () => {
|
|
45126
|
-
const
|
|
45126
|
+
const text8 = await res.text();
|
|
45127
45127
|
try {
|
|
45128
|
-
const doc = JSON.parse(
|
|
45128
|
+
const doc = JSON.parse(text8);
|
|
45129
45129
|
if (!publishedFontPlan) {
|
|
45130
|
-
if (!("fontFaces" in doc)) return
|
|
45130
|
+
if (!("fontFaces" in doc)) return text8;
|
|
45131
45131
|
const kept = publishableFontFaces(doc.fontFaces);
|
|
45132
45132
|
if (kept) doc.fontFaces = kept;
|
|
45133
45133
|
else delete doc.fontFaces;
|
|
@@ -45136,12 +45136,12 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
45136
45136
|
doc.fontFaces = servedProjection(publishedFontPlan);
|
|
45137
45137
|
return JSON.stringify(doc);
|
|
45138
45138
|
} catch {
|
|
45139
|
-
return
|
|
45139
|
+
return text8;
|
|
45140
45140
|
}
|
|
45141
45141
|
}
|
|
45142
45142
|
};
|
|
45143
45143
|
},
|
|
45144
|
-
(
|
|
45144
|
+
(text8) => store.putTokens(app, text8)
|
|
45145
45145
|
);
|
|
45146
45146
|
if (snapshot2.hash) tokensHash = snapshot2.hash;
|
|
45147
45147
|
if (snapshot2.failure) {
|
|
@@ -45171,14 +45171,14 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
45171
45171
|
if (streamPolicyErrors.length) {
|
|
45172
45172
|
throw new Error(`invalid streamPolicy for release ${app}: ${streamPolicyErrors.join("; ")}`);
|
|
45173
45173
|
}
|
|
45174
|
-
const
|
|
45174
|
+
const text8 = await withStoreNavBundle(prodText, async (name) => {
|
|
45175
45175
|
const hash = await addressBundle(name) ?? null;
|
|
45176
45176
|
const entry = hash ? bundles[name] : void 0;
|
|
45177
45177
|
return entry ? { url: store.bundleUrl(app, entry.sha256), sri: entry.sri } : null;
|
|
45178
45178
|
});
|
|
45179
|
-
await store.putAppConfig(app,
|
|
45180
|
-
appConfigHash = sha2564(
|
|
45181
|
-
if (collect2?.descriptors) for (const id of linkableScreenIdsFrom(
|
|
45179
|
+
await store.putAppConfig(app, text8);
|
|
45180
|
+
appConfigHash = sha2564(text8);
|
|
45181
|
+
if (collect2?.descriptors) for (const id of linkableScreenIdsFrom(text8)) linkable.add(id);
|
|
45182
45182
|
}
|
|
45183
45183
|
const ahRes = await devFetch(`${base}/v1/action-handlers/${encodeURIComponent(app)}`, { headers: { "X-Himalaya-App": app } });
|
|
45184
45184
|
if (ahRes.ok) {
|
|
@@ -46044,14 +46044,14 @@ function headline(changes) {
|
|
|
46044
46044
|
function boardLines(changes) {
|
|
46045
46045
|
const lines = [];
|
|
46046
46046
|
for (const c of changes.items) {
|
|
46047
|
-
const
|
|
46048
|
-
const same3 = lines.find((l) => l.text ===
|
|
46047
|
+
const text8 = lineOf(c);
|
|
46048
|
+
const same3 = lines.find((l) => l.text === text8);
|
|
46049
46049
|
if (same3) {
|
|
46050
46050
|
same3.n++;
|
|
46051
46051
|
continue;
|
|
46052
46052
|
}
|
|
46053
46053
|
lines.push({
|
|
46054
|
-
text:
|
|
46054
|
+
text: text8,
|
|
46055
46055
|
n: 1,
|
|
46056
46056
|
...c.kind === "token" && c.from && HEX.test(c.from) ? { from: c.from } : {},
|
|
46057
46057
|
...c.kind === "token" && c.to && HEX.test(c.to) ? { to: c.to } : {}
|
|
@@ -46371,12 +46371,12 @@ function testRuns(dir) {
|
|
|
46371
46371
|
if (!f.endsWith(".json") || f === "latest.json") continue;
|
|
46372
46372
|
const r = obj(readJson3(join41(att, f)));
|
|
46373
46373
|
if (!r || r.tool !== "himi-test" || typeof r.runId !== "string") continue;
|
|
46374
|
-
const
|
|
46374
|
+
const report3 = obj(r.report);
|
|
46375
46375
|
const coverage = obj(r.coverage);
|
|
46376
46376
|
runs.push({
|
|
46377
46377
|
runId: r.runId,
|
|
46378
|
-
ok:
|
|
46379
|
-
errors: num(obj(
|
|
46378
|
+
ok: report3?.ok === true,
|
|
46379
|
+
errors: num(obj(report3?.counts)?.errors),
|
|
46380
46380
|
screens: num(coverage?.screens),
|
|
46381
46381
|
actions: num(coverage?.actionsDispatched),
|
|
46382
46382
|
gaps: num(coverage?.gaps)
|
|
@@ -46495,7 +46495,7 @@ function focusScreen(memory) {
|
|
|
46495
46495
|
}
|
|
46496
46496
|
function buildView(dir, memory, now) {
|
|
46497
46497
|
const { entries } = readProgress(dir);
|
|
46498
|
-
const
|
|
46498
|
+
const summary2 = summarizeProgress(entries);
|
|
46499
46499
|
const { name, iconFile } = appIdentity(dir);
|
|
46500
46500
|
const iconArchived = iconFile ? archiveFile(dir, memory, iconFile) : null;
|
|
46501
46501
|
const icon = iconArchived ? historyUrl(iconArchived.file) : null;
|
|
@@ -46524,12 +46524,12 @@ function buildView(dir, memory, now) {
|
|
|
46524
46524
|
}
|
|
46525
46525
|
}
|
|
46526
46526
|
const firstShot = screens.map((s) => s.firstSeen).sort()[0];
|
|
46527
|
-
const startedAt = [
|
|
46527
|
+
const startedAt = [summary2.startedAt, firstShot, memory.createdAt].filter((x) => !!x).sort()[0] ?? null;
|
|
46528
46528
|
const view = {
|
|
46529
46529
|
generatedAt: now,
|
|
46530
46530
|
app: { name, icon, palette: palette(dir) },
|
|
46531
46531
|
steps: JOURNEY_STEPS,
|
|
46532
|
-
current:
|
|
46532
|
+
current: summary2.current ?? null,
|
|
46533
46533
|
startedAt,
|
|
46534
46534
|
journal: entries.slice(-MAX_JOURNAL).reverse().map((e) => ({
|
|
46535
46535
|
ts: e.ts,
|
|
@@ -47194,16 +47194,16 @@ function pushSetupBodyBytes(body) {
|
|
|
47194
47194
|
return Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
47195
47195
|
}
|
|
47196
47196
|
async function pushSetupRequest(options) {
|
|
47197
|
-
const
|
|
47198
|
-
if (!options.target.controlToken) return
|
|
47199
|
-
if (!options.wixToken) return
|
|
47200
|
-
if (credentialHostRefusal(options.target.control)) return
|
|
47201
|
-
if (options.previewTag !== void 0 && !PREVIEW_TAG.test(options.previewTag)) return
|
|
47197
|
+
const refuse5 = (error) => ({ ok: false, status: 0, body: null, error });
|
|
47198
|
+
if (!options.target.controlToken) return refuse5("control_token_required");
|
|
47199
|
+
if (!options.wixToken) return refuse5("wix_account_token_required");
|
|
47200
|
+
if (credentialHostRefusal(options.target.control)) return refuse5("insecure_target");
|
|
47201
|
+
if (options.previewTag !== void 0 && !PREVIEW_TAG.test(options.previewTag)) return refuse5("invalid_preview_tag");
|
|
47202
47202
|
const setup = options.operation === "setup";
|
|
47203
|
-
if (setup && !options.body) return
|
|
47204
|
-
if (!setup && (!options.query?.app || !options.query?.site)) return
|
|
47203
|
+
if (setup && !options.body) return refuse5("push_setup_body_required");
|
|
47204
|
+
if (!setup && (!options.query?.app || !options.query?.site)) return refuse5("push_setup_query_required");
|
|
47205
47205
|
if (setup && pushSetupBodyBytes(options.body) > MAX_PUSH_SETUP_BODY_BYTES) {
|
|
47206
|
-
return
|
|
47206
|
+
return refuse5("push_setup_body_too_large");
|
|
47207
47207
|
}
|
|
47208
47208
|
const base = options.target.control.replace(/\/+$/, "");
|
|
47209
47209
|
let path2 = "/v1/admin/push/setup";
|
|
@@ -47228,10 +47228,10 @@ async function pushSetupRequest(options) {
|
|
|
47228
47228
|
signal: AbortSignal.timeout(options.timeoutMs ?? (setup ? 12e4 : 3e4)),
|
|
47229
47229
|
...setup ? { body: JSON.stringify(options.body) } : {}
|
|
47230
47230
|
});
|
|
47231
|
-
const
|
|
47231
|
+
const text8 = await response.text();
|
|
47232
47232
|
let parsed = null;
|
|
47233
47233
|
try {
|
|
47234
|
-
const value =
|
|
47234
|
+
const value = text8 ? JSON.parse(text8) : null;
|
|
47235
47235
|
parsed = value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
47236
47236
|
} catch {
|
|
47237
47237
|
parsed = null;
|
|
@@ -47271,6 +47271,41 @@ var init_push_setup_apple_credentials = __esm({
|
|
|
47271
47271
|
}
|
|
47272
47272
|
});
|
|
47273
47273
|
|
|
47274
|
+
// src/hosted-owner.ts
|
|
47275
|
+
async function hostedOwnerSession(flags, deps = {}) {
|
|
47276
|
+
let target;
|
|
47277
|
+
try {
|
|
47278
|
+
target = resolveTarget({ target: text3(flags.target), defaultTarget: "wix", controlUrl: text3(flags["control-url"]), controlToken: text3(flags["control-token"]), ownerIssueUrl: text3(flags["owner-issue-url"]) });
|
|
47279
|
+
} catch {
|
|
47280
|
+
return refused("unknown_target", "Select a configured serve target.");
|
|
47281
|
+
}
|
|
47282
|
+
if (credentialHostRefusal(target.control)) return refused("insecure_target");
|
|
47283
|
+
const previewTag = text3(flags["preview-tag"]) ?? process.env.HIMI_SERVE_PREVIEW_TAG;
|
|
47284
|
+
if (previewTag !== void 0 && !/^dp-[a-z0-9]+$/.test(previewTag)) return refused("invalid_preview_tag");
|
|
47285
|
+
const controlToken = target.controlToken;
|
|
47286
|
+
if (!controlToken || !decodeControlTokenClaims(controlToken)?.sub) return refused("owner_login_required", "Run himi login --browser --target wix.");
|
|
47287
|
+
let wixToken;
|
|
47288
|
+
try {
|
|
47289
|
+
wixToken = await (deps.wixToken ?? accountToken)();
|
|
47290
|
+
} catch {
|
|
47291
|
+
return refused("wix_account_token_required", "Browser login supplies a Himi control token only. Sign into the Wix CLI with wix login, using the same Wix account, then retry. You can continue building without push setup.", 1);
|
|
47292
|
+
}
|
|
47293
|
+
if (!wixToken) return refused("wix_account_token_required", "Run wix login using the same Wix account.", 1);
|
|
47294
|
+
if (!target.ownerIssue) return refused("owner_issuer_required");
|
|
47295
|
+
return { ok: true, session: { target, controlToken, wixToken, ownerIssue: target.ownerIssue, ...previewTag ? { previewTag } : {} } };
|
|
47296
|
+
}
|
|
47297
|
+
var text3, refused;
|
|
47298
|
+
var init_hosted_owner = __esm({
|
|
47299
|
+
"src/hosted-owner.ts"() {
|
|
47300
|
+
init_config();
|
|
47301
|
+
init_credential_hosts();
|
|
47302
|
+
init_owner_claim();
|
|
47303
|
+
init_wix_owner();
|
|
47304
|
+
text3 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
47305
|
+
refused = (error, hint, exit = 2) => ({ ok: false, error, ...hint ? { hint } : {}, exit });
|
|
47306
|
+
}
|
|
47307
|
+
});
|
|
47308
|
+
|
|
47274
47309
|
// src/push-onboarding.ts
|
|
47275
47310
|
import { existsSync as existsSync44, mkdirSync as mkdirSync20, readFileSync as readFileSync48, statSync as statSync9, writeFileSync as writeFileSync15, chmodSync as chmodSync2 } from "node:fs";
|
|
47276
47311
|
import { basename as basename12, dirname as dirname25, join as join42, resolve as resolve37 } from "node:path";
|
|
@@ -47294,26 +47329,26 @@ function pushInputsFromContent(dir) {
|
|
|
47294
47329
|
// autoClaimSlug's docblock describes as the project-declared slug. Without the fallback a
|
|
47295
47330
|
// package with no `name` sent a body missing `app` and earned `400 invalid_app_id` with both
|
|
47296
47331
|
// private keys already on the wire.
|
|
47297
|
-
app:
|
|
47298
|
-
...
|
|
47299
|
-
...
|
|
47300
|
-
...
|
|
47332
|
+
app: text4(content.name) ?? basename12(root),
|
|
47333
|
+
...text4(provisioning.siteId) ? { site: text4(provisioning.siteId) } : {},
|
|
47334
|
+
...text4(native.iosBundleId) ? { bundleId: text4(native.iosBundleId) } : {},
|
|
47335
|
+
...text4(native.androidApplicationId) ? { androidApplicationId: text4(native.androidApplicationId) } : {}
|
|
47301
47336
|
};
|
|
47302
47337
|
}
|
|
47303
47338
|
function mergePushInputs(content, flags) {
|
|
47304
47339
|
const merged = { ...content };
|
|
47305
47340
|
for (const [flag, apply] of FLAG_SETTERS) {
|
|
47306
|
-
const value =
|
|
47341
|
+
const value = text4(flags[flag]);
|
|
47307
47342
|
if (value !== void 0) apply(merged, value);
|
|
47308
47343
|
}
|
|
47309
47344
|
return merged;
|
|
47310
47345
|
}
|
|
47311
47346
|
function missingPushInputs(i, scope) {
|
|
47312
47347
|
const needed = scope === "push_and_signing" ? [...REQUIRED_ORDER, ...ASC_ORDER] : REQUIRED_ORDER;
|
|
47313
|
-
return needed.filter((name) => !
|
|
47348
|
+
return needed.filter((name) => !text4(i[name]));
|
|
47314
47349
|
}
|
|
47315
47350
|
function ascGroupError(i) {
|
|
47316
|
-
const present = ASC_ORDER.filter((name) =>
|
|
47351
|
+
const present = ASC_ORDER.filter((name) => text4(i[name])).length;
|
|
47317
47352
|
return present === 0 || present === ASC_ORDER.length ? null : "incomplete_asc_group";
|
|
47318
47353
|
}
|
|
47319
47354
|
function localIdentityRefusal(i) {
|
|
@@ -47382,8 +47417,8 @@ function validateApnsAuthKey(body) {
|
|
|
47382
47417
|
return { ok: true };
|
|
47383
47418
|
}
|
|
47384
47419
|
function buildPushSetupBody(i, keys) {
|
|
47385
|
-
const missing = REQUIRED_ORDER.filter((name) => !
|
|
47386
|
-
const app =
|
|
47420
|
+
const missing = REQUIRED_ORDER.filter((name) => !text4(i[name]));
|
|
47421
|
+
const app = text4(i.app);
|
|
47387
47422
|
if (!app) return { ok: false, code: "app_not_initialized", missing };
|
|
47388
47423
|
if (missing.length > 0) return { ok: false, code: "needs_input", missing };
|
|
47389
47424
|
if (i.apnsEnvironment !== "development" && i.apnsEnvironment !== "production") {
|
|
@@ -47463,7 +47498,7 @@ function savePushSelection(dir, input) {
|
|
|
47463
47498
|
if (input.androidApplicationId) selection.androidApplicationId = input.androidApplicationId;
|
|
47464
47499
|
writeFile(dir, { ...readPushOnboarding(dir), selection });
|
|
47465
47500
|
}
|
|
47466
|
-
var PUSH_ONBOARDING_PATH, MAX_KEY_FILE_BYTES, SITE_RE, APP_RE, ANDROID_ID_RE, PLACEHOLDER_BUNDLE_RE,
|
|
47501
|
+
var PUSH_ONBOARDING_PATH, MAX_KEY_FILE_BYTES, SITE_RE, APP_RE, ANDROID_ID_RE, PLACEHOLDER_BUNDLE_RE, text4, FLAG_SETTERS, REQUIRED_ORDER, ASC_ORDER, NOTE;
|
|
47467
47502
|
var init_push_onboarding = __esm({
|
|
47468
47503
|
"src/push-onboarding.ts"() {
|
|
47469
47504
|
PUSH_ONBOARDING_PATH = ".himi/push-onboarding.json";
|
|
@@ -47472,7 +47507,7 @@ var init_push_onboarding = __esm({
|
|
|
47472
47507
|
APP_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
|
|
47473
47508
|
ANDROID_ID_RE = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)+$/;
|
|
47474
47509
|
PLACEHOLDER_BUNDLE_RE = /^com\.example\.|^__HIMI_APP_/;
|
|
47475
|
-
|
|
47510
|
+
text4 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
47476
47511
|
FLAG_SETTERS = [
|
|
47477
47512
|
["app", (m, v) => {
|
|
47478
47513
|
m.app = v;
|
|
@@ -47604,7 +47639,7 @@ async function runNotifySetup(pos, flags, io, deps = {}) {
|
|
|
47604
47639
|
if (operation !== "setup" && operation !== "status") return refuse2(io, "invalid_notify_operation");
|
|
47605
47640
|
const flagError = pushSetupFlagError(flags);
|
|
47606
47641
|
if (flagError) return refuse2(io, flagError);
|
|
47607
|
-
const dir = resolve38(
|
|
47642
|
+
const dir = resolve38(text5(flags.content) ?? process.cwd());
|
|
47608
47643
|
const local = readPushOnboarding(dir);
|
|
47609
47644
|
const progress = local.push;
|
|
47610
47645
|
const content = pushInputsFromContent(dir);
|
|
@@ -47636,26 +47671,10 @@ async function runNotifySetup(pos, flags, io, deps = {}) {
|
|
|
47636
47671
|
return 2;
|
|
47637
47672
|
}
|
|
47638
47673
|
if (operation === "setup" && ascGroupError(input)) return refuse2(io, "incomplete_asc_group");
|
|
47639
|
-
|
|
47640
|
-
|
|
47641
|
-
|
|
47642
|
-
|
|
47643
|
-
return refuse2(io, "unknown_target", "Select a configured serve target.");
|
|
47644
|
-
}
|
|
47645
|
-
if (credentialHostRefusal(target.control)) return refuse2(io, "insecure_target");
|
|
47646
|
-
const previewTag = text4(flags["preview-tag"]) ?? process.env.HIMI_SERVE_PREVIEW_TAG;
|
|
47647
|
-
if (previewTag !== void 0 && !/^dp-[a-z0-9]+$/.test(previewTag)) return refuse2(io, "invalid_preview_tag");
|
|
47648
|
-
const token = target.controlToken;
|
|
47649
|
-
if (!token || !decodeControlTokenClaims(token)?.sub) return refuse2(io, "owner_login_required", "Run himi login --browser --target wix.");
|
|
47650
|
-
let wixToken;
|
|
47651
|
-
try {
|
|
47652
|
-
wixToken = await (deps.wixToken ?? accountToken)();
|
|
47653
|
-
} catch {
|
|
47654
|
-
return refuse2(io, "wix_account_token_required", "Browser login supplies a Himi control token only. Sign into the Wix CLI with wix login, using the same Wix account, then retry. You can continue building without push setup.", 1);
|
|
47655
|
-
}
|
|
47656
|
-
if (!wixToken) return refuse2(io, "wix_account_token_required", "Run wix login using the same Wix account.", 1);
|
|
47657
|
-
if (!target.ownerIssue) return refuse2(io, "owner_issuer_required");
|
|
47658
|
-
const ownershipArgs = { ownerIssue: target.ownerIssue, controlToken: token, declaredName: input.app, fetchImpl: deps.fetchImpl };
|
|
47674
|
+
const owner = await hostedOwnerSession(flags, deps);
|
|
47675
|
+
if (!owner.ok) return refuse2(io, owner.error, owner.hint, owner.exit);
|
|
47676
|
+
const { target, controlToken: token, wixToken, previewTag, ownerIssue } = owner.session;
|
|
47677
|
+
const ownershipArgs = { ownerIssue, controlToken: token, declaredName: input.app, fetchImpl: deps.fetchImpl };
|
|
47659
47678
|
let ownership = await verifyAppOwnership(ownershipArgs);
|
|
47660
47679
|
logOwnershipFailure(io, ownership);
|
|
47661
47680
|
if (ownership.state !== "owned" && ownership.state !== "not_claimed") return refuse2(io, `app_ownership_${ownership.state}`, "Setup requires the app owner; retry after ownership is verified.", 1);
|
|
@@ -47701,7 +47720,7 @@ async function runNotifySetup(pos, flags, io, deps = {}) {
|
|
|
47701
47720
|
}
|
|
47702
47721
|
}
|
|
47703
47722
|
if (ownership.state === "not_claimed") {
|
|
47704
|
-
const claim = await autoClaimSlug({ ownerIssue
|
|
47723
|
+
const claim = await autoClaimSlug({ ownerIssue, controlToken: token, app: input.app, accountId: text5(flags["account-id"]), fetchImpl: deps.fetchImpl });
|
|
47705
47724
|
if (claim.fatal) return refuse2(io, "app_claim_refused", "Check app ownership and the selected account.", 1);
|
|
47706
47725
|
ownership = await verifyAppOwnership({ ...ownershipArgs, declaredName: claim.slug ?? input.app });
|
|
47707
47726
|
logOwnershipFailure(io, ownership);
|
|
@@ -47751,17 +47770,15 @@ async function offerPushSetup(options) {
|
|
|
47751
47770
|
return { status: "needs_attention", resume: resume(contentDir2) };
|
|
47752
47771
|
}
|
|
47753
47772
|
}
|
|
47754
|
-
var
|
|
47773
|
+
var text5, obj2, STATES, CHECKS, CHECK_STATES, STAGES, ERROR_CODES, PROMPTS, later, resume;
|
|
47755
47774
|
var init_notify_setup = __esm({
|
|
47756
47775
|
"src/notify-setup.ts"() {
|
|
47757
|
-
init_config();
|
|
47758
|
-
init_credential_hosts();
|
|
47759
47776
|
init_push_setup();
|
|
47760
47777
|
init_push_setup_apple_credentials();
|
|
47761
|
-
init_wix_owner();
|
|
47762
47778
|
init_owner_claim();
|
|
47779
|
+
init_hosted_owner();
|
|
47763
47780
|
init_push_onboarding();
|
|
47764
|
-
|
|
47781
|
+
text5 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
47765
47782
|
obj2 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
47766
47783
|
STATES = /* @__PURE__ */ new Set(["not_configured", "provisioning", "ready", "needs_attention"]);
|
|
47767
47784
|
CHECKS = ["brandedRecord", "pingApns", "pingFcm", "appleSigning", "nativeBuild", "himiRouting", "deviceDelivery"];
|
|
@@ -48456,7 +48473,7 @@ function thin(items, max) {
|
|
|
48456
48473
|
function planReel(dir) {
|
|
48457
48474
|
const memory = loadMemory2(dir);
|
|
48458
48475
|
const { entries } = readProgress(dir);
|
|
48459
|
-
const
|
|
48476
|
+
const summary2 = summarizeProgress(entries);
|
|
48460
48477
|
const manifest = readJson5(join45(dir, "himalaya.content.json"));
|
|
48461
48478
|
const tokens = readJson5(join45(dir, "tokens.json"));
|
|
48462
48479
|
const accentToken = tokens?.colors?.accentPrimary;
|
|
@@ -48476,9 +48493,9 @@ function planReel(dir) {
|
|
|
48476
48493
|
by: isCliEntry(e) ? CLI_AUTHOR : null,
|
|
48477
48494
|
files: (Array.isArray(e.images) ? e.images : []).map((i) => isObj3(i) && typeof i.file === "string" ? basename13(i.file) : "").filter((f) => HISTORY_NAME.test(f))
|
|
48478
48495
|
}));
|
|
48479
|
-
const times = [
|
|
48496
|
+
const times = [summary2.startedAt, ...timeline.map((t) => t.ts), memory?.createdAt].filter((x) => !!x).sort();
|
|
48480
48497
|
const startedAt = times[0] ?? null;
|
|
48481
|
-
const endedAt = [
|
|
48498
|
+
const endedAt = [summary2.lastAt, ...timeline.map((t) => t.ts)].filter((x) => !!x).sort().pop() ?? null;
|
|
48482
48499
|
return {
|
|
48483
48500
|
app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename13(dir),
|
|
48484
48501
|
accent,
|
|
@@ -48778,9 +48795,9 @@ async function firstLookAtInit(dir, opts) {
|
|
|
48778
48795
|
child.on("error", (e) => finish2({ skipped: `the render did not start: ${e.message}` }));
|
|
48779
48796
|
child.on("close", (code) => {
|
|
48780
48797
|
clearTimeout(hardKill);
|
|
48781
|
-
let
|
|
48798
|
+
let report3 = null;
|
|
48782
48799
|
try {
|
|
48783
|
-
|
|
48800
|
+
report3 = JSON.parse(Buffer.concat(out2).toString("utf8"));
|
|
48784
48801
|
} catch {
|
|
48785
48802
|
}
|
|
48786
48803
|
let fresh = false;
|
|
@@ -48789,7 +48806,7 @@ async function firstLookAtInit(dir, opts) {
|
|
|
48789
48806
|
} catch {
|
|
48790
48807
|
}
|
|
48791
48808
|
if (code === 0 && fresh) return finish2({ image: `.himi/shots/${home}.png` });
|
|
48792
|
-
if (
|
|
48809
|
+
if (report3?.pngUnavailable) return finish2({ skipped: "no headless browser to draw the PNG \u2014 `npx playwright install chromium`, then run the render step below" });
|
|
48793
48810
|
let refusal = null;
|
|
48794
48811
|
for (const line of errTail.trim().split("\n").reverse()) {
|
|
48795
48812
|
try {
|
|
@@ -48799,7 +48816,7 @@ async function firstLookAtInit(dir, opts) {
|
|
|
48799
48816
|
}
|
|
48800
48817
|
if (refusal) break;
|
|
48801
48818
|
}
|
|
48802
|
-
const why = typeof
|
|
48819
|
+
const why = typeof report3?.reason === "string" ? report3.reason : typeof report3?.error === "string" ? report3.error : refusal;
|
|
48803
48820
|
finish2({ skipped: `the render made no picture (exit ${code ?? "killed"})${why ? `: ${why.slice(0, 200)}` : ""}` });
|
|
48804
48821
|
});
|
|
48805
48822
|
});
|
|
@@ -49754,9 +49771,9 @@ function bundlesOf(block) {
|
|
|
49754
49771
|
walk2(block);
|
|
49755
49772
|
return [...out2];
|
|
49756
49773
|
}
|
|
49757
|
-
function parseJson2(
|
|
49774
|
+
function parseJson2(text8, what) {
|
|
49758
49775
|
try {
|
|
49759
|
-
const value = JSON.parse(
|
|
49776
|
+
const value = JSON.parse(text8);
|
|
49760
49777
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("not an object");
|
|
49761
49778
|
return value;
|
|
49762
49779
|
} catch (e) {
|
|
@@ -49991,25 +50008,25 @@ function pruneChrome(items, removed, ledger) {
|
|
|
49991
50008
|
}
|
|
49992
50009
|
function rewriteNav(nav, removed, homeId) {
|
|
49993
50010
|
const next = structuredClone(nav);
|
|
49994
|
-
const
|
|
50011
|
+
const report3 = { linkable: [], tabs: [], drawer: [], sidebar: [], deepLinkPatterns: [], topBarActions: [], headerActions: [], surfaceDestinations: [], appIconBadgeSources: [], reparented: [] };
|
|
49995
50012
|
const tabItems = asItems(next.tabBar);
|
|
49996
50013
|
const hadTabs = !!tabItems?.length;
|
|
49997
|
-
if (tabItems) next.tabBar.items = pruneChrome(tabItems, removed,
|
|
50014
|
+
if (tabItems) next.tabBar.items = pruneChrome(tabItems, removed, report3.tabs);
|
|
49998
50015
|
const drawerItems = asItems(next.drawer);
|
|
49999
|
-
if (drawerItems) next.drawer.items = pruneChrome(drawerItems, removed,
|
|
50016
|
+
if (drawerItems) next.drawer.items = pruneChrome(drawerItems, removed, report3.drawer);
|
|
50000
50017
|
const sidebarItems = asItems(next.sidebar);
|
|
50001
|
-
if (sidebarItems) next.sidebar.items = pruneChrome(sidebarItems, removed,
|
|
50018
|
+
if (sidebarItems) next.sidebar.items = pruneChrome(sidebarItems, removed, report3.sidebar);
|
|
50002
50019
|
if (hadTabs && !asItems(next.tabBar).length) {
|
|
50003
|
-
throw new TrimRefusal(`no tab would remain \u2014 every tabBar item opens a screen this trim removes (${
|
|
50020
|
+
throw new TrimRefusal(`no tab would remain \u2014 every tabBar item opens a screen this trim removes (${report3.tabs.join(", ")}); keep at least one tab's screen`, { removedTabs: report3.tabs });
|
|
50004
50021
|
}
|
|
50005
50022
|
const remainingRoots = [...asItems(next.tabBar) ?? [], ...asItems(next.sidebar) ?? []].filter((i) => i.role !== "section");
|
|
50006
50023
|
const remainingRootIds = new Set(remainingRoots.map((i) => i.id).filter((id) => typeof id === "string"));
|
|
50007
|
-
const removedRootIds = /* @__PURE__ */ new Set([...
|
|
50024
|
+
const removedRootIds = /* @__PURE__ */ new Set([...report3.tabs, ...report3.sidebar]);
|
|
50008
50025
|
if (Array.isArray(next.deepLinkPatterns)) {
|
|
50009
50026
|
next.deepLinkPatterns = next.deepLinkPatterns.filter((p) => {
|
|
50010
50027
|
const id = p?.params?.screenId ?? p?.screenId;
|
|
50011
50028
|
if (typeof id === "string" && removed(id)) {
|
|
50012
|
-
|
|
50029
|
+
report3.deepLinkPatterns.push(String(p.pattern ?? id));
|
|
50013
50030
|
return false;
|
|
50014
50031
|
}
|
|
50015
50032
|
return true;
|
|
@@ -50020,7 +50037,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50020
50037
|
if (!Array.isArray(actions)) continue;
|
|
50021
50038
|
next[key2].header.actions = actions.filter((a) => {
|
|
50022
50039
|
if (!(typeof a?.screenId === "string" && removed(a.screenId))) return true;
|
|
50023
|
-
|
|
50040
|
+
report3.headerActions.push(`${key2}:${String(a.icon ?? a.screenId)}`);
|
|
50024
50041
|
return false;
|
|
50025
50042
|
});
|
|
50026
50043
|
}
|
|
@@ -50029,7 +50046,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50029
50046
|
next.topBarDefault.actions = topActions.filter((a) => {
|
|
50030
50047
|
const to = openTarget(a?.onTap) ?? openTarget(a?.action);
|
|
50031
50048
|
if (to && removed(to)) {
|
|
50032
|
-
|
|
50049
|
+
report3.topBarActions.push(entryLabel(a));
|
|
50033
50050
|
return false;
|
|
50034
50051
|
}
|
|
50035
50052
|
return true;
|
|
@@ -50044,7 +50061,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50044
50061
|
for (const [dest, screenId] of Object.entries(cfg.screenIds)) {
|
|
50045
50062
|
if (goneDest(dest) || typeof screenId === "string" && removed(screenId)) {
|
|
50046
50063
|
delete cfg.screenIds[dest];
|
|
50047
|
-
|
|
50064
|
+
report3.surfaceDestinations.push(`${surface}:${dest}`);
|
|
50048
50065
|
if (!remainingRootIds.has(dest)) unmapped.add(dest);
|
|
50049
50066
|
}
|
|
50050
50067
|
}
|
|
@@ -50054,24 +50071,24 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50054
50071
|
const gone = goneDest(id) || typeof id === "string" && unmapped.has(id);
|
|
50055
50072
|
if (!gone) return true;
|
|
50056
50073
|
const entry = `${surface}:${String(id)}`;
|
|
50057
|
-
if (!
|
|
50074
|
+
if (!report3.surfaceDestinations.includes(entry)) report3.surfaceDestinations.push(entry);
|
|
50058
50075
|
return false;
|
|
50059
50076
|
});
|
|
50060
50077
|
}
|
|
50061
50078
|
}
|
|
50062
50079
|
}
|
|
50063
50080
|
if (Array.isArray(next.appIconBadgeSources)) {
|
|
50064
|
-
const goneActions = new Set(
|
|
50081
|
+
const goneActions = new Set(report3.topBarActions);
|
|
50065
50082
|
const idsOf = (items) => new Set((items ?? []).map((i) => i.id).filter((x) => typeof x === "string"));
|
|
50066
|
-
const removedTabs = new Set(
|
|
50067
|
-
const removedDrawer = new Set(
|
|
50083
|
+
const removedTabs = new Set(report3.tabs);
|
|
50084
|
+
const removedDrawer = new Set(report3.drawer);
|
|
50068
50085
|
const remainingTabIds = idsOf(asItems(next.tabBar));
|
|
50069
50086
|
const remainingDrawerIds = idsOf(asItems(next.drawer));
|
|
50070
50087
|
next.appIconBadgeSources = next.appIconBadgeSources.filter((s) => {
|
|
50071
50088
|
if (typeof s !== "string") return true;
|
|
50072
50089
|
const [kind, id] = [s.slice(0, s.indexOf(":")), s.slice(s.indexOf(":") + 1)];
|
|
50073
50090
|
const gone = kind === "topBarAction" ? goneActions.has(id) : kind === "tab" ? removedTabs.has(id) && !remainingTabIds.has(id) : kind === "drawer" ? removedDrawer.has(id) && !remainingDrawerIds.has(id) : false;
|
|
50074
|
-
if (gone)
|
|
50091
|
+
if (gone) report3.appIconBadgeSources.push(s);
|
|
50075
50092
|
return !gone;
|
|
50076
50093
|
});
|
|
50077
50094
|
}
|
|
@@ -50081,7 +50098,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50081
50098
|
for (const l of original) if (typeof l.screenId === "string") byId.set(l.screenId, l);
|
|
50082
50099
|
const kept = original.filter((l) => {
|
|
50083
50100
|
if (typeof l.screenId === "string" && removed(l.screenId)) {
|
|
50084
|
-
|
|
50101
|
+
report3.linkable.push(l.screenId);
|
|
50085
50102
|
return false;
|
|
50086
50103
|
}
|
|
50087
50104
|
return true;
|
|
@@ -50125,7 +50142,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50125
50142
|
const entry = { screenId: String(l.screenId) };
|
|
50126
50143
|
if (toParent !== fromParent) entry.parentScreenId = { from: fromParent, to: toParent };
|
|
50127
50144
|
if (toTab !== fromTab) entry.tabId = { from: fromTab, to: toTab };
|
|
50128
|
-
|
|
50145
|
+
report3.reparented.push(entry);
|
|
50129
50146
|
}
|
|
50130
50147
|
for (const l of kept) {
|
|
50131
50148
|
if (typeof l.parentScreenId === "string") l.parentScreenId = newParent(l);
|
|
@@ -50133,7 +50150,7 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
50133
50150
|
}
|
|
50134
50151
|
next.linkableScreens = kept;
|
|
50135
50152
|
}
|
|
50136
|
-
return { nav: next, report:
|
|
50153
|
+
return { nav: next, report: report3 };
|
|
50137
50154
|
}
|
|
50138
50155
|
function leftoverNavRefs(nav, removedIds) {
|
|
50139
50156
|
const gone = new Set(removedIds);
|
|
@@ -50292,9 +50309,9 @@ function planTrim(src, keepIds, links) {
|
|
|
50292
50309
|
for (const r of keptRoutes) for (const b of r.bundles) keptWorkers.add(b);
|
|
50293
50310
|
const importsOf = (dir) => {
|
|
50294
50311
|
const out2 = [];
|
|
50295
|
-
for (const [rel,
|
|
50312
|
+
for (const [rel, text8] of Object.entries(src.workerFiles)) {
|
|
50296
50313
|
if (!rel.startsWith(`tier5-src/${dir}/`)) continue;
|
|
50297
|
-
for (const m of
|
|
50314
|
+
for (const m of text8.matchAll(/(?:\bfrom\s*|\bimport\s*\(?\s*|\brequire\s*\(\s*)["']\.\.\/([A-Za-z0-9_.-]+)(?:\/|["'])/g)) out2.push(m[1]);
|
|
50298
50315
|
}
|
|
50299
50316
|
return out2;
|
|
50300
50317
|
};
|
|
@@ -50340,9 +50357,9 @@ function planTrim(src, keepIds, links) {
|
|
|
50340
50357
|
continue;
|
|
50341
50358
|
}
|
|
50342
50359
|
const block = edited.get(r);
|
|
50343
|
-
let
|
|
50344
|
-
if (r === app.home && homeModules?.text !== void 0)
|
|
50345
|
-
if (
|
|
50360
|
+
let text8 = block ? serializeAt(block, app.dev, r.open) : void 0;
|
|
50361
|
+
if (r === app.home && homeModules?.text !== void 0) text8 = homeModules.text;
|
|
50362
|
+
if (text8 !== void 0) cut2(r.open, r.close, text8);
|
|
50346
50363
|
}
|
|
50347
50364
|
if (templatedEmptied) cut2(templatedEmptied[0], templatedEmptied[1], "\n");
|
|
50348
50365
|
dev += app.dev.slice(cursor);
|
|
@@ -50358,7 +50375,7 @@ function planTrim(src, keepIds, links) {
|
|
|
50358
50375
|
for (const e of edits.sort((a, b) => b.start - a.start)) config = config.slice(0, e.start) + e.text + config.slice(e.end);
|
|
50359
50376
|
const keptExact = keptRoutes.filter((r) => r.kind === "screen");
|
|
50360
50377
|
const keptTemplated = keptRoutes.filter((r) => r.kind === "templated");
|
|
50361
|
-
const
|
|
50378
|
+
const report3 = {
|
|
50362
50379
|
...links ? { links } : {},
|
|
50363
50380
|
kept: { screens: sorted(keptExact.map((r) => r.label)), templated: sorted(keptTemplated.map((r) => r.label)) },
|
|
50364
50381
|
implicit: implicit.map((r) => r.label),
|
|
@@ -50388,16 +50405,16 @@ function planTrim(src, keepIds, links) {
|
|
|
50388
50405
|
},
|
|
50389
50406
|
bytes: { before: Buffer.byteLength(app.dev), after: Buffer.byteLength(dev) }
|
|
50390
50407
|
};
|
|
50391
|
-
return { dev, config, removedWorkers, removedIds, report:
|
|
50408
|
+
return { dev, config, removedWorkers, removedIds, report: report3 };
|
|
50392
50409
|
}
|
|
50393
50410
|
function homeModulesPass(app, kept, edited) {
|
|
50394
50411
|
const verticals = Object.entries(EXPLORE_CARDS).filter(([, card2]) => app.exact.has(card2.screenId));
|
|
50395
50412
|
const removedVertical = verticals.some(([, card2]) => !kept.has(app.exact.get(card2.screenId)));
|
|
50396
50413
|
if (!removedVertical) return { dropped: [] };
|
|
50397
50414
|
const block = edited.get(app.home);
|
|
50398
|
-
const
|
|
50415
|
+
const text8 = block ? serializeAt(block, app.dev, app.home.open) : app.dev.slice(app.home.open, app.home.close);
|
|
50399
50416
|
const installed = verticals.filter(([, card2]) => kept.has(app.exact.get(card2.screenId))).map(([v]) => v);
|
|
50400
|
-
const patched = patchHomeModules(
|
|
50417
|
+
const patched = patchHomeModules(text8, installed);
|
|
50401
50418
|
if (!patched.droppedModules.length) return { dropped: [] };
|
|
50402
50419
|
return { text: patched.src, dropped: patched.droppedModules };
|
|
50403
50420
|
}
|
|
@@ -51111,8 +51128,8 @@ function isNoneEntry(entry) {
|
|
|
51111
51128
|
const head = entryHead(entry);
|
|
51112
51129
|
return NONE.test(entry) || head !== "" && NONE.test(head);
|
|
51113
51130
|
}
|
|
51114
|
-
function parseDataAccess(
|
|
51115
|
-
const body =
|
|
51131
|
+
function parseDataAccess(text8, from) {
|
|
51132
|
+
const body = text8.replace(/<!--[\s\S]*?(?:-->|$)/g, "");
|
|
51116
51133
|
const heading = new RegExp(`(?:^|\\n)##[ \\t]+${DATA_ACCESS_HEADING}\\b[^\\n]*([\\s\\S]*?)(?=\\n##[ \\t]|$)`, "i").exec(body);
|
|
51117
51134
|
if (!heading) return null;
|
|
51118
51135
|
const lines = heading[1].split("\n").map((l) => l.trim()).filter((l) => l.startsWith("|"));
|
|
@@ -51139,13 +51156,13 @@ function readDataAccess(dir) {
|
|
|
51139
51156
|
for (const name of ["SPEC.md", "MOBILE-UX.md"]) {
|
|
51140
51157
|
const p = join49(dir, name);
|
|
51141
51158
|
if (!existsSync50(p)) continue;
|
|
51142
|
-
let
|
|
51159
|
+
let text8;
|
|
51143
51160
|
try {
|
|
51144
|
-
|
|
51161
|
+
text8 = readFileSync55(p, "utf8");
|
|
51145
51162
|
} catch {
|
|
51146
51163
|
continue;
|
|
51147
51164
|
}
|
|
51148
|
-
const plan = parseDataAccess(
|
|
51165
|
+
const plan = parseDataAccess(text8, name);
|
|
51149
51166
|
if (plan) return plan;
|
|
51150
51167
|
}
|
|
51151
51168
|
return null;
|
|
@@ -51298,7 +51315,7 @@ function readTestConfig(dir) {
|
|
|
51298
51315
|
if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input) || Object.values(input).some((v) => typeof v !== "string"))) {
|
|
51299
51316
|
throw new Error(`${TEST_CONFIG_FILE}: journeys[${i}].input must be an object of string values \u2014 the screen input a nav edge would send, e.g. { "id": "svc-0001" }`);
|
|
51300
51317
|
}
|
|
51301
|
-
if (!Array.isArray(journey.expectText) || !journey.expectText.length || journey.expectText.some((
|
|
51318
|
+
if (!Array.isArray(journey.expectText) || !journey.expectText.length || journey.expectText.some((text8) => typeof text8 !== "string" || !text8.trim())) {
|
|
51302
51319
|
throw new Error(`${TEST_CONFIG_FILE}: journeys[${i}] needs non-empty expectText values that prove a visible result`);
|
|
51303
51320
|
}
|
|
51304
51321
|
});
|
|
@@ -51359,16 +51376,16 @@ function readCannedResponses() {
|
|
|
51359
51376
|
}
|
|
51360
51377
|
function makeRecordingWixCall(send2, token, app) {
|
|
51361
51378
|
const events = [];
|
|
51362
|
-
const
|
|
51379
|
+
const refused2 = [];
|
|
51363
51380
|
let id = 0;
|
|
51364
51381
|
const call = async (method, path2, body) => {
|
|
51365
51382
|
const verb = method.toUpperCase();
|
|
51366
51383
|
if (/[#\x00-\x1F\x7F]/.test(path2)) {
|
|
51367
|
-
|
|
51384
|
+
refused2.push(`${verb} ${path2}`);
|
|
51368
51385
|
throw new Error(`--record refused ${verb} ${path2}: the path carries a fragment or control character \u2014 not a provable read`);
|
|
51369
51386
|
}
|
|
51370
51387
|
if (!isProvenRead(verb, path2)) {
|
|
51371
|
-
|
|
51388
|
+
refused2.push(`${verb} ${path2}`);
|
|
51372
51389
|
throw new Error(`--record refused ${verb} ${path2}: recording sends only proven reads (GET, or POST ending in /query, /search, /list*, /get*, /count, /aggregate, /facets, /connections) \u2014 if this IS a read, add its rule to dev/net-mocks.json by hand`);
|
|
51373
51390
|
}
|
|
51374
51391
|
const bodyStr = body === void 0 ? void 0 : typeof body === "string" ? body : JSON.stringify(body);
|
|
@@ -51395,7 +51412,7 @@ function makeRecordingWixCall(send2, token, app) {
|
|
|
51395
51412
|
return r.body;
|
|
51396
51413
|
}
|
|
51397
51414
|
};
|
|
51398
|
-
return { call, events, refused };
|
|
51415
|
+
return { call, events, refused: refused2 };
|
|
51399
51416
|
}
|
|
51400
51417
|
async function runRecordPass(opts) {
|
|
51401
51418
|
const bootErrors = [];
|
|
@@ -51799,9 +51816,9 @@ function formatReport(r) {
|
|
|
51799
51816
|
out2.push(`transport: ${r.transport}`);
|
|
51800
51817
|
if (r.nativeDecode) {
|
|
51801
51818
|
for (const platform of ["ios", "android"]) {
|
|
51802
|
-
const
|
|
51803
|
-
if (!
|
|
51804
|
-
out2.push("unavailable" in
|
|
51819
|
+
const summary2 = r.nativeDecode[platform];
|
|
51820
|
+
if (!summary2) continue;
|
|
51821
|
+
out2.push("unavailable" in summary2 ? `native decode ${platform}: unavailable \u2014 ${summary2.reason}` : `native decode ${platform}: ${summary2.checked} checked, ${summary2.failed} failed in ${r.nativeDecode.wallMs}ms`);
|
|
51805
51822
|
}
|
|
51806
51823
|
}
|
|
51807
51824
|
out2.push("");
|
|
@@ -51944,14 +51961,14 @@ import { join as join51 } from "node:path";
|
|
|
51944
51961
|
function mobileUxIssues(dir, strict) {
|
|
51945
51962
|
const file = join51(dir, "MOBILE-UX.md");
|
|
51946
51963
|
if (!existsSync52(file)) return [];
|
|
51947
|
-
let
|
|
51964
|
+
let text8;
|
|
51948
51965
|
try {
|
|
51949
|
-
|
|
51966
|
+
text8 = readFileSync57(file, "utf8");
|
|
51950
51967
|
} catch {
|
|
51951
51968
|
return [];
|
|
51952
51969
|
}
|
|
51953
|
-
if (!
|
|
51954
|
-
return mobileUxMarkerFindings(
|
|
51970
|
+
if (!text8) return [];
|
|
51971
|
+
return mobileUxMarkerFindings(text8, recordedRenderWidths(dir)).map((finding) => {
|
|
51955
51972
|
const scaffoldAdvisory = finding.code === "missing-width-evidence";
|
|
51956
51973
|
return {
|
|
51957
51974
|
screen: null,
|
|
@@ -52246,7 +52263,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
52246
52263
|
const headers2 = Object.fromEntries(new Headers(init.headers).entries());
|
|
52247
52264
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
52248
52265
|
const hostname2 = url.hostname.replace(/^\[|\]$/g, "");
|
|
52249
|
-
return await new Promise((
|
|
52266
|
+
return await new Promise((resolve53, reject) => {
|
|
52250
52267
|
let settled = false;
|
|
52251
52268
|
const finish2 = (fn) => {
|
|
52252
52269
|
if (settled) return;
|
|
@@ -52283,7 +52300,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
52283
52300
|
}
|
|
52284
52301
|
const responseHeaders = new Headers();
|
|
52285
52302
|
for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
|
|
52286
|
-
|
|
52303
|
+
resolve53(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
|
|
52287
52304
|
}));
|
|
52288
52305
|
});
|
|
52289
52306
|
req.once("error", (error) => finish2(() => reject(error)));
|
|
@@ -52583,7 +52600,7 @@ function createLocalTestSandbox() {
|
|
|
52583
52600
|
}
|
|
52584
52601
|
})();
|
|
52585
52602
|
`;
|
|
52586
|
-
return await new Promise((
|
|
52603
|
+
return await new Promise((resolve53, reject) => {
|
|
52587
52604
|
const { port1, port2 } = new MessageChannel();
|
|
52588
52605
|
const serializableContext = {
|
|
52589
52606
|
auth: context.auth,
|
|
@@ -52659,7 +52676,7 @@ function createLocalTestSandbox() {
|
|
|
52659
52676
|
timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
|
|
52660
52677
|
return;
|
|
52661
52678
|
}
|
|
52662
|
-
if (message.ok) finish2(() =>
|
|
52679
|
+
if (message.ok) finish2(() => resolve53({ value: message.value, durationMs: Date.now() - started }));
|
|
52663
52680
|
else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
|
|
52664
52681
|
});
|
|
52665
52682
|
worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
|
|
@@ -53775,12 +53792,12 @@ async function runRemoteFunctionOperation(input) {
|
|
|
53775
53792
|
if (input.boCookie) headers2.cookie = input.boCookie;
|
|
53776
53793
|
if (input.previewToken) headers2["x-himalaya-preview-token"] = input.previewToken;
|
|
53777
53794
|
const response = await (input.fetchImpl ?? fetch)(url, { method, headers: headers2 });
|
|
53778
|
-
const
|
|
53795
|
+
const text8 = await response.text();
|
|
53779
53796
|
let body;
|
|
53780
53797
|
try {
|
|
53781
|
-
body = JSON.parse(
|
|
53798
|
+
body = JSON.parse(text8);
|
|
53782
53799
|
} catch {
|
|
53783
|
-
body =
|
|
53800
|
+
body = text8;
|
|
53784
53801
|
}
|
|
53785
53802
|
return { ok: response.ok, status: response.status, body };
|
|
53786
53803
|
}
|
|
@@ -53868,7 +53885,7 @@ function flagShapedInputs(args) {
|
|
|
53868
53885
|
function guarded(h) {
|
|
53869
53886
|
return async (args, deps) => {
|
|
53870
53887
|
const bad2 = flagShapedInputs(args);
|
|
53871
|
-
if (bad2.length) return
|
|
53888
|
+
if (bad2.length) return text6(`refused: ${bad2.join(", ")} may not start with "-" (it would be read as a himi flag)`, true);
|
|
53872
53889
|
return h(args, deps);
|
|
53873
53890
|
};
|
|
53874
53891
|
}
|
|
@@ -54021,7 +54038,7 @@ function rawTools() {
|
|
|
54021
54038
|
return json3({ ...await d.preview.start(await appDir2(a, d)), hint: PREVIEW_HINT });
|
|
54022
54039
|
} catch (e) {
|
|
54023
54040
|
const log = e.log;
|
|
54024
|
-
return
|
|
54041
|
+
return text6(`${e.message}${typeof log === "string" && log ? `
|
|
54025
54042
|
|
|
54026
54043
|
${log}` : ""}`, true);
|
|
54027
54044
|
}
|
|
@@ -54086,7 +54103,9 @@ ${log}` : ""}`, true);
|
|
|
54086
54103
|
name: "himi_preview_links",
|
|
54087
54104
|
title: "Preview links for a release",
|
|
54088
54105
|
description: "The shareable web preview URL, the Himi Player deep link and the agent preview JSON URLs for an app + release (for example the draft `himi_push` just published).",
|
|
54089
|
-
|
|
54106
|
+
// Not idempotent: with credentials, each `himi preview` mints a fresh single-use handover —
|
|
54107
|
+
// the same reason the hosted connector's tool of this name says false (RFC 0064 §5).
|
|
54108
|
+
annotations: { ...PUBLISH, readOnlyHint: true, idempotentHint: false },
|
|
54090
54109
|
inputSchema: z.object({
|
|
54091
54110
|
app: z.string().min(1),
|
|
54092
54111
|
release: z.string().min(1),
|
|
@@ -54097,14 +54116,14 @@ ${log}` : ""}`, true);
|
|
|
54097
54116
|
}
|
|
54098
54117
|
];
|
|
54099
54118
|
}
|
|
54100
|
-
var MAX_TEXT2, clip,
|
|
54119
|
+
var MAX_TEXT2, clip, text6, json3, opt, sw, DIR, LEARN, CHECK, LOCAL_WRITE, PUBLISH, PREVIEW_HINT, LOGIN_HINT;
|
|
54101
54120
|
var init_tools = __esm({
|
|
54102
54121
|
"src/mcp/tools.ts"() {
|
|
54103
54122
|
MAX_TEXT2 = 8e4;
|
|
54104
54123
|
clip = (s) => s.length <= MAX_TEXT2 ? s : `${s.slice(0, MAX_TEXT2)}
|
|
54105
54124
|
\u2026 [truncated ${s.length - MAX_TEXT2} chars \u2014 re-run the command in a terminal for the full output]`;
|
|
54106
|
-
|
|
54107
|
-
json3 = (o) =>
|
|
54125
|
+
text6 = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...isError ? { isError: true } : {} });
|
|
54126
|
+
json3 = (o) => text6(JSON.stringify(o, null, 2));
|
|
54108
54127
|
opt = (flag, v) => typeof v === "string" && v ? [flag, v] : typeof v === "number" ? [flag, String(v)] : [];
|
|
54109
54128
|
sw = (flag, v) => v === true ? [flag] : [];
|
|
54110
54129
|
DIR = z.string().optional().describe("The app (content package) directory. Default: the workspace root the host opened, else the server's working directory.");
|
|
@@ -54180,9 +54199,9 @@ async function startMcpServer(opts) {
|
|
|
54180
54199
|
},
|
|
54181
54200
|
readFile: (p) => readFileSync59(p)
|
|
54182
54201
|
};
|
|
54183
|
-
const closed = new Promise((
|
|
54184
|
-
stdin.once("end",
|
|
54185
|
-
stdin.once("close",
|
|
54202
|
+
const closed = new Promise((resolve53) => {
|
|
54203
|
+
stdin.once("end", resolve53);
|
|
54204
|
+
stdin.once("close", resolve53);
|
|
54186
54205
|
});
|
|
54187
54206
|
const handle = serveStdio(
|
|
54188
54207
|
() => {
|
|
@@ -54424,7 +54443,7 @@ function fieldAt(path2) {
|
|
|
54424
54443
|
if (path2 === null) return void 0;
|
|
54425
54444
|
return path2.match(/\.([^.[\]]+)$/)?.[1];
|
|
54426
54445
|
}
|
|
54427
|
-
function mergeNativeDecode(
|
|
54446
|
+
function mergeNativeDecode(report3, run2) {
|
|
54428
54447
|
const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
|
|
54429
54448
|
const nativeFailures = run2.verdicts.flatMap((verdict) => verdict.errors.map((error) => ({
|
|
54430
54449
|
screen: verdict.screenId,
|
|
@@ -54437,18 +54456,18 @@ function mergeNativeDecode(report2, run2) {
|
|
|
54437
54456
|
...error.actual ? { actual: error.actual } : {},
|
|
54438
54457
|
hint: `This descriptor ships as a full-screen \u201CCouldn't load\u201D; fix the typed field and rerun \`himi test --native ${run2.platform}\`.`
|
|
54439
54458
|
})));
|
|
54440
|
-
const failures = [...
|
|
54459
|
+
const failures = [...report3.failures, ...nativeFailures];
|
|
54441
54460
|
const failedScreens = new Set(failures.map((finding) => finding.screen));
|
|
54442
54461
|
return {
|
|
54443
|
-
...
|
|
54444
|
-
ok:
|
|
54462
|
+
...report3,
|
|
54463
|
+
ok: report3.ok && nativeFailures.length === 0,
|
|
54445
54464
|
failures,
|
|
54446
|
-
counts: { ...
|
|
54447
|
-
screens: { ...
|
|
54465
|
+
counts: { ...report3.counts, errors: failures.length },
|
|
54466
|
+
screens: { ...report3.screens, clean: report3.screens.total - failedScreens.size, failed: failedScreens.size },
|
|
54448
54467
|
nativeDecode: {
|
|
54449
|
-
...
|
|
54468
|
+
...report3.nativeDecode,
|
|
54450
54469
|
[run2.platform]: { checked: run2.verdicts.length, failed: run2.verdicts.filter((verdict) => !verdict.ok).length },
|
|
54451
|
-
wallMs: (
|
|
54470
|
+
wallMs: (report3.nativeDecode?.wallMs ?? 0) + run2.wallMs
|
|
54452
54471
|
}
|
|
54453
54472
|
};
|
|
54454
54473
|
}
|
|
@@ -54561,10 +54580,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
54561
54580
|
for (const source of Object.values(files)) visit(source);
|
|
54562
54581
|
return { modules, unsupported };
|
|
54563
54582
|
}
|
|
54564
|
-
function sdkSubpathReader(
|
|
54583
|
+
function sdkSubpathReader(resolve53) {
|
|
54565
54584
|
return (sub) => {
|
|
54566
54585
|
try {
|
|
54567
|
-
return readFileSync61(
|
|
54586
|
+
return readFileSync61(resolve53(`@wix/himalaya/${sub}`), "utf8");
|
|
54568
54587
|
} catch {
|
|
54569
54588
|
return null;
|
|
54570
54589
|
}
|
|
@@ -54642,7 +54661,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
54642
54661
|
const token = mintToken2(payload);
|
|
54643
54662
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
54644
54663
|
if (unusable) throw new Error(unusable);
|
|
54645
|
-
return await new Promise((
|
|
54664
|
+
return await new Promise((resolve53, reject) => {
|
|
54646
54665
|
let settled = false;
|
|
54647
54666
|
let url = "";
|
|
54648
54667
|
const server = createServer5();
|
|
@@ -54693,8 +54712,8 @@ async function runBrowserAuthoring(opts) {
|
|
|
54693
54712
|
return;
|
|
54694
54713
|
}
|
|
54695
54714
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
54696
|
-
const
|
|
54697
|
-
finish2(() =>
|
|
54715
|
+
const report3 = body.result;
|
|
54716
|
+
finish2(() => resolve53({ report: report3, url }));
|
|
54698
54717
|
})();
|
|
54699
54718
|
});
|
|
54700
54719
|
server.on("error", (e) => finish2(() => reject(e)));
|
|
@@ -55371,10 +55390,10 @@ async function hostedAuthUrl(req, visitorToken, fetchImpl = fetch) {
|
|
|
55371
55390
|
}
|
|
55372
55391
|
})
|
|
55373
55392
|
});
|
|
55374
|
-
const
|
|
55393
|
+
const text8 = await res.text();
|
|
55375
55394
|
let parsed = {};
|
|
55376
55395
|
try {
|
|
55377
|
-
parsed =
|
|
55396
|
+
parsed = text8 ? JSON.parse(text8) : {};
|
|
55378
55397
|
} catch {
|
|
55379
55398
|
}
|
|
55380
55399
|
const fullUrl = parsed.redirectSession?.fullUrl;
|
|
@@ -55394,10 +55413,10 @@ async function exchangeAuthCode(cfg, code, verifier, fetchImpl = fetch) {
|
|
|
55394
55413
|
redirectUri: cfg.redirectUri
|
|
55395
55414
|
})
|
|
55396
55415
|
});
|
|
55397
|
-
const
|
|
55416
|
+
const text8 = await res.text();
|
|
55398
55417
|
let parsed = {};
|
|
55399
55418
|
try {
|
|
55400
|
-
parsed =
|
|
55419
|
+
parsed = text8 ? JSON.parse(text8) : {};
|
|
55401
55420
|
} catch {
|
|
55402
55421
|
}
|
|
55403
55422
|
if (res.status !== 200 || !parsed.access_token) throw new Error(`token exchange failed (${res.status})`);
|
|
@@ -56611,11 +56630,11 @@ async function localizeConfigResponse(res, kind, header) {
|
|
|
56611
56630
|
header
|
|
56612
56631
|
)
|
|
56613
56632
|
};
|
|
56614
|
-
const
|
|
56633
|
+
const text8 = JSON.stringify(next);
|
|
56615
56634
|
const headers2 = new Headers(res.headers);
|
|
56616
56635
|
headers2.delete("etag");
|
|
56617
|
-
headers2.set("content-length", String(new TextEncoder().encode(
|
|
56618
|
-
return new Response(
|
|
56636
|
+
headers2.set("content-length", String(new TextEncoder().encode(text8).length));
|
|
56637
|
+
return new Response(text8, { status: 200, headers: headers2 });
|
|
56619
56638
|
}
|
|
56620
56639
|
function makeRunHandler(opts) {
|
|
56621
56640
|
const mount = opts.chrome === "app" ? "/app" : "/preview";
|
|
@@ -56803,8 +56822,8 @@ var init_node_adapter = __esm({
|
|
|
56803
56822
|
function authConfigOf(appConfig) {
|
|
56804
56823
|
if (!appConfig) return void 0;
|
|
56805
56824
|
try {
|
|
56806
|
-
const
|
|
56807
|
-
return JSON.parse(
|
|
56825
|
+
const text8 = typeof appConfig === "string" ? appConfig : new TextDecoder().decode(appConfig);
|
|
56826
|
+
return JSON.parse(text8)?.authConfig ?? void 0;
|
|
56808
56827
|
} catch {
|
|
56809
56828
|
return void 0;
|
|
56810
56829
|
}
|
|
@@ -57414,16 +57433,16 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57414
57433
|
const manifest = await store.getManifest(app);
|
|
57415
57434
|
if (!manifest) throw new Error(`no release manifest for ${app} under ${root}`);
|
|
57416
57435
|
const b64 = (b) => b ? Buffer.from(b).toString("base64") : void 0;
|
|
57417
|
-
const
|
|
57436
|
+
const text8 = (b) => b ? new TextDecoder().decode(b) : void 0;
|
|
57418
57437
|
const screens = {};
|
|
57419
57438
|
const docs = {};
|
|
57420
57439
|
const addDoc = async (hash) => {
|
|
57421
57440
|
if (!hash || docs[hash] !== void 0) return;
|
|
57422
|
-
const d =
|
|
57441
|
+
const d = text8(await store.getDoc?.(app, hash) ?? null);
|
|
57423
57442
|
if (d !== void 0) docs[hash] = d;
|
|
57424
57443
|
};
|
|
57425
57444
|
for (const [id, meta] of Object.entries(manifest.screens ?? {})) {
|
|
57426
|
-
const s =
|
|
57445
|
+
const s = text8(await store.getScreen(app, id));
|
|
57427
57446
|
if (s !== void 0) screens[id] = s;
|
|
57428
57447
|
await addDoc(meta.descriptorHash);
|
|
57429
57448
|
}
|
|
@@ -57444,10 +57463,10 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57444
57463
|
}
|
|
57445
57464
|
const widgets = {};
|
|
57446
57465
|
for (const id of Object.keys(manifest.widgets ?? {})) {
|
|
57447
|
-
const w =
|
|
57466
|
+
const w = text8(await store.getWidget?.(app, id) ?? null);
|
|
57448
57467
|
if (w !== void 0) widgets[id] = w;
|
|
57449
57468
|
}
|
|
57450
|
-
const appConfig =
|
|
57469
|
+
const appConfig = text8(await store.getAppConfig(app));
|
|
57451
57470
|
const wixClientId = appConfigWixClientId(appConfig);
|
|
57452
57471
|
return {
|
|
57453
57472
|
app,
|
|
@@ -57457,7 +57476,7 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57457
57476
|
docs,
|
|
57458
57477
|
assets,
|
|
57459
57478
|
widgets,
|
|
57460
|
-
tokens:
|
|
57479
|
+
tokens: text8(await store.getTokens(app)),
|
|
57461
57480
|
appConfig,
|
|
57462
57481
|
icon: b64(await store.getIcon?.(app) ?? null),
|
|
57463
57482
|
header,
|
|
@@ -57987,10 +58006,10 @@ function scalar3(v) {
|
|
|
57987
58006
|
}
|
|
57988
58007
|
return t;
|
|
57989
58008
|
}
|
|
57990
|
-
function parseStoreConfig(
|
|
58009
|
+
function parseStoreConfig(text8) {
|
|
57991
58010
|
const cfg = {};
|
|
57992
58011
|
let section2 = null;
|
|
57993
|
-
for (const raw of
|
|
58012
|
+
for (const raw of text8.split("\n")) {
|
|
57994
58013
|
const line = strip2(raw);
|
|
57995
58014
|
if (!line.trim()) continue;
|
|
57996
58015
|
const indented = /^\s+/.test(raw);
|
|
@@ -58049,10 +58068,10 @@ function profilePath(name, home = homedir5()) {
|
|
|
58049
58068
|
}
|
|
58050
58069
|
return join59(credentialsDir(home), `${name}.json`);
|
|
58051
58070
|
}
|
|
58052
|
-
function parseProfile(
|
|
58071
|
+
function parseProfile(text8, label2) {
|
|
58053
58072
|
let doc;
|
|
58054
58073
|
try {
|
|
58055
|
-
doc = JSON.parse(
|
|
58074
|
+
doc = JSON.parse(text8);
|
|
58056
58075
|
} catch (e) {
|
|
58057
58076
|
throw new Error(`${label2} is not valid JSON: ${e.message}`);
|
|
58058
58077
|
}
|
|
@@ -58661,11 +58680,11 @@ async function registerBundleId(opts) {
|
|
|
58661
58680
|
const j = await res.json();
|
|
58662
58681
|
return { status: "created", id: j.data?.id };
|
|
58663
58682
|
}
|
|
58664
|
-
const
|
|
58665
|
-
if (res.status === 409 || /already (exists|in use)|duplicate|ENTITY_ERROR.*identifier/i.test(
|
|
58683
|
+
const text8 = await res.text();
|
|
58684
|
+
if (res.status === 409 || /already (exists|in use)|duplicate|ENTITY_ERROR.*identifier/i.test(text8)) {
|
|
58666
58685
|
return { status: "exists" };
|
|
58667
58686
|
}
|
|
58668
|
-
throw new Error(`POST /v1/bundleIds \u2192 ${res.status}: ${
|
|
58687
|
+
throw new Error(`POST /v1/bundleIds \u2192 ${res.status}: ${text8.slice(0, 300)}`);
|
|
58669
58688
|
}
|
|
58670
58689
|
async function main2() {
|
|
58671
58690
|
const [app, ...rest] = process.argv.slice(2);
|
|
@@ -58943,12 +58962,12 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
58943
58962
|
body = JSON.stringify({ value });
|
|
58944
58963
|
}
|
|
58945
58964
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
58946
|
-
const
|
|
58965
|
+
const text8 = await response.text();
|
|
58947
58966
|
let output;
|
|
58948
58967
|
try {
|
|
58949
|
-
output = JSON.parse(
|
|
58968
|
+
output = JSON.parse(text8);
|
|
58950
58969
|
} catch {
|
|
58951
|
-
output =
|
|
58970
|
+
output = text8;
|
|
58952
58971
|
}
|
|
58953
58972
|
if (!response.ok) throw new Error(typeof output === "string" ? output : JSON.stringify(output));
|
|
58954
58973
|
io.log(JSON.stringify(output));
|
|
@@ -58964,6 +58983,217 @@ var init_secrets2 = __esm({
|
|
|
58964
58983
|
}
|
|
58965
58984
|
});
|
|
58966
58985
|
|
|
58986
|
+
// ../serve-cli/src/push-send.ts
|
|
58987
|
+
async function pushSendRequest(options) {
|
|
58988
|
+
const refusal = localRefusal(options);
|
|
58989
|
+
if (refusal) return { ok: false, status: 0, body: null, error: refusal };
|
|
58990
|
+
try {
|
|
58991
|
+
const response = await (options.fetchImpl ?? fetch)(`${options.target.control.replace(/\/+$/, "")}/v1/admin/push/send`, {
|
|
58992
|
+
method: "POST",
|
|
58993
|
+
headers: headersFor(options),
|
|
58994
|
+
redirect: "error",
|
|
58995
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
58996
|
+
body: JSON.stringify(options.body)
|
|
58997
|
+
});
|
|
58998
|
+
const retryAfterSec = response.status === 429 ? Number(response.headers.get("retry-after")) : NaN;
|
|
58999
|
+
return {
|
|
59000
|
+
ok: response.ok,
|
|
59001
|
+
status: response.status,
|
|
59002
|
+
body: objectFrom(await response.text()),
|
|
59003
|
+
...Number.isFinite(retryAfterSec) && retryAfterSec > 0 ? { retryAfterSec } : {}
|
|
59004
|
+
};
|
|
59005
|
+
} catch {
|
|
59006
|
+
return { ok: false, status: 0, body: null, error: "push_send_unreachable" };
|
|
59007
|
+
}
|
|
59008
|
+
}
|
|
59009
|
+
function localRefusal(options) {
|
|
59010
|
+
if (!options.target.controlToken) return "control_token_required";
|
|
59011
|
+
if (!options.wixToken) return "wix_account_token_required";
|
|
59012
|
+
if (!options.siteToken) return "site_token_required";
|
|
59013
|
+
if (credentialHostRefusal(options.target.control)) return "insecure_target";
|
|
59014
|
+
if (options.previewTag !== void 0 && !PREVIEW_TAG2.test(options.previewTag)) return "invalid_preview_tag";
|
|
59015
|
+
return void 0;
|
|
59016
|
+
}
|
|
59017
|
+
function headersFor(options) {
|
|
59018
|
+
return {
|
|
59019
|
+
"x-control-token": options.target.controlToken,
|
|
59020
|
+
// RAW, never `Bearer ` — what normalizeWixAuthorization and token-info expect.
|
|
59021
|
+
Authorization: options.wixToken,
|
|
59022
|
+
[SITE_TOKEN_HEADER]: options.siteToken,
|
|
59023
|
+
accept: "application/json",
|
|
59024
|
+
"content-type": "application/json",
|
|
59025
|
+
...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
|
|
59026
|
+
};
|
|
59027
|
+
}
|
|
59028
|
+
function objectFrom(text8) {
|
|
59029
|
+
try {
|
|
59030
|
+
const value = text8 ? JSON.parse(text8) : null;
|
|
59031
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
59032
|
+
} catch {
|
|
59033
|
+
return null;
|
|
59034
|
+
}
|
|
59035
|
+
}
|
|
59036
|
+
var SITE_TOKEN_HEADER, PREVIEW_TAG2, TIMEOUT_MS;
|
|
59037
|
+
var init_push_send = __esm({
|
|
59038
|
+
"../serve-cli/src/push-send.ts"() {
|
|
59039
|
+
init_credential_hosts();
|
|
59040
|
+
SITE_TOKEN_HEADER = "x-himi-site-token";
|
|
59041
|
+
PREVIEW_TAG2 = /^dp-[a-z0-9]+$/;
|
|
59042
|
+
TIMEOUT_MS = 6e4;
|
|
59043
|
+
}
|
|
59044
|
+
});
|
|
59045
|
+
|
|
59046
|
+
// ../../core/serve-control/src/push-send-service.ts
|
|
59047
|
+
var PUSH_SEND_ERROR_CODES;
|
|
59048
|
+
var init_push_send_service = __esm({
|
|
59049
|
+
"../../core/serve-control/src/push-send-service.ts"() {
|
|
59050
|
+
PUSH_SEND_ERROR_CODES = [
|
|
59051
|
+
"unauthorized",
|
|
59052
|
+
"token_revoked",
|
|
59053
|
+
"revocation_check_unavailable",
|
|
59054
|
+
"method_not_allowed",
|
|
59055
|
+
"rate_limited",
|
|
59056
|
+
"forbidden_cross_tenant",
|
|
59057
|
+
"forbidden_site",
|
|
59058
|
+
"site_check_unavailable",
|
|
59059
|
+
"push_send_unconfigured",
|
|
59060
|
+
"push_send_unavailable",
|
|
59061
|
+
"invalid_input",
|
|
59062
|
+
"payload_too_large",
|
|
59063
|
+
"unknown_field",
|
|
59064
|
+
"invalid_app_id",
|
|
59065
|
+
"invalid_site_id",
|
|
59066
|
+
"invalid_member_email",
|
|
59067
|
+
"invalid_title",
|
|
59068
|
+
"invalid_body",
|
|
59069
|
+
"invalid_link",
|
|
59070
|
+
"invalid_request_id",
|
|
59071
|
+
"invalid_dry_run",
|
|
59072
|
+
"link_not_routable",
|
|
59073
|
+
"app_config_unavailable",
|
|
59074
|
+
"push_not_ready",
|
|
59075
|
+
"site_token_required",
|
|
59076
|
+
"site_token_invalid",
|
|
59077
|
+
"site_token_unverifiable",
|
|
59078
|
+
"member_not_found",
|
|
59079
|
+
"member_ambiguous",
|
|
59080
|
+
"member_not_active",
|
|
59081
|
+
"member_read_forbidden",
|
|
59082
|
+
"member_lookup_unavailable",
|
|
59083
|
+
"ping_unconfigured",
|
|
59084
|
+
"ping_permission_denied",
|
|
59085
|
+
"ping_rejected",
|
|
59086
|
+
"ping_rate_limited",
|
|
59087
|
+
"send_outcome_unknown"
|
|
59088
|
+
];
|
|
59089
|
+
}
|
|
59090
|
+
});
|
|
59091
|
+
|
|
59092
|
+
// src/notify-ping.ts
|
|
59093
|
+
var notify_ping_exports = {};
|
|
59094
|
+
__export(notify_ping_exports, {
|
|
59095
|
+
runNotifyPing: () => runNotifyPing
|
|
59096
|
+
});
|
|
59097
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
59098
|
+
import { resolve as resolve49 } from "node:path";
|
|
59099
|
+
function refuse4(io, error, hint, exit = 2, extra = {}) {
|
|
59100
|
+
io.error(JSON.stringify({ ok: false, error, ...hint ? { hint } : {}, ...extra }));
|
|
59101
|
+
return exit;
|
|
59102
|
+
}
|
|
59103
|
+
async function runNotifyPing(flags, io, deps = {}) {
|
|
59104
|
+
const flagError = flagRefusal(flags);
|
|
59105
|
+
if (flagError) return refuse4(io, flagError);
|
|
59106
|
+
const input = mergePushInputs(pushInputsFromContent(resolve49(text7(flags.content) ?? process.cwd())), flags);
|
|
59107
|
+
const missing = [...input.app ? [] : ["app"], ...input.site ? [] : ["site"], ...REQUIRED_FLAGS.filter((f) => !text7(flags[f]))];
|
|
59108
|
+
if (missing.length) return refuse4(io, "needs_input", "Name the app and site (or --content), the member's login email, a title and a link.", 2, { missing });
|
|
59109
|
+
const requestId2 = text7(flags["request-id"]) ?? (deps.newRequestId ?? randomUUID5)();
|
|
59110
|
+
if (!UUID_RE.test(requestId2)) return refuse4(io, "invalid_request_id", "Reuse the requestId a previous send printed.");
|
|
59111
|
+
const owner = await hostedOwnerSession(flags, deps);
|
|
59112
|
+
if (!owner.ok) return refuse4(io, owner.error, owner.hint, owner.exit);
|
|
59113
|
+
const { session } = owner;
|
|
59114
|
+
const ownership = await verifyAppOwnership({ ownerIssue: session.ownerIssue, controlToken: session.controlToken, declaredName: input.app, fetchImpl: deps.fetchImpl });
|
|
59115
|
+
if (ownership.state !== "owned") return refuse4(io, `app_ownership_${ownership.state}`, "Sending requires the app owner.", 1);
|
|
59116
|
+
let siteToken2;
|
|
59117
|
+
try {
|
|
59118
|
+
siteToken2 = await (deps.siteToken ?? siteToken)(input.site);
|
|
59119
|
+
} catch {
|
|
59120
|
+
return refuse4(io, "wix_site_token_required", "Run wix login as the site owner; the site token reads this site's members.", 1);
|
|
59121
|
+
}
|
|
59122
|
+
const body = {
|
|
59123
|
+
app: ownership.slug,
|
|
59124
|
+
site: input.site,
|
|
59125
|
+
memberEmail: text7(flags["member-email"]),
|
|
59126
|
+
title: text7(flags.title),
|
|
59127
|
+
...text7(flags.body) ? { body: text7(flags.body) } : {},
|
|
59128
|
+
link: text7(flags.link),
|
|
59129
|
+
requestId: requestId2,
|
|
59130
|
+
...flags["dry-run"] === true ? { dryRun: true } : {}
|
|
59131
|
+
};
|
|
59132
|
+
const http = await pushSendRequest({ target: session.target, wixToken: session.wixToken, siteToken: siteToken2, body, previewTag: session.previewTag, fetchImpl: deps.fetchImpl });
|
|
59133
|
+
return report2(http, body, flags, io);
|
|
59134
|
+
}
|
|
59135
|
+
function flagRefusal(flags) {
|
|
59136
|
+
if (LOCAL_SENDER_FLAGS.some((f) => flags[f] !== void 0)) return "flag_not_supported_with_ping";
|
|
59137
|
+
if (SWITCHES.some((f) => flags[f] !== void 0 && typeof flags[f] !== "boolean")) return "invalid_boolean_flag";
|
|
59138
|
+
return void 0;
|
|
59139
|
+
}
|
|
59140
|
+
function report2(http, sent, flags, io) {
|
|
59141
|
+
const code = refusalCode(http);
|
|
59142
|
+
if (code === "send_outcome_unknown") {
|
|
59143
|
+
return refuse4(io, code, `Ping may have accepted it. Re-run the same command with --request-id ${sent.requestId}: Ping runs one request at most once per site for 24 hours.`, 1, { requestId: sent.requestId });
|
|
59144
|
+
}
|
|
59145
|
+
if (code === "rate_limited" && http.retryAfterSec) {
|
|
59146
|
+
return refuse4(io, code, `Test sends are limited per owner; retry in ${http.retryAfterSec} seconds.`, 1, { retryAfterSec: http.retryAfterSec });
|
|
59147
|
+
}
|
|
59148
|
+
if (code) return refuse4(io, code, HINTS[code], 1);
|
|
59149
|
+
if (flags.json === true) io.log(JSON.stringify(http.body, null, 2));
|
|
59150
|
+
else io.log(summary(http.body ?? {}, sent));
|
|
59151
|
+
return 0;
|
|
59152
|
+
}
|
|
59153
|
+
function refusalCode(http) {
|
|
59154
|
+
if (http.error) return http.error === "push_send_unreachable" ? "send_outcome_unknown" : http.error;
|
|
59155
|
+
if (http.ok && (http.body?.state === "accepted" || http.body?.state === "dry_run")) return void 0;
|
|
59156
|
+
const code = String(http.body?.error ?? "");
|
|
59157
|
+
if (KNOWN_CODES.has(code)) return code;
|
|
59158
|
+
return http.ok || http.status >= 500 ? "send_outcome_unknown" : "push_send_failed";
|
|
59159
|
+
}
|
|
59160
|
+
function summary(result, sent) {
|
|
59161
|
+
if (result.state === "dry_run") {
|
|
59162
|
+
return `Dry run passed: ${sent.memberEmail} is an approved member, the link routes, and push is ready for ${sent.app}. No notification was sent.`;
|
|
59163
|
+
}
|
|
59164
|
+
if (result.deduplicated === true) {
|
|
59165
|
+
return `Ping already ran request ${sent.requestId}; the earlier send stands and no second notification was sent.`;
|
|
59166
|
+
}
|
|
59167
|
+
return `Ping accepted request ${sent.requestId} for ${sent.memberEmail}. Ping does not confirm delivery: it reaches the member's signed-in devices with notifications allowed.`;
|
|
59168
|
+
}
|
|
59169
|
+
var LOCAL_SENDER_FLAGS, SWITCHES, REQUIRED_FLAGS, UUID_RE, KNOWN_CODES, HINTS, text7;
|
|
59170
|
+
var init_notify_ping = __esm({
|
|
59171
|
+
"src/notify-ping.ts"() {
|
|
59172
|
+
init_push_send();
|
|
59173
|
+
init_push_send_service();
|
|
59174
|
+
init_hosted_owner();
|
|
59175
|
+
init_owner_claim();
|
|
59176
|
+
init_push_onboarding();
|
|
59177
|
+
init_wix_owner();
|
|
59178
|
+
LOCAL_SENDER_FLAGS = ["token", "device", "all", "admin-url", "admin-session", "silent", "badge", "data", "category", "channel", "platform", "bundle-id"];
|
|
59179
|
+
SWITCHES = ["json", "dry-run"];
|
|
59180
|
+
REQUIRED_FLAGS = ["member-email", "title", "link"];
|
|
59181
|
+
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
59182
|
+
KNOWN_CODES = new Set(PUSH_SEND_ERROR_CODES);
|
|
59183
|
+
HINTS = {
|
|
59184
|
+
push_not_ready: "Run himi notify setup for this app and site first; status must be ready.",
|
|
59185
|
+
member_not_found: "Use the login email of an approved member of this site.",
|
|
59186
|
+
member_ambiguous: "More than one member has this login email; resolve it in the site's Members.",
|
|
59187
|
+
member_not_active: "The member must be approved before they can be notified.",
|
|
59188
|
+
link_not_routable: "Link to a screen this app's published release ships, e.g. <scheme>://screen/<screenId>?id=\u2026.",
|
|
59189
|
+
forbidden_site: "The Wix account from wix login must own this site.",
|
|
59190
|
+
site_token_invalid: "Run wix login as the site owner; the site token must belong to the app owner's account.",
|
|
59191
|
+
ping_permission_denied: "Himi Serve is not permitted to send through Ping; this is a platform issue, not your setup."
|
|
59192
|
+
};
|
|
59193
|
+
text7 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
59194
|
+
}
|
|
59195
|
+
});
|
|
59196
|
+
|
|
58967
59197
|
// src/notify.ts
|
|
58968
59198
|
var notify_exports = {};
|
|
58969
59199
|
__export(notify_exports, {
|
|
@@ -59066,7 +59296,7 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59066
59296
|
} catch {
|
|
59067
59297
|
reachable = false;
|
|
59068
59298
|
}
|
|
59069
|
-
const
|
|
59299
|
+
const report3 = {
|
|
59070
59300
|
// BOTH platforms must be ready. Considering only iOS meant a server with an APNs
|
|
59071
59301
|
// key but no Firebase credentials reported ok and exited 0, while every Android
|
|
59072
59302
|
// send would fail — from the command whose whole job is to answer that question.
|
|
@@ -59079,15 +59309,15 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59079
59309
|
...reachable && authed && !senders ? { hint: "this admin-server predates /v1/admin/push-doctor \u2014 upgrade it to see sender readiness" } : {}
|
|
59080
59310
|
};
|
|
59081
59311
|
if (json6) {
|
|
59082
|
-
print(
|
|
59083
|
-
return
|
|
59312
|
+
print(report3);
|
|
59313
|
+
return report3.ok ? 0 : 1;
|
|
59084
59314
|
}
|
|
59085
59315
|
io.log(
|
|
59086
59316
|
`admin ${adminUrl} ${reachable ? authed ? "reachable, authenticated" : "reachable, NOT authenticated" : "UNREACHABLE"}`
|
|
59087
59317
|
);
|
|
59088
59318
|
if (!senders) {
|
|
59089
59319
|
io.log("senders unknown \u2014 credentials live on the admin-server, and it did not report them");
|
|
59090
|
-
if (
|
|
59320
|
+
if (report3.hint) io.log(` ${report3.hint}`);
|
|
59091
59321
|
return 1;
|
|
59092
59322
|
}
|
|
59093
59323
|
for (const [platform, r] of [
|
|
@@ -59097,7 +59327,7 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59097
59327
|
io.log(`${platform.padEnd(11)} ${r.sender}${r.note ? ` \u2014 ${r.note}` : ""}`);
|
|
59098
59328
|
if (r.missing.length) io.log(` missing on the server: ${r.missing.join(", ")}`);
|
|
59099
59329
|
}
|
|
59100
|
-
return
|
|
59330
|
+
return report3.ok ? 0 : 1;
|
|
59101
59331
|
}
|
|
59102
59332
|
const app = str9(flags.app);
|
|
59103
59333
|
if (!app) {
|
|
@@ -59276,10 +59506,10 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
|
59276
59506
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
59277
59507
|
signal: AbortSignal.timeout(timeoutMs)
|
|
59278
59508
|
});
|
|
59279
|
-
const
|
|
59280
|
-
let parsed =
|
|
59509
|
+
const text8 = await res.text();
|
|
59510
|
+
let parsed = text8;
|
|
59281
59511
|
try {
|
|
59282
|
-
parsed =
|
|
59512
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
59283
59513
|
} catch {
|
|
59284
59514
|
}
|
|
59285
59515
|
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
@@ -59376,10 +59606,10 @@ async function mintVisitorToken(fetchImpl, clientId) {
|
|
|
59376
59606
|
body: JSON.stringify({ clientId, grantType: "anonymous" }),
|
|
59377
59607
|
signal: AbortSignal.timeout(8e3)
|
|
59378
59608
|
});
|
|
59379
|
-
const
|
|
59380
|
-
let parsed =
|
|
59609
|
+
const text8 = await res.text();
|
|
59610
|
+
let parsed = text8;
|
|
59381
59611
|
try {
|
|
59382
|
-
parsed =
|
|
59612
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
59383
59613
|
} catch {
|
|
59384
59614
|
}
|
|
59385
59615
|
if (!res.ok) throw new WixApiError2(res.status, "POST", "/oauth2/token", parsed);
|
|
@@ -59394,28 +59624,28 @@ var init_visitor_auth = __esm({
|
|
|
59394
59624
|
});
|
|
59395
59625
|
|
|
59396
59626
|
// src/site-analyze/copy-clean.ts
|
|
59397
|
-
function isTemplatePlaceholder(
|
|
59398
|
-
return PLACEHOLDER_RE.test(
|
|
59627
|
+
function isTemplatePlaceholder(text8) {
|
|
59628
|
+
return PLACEHOLDER_RE.test(text8);
|
|
59399
59629
|
}
|
|
59400
59630
|
function cleanText(raw, cap) {
|
|
59401
59631
|
const s = String(raw ?? "").replace(/[\u0000-\u001F\u007F]/g, " ").replace(/\s+/g, " ").trim();
|
|
59402
59632
|
return s.length > cap ? `${s.slice(0, cap - 1).trimEnd()}\u2026` : s;
|
|
59403
59633
|
}
|
|
59404
|
-
function stripPii(
|
|
59405
|
-
return
|
|
59634
|
+
function stripPii(text8) {
|
|
59635
|
+
return text8.replace(EMAIL_RE2, "").replace(PHONE_SHAPE_RE, (m) => {
|
|
59406
59636
|
const digits2 = (m.match(ANY_DIGIT_RE) ?? []).length;
|
|
59407
59637
|
return digits2 >= PHONE_MIN_DIGITS && PHONE_DIGIT_RUN_RE.test(m) ? "" : m;
|
|
59408
59638
|
}).replace(/\s+/g, " ").trim();
|
|
59409
59639
|
}
|
|
59410
|
-
function isBoilerplate(
|
|
59411
|
-
return BOILERPLATE_RE.test(
|
|
59640
|
+
function isBoilerplate(text8) {
|
|
59641
|
+
return BOILERPLATE_RE.test(text8) || PLACEHOLDER_RE.test(text8);
|
|
59412
59642
|
}
|
|
59413
59643
|
function copyOrDrop(raw, cap) {
|
|
59414
|
-
const
|
|
59415
|
-
if (
|
|
59416
|
-
if (isBoilerplate(
|
|
59417
|
-
if (!/[A-Za-zͰ--]/.test(
|
|
59418
|
-
return
|
|
59644
|
+
const text8 = stripPii(cleanText(raw, cap));
|
|
59645
|
+
if (text8.length < 2) return "";
|
|
59646
|
+
if (isBoilerplate(text8)) return "";
|
|
59647
|
+
if (!/[A-Za-zͰ--]/.test(text8)) return "";
|
|
59648
|
+
return text8;
|
|
59419
59649
|
}
|
|
59420
59650
|
function dedupe2(values, cap) {
|
|
59421
59651
|
const out2 = [];
|
|
@@ -59449,9 +59679,9 @@ var init_copy_clean = __esm({
|
|
|
59449
59679
|
function genericDescription(it) {
|
|
59450
59680
|
for (const field of DESCRIPTION_FIELDS) {
|
|
59451
59681
|
const raw = it[field];
|
|
59452
|
-
const
|
|
59453
|
-
if (!
|
|
59454
|
-
const plain2 =
|
|
59682
|
+
const text8 = typeof raw === "string" ? raw : str6(raw?.text);
|
|
59683
|
+
if (!text8) continue;
|
|
59684
|
+
const plain2 = text8.replace(/<[^>]*>/g, " ").replace(/ /g, " ");
|
|
59455
59685
|
if (plain2.trim()) return plain2;
|
|
59456
59686
|
}
|
|
59457
59687
|
return void 0;
|
|
@@ -59564,7 +59794,7 @@ function formLabels(x, depth = 0, out2 = []) {
|
|
|
59564
59794
|
if (typeof x !== "object") return out2;
|
|
59565
59795
|
const o = x;
|
|
59566
59796
|
const label2 = str6(o.label ?? o.displayName ?? o.fieldTitle ?? o.title);
|
|
59567
|
-
if (label2 && !
|
|
59797
|
+
if (label2 && !UUID_RE2.test(label2) && label2.length < 80 && !out2.includes(label2)) out2.push(label2);
|
|
59568
59798
|
for (const k of ["fields", "formFields", "form", "schema", "properties"]) {
|
|
59569
59799
|
if (o[k] != null) formLabels(o[k], depth + 1, out2);
|
|
59570
59800
|
}
|
|
@@ -59682,7 +59912,7 @@ function sampleTitle(data) {
|
|
|
59682
59912
|
for (const [k, v] of Object.entries(data)) {
|
|
59683
59913
|
if (k.startsWith("_") || typeof v !== "string") continue;
|
|
59684
59914
|
const s = v.trim();
|
|
59685
|
-
if (s.length > 2 && s.length < 80 && !s.includes("@") && !/^https?:/i.test(s) && !
|
|
59915
|
+
if (s.length > 2 && s.length < 80 && !s.includes("@") && !/^https?:/i.test(s) && !UUID_RE2.test(s)) return s;
|
|
59686
59916
|
}
|
|
59687
59917
|
return void 0;
|
|
59688
59918
|
}
|
|
@@ -59781,7 +60011,7 @@ async function readMemberRoles(call) {
|
|
|
59781
60011
|
if (sawAuthError) return { names: [], status: "error" };
|
|
59782
60012
|
return { names: [], status: "empty" };
|
|
59783
60013
|
}
|
|
59784
|
-
var asArr, str6, DESCRIPTION_FIELDS,
|
|
60014
|
+
var asArr, str6, DESCRIPTION_FIELDS, UUID_RE2, CORE_PROBES, OPTIONAL_PROBES, ALL, CMS_LIST_LIMIT;
|
|
59785
60015
|
var init_probes = __esm({
|
|
59786
60016
|
"src/site-analyze/probes.ts"() {
|
|
59787
60017
|
init_rest();
|
|
@@ -59789,7 +60019,7 @@ var init_probes = __esm({
|
|
|
59789
60019
|
asArr = (x) => Array.isArray(x) ? x : [];
|
|
59790
60020
|
str6 = (x) => typeof x === "string" ? x : "";
|
|
59791
60021
|
DESCRIPTION_FIELDS = ["plainDescription", "description", "shortDescription", "excerpt", "tagLine", "subtitle"];
|
|
59792
|
-
|
|
60022
|
+
UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
59793
60023
|
CORE_PROBES = [
|
|
59794
60024
|
{
|
|
59795
60025
|
vertical: "store",
|
|
@@ -60496,12 +60726,12 @@ function mergeWst(pages) {
|
|
|
60496
60726
|
return acc;
|
|
60497
60727
|
}
|
|
60498
60728
|
function fontSlug(value) {
|
|
60499
|
-
let
|
|
60729
|
+
let text8 = value;
|
|
60500
60730
|
try {
|
|
60501
|
-
|
|
60731
|
+
text8 = decodeURIComponent(value);
|
|
60502
60732
|
} catch {
|
|
60503
60733
|
}
|
|
60504
|
-
return
|
|
60734
|
+
return text8.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
60505
60735
|
}
|
|
60506
60736
|
function fontUrlSlug(url) {
|
|
60507
60737
|
const last = url.split("?")[0].split("#")[0].split("/").pop() ?? "";
|
|
@@ -60675,8 +60905,8 @@ function parsePublishedHtml(html) {
|
|
|
60675
60905
|
const rawHeadings = [];
|
|
60676
60906
|
HEADING_RE.lastIndex = 0;
|
|
60677
60907
|
while (m = HEADING_RE.exec(html)) {
|
|
60678
|
-
const
|
|
60679
|
-
if (
|
|
60908
|
+
const text8 = copyOrDrop(textFromHtml(m[1] ?? ""), 120);
|
|
60909
|
+
if (text8) rawHeadings.push(text8);
|
|
60680
60910
|
if (rawHeadings.length >= 40) break;
|
|
60681
60911
|
}
|
|
60682
60912
|
const headings = dedupe2(rawHeadings, 20);
|
|
@@ -61503,16 +61733,16 @@ function isPrivateV4([a, b, c]) {
|
|
|
61503
61733
|
return a >= 224;
|
|
61504
61734
|
}
|
|
61505
61735
|
function v6Groups(host) {
|
|
61506
|
-
let
|
|
61507
|
-
const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(
|
|
61736
|
+
let text8 = host;
|
|
61737
|
+
const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(text8);
|
|
61508
61738
|
if (dotted) {
|
|
61509
61739
|
const octets = ipv4Octets(dotted[1]);
|
|
61510
61740
|
if (!octets) return null;
|
|
61511
61741
|
const hi = (octets[0] << 8 | octets[1]).toString(16);
|
|
61512
61742
|
const lo = (octets[2] << 8 | octets[3]).toString(16);
|
|
61513
|
-
|
|
61743
|
+
text8 = `${text8.slice(0, dotted.index)}:${hi}:${lo}`;
|
|
61514
61744
|
}
|
|
61515
|
-
const halves =
|
|
61745
|
+
const halves = text8.split("::");
|
|
61516
61746
|
if (halves.length > 2) return null;
|
|
61517
61747
|
const parts = (part) => part ? part.split(":") : [];
|
|
61518
61748
|
const head = parts(halves[0]);
|
|
@@ -61594,10 +61824,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
61594
61824
|
if (refusal) throw new Error(refusal);
|
|
61595
61825
|
}
|
|
61596
61826
|
function resolveAll(hostname2) {
|
|
61597
|
-
return new Promise((
|
|
61827
|
+
return new Promise((resolve53, reject) => {
|
|
61598
61828
|
dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
|
|
61599
61829
|
if (err) reject(err);
|
|
61600
|
-
else
|
|
61830
|
+
else resolve53(addresses);
|
|
61601
61831
|
});
|
|
61602
61832
|
});
|
|
61603
61833
|
}
|
|
@@ -61605,13 +61835,13 @@ function withAbort(start, signal, what) {
|
|
|
61605
61835
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
61606
61836
|
const work = start();
|
|
61607
61837
|
if (!signal) return work;
|
|
61608
|
-
return new Promise((
|
|
61838
|
+
return new Promise((resolve53, reject) => {
|
|
61609
61839
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
61610
61840
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
61611
|
-
work.then(
|
|
61841
|
+
work.then(resolve53, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
61612
61842
|
});
|
|
61613
61843
|
}
|
|
61614
|
-
async function pinAddress(url,
|
|
61844
|
+
async function pinAddress(url, resolve53 = resolveAll, signal) {
|
|
61615
61845
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
61616
61846
|
if (ipv4Octets(host)) {
|
|
61617
61847
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -61621,7 +61851,7 @@ async function pinAddress(url, resolve52 = resolveAll, signal) {
|
|
|
61621
61851
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
61622
61852
|
return { address: host, family: 6 };
|
|
61623
61853
|
}
|
|
61624
|
-
const addresses = await withAbort(() =>
|
|
61854
|
+
const addresses = await withAbort(() => resolve53(host), signal, `${host} lookup`);
|
|
61625
61855
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
61626
61856
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
61627
61857
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -61661,7 +61891,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
61661
61891
|
return out2;
|
|
61662
61892
|
}
|
|
61663
61893
|
function requestOnce(url, pinned, init) {
|
|
61664
|
-
return new Promise((
|
|
61894
|
+
return new Promise((resolve53, reject) => {
|
|
61665
61895
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
61666
61896
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
61667
61897
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -61691,7 +61921,7 @@ function requestOnce(url, pinned, init) {
|
|
|
61691
61921
|
reject(err);
|
|
61692
61922
|
return;
|
|
61693
61923
|
}
|
|
61694
|
-
|
|
61924
|
+
resolve53(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out2 }));
|
|
61695
61925
|
}
|
|
61696
61926
|
);
|
|
61697
61927
|
req.on("error", reject);
|
|
@@ -61767,8 +61997,8 @@ var init_net_guard = __esm({
|
|
|
61767
61997
|
function textFields(look) {
|
|
61768
61998
|
if (look.unavailable) return [];
|
|
61769
61999
|
const out2 = [];
|
|
61770
|
-
const add = (
|
|
61771
|
-
if (
|
|
62000
|
+
const add = (text8, where, narrative = false) => {
|
|
62001
|
+
if (text8 && text8.trim()) out2.push({ text: text8, where, narrative });
|
|
61772
62002
|
};
|
|
61773
62003
|
for (const label2 of look.navLabels) add(label2, "nav");
|
|
61774
62004
|
for (const p of look.pages) {
|
|
@@ -62159,8 +62389,8 @@ async function analyzeSite(input, ports) {
|
|
|
62159
62389
|
if (locale) plan.provisioning.locale = locale;
|
|
62160
62390
|
const velo = buildVeloChapter({ look, owner: ownerVelo });
|
|
62161
62391
|
const veloFiles = ownerVelo.files.flatMap((f) => {
|
|
62162
|
-
const
|
|
62163
|
-
return
|
|
62392
|
+
const text8 = f.content ?? f.excerpt;
|
|
62393
|
+
return text8 ? [{ path: f.path, text: text8 }] : [];
|
|
62164
62394
|
}).slice(0, 80);
|
|
62165
62395
|
const permissions = buildPermissionsChapter({
|
|
62166
62396
|
cms,
|
|
@@ -62382,8 +62612,8 @@ function cmsStatusNote(taxonomy) {
|
|
|
62382
62612
|
function yn(v) {
|
|
62383
62613
|
return v == null || v === "" ? "\u2014" : String(v);
|
|
62384
62614
|
}
|
|
62385
|
-
function isAuthPhrase(
|
|
62386
|
-
const t =
|
|
62615
|
+
function isAuthPhrase(text8) {
|
|
62616
|
+
const t = text8.trim();
|
|
62387
62617
|
return AUTH_ONLY_ASCII.test(t) || LOGIN_HE.includes(t);
|
|
62388
62618
|
}
|
|
62389
62619
|
function looksGated(page) {
|
|
@@ -62760,9 +62990,9 @@ function attachVeloSources(book, sources, put) {
|
|
|
62760
62990
|
if (isSecretVeloPath(f.path)) continue;
|
|
62761
62991
|
const rel = veloArtifactRelPath(f.path);
|
|
62762
62992
|
if (!rel) continue;
|
|
62763
|
-
const
|
|
62764
|
-
if (!
|
|
62765
|
-
put(rel,
|
|
62993
|
+
const text8 = byPath.get(f.path) ?? f.excerpt;
|
|
62994
|
+
if (!text8) continue;
|
|
62995
|
+
put(rel, text8);
|
|
62766
62996
|
f.localPath = rel;
|
|
62767
62997
|
}
|
|
62768
62998
|
}
|
|
@@ -63007,14 +63237,14 @@ var init_customer_build = __esm({
|
|
|
63007
63237
|
|
|
63008
63238
|
// src/site-analyze/apply.ts
|
|
63009
63239
|
import { existsSync as existsSync64, readFileSync as readFileSync76, writeFileSync as writeFileSync27, copyFileSync as copyFileSync3, mkdirSync as mkdirSync31, realpathSync as realpathSync9, statSync as statSync17 } from "node:fs";
|
|
63010
|
-
import { dirname as dirname35, isAbsolute as isAbsolute6, join as join63, resolve as
|
|
63240
|
+
import { dirname as dirname35, isAbsolute as isAbsolute6, join as join63, resolve as resolve50, sep as sep16 } from "node:path";
|
|
63011
63241
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
63012
63242
|
function unpairedRedirectNote(overlay) {
|
|
63013
63243
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
63014
63244
|
return `no OAuth redirect paired with client ${overlay.wix.clientId} \u2014 the app (and prepare:customer) will refuse to start until one is set. Register it with \`himi site client ensure --site ${overlay.siteId?.trim() || "<msid>"} --redirect-uri <uri> --yes\`, then re-run analyze with \`--redirect-uri <uri>\` (or export HIMI_BRANDED_LITE_WIX_REDIRECT_URI)`;
|
|
63015
63245
|
}
|
|
63016
63246
|
function posix3(p) {
|
|
63017
|
-
return
|
|
63247
|
+
return resolve50(p).replace(/\\/g, "/");
|
|
63018
63248
|
}
|
|
63019
63249
|
function committedShellProvisioning(path2) {
|
|
63020
63250
|
return committedShellFor(posix3(path2));
|
|
@@ -63048,7 +63278,7 @@ function assertNotCommitted(path2, forbidden) {
|
|
|
63048
63278
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
63049
63279
|
);
|
|
63050
63280
|
}
|
|
63051
|
-
if (forbidden &&
|
|
63281
|
+
if (forbidden && resolve50(path2) === resolve50(forbidden)) {
|
|
63052
63282
|
const named = committedShellProvisioning(forbidden);
|
|
63053
63283
|
throw new Error(
|
|
63054
63284
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -63104,8 +63334,8 @@ function buildMergedContract(options) {
|
|
|
63104
63334
|
const staged = [];
|
|
63105
63335
|
const contained = (root, rel) => {
|
|
63106
63336
|
if (isAbsolute6(rel)) return void 0;
|
|
63107
|
-
const full =
|
|
63108
|
-
return full.startsWith(
|
|
63337
|
+
const full = resolve50(root, rel);
|
|
63338
|
+
return full.startsWith(resolve50(root) + sep16) ? full : void 0;
|
|
63109
63339
|
};
|
|
63110
63340
|
const stage = (fromRel, toRel) => {
|
|
63111
63341
|
const from = contained(packageDir, fromRel);
|
|
@@ -63194,7 +63424,7 @@ function catalogTypography(overlay, template) {
|
|
|
63194
63424
|
function staticFaqFor(overlay, overlayPath) {
|
|
63195
63425
|
const own3 = overlay.faq;
|
|
63196
63426
|
if (own3 !== void 0) return deriveStaticFaq(own3);
|
|
63197
|
-
const bookPath = join63(dirname35(
|
|
63427
|
+
const bookPath = join63(dirname35(resolve50(overlayPath)), "book.json");
|
|
63198
63428
|
if (!existsSync64(bookPath)) return void 0;
|
|
63199
63429
|
try {
|
|
63200
63430
|
const book = JSON.parse(readFileSync76(bookPath, "utf8"));
|
|
@@ -63208,7 +63438,7 @@ function staticFaqFor(overlay, overlayPath) {
|
|
|
63208
63438
|
}
|
|
63209
63439
|
}
|
|
63210
63440
|
async function applyOverlays(input) {
|
|
63211
|
-
const cwd =
|
|
63441
|
+
const cwd = resolve50(input.cwd);
|
|
63212
63442
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
63213
63443
|
assertKnownShell(shell);
|
|
63214
63444
|
const overlay = JSON.parse(readFileSync76(input.overlayPath, "utf8"));
|
|
@@ -63232,7 +63462,7 @@ async function applyOverlays(input) {
|
|
|
63232
63462
|
`shell "${shell}" is a site shell: its contract names the customer's website (a \`site\` block), and this overlay has none. Re-run \`himi site analyze --url <site> --shell ${shell}\` to derive the site's page map (edit \`site.pages\` in provisioning.overlay.json if needed), then --apply.`
|
|
63233
63463
|
);
|
|
63234
63464
|
}
|
|
63235
|
-
const packageDir = dirname35(
|
|
63465
|
+
const packageDir = dirname35(resolve50(input.overlayPath));
|
|
63236
63466
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir3, packageDir, overlay });
|
|
63237
63467
|
wrote.push(...staged);
|
|
63238
63468
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -63327,7 +63557,7 @@ async function applyOverlays(input) {
|
|
|
63327
63557
|
}
|
|
63328
63558
|
}
|
|
63329
63559
|
if (!input.iconPath || !existsSync64(input.iconPath)) {
|
|
63330
|
-
const book = input.iconPath ? dirname35(dirname35(
|
|
63560
|
+
const book = input.iconPath ? dirname35(dirname35(resolve50(input.iconPath))) : void 0;
|
|
63331
63561
|
notes.push(
|
|
63332
63562
|
book ? `no icon installed \u2014 ${siteLogoAbsence(book).hint}` : "no icon installed and no business book to say why \u2014 `himi icon generate` draws one from the accent, or `himi icon set <file.png>` installs the customer's own mark"
|
|
63333
63563
|
);
|
|
@@ -64446,10 +64676,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
64446
64676
|
}
|
|
64447
64677
|
function createPromiseCallback(cb) {
|
|
64448
64678
|
let callback;
|
|
64449
|
-
let
|
|
64679
|
+
let resolve53;
|
|
64450
64680
|
let reject;
|
|
64451
64681
|
const promise = new Promise((_resolve, _reject) => {
|
|
64452
|
-
|
|
64682
|
+
resolve53 = _resolve;
|
|
64453
64683
|
reject = _reject;
|
|
64454
64684
|
});
|
|
64455
64685
|
if (typeof cb === "function") {
|
|
@@ -64465,7 +64695,7 @@ function createPromiseCallback(cb) {
|
|
|
64465
64695
|
callback = (err, result) => {
|
|
64466
64696
|
try {
|
|
64467
64697
|
if (err) reject(err);
|
|
64468
|
-
else
|
|
64698
|
+
else resolve53(result);
|
|
64469
64699
|
} catch (e) {
|
|
64470
64700
|
reject(e instanceof Error ? e : new Error());
|
|
64471
64701
|
}
|
|
@@ -66532,8 +66762,8 @@ function copyFromEval(evaled) {
|
|
|
66532
66762
|
evaled.meta?.ogTitle,
|
|
66533
66763
|
evaled.meta?.ogDescription
|
|
66534
66764
|
].map((raw) => {
|
|
66535
|
-
const
|
|
66536
|
-
return
|
|
66765
|
+
const text8 = cleanText(raw, 400);
|
|
66766
|
+
return text8 && isTemplatePlaceholder(text8) ? stripPii(cleanText(text8, 90)) : "";
|
|
66537
66767
|
}),
|
|
66538
66768
|
8
|
|
66539
66769
|
);
|
|
@@ -67065,7 +67295,7 @@ var init_crawl_look = __esm({
|
|
|
67065
67295
|
});
|
|
67066
67296
|
|
|
67067
67297
|
// src/site-analyze/site-function.ts
|
|
67068
|
-
import { randomUUID as
|
|
67298
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
67069
67299
|
function createRevisionUrl(msid, esi) {
|
|
67070
67300
|
const q = new URLSearchParams({ editorSessionId: esi, esi, metaSiteId: msid });
|
|
67071
67301
|
return `https://editor.wix.com/html/v1/create_revision?${q}`;
|
|
@@ -67432,13 +67662,13 @@ async function veloCall(fetchImpl, method, url, opts = {}) {
|
|
|
67432
67662
|
body: opts.body === void 0 ? void 0 : JSON.stringify(opts.body),
|
|
67433
67663
|
signal: AbortSignal.timeout(opts.timeoutMs ?? 3e4)
|
|
67434
67664
|
});
|
|
67435
|
-
const
|
|
67436
|
-
let json6 =
|
|
67665
|
+
const text8 = await res.text();
|
|
67666
|
+
let json6 = text8;
|
|
67437
67667
|
try {
|
|
67438
|
-
json6 =
|
|
67668
|
+
json6 = text8 ? JSON.parse(text8) : null;
|
|
67439
67669
|
} catch {
|
|
67440
67670
|
}
|
|
67441
|
-
return { status: res.status, json: json6, text:
|
|
67671
|
+
return { status: res.status, json: json6, text: text8 };
|
|
67442
67672
|
}
|
|
67443
67673
|
function snippet2(x, cap = 180) {
|
|
67444
67674
|
const s = typeof x === "string" ? x : JSON.stringify(x) ?? "";
|
|
@@ -67510,7 +67740,7 @@ function codeAppIdFromRevision(json6) {
|
|
|
67510
67740
|
async function snapshotAndPublish(fetchImpl, token, msid, opts = {}) {
|
|
67511
67741
|
const production = opts.production !== false;
|
|
67512
67742
|
const initiator = opts.initiator ?? "himi";
|
|
67513
|
-
const esi =
|
|
67743
|
+
const esi = randomUUID6();
|
|
67514
67744
|
const rev = await veloCall(fetchImpl, "POST", createRevisionUrl(msid, esi), {
|
|
67515
67745
|
token,
|
|
67516
67746
|
msid,
|
|
@@ -67607,7 +67837,7 @@ async function runSiteFunction(opts) {
|
|
|
67607
67837
|
if (!httpOk(patched)) {
|
|
67608
67838
|
return { ...base, error: `UpdateFiles ${patched.status}: ${snippet2(patched.json ?? patched.text)}` };
|
|
67609
67839
|
}
|
|
67610
|
-
let
|
|
67840
|
+
let report3 = {
|
|
67611
67841
|
...base,
|
|
67612
67842
|
ok: true,
|
|
67613
67843
|
source: extractHttpFunction(next, method, name),
|
|
@@ -67616,21 +67846,21 @@ async function runSiteFunction(opts) {
|
|
|
67616
67846
|
if (opts.publish) {
|
|
67617
67847
|
const snap = await snapshotAndPublish(fetchImpl, opts.token, opts.msid, { production: true, initiator: "himi" });
|
|
67618
67848
|
const pubOk = httpOk(snap.rev) && httpOk(snap.live);
|
|
67619
|
-
|
|
67620
|
-
...
|
|
67621
|
-
ok:
|
|
67849
|
+
report3 = {
|
|
67850
|
+
...report3,
|
|
67851
|
+
ok: report3.ok && pubOk,
|
|
67622
67852
|
revision: snap.revision,
|
|
67623
67853
|
codeAppId: snap.codeAppId,
|
|
67624
67854
|
publish: { revision: httpOk(snap.rev), rc: httpOk(snap.rc), live: httpOk(snap.live), status: snap.live?.status },
|
|
67625
|
-
error: pubOk ?
|
|
67855
|
+
error: pubOk ? report3.error : snippet2(snap.live?.json ?? snap.rev.json)
|
|
67626
67856
|
};
|
|
67627
67857
|
}
|
|
67628
67858
|
if (opts.invoke) {
|
|
67629
|
-
if (!opts.siteUrl) return { ...
|
|
67630
|
-
const invoked = await invokeAndReport(fetchImpl, opts,
|
|
67631
|
-
return { ...
|
|
67859
|
+
if (!opts.siteUrl) return { ...report3, ok: false, error: "put --invoke needs --url" };
|
|
67860
|
+
const invoked = await invokeAndReport(fetchImpl, opts, report3, name, method);
|
|
67861
|
+
return { ...report3, ...invoked, op: "put", ok: report3.ok && invoked.ok };
|
|
67632
67862
|
}
|
|
67633
|
-
return
|
|
67863
|
+
return report3;
|
|
67634
67864
|
}
|
|
67635
67865
|
async function invokeAndReport(fetchImpl, opts, base, name, method) {
|
|
67636
67866
|
const siteUrl = opts.siteUrl;
|
|
@@ -67695,7 +67925,7 @@ __export(cli_exports, {
|
|
|
67695
67925
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
67696
67926
|
});
|
|
67697
67927
|
import { readFileSync as readFileSync77 } from "node:fs";
|
|
67698
|
-
import { resolve as
|
|
67928
|
+
import { resolve as resolve51 } from "node:path";
|
|
67699
67929
|
function assetFetchFor(_opts) {
|
|
67700
67930
|
return pinnedFetch2;
|
|
67701
67931
|
}
|
|
@@ -67715,7 +67945,7 @@ async function runSiteAnalyze(opts) {
|
|
|
67715
67945
|
const assetFetch = assetFetchFor(opts);
|
|
67716
67946
|
const siteFetch = guardedSiteFetch;
|
|
67717
67947
|
const cwd = opts.cwd ?? process.cwd();
|
|
67718
|
-
const outDir =
|
|
67948
|
+
const outDir = resolve51(cwd, opts.outDir ?? ".himi/business-book");
|
|
67719
67949
|
let ownerAuth;
|
|
67720
67950
|
let msid;
|
|
67721
67951
|
const ownerSite = ownerSiteFor(opts);
|
|
@@ -67767,9 +67997,9 @@ async function runSiteAnalyze(opts) {
|
|
|
67767
67997
|
if (opts.apply) {
|
|
67768
67998
|
applied = await applyOverlays({
|
|
67769
67999
|
cwd,
|
|
67770
|
-
overlayPath:
|
|
67771
|
-
tokensPath:
|
|
67772
|
-
iconPath:
|
|
68000
|
+
overlayPath: resolve51(outDir, "provisioning.overlay.json"),
|
|
68001
|
+
tokensPath: resolve51(outDir, "tokens.overlay.json"),
|
|
68002
|
+
iconPath: resolve51(outDir, "media/icon.png"),
|
|
67773
68003
|
shell: opts.shell
|
|
67774
68004
|
});
|
|
67775
68005
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -67805,7 +68035,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
67805
68035
|
const token = opts.token ?? await siteToken(msid);
|
|
67806
68036
|
let source;
|
|
67807
68037
|
if (opts.sourcePath) {
|
|
67808
|
-
const p =
|
|
68038
|
+
const p = resolve51(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
67809
68039
|
source = readFileSync77(p, "utf8");
|
|
67810
68040
|
}
|
|
67811
68041
|
let body;
|
|
@@ -67861,7 +68091,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
67861
68091
|
cached2 = fromEnv;
|
|
67862
68092
|
return fromEnv;
|
|
67863
68093
|
}
|
|
67864
|
-
const token = await new Promise((
|
|
68094
|
+
const token = await new Promise((resolve53, reject) => {
|
|
67865
68095
|
let child;
|
|
67866
68096
|
try {
|
|
67867
68097
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -67890,7 +68120,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
67890
68120
|
const scan = (d) => {
|
|
67891
68121
|
out2 += String(d);
|
|
67892
68122
|
const m = out2.match(TOKEN_RE2);
|
|
67893
|
-
if (m) done(() =>
|
|
68123
|
+
if (m) done(() => resolve53(m[0]));
|
|
67894
68124
|
};
|
|
67895
68125
|
child.stdout?.on("data", scan);
|
|
67896
68126
|
child.stderr?.on("data", scan);
|
|
@@ -67933,10 +68163,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
67933
68163
|
}
|
|
67934
68164
|
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
67935
68165
|
}
|
|
67936
|
-
const
|
|
67937
|
-
let parsed =
|
|
68166
|
+
const text8 = await res.text();
|
|
68167
|
+
let parsed = text8;
|
|
67938
68168
|
try {
|
|
67939
|
-
parsed =
|
|
68169
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
67940
68170
|
} catch {
|
|
67941
68171
|
}
|
|
67942
68172
|
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
@@ -67997,16 +68227,16 @@ async function installVerticals(msid, wanted, token, fetchImpl = fetch, timeoutM
|
|
|
67997
68227
|
body: JSON.stringify({ apps: wanted.map((w) => ({ id: w.appDefId })) }),
|
|
67998
68228
|
signal: AbortSignal.timeout(timeoutMs)
|
|
67999
68229
|
});
|
|
68000
|
-
const
|
|
68230
|
+
const text8 = await res.text();
|
|
68001
68231
|
if (!res.ok) {
|
|
68002
68232
|
return {
|
|
68003
68233
|
...empty,
|
|
68004
|
-
errors: wanted.map((w) => ({ ...w, message: `bulk-install -> ${res.status}: ${
|
|
68234
|
+
errors: wanted.map((w) => ({ ...w, message: `bulk-install -> ${res.status}: ${text8.slice(0, 200)}` }))
|
|
68005
68235
|
};
|
|
68006
68236
|
}
|
|
68007
68237
|
let body = {};
|
|
68008
68238
|
try {
|
|
68009
|
-
body =
|
|
68239
|
+
body = text8 ? JSON.parse(text8) : {};
|
|
68010
68240
|
} catch {
|
|
68011
68241
|
}
|
|
68012
68242
|
const nameOf = (appDefId) => wanted.find((w) => w.appDefId === appDefId)?.vertical ?? appDefId;
|
|
@@ -68609,9 +68839,9 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
68609
68839
|
const visitLiterals = (node) => {
|
|
68610
68840
|
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isTemplateExpression(node)) {
|
|
68611
68841
|
const start = node.getStart(clean2);
|
|
68612
|
-
const
|
|
68613
|
-
const redacted = redactLiteral(
|
|
68614
|
-
if (redacted !==
|
|
68842
|
+
const text8 = source.slice(start, node.end);
|
|
68843
|
+
const redacted = redactLiteral(text8, start);
|
|
68844
|
+
if (redacted !== text8) {
|
|
68615
68845
|
edits.push({ start, end: node.end, text: redacted });
|
|
68616
68846
|
return;
|
|
68617
68847
|
}
|
|
@@ -68892,9 +69122,9 @@ var init_context = __esm({
|
|
|
68892
69122
|
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync79, mkdirSync as mkdirSync32, writeFileSync as writeFileSync29, existsSync as existsSync66, rmSync as rmSync15, readdirSync as readdirSync30, statSync as statSync18, lstatSync as lstatSync13, accessSync, constants as constants2, renameSync as renameSync7, cpSync as cpSync3 } from "node:fs";
|
|
68893
69123
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
68894
69124
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
68895
|
-
import { createHash as createHash31, randomUUID as
|
|
69125
|
+
import { createHash as createHash31, randomUUID as randomUUID7 } from "node:crypto";
|
|
68896
69126
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
68897
|
-
import { join as join64, resolve as
|
|
69127
|
+
import { join as join64, resolve as resolve52, relative as relative13, basename as basename17, dirname as dirname36 } from "node:path";
|
|
68898
69128
|
import { fileURLToPath as fileURLToPath26 } from "node:url";
|
|
68899
69129
|
|
|
68900
69130
|
// ../serve-cli/src/client.ts
|
|
@@ -68935,10 +69165,10 @@ var ServeCliClient = class {
|
|
|
68935
69165
|
...carriesCredential ? { redirect: "error" } : {},
|
|
68936
69166
|
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
68937
69167
|
});
|
|
68938
|
-
const
|
|
69168
|
+
const text8 = await res.text();
|
|
68939
69169
|
let json6 = null;
|
|
68940
69170
|
try {
|
|
68941
|
-
json6 =
|
|
69171
|
+
json6 = text8 ? JSON.parse(text8) : null;
|
|
68942
69172
|
} catch {
|
|
68943
69173
|
json6 = null;
|
|
68944
69174
|
}
|
|
@@ -68946,7 +69176,7 @@ var ServeCliClient = class {
|
|
|
68946
69176
|
res.headers.forEach((v, k) => {
|
|
68947
69177
|
h[k] = v;
|
|
68948
69178
|
});
|
|
68949
|
-
return { status: res.status, ok: res.ok, json: json6, text:
|
|
69179
|
+
return { status: res.status, ok: res.ok, json: json6, text: text8, headers: h };
|
|
68950
69180
|
}
|
|
68951
69181
|
// ---- serve (device-facing reads) ----
|
|
68952
69182
|
health(plane) {
|
|
@@ -69511,8 +69741,8 @@ init_attestation();
|
|
|
69511
69741
|
|
|
69512
69742
|
// ../../core/admin-web/src/utils/qr-terminal.ts
|
|
69513
69743
|
init_qr();
|
|
69514
|
-
function qrTerminal(
|
|
69515
|
-
const { modules, size } = encodeQr(
|
|
69744
|
+
function qrTerminal(text8, opts = {}) {
|
|
69745
|
+
const { modules, size } = encodeQr(text8);
|
|
69516
69746
|
const quietZone = opts.quietZone ?? 4;
|
|
69517
69747
|
const dim = size + quietZone * 2;
|
|
69518
69748
|
const dark = (x, y) => x >= quietZone && x < quietZone + size && y >= quietZone && y < quietZone + size ? modules[y - quietZone][x - quietZone] : false;
|
|
@@ -69568,9 +69798,9 @@ function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
|
|
|
69568
69798
|
return false;
|
|
69569
69799
|
}
|
|
69570
69800
|
}
|
|
69571
|
-
function isPortInUseError(
|
|
69572
|
-
if (!
|
|
69573
|
-
return /EADDRINUSE/i.test(
|
|
69801
|
+
function isPortInUseError(text8) {
|
|
69802
|
+
if (!text8) return false;
|
|
69803
|
+
return /EADDRINUSE/i.test(text8) || new RegExp(`(:::|:)${DPX_SESSION_PORT}\\b`).test(text8);
|
|
69574
69804
|
}
|
|
69575
69805
|
function parseDpxAuthStatusIdentity(stdout) {
|
|
69576
69806
|
if (!stdout) return void 0;
|
|
@@ -69635,7 +69865,7 @@ async function browserLogin(opts) {
|
|
|
69635
69865
|
const log = opts.log ?? (() => {
|
|
69636
69866
|
});
|
|
69637
69867
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
69638
|
-
return await new Promise((
|
|
69868
|
+
return await new Promise((resolve53, reject) => {
|
|
69639
69869
|
let settled = false;
|
|
69640
69870
|
let loginUrl = "";
|
|
69641
69871
|
const server = createServer();
|
|
@@ -69699,7 +69929,7 @@ async function browserLogin(opts) {
|
|
|
69699
69929
|
return;
|
|
69700
69930
|
}
|
|
69701
69931
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
69702
|
-
finish2(() =>
|
|
69932
|
+
finish2(() => resolve53({ token, loginUrl }));
|
|
69703
69933
|
});
|
|
69704
69934
|
});
|
|
69705
69935
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -69963,7 +70193,7 @@ async function queryCms(opts) {
|
|
|
69963
70193
|
async function createCms(opts) {
|
|
69964
70194
|
const { app, cms, call, dryRun = false, allowDestructive = false, applyPermissions = false } = opts;
|
|
69965
70195
|
const prefix = namespacePrefix(app);
|
|
69966
|
-
const
|
|
70196
|
+
const report3 = {
|
|
69967
70197
|
ok: true,
|
|
69968
70198
|
app,
|
|
69969
70199
|
namespace: prefix,
|
|
@@ -69985,19 +70215,19 @@ async function createCms(opts) {
|
|
|
69985
70215
|
for (const spec of cms?.collections ?? []) {
|
|
69986
70216
|
const id = physicalId(spec, app);
|
|
69987
70217
|
if (spec.wixId) {
|
|
69988
|
-
|
|
70218
|
+
report3.skipped.push({
|
|
69989
70219
|
collection: id,
|
|
69990
70220
|
reason: remoteById.has(id) ? "adopted (read-only) \u2014 himi never changes the schema of a collection it does not own" : `adopted but absent from this site \u2014 create it in the Wix dashboard, or declare it as owned ("${prefix}\u2026")`
|
|
69991
70221
|
});
|
|
69992
|
-
if (!remoteById.has(id))
|
|
70222
|
+
if (!remoteById.has(id)) report3.ok = false;
|
|
69993
70223
|
continue;
|
|
69994
70224
|
}
|
|
69995
70225
|
if (!spec.id?.startsWith(prefix)) {
|
|
69996
|
-
|
|
70226
|
+
report3.refused.push({
|
|
69997
70227
|
collection: id || "<unnamed>",
|
|
69998
70228
|
reason: `"${id}" is outside this app's namespace "${prefix}" \u2014 himi only writes collections it owns. Rename it in config.ts, or bind an existing collection read-only with \`wixId\`.`
|
|
69999
70229
|
});
|
|
70000
|
-
|
|
70230
|
+
report3.ok = false;
|
|
70001
70231
|
continue;
|
|
70002
70232
|
}
|
|
70003
70233
|
const existing = remoteById.get(id);
|
|
@@ -70005,35 +70235,35 @@ async function createCms(opts) {
|
|
|
70005
70235
|
if (!dryRun) {
|
|
70006
70236
|
await call("POST", "/data/v2/collections", { collection: toWixCollection(spec, app) });
|
|
70007
70237
|
}
|
|
70008
|
-
|
|
70238
|
+
report3.created.push(id);
|
|
70009
70239
|
continue;
|
|
70010
70240
|
}
|
|
70011
70241
|
const permDrift = diffPermissions(spec, existing);
|
|
70012
|
-
for (const d of permDrift)
|
|
70242
|
+
for (const d of permDrift) report3.permissionDrift.push({ collection: id, ...d });
|
|
70013
70243
|
const applyingPermissions = applyPermissions && permDrift.length > 0;
|
|
70014
70244
|
const drift = diffFields(spec, existing);
|
|
70015
70245
|
const extras = drift.filter((d) => d.kind === "extra-field");
|
|
70016
70246
|
const mismatches = drift.filter((d) => d.kind === "type-mismatch");
|
|
70017
70247
|
const missing = drift.filter((d) => d.kind === "missing-field");
|
|
70018
70248
|
for (const m of mismatches) {
|
|
70019
|
-
|
|
70020
|
-
|
|
70249
|
+
report3.skipped.push({ collection: id, reason: m.detail });
|
|
70250
|
+
report3.ok = false;
|
|
70021
70251
|
}
|
|
70022
70252
|
for (const e of extras) {
|
|
70023
70253
|
if (allowDestructive) continue;
|
|
70024
|
-
|
|
70254
|
+
report3.skipped.push({ collection: id, reason: e.detail });
|
|
70025
70255
|
}
|
|
70026
70256
|
if (mismatches.length > 0) continue;
|
|
70027
70257
|
if (missing.length === 0 && (extras.length === 0 || !allowDestructive) && !applyingPermissions) {
|
|
70028
|
-
|
|
70258
|
+
report3.unchanged.push(id);
|
|
70029
70259
|
continue;
|
|
70030
70260
|
}
|
|
70031
70261
|
if (!allowDestructive && !Array.isArray(existing.fields)) {
|
|
70032
|
-
|
|
70262
|
+
report3.skipped.push({
|
|
70033
70263
|
collection: id,
|
|
70034
70264
|
reason: "the site returned this collection without a `fields` array, so an update would drop every field (and its data) by omission. Re-run to retry the read; pass --allow-destructive only if narrowing to the declaration is genuinely what you want."
|
|
70035
70265
|
});
|
|
70036
|
-
|
|
70266
|
+
report3.ok = false;
|
|
70037
70267
|
continue;
|
|
70038
70268
|
}
|
|
70039
70269
|
if (applyingPermissions) {
|
|
@@ -70070,14 +70300,14 @@ async function createCms(opts) {
|
|
|
70070
70300
|
}
|
|
70071
70301
|
}
|
|
70072
70302
|
}
|
|
70073
|
-
|
|
70303
|
+
report3.updated.push(id);
|
|
70074
70304
|
}
|
|
70075
|
-
return
|
|
70305
|
+
return report3;
|
|
70076
70306
|
}
|
|
70077
70307
|
async function seedCms(opts) {
|
|
70078
70308
|
const { app, cms, call, dryRun = false, force = false, only, dir } = opts;
|
|
70079
70309
|
const prefix = namespacePrefix(app);
|
|
70080
|
-
const
|
|
70310
|
+
const report3 = { ok: true, app, inserted: {}, sources: {}, skipped: [], refused: [], dryRun };
|
|
70081
70311
|
const fileRows = dir ? readSeedFile(dir) : {};
|
|
70082
70312
|
const rowsFor = (id, spec) => fileRows[id]?.length ? { rows: fileRows[id], source: "cms-seed.json" } : { rows: spec.seed ?? [], source: "config.ts" };
|
|
70083
70313
|
const remoteIds = /* @__PURE__ */ new Set();
|
|
@@ -70094,30 +70324,30 @@ async function seedCms(opts) {
|
|
|
70094
70324
|
const { rows, source } = rowsFor(id, spec);
|
|
70095
70325
|
considered++;
|
|
70096
70326
|
if (!rows.length) {
|
|
70097
|
-
|
|
70327
|
+
report3.skipped.push({
|
|
70098
70328
|
collection: id,
|
|
70099
70329
|
reason: `no seed rows \u2014 add a \`seed\` array to this collection in config.ts, or run \`himi cms seed --ai\` and refine ${dir ? "cms-seed.json" : "the generated cms-seed.json"}`
|
|
70100
70330
|
});
|
|
70101
70331
|
continue;
|
|
70102
70332
|
}
|
|
70103
70333
|
if (!spec.id?.startsWith(prefix)) {
|
|
70104
|
-
|
|
70105
|
-
|
|
70334
|
+
report3.refused.push({ collection: id, reason: `"${id}" is outside this app's namespace "${prefix}" \u2014 himi only seeds collections it owns.` });
|
|
70335
|
+
report3.ok = false;
|
|
70106
70336
|
continue;
|
|
70107
70337
|
}
|
|
70108
70338
|
if (!remoteIds.has(id)) {
|
|
70109
|
-
|
|
70110
|
-
|
|
70339
|
+
report3.skipped.push({ collection: id, reason: `not on the site yet \u2014 run \`himi cms create\` first` });
|
|
70340
|
+
report3.ok = false;
|
|
70111
70341
|
continue;
|
|
70112
70342
|
}
|
|
70113
70343
|
const count2 = await countItems(call, id);
|
|
70114
70344
|
if (count2 === null && !force) {
|
|
70115
|
-
|
|
70116
|
-
|
|
70345
|
+
report3.skipped.push({ collection: id, reason: "could not read the current row count, so seeding might bury existing content. Re-run, or pass --force if you are sure." });
|
|
70346
|
+
report3.ok = false;
|
|
70117
70347
|
continue;
|
|
70118
70348
|
}
|
|
70119
70349
|
if (count2 !== null && count2 > 0 && !force) {
|
|
70120
|
-
|
|
70350
|
+
report3.skipped.push({ collection: id, reason: `already has ${count2} items \u2014 seeding an already-populated collection needs --force so real content is never buried under sample rows` });
|
|
70121
70351
|
continue;
|
|
70122
70352
|
}
|
|
70123
70353
|
if (!dryRun) {
|
|
@@ -70129,7 +70359,7 @@ async function seedCms(opts) {
|
|
|
70129
70359
|
});
|
|
70130
70360
|
const droppedKeys = [...new Set(rows.flatMap((r) => Object.keys(r).filter((k) => !declaredKeys.has(k))))];
|
|
70131
70361
|
if (droppedKeys.length > 0) {
|
|
70132
|
-
|
|
70362
|
+
report3.skipped.push({
|
|
70133
70363
|
collection: id,
|
|
70134
70364
|
reason: `ignored undeclared key(s) in seed rows: ${droppedKeys.join(", ")} \u2014 only declared fields are written (a row cannot set system keys such as _id or _owner)`
|
|
70135
70365
|
});
|
|
@@ -70145,18 +70375,18 @@ async function seedCms(opts) {
|
|
|
70145
70375
|
)
|
|
70146
70376
|
);
|
|
70147
70377
|
}
|
|
70148
|
-
|
|
70149
|
-
|
|
70378
|
+
report3.inserted[id] = rows.length;
|
|
70379
|
+
report3.sources[id] = source;
|
|
70150
70380
|
}
|
|
70151
70381
|
if (considered === 0) {
|
|
70152
70382
|
const adopted = (cms?.collections ?? []).map((spec) => ({ spec, id: physicalId(spec, app) })).filter(({ spec, id }) => !!spec.wixId && (!only || id === only));
|
|
70153
|
-
|
|
70383
|
+
report3.skipped.push({
|
|
70154
70384
|
collection: only ?? "<none>",
|
|
70155
70385
|
reason: adopted.length ? `the selected collection${adopted.length === 1 ? " is" : "s are"} adopted and read-only \u2014 himi never seeds ${adopted.map(({ id }) => `"${id}"`).join(", ")}. Add rows in Wix CMS, or declare an owned collection with an id beginning "${prefix}".` : only ? `--only "${only}" matched no owned collection declared by this app` : "this app declares no owned CMS collections to seed"
|
|
70156
70386
|
});
|
|
70157
|
-
|
|
70387
|
+
report3.ok = false;
|
|
70158
70388
|
}
|
|
70159
|
-
return
|
|
70389
|
+
return report3;
|
|
70160
70390
|
}
|
|
70161
70391
|
function readSeedFile(dir) {
|
|
70162
70392
|
const file = join8(dir, "cms-seed.json");
|
|
@@ -70457,57 +70687,57 @@ function summarizeLint(app, bres, outcome, strict, extraIssues = []) {
|
|
|
70457
70687
|
}
|
|
70458
70688
|
};
|
|
70459
70689
|
const record2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
70460
|
-
const
|
|
70690
|
+
const text8 = (value) => typeof value === "string" && value ? value : void 0;
|
|
70461
70691
|
const message = (value) => {
|
|
70462
70692
|
const item = record2(value);
|
|
70463
|
-
if (
|
|
70464
|
-
if (
|
|
70693
|
+
if (text8(item.message)) return text8(item.message);
|
|
70694
|
+
if (text8(item.error)) return text8(item.error);
|
|
70465
70695
|
if (Array.isArray(item.errors)) {
|
|
70466
70696
|
const diagnostics = item.errors.map((entry) => {
|
|
70467
70697
|
const diagnostic = record2(entry);
|
|
70468
|
-
return
|
|
70698
|
+
return text8(diagnostic.text) ?? text8(diagnostic.message);
|
|
70469
70699
|
}).filter((entry) => !!entry);
|
|
70470
70700
|
if (diagnostics.length) return diagnostics.join("; ");
|
|
70471
70701
|
}
|
|
70472
70702
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
70473
70703
|
};
|
|
70474
|
-
const
|
|
70704
|
+
const report3 = foldLegacyReport(legacy, {
|
|
70475
70705
|
source: "validate",
|
|
70476
70706
|
evidence: { runId: `validate:${outcome.manifest.releaseId}`, ts: (/* @__PURE__ */ new Date()).toISOString() },
|
|
70477
70707
|
findings: [
|
|
70478
70708
|
...issues,
|
|
70479
70709
|
...bres.compileErrors.map((value) => ({
|
|
70480
70710
|
pass: "compile",
|
|
70481
|
-
path:
|
|
70711
|
+
path: text8(record2(value).bundle),
|
|
70482
70712
|
ruleCode: "compile-error",
|
|
70483
70713
|
severity: "error",
|
|
70484
70714
|
message: message(value)
|
|
70485
70715
|
})),
|
|
70486
70716
|
...outcome.failedToBuild.map((value) => ({
|
|
70487
70717
|
pass: "build",
|
|
70488
|
-
screen:
|
|
70718
|
+
screen: text8(record2(value).screenId),
|
|
70489
70719
|
ruleCode: "failed-to-build",
|
|
70490
70720
|
severity: "error",
|
|
70491
70721
|
message: message(value)
|
|
70492
70722
|
})),
|
|
70493
70723
|
...outcome.missingBundles.map((value) => ({
|
|
70494
70724
|
pass: "build",
|
|
70495
|
-
screen:
|
|
70496
|
-
path:
|
|
70725
|
+
screen: text8(record2(value).screen),
|
|
70726
|
+
path: text8(record2(value).bundle),
|
|
70497
70727
|
ruleCode: "missing-bundle",
|
|
70498
70728
|
severity: "error",
|
|
70499
70729
|
message: message(value)
|
|
70500
70730
|
})),
|
|
70501
70731
|
...workerThrows.map((value) => ({
|
|
70502
70732
|
pass: "worker",
|
|
70503
|
-
path:
|
|
70733
|
+
path: text8(record2(value).bundle),
|
|
70504
70734
|
ruleCode: "worker-threw",
|
|
70505
70735
|
severity: "error",
|
|
70506
70736
|
message: message(value.threw)
|
|
70507
70737
|
}))
|
|
70508
70738
|
]
|
|
70509
70739
|
});
|
|
70510
|
-
return { report:
|
|
70740
|
+
return { report: report3, hasErrors };
|
|
70511
70741
|
}
|
|
70512
70742
|
|
|
70513
70743
|
// src/cms-lint.ts
|
|
@@ -70631,8 +70861,8 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
70631
70861
|
if (requested.length) {
|
|
70632
70862
|
const { rejected } = resolveSurfaceEnvelope(platforms, requested);
|
|
70633
70863
|
for (const r of rejected) {
|
|
70634
|
-
const
|
|
70635
|
-
|
|
70864
|
+
const report3 = surfaceById(r.id) ? warn : error;
|
|
70865
|
+
report3(`navigation.surfaces: ${r.reason} \u2014 the server will drop this key (narrow-only rule, RFC 0051 \xA73.6)`);
|
|
70636
70866
|
}
|
|
70637
70867
|
}
|
|
70638
70868
|
return issues;
|
|
@@ -70779,18 +71009,18 @@ function walkSource(dir, root = dir) {
|
|
|
70779
71009
|
const ext = entry.name.slice(entry.name.lastIndexOf("."));
|
|
70780
71010
|
if (!SOURCE_EXTENSIONS.has(ext)) continue;
|
|
70781
71011
|
const absolute = join25(dir, entry.name);
|
|
70782
|
-
const
|
|
70783
|
-
if (
|
|
71012
|
+
const text8 = readText2(absolute);
|
|
71013
|
+
if (text8 !== null) found.push({ path: relative4(root, absolute), text: text8 });
|
|
70784
71014
|
}
|
|
70785
71015
|
return found;
|
|
70786
71016
|
}
|
|
70787
|
-
function blankMatrixRows(
|
|
70788
|
-
const acceptance = mobileUxSection(mobileUxDocumentBody(
|
|
71017
|
+
function blankMatrixRows(text8) {
|
|
71018
|
+
const acceptance = mobileUxSection(mobileUxDocumentBody(text8), "Implementation acceptance") ?? "";
|
|
70789
71019
|
return /\|\s*(?:Ready|Empty|Add\s*\/\s*edit|Saved\s*\/\s*completed|Error\s*\/\s*recovery)\s*\|\s*\|\s*\|\s*\|\s*\|/i.test(acceptance);
|
|
70790
71020
|
}
|
|
70791
71021
|
function usesAppNetwork(source) {
|
|
70792
|
-
const code = (
|
|
70793
|
-
return source.some(({ text:
|
|
71022
|
+
const code = (text8) => text8.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
|
|
71023
|
+
return source.some(({ text: text8 }) => /\bwixApi\b|(?:from|import)\s*["']@(?:himalaya|wix\/himalaya)\/wix-[^"']+["']/.test(code(text8)));
|
|
70794
71024
|
}
|
|
70795
71025
|
function auditUx(content, strict = false) {
|
|
70796
71026
|
const dir = resolve16(content);
|
|
@@ -71504,6 +71734,13 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
71504
71734
|
Requires Himi owner login plus Wix CLI login for site authorization.
|
|
71505
71735
|
himi notify status --content <dir> [--site <msid>] [--refresh] [--json]
|
|
71506
71736
|
Reads server setup status. --refresh checks Branded/Ping live; it does not send push.
|
|
71737
|
+
himi notify send --provider ping --target wix --app <a> --site <msid> --member-email <email>
|
|
71738
|
+
--title <s> [--body <s>] --link <scheme>://screen/<id>[?\u2026] [--request-id <uuid>] [--dry-run] [--json]
|
|
71739
|
+
Hosted test notification to ONE site member's devices: Himi Serve sends it through Ping
|
|
71740
|
+
as Himalaya, so no Apple/Firebase keys or Fire Console. Needs himi login --browser and
|
|
71741
|
+
wix login as the site owner, and a ready notify setup. Acceptance is not delivery.
|
|
71742
|
+
--dry-run checks ownership, member, link and readiness without sending. After an unknown
|
|
71743
|
+
outcome, re-run the same command with the printed --request-id; Ping never runs it twice.
|
|
71507
71744
|
himi notify send --app <a> (--token <t> | --device <id> | --all) --title <s> [--body <s>] [--link <url>]
|
|
71508
71745
|
deliver a REAL push notification to registered devices \u2014
|
|
71509
71746
|
APNs (.p8) for iOS, FCM v1 for Android. --all fans out to
|
|
@@ -71695,7 +71932,7 @@ var COMMANDS = [
|
|
|
71695
71932
|
{ name: "icon", summary: "the app's LAUNCHER icon \u2014 the home-screen / store mark, which is BINARY-floor and never over-the-air (distinct from `himi icons`, the in-screen glyph vocabulary). `status`/`check` report what this app would actually ship and validate it against both stores: exact 1024x1024, no tRNS chunk, non-interlaced, and \u2014 when the optional image toolchain is installed \u2014 no transparent regions (Apple permits an alpha channel but not transparent pixels: ITMS-90717), no pre-masked corners, no letterboxed wordmark; they also print the store-policy checklist no checker can decide. `set <file.png>` installs supplied art, `from-site` installs the logo `himi site analyze` downloaded, and `generate` makes a gradient tile + glyph \u2014 all three trim, flatten onto the app's accent, write the 1024 opaque master plus the 512 Play listing icon (Play wants 32-bit WITH alpha, so it is a separate file), and DECLARE it in himalaya.content.json, without which the release bakes no icon at all", required: "[status|check] | set <file.png> | from-site [--book <dir>] | generate [--glyph <g>] [--accent <hex>] | glyphs [--content <dir>] [--json]" },
|
|
71696
71933
|
{ name: "login", summary: "obtain a scoped serve-control token from Wix identity and store it in ~/.himalaya/serve-targets.json (so push/promote need no hand-pasted token). Three modes: --browser (your own Wix account, no VPN/BO), --wix (HEADLESS \u2014 the machine's own Wix CLI credential; the mode a CI pod or agent container can satisfy), --dpx (Wix employee, reads ~/.dpx/session/token). RFC 0026 WS3.", required: "[--browser|--wix|--dpx] [--target <t>] [--issue-url <url>]" },
|
|
71697
71934
|
{ name: "logout", summary: "remove the stored control token for a target", required: "[--target <t>]" },
|
|
71698
|
-
{ name: "notify", summary: "`setup` optionally configures Branded/Ping from local customer key files; `status --refresh` reads live backend readiness. Setup may be deferred while building. These use serve-control and require owner plus Wix account authentication. `send`, `tokens`, `doctor`: send a REAL push notification to registered devices (RFC 0036 WS5) \u2014 APNs .p8 over HTTP/2 for iOS, FCM v1 for Android. `send` targets one device (--token / --device <registry id>) or fans out to the whole app (--all), reporting a per-device result; a token the provider says is uninstalled (APNs 410 Unregistered / FCM UNREGISTERED) is auto-disabled, while a merely wrong one (BadDeviceToken \u2014 usually a sandbox/production mismatch) is recorded and left enabled. `tokens` lists the registry. `doctor` reports which credentials resolve and which sender each platform picks. Talks to the admin-server via --admin-url/HIMALAYA_ADMIN_URL, authenticated with --admin-session/HIMALAYA_ADMIN_SESSION. NOT `himi push`, which publishes a release.", required: "setup|status [--content <dir>] [--target <t>] [--refresh] [--yes] [--no-push-setup] | send|tokens|doctor [--app <a>] [--token <t> | --device <id> | --all] [--title <s>] [--body <s>] [--link <url>] [--platform ios|android] [--badge <n>] [--channel <id>] [--silent] [--dry-run] [--json]" },
|
|
71935
|
+
{ name: "notify", summary: "`setup` optionally configures Branded/Ping from local customer key files; `status --refresh` reads live backend readiness. Setup may be deferred while building. These use serve-control and require owner plus Wix account authentication. `send`, `tokens`, `doctor`: send a REAL push notification to registered devices (RFC 0036 WS5) \u2014 APNs .p8 over HTTP/2 for iOS, FCM v1 for Android. `send` targets one device (--token / --device <registry id>) or fans out to the whole app (--all), reporting a per-device result; a token the provider says is uninstalled (APNs 410 Unregistered / FCM UNREGISTERED) is auto-disabled, while a merely wrong one (BadDeviceToken \u2014 usually a sandbox/production mismatch) is recorded and left enabled. `tokens` lists the registry. `doctor` reports which credentials resolve and which sender each platform picks. Talks to the admin-server via --admin-url/HIMALAYA_ADMIN_URL, authenticated with --admin-session/HIMALAYA_ADMIN_SESSION. `send --provider ping` is the hosted alternative: the serve plane sends one test notification to one site member through Ping as Himalaya, with owner login instead of provider keys, and reports acceptance, never delivery. NOT `himi push`, which publishes a release.", required: "setup|status [--content <dir>] [--target <t>] [--refresh] [--yes] [--no-push-setup] | send --provider ping [--content <dir>] [--app <a>] [--site <msid>] --member-email <email> --title <s> [--body <s>] --link <url> [--request-id <uuid>] [--dry-run] [--json] | send|tokens|doctor [--app <a>] [--token <t> | --device <id> | --all] [--title <s>] [--body <s>] [--link <url>] [--platform ios|android] [--badge <n>] [--channel <id>] [--silent] [--dry-run] [--json]" },
|
|
71699
71936
|
{ name: "site", summary: "PROVISION a Wix project, then analyze or extend it. `create` is the one door that makes a site instead of adopting one: POST /funnel/projects/v1/create (a WIX site, a HEADLESS backend, a BRANDED_APP, or a VIBE site), and for headless it also mints the OAuth app whose id IS the `WIX_CLIENT_ID` \u2014 with --redirect-uri already registered, because an unregistered redirect makes native signInDirect fail at redirect-session. `--verticals` REQUIRES `--template` and reports only what Wix confirmed: measured, installing onto a project created from the BLANK template returns 200 while the vertical's API answers 428 forever, because there is no site for it to attach to (the install asks for CREATE_SITE). A real template ships its verticals installed and populated, and installing further ones onto it then works. It MUTATES your Wix account and needs --yes; without it you get the payload and nothing is sent. `list` is the read-only site inventory (with each site's premium flag, which is what explains an installed-but-428 vertical). Auth is the account-scoped `wix token` (no --site), falling back to WIX_API_KEY + WIX_ACCOUNT_ID. `client` is the same OAuth step for a site that ALREADY exists \u2014 the one himi adopts rather than makes \u2014 so a clientId no longer means a manual trip to the dashboard: `client ensure` reconciles rather than mints, because a site can already carry a client with NO registered redirect and shipping that one fails signInDirect at runtime; it reuses a client that carries --redirect-uri, PATCHes one that matches --name but lacks it (unioning, so another app's redirect survives), and creates only when there is nothing to reuse (--new forces a fresh one). --name IS the idempotency key. `client` auth is SITE-scoped (`wix token --site <msid>`) because minting is owner-of-that-site, and --yes gates every mutation: a site that already has a usable client resolves WITHOUT it, but --write-provisioning needs --yes even then because it rewrites a manifest on disk (the dry run's planned.provisioning names the file). That query endpoint IGNORES paging (measured: query.paging, cursorPaging and a top-level paging all return the full set at offset 0), so when pagingMetadata reports more clients than came back, `ensure` REFUSES EVERY outcome \u2014 create, patch AND reuse. Reuse is refused too because pickClient breaks ties on the OLDEST createdDate, so an omitted older same-named MOBILE client with the same redirect would win a later complete read and the resolved clientId would MOVE between runs \u2014 and it gets written into provisioning.json; convergence is what makes a stray duplicate untidy rather than harmful. --name cannot narrow the query (no filter is sent; the name is applied to the rows after they arrive), so the recovery is the dashboard; --new skips the query entirely. A `patched` result is verified against what Wix STORED \u2014 the redirect list is read off the PATCH response, and re-read via GET when the response omits it, because falling back to the list himi just sent would make the guard pass vacuously on exactly the silent no-op it exists to catch. `client list` is the read-only inventory of a site's clients: act on its `shippable` column rather than `hasRedirect`, because shippable ALSO requires a MOBILE applicationType and `ensure` refuses a WEB client \u2014 a WEB one carrying your redirect looks right and is not a candidate \u2014 and it sets truncated:true rather than presenting a partial inventory as the whole one. `analyze --read-only` returns API-only generation context as JSON (identity, access probes, CMS permissions and selected redacted Velo source); it needs no URL/browser and never uploads or applies anything. `analyze` reads a site into a business-book folder (REST + Playwright, GET-only); `--url` alone is the visitor-only pass over the published pages, and `--client-id` adds the vertical probes and the app binding `--apply` requires; `site function` list/get/put/publish/invokes that site's Velo HTTP functions and is not `himi functions` (serve-plane jobs). `--apply` bakes into a brandable shell; `--shell` takes the same names `himi dist --shell` does and defaults to branded-lite, and a shell that ships no prepare:customer is refused by name rather than half-built. `--shell brandy` (the site shell, RFC 0062) also derives the site's page map from its published pages and header menu \u2014 Home first, up to four tabs for the pages a visitor returns to, the rest in the drawer \u2014 into the overlay's `site` block, so it can be edited before `--apply`; only a site shell ever receives that block. It never overwrites any shell's committed apps/<shell>/provisioning.json.", required: "create <name> [--type wix|headless|branded-app|vibe] [--template <guid>] [--verticals stores,bookings,\u2026] [--folder <guid>] [--redirect-uri <uri>] [--no-oauth-app] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | list | client ensure|list --site <msid> [--name <name>] [--redirect-uri <uri>] [--new] [--write-provisioning [path]] [--site-url <url>] [--json] --yes | analyze --read-only [--site <msid>] [--client-id <id>] [--json] | analyze --url <https> [--client-id <id>] [--site <msid>] [--out <dir>] [--redirect-uri <uri>] [--apply] [--shell " + SHELL_ENUM + "] | function list|get|put|publish|invoke [--site <msid>] [--url <https>] [--method GET|POST|PUT|DELETE] [--source <file>] [--body <json>] [--publish] [--invoke]" },
|
|
71700
71937
|
{ name: "doctor", summary: 'off-VPN preflight in one shot: probe the PUBLIC data plane (www.wixapis.com \u2014 reachable off-VPN), the INTERNAL serve/control plane for the selected target (VPN-gated), and report auth state (dpx session on disk + stored control token). --dpx additionally runs a live, EADDRINUSE-safe `dpx whoami`. Machine-readable with --json (an unreachable internal plane carries a stable code:"needs_vpn" so an agent branches on the code, not the prose); human-readable otherwise. Never loads the authoring runtime \u2014 works off-repo.', required: "[--target <t>] [--dpx] [--json] [--data-url <url>] [--timeout <ms>]" },
|
|
71701
71938
|
{ name: "upgrade", summary: "install the newest published CLI (`npm i -g @wix/himalaya-cli@latest`) and report what moved. This is the explicit door: himi also updates itself when the running build is more than a week old \u2014 unattended it just does it and re-runs your command, at a terminal it asks first \u2014 and `HIMI_NO_UPDATE_CHECK=1` turns that off, leaving this command as the way to catch up. Reports `unchanged` rather than claiming success when npm exits 0 without moving the version, which is what a registry mirror serving its own pinned copy looks like.", required: "[--json]" },
|
|
@@ -71788,16 +72025,16 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
71788
72025
|
}
|
|
71789
72026
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
71790
72027
|
function execNpmConfig(file, args, options) {
|
|
71791
|
-
return new Promise((
|
|
71792
|
-
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) :
|
|
72028
|
+
return new Promise((resolve53, reject) => {
|
|
72029
|
+
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve53(String(stdout)));
|
|
71793
72030
|
});
|
|
71794
72031
|
}
|
|
71795
72032
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
71796
72033
|
async function scopedRegistryBefore(lookup2, deadline) {
|
|
71797
72034
|
let cancel = () => {
|
|
71798
72035
|
};
|
|
71799
|
-
const expired = new Promise((
|
|
71800
|
-
const timer = setTimeout(() =>
|
|
72036
|
+
const expired = new Promise((resolve53) => {
|
|
72037
|
+
const timer = setTimeout(() => resolve53(void 0), Math.max(0, deadline - Date.now()));
|
|
71801
72038
|
cancel = () => clearTimeout(timer);
|
|
71802
72039
|
});
|
|
71803
72040
|
try {
|
|
@@ -71862,7 +72099,7 @@ function packageVersion(path2) {
|
|
|
71862
72099
|
}
|
|
71863
72100
|
}
|
|
71864
72101
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
71865
|
-
let dir =
|
|
72102
|
+
let dir = resolve52(fromDir);
|
|
71866
72103
|
for (; ; ) {
|
|
71867
72104
|
const version2 = packageVersion(join64(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
71868
72105
|
if (version2) return { version: version2, source: "local" };
|
|
@@ -72027,7 +72264,7 @@ function thisHost() {
|
|
|
72027
72264
|
return hostname().replace(/\s+/g, "_");
|
|
72028
72265
|
}
|
|
72029
72266
|
function lockStamp(now) {
|
|
72030
|
-
return `${now} ${process.pid} ${thisHost()} ${
|
|
72267
|
+
return `${now} ${process.pid} ${thisHost()} ${randomUUID7()}`;
|
|
72031
72268
|
}
|
|
72032
72269
|
function processAlive(pid) {
|
|
72033
72270
|
try {
|
|
@@ -72181,21 +72418,21 @@ function loaderArgs(execArgv) {
|
|
|
72181
72418
|
}
|
|
72182
72419
|
var spawnUpdateRefresh = createUpdateRefreshSpawner();
|
|
72183
72420
|
function createTrimValidator(deps = {}, spawnFn = spawn7) {
|
|
72184
|
-
const outcome = (code,
|
|
72421
|
+
const outcome = (code, report3, said) => {
|
|
72185
72422
|
let counts;
|
|
72186
72423
|
let errors;
|
|
72187
72424
|
try {
|
|
72188
|
-
const parsed = JSON.parse(
|
|
72425
|
+
const parsed = JSON.parse(report3);
|
|
72189
72426
|
counts = parsed.counts;
|
|
72190
72427
|
if (Array.isArray(parsed.findings)) {
|
|
72191
|
-
const
|
|
72428
|
+
const text8 = (v) => typeof v === "string" && v ? v : void 0;
|
|
72192
72429
|
errors = parsed.findings.filter((f) => f && f.severity === "error" && typeof f.id === "string").map((f) => ({
|
|
72193
72430
|
id: f.id,
|
|
72194
|
-
message:
|
|
72195
|
-
...
|
|
72196
|
-
...
|
|
72197
|
-
...
|
|
72198
|
-
...
|
|
72431
|
+
message: text8(f.message) ?? "",
|
|
72432
|
+
...text8(f.pass) ? { pass: text8(f.pass) } : {},
|
|
72433
|
+
...text8(f.screen) ? { screen: text8(f.screen) } : {},
|
|
72434
|
+
...text8(f.path) ? { path: text8(f.path) } : {},
|
|
72435
|
+
...text8(f.ruleCode) ? { ruleCode: text8(f.ruleCode) } : {}
|
|
72199
72436
|
}));
|
|
72200
72437
|
}
|
|
72201
72438
|
} catch {
|
|
@@ -72203,7 +72440,7 @@ function createTrimValidator(deps = {}, spawnFn = spawn7) {
|
|
|
72203
72440
|
return { code, counts, ...errors ? { errors } : {}, ...code !== 0 ? { tail: said.slice(-4e3) } : {} };
|
|
72204
72441
|
};
|
|
72205
72442
|
return async (dir, opts = {}) => {
|
|
72206
|
-
const argv = ["validate", "--content",
|
|
72443
|
+
const argv = ["validate", "--content", resolve52(dir), "--strict", "--skip-version-check"];
|
|
72207
72444
|
if (!opts.fresh) {
|
|
72208
72445
|
const out2 = [];
|
|
72209
72446
|
const err = [];
|
|
@@ -72819,7 +73056,7 @@ function keptPlan(kept) {
|
|
|
72819
73056
|
return note ? { kept, note } : {};
|
|
72820
73057
|
}
|
|
72821
73058
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
72822
|
-
const dir =
|
|
73059
|
+
const dir = resolve52(parentDir, name);
|
|
72823
73060
|
if (existsSync66(join64(dir, "himalaya.content.json"))) {
|
|
72824
73061
|
throw new Error(`content package already exists at ${dir}`);
|
|
72825
73062
|
}
|
|
@@ -72832,17 +73069,17 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
72832
73069
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
72833
73070
|
}
|
|
72834
73071
|
function contentDir(flags) {
|
|
72835
|
-
return
|
|
73072
|
+
return resolve52(str8(flags.content) ?? process.cwd());
|
|
72836
73073
|
}
|
|
72837
73074
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
72838
|
-
const
|
|
73075
|
+
const text8 = {};
|
|
72839
73076
|
for (const entry of restored) {
|
|
72840
73077
|
const decoded = entry.bytes.toString("utf8");
|
|
72841
|
-
if (Buffer.from(decoded, "utf8").equals(entry.bytes))
|
|
73078
|
+
if (Buffer.from(decoded, "utf8").equals(entry.bytes)) text8[entry.path] = decoded;
|
|
72842
73079
|
}
|
|
72843
|
-
const sentineled = sentinelizeArchive(
|
|
73080
|
+
const sentineled = sentinelizeArchive(text8, declaredApp);
|
|
72844
73081
|
for (const entry of restored) {
|
|
72845
|
-
if (!(entry.path in
|
|
73082
|
+
if (!(entry.path in text8)) continue;
|
|
72846
73083
|
const body = sentineled[entry.path];
|
|
72847
73084
|
if (body !== void 0) entry.bytes = Buffer.from(substituteIdentity(body, renamed), "utf8");
|
|
72848
73085
|
}
|
|
@@ -72876,7 +73113,7 @@ function restoreDestinationIssue(dest, force) {
|
|
|
72876
73113
|
return null;
|
|
72877
73114
|
}
|
|
72878
73115
|
function isHimalayaMonorepoCheckout(start) {
|
|
72879
|
-
let dir =
|
|
73116
|
+
let dir = resolve52(start);
|
|
72880
73117
|
for (; ; ) {
|
|
72881
73118
|
if (existsSync66(join64(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync66(join64(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
72882
73119
|
const parent = dirname36(dir);
|
|
@@ -72938,7 +73175,7 @@ function materializeForPreview(appDir3, slug, displayName) {
|
|
|
72938
73175
|
const forBuild = Object.fromEntries(
|
|
72939
73176
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
72940
73177
|
);
|
|
72941
|
-
const repoRoot2 =
|
|
73178
|
+
const repoRoot2 = resolve52(fileURLToPath26(new URL("../../..", import.meta.url)));
|
|
72942
73179
|
const root = join64(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
72943
73180
|
const stillRunning = (pid) => {
|
|
72944
73181
|
try {
|
|
@@ -73184,7 +73421,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
73184
73421
|
return 0;
|
|
73185
73422
|
}
|
|
73186
73423
|
case "agent-init": {
|
|
73187
|
-
const dir =
|
|
73424
|
+
const dir = resolve52(str8(flags.dir) ?? process.cwd());
|
|
73188
73425
|
const { seedAgentFiles: seedAgentFiles2, NotAContentPackage: NotAContentPackage2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
73189
73426
|
let res;
|
|
73190
73427
|
try {
|
|
@@ -73741,7 +73978,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
73741
73978
|
return 2;
|
|
73742
73979
|
}
|
|
73743
73980
|
const template = str8(flags.template);
|
|
73744
|
-
const parentDir =
|
|
73981
|
+
const parentDir = resolve52(str8(flags.dir) ?? process.cwd());
|
|
73745
73982
|
const withAgentFiles = async (dir) => {
|
|
73746
73983
|
const seeded = await seedAgentFilesFor(dir, flags);
|
|
73747
73984
|
if (!seeded.agent || "error" in seeded.agent) return seeded;
|
|
@@ -73902,8 +74139,8 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73902
74139
|
return 2;
|
|
73903
74140
|
}
|
|
73904
74141
|
}
|
|
73905
|
-
const appDir3 =
|
|
73906
|
-
const sourceDir =
|
|
74142
|
+
const appDir3 = resolve52(str8(flags.dir) ?? process.cwd());
|
|
74143
|
+
const sourceDir = resolve52(str8(flags["source-dir"]) ?? appDir3);
|
|
73907
74144
|
let meta;
|
|
73908
74145
|
try {
|
|
73909
74146
|
meta = JSON.parse(readFileSync79(join64(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
@@ -73945,7 +74182,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73945
74182
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
73946
74183
|
collect: { lint: true, strict }
|
|
73947
74184
|
});
|
|
73948
|
-
const scaffoldSourceFindings =
|
|
74185
|
+
const scaffoldSourceFindings = resolve52(sourceDir) === resolve52(appDir3) ? [] : [
|
|
73949
74186
|
...tokenColorIssues(sourceDir),
|
|
73950
74187
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
73951
74188
|
...await fontIssues(sourceDir, strict),
|
|
@@ -73957,7 +74194,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73957
74194
|
message: `scaffold source (--source-dir ${sourceDir}): ${issue2.message}`
|
|
73958
74195
|
}));
|
|
73959
74196
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
73960
|
-
const { report:
|
|
74197
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
73961
74198
|
...await cmsIssues(buildDir, app, strict, { local: true }),
|
|
73962
74199
|
...surfaceIssues(buildDir, outcome.surfaceNav, strict),
|
|
73963
74200
|
...tokenColorIssues(buildDir),
|
|
@@ -73967,7 +74204,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73967
74204
|
...scaffoldSourceFindings
|
|
73968
74205
|
]);
|
|
73969
74206
|
if (hasErrors && !force) {
|
|
73970
|
-
print({ ...
|
|
74207
|
+
print({ ...report3, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
73971
74208
|
return 1;
|
|
73972
74209
|
}
|
|
73973
74210
|
const payload = await loadReleaseFromDir(app, out2);
|
|
@@ -73988,7 +74225,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73988
74225
|
}));
|
|
73989
74226
|
return 1;
|
|
73990
74227
|
}
|
|
73991
|
-
const iconPath = str8(flags.icon) ?
|
|
74228
|
+
const iconPath = str8(flags.icon) ? resolve52(str8(flags.icon)) : templateIconPath(name);
|
|
73992
74229
|
let iconHash;
|
|
73993
74230
|
if (iconPath) {
|
|
73994
74231
|
try {
|
|
@@ -74242,7 +74479,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74242
74479
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
74243
74480
|
collect: { lint: true, strict }
|
|
74244
74481
|
});
|
|
74245
|
-
const { report:
|
|
74482
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
74246
74483
|
...await cmsIssues(dir, app, strict, { local: true }),
|
|
74247
74484
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
74248
74485
|
...tokenColorIssues(dir),
|
|
@@ -74259,10 +74496,10 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74259
74496
|
if (authWarning) advisories.push(authWarning);
|
|
74260
74497
|
advisories.push(...await nativeConfigAdvisories(app, configSource));
|
|
74261
74498
|
const finalReport = advisories.length ? {
|
|
74262
|
-
...
|
|
74263
|
-
warnings: [...
|
|
74264
|
-
counts: { ...
|
|
74265
|
-
} :
|
|
74499
|
+
...report3,
|
|
74500
|
+
warnings: [...report3.warnings ?? [], ...advisories],
|
|
74501
|
+
counts: { ...report3.counts, warnings: report3.counts.warnings + advisories.length }
|
|
74502
|
+
} : report3;
|
|
74266
74503
|
await leaveForBoard(dir, "validate", {
|
|
74267
74504
|
ok: !hasErrors,
|
|
74268
74505
|
errors: finalReport.counts.errors,
|
|
@@ -74375,23 +74612,23 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74375
74612
|
const app = str8(flags.app) ?? loaded.app;
|
|
74376
74613
|
const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken: str8(flags["preview-token"]), boCookie: boCookie() });
|
|
74377
74614
|
const response = invoked2.response;
|
|
74378
|
-
const
|
|
74615
|
+
const text9 = await response.text();
|
|
74379
74616
|
let body2;
|
|
74380
74617
|
try {
|
|
74381
|
-
body2 = JSON.parse(
|
|
74618
|
+
body2 = JSON.parse(text9);
|
|
74382
74619
|
} catch {
|
|
74383
|
-
body2 =
|
|
74620
|
+
body2 = text9;
|
|
74384
74621
|
}
|
|
74385
74622
|
print({ ok: response.ok, app, releaseId: remoteRelease ?? null, url: invoked2.url, status: response.status, body: body2 });
|
|
74386
74623
|
return response.ok ? 0 : 1;
|
|
74387
74624
|
}
|
|
74388
74625
|
const invoked = await invokeLocalFunction2(loaded, name, input, params);
|
|
74389
|
-
const
|
|
74626
|
+
const text8 = await invoked.response.text();
|
|
74390
74627
|
let body;
|
|
74391
74628
|
try {
|
|
74392
|
-
body = JSON.parse(
|
|
74629
|
+
body = JSON.parse(text8);
|
|
74393
74630
|
} catch {
|
|
74394
|
-
body =
|
|
74631
|
+
body = text8;
|
|
74395
74632
|
}
|
|
74396
74633
|
print({ ok: invoked.response.ok, app: loaded.app, releaseId: invoked.releaseId, status: invoked.response.status, body });
|
|
74397
74634
|
return invoked.response.ok ? 0 : 1;
|
|
@@ -74410,7 +74647,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74410
74647
|
return 1;
|
|
74411
74648
|
}
|
|
74412
74649
|
const { himiPluginFiles: himiPluginFiles2 } = await Promise.resolve().then(() => (init_claude_plugin(), claude_plugin_exports));
|
|
74413
|
-
const dir =
|
|
74650
|
+
const dir = resolve52(out2);
|
|
74414
74651
|
const files = himiPluginFiles2(skills.skillMd);
|
|
74415
74652
|
for (const f of files) {
|
|
74416
74653
|
mkdirSync32(dirname36(join64(dir, f.path)), { recursive: true });
|
|
@@ -74432,7 +74669,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74432
74669
|
}
|
|
74433
74670
|
if (pos[1] === "reel") {
|
|
74434
74671
|
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
74435
|
-
const out2 =
|
|
74672
|
+
const out2 = resolve52(str8(flags.out) ?? join64(dir, ".himi", "making-of.html"));
|
|
74436
74673
|
const { html, plan } = buildReel2(dir);
|
|
74437
74674
|
mkdirSync32(dirname36(out2), { recursive: true });
|
|
74438
74675
|
writeFileSync29(out2, html);
|
|
@@ -74444,7 +74681,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74444
74681
|
openUrl2(url2);
|
|
74445
74682
|
}
|
|
74446
74683
|
const handover = { file: out2, hint: `hand ${basename17(out2)} to the owner at the handover \u2014 one self-contained page of their app taking shape; send it beside the preview link, never instead of it` };
|
|
74447
|
-
const
|
|
74684
|
+
const report3 = {
|
|
74448
74685
|
ok: true,
|
|
74449
74686
|
file: out2,
|
|
74450
74687
|
url: url2,
|
|
@@ -74457,7 +74694,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74457
74694
|
...plan.dropped ? { dropped: plan.dropped, note: "pictures were left out to keep the file attachable" } : {},
|
|
74458
74695
|
...plan.frames.length === 0 ? { hint: "no screen versions were recorded \u2014 run `himi studio` before building so the board keeps them" } : {}
|
|
74459
74696
|
};
|
|
74460
|
-
if (flags.json === true || io.isTTY !== true) print(
|
|
74697
|
+
if (flags.json === true || io.isTTY !== true) print(report3);
|
|
74461
74698
|
else io.log(`The making-of: ${out2}
|
|
74462
74699
|
${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
74463
74700
|
return 0;
|
|
@@ -74543,10 +74780,10 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74543
74780
|
}
|
|
74544
74781
|
if (flags.brief === true) {
|
|
74545
74782
|
const { agentContextNote: agentContextNote2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
74546
|
-
const
|
|
74783
|
+
const summary2 = summarizeProgress2(readProgress2(dir).entries);
|
|
74547
74784
|
const open = openApprovals2(readApprovals2(dir).events);
|
|
74548
74785
|
const note = agentContextNote2(dir, cliVersion());
|
|
74549
|
-
io.log(formatBrief2({ appName: appLabel2(dir), isContentPackage, summary, open, ...note ? { agentContextNote: note } : {} }));
|
|
74786
|
+
io.log(formatBrief2({ appName: appLabel2(dir), isContentPackage, summary: summary2, open, ...note ? { agentContextNote: note } : {} }));
|
|
74550
74787
|
return 0;
|
|
74551
74788
|
}
|
|
74552
74789
|
if (!message) {
|
|
@@ -74604,9 +74841,9 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74604
74841
|
const sub = pos[1] ?? "audit";
|
|
74605
74842
|
const dir = contentDir(flags);
|
|
74606
74843
|
if (sub === "audit") {
|
|
74607
|
-
const
|
|
74608
|
-
print(
|
|
74609
|
-
return
|
|
74844
|
+
const report3 = auditUx(dir, flags.strict === true);
|
|
74845
|
+
print(report3);
|
|
74846
|
+
return report3.ok ? 0 : 1;
|
|
74610
74847
|
}
|
|
74611
74848
|
if (sub !== "record") {
|
|
74612
74849
|
io.error(JSON.stringify({ error: "ux needs audit | record" }));
|
|
@@ -74818,7 +75055,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74818
75055
|
}
|
|
74819
75056
|
const authoringBase = serveBase();
|
|
74820
75057
|
try {
|
|
74821
|
-
const { report:
|
|
75058
|
+
const { report: report3 } = await (deps.browserAuthoring ?? runBrowserAuthoring2)({
|
|
74822
75059
|
authoringBase,
|
|
74823
75060
|
job: {
|
|
74824
75061
|
entry: sources.entry,
|
|
@@ -74835,10 +75072,10 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74835
75072
|
log: (line) => io.error(line)
|
|
74836
75073
|
});
|
|
74837
75074
|
const { afterBrowserTestRun: afterBrowserTestRun2, watchReminder: watchReminder3 } = await Promise.resolve().then(() => (init_milestones(), milestones_exports));
|
|
74838
|
-
const afterRun2 = afterBrowserTestRun2(dir, { screen: screen.screenId, report:
|
|
75075
|
+
const afterRun2 = afterBrowserTestRun2(dir, { screen: screen.screenId, report: report3, boardOpen: boardOpen(dir) });
|
|
74839
75076
|
const browserReminder = watchReminder3(dir, { content: str8(flags.content) });
|
|
74840
75077
|
print({
|
|
74841
|
-
...
|
|
75078
|
+
...report3,
|
|
74842
75079
|
screen: screen.screenId,
|
|
74843
75080
|
ranIn: "browser",
|
|
74844
75081
|
liveRequested: jobWix !== void 0,
|
|
@@ -74847,7 +75084,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74847
75084
|
// Also the envelope's LAST key (`tailLast` keeps it there): an agent may read only the tail.
|
|
74848
75085
|
...browserReminder ? { reminder: browserReminder } : {}
|
|
74849
75086
|
});
|
|
74850
|
-
return
|
|
75087
|
+
return report3.ok ? 0 : 1;
|
|
74851
75088
|
} catch (e) {
|
|
74852
75089
|
io.error(JSON.stringify({ error: e.message }));
|
|
74853
75090
|
return 1;
|
|
@@ -75193,7 +75430,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75193
75430
|
const pngTarget = typeof flags.png === "string" ? str8(flags.png) : flags.png === true ? shotPath : void 0;
|
|
75194
75431
|
if (pngTarget && r.pngBase64) {
|
|
75195
75432
|
pngFile = writePngFile(pngTarget, r.pngBase64);
|
|
75196
|
-
attestationPngFile =
|
|
75433
|
+
attestationPngFile = resolve52(pngTarget) === resolve52(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
|
|
75197
75434
|
}
|
|
75198
75435
|
if (renderWidth !== void 0 && r.renderable) {
|
|
75199
75436
|
recordRenderWidth(dir, {
|
|
@@ -75285,23 +75522,23 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75285
75522
|
return 2;
|
|
75286
75523
|
}
|
|
75287
75524
|
const { kitReport: kitReport2 } = await Promise.resolve().then(() => (init_design_kits(), design_kits_exports));
|
|
75288
|
-
const
|
|
75289
|
-
print(
|
|
75290
|
-
return
|
|
75525
|
+
const report3 = kitReport2(pos[2]);
|
|
75526
|
+
print(report3);
|
|
75527
|
+
return report3.ok ? 0 : 1;
|
|
75291
75528
|
}
|
|
75292
75529
|
case "fonts": {
|
|
75293
75530
|
const sub = pos[1];
|
|
75294
75531
|
const dir = contentDir(flags);
|
|
75295
75532
|
const { listReport: listReport3, checkReport: checkReport2, addReport: addReport2 } = await Promise.resolve().then(() => (init_fonts(), fonts_exports));
|
|
75296
75533
|
if (sub === void 0 || sub === "list") {
|
|
75297
|
-
const
|
|
75298
|
-
print(
|
|
75299
|
-
return
|
|
75534
|
+
const report3 = listReport3({ licenses: flags.licenses === true });
|
|
75535
|
+
print(report3);
|
|
75536
|
+
return report3.ok ? 0 : 1;
|
|
75300
75537
|
}
|
|
75301
75538
|
if (sub === "check") {
|
|
75302
|
-
const
|
|
75303
|
-
print(
|
|
75304
|
-
return
|
|
75539
|
+
const report3 = await checkReport2(dir);
|
|
75540
|
+
print(report3);
|
|
75541
|
+
return report3.ok ? 0 : 1;
|
|
75305
75542
|
}
|
|
75306
75543
|
if (sub === "add") {
|
|
75307
75544
|
const family = pos[2];
|
|
@@ -75309,9 +75546,9 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75309
75546
|
print({ ok: false, problems: ["usage: himi fonts add <Family>"] });
|
|
75310
75547
|
return 2;
|
|
75311
75548
|
}
|
|
75312
|
-
const
|
|
75313
|
-
print(
|
|
75314
|
-
return
|
|
75549
|
+
const report3 = addReport2(dir, family);
|
|
75550
|
+
print(report3);
|
|
75551
|
+
return report3.ok ? 0 : 1;
|
|
75315
75552
|
}
|
|
75316
75553
|
print({ ok: false, problems: [`unknown subcommand "${sub}"`], hint: "himi fonts [list|check|add]" });
|
|
75317
75554
|
return 2;
|
|
@@ -75332,7 +75569,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75332
75569
|
summarize: summarize4
|
|
75333
75570
|
} = await Promise.resolve().then(() => (init_icon(), icon_exports));
|
|
75334
75571
|
const requireVerified = sub === "check";
|
|
75335
|
-
const
|
|
75572
|
+
const report3 = async (status, extra = {}) => {
|
|
75336
75573
|
const findings = [
|
|
75337
75574
|
// Not a store rule, so it is not in byteIssues — but it is the one `himi dist`
|
|
75338
75575
|
// will refuse, and the point of `check` is to say so before the build does.
|
|
@@ -75370,7 +75607,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75370
75607
|
}
|
|
75371
75608
|
return blocksRelease2(status, { requireVerified }) ? 1 : 0;
|
|
75372
75609
|
};
|
|
75373
|
-
if (sub === "status" || sub === "check") return
|
|
75610
|
+
if (sub === "status" || sub === "check") return report3(await iconStatus2(dir));
|
|
75374
75611
|
if (sub === "set") {
|
|
75375
75612
|
const file = pos[2];
|
|
75376
75613
|
if (!file) {
|
|
@@ -75378,7 +75615,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75378
75615
|
return 1;
|
|
75379
75616
|
}
|
|
75380
75617
|
const res = await installIcon2(dir, file, { derivePlay: true });
|
|
75381
|
-
return
|
|
75618
|
+
return report3(res.status, { wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
75382
75619
|
}
|
|
75383
75620
|
if (sub === "from-site") {
|
|
75384
75621
|
const book = str8(flags.book) ?? ".himi/business-book";
|
|
@@ -75393,11 +75630,11 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75393
75630
|
return 1;
|
|
75394
75631
|
}
|
|
75395
75632
|
const res = await installIcon2(dir, logo, { derivePlay: true });
|
|
75396
|
-
return
|
|
75633
|
+
return report3(res.status, { from: logo, wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
75397
75634
|
}
|
|
75398
75635
|
if (sub === "generate") {
|
|
75399
75636
|
const res = await generateIcon2(dir, { glyph: str8(flags.glyph), background: str8(flags.accent), derivePlay: true });
|
|
75400
|
-
return
|
|
75637
|
+
return report3(res.status, { wrote: res.wrote });
|
|
75401
75638
|
}
|
|
75402
75639
|
if (sub === "glyphs") {
|
|
75403
75640
|
const names = glyphNames2();
|
|
@@ -75423,9 +75660,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75423
75660
|
const dir = contentDir(flags);
|
|
75424
75661
|
const { listReport: listReport3, verifyReport: verifyReport2, addAssetPayload: addAssetPayload2, removeAssetPayload: removeAssetPayload2 } = await Promise.resolve().then(() => (init_assets(), assets_exports));
|
|
75425
75662
|
if (sub === void 0 || sub === "list") {
|
|
75426
|
-
const
|
|
75427
|
-
print(
|
|
75428
|
-
return
|
|
75663
|
+
const report3 = listReport3(dir);
|
|
75664
|
+
print(report3);
|
|
75665
|
+
return report3.ok ? 0 : 1;
|
|
75429
75666
|
}
|
|
75430
75667
|
if (sub === "verify") {
|
|
75431
75668
|
const app = str8(flags.app) ?? await appId(dir);
|
|
@@ -75434,9 +75671,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75434
75671
|
io.error(JSON.stringify(found));
|
|
75435
75672
|
return 1;
|
|
75436
75673
|
}
|
|
75437
|
-
const
|
|
75438
|
-
print(
|
|
75439
|
-
return
|
|
75674
|
+
const report3 = verifyReport2(dir, app, found.manifest);
|
|
75675
|
+
print(report3);
|
|
75676
|
+
return report3.ok ? 0 : 1;
|
|
75440
75677
|
}
|
|
75441
75678
|
if (sub === "add" || sub === "rm") {
|
|
75442
75679
|
const app = str8(flags.app) ?? await appId(dir);
|
|
@@ -75529,7 +75766,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75529
75766
|
return 2;
|
|
75530
75767
|
}
|
|
75531
75768
|
const renamed = str8(flags.name);
|
|
75532
|
-
const dest =
|
|
75769
|
+
const dest = resolve52(str8(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
75533
75770
|
const replace = flags.replace === true;
|
|
75534
75771
|
const force = replace || flags.force === true;
|
|
75535
75772
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -75602,7 +75839,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75602
75839
|
let removed = [];
|
|
75603
75840
|
if (replace) removed = removeStaleSource2(restored, dest);
|
|
75604
75841
|
else left = staleSourcePaths2(restored, dest);
|
|
75605
|
-
const
|
|
75842
|
+
const refused2 = deniedArchivePaths2(restored);
|
|
75606
75843
|
const written = writeAppSource2(restored, dest);
|
|
75607
75844
|
const agent = await seedAgentFilesFor(dest, flags, "restore");
|
|
75608
75845
|
print({
|
|
@@ -75613,8 +75850,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75613
75850
|
...agent,
|
|
75614
75851
|
...renamed ? { renamedTo: renamed } : {},
|
|
75615
75852
|
...removed.length ? { removed } : {},
|
|
75616
|
-
...
|
|
75617
|
-
refused,
|
|
75853
|
+
...refused2.length ? {
|
|
75854
|
+
refused: refused2,
|
|
75618
75855
|
refusedNote: "this archive carries paths a restore will not write (the deny-list has grown since it was published) \u2014 they were skipped, not written over"
|
|
75619
75856
|
} : {},
|
|
75620
75857
|
// EVERY path, not a count and not a sample: the whole failure was that a hybrid tree
|
|
@@ -75698,7 +75935,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75698
75935
|
collect: { lint: true, strict }
|
|
75699
75936
|
});
|
|
75700
75937
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
75701
|
-
const { report:
|
|
75938
|
+
const { report: report3, hasErrors } = summarizeLint(declared, bres, outcome, strict, [
|
|
75702
75939
|
...await cmsIssues(dir, declared, strict, { local: true }),
|
|
75703
75940
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
75704
75941
|
...tokenColorIssues(dir),
|
|
@@ -75708,7 +75945,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75708
75945
|
...await navIssues2(dir, strict)
|
|
75709
75946
|
]);
|
|
75710
75947
|
if (hasErrors && !force) {
|
|
75711
|
-
print({ ...
|
|
75948
|
+
print({ ...report3, pushed: false, hint: "lint found errors \u2014 fix them, or re-run `himi push --force` to publish anyway" });
|
|
75712
75949
|
return 1;
|
|
75713
75950
|
}
|
|
75714
75951
|
const declaredData = await loadDataResourcesQuietly(dir);
|
|
@@ -75807,7 +76044,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75807
76044
|
// Reaches here ONLY on the forced path — the refusal above returned otherwise — so
|
|
75808
76045
|
// this is the override's record, and the case it matters most for is a `failed` drive.
|
|
75809
76046
|
ux: { evidence: patchUxEvidence, ctx: patchUxContext },
|
|
75810
|
-
lint:
|
|
76047
|
+
lint: report3.counts ?? null,
|
|
75811
76048
|
extra: { selector: parsed.selectors.map((s) => "pattern" in s ? `${s.kind}:${s.pattern}` : s.kind) }
|
|
75812
76049
|
});
|
|
75813
76050
|
}
|
|
@@ -76059,7 +76296,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76059
76296
|
// print a `himi pull` command that answers app_source_not_found later — the worst
|
|
76060
76297
|
// shape for a backup, which is one you are told you have.
|
|
76061
76298
|
...sourceSummary ? sourceStored === true ? { source: { ...sourceSummary, restore: `himi pull ${app} --release ${release}` } } : sourceStored === false ? { source: { ...sourceSummary, archived: false, note: "this serve target cannot store source archives, so this release cannot be restored with `himi pull`" } } : { source: { ...sourceSummary, archived: "unconfirmed", note: `this serve target did not report whether it stored the source (it may predate the field). Verify with \`himi pull ${app} --release ${release}\` before relying on it.` } } : { source: { archived: false, note: "pushed with --no-source \u2014 this release cannot be restored with `himi pull`" } },
|
|
76062
|
-
lint:
|
|
76299
|
+
lint: report3.counts,
|
|
76063
76300
|
// A push ships content, not backends. If the app declares CMS
|
|
76064
76301
|
// collections, say so and point at the verbs — but never mutate the
|
|
76065
76302
|
// site as a side effect of publishing a release.
|
|
@@ -76091,7 +76328,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76091
76328
|
nondeterministicWorkers: drifting
|
|
76092
76329
|
}),
|
|
76093
76330
|
...loopbackWarning ? { warning: loopbackWarning } : {},
|
|
76094
|
-
...
|
|
76331
|
+
...report3.issues ? { issues: report3.issues } : {},
|
|
76095
76332
|
previewWeb: base ? previewWebUrl(base, app, release, void 0, void 0, previewToken, previewHandover) : null,
|
|
76096
76333
|
// A timestamp alone leaves the reader to work out both how long they have and how to
|
|
76097
76334
|
// get another one. Print the duration and the re-mint command beside it (#2502 item 3).
|
|
@@ -76188,7 +76425,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76188
76425
|
return 2;
|
|
76189
76426
|
}
|
|
76190
76427
|
try {
|
|
76191
|
-
const res = writePack(
|
|
76428
|
+
const res = writePack(resolve52(releaseDir), only, resolve52(str8(flags.out) ?? process.cwd()));
|
|
76192
76429
|
print({
|
|
76193
76430
|
ok: true,
|
|
76194
76431
|
app: res.app,
|
|
@@ -76244,7 +76481,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76244
76481
|
collect: { lint: true, strict }
|
|
76245
76482
|
});
|
|
76246
76483
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
76247
|
-
const { report:
|
|
76484
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
76248
76485
|
...await cmsIssues(dir, app, strict, { local: true }),
|
|
76249
76486
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
76250
76487
|
...tokenColorIssues(dir),
|
|
@@ -76255,11 +76492,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76255
76492
|
]);
|
|
76256
76493
|
if (hasErrors && !force) {
|
|
76257
76494
|
rmSync15(built, { recursive: true, force: true });
|
|
76258
|
-
print({ ...
|
|
76495
|
+
print({ ...report3, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
76259
76496
|
return 1;
|
|
76260
76497
|
}
|
|
76261
76498
|
try {
|
|
76262
|
-
const res = writePack(built, app,
|
|
76499
|
+
const res = writePack(built, app, resolve52(str8(flags.out) ?? dir), sourceArchive);
|
|
76263
76500
|
print({
|
|
76264
76501
|
ok: true,
|
|
76265
76502
|
app: res.app,
|
|
@@ -76269,12 +76506,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76269
76506
|
entries: res.entryCount,
|
|
76270
76507
|
format,
|
|
76271
76508
|
launchMode,
|
|
76272
|
-
lint:
|
|
76509
|
+
lint: report3.counts,
|
|
76273
76510
|
contents: withSource ? "dev" : "release",
|
|
76274
76511
|
...sourceSummary ? { source: sourceSummary } : {},
|
|
76275
76512
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
76276
76513
|
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
76277
|
-
...
|
|
76514
|
+
...report3.issues ? { issues: report3.issues } : {},
|
|
76278
76515
|
open: [
|
|
76279
76516
|
...withSource ? [`himi import ${res.out}`] : [],
|
|
76280
76517
|
`himi run ${res.out}`,
|
|
@@ -76304,7 +76541,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76304
76541
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
76305
76542
|
let opened;
|
|
76306
76543
|
try {
|
|
76307
|
-
opened = openPackageFile2(
|
|
76544
|
+
opened = openPackageFile2(resolve52(file));
|
|
76308
76545
|
} catch (e) {
|
|
76309
76546
|
io.error(JSON.stringify({ error: e.message }));
|
|
76310
76547
|
return 1;
|
|
@@ -76317,7 +76554,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76317
76554
|
io.error(JSON.stringify({
|
|
76318
76555
|
ok: false,
|
|
76319
76556
|
error: "app_source_not_in_package",
|
|
76320
|
-
detail: `${
|
|
76557
|
+
detail: `${resolve52(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
76321
76558
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
76322
76559
|
}));
|
|
76323
76560
|
return 1;
|
|
@@ -76340,7 +76577,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76340
76577
|
return 1;
|
|
76341
76578
|
}
|
|
76342
76579
|
}
|
|
76343
|
-
const dest =
|
|
76580
|
+
const dest = resolve52(str8(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
76344
76581
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
76345
76582
|
if (issue2) {
|
|
76346
76583
|
io.error(JSON.stringify(issue2));
|
|
@@ -76379,7 +76616,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76379
76616
|
return 1;
|
|
76380
76617
|
}
|
|
76381
76618
|
const left = staleSourcePaths2(restored, dest);
|
|
76382
|
-
const
|
|
76619
|
+
const refused2 = deniedArchivePaths2(restored);
|
|
76383
76620
|
const written = writeAppSource2(restored, dest);
|
|
76384
76621
|
const agent = await seedAgentFilesFor(dest, flags, "restore");
|
|
76385
76622
|
print({
|
|
@@ -76390,8 +76627,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76390
76627
|
files: written.length,
|
|
76391
76628
|
...agent,
|
|
76392
76629
|
...renamed ? { renamedTo: renamed } : {},
|
|
76393
|
-
...
|
|
76394
|
-
refused,
|
|
76630
|
+
...refused2.length ? {
|
|
76631
|
+
refused: refused2,
|
|
76395
76632
|
refusedNote: "this package carries paths a restore will not write (the deny-list has grown since it was packed) \u2014 they were skipped, not written over"
|
|
76396
76633
|
} : {},
|
|
76397
76634
|
...left.length ? {
|
|
@@ -76427,7 +76664,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76427
76664
|
}
|
|
76428
76665
|
try {
|
|
76429
76666
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
76430
|
-
const opened = openPackageFile2(
|
|
76667
|
+
const opened = openPackageFile2(resolve52(file));
|
|
76431
76668
|
if (!opened.validation.ok || !opened.header) {
|
|
76432
76669
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
76433
76670
|
return 1;
|
|
@@ -76437,12 +76674,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76437
76674
|
io.error(JSON.stringify({
|
|
76438
76675
|
ok: false,
|
|
76439
76676
|
error: "refusing to share a package that carries the app's source",
|
|
76440
|
-
detail: `${
|
|
76677
|
+
detail: `${resolve52(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
|
|
76441
76678
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
76442
76679
|
}));
|
|
76443
76680
|
return 1;
|
|
76444
76681
|
}
|
|
76445
|
-
const archive = readFileSync79(
|
|
76682
|
+
const archive = readFileSync79(resolve52(file));
|
|
76446
76683
|
const result = await client2().createPackageShare({
|
|
76447
76684
|
app: opened.header.app,
|
|
76448
76685
|
releaseId: opened.header.releaseId,
|
|
@@ -76581,9 +76818,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76581
76818
|
});
|
|
76582
76819
|
await announce(run2);
|
|
76583
76820
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
76584
|
-
await new Promise((
|
|
76821
|
+
await new Promise((resolve53) => {
|
|
76585
76822
|
const stop = () => {
|
|
76586
|
-
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() =>
|
|
76823
|
+
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() => resolve53()));
|
|
76587
76824
|
};
|
|
76588
76825
|
process.once("SIGINT", stop);
|
|
76589
76826
|
process.once("SIGTERM", stop);
|
|
@@ -78623,13 +78860,13 @@ ${label2}`);
|
|
|
78623
78860
|
// advertisable for the target this report is about.
|
|
78624
78861
|
hasOwnerIssuer: (resolved2?.ownerIssue ?? "") !== ""
|
|
78625
78862
|
});
|
|
78626
|
-
const
|
|
78627
|
-
if (targetError)
|
|
78863
|
+
const report3 = buildDoctorReport({ target, version: cliVersion(), data, serve, auth, loginModes, dpxStatus, versions });
|
|
78864
|
+
if (targetError) report3.targetError = targetError;
|
|
78628
78865
|
const { agentContextStatus: agentContextStatus2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
78629
78866
|
const agentContext = agentContextStatus2(contentDir(flags), cliVersion());
|
|
78630
|
-
if (agentContext)
|
|
78867
|
+
if (agentContext) report3.agentContext = agentContext;
|
|
78631
78868
|
if (flags.json === true) {
|
|
78632
|
-
print(
|
|
78869
|
+
print(report3);
|
|
78633
78870
|
return 0;
|
|
78634
78871
|
}
|
|
78635
78872
|
const mark = (r) => r.reachable ? `reachable${r.status ? ` [${r.status}]` : ""}` : `UNREACHABLE${r.error ? ` (${r.error})` : ""}`;
|
|
@@ -78639,7 +78876,7 @@ ${label2}`);
|
|
|
78639
78876
|
io.log(` ${mark(data)}`);
|
|
78640
78877
|
io.log(` serve plane ${serveUrl || "(no serve url)"}`);
|
|
78641
78878
|
io.log(` ${mark(serve)}`);
|
|
78642
|
-
const serveCode =
|
|
78879
|
+
const serveCode = report3.servePlane.code;
|
|
78643
78880
|
if (serveCode) io.log(` ${serveCode}: ${serveUnreachableHint(target)}`);
|
|
78644
78881
|
io.log(` auth dpx session: ${auth.dpxSession ? "yes" : "no"} control token: ${auth.controlToken ? "yes" : controlHostRefused ? "REFUSED" : auth.controlTokenPresent ? "STALE" : "no"}`);
|
|
78645
78882
|
if (auth.controlTokenHint) io.log(` ${auth.controlTokenHint}`);
|
|
@@ -78662,7 +78899,7 @@ ${label2}`);
|
|
|
78662
78899
|
}
|
|
78663
78900
|
io.log(
|
|
78664
78901
|
`
|
|
78665
|
-
${
|
|
78902
|
+
${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint === "string" && report3.hint ? report3.hint : serve.reachable ? "Data plane unreachable \u2014 check basic connectivity." : serveUnreachableHint(target)}`
|
|
78666
78903
|
);
|
|
78667
78904
|
return 0;
|
|
78668
78905
|
}
|
|
@@ -78775,9 +79012,9 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78775
79012
|
}
|
|
78776
79013
|
const scope = { app, siteId: site, environment: environment2 };
|
|
78777
79014
|
try {
|
|
78778
|
-
const
|
|
78779
|
-
print(
|
|
78780
|
-
return
|
|
79015
|
+
const report3 = sub === "plan" ? await planData({ scope, data, kv, call }) : sub === "create" ? await createData({ scope, data, kv, call, dryRun: flags["dry-run"] === true }) : await seedData({ scope, data, kv, call, dir, dryRun: flags["dry-run"] === true, force: flags.force === true });
|
|
79016
|
+
print(report3);
|
|
79017
|
+
return report3.ok ? 0 : 1;
|
|
78781
79018
|
} catch (error) {
|
|
78782
79019
|
io.error(JSON.stringify({ error: error.message, app, site, environment: environment2, hint: "run `himi data plan` to re-read actual state before retrying" }));
|
|
78783
79020
|
return 1;
|
|
@@ -78792,6 +79029,14 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78792
79029
|
const { runNotifySetup: runNotifySetup2 } = await Promise.resolve().then(() => (init_notify_setup(), notify_setup_exports));
|
|
78793
79030
|
return runNotifySetup2(pos, flags, io);
|
|
78794
79031
|
}
|
|
79032
|
+
if (pos[1] === "send" && flags.provider !== void 0) {
|
|
79033
|
+
if (flags.provider !== "ping") {
|
|
79034
|
+
io.error(JSON.stringify({ ok: false, error: "unknown_provider", hint: "The hosted sender is --provider ping." }));
|
|
79035
|
+
return 2;
|
|
79036
|
+
}
|
|
79037
|
+
const { runNotifyPing: runNotifyPing2 } = await Promise.resolve().then(() => (init_notify_ping(), notify_ping_exports));
|
|
79038
|
+
return runNotifyPing2(flags, io);
|
|
79039
|
+
}
|
|
78795
79040
|
const { runNotify: runNotify2 } = await Promise.resolve().then(() => (init_notify(), notify_exports));
|
|
78796
79041
|
return await runNotify2(pos, flags, io);
|
|
78797
79042
|
case "cms": {
|
|
@@ -78850,9 +79095,9 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78850
79095
|
return 2;
|
|
78851
79096
|
}
|
|
78852
79097
|
const common = { app, cms, call };
|
|
78853
|
-
let
|
|
79098
|
+
let report3;
|
|
78854
79099
|
try {
|
|
78855
|
-
|
|
79100
|
+
report3 = sub === "query" ? await queryCms({ ...common, all: flags.all === true }) : sub === "create" ? await createCms({ ...common, dryRun: flags["dry-run"] === true, allowDestructive: flags["allow-destructive"] === true, applyPermissions: flags["apply-permissions"] === true }) : await seedCms({ ...common, dir, dryRun: flags["dry-run"] === true, force: flags.force === true, only: str8(flags.only) });
|
|
78856
79101
|
} catch (e) {
|
|
78857
79102
|
const partial = e.partial;
|
|
78858
79103
|
io.error(JSON.stringify({
|
|
@@ -78864,8 +79109,8 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78864
79109
|
}));
|
|
78865
79110
|
return 1;
|
|
78866
79111
|
}
|
|
78867
|
-
print({ ...
|
|
78868
|
-
return
|
|
79112
|
+
print({ ...report3, site });
|
|
79113
|
+
return report3.ok ? 0 : 1;
|
|
78869
79114
|
}
|
|
78870
79115
|
case "site": {
|
|
78871
79116
|
const sub = pos[1];
|