@wix/himalaya-cli 0.1110.0 → 0.1111.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 +905 -662
- 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
|
}
|
|
@@ -54097,14 +54114,14 @@ ${log}` : ""}`, true);
|
|
|
54097
54114
|
}
|
|
54098
54115
|
];
|
|
54099
54116
|
}
|
|
54100
|
-
var MAX_TEXT2, clip,
|
|
54117
|
+
var MAX_TEXT2, clip, text6, json3, opt, sw, DIR, LEARN, CHECK, LOCAL_WRITE, PUBLISH, PREVIEW_HINT, LOGIN_HINT;
|
|
54101
54118
|
var init_tools = __esm({
|
|
54102
54119
|
"src/mcp/tools.ts"() {
|
|
54103
54120
|
MAX_TEXT2 = 8e4;
|
|
54104
54121
|
clip = (s) => s.length <= MAX_TEXT2 ? s : `${s.slice(0, MAX_TEXT2)}
|
|
54105
54122
|
\u2026 [truncated ${s.length - MAX_TEXT2} chars \u2014 re-run the command in a terminal for the full output]`;
|
|
54106
|
-
|
|
54107
|
-
json3 = (o) =>
|
|
54123
|
+
text6 = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...isError ? { isError: true } : {} });
|
|
54124
|
+
json3 = (o) => text6(JSON.stringify(o, null, 2));
|
|
54108
54125
|
opt = (flag, v) => typeof v === "string" && v ? [flag, v] : typeof v === "number" ? [flag, String(v)] : [];
|
|
54109
54126
|
sw = (flag, v) => v === true ? [flag] : [];
|
|
54110
54127
|
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 +54197,9 @@ async function startMcpServer(opts) {
|
|
|
54180
54197
|
},
|
|
54181
54198
|
readFile: (p) => readFileSync59(p)
|
|
54182
54199
|
};
|
|
54183
|
-
const closed = new Promise((
|
|
54184
|
-
stdin.once("end",
|
|
54185
|
-
stdin.once("close",
|
|
54200
|
+
const closed = new Promise((resolve53) => {
|
|
54201
|
+
stdin.once("end", resolve53);
|
|
54202
|
+
stdin.once("close", resolve53);
|
|
54186
54203
|
});
|
|
54187
54204
|
const handle = serveStdio(
|
|
54188
54205
|
() => {
|
|
@@ -54424,7 +54441,7 @@ function fieldAt(path2) {
|
|
|
54424
54441
|
if (path2 === null) return void 0;
|
|
54425
54442
|
return path2.match(/\.([^.[\]]+)$/)?.[1];
|
|
54426
54443
|
}
|
|
54427
|
-
function mergeNativeDecode(
|
|
54444
|
+
function mergeNativeDecode(report3, run2) {
|
|
54428
54445
|
const platformLabel = run2.platform === "ios" ? "iOS" : "Android";
|
|
54429
54446
|
const nativeFailures = run2.verdicts.flatMap((verdict) => verdict.errors.map((error) => ({
|
|
54430
54447
|
screen: verdict.screenId,
|
|
@@ -54437,18 +54454,18 @@ function mergeNativeDecode(report2, run2) {
|
|
|
54437
54454
|
...error.actual ? { actual: error.actual } : {},
|
|
54438
54455
|
hint: `This descriptor ships as a full-screen \u201CCouldn't load\u201D; fix the typed field and rerun \`himi test --native ${run2.platform}\`.`
|
|
54439
54456
|
})));
|
|
54440
|
-
const failures = [...
|
|
54457
|
+
const failures = [...report3.failures, ...nativeFailures];
|
|
54441
54458
|
const failedScreens = new Set(failures.map((finding) => finding.screen));
|
|
54442
54459
|
return {
|
|
54443
|
-
...
|
|
54444
|
-
ok:
|
|
54460
|
+
...report3,
|
|
54461
|
+
ok: report3.ok && nativeFailures.length === 0,
|
|
54445
54462
|
failures,
|
|
54446
|
-
counts: { ...
|
|
54447
|
-
screens: { ...
|
|
54463
|
+
counts: { ...report3.counts, errors: failures.length },
|
|
54464
|
+
screens: { ...report3.screens, clean: report3.screens.total - failedScreens.size, failed: failedScreens.size },
|
|
54448
54465
|
nativeDecode: {
|
|
54449
|
-
...
|
|
54466
|
+
...report3.nativeDecode,
|
|
54450
54467
|
[run2.platform]: { checked: run2.verdicts.length, failed: run2.verdicts.filter((verdict) => !verdict.ok).length },
|
|
54451
|
-
wallMs: (
|
|
54468
|
+
wallMs: (report3.nativeDecode?.wallMs ?? 0) + run2.wallMs
|
|
54452
54469
|
}
|
|
54453
54470
|
};
|
|
54454
54471
|
}
|
|
@@ -54561,10 +54578,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
54561
54578
|
for (const source of Object.values(files)) visit(source);
|
|
54562
54579
|
return { modules, unsupported };
|
|
54563
54580
|
}
|
|
54564
|
-
function sdkSubpathReader(
|
|
54581
|
+
function sdkSubpathReader(resolve53) {
|
|
54565
54582
|
return (sub) => {
|
|
54566
54583
|
try {
|
|
54567
|
-
return readFileSync61(
|
|
54584
|
+
return readFileSync61(resolve53(`@wix/himalaya/${sub}`), "utf8");
|
|
54568
54585
|
} catch {
|
|
54569
54586
|
return null;
|
|
54570
54587
|
}
|
|
@@ -54642,7 +54659,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
54642
54659
|
const token = mintToken2(payload);
|
|
54643
54660
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
54644
54661
|
if (unusable) throw new Error(unusable);
|
|
54645
|
-
return await new Promise((
|
|
54662
|
+
return await new Promise((resolve53, reject) => {
|
|
54646
54663
|
let settled = false;
|
|
54647
54664
|
let url = "";
|
|
54648
54665
|
const server = createServer5();
|
|
@@ -54693,8 +54710,8 @@ async function runBrowserAuthoring(opts) {
|
|
|
54693
54710
|
return;
|
|
54694
54711
|
}
|
|
54695
54712
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
54696
|
-
const
|
|
54697
|
-
finish2(() =>
|
|
54713
|
+
const report3 = body.result;
|
|
54714
|
+
finish2(() => resolve53({ report: report3, url }));
|
|
54698
54715
|
})();
|
|
54699
54716
|
});
|
|
54700
54717
|
server.on("error", (e) => finish2(() => reject(e)));
|
|
@@ -55371,10 +55388,10 @@ async function hostedAuthUrl(req, visitorToken, fetchImpl = fetch) {
|
|
|
55371
55388
|
}
|
|
55372
55389
|
})
|
|
55373
55390
|
});
|
|
55374
|
-
const
|
|
55391
|
+
const text8 = await res.text();
|
|
55375
55392
|
let parsed = {};
|
|
55376
55393
|
try {
|
|
55377
|
-
parsed =
|
|
55394
|
+
parsed = text8 ? JSON.parse(text8) : {};
|
|
55378
55395
|
} catch {
|
|
55379
55396
|
}
|
|
55380
55397
|
const fullUrl = parsed.redirectSession?.fullUrl;
|
|
@@ -55394,10 +55411,10 @@ async function exchangeAuthCode(cfg, code, verifier, fetchImpl = fetch) {
|
|
|
55394
55411
|
redirectUri: cfg.redirectUri
|
|
55395
55412
|
})
|
|
55396
55413
|
});
|
|
55397
|
-
const
|
|
55414
|
+
const text8 = await res.text();
|
|
55398
55415
|
let parsed = {};
|
|
55399
55416
|
try {
|
|
55400
|
-
parsed =
|
|
55417
|
+
parsed = text8 ? JSON.parse(text8) : {};
|
|
55401
55418
|
} catch {
|
|
55402
55419
|
}
|
|
55403
55420
|
if (res.status !== 200 || !parsed.access_token) throw new Error(`token exchange failed (${res.status})`);
|
|
@@ -56611,11 +56628,11 @@ async function localizeConfigResponse(res, kind, header) {
|
|
|
56611
56628
|
header
|
|
56612
56629
|
)
|
|
56613
56630
|
};
|
|
56614
|
-
const
|
|
56631
|
+
const text8 = JSON.stringify(next);
|
|
56615
56632
|
const headers2 = new Headers(res.headers);
|
|
56616
56633
|
headers2.delete("etag");
|
|
56617
|
-
headers2.set("content-length", String(new TextEncoder().encode(
|
|
56618
|
-
return new Response(
|
|
56634
|
+
headers2.set("content-length", String(new TextEncoder().encode(text8).length));
|
|
56635
|
+
return new Response(text8, { status: 200, headers: headers2 });
|
|
56619
56636
|
}
|
|
56620
56637
|
function makeRunHandler(opts) {
|
|
56621
56638
|
const mount = opts.chrome === "app" ? "/app" : "/preview";
|
|
@@ -56803,8 +56820,8 @@ var init_node_adapter = __esm({
|
|
|
56803
56820
|
function authConfigOf(appConfig) {
|
|
56804
56821
|
if (!appConfig) return void 0;
|
|
56805
56822
|
try {
|
|
56806
|
-
const
|
|
56807
|
-
return JSON.parse(
|
|
56823
|
+
const text8 = typeof appConfig === "string" ? appConfig : new TextDecoder().decode(appConfig);
|
|
56824
|
+
return JSON.parse(text8)?.authConfig ?? void 0;
|
|
56808
56825
|
} catch {
|
|
56809
56826
|
return void 0;
|
|
56810
56827
|
}
|
|
@@ -57414,16 +57431,16 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57414
57431
|
const manifest = await store.getManifest(app);
|
|
57415
57432
|
if (!manifest) throw new Error(`no release manifest for ${app} under ${root}`);
|
|
57416
57433
|
const b64 = (b) => b ? Buffer.from(b).toString("base64") : void 0;
|
|
57417
|
-
const
|
|
57434
|
+
const text8 = (b) => b ? new TextDecoder().decode(b) : void 0;
|
|
57418
57435
|
const screens = {};
|
|
57419
57436
|
const docs = {};
|
|
57420
57437
|
const addDoc = async (hash) => {
|
|
57421
57438
|
if (!hash || docs[hash] !== void 0) return;
|
|
57422
|
-
const d =
|
|
57439
|
+
const d = text8(await store.getDoc?.(app, hash) ?? null);
|
|
57423
57440
|
if (d !== void 0) docs[hash] = d;
|
|
57424
57441
|
};
|
|
57425
57442
|
for (const [id, meta] of Object.entries(manifest.screens ?? {})) {
|
|
57426
|
-
const s =
|
|
57443
|
+
const s = text8(await store.getScreen(app, id));
|
|
57427
57444
|
if (s !== void 0) screens[id] = s;
|
|
57428
57445
|
await addDoc(meta.descriptorHash);
|
|
57429
57446
|
}
|
|
@@ -57444,10 +57461,10 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57444
57461
|
}
|
|
57445
57462
|
const widgets = {};
|
|
57446
57463
|
for (const id of Object.keys(manifest.widgets ?? {})) {
|
|
57447
|
-
const w =
|
|
57464
|
+
const w = text8(await store.getWidget?.(app, id) ?? null);
|
|
57448
57465
|
if (w !== void 0) widgets[id] = w;
|
|
57449
57466
|
}
|
|
57450
|
-
const appConfig =
|
|
57467
|
+
const appConfig = text8(await store.getAppConfig(app));
|
|
57451
57468
|
const wixClientId = appConfigWixClientId(appConfig);
|
|
57452
57469
|
return {
|
|
57453
57470
|
app,
|
|
@@ -57457,7 +57474,7 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
57457
57474
|
docs,
|
|
57458
57475
|
assets,
|
|
57459
57476
|
widgets,
|
|
57460
|
-
tokens:
|
|
57477
|
+
tokens: text8(await store.getTokens(app)),
|
|
57461
57478
|
appConfig,
|
|
57462
57479
|
icon: b64(await store.getIcon?.(app) ?? null),
|
|
57463
57480
|
header,
|
|
@@ -57987,10 +58004,10 @@ function scalar3(v) {
|
|
|
57987
58004
|
}
|
|
57988
58005
|
return t;
|
|
57989
58006
|
}
|
|
57990
|
-
function parseStoreConfig(
|
|
58007
|
+
function parseStoreConfig(text8) {
|
|
57991
58008
|
const cfg = {};
|
|
57992
58009
|
let section2 = null;
|
|
57993
|
-
for (const raw of
|
|
58010
|
+
for (const raw of text8.split("\n")) {
|
|
57994
58011
|
const line = strip2(raw);
|
|
57995
58012
|
if (!line.trim()) continue;
|
|
57996
58013
|
const indented = /^\s+/.test(raw);
|
|
@@ -58049,10 +58066,10 @@ function profilePath(name, home = homedir5()) {
|
|
|
58049
58066
|
}
|
|
58050
58067
|
return join59(credentialsDir(home), `${name}.json`);
|
|
58051
58068
|
}
|
|
58052
|
-
function parseProfile(
|
|
58069
|
+
function parseProfile(text8, label2) {
|
|
58053
58070
|
let doc;
|
|
58054
58071
|
try {
|
|
58055
|
-
doc = JSON.parse(
|
|
58072
|
+
doc = JSON.parse(text8);
|
|
58056
58073
|
} catch (e) {
|
|
58057
58074
|
throw new Error(`${label2} is not valid JSON: ${e.message}`);
|
|
58058
58075
|
}
|
|
@@ -58661,11 +58678,11 @@ async function registerBundleId(opts) {
|
|
|
58661
58678
|
const j = await res.json();
|
|
58662
58679
|
return { status: "created", id: j.data?.id };
|
|
58663
58680
|
}
|
|
58664
|
-
const
|
|
58665
|
-
if (res.status === 409 || /already (exists|in use)|duplicate|ENTITY_ERROR.*identifier/i.test(
|
|
58681
|
+
const text8 = await res.text();
|
|
58682
|
+
if (res.status === 409 || /already (exists|in use)|duplicate|ENTITY_ERROR.*identifier/i.test(text8)) {
|
|
58666
58683
|
return { status: "exists" };
|
|
58667
58684
|
}
|
|
58668
|
-
throw new Error(`POST /v1/bundleIds \u2192 ${res.status}: ${
|
|
58685
|
+
throw new Error(`POST /v1/bundleIds \u2192 ${res.status}: ${text8.slice(0, 300)}`);
|
|
58669
58686
|
}
|
|
58670
58687
|
async function main2() {
|
|
58671
58688
|
const [app, ...rest] = process.argv.slice(2);
|
|
@@ -58943,12 +58960,12 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
58943
58960
|
body = JSON.stringify({ value });
|
|
58944
58961
|
}
|
|
58945
58962
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
58946
|
-
const
|
|
58963
|
+
const text8 = await response.text();
|
|
58947
58964
|
let output;
|
|
58948
58965
|
try {
|
|
58949
|
-
output = JSON.parse(
|
|
58966
|
+
output = JSON.parse(text8);
|
|
58950
58967
|
} catch {
|
|
58951
|
-
output =
|
|
58968
|
+
output = text8;
|
|
58952
58969
|
}
|
|
58953
58970
|
if (!response.ok) throw new Error(typeof output === "string" ? output : JSON.stringify(output));
|
|
58954
58971
|
io.log(JSON.stringify(output));
|
|
@@ -58964,6 +58981,217 @@ var init_secrets2 = __esm({
|
|
|
58964
58981
|
}
|
|
58965
58982
|
});
|
|
58966
58983
|
|
|
58984
|
+
// ../serve-cli/src/push-send.ts
|
|
58985
|
+
async function pushSendRequest(options) {
|
|
58986
|
+
const refusal = localRefusal(options);
|
|
58987
|
+
if (refusal) return { ok: false, status: 0, body: null, error: refusal };
|
|
58988
|
+
try {
|
|
58989
|
+
const response = await (options.fetchImpl ?? fetch)(`${options.target.control.replace(/\/+$/, "")}/v1/admin/push/send`, {
|
|
58990
|
+
method: "POST",
|
|
58991
|
+
headers: headersFor(options),
|
|
58992
|
+
redirect: "error",
|
|
58993
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
58994
|
+
body: JSON.stringify(options.body)
|
|
58995
|
+
});
|
|
58996
|
+
const retryAfterSec = response.status === 429 ? Number(response.headers.get("retry-after")) : NaN;
|
|
58997
|
+
return {
|
|
58998
|
+
ok: response.ok,
|
|
58999
|
+
status: response.status,
|
|
59000
|
+
body: objectFrom(await response.text()),
|
|
59001
|
+
...Number.isFinite(retryAfterSec) && retryAfterSec > 0 ? { retryAfterSec } : {}
|
|
59002
|
+
};
|
|
59003
|
+
} catch {
|
|
59004
|
+
return { ok: false, status: 0, body: null, error: "push_send_unreachable" };
|
|
59005
|
+
}
|
|
59006
|
+
}
|
|
59007
|
+
function localRefusal(options) {
|
|
59008
|
+
if (!options.target.controlToken) return "control_token_required";
|
|
59009
|
+
if (!options.wixToken) return "wix_account_token_required";
|
|
59010
|
+
if (!options.siteToken) return "site_token_required";
|
|
59011
|
+
if (credentialHostRefusal(options.target.control)) return "insecure_target";
|
|
59012
|
+
if (options.previewTag !== void 0 && !PREVIEW_TAG2.test(options.previewTag)) return "invalid_preview_tag";
|
|
59013
|
+
return void 0;
|
|
59014
|
+
}
|
|
59015
|
+
function headersFor(options) {
|
|
59016
|
+
return {
|
|
59017
|
+
"x-control-token": options.target.controlToken,
|
|
59018
|
+
// RAW, never `Bearer ` — what normalizeWixAuthorization and token-info expect.
|
|
59019
|
+
Authorization: options.wixToken,
|
|
59020
|
+
[SITE_TOKEN_HEADER]: options.siteToken,
|
|
59021
|
+
accept: "application/json",
|
|
59022
|
+
"content-type": "application/json",
|
|
59023
|
+
...options.previewTag ? { "x-wix-route-serve": options.previewTag } : {}
|
|
59024
|
+
};
|
|
59025
|
+
}
|
|
59026
|
+
function objectFrom(text8) {
|
|
59027
|
+
try {
|
|
59028
|
+
const value = text8 ? JSON.parse(text8) : null;
|
|
59029
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
59030
|
+
} catch {
|
|
59031
|
+
return null;
|
|
59032
|
+
}
|
|
59033
|
+
}
|
|
59034
|
+
var SITE_TOKEN_HEADER, PREVIEW_TAG2, TIMEOUT_MS;
|
|
59035
|
+
var init_push_send = __esm({
|
|
59036
|
+
"../serve-cli/src/push-send.ts"() {
|
|
59037
|
+
init_credential_hosts();
|
|
59038
|
+
SITE_TOKEN_HEADER = "x-himi-site-token";
|
|
59039
|
+
PREVIEW_TAG2 = /^dp-[a-z0-9]+$/;
|
|
59040
|
+
TIMEOUT_MS = 6e4;
|
|
59041
|
+
}
|
|
59042
|
+
});
|
|
59043
|
+
|
|
59044
|
+
// ../../core/serve-control/src/push-send-service.ts
|
|
59045
|
+
var PUSH_SEND_ERROR_CODES;
|
|
59046
|
+
var init_push_send_service = __esm({
|
|
59047
|
+
"../../core/serve-control/src/push-send-service.ts"() {
|
|
59048
|
+
PUSH_SEND_ERROR_CODES = [
|
|
59049
|
+
"unauthorized",
|
|
59050
|
+
"token_revoked",
|
|
59051
|
+
"revocation_check_unavailable",
|
|
59052
|
+
"method_not_allowed",
|
|
59053
|
+
"rate_limited",
|
|
59054
|
+
"forbidden_cross_tenant",
|
|
59055
|
+
"forbidden_site",
|
|
59056
|
+
"site_check_unavailable",
|
|
59057
|
+
"push_send_unconfigured",
|
|
59058
|
+
"push_send_unavailable",
|
|
59059
|
+
"invalid_input",
|
|
59060
|
+
"payload_too_large",
|
|
59061
|
+
"unknown_field",
|
|
59062
|
+
"invalid_app_id",
|
|
59063
|
+
"invalid_site_id",
|
|
59064
|
+
"invalid_member_email",
|
|
59065
|
+
"invalid_title",
|
|
59066
|
+
"invalid_body",
|
|
59067
|
+
"invalid_link",
|
|
59068
|
+
"invalid_request_id",
|
|
59069
|
+
"invalid_dry_run",
|
|
59070
|
+
"link_not_routable",
|
|
59071
|
+
"app_config_unavailable",
|
|
59072
|
+
"push_not_ready",
|
|
59073
|
+
"site_token_required",
|
|
59074
|
+
"site_token_invalid",
|
|
59075
|
+
"site_token_unverifiable",
|
|
59076
|
+
"member_not_found",
|
|
59077
|
+
"member_ambiguous",
|
|
59078
|
+
"member_not_active",
|
|
59079
|
+
"member_read_forbidden",
|
|
59080
|
+
"member_lookup_unavailable",
|
|
59081
|
+
"ping_unconfigured",
|
|
59082
|
+
"ping_permission_denied",
|
|
59083
|
+
"ping_rejected",
|
|
59084
|
+
"ping_rate_limited",
|
|
59085
|
+
"send_outcome_unknown"
|
|
59086
|
+
];
|
|
59087
|
+
}
|
|
59088
|
+
});
|
|
59089
|
+
|
|
59090
|
+
// src/notify-ping.ts
|
|
59091
|
+
var notify_ping_exports = {};
|
|
59092
|
+
__export(notify_ping_exports, {
|
|
59093
|
+
runNotifyPing: () => runNotifyPing
|
|
59094
|
+
});
|
|
59095
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
59096
|
+
import { resolve as resolve49 } from "node:path";
|
|
59097
|
+
function refuse4(io, error, hint, exit = 2, extra = {}) {
|
|
59098
|
+
io.error(JSON.stringify({ ok: false, error, ...hint ? { hint } : {}, ...extra }));
|
|
59099
|
+
return exit;
|
|
59100
|
+
}
|
|
59101
|
+
async function runNotifyPing(flags, io, deps = {}) {
|
|
59102
|
+
const flagError = flagRefusal(flags);
|
|
59103
|
+
if (flagError) return refuse4(io, flagError);
|
|
59104
|
+
const input = mergePushInputs(pushInputsFromContent(resolve49(text7(flags.content) ?? process.cwd())), flags);
|
|
59105
|
+
const missing = [...input.app ? [] : ["app"], ...input.site ? [] : ["site"], ...REQUIRED_FLAGS.filter((f) => !text7(flags[f]))];
|
|
59106
|
+
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 });
|
|
59107
|
+
const requestId2 = text7(flags["request-id"]) ?? (deps.newRequestId ?? randomUUID5)();
|
|
59108
|
+
if (!UUID_RE.test(requestId2)) return refuse4(io, "invalid_request_id", "Reuse the requestId a previous send printed.");
|
|
59109
|
+
const owner = await hostedOwnerSession(flags, deps);
|
|
59110
|
+
if (!owner.ok) return refuse4(io, owner.error, owner.hint, owner.exit);
|
|
59111
|
+
const { session } = owner;
|
|
59112
|
+
const ownership = await verifyAppOwnership({ ownerIssue: session.ownerIssue, controlToken: session.controlToken, declaredName: input.app, fetchImpl: deps.fetchImpl });
|
|
59113
|
+
if (ownership.state !== "owned") return refuse4(io, `app_ownership_${ownership.state}`, "Sending requires the app owner.", 1);
|
|
59114
|
+
let siteToken2;
|
|
59115
|
+
try {
|
|
59116
|
+
siteToken2 = await (deps.siteToken ?? siteToken)(input.site);
|
|
59117
|
+
} catch {
|
|
59118
|
+
return refuse4(io, "wix_site_token_required", "Run wix login as the site owner; the site token reads this site's members.", 1);
|
|
59119
|
+
}
|
|
59120
|
+
const body = {
|
|
59121
|
+
app: ownership.slug,
|
|
59122
|
+
site: input.site,
|
|
59123
|
+
memberEmail: text7(flags["member-email"]),
|
|
59124
|
+
title: text7(flags.title),
|
|
59125
|
+
...text7(flags.body) ? { body: text7(flags.body) } : {},
|
|
59126
|
+
link: text7(flags.link),
|
|
59127
|
+
requestId: requestId2,
|
|
59128
|
+
...flags["dry-run"] === true ? { dryRun: true } : {}
|
|
59129
|
+
};
|
|
59130
|
+
const http = await pushSendRequest({ target: session.target, wixToken: session.wixToken, siteToken: siteToken2, body, previewTag: session.previewTag, fetchImpl: deps.fetchImpl });
|
|
59131
|
+
return report2(http, body, flags, io);
|
|
59132
|
+
}
|
|
59133
|
+
function flagRefusal(flags) {
|
|
59134
|
+
if (LOCAL_SENDER_FLAGS.some((f) => flags[f] !== void 0)) return "flag_not_supported_with_ping";
|
|
59135
|
+
if (SWITCHES.some((f) => flags[f] !== void 0 && typeof flags[f] !== "boolean")) return "invalid_boolean_flag";
|
|
59136
|
+
return void 0;
|
|
59137
|
+
}
|
|
59138
|
+
function report2(http, sent, flags, io) {
|
|
59139
|
+
const code = refusalCode(http);
|
|
59140
|
+
if (code === "send_outcome_unknown") {
|
|
59141
|
+
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 });
|
|
59142
|
+
}
|
|
59143
|
+
if (code === "rate_limited" && http.retryAfterSec) {
|
|
59144
|
+
return refuse4(io, code, `Test sends are limited per owner; retry in ${http.retryAfterSec} seconds.`, 1, { retryAfterSec: http.retryAfterSec });
|
|
59145
|
+
}
|
|
59146
|
+
if (code) return refuse4(io, code, HINTS[code], 1);
|
|
59147
|
+
if (flags.json === true) io.log(JSON.stringify(http.body, null, 2));
|
|
59148
|
+
else io.log(summary(http.body ?? {}, sent));
|
|
59149
|
+
return 0;
|
|
59150
|
+
}
|
|
59151
|
+
function refusalCode(http) {
|
|
59152
|
+
if (http.error) return http.error === "push_send_unreachable" ? "send_outcome_unknown" : http.error;
|
|
59153
|
+
if (http.ok && (http.body?.state === "accepted" || http.body?.state === "dry_run")) return void 0;
|
|
59154
|
+
const code = String(http.body?.error ?? "");
|
|
59155
|
+
if (KNOWN_CODES.has(code)) return code;
|
|
59156
|
+
return http.ok || http.status >= 500 ? "send_outcome_unknown" : "push_send_failed";
|
|
59157
|
+
}
|
|
59158
|
+
function summary(result, sent) {
|
|
59159
|
+
if (result.state === "dry_run") {
|
|
59160
|
+
return `Dry run passed: ${sent.memberEmail} is an approved member, the link routes, and push is ready for ${sent.app}. No notification was sent.`;
|
|
59161
|
+
}
|
|
59162
|
+
if (result.deduplicated === true) {
|
|
59163
|
+
return `Ping already ran request ${sent.requestId}; the earlier send stands and no second notification was sent.`;
|
|
59164
|
+
}
|
|
59165
|
+
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.`;
|
|
59166
|
+
}
|
|
59167
|
+
var LOCAL_SENDER_FLAGS, SWITCHES, REQUIRED_FLAGS, UUID_RE, KNOWN_CODES, HINTS, text7;
|
|
59168
|
+
var init_notify_ping = __esm({
|
|
59169
|
+
"src/notify-ping.ts"() {
|
|
59170
|
+
init_push_send();
|
|
59171
|
+
init_push_send_service();
|
|
59172
|
+
init_hosted_owner();
|
|
59173
|
+
init_owner_claim();
|
|
59174
|
+
init_push_onboarding();
|
|
59175
|
+
init_wix_owner();
|
|
59176
|
+
LOCAL_SENDER_FLAGS = ["token", "device", "all", "admin-url", "admin-session", "silent", "badge", "data", "category", "channel", "platform", "bundle-id"];
|
|
59177
|
+
SWITCHES = ["json", "dry-run"];
|
|
59178
|
+
REQUIRED_FLAGS = ["member-email", "title", "link"];
|
|
59179
|
+
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
59180
|
+
KNOWN_CODES = new Set(PUSH_SEND_ERROR_CODES);
|
|
59181
|
+
HINTS = {
|
|
59182
|
+
push_not_ready: "Run himi notify setup for this app and site first; status must be ready.",
|
|
59183
|
+
member_not_found: "Use the login email of an approved member of this site.",
|
|
59184
|
+
member_ambiguous: "More than one member has this login email; resolve it in the site's Members.",
|
|
59185
|
+
member_not_active: "The member must be approved before they can be notified.",
|
|
59186
|
+
link_not_routable: "Link to a screen this app's published release ships, e.g. <scheme>://screen/<screenId>?id=\u2026.",
|
|
59187
|
+
forbidden_site: "The Wix account from wix login must own this site.",
|
|
59188
|
+
site_token_invalid: "Run wix login as the site owner; the site token must belong to the app owner's account.",
|
|
59189
|
+
ping_permission_denied: "Himi Serve is not permitted to send through Ping; this is a platform issue, not your setup."
|
|
59190
|
+
};
|
|
59191
|
+
text7 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
|
|
59192
|
+
}
|
|
59193
|
+
});
|
|
59194
|
+
|
|
58967
59195
|
// src/notify.ts
|
|
58968
59196
|
var notify_exports = {};
|
|
58969
59197
|
__export(notify_exports, {
|
|
@@ -59066,7 +59294,7 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59066
59294
|
} catch {
|
|
59067
59295
|
reachable = false;
|
|
59068
59296
|
}
|
|
59069
|
-
const
|
|
59297
|
+
const report3 = {
|
|
59070
59298
|
// BOTH platforms must be ready. Considering only iOS meant a server with an APNs
|
|
59071
59299
|
// key but no Firebase credentials reported ok and exited 0, while every Android
|
|
59072
59300
|
// send would fail — from the command whose whole job is to answer that question.
|
|
@@ -59079,15 +59307,15 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59079
59307
|
...reachable && authed && !senders ? { hint: "this admin-server predates /v1/admin/push-doctor \u2014 upgrade it to see sender readiness" } : {}
|
|
59080
59308
|
};
|
|
59081
59309
|
if (json6) {
|
|
59082
|
-
print(
|
|
59083
|
-
return
|
|
59310
|
+
print(report3);
|
|
59311
|
+
return report3.ok ? 0 : 1;
|
|
59084
59312
|
}
|
|
59085
59313
|
io.log(
|
|
59086
59314
|
`admin ${adminUrl} ${reachable ? authed ? "reachable, authenticated" : "reachable, NOT authenticated" : "UNREACHABLE"}`
|
|
59087
59315
|
);
|
|
59088
59316
|
if (!senders) {
|
|
59089
59317
|
io.log("senders unknown \u2014 credentials live on the admin-server, and it did not report them");
|
|
59090
|
-
if (
|
|
59318
|
+
if (report3.hint) io.log(` ${report3.hint}`);
|
|
59091
59319
|
return 1;
|
|
59092
59320
|
}
|
|
59093
59321
|
for (const [platform, r] of [
|
|
@@ -59097,7 +59325,7 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
59097
59325
|
io.log(`${platform.padEnd(11)} ${r.sender}${r.note ? ` \u2014 ${r.note}` : ""}`);
|
|
59098
59326
|
if (r.missing.length) io.log(` missing on the server: ${r.missing.join(", ")}`);
|
|
59099
59327
|
}
|
|
59100
|
-
return
|
|
59328
|
+
return report3.ok ? 0 : 1;
|
|
59101
59329
|
}
|
|
59102
59330
|
const app = str9(flags.app);
|
|
59103
59331
|
if (!app) {
|
|
@@ -59276,10 +59504,10 @@ function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS4) {
|
|
|
59276
59504
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
59277
59505
|
signal: AbortSignal.timeout(timeoutMs)
|
|
59278
59506
|
});
|
|
59279
|
-
const
|
|
59280
|
-
let parsed =
|
|
59507
|
+
const text8 = await res.text();
|
|
59508
|
+
let parsed = text8;
|
|
59281
59509
|
try {
|
|
59282
|
-
parsed =
|
|
59510
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
59283
59511
|
} catch {
|
|
59284
59512
|
}
|
|
59285
59513
|
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
@@ -59376,10 +59604,10 @@ async function mintVisitorToken(fetchImpl, clientId) {
|
|
|
59376
59604
|
body: JSON.stringify({ clientId, grantType: "anonymous" }),
|
|
59377
59605
|
signal: AbortSignal.timeout(8e3)
|
|
59378
59606
|
});
|
|
59379
|
-
const
|
|
59380
|
-
let parsed =
|
|
59607
|
+
const text8 = await res.text();
|
|
59608
|
+
let parsed = text8;
|
|
59381
59609
|
try {
|
|
59382
|
-
parsed =
|
|
59610
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
59383
59611
|
} catch {
|
|
59384
59612
|
}
|
|
59385
59613
|
if (!res.ok) throw new WixApiError2(res.status, "POST", "/oauth2/token", parsed);
|
|
@@ -59394,28 +59622,28 @@ var init_visitor_auth = __esm({
|
|
|
59394
59622
|
});
|
|
59395
59623
|
|
|
59396
59624
|
// src/site-analyze/copy-clean.ts
|
|
59397
|
-
function isTemplatePlaceholder(
|
|
59398
|
-
return PLACEHOLDER_RE.test(
|
|
59625
|
+
function isTemplatePlaceholder(text8) {
|
|
59626
|
+
return PLACEHOLDER_RE.test(text8);
|
|
59399
59627
|
}
|
|
59400
59628
|
function cleanText(raw, cap) {
|
|
59401
59629
|
const s = String(raw ?? "").replace(/[\u0000-\u001F\u007F]/g, " ").replace(/\s+/g, " ").trim();
|
|
59402
59630
|
return s.length > cap ? `${s.slice(0, cap - 1).trimEnd()}\u2026` : s;
|
|
59403
59631
|
}
|
|
59404
|
-
function stripPii(
|
|
59405
|
-
return
|
|
59632
|
+
function stripPii(text8) {
|
|
59633
|
+
return text8.replace(EMAIL_RE2, "").replace(PHONE_SHAPE_RE, (m) => {
|
|
59406
59634
|
const digits2 = (m.match(ANY_DIGIT_RE) ?? []).length;
|
|
59407
59635
|
return digits2 >= PHONE_MIN_DIGITS && PHONE_DIGIT_RUN_RE.test(m) ? "" : m;
|
|
59408
59636
|
}).replace(/\s+/g, " ").trim();
|
|
59409
59637
|
}
|
|
59410
|
-
function isBoilerplate(
|
|
59411
|
-
return BOILERPLATE_RE.test(
|
|
59638
|
+
function isBoilerplate(text8) {
|
|
59639
|
+
return BOILERPLATE_RE.test(text8) || PLACEHOLDER_RE.test(text8);
|
|
59412
59640
|
}
|
|
59413
59641
|
function copyOrDrop(raw, cap) {
|
|
59414
|
-
const
|
|
59415
|
-
if (
|
|
59416
|
-
if (isBoilerplate(
|
|
59417
|
-
if (!/[A-Za-zͰ--]/.test(
|
|
59418
|
-
return
|
|
59642
|
+
const text8 = stripPii(cleanText(raw, cap));
|
|
59643
|
+
if (text8.length < 2) return "";
|
|
59644
|
+
if (isBoilerplate(text8)) return "";
|
|
59645
|
+
if (!/[A-Za-zͰ--]/.test(text8)) return "";
|
|
59646
|
+
return text8;
|
|
59419
59647
|
}
|
|
59420
59648
|
function dedupe2(values, cap) {
|
|
59421
59649
|
const out2 = [];
|
|
@@ -59449,9 +59677,9 @@ var init_copy_clean = __esm({
|
|
|
59449
59677
|
function genericDescription(it) {
|
|
59450
59678
|
for (const field of DESCRIPTION_FIELDS) {
|
|
59451
59679
|
const raw = it[field];
|
|
59452
|
-
const
|
|
59453
|
-
if (!
|
|
59454
|
-
const plain2 =
|
|
59680
|
+
const text8 = typeof raw === "string" ? raw : str6(raw?.text);
|
|
59681
|
+
if (!text8) continue;
|
|
59682
|
+
const plain2 = text8.replace(/<[^>]*>/g, " ").replace(/ /g, " ");
|
|
59455
59683
|
if (plain2.trim()) return plain2;
|
|
59456
59684
|
}
|
|
59457
59685
|
return void 0;
|
|
@@ -59564,7 +59792,7 @@ function formLabels(x, depth = 0, out2 = []) {
|
|
|
59564
59792
|
if (typeof x !== "object") return out2;
|
|
59565
59793
|
const o = x;
|
|
59566
59794
|
const label2 = str6(o.label ?? o.displayName ?? o.fieldTitle ?? o.title);
|
|
59567
|
-
if (label2 && !
|
|
59795
|
+
if (label2 && !UUID_RE2.test(label2) && label2.length < 80 && !out2.includes(label2)) out2.push(label2);
|
|
59568
59796
|
for (const k of ["fields", "formFields", "form", "schema", "properties"]) {
|
|
59569
59797
|
if (o[k] != null) formLabels(o[k], depth + 1, out2);
|
|
59570
59798
|
}
|
|
@@ -59682,7 +59910,7 @@ function sampleTitle(data) {
|
|
|
59682
59910
|
for (const [k, v] of Object.entries(data)) {
|
|
59683
59911
|
if (k.startsWith("_") || typeof v !== "string") continue;
|
|
59684
59912
|
const s = v.trim();
|
|
59685
|
-
if (s.length > 2 && s.length < 80 && !s.includes("@") && !/^https?:/i.test(s) && !
|
|
59913
|
+
if (s.length > 2 && s.length < 80 && !s.includes("@") && !/^https?:/i.test(s) && !UUID_RE2.test(s)) return s;
|
|
59686
59914
|
}
|
|
59687
59915
|
return void 0;
|
|
59688
59916
|
}
|
|
@@ -59781,7 +60009,7 @@ async function readMemberRoles(call) {
|
|
|
59781
60009
|
if (sawAuthError) return { names: [], status: "error" };
|
|
59782
60010
|
return { names: [], status: "empty" };
|
|
59783
60011
|
}
|
|
59784
|
-
var asArr, str6, DESCRIPTION_FIELDS,
|
|
60012
|
+
var asArr, str6, DESCRIPTION_FIELDS, UUID_RE2, CORE_PROBES, OPTIONAL_PROBES, ALL, CMS_LIST_LIMIT;
|
|
59785
60013
|
var init_probes = __esm({
|
|
59786
60014
|
"src/site-analyze/probes.ts"() {
|
|
59787
60015
|
init_rest();
|
|
@@ -59789,7 +60017,7 @@ var init_probes = __esm({
|
|
|
59789
60017
|
asArr = (x) => Array.isArray(x) ? x : [];
|
|
59790
60018
|
str6 = (x) => typeof x === "string" ? x : "";
|
|
59791
60019
|
DESCRIPTION_FIELDS = ["plainDescription", "description", "shortDescription", "excerpt", "tagLine", "subtitle"];
|
|
59792
|
-
|
|
60020
|
+
UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
59793
60021
|
CORE_PROBES = [
|
|
59794
60022
|
{
|
|
59795
60023
|
vertical: "store",
|
|
@@ -60496,12 +60724,12 @@ function mergeWst(pages) {
|
|
|
60496
60724
|
return acc;
|
|
60497
60725
|
}
|
|
60498
60726
|
function fontSlug(value) {
|
|
60499
|
-
let
|
|
60727
|
+
let text8 = value;
|
|
60500
60728
|
try {
|
|
60501
|
-
|
|
60729
|
+
text8 = decodeURIComponent(value);
|
|
60502
60730
|
} catch {
|
|
60503
60731
|
}
|
|
60504
|
-
return
|
|
60732
|
+
return text8.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
60505
60733
|
}
|
|
60506
60734
|
function fontUrlSlug(url) {
|
|
60507
60735
|
const last = url.split("?")[0].split("#")[0].split("/").pop() ?? "";
|
|
@@ -60675,8 +60903,8 @@ function parsePublishedHtml(html) {
|
|
|
60675
60903
|
const rawHeadings = [];
|
|
60676
60904
|
HEADING_RE.lastIndex = 0;
|
|
60677
60905
|
while (m = HEADING_RE.exec(html)) {
|
|
60678
|
-
const
|
|
60679
|
-
if (
|
|
60906
|
+
const text8 = copyOrDrop(textFromHtml(m[1] ?? ""), 120);
|
|
60907
|
+
if (text8) rawHeadings.push(text8);
|
|
60680
60908
|
if (rawHeadings.length >= 40) break;
|
|
60681
60909
|
}
|
|
60682
60910
|
const headings = dedupe2(rawHeadings, 20);
|
|
@@ -61503,16 +61731,16 @@ function isPrivateV4([a, b, c]) {
|
|
|
61503
61731
|
return a >= 224;
|
|
61504
61732
|
}
|
|
61505
61733
|
function v6Groups(host) {
|
|
61506
|
-
let
|
|
61507
|
-
const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(
|
|
61734
|
+
let text8 = host;
|
|
61735
|
+
const dotted = /:((?:\d{1,3}\.){3}\d{1,3})$/.exec(text8);
|
|
61508
61736
|
if (dotted) {
|
|
61509
61737
|
const octets = ipv4Octets(dotted[1]);
|
|
61510
61738
|
if (!octets) return null;
|
|
61511
61739
|
const hi = (octets[0] << 8 | octets[1]).toString(16);
|
|
61512
61740
|
const lo = (octets[2] << 8 | octets[3]).toString(16);
|
|
61513
|
-
|
|
61741
|
+
text8 = `${text8.slice(0, dotted.index)}:${hi}:${lo}`;
|
|
61514
61742
|
}
|
|
61515
|
-
const halves =
|
|
61743
|
+
const halves = text8.split("::");
|
|
61516
61744
|
if (halves.length > 2) return null;
|
|
61517
61745
|
const parts = (part) => part ? part.split(":") : [];
|
|
61518
61746
|
const head = parts(halves[0]);
|
|
@@ -61594,10 +61822,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
61594
61822
|
if (refusal) throw new Error(refusal);
|
|
61595
61823
|
}
|
|
61596
61824
|
function resolveAll(hostname2) {
|
|
61597
|
-
return new Promise((
|
|
61825
|
+
return new Promise((resolve53, reject) => {
|
|
61598
61826
|
dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
|
|
61599
61827
|
if (err) reject(err);
|
|
61600
|
-
else
|
|
61828
|
+
else resolve53(addresses);
|
|
61601
61829
|
});
|
|
61602
61830
|
});
|
|
61603
61831
|
}
|
|
@@ -61605,13 +61833,13 @@ function withAbort(start, signal, what) {
|
|
|
61605
61833
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
61606
61834
|
const work = start();
|
|
61607
61835
|
if (!signal) return work;
|
|
61608
|
-
return new Promise((
|
|
61836
|
+
return new Promise((resolve53, reject) => {
|
|
61609
61837
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
61610
61838
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
61611
|
-
work.then(
|
|
61839
|
+
work.then(resolve53, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
61612
61840
|
});
|
|
61613
61841
|
}
|
|
61614
|
-
async function pinAddress(url,
|
|
61842
|
+
async function pinAddress(url, resolve53 = resolveAll, signal) {
|
|
61615
61843
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
61616
61844
|
if (ipv4Octets(host)) {
|
|
61617
61845
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -61621,7 +61849,7 @@ async function pinAddress(url, resolve52 = resolveAll, signal) {
|
|
|
61621
61849
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
61622
61850
|
return { address: host, family: 6 };
|
|
61623
61851
|
}
|
|
61624
|
-
const addresses = await withAbort(() =>
|
|
61852
|
+
const addresses = await withAbort(() => resolve53(host), signal, `${host} lookup`);
|
|
61625
61853
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
61626
61854
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
61627
61855
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -61661,7 +61889,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
61661
61889
|
return out2;
|
|
61662
61890
|
}
|
|
61663
61891
|
function requestOnce(url, pinned, init) {
|
|
61664
|
-
return new Promise((
|
|
61892
|
+
return new Promise((resolve53, reject) => {
|
|
61665
61893
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
61666
61894
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
61667
61895
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -61691,7 +61919,7 @@ function requestOnce(url, pinned, init) {
|
|
|
61691
61919
|
reject(err);
|
|
61692
61920
|
return;
|
|
61693
61921
|
}
|
|
61694
|
-
|
|
61922
|
+
resolve53(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out2 }));
|
|
61695
61923
|
}
|
|
61696
61924
|
);
|
|
61697
61925
|
req.on("error", reject);
|
|
@@ -61767,8 +61995,8 @@ var init_net_guard = __esm({
|
|
|
61767
61995
|
function textFields(look) {
|
|
61768
61996
|
if (look.unavailable) return [];
|
|
61769
61997
|
const out2 = [];
|
|
61770
|
-
const add = (
|
|
61771
|
-
if (
|
|
61998
|
+
const add = (text8, where, narrative = false) => {
|
|
61999
|
+
if (text8 && text8.trim()) out2.push({ text: text8, where, narrative });
|
|
61772
62000
|
};
|
|
61773
62001
|
for (const label2 of look.navLabels) add(label2, "nav");
|
|
61774
62002
|
for (const p of look.pages) {
|
|
@@ -62159,8 +62387,8 @@ async function analyzeSite(input, ports) {
|
|
|
62159
62387
|
if (locale) plan.provisioning.locale = locale;
|
|
62160
62388
|
const velo = buildVeloChapter({ look, owner: ownerVelo });
|
|
62161
62389
|
const veloFiles = ownerVelo.files.flatMap((f) => {
|
|
62162
|
-
const
|
|
62163
|
-
return
|
|
62390
|
+
const text8 = f.content ?? f.excerpt;
|
|
62391
|
+
return text8 ? [{ path: f.path, text: text8 }] : [];
|
|
62164
62392
|
}).slice(0, 80);
|
|
62165
62393
|
const permissions = buildPermissionsChapter({
|
|
62166
62394
|
cms,
|
|
@@ -62382,8 +62610,8 @@ function cmsStatusNote(taxonomy) {
|
|
|
62382
62610
|
function yn(v) {
|
|
62383
62611
|
return v == null || v === "" ? "\u2014" : String(v);
|
|
62384
62612
|
}
|
|
62385
|
-
function isAuthPhrase(
|
|
62386
|
-
const t =
|
|
62613
|
+
function isAuthPhrase(text8) {
|
|
62614
|
+
const t = text8.trim();
|
|
62387
62615
|
return AUTH_ONLY_ASCII.test(t) || LOGIN_HE.includes(t);
|
|
62388
62616
|
}
|
|
62389
62617
|
function looksGated(page) {
|
|
@@ -62760,9 +62988,9 @@ function attachVeloSources(book, sources, put) {
|
|
|
62760
62988
|
if (isSecretVeloPath(f.path)) continue;
|
|
62761
62989
|
const rel = veloArtifactRelPath(f.path);
|
|
62762
62990
|
if (!rel) continue;
|
|
62763
|
-
const
|
|
62764
|
-
if (!
|
|
62765
|
-
put(rel,
|
|
62991
|
+
const text8 = byPath.get(f.path) ?? f.excerpt;
|
|
62992
|
+
if (!text8) continue;
|
|
62993
|
+
put(rel, text8);
|
|
62766
62994
|
f.localPath = rel;
|
|
62767
62995
|
}
|
|
62768
62996
|
}
|
|
@@ -63007,14 +63235,14 @@ var init_customer_build = __esm({
|
|
|
63007
63235
|
|
|
63008
63236
|
// src/site-analyze/apply.ts
|
|
63009
63237
|
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
|
|
63238
|
+
import { dirname as dirname35, isAbsolute as isAbsolute6, join as join63, resolve as resolve50, sep as sep16 } from "node:path";
|
|
63011
63239
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
63012
63240
|
function unpairedRedirectNote(overlay) {
|
|
63013
63241
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
63014
63242
|
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
63243
|
}
|
|
63016
63244
|
function posix3(p) {
|
|
63017
|
-
return
|
|
63245
|
+
return resolve50(p).replace(/\\/g, "/");
|
|
63018
63246
|
}
|
|
63019
63247
|
function committedShellProvisioning(path2) {
|
|
63020
63248
|
return committedShellFor(posix3(path2));
|
|
@@ -63048,7 +63276,7 @@ function assertNotCommitted(path2, forbidden) {
|
|
|
63048
63276
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
63049
63277
|
);
|
|
63050
63278
|
}
|
|
63051
|
-
if (forbidden &&
|
|
63279
|
+
if (forbidden && resolve50(path2) === resolve50(forbidden)) {
|
|
63052
63280
|
const named = committedShellProvisioning(forbidden);
|
|
63053
63281
|
throw new Error(
|
|
63054
63282
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -63104,8 +63332,8 @@ function buildMergedContract(options) {
|
|
|
63104
63332
|
const staged = [];
|
|
63105
63333
|
const contained = (root, rel) => {
|
|
63106
63334
|
if (isAbsolute6(rel)) return void 0;
|
|
63107
|
-
const full =
|
|
63108
|
-
return full.startsWith(
|
|
63335
|
+
const full = resolve50(root, rel);
|
|
63336
|
+
return full.startsWith(resolve50(root) + sep16) ? full : void 0;
|
|
63109
63337
|
};
|
|
63110
63338
|
const stage = (fromRel, toRel) => {
|
|
63111
63339
|
const from = contained(packageDir, fromRel);
|
|
@@ -63194,7 +63422,7 @@ function catalogTypography(overlay, template) {
|
|
|
63194
63422
|
function staticFaqFor(overlay, overlayPath) {
|
|
63195
63423
|
const own3 = overlay.faq;
|
|
63196
63424
|
if (own3 !== void 0) return deriveStaticFaq(own3);
|
|
63197
|
-
const bookPath = join63(dirname35(
|
|
63425
|
+
const bookPath = join63(dirname35(resolve50(overlayPath)), "book.json");
|
|
63198
63426
|
if (!existsSync64(bookPath)) return void 0;
|
|
63199
63427
|
try {
|
|
63200
63428
|
const book = JSON.parse(readFileSync76(bookPath, "utf8"));
|
|
@@ -63208,7 +63436,7 @@ function staticFaqFor(overlay, overlayPath) {
|
|
|
63208
63436
|
}
|
|
63209
63437
|
}
|
|
63210
63438
|
async function applyOverlays(input) {
|
|
63211
|
-
const cwd =
|
|
63439
|
+
const cwd = resolve50(input.cwd);
|
|
63212
63440
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
63213
63441
|
assertKnownShell(shell);
|
|
63214
63442
|
const overlay = JSON.parse(readFileSync76(input.overlayPath, "utf8"));
|
|
@@ -63232,7 +63460,7 @@ async function applyOverlays(input) {
|
|
|
63232
63460
|
`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
63461
|
);
|
|
63234
63462
|
}
|
|
63235
|
-
const packageDir = dirname35(
|
|
63463
|
+
const packageDir = dirname35(resolve50(input.overlayPath));
|
|
63236
63464
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir3, packageDir, overlay });
|
|
63237
63465
|
wrote.push(...staged);
|
|
63238
63466
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -63327,7 +63555,7 @@ async function applyOverlays(input) {
|
|
|
63327
63555
|
}
|
|
63328
63556
|
}
|
|
63329
63557
|
if (!input.iconPath || !existsSync64(input.iconPath)) {
|
|
63330
|
-
const book = input.iconPath ? dirname35(dirname35(
|
|
63558
|
+
const book = input.iconPath ? dirname35(dirname35(resolve50(input.iconPath))) : void 0;
|
|
63331
63559
|
notes.push(
|
|
63332
63560
|
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
63561
|
);
|
|
@@ -64446,10 +64674,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
64446
64674
|
}
|
|
64447
64675
|
function createPromiseCallback(cb) {
|
|
64448
64676
|
let callback;
|
|
64449
|
-
let
|
|
64677
|
+
let resolve53;
|
|
64450
64678
|
let reject;
|
|
64451
64679
|
const promise = new Promise((_resolve, _reject) => {
|
|
64452
|
-
|
|
64680
|
+
resolve53 = _resolve;
|
|
64453
64681
|
reject = _reject;
|
|
64454
64682
|
});
|
|
64455
64683
|
if (typeof cb === "function") {
|
|
@@ -64465,7 +64693,7 @@ function createPromiseCallback(cb) {
|
|
|
64465
64693
|
callback = (err, result) => {
|
|
64466
64694
|
try {
|
|
64467
64695
|
if (err) reject(err);
|
|
64468
|
-
else
|
|
64696
|
+
else resolve53(result);
|
|
64469
64697
|
} catch (e) {
|
|
64470
64698
|
reject(e instanceof Error ? e : new Error());
|
|
64471
64699
|
}
|
|
@@ -66532,8 +66760,8 @@ function copyFromEval(evaled) {
|
|
|
66532
66760
|
evaled.meta?.ogTitle,
|
|
66533
66761
|
evaled.meta?.ogDescription
|
|
66534
66762
|
].map((raw) => {
|
|
66535
|
-
const
|
|
66536
|
-
return
|
|
66763
|
+
const text8 = cleanText(raw, 400);
|
|
66764
|
+
return text8 && isTemplatePlaceholder(text8) ? stripPii(cleanText(text8, 90)) : "";
|
|
66537
66765
|
}),
|
|
66538
66766
|
8
|
|
66539
66767
|
);
|
|
@@ -67065,7 +67293,7 @@ var init_crawl_look = __esm({
|
|
|
67065
67293
|
});
|
|
67066
67294
|
|
|
67067
67295
|
// src/site-analyze/site-function.ts
|
|
67068
|
-
import { randomUUID as
|
|
67296
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
67069
67297
|
function createRevisionUrl(msid, esi) {
|
|
67070
67298
|
const q = new URLSearchParams({ editorSessionId: esi, esi, metaSiteId: msid });
|
|
67071
67299
|
return `https://editor.wix.com/html/v1/create_revision?${q}`;
|
|
@@ -67432,13 +67660,13 @@ async function veloCall(fetchImpl, method, url, opts = {}) {
|
|
|
67432
67660
|
body: opts.body === void 0 ? void 0 : JSON.stringify(opts.body),
|
|
67433
67661
|
signal: AbortSignal.timeout(opts.timeoutMs ?? 3e4)
|
|
67434
67662
|
});
|
|
67435
|
-
const
|
|
67436
|
-
let json6 =
|
|
67663
|
+
const text8 = await res.text();
|
|
67664
|
+
let json6 = text8;
|
|
67437
67665
|
try {
|
|
67438
|
-
json6 =
|
|
67666
|
+
json6 = text8 ? JSON.parse(text8) : null;
|
|
67439
67667
|
} catch {
|
|
67440
67668
|
}
|
|
67441
|
-
return { status: res.status, json: json6, text:
|
|
67669
|
+
return { status: res.status, json: json6, text: text8 };
|
|
67442
67670
|
}
|
|
67443
67671
|
function snippet2(x, cap = 180) {
|
|
67444
67672
|
const s = typeof x === "string" ? x : JSON.stringify(x) ?? "";
|
|
@@ -67510,7 +67738,7 @@ function codeAppIdFromRevision(json6) {
|
|
|
67510
67738
|
async function snapshotAndPublish(fetchImpl, token, msid, opts = {}) {
|
|
67511
67739
|
const production = opts.production !== false;
|
|
67512
67740
|
const initiator = opts.initiator ?? "himi";
|
|
67513
|
-
const esi =
|
|
67741
|
+
const esi = randomUUID6();
|
|
67514
67742
|
const rev = await veloCall(fetchImpl, "POST", createRevisionUrl(msid, esi), {
|
|
67515
67743
|
token,
|
|
67516
67744
|
msid,
|
|
@@ -67607,7 +67835,7 @@ async function runSiteFunction(opts) {
|
|
|
67607
67835
|
if (!httpOk(patched)) {
|
|
67608
67836
|
return { ...base, error: `UpdateFiles ${patched.status}: ${snippet2(patched.json ?? patched.text)}` };
|
|
67609
67837
|
}
|
|
67610
|
-
let
|
|
67838
|
+
let report3 = {
|
|
67611
67839
|
...base,
|
|
67612
67840
|
ok: true,
|
|
67613
67841
|
source: extractHttpFunction(next, method, name),
|
|
@@ -67616,21 +67844,21 @@ async function runSiteFunction(opts) {
|
|
|
67616
67844
|
if (opts.publish) {
|
|
67617
67845
|
const snap = await snapshotAndPublish(fetchImpl, opts.token, opts.msid, { production: true, initiator: "himi" });
|
|
67618
67846
|
const pubOk = httpOk(snap.rev) && httpOk(snap.live);
|
|
67619
|
-
|
|
67620
|
-
...
|
|
67621
|
-
ok:
|
|
67847
|
+
report3 = {
|
|
67848
|
+
...report3,
|
|
67849
|
+
ok: report3.ok && pubOk,
|
|
67622
67850
|
revision: snap.revision,
|
|
67623
67851
|
codeAppId: snap.codeAppId,
|
|
67624
67852
|
publish: { revision: httpOk(snap.rev), rc: httpOk(snap.rc), live: httpOk(snap.live), status: snap.live?.status },
|
|
67625
|
-
error: pubOk ?
|
|
67853
|
+
error: pubOk ? report3.error : snippet2(snap.live?.json ?? snap.rev.json)
|
|
67626
67854
|
};
|
|
67627
67855
|
}
|
|
67628
67856
|
if (opts.invoke) {
|
|
67629
|
-
if (!opts.siteUrl) return { ...
|
|
67630
|
-
const invoked = await invokeAndReport(fetchImpl, opts,
|
|
67631
|
-
return { ...
|
|
67857
|
+
if (!opts.siteUrl) return { ...report3, ok: false, error: "put --invoke needs --url" };
|
|
67858
|
+
const invoked = await invokeAndReport(fetchImpl, opts, report3, name, method);
|
|
67859
|
+
return { ...report3, ...invoked, op: "put", ok: report3.ok && invoked.ok };
|
|
67632
67860
|
}
|
|
67633
|
-
return
|
|
67861
|
+
return report3;
|
|
67634
67862
|
}
|
|
67635
67863
|
async function invokeAndReport(fetchImpl, opts, base, name, method) {
|
|
67636
67864
|
const siteUrl = opts.siteUrl;
|
|
@@ -67695,7 +67923,7 @@ __export(cli_exports, {
|
|
|
67695
67923
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
67696
67924
|
});
|
|
67697
67925
|
import { readFileSync as readFileSync77 } from "node:fs";
|
|
67698
|
-
import { resolve as
|
|
67926
|
+
import { resolve as resolve51 } from "node:path";
|
|
67699
67927
|
function assetFetchFor(_opts) {
|
|
67700
67928
|
return pinnedFetch2;
|
|
67701
67929
|
}
|
|
@@ -67715,7 +67943,7 @@ async function runSiteAnalyze(opts) {
|
|
|
67715
67943
|
const assetFetch = assetFetchFor(opts);
|
|
67716
67944
|
const siteFetch = guardedSiteFetch;
|
|
67717
67945
|
const cwd = opts.cwd ?? process.cwd();
|
|
67718
|
-
const outDir =
|
|
67946
|
+
const outDir = resolve51(cwd, opts.outDir ?? ".himi/business-book");
|
|
67719
67947
|
let ownerAuth;
|
|
67720
67948
|
let msid;
|
|
67721
67949
|
const ownerSite = ownerSiteFor(opts);
|
|
@@ -67767,9 +67995,9 @@ async function runSiteAnalyze(opts) {
|
|
|
67767
67995
|
if (opts.apply) {
|
|
67768
67996
|
applied = await applyOverlays({
|
|
67769
67997
|
cwd,
|
|
67770
|
-
overlayPath:
|
|
67771
|
-
tokensPath:
|
|
67772
|
-
iconPath:
|
|
67998
|
+
overlayPath: resolve51(outDir, "provisioning.overlay.json"),
|
|
67999
|
+
tokensPath: resolve51(outDir, "tokens.overlay.json"),
|
|
68000
|
+
iconPath: resolve51(outDir, "media/icon.png"),
|
|
67773
68001
|
shell: opts.shell
|
|
67774
68002
|
});
|
|
67775
68003
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -67805,7 +68033,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
67805
68033
|
const token = opts.token ?? await siteToken(msid);
|
|
67806
68034
|
let source;
|
|
67807
68035
|
if (opts.sourcePath) {
|
|
67808
|
-
const p =
|
|
68036
|
+
const p = resolve51(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
67809
68037
|
source = readFileSync77(p, "utf8");
|
|
67810
68038
|
}
|
|
67811
68039
|
let body;
|
|
@@ -67861,7 +68089,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
67861
68089
|
cached2 = fromEnv;
|
|
67862
68090
|
return fromEnv;
|
|
67863
68091
|
}
|
|
67864
|
-
const token = await new Promise((
|
|
68092
|
+
const token = await new Promise((resolve53, reject) => {
|
|
67865
68093
|
let child;
|
|
67866
68094
|
try {
|
|
67867
68095
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -67890,7 +68118,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
67890
68118
|
const scan = (d) => {
|
|
67891
68119
|
out2 += String(d);
|
|
67892
68120
|
const m = out2.match(TOKEN_RE2);
|
|
67893
|
-
if (m) done(() =>
|
|
68121
|
+
if (m) done(() => resolve53(m[0]));
|
|
67894
68122
|
};
|
|
67895
68123
|
child.stdout?.on("data", scan);
|
|
67896
68124
|
child.stderr?.on("data", scan);
|
|
@@ -67933,10 +68161,10 @@ function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, sp
|
|
|
67933
68161
|
}
|
|
67934
68162
|
throw new Error(`${method} ${path2} failed: ${err?.message ?? String(e)}`);
|
|
67935
68163
|
}
|
|
67936
|
-
const
|
|
67937
|
-
let parsed =
|
|
68164
|
+
const text8 = await res.text();
|
|
68165
|
+
let parsed = text8;
|
|
67938
68166
|
try {
|
|
67939
|
-
parsed =
|
|
68167
|
+
parsed = text8 ? JSON.parse(text8) : null;
|
|
67940
68168
|
} catch {
|
|
67941
68169
|
}
|
|
67942
68170
|
if (!res.ok) throw new WixApiError(res.status, method, path2, parsed);
|
|
@@ -67997,16 +68225,16 @@ async function installVerticals(msid, wanted, token, fetchImpl = fetch, timeoutM
|
|
|
67997
68225
|
body: JSON.stringify({ apps: wanted.map((w) => ({ id: w.appDefId })) }),
|
|
67998
68226
|
signal: AbortSignal.timeout(timeoutMs)
|
|
67999
68227
|
});
|
|
68000
|
-
const
|
|
68228
|
+
const text8 = await res.text();
|
|
68001
68229
|
if (!res.ok) {
|
|
68002
68230
|
return {
|
|
68003
68231
|
...empty,
|
|
68004
|
-
errors: wanted.map((w) => ({ ...w, message: `bulk-install -> ${res.status}: ${
|
|
68232
|
+
errors: wanted.map((w) => ({ ...w, message: `bulk-install -> ${res.status}: ${text8.slice(0, 200)}` }))
|
|
68005
68233
|
};
|
|
68006
68234
|
}
|
|
68007
68235
|
let body = {};
|
|
68008
68236
|
try {
|
|
68009
|
-
body =
|
|
68237
|
+
body = text8 ? JSON.parse(text8) : {};
|
|
68010
68238
|
} catch {
|
|
68011
68239
|
}
|
|
68012
68240
|
const nameOf = (appDefId) => wanted.find((w) => w.appDefId === appDefId)?.vertical ?? appDefId;
|
|
@@ -68609,9 +68837,9 @@ function redactVeloSource(source, knownSecrets = []) {
|
|
|
68609
68837
|
const visitLiterals = (node) => {
|
|
68610
68838
|
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || ts.isTemplateExpression(node)) {
|
|
68611
68839
|
const start = node.getStart(clean2);
|
|
68612
|
-
const
|
|
68613
|
-
const redacted = redactLiteral(
|
|
68614
|
-
if (redacted !==
|
|
68840
|
+
const text8 = source.slice(start, node.end);
|
|
68841
|
+
const redacted = redactLiteral(text8, start);
|
|
68842
|
+
if (redacted !== text8) {
|
|
68615
68843
|
edits.push({ start, end: node.end, text: redacted });
|
|
68616
68844
|
return;
|
|
68617
68845
|
}
|
|
@@ -68892,9 +69120,9 @@ var init_context = __esm({
|
|
|
68892
69120
|
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
69121
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
68894
69122
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
68895
|
-
import { createHash as createHash31, randomUUID as
|
|
69123
|
+
import { createHash as createHash31, randomUUID as randomUUID7 } from "node:crypto";
|
|
68896
69124
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
68897
|
-
import { join as join64, resolve as
|
|
69125
|
+
import { join as join64, resolve as resolve52, relative as relative13, basename as basename17, dirname as dirname36 } from "node:path";
|
|
68898
69126
|
import { fileURLToPath as fileURLToPath26 } from "node:url";
|
|
68899
69127
|
|
|
68900
69128
|
// ../serve-cli/src/client.ts
|
|
@@ -68935,10 +69163,10 @@ var ServeCliClient = class {
|
|
|
68935
69163
|
...carriesCredential ? { redirect: "error" } : {},
|
|
68936
69164
|
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
68937
69165
|
});
|
|
68938
|
-
const
|
|
69166
|
+
const text8 = await res.text();
|
|
68939
69167
|
let json6 = null;
|
|
68940
69168
|
try {
|
|
68941
|
-
json6 =
|
|
69169
|
+
json6 = text8 ? JSON.parse(text8) : null;
|
|
68942
69170
|
} catch {
|
|
68943
69171
|
json6 = null;
|
|
68944
69172
|
}
|
|
@@ -68946,7 +69174,7 @@ var ServeCliClient = class {
|
|
|
68946
69174
|
res.headers.forEach((v, k) => {
|
|
68947
69175
|
h[k] = v;
|
|
68948
69176
|
});
|
|
68949
|
-
return { status: res.status, ok: res.ok, json: json6, text:
|
|
69177
|
+
return { status: res.status, ok: res.ok, json: json6, text: text8, headers: h };
|
|
68950
69178
|
}
|
|
68951
69179
|
// ---- serve (device-facing reads) ----
|
|
68952
69180
|
health(plane) {
|
|
@@ -69511,8 +69739,8 @@ init_attestation();
|
|
|
69511
69739
|
|
|
69512
69740
|
// ../../core/admin-web/src/utils/qr-terminal.ts
|
|
69513
69741
|
init_qr();
|
|
69514
|
-
function qrTerminal(
|
|
69515
|
-
const { modules, size } = encodeQr(
|
|
69742
|
+
function qrTerminal(text8, opts = {}) {
|
|
69743
|
+
const { modules, size } = encodeQr(text8);
|
|
69516
69744
|
const quietZone = opts.quietZone ?? 4;
|
|
69517
69745
|
const dim = size + quietZone * 2;
|
|
69518
69746
|
const dark = (x, y) => x >= quietZone && x < quietZone + size && y >= quietZone && y < quietZone + size ? modules[y - quietZone][x - quietZone] : false;
|
|
@@ -69568,9 +69796,9 @@ function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
|
|
|
69568
69796
|
return false;
|
|
69569
69797
|
}
|
|
69570
69798
|
}
|
|
69571
|
-
function isPortInUseError(
|
|
69572
|
-
if (!
|
|
69573
|
-
return /EADDRINUSE/i.test(
|
|
69799
|
+
function isPortInUseError(text8) {
|
|
69800
|
+
if (!text8) return false;
|
|
69801
|
+
return /EADDRINUSE/i.test(text8) || new RegExp(`(:::|:)${DPX_SESSION_PORT}\\b`).test(text8);
|
|
69574
69802
|
}
|
|
69575
69803
|
function parseDpxAuthStatusIdentity(stdout) {
|
|
69576
69804
|
if (!stdout) return void 0;
|
|
@@ -69635,7 +69863,7 @@ async function browserLogin(opts) {
|
|
|
69635
69863
|
const log = opts.log ?? (() => {
|
|
69636
69864
|
});
|
|
69637
69865
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
69638
|
-
return await new Promise((
|
|
69866
|
+
return await new Promise((resolve53, reject) => {
|
|
69639
69867
|
let settled = false;
|
|
69640
69868
|
let loginUrl = "";
|
|
69641
69869
|
const server = createServer();
|
|
@@ -69699,7 +69927,7 @@ async function browserLogin(opts) {
|
|
|
69699
69927
|
return;
|
|
69700
69928
|
}
|
|
69701
69929
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
69702
|
-
finish2(() =>
|
|
69930
|
+
finish2(() => resolve53({ token, loginUrl }));
|
|
69703
69931
|
});
|
|
69704
69932
|
});
|
|
69705
69933
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -69963,7 +70191,7 @@ async function queryCms(opts) {
|
|
|
69963
70191
|
async function createCms(opts) {
|
|
69964
70192
|
const { app, cms, call, dryRun = false, allowDestructive = false, applyPermissions = false } = opts;
|
|
69965
70193
|
const prefix = namespacePrefix(app);
|
|
69966
|
-
const
|
|
70194
|
+
const report3 = {
|
|
69967
70195
|
ok: true,
|
|
69968
70196
|
app,
|
|
69969
70197
|
namespace: prefix,
|
|
@@ -69985,19 +70213,19 @@ async function createCms(opts) {
|
|
|
69985
70213
|
for (const spec of cms?.collections ?? []) {
|
|
69986
70214
|
const id = physicalId(spec, app);
|
|
69987
70215
|
if (spec.wixId) {
|
|
69988
|
-
|
|
70216
|
+
report3.skipped.push({
|
|
69989
70217
|
collection: id,
|
|
69990
70218
|
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
70219
|
});
|
|
69992
|
-
if (!remoteById.has(id))
|
|
70220
|
+
if (!remoteById.has(id)) report3.ok = false;
|
|
69993
70221
|
continue;
|
|
69994
70222
|
}
|
|
69995
70223
|
if (!spec.id?.startsWith(prefix)) {
|
|
69996
|
-
|
|
70224
|
+
report3.refused.push({
|
|
69997
70225
|
collection: id || "<unnamed>",
|
|
69998
70226
|
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
70227
|
});
|
|
70000
|
-
|
|
70228
|
+
report3.ok = false;
|
|
70001
70229
|
continue;
|
|
70002
70230
|
}
|
|
70003
70231
|
const existing = remoteById.get(id);
|
|
@@ -70005,35 +70233,35 @@ async function createCms(opts) {
|
|
|
70005
70233
|
if (!dryRun) {
|
|
70006
70234
|
await call("POST", "/data/v2/collections", { collection: toWixCollection(spec, app) });
|
|
70007
70235
|
}
|
|
70008
|
-
|
|
70236
|
+
report3.created.push(id);
|
|
70009
70237
|
continue;
|
|
70010
70238
|
}
|
|
70011
70239
|
const permDrift = diffPermissions(spec, existing);
|
|
70012
|
-
for (const d of permDrift)
|
|
70240
|
+
for (const d of permDrift) report3.permissionDrift.push({ collection: id, ...d });
|
|
70013
70241
|
const applyingPermissions = applyPermissions && permDrift.length > 0;
|
|
70014
70242
|
const drift = diffFields(spec, existing);
|
|
70015
70243
|
const extras = drift.filter((d) => d.kind === "extra-field");
|
|
70016
70244
|
const mismatches = drift.filter((d) => d.kind === "type-mismatch");
|
|
70017
70245
|
const missing = drift.filter((d) => d.kind === "missing-field");
|
|
70018
70246
|
for (const m of mismatches) {
|
|
70019
|
-
|
|
70020
|
-
|
|
70247
|
+
report3.skipped.push({ collection: id, reason: m.detail });
|
|
70248
|
+
report3.ok = false;
|
|
70021
70249
|
}
|
|
70022
70250
|
for (const e of extras) {
|
|
70023
70251
|
if (allowDestructive) continue;
|
|
70024
|
-
|
|
70252
|
+
report3.skipped.push({ collection: id, reason: e.detail });
|
|
70025
70253
|
}
|
|
70026
70254
|
if (mismatches.length > 0) continue;
|
|
70027
70255
|
if (missing.length === 0 && (extras.length === 0 || !allowDestructive) && !applyingPermissions) {
|
|
70028
|
-
|
|
70256
|
+
report3.unchanged.push(id);
|
|
70029
70257
|
continue;
|
|
70030
70258
|
}
|
|
70031
70259
|
if (!allowDestructive && !Array.isArray(existing.fields)) {
|
|
70032
|
-
|
|
70260
|
+
report3.skipped.push({
|
|
70033
70261
|
collection: id,
|
|
70034
70262
|
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
70263
|
});
|
|
70036
|
-
|
|
70264
|
+
report3.ok = false;
|
|
70037
70265
|
continue;
|
|
70038
70266
|
}
|
|
70039
70267
|
if (applyingPermissions) {
|
|
@@ -70070,14 +70298,14 @@ async function createCms(opts) {
|
|
|
70070
70298
|
}
|
|
70071
70299
|
}
|
|
70072
70300
|
}
|
|
70073
|
-
|
|
70301
|
+
report3.updated.push(id);
|
|
70074
70302
|
}
|
|
70075
|
-
return
|
|
70303
|
+
return report3;
|
|
70076
70304
|
}
|
|
70077
70305
|
async function seedCms(opts) {
|
|
70078
70306
|
const { app, cms, call, dryRun = false, force = false, only, dir } = opts;
|
|
70079
70307
|
const prefix = namespacePrefix(app);
|
|
70080
|
-
const
|
|
70308
|
+
const report3 = { ok: true, app, inserted: {}, sources: {}, skipped: [], refused: [], dryRun };
|
|
70081
70309
|
const fileRows = dir ? readSeedFile(dir) : {};
|
|
70082
70310
|
const rowsFor = (id, spec) => fileRows[id]?.length ? { rows: fileRows[id], source: "cms-seed.json" } : { rows: spec.seed ?? [], source: "config.ts" };
|
|
70083
70311
|
const remoteIds = /* @__PURE__ */ new Set();
|
|
@@ -70094,30 +70322,30 @@ async function seedCms(opts) {
|
|
|
70094
70322
|
const { rows, source } = rowsFor(id, spec);
|
|
70095
70323
|
considered++;
|
|
70096
70324
|
if (!rows.length) {
|
|
70097
|
-
|
|
70325
|
+
report3.skipped.push({
|
|
70098
70326
|
collection: id,
|
|
70099
70327
|
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
70328
|
});
|
|
70101
70329
|
continue;
|
|
70102
70330
|
}
|
|
70103
70331
|
if (!spec.id?.startsWith(prefix)) {
|
|
70104
|
-
|
|
70105
|
-
|
|
70332
|
+
report3.refused.push({ collection: id, reason: `"${id}" is outside this app's namespace "${prefix}" \u2014 himi only seeds collections it owns.` });
|
|
70333
|
+
report3.ok = false;
|
|
70106
70334
|
continue;
|
|
70107
70335
|
}
|
|
70108
70336
|
if (!remoteIds.has(id)) {
|
|
70109
|
-
|
|
70110
|
-
|
|
70337
|
+
report3.skipped.push({ collection: id, reason: `not on the site yet \u2014 run \`himi cms create\` first` });
|
|
70338
|
+
report3.ok = false;
|
|
70111
70339
|
continue;
|
|
70112
70340
|
}
|
|
70113
70341
|
const count2 = await countItems(call, id);
|
|
70114
70342
|
if (count2 === null && !force) {
|
|
70115
|
-
|
|
70116
|
-
|
|
70343
|
+
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." });
|
|
70344
|
+
report3.ok = false;
|
|
70117
70345
|
continue;
|
|
70118
70346
|
}
|
|
70119
70347
|
if (count2 !== null && count2 > 0 && !force) {
|
|
70120
|
-
|
|
70348
|
+
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
70349
|
continue;
|
|
70122
70350
|
}
|
|
70123
70351
|
if (!dryRun) {
|
|
@@ -70129,7 +70357,7 @@ async function seedCms(opts) {
|
|
|
70129
70357
|
});
|
|
70130
70358
|
const droppedKeys = [...new Set(rows.flatMap((r) => Object.keys(r).filter((k) => !declaredKeys.has(k))))];
|
|
70131
70359
|
if (droppedKeys.length > 0) {
|
|
70132
|
-
|
|
70360
|
+
report3.skipped.push({
|
|
70133
70361
|
collection: id,
|
|
70134
70362
|
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
70363
|
});
|
|
@@ -70145,18 +70373,18 @@ async function seedCms(opts) {
|
|
|
70145
70373
|
)
|
|
70146
70374
|
);
|
|
70147
70375
|
}
|
|
70148
|
-
|
|
70149
|
-
|
|
70376
|
+
report3.inserted[id] = rows.length;
|
|
70377
|
+
report3.sources[id] = source;
|
|
70150
70378
|
}
|
|
70151
70379
|
if (considered === 0) {
|
|
70152
70380
|
const adopted = (cms?.collections ?? []).map((spec) => ({ spec, id: physicalId(spec, app) })).filter(({ spec, id }) => !!spec.wixId && (!only || id === only));
|
|
70153
|
-
|
|
70381
|
+
report3.skipped.push({
|
|
70154
70382
|
collection: only ?? "<none>",
|
|
70155
70383
|
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
70384
|
});
|
|
70157
|
-
|
|
70385
|
+
report3.ok = false;
|
|
70158
70386
|
}
|
|
70159
|
-
return
|
|
70387
|
+
return report3;
|
|
70160
70388
|
}
|
|
70161
70389
|
function readSeedFile(dir) {
|
|
70162
70390
|
const file = join8(dir, "cms-seed.json");
|
|
@@ -70457,57 +70685,57 @@ function summarizeLint(app, bres, outcome, strict, extraIssues = []) {
|
|
|
70457
70685
|
}
|
|
70458
70686
|
};
|
|
70459
70687
|
const record2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
70460
|
-
const
|
|
70688
|
+
const text8 = (value) => typeof value === "string" && value ? value : void 0;
|
|
70461
70689
|
const message = (value) => {
|
|
70462
70690
|
const item = record2(value);
|
|
70463
|
-
if (
|
|
70464
|
-
if (
|
|
70691
|
+
if (text8(item.message)) return text8(item.message);
|
|
70692
|
+
if (text8(item.error)) return text8(item.error);
|
|
70465
70693
|
if (Array.isArray(item.errors)) {
|
|
70466
70694
|
const diagnostics = item.errors.map((entry) => {
|
|
70467
70695
|
const diagnostic = record2(entry);
|
|
70468
|
-
return
|
|
70696
|
+
return text8(diagnostic.text) ?? text8(diagnostic.message);
|
|
70469
70697
|
}).filter((entry) => !!entry);
|
|
70470
70698
|
if (diagnostics.length) return diagnostics.join("; ");
|
|
70471
70699
|
}
|
|
70472
70700
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
70473
70701
|
};
|
|
70474
|
-
const
|
|
70702
|
+
const report3 = foldLegacyReport(legacy, {
|
|
70475
70703
|
source: "validate",
|
|
70476
70704
|
evidence: { runId: `validate:${outcome.manifest.releaseId}`, ts: (/* @__PURE__ */ new Date()).toISOString() },
|
|
70477
70705
|
findings: [
|
|
70478
70706
|
...issues,
|
|
70479
70707
|
...bres.compileErrors.map((value) => ({
|
|
70480
70708
|
pass: "compile",
|
|
70481
|
-
path:
|
|
70709
|
+
path: text8(record2(value).bundle),
|
|
70482
70710
|
ruleCode: "compile-error",
|
|
70483
70711
|
severity: "error",
|
|
70484
70712
|
message: message(value)
|
|
70485
70713
|
})),
|
|
70486
70714
|
...outcome.failedToBuild.map((value) => ({
|
|
70487
70715
|
pass: "build",
|
|
70488
|
-
screen:
|
|
70716
|
+
screen: text8(record2(value).screenId),
|
|
70489
70717
|
ruleCode: "failed-to-build",
|
|
70490
70718
|
severity: "error",
|
|
70491
70719
|
message: message(value)
|
|
70492
70720
|
})),
|
|
70493
70721
|
...outcome.missingBundles.map((value) => ({
|
|
70494
70722
|
pass: "build",
|
|
70495
|
-
screen:
|
|
70496
|
-
path:
|
|
70723
|
+
screen: text8(record2(value).screen),
|
|
70724
|
+
path: text8(record2(value).bundle),
|
|
70497
70725
|
ruleCode: "missing-bundle",
|
|
70498
70726
|
severity: "error",
|
|
70499
70727
|
message: message(value)
|
|
70500
70728
|
})),
|
|
70501
70729
|
...workerThrows.map((value) => ({
|
|
70502
70730
|
pass: "worker",
|
|
70503
|
-
path:
|
|
70731
|
+
path: text8(record2(value).bundle),
|
|
70504
70732
|
ruleCode: "worker-threw",
|
|
70505
70733
|
severity: "error",
|
|
70506
70734
|
message: message(value.threw)
|
|
70507
70735
|
}))
|
|
70508
70736
|
]
|
|
70509
70737
|
});
|
|
70510
|
-
return { report:
|
|
70738
|
+
return { report: report3, hasErrors };
|
|
70511
70739
|
}
|
|
70512
70740
|
|
|
70513
70741
|
// src/cms-lint.ts
|
|
@@ -70631,8 +70859,8 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
70631
70859
|
if (requested.length) {
|
|
70632
70860
|
const { rejected } = resolveSurfaceEnvelope(platforms, requested);
|
|
70633
70861
|
for (const r of rejected) {
|
|
70634
|
-
const
|
|
70635
|
-
|
|
70862
|
+
const report3 = surfaceById(r.id) ? warn : error;
|
|
70863
|
+
report3(`navigation.surfaces: ${r.reason} \u2014 the server will drop this key (narrow-only rule, RFC 0051 \xA73.6)`);
|
|
70636
70864
|
}
|
|
70637
70865
|
}
|
|
70638
70866
|
return issues;
|
|
@@ -70779,18 +71007,18 @@ function walkSource(dir, root = dir) {
|
|
|
70779
71007
|
const ext = entry.name.slice(entry.name.lastIndexOf("."));
|
|
70780
71008
|
if (!SOURCE_EXTENSIONS.has(ext)) continue;
|
|
70781
71009
|
const absolute = join25(dir, entry.name);
|
|
70782
|
-
const
|
|
70783
|
-
if (
|
|
71010
|
+
const text8 = readText2(absolute);
|
|
71011
|
+
if (text8 !== null) found.push({ path: relative4(root, absolute), text: text8 });
|
|
70784
71012
|
}
|
|
70785
71013
|
return found;
|
|
70786
71014
|
}
|
|
70787
|
-
function blankMatrixRows(
|
|
70788
|
-
const acceptance = mobileUxSection(mobileUxDocumentBody(
|
|
71015
|
+
function blankMatrixRows(text8) {
|
|
71016
|
+
const acceptance = mobileUxSection(mobileUxDocumentBody(text8), "Implementation acceptance") ?? "";
|
|
70789
71017
|
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
71018
|
}
|
|
70791
71019
|
function usesAppNetwork(source) {
|
|
70792
|
-
const code = (
|
|
70793
|
-
return source.some(({ text:
|
|
71020
|
+
const code = (text8) => text8.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
|
|
71021
|
+
return source.some(({ text: text8 }) => /\bwixApi\b|(?:from|import)\s*["']@(?:himalaya|wix\/himalaya)\/wix-[^"']+["']/.test(code(text8)));
|
|
70794
71022
|
}
|
|
70795
71023
|
function auditUx(content, strict = false) {
|
|
70796
71024
|
const dir = resolve16(content);
|
|
@@ -71504,6 +71732,13 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
71504
71732
|
Requires Himi owner login plus Wix CLI login for site authorization.
|
|
71505
71733
|
himi notify status --content <dir> [--site <msid>] [--refresh] [--json]
|
|
71506
71734
|
Reads server setup status. --refresh checks Branded/Ping live; it does not send push.
|
|
71735
|
+
himi notify send --provider ping --target wix --app <a> --site <msid> --member-email <email>
|
|
71736
|
+
--title <s> [--body <s>] --link <scheme>://screen/<id>[?\u2026] [--request-id <uuid>] [--dry-run] [--json]
|
|
71737
|
+
Hosted test notification to ONE site member's devices: Himi Serve sends it through Ping
|
|
71738
|
+
as Himalaya, so no Apple/Firebase keys or Fire Console. Needs himi login --browser and
|
|
71739
|
+
wix login as the site owner, and a ready notify setup. Acceptance is not delivery.
|
|
71740
|
+
--dry-run checks ownership, member, link and readiness without sending. After an unknown
|
|
71741
|
+
outcome, re-run the same command with the printed --request-id; Ping never runs it twice.
|
|
71507
71742
|
himi notify send --app <a> (--token <t> | --device <id> | --all) --title <s> [--body <s>] [--link <url>]
|
|
71508
71743
|
deliver a REAL push notification to registered devices \u2014
|
|
71509
71744
|
APNs (.p8) for iOS, FCM v1 for Android. --all fans out to
|
|
@@ -71695,7 +71930,7 @@ var COMMANDS = [
|
|
|
71695
71930
|
{ 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
71931
|
{ 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
71932
|
{ 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]" },
|
|
71933
|
+
{ 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
71934
|
{ 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
71935
|
{ 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
71936
|
{ 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 +72023,16 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
71788
72023
|
}
|
|
71789
72024
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
71790
72025
|
function execNpmConfig(file, args, options) {
|
|
71791
|
-
return new Promise((
|
|
71792
|
-
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) :
|
|
72026
|
+
return new Promise((resolve53, reject) => {
|
|
72027
|
+
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve53(String(stdout)));
|
|
71793
72028
|
});
|
|
71794
72029
|
}
|
|
71795
72030
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
71796
72031
|
async function scopedRegistryBefore(lookup2, deadline) {
|
|
71797
72032
|
let cancel = () => {
|
|
71798
72033
|
};
|
|
71799
|
-
const expired = new Promise((
|
|
71800
|
-
const timer = setTimeout(() =>
|
|
72034
|
+
const expired = new Promise((resolve53) => {
|
|
72035
|
+
const timer = setTimeout(() => resolve53(void 0), Math.max(0, deadline - Date.now()));
|
|
71801
72036
|
cancel = () => clearTimeout(timer);
|
|
71802
72037
|
});
|
|
71803
72038
|
try {
|
|
@@ -71862,7 +72097,7 @@ function packageVersion(path2) {
|
|
|
71862
72097
|
}
|
|
71863
72098
|
}
|
|
71864
72099
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
71865
|
-
let dir =
|
|
72100
|
+
let dir = resolve52(fromDir);
|
|
71866
72101
|
for (; ; ) {
|
|
71867
72102
|
const version2 = packageVersion(join64(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
71868
72103
|
if (version2) return { version: version2, source: "local" };
|
|
@@ -72027,7 +72262,7 @@ function thisHost() {
|
|
|
72027
72262
|
return hostname().replace(/\s+/g, "_");
|
|
72028
72263
|
}
|
|
72029
72264
|
function lockStamp(now) {
|
|
72030
|
-
return `${now} ${process.pid} ${thisHost()} ${
|
|
72265
|
+
return `${now} ${process.pid} ${thisHost()} ${randomUUID7()}`;
|
|
72031
72266
|
}
|
|
72032
72267
|
function processAlive(pid) {
|
|
72033
72268
|
try {
|
|
@@ -72181,21 +72416,21 @@ function loaderArgs(execArgv) {
|
|
|
72181
72416
|
}
|
|
72182
72417
|
var spawnUpdateRefresh = createUpdateRefreshSpawner();
|
|
72183
72418
|
function createTrimValidator(deps = {}, spawnFn = spawn7) {
|
|
72184
|
-
const outcome = (code,
|
|
72419
|
+
const outcome = (code, report3, said) => {
|
|
72185
72420
|
let counts;
|
|
72186
72421
|
let errors;
|
|
72187
72422
|
try {
|
|
72188
|
-
const parsed = JSON.parse(
|
|
72423
|
+
const parsed = JSON.parse(report3);
|
|
72189
72424
|
counts = parsed.counts;
|
|
72190
72425
|
if (Array.isArray(parsed.findings)) {
|
|
72191
|
-
const
|
|
72426
|
+
const text8 = (v) => typeof v === "string" && v ? v : void 0;
|
|
72192
72427
|
errors = parsed.findings.filter((f) => f && f.severity === "error" && typeof f.id === "string").map((f) => ({
|
|
72193
72428
|
id: f.id,
|
|
72194
|
-
message:
|
|
72195
|
-
...
|
|
72196
|
-
...
|
|
72197
|
-
...
|
|
72198
|
-
...
|
|
72429
|
+
message: text8(f.message) ?? "",
|
|
72430
|
+
...text8(f.pass) ? { pass: text8(f.pass) } : {},
|
|
72431
|
+
...text8(f.screen) ? { screen: text8(f.screen) } : {},
|
|
72432
|
+
...text8(f.path) ? { path: text8(f.path) } : {},
|
|
72433
|
+
...text8(f.ruleCode) ? { ruleCode: text8(f.ruleCode) } : {}
|
|
72199
72434
|
}));
|
|
72200
72435
|
}
|
|
72201
72436
|
} catch {
|
|
@@ -72203,7 +72438,7 @@ function createTrimValidator(deps = {}, spawnFn = spawn7) {
|
|
|
72203
72438
|
return { code, counts, ...errors ? { errors } : {}, ...code !== 0 ? { tail: said.slice(-4e3) } : {} };
|
|
72204
72439
|
};
|
|
72205
72440
|
return async (dir, opts = {}) => {
|
|
72206
|
-
const argv = ["validate", "--content",
|
|
72441
|
+
const argv = ["validate", "--content", resolve52(dir), "--strict", "--skip-version-check"];
|
|
72207
72442
|
if (!opts.fresh) {
|
|
72208
72443
|
const out2 = [];
|
|
72209
72444
|
const err = [];
|
|
@@ -72819,7 +73054,7 @@ function keptPlan(kept) {
|
|
|
72819
73054
|
return note ? { kept, note } : {};
|
|
72820
73055
|
}
|
|
72821
73056
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
72822
|
-
const dir =
|
|
73057
|
+
const dir = resolve52(parentDir, name);
|
|
72823
73058
|
if (existsSync66(join64(dir, "himalaya.content.json"))) {
|
|
72824
73059
|
throw new Error(`content package already exists at ${dir}`);
|
|
72825
73060
|
}
|
|
@@ -72832,17 +73067,17 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
72832
73067
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
72833
73068
|
}
|
|
72834
73069
|
function contentDir(flags) {
|
|
72835
|
-
return
|
|
73070
|
+
return resolve52(str8(flags.content) ?? process.cwd());
|
|
72836
73071
|
}
|
|
72837
73072
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
72838
|
-
const
|
|
73073
|
+
const text8 = {};
|
|
72839
73074
|
for (const entry of restored) {
|
|
72840
73075
|
const decoded = entry.bytes.toString("utf8");
|
|
72841
|
-
if (Buffer.from(decoded, "utf8").equals(entry.bytes))
|
|
73076
|
+
if (Buffer.from(decoded, "utf8").equals(entry.bytes)) text8[entry.path] = decoded;
|
|
72842
73077
|
}
|
|
72843
|
-
const sentineled = sentinelizeArchive(
|
|
73078
|
+
const sentineled = sentinelizeArchive(text8, declaredApp);
|
|
72844
73079
|
for (const entry of restored) {
|
|
72845
|
-
if (!(entry.path in
|
|
73080
|
+
if (!(entry.path in text8)) continue;
|
|
72846
73081
|
const body = sentineled[entry.path];
|
|
72847
73082
|
if (body !== void 0) entry.bytes = Buffer.from(substituteIdentity(body, renamed), "utf8");
|
|
72848
73083
|
}
|
|
@@ -72876,7 +73111,7 @@ function restoreDestinationIssue(dest, force) {
|
|
|
72876
73111
|
return null;
|
|
72877
73112
|
}
|
|
72878
73113
|
function isHimalayaMonorepoCheckout(start) {
|
|
72879
|
-
let dir =
|
|
73114
|
+
let dir = resolve52(start);
|
|
72880
73115
|
for (; ; ) {
|
|
72881
73116
|
if (existsSync66(join64(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync66(join64(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
72882
73117
|
const parent = dirname36(dir);
|
|
@@ -72938,7 +73173,7 @@ function materializeForPreview(appDir3, slug, displayName) {
|
|
|
72938
73173
|
const forBuild = Object.fromEntries(
|
|
72939
73174
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
72940
73175
|
);
|
|
72941
|
-
const repoRoot2 =
|
|
73176
|
+
const repoRoot2 = resolve52(fileURLToPath26(new URL("../../..", import.meta.url)));
|
|
72942
73177
|
const root = join64(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
72943
73178
|
const stillRunning = (pid) => {
|
|
72944
73179
|
try {
|
|
@@ -73184,7 +73419,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
73184
73419
|
return 0;
|
|
73185
73420
|
}
|
|
73186
73421
|
case "agent-init": {
|
|
73187
|
-
const dir =
|
|
73422
|
+
const dir = resolve52(str8(flags.dir) ?? process.cwd());
|
|
73188
73423
|
const { seedAgentFiles: seedAgentFiles2, NotAContentPackage: NotAContentPackage2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
73189
73424
|
let res;
|
|
73190
73425
|
try {
|
|
@@ -73741,7 +73976,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
73741
73976
|
return 2;
|
|
73742
73977
|
}
|
|
73743
73978
|
const template = str8(flags.template);
|
|
73744
|
-
const parentDir =
|
|
73979
|
+
const parentDir = resolve52(str8(flags.dir) ?? process.cwd());
|
|
73745
73980
|
const withAgentFiles = async (dir) => {
|
|
73746
73981
|
const seeded = await seedAgentFilesFor(dir, flags);
|
|
73747
73982
|
if (!seeded.agent || "error" in seeded.agent) return seeded;
|
|
@@ -73902,8 +74137,8 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73902
74137
|
return 2;
|
|
73903
74138
|
}
|
|
73904
74139
|
}
|
|
73905
|
-
const appDir3 =
|
|
73906
|
-
const sourceDir =
|
|
74140
|
+
const appDir3 = resolve52(str8(flags.dir) ?? process.cwd());
|
|
74141
|
+
const sourceDir = resolve52(str8(flags["source-dir"]) ?? appDir3);
|
|
73907
74142
|
let meta;
|
|
73908
74143
|
try {
|
|
73909
74144
|
meta = JSON.parse(readFileSync79(join64(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
@@ -73945,7 +74180,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73945
74180
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
73946
74181
|
collect: { lint: true, strict }
|
|
73947
74182
|
});
|
|
73948
|
-
const scaffoldSourceFindings =
|
|
74183
|
+
const scaffoldSourceFindings = resolve52(sourceDir) === resolve52(appDir3) ? [] : [
|
|
73949
74184
|
...tokenColorIssues(sourceDir),
|
|
73950
74185
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
73951
74186
|
...await fontIssues(sourceDir, strict),
|
|
@@ -73957,7 +74192,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73957
74192
|
message: `scaffold source (--source-dir ${sourceDir}): ${issue2.message}`
|
|
73958
74193
|
}));
|
|
73959
74194
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
73960
|
-
const { report:
|
|
74195
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
73961
74196
|
...await cmsIssues(buildDir, app, strict, { local: true }),
|
|
73962
74197
|
...surfaceIssues(buildDir, outcome.surfaceNav, strict),
|
|
73963
74198
|
...tokenColorIssues(buildDir),
|
|
@@ -73967,7 +74202,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73967
74202
|
...scaffoldSourceFindings
|
|
73968
74203
|
]);
|
|
73969
74204
|
if (hasErrors && !force) {
|
|
73970
|
-
print({ ...
|
|
74205
|
+
print({ ...report3, published: false, hint: "lint found errors \u2014 fix them, or re-run with --force to publish anyway" });
|
|
73971
74206
|
return 1;
|
|
73972
74207
|
}
|
|
73973
74208
|
const payload = await loadReleaseFromDir(app, out2);
|
|
@@ -73988,7 +74223,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
73988
74223
|
}));
|
|
73989
74224
|
return 1;
|
|
73990
74225
|
}
|
|
73991
|
-
const iconPath = str8(flags.icon) ?
|
|
74226
|
+
const iconPath = str8(flags.icon) ? resolve52(str8(flags.icon)) : templateIconPath(name);
|
|
73992
74227
|
let iconHash;
|
|
73993
74228
|
if (iconPath) {
|
|
73994
74229
|
try {
|
|
@@ -74242,7 +74477,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74242
74477
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
74243
74478
|
collect: { lint: true, strict }
|
|
74244
74479
|
});
|
|
74245
|
-
const { report:
|
|
74480
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
74246
74481
|
...await cmsIssues(dir, app, strict, { local: true }),
|
|
74247
74482
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
74248
74483
|
...tokenColorIssues(dir),
|
|
@@ -74259,10 +74494,10 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74259
74494
|
if (authWarning) advisories.push(authWarning);
|
|
74260
74495
|
advisories.push(...await nativeConfigAdvisories(app, configSource));
|
|
74261
74496
|
const finalReport = advisories.length ? {
|
|
74262
|
-
...
|
|
74263
|
-
warnings: [...
|
|
74264
|
-
counts: { ...
|
|
74265
|
-
} :
|
|
74497
|
+
...report3,
|
|
74498
|
+
warnings: [...report3.warnings ?? [], ...advisories],
|
|
74499
|
+
counts: { ...report3.counts, warnings: report3.counts.warnings + advisories.length }
|
|
74500
|
+
} : report3;
|
|
74266
74501
|
await leaveForBoard(dir, "validate", {
|
|
74267
74502
|
ok: !hasErrors,
|
|
74268
74503
|
errors: finalReport.counts.errors,
|
|
@@ -74375,23 +74610,23 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74375
74610
|
const app = str8(flags.app) ?? loaded.app;
|
|
74376
74611
|
const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken: str8(flags["preview-token"]), boCookie: boCookie() });
|
|
74377
74612
|
const response = invoked2.response;
|
|
74378
|
-
const
|
|
74613
|
+
const text9 = await response.text();
|
|
74379
74614
|
let body2;
|
|
74380
74615
|
try {
|
|
74381
|
-
body2 = JSON.parse(
|
|
74616
|
+
body2 = JSON.parse(text9);
|
|
74382
74617
|
} catch {
|
|
74383
|
-
body2 =
|
|
74618
|
+
body2 = text9;
|
|
74384
74619
|
}
|
|
74385
74620
|
print({ ok: response.ok, app, releaseId: remoteRelease ?? null, url: invoked2.url, status: response.status, body: body2 });
|
|
74386
74621
|
return response.ok ? 0 : 1;
|
|
74387
74622
|
}
|
|
74388
74623
|
const invoked = await invokeLocalFunction2(loaded, name, input, params);
|
|
74389
|
-
const
|
|
74624
|
+
const text8 = await invoked.response.text();
|
|
74390
74625
|
let body;
|
|
74391
74626
|
try {
|
|
74392
|
-
body = JSON.parse(
|
|
74627
|
+
body = JSON.parse(text8);
|
|
74393
74628
|
} catch {
|
|
74394
|
-
body =
|
|
74629
|
+
body = text8;
|
|
74395
74630
|
}
|
|
74396
74631
|
print({ ok: invoked.response.ok, app: loaded.app, releaseId: invoked.releaseId, status: invoked.response.status, body });
|
|
74397
74632
|
return invoked.response.ok ? 0 : 1;
|
|
@@ -74410,7 +74645,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74410
74645
|
return 1;
|
|
74411
74646
|
}
|
|
74412
74647
|
const { himiPluginFiles: himiPluginFiles2 } = await Promise.resolve().then(() => (init_claude_plugin(), claude_plugin_exports));
|
|
74413
|
-
const dir =
|
|
74648
|
+
const dir = resolve52(out2);
|
|
74414
74649
|
const files = himiPluginFiles2(skills.skillMd);
|
|
74415
74650
|
for (const f of files) {
|
|
74416
74651
|
mkdirSync32(dirname36(join64(dir, f.path)), { recursive: true });
|
|
@@ -74432,7 +74667,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74432
74667
|
}
|
|
74433
74668
|
if (pos[1] === "reel") {
|
|
74434
74669
|
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
74435
|
-
const out2 =
|
|
74670
|
+
const out2 = resolve52(str8(flags.out) ?? join64(dir, ".himi", "making-of.html"));
|
|
74436
74671
|
const { html, plan } = buildReel2(dir);
|
|
74437
74672
|
mkdirSync32(dirname36(out2), { recursive: true });
|
|
74438
74673
|
writeFileSync29(out2, html);
|
|
@@ -74444,7 +74679,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74444
74679
|
openUrl2(url2);
|
|
74445
74680
|
}
|
|
74446
74681
|
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
|
|
74682
|
+
const report3 = {
|
|
74448
74683
|
ok: true,
|
|
74449
74684
|
file: out2,
|
|
74450
74685
|
url: url2,
|
|
@@ -74457,7 +74692,7 @@ ${doNow.map((l) => ` ${l}`).join("\n")}`);
|
|
|
74457
74692
|
...plan.dropped ? { dropped: plan.dropped, note: "pictures were left out to keep the file attachable" } : {},
|
|
74458
74693
|
...plan.frames.length === 0 ? { hint: "no screen versions were recorded \u2014 run `himi studio` before building so the board keeps them" } : {}
|
|
74459
74694
|
};
|
|
74460
|
-
if (flags.json === true || io.isTTY !== true) print(
|
|
74695
|
+
if (flags.json === true || io.isTTY !== true) print(report3);
|
|
74461
74696
|
else io.log(`The making-of: ${out2}
|
|
74462
74697
|
${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
74463
74698
|
return 0;
|
|
@@ -74543,10 +74778,10 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74543
74778
|
}
|
|
74544
74779
|
if (flags.brief === true) {
|
|
74545
74780
|
const { agentContextNote: agentContextNote2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
74546
|
-
const
|
|
74781
|
+
const summary2 = summarizeProgress2(readProgress2(dir).entries);
|
|
74547
74782
|
const open = openApprovals2(readApprovals2(dir).events);
|
|
74548
74783
|
const note = agentContextNote2(dir, cliVersion());
|
|
74549
|
-
io.log(formatBrief2({ appName: appLabel2(dir), isContentPackage, summary, open, ...note ? { agentContextNote: note } : {} }));
|
|
74784
|
+
io.log(formatBrief2({ appName: appLabel2(dir), isContentPackage, summary: summary2, open, ...note ? { agentContextNote: note } : {} }));
|
|
74550
74785
|
return 0;
|
|
74551
74786
|
}
|
|
74552
74787
|
if (!message) {
|
|
@@ -74604,9 +74839,9 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74604
74839
|
const sub = pos[1] ?? "audit";
|
|
74605
74840
|
const dir = contentDir(flags);
|
|
74606
74841
|
if (sub === "audit") {
|
|
74607
|
-
const
|
|
74608
|
-
print(
|
|
74609
|
-
return
|
|
74842
|
+
const report3 = auditUx(dir, flags.strict === true);
|
|
74843
|
+
print(report3);
|
|
74844
|
+
return report3.ok ? 0 : 1;
|
|
74610
74845
|
}
|
|
74611
74846
|
if (sub !== "record") {
|
|
74612
74847
|
io.error(JSON.stringify({ error: "ux needs audit | record" }));
|
|
@@ -74818,7 +75053,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74818
75053
|
}
|
|
74819
75054
|
const authoringBase = serveBase();
|
|
74820
75055
|
try {
|
|
74821
|
-
const { report:
|
|
75056
|
+
const { report: report3 } = await (deps.browserAuthoring ?? runBrowserAuthoring2)({
|
|
74822
75057
|
authoringBase,
|
|
74823
75058
|
job: {
|
|
74824
75059
|
entry: sources.entry,
|
|
@@ -74835,10 +75070,10 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74835
75070
|
log: (line) => io.error(line)
|
|
74836
75071
|
});
|
|
74837
75072
|
const { afterBrowserTestRun: afterBrowserTestRun2, watchReminder: watchReminder3 } = await Promise.resolve().then(() => (init_milestones(), milestones_exports));
|
|
74838
|
-
const afterRun2 = afterBrowserTestRun2(dir, { screen: screen.screenId, report:
|
|
75073
|
+
const afterRun2 = afterBrowserTestRun2(dir, { screen: screen.screenId, report: report3, boardOpen: boardOpen(dir) });
|
|
74839
75074
|
const browserReminder = watchReminder3(dir, { content: str8(flags.content) });
|
|
74840
75075
|
print({
|
|
74841
|
-
...
|
|
75076
|
+
...report3,
|
|
74842
75077
|
screen: screen.screenId,
|
|
74843
75078
|
ranIn: "browser",
|
|
74844
75079
|
liveRequested: jobWix !== void 0,
|
|
@@ -74847,7 +75082,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
74847
75082
|
// Also the envelope's LAST key (`tailLast` keeps it there): an agent may read only the tail.
|
|
74848
75083
|
...browserReminder ? { reminder: browserReminder } : {}
|
|
74849
75084
|
});
|
|
74850
|
-
return
|
|
75085
|
+
return report3.ok ? 0 : 1;
|
|
74851
75086
|
} catch (e) {
|
|
74852
75087
|
io.error(JSON.stringify({ error: e.message }));
|
|
74853
75088
|
return 1;
|
|
@@ -75193,7 +75428,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75193
75428
|
const pngTarget = typeof flags.png === "string" ? str8(flags.png) : flags.png === true ? shotPath : void 0;
|
|
75194
75429
|
if (pngTarget && r.pngBase64) {
|
|
75195
75430
|
pngFile = writePngFile(pngTarget, r.pngBase64);
|
|
75196
|
-
attestationPngFile =
|
|
75431
|
+
attestationPngFile = resolve52(pngTarget) === resolve52(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
|
|
75197
75432
|
}
|
|
75198
75433
|
if (renderWidth !== void 0 && r.renderable) {
|
|
75199
75434
|
recordRenderWidth(dir, {
|
|
@@ -75285,23 +75520,23 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75285
75520
|
return 2;
|
|
75286
75521
|
}
|
|
75287
75522
|
const { kitReport: kitReport2 } = await Promise.resolve().then(() => (init_design_kits(), design_kits_exports));
|
|
75288
|
-
const
|
|
75289
|
-
print(
|
|
75290
|
-
return
|
|
75523
|
+
const report3 = kitReport2(pos[2]);
|
|
75524
|
+
print(report3);
|
|
75525
|
+
return report3.ok ? 0 : 1;
|
|
75291
75526
|
}
|
|
75292
75527
|
case "fonts": {
|
|
75293
75528
|
const sub = pos[1];
|
|
75294
75529
|
const dir = contentDir(flags);
|
|
75295
75530
|
const { listReport: listReport3, checkReport: checkReport2, addReport: addReport2 } = await Promise.resolve().then(() => (init_fonts(), fonts_exports));
|
|
75296
75531
|
if (sub === void 0 || sub === "list") {
|
|
75297
|
-
const
|
|
75298
|
-
print(
|
|
75299
|
-
return
|
|
75532
|
+
const report3 = listReport3({ licenses: flags.licenses === true });
|
|
75533
|
+
print(report3);
|
|
75534
|
+
return report3.ok ? 0 : 1;
|
|
75300
75535
|
}
|
|
75301
75536
|
if (sub === "check") {
|
|
75302
|
-
const
|
|
75303
|
-
print(
|
|
75304
|
-
return
|
|
75537
|
+
const report3 = await checkReport2(dir);
|
|
75538
|
+
print(report3);
|
|
75539
|
+
return report3.ok ? 0 : 1;
|
|
75305
75540
|
}
|
|
75306
75541
|
if (sub === "add") {
|
|
75307
75542
|
const family = pos[2];
|
|
@@ -75309,9 +75544,9 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75309
75544
|
print({ ok: false, problems: ["usage: himi fonts add <Family>"] });
|
|
75310
75545
|
return 2;
|
|
75311
75546
|
}
|
|
75312
|
-
const
|
|
75313
|
-
print(
|
|
75314
|
-
return
|
|
75547
|
+
const report3 = addReport2(dir, family);
|
|
75548
|
+
print(report3);
|
|
75549
|
+
return report3.ok ? 0 : 1;
|
|
75315
75550
|
}
|
|
75316
75551
|
print({ ok: false, problems: [`unknown subcommand "${sub}"`], hint: "himi fonts [list|check|add]" });
|
|
75317
75552
|
return 2;
|
|
@@ -75332,7 +75567,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75332
75567
|
summarize: summarize4
|
|
75333
75568
|
} = await Promise.resolve().then(() => (init_icon(), icon_exports));
|
|
75334
75569
|
const requireVerified = sub === "check";
|
|
75335
|
-
const
|
|
75570
|
+
const report3 = async (status, extra = {}) => {
|
|
75336
75571
|
const findings = [
|
|
75337
75572
|
// Not a store rule, so it is not in byteIssues — but it is the one `himi dist`
|
|
75338
75573
|
// will refuse, and the point of `check` is to say so before the build does.
|
|
@@ -75370,7 +75605,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75370
75605
|
}
|
|
75371
75606
|
return blocksRelease2(status, { requireVerified }) ? 1 : 0;
|
|
75372
75607
|
};
|
|
75373
|
-
if (sub === "status" || sub === "check") return
|
|
75608
|
+
if (sub === "status" || sub === "check") return report3(await iconStatus2(dir));
|
|
75374
75609
|
if (sub === "set") {
|
|
75375
75610
|
const file = pos[2];
|
|
75376
75611
|
if (!file) {
|
|
@@ -75378,7 +75613,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75378
75613
|
return 1;
|
|
75379
75614
|
}
|
|
75380
75615
|
const res = await installIcon2(dir, file, { derivePlay: true });
|
|
75381
|
-
return
|
|
75616
|
+
return report3(res.status, { wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
75382
75617
|
}
|
|
75383
75618
|
if (sub === "from-site") {
|
|
75384
75619
|
const book = str8(flags.book) ?? ".himi/business-book";
|
|
@@ -75393,11 +75628,11 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
75393
75628
|
return 1;
|
|
75394
75629
|
}
|
|
75395
75630
|
const res = await installIcon2(dir, logo, { derivePlay: true });
|
|
75396
|
-
return
|
|
75631
|
+
return report3(res.status, { from: logo, wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
75397
75632
|
}
|
|
75398
75633
|
if (sub === "generate") {
|
|
75399
75634
|
const res = await generateIcon2(dir, { glyph: str8(flags.glyph), background: str8(flags.accent), derivePlay: true });
|
|
75400
|
-
return
|
|
75635
|
+
return report3(res.status, { wrote: res.wrote });
|
|
75401
75636
|
}
|
|
75402
75637
|
if (sub === "glyphs") {
|
|
75403
75638
|
const names = glyphNames2();
|
|
@@ -75423,9 +75658,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75423
75658
|
const dir = contentDir(flags);
|
|
75424
75659
|
const { listReport: listReport3, verifyReport: verifyReport2, addAssetPayload: addAssetPayload2, removeAssetPayload: removeAssetPayload2 } = await Promise.resolve().then(() => (init_assets(), assets_exports));
|
|
75425
75660
|
if (sub === void 0 || sub === "list") {
|
|
75426
|
-
const
|
|
75427
|
-
print(
|
|
75428
|
-
return
|
|
75661
|
+
const report3 = listReport3(dir);
|
|
75662
|
+
print(report3);
|
|
75663
|
+
return report3.ok ? 0 : 1;
|
|
75429
75664
|
}
|
|
75430
75665
|
if (sub === "verify") {
|
|
75431
75666
|
const app = str8(flags.app) ?? await appId(dir);
|
|
@@ -75434,9 +75669,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75434
75669
|
io.error(JSON.stringify(found));
|
|
75435
75670
|
return 1;
|
|
75436
75671
|
}
|
|
75437
|
-
const
|
|
75438
|
-
print(
|
|
75439
|
-
return
|
|
75672
|
+
const report3 = verifyReport2(dir, app, found.manifest);
|
|
75673
|
+
print(report3);
|
|
75674
|
+
return report3.ok ? 0 : 1;
|
|
75440
75675
|
}
|
|
75441
75676
|
if (sub === "add" || sub === "rm") {
|
|
75442
75677
|
const app = str8(flags.app) ?? await appId(dir);
|
|
@@ -75529,7 +75764,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75529
75764
|
return 2;
|
|
75530
75765
|
}
|
|
75531
75766
|
const renamed = str8(flags.name);
|
|
75532
|
-
const dest =
|
|
75767
|
+
const dest = resolve52(str8(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
75533
75768
|
const replace = flags.replace === true;
|
|
75534
75769
|
const force = replace || flags.force === true;
|
|
75535
75770
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -75602,7 +75837,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75602
75837
|
let removed = [];
|
|
75603
75838
|
if (replace) removed = removeStaleSource2(restored, dest);
|
|
75604
75839
|
else left = staleSourcePaths2(restored, dest);
|
|
75605
|
-
const
|
|
75840
|
+
const refused2 = deniedArchivePaths2(restored);
|
|
75606
75841
|
const written = writeAppSource2(restored, dest);
|
|
75607
75842
|
const agent = await seedAgentFilesFor(dest, flags, "restore");
|
|
75608
75843
|
print({
|
|
@@ -75613,8 +75848,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75613
75848
|
...agent,
|
|
75614
75849
|
...renamed ? { renamedTo: renamed } : {},
|
|
75615
75850
|
...removed.length ? { removed } : {},
|
|
75616
|
-
...
|
|
75617
|
-
refused,
|
|
75851
|
+
...refused2.length ? {
|
|
75852
|
+
refused: refused2,
|
|
75618
75853
|
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
75854
|
} : {},
|
|
75620
75855
|
// EVERY path, not a count and not a sample: the whole failure was that a hybrid tree
|
|
@@ -75698,7 +75933,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75698
75933
|
collect: { lint: true, strict }
|
|
75699
75934
|
});
|
|
75700
75935
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
75701
|
-
const { report:
|
|
75936
|
+
const { report: report3, hasErrors } = summarizeLint(declared, bres, outcome, strict, [
|
|
75702
75937
|
...await cmsIssues(dir, declared, strict, { local: true }),
|
|
75703
75938
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
75704
75939
|
...tokenColorIssues(dir),
|
|
@@ -75708,7 +75943,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75708
75943
|
...await navIssues2(dir, strict)
|
|
75709
75944
|
]);
|
|
75710
75945
|
if (hasErrors && !force) {
|
|
75711
|
-
print({ ...
|
|
75946
|
+
print({ ...report3, pushed: false, hint: "lint found errors \u2014 fix them, or re-run `himi push --force` to publish anyway" });
|
|
75712
75947
|
return 1;
|
|
75713
75948
|
}
|
|
75714
75949
|
const declaredData = await loadDataResourcesQuietly(dir);
|
|
@@ -75807,7 +76042,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
75807
76042
|
// Reaches here ONLY on the forced path — the refusal above returned otherwise — so
|
|
75808
76043
|
// this is the override's record, and the case it matters most for is a `failed` drive.
|
|
75809
76044
|
ux: { evidence: patchUxEvidence, ctx: patchUxContext },
|
|
75810
|
-
lint:
|
|
76045
|
+
lint: report3.counts ?? null,
|
|
75811
76046
|
extra: { selector: parsed.selectors.map((s) => "pattern" in s ? `${s.kind}:${s.pattern}` : s.kind) }
|
|
75812
76047
|
});
|
|
75813
76048
|
}
|
|
@@ -76059,7 +76294,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76059
76294
|
// print a `himi pull` command that answers app_source_not_found later — the worst
|
|
76060
76295
|
// shape for a backup, which is one you are told you have.
|
|
76061
76296
|
...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:
|
|
76297
|
+
lint: report3.counts,
|
|
76063
76298
|
// A push ships content, not backends. If the app declares CMS
|
|
76064
76299
|
// collections, say so and point at the verbs — but never mutate the
|
|
76065
76300
|
// site as a side effect of publishing a release.
|
|
@@ -76091,7 +76326,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76091
76326
|
nondeterministicWorkers: drifting
|
|
76092
76327
|
}),
|
|
76093
76328
|
...loopbackWarning ? { warning: loopbackWarning } : {},
|
|
76094
|
-
...
|
|
76329
|
+
...report3.issues ? { issues: report3.issues } : {},
|
|
76095
76330
|
previewWeb: base ? previewWebUrl(base, app, release, void 0, void 0, previewToken, previewHandover) : null,
|
|
76096
76331
|
// A timestamp alone leaves the reader to work out both how long they have and how to
|
|
76097
76332
|
// get another one. Print the duration and the re-mint command beside it (#2502 item 3).
|
|
@@ -76188,7 +76423,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76188
76423
|
return 2;
|
|
76189
76424
|
}
|
|
76190
76425
|
try {
|
|
76191
|
-
const res = writePack(
|
|
76426
|
+
const res = writePack(resolve52(releaseDir), only, resolve52(str8(flags.out) ?? process.cwd()));
|
|
76192
76427
|
print({
|
|
76193
76428
|
ok: true,
|
|
76194
76429
|
app: res.app,
|
|
@@ -76244,7 +76479,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76244
76479
|
collect: { lint: true, strict }
|
|
76245
76480
|
});
|
|
76246
76481
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
76247
|
-
const { report:
|
|
76482
|
+
const { report: report3, hasErrors } = summarizeLint(app, bres, outcome, strict, [
|
|
76248
76483
|
...await cmsIssues(dir, app, strict, { local: true }),
|
|
76249
76484
|
...surfaceIssues(dir, outcome.surfaceNav, strict),
|
|
76250
76485
|
...tokenColorIssues(dir),
|
|
@@ -76255,11 +76490,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76255
76490
|
]);
|
|
76256
76491
|
if (hasErrors && !force) {
|
|
76257
76492
|
rmSync15(built, { recursive: true, force: true });
|
|
76258
|
-
print({ ...
|
|
76493
|
+
print({ ...report3, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
76259
76494
|
return 1;
|
|
76260
76495
|
}
|
|
76261
76496
|
try {
|
|
76262
|
-
const res = writePack(built, app,
|
|
76497
|
+
const res = writePack(built, app, resolve52(str8(flags.out) ?? dir), sourceArchive);
|
|
76263
76498
|
print({
|
|
76264
76499
|
ok: true,
|
|
76265
76500
|
app: res.app,
|
|
@@ -76269,12 +76504,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76269
76504
|
entries: res.entryCount,
|
|
76270
76505
|
format,
|
|
76271
76506
|
launchMode,
|
|
76272
|
-
lint:
|
|
76507
|
+
lint: report3.counts,
|
|
76273
76508
|
contents: withSource ? "dev" : "release",
|
|
76274
76509
|
...sourceSummary ? { source: sourceSummary } : {},
|
|
76275
76510
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
76276
76511
|
...hasErrors && force ? { forcedPastErrors: true } : {},
|
|
76277
|
-
...
|
|
76512
|
+
...report3.issues ? { issues: report3.issues } : {},
|
|
76278
76513
|
open: [
|
|
76279
76514
|
...withSource ? [`himi import ${res.out}`] : [],
|
|
76280
76515
|
`himi run ${res.out}`,
|
|
@@ -76304,7 +76539,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76304
76539
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
76305
76540
|
let opened;
|
|
76306
76541
|
try {
|
|
76307
|
-
opened = openPackageFile2(
|
|
76542
|
+
opened = openPackageFile2(resolve52(file));
|
|
76308
76543
|
} catch (e) {
|
|
76309
76544
|
io.error(JSON.stringify({ error: e.message }));
|
|
76310
76545
|
return 1;
|
|
@@ -76317,7 +76552,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76317
76552
|
io.error(JSON.stringify({
|
|
76318
76553
|
ok: false,
|
|
76319
76554
|
error: "app_source_not_in_package",
|
|
76320
|
-
detail: `${
|
|
76555
|
+
detail: `${resolve52(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
76321
76556
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
76322
76557
|
}));
|
|
76323
76558
|
return 1;
|
|
@@ -76340,7 +76575,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76340
76575
|
return 1;
|
|
76341
76576
|
}
|
|
76342
76577
|
}
|
|
76343
|
-
const dest =
|
|
76578
|
+
const dest = resolve52(str8(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
76344
76579
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
76345
76580
|
if (issue2) {
|
|
76346
76581
|
io.error(JSON.stringify(issue2));
|
|
@@ -76379,7 +76614,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76379
76614
|
return 1;
|
|
76380
76615
|
}
|
|
76381
76616
|
const left = staleSourcePaths2(restored, dest);
|
|
76382
|
-
const
|
|
76617
|
+
const refused2 = deniedArchivePaths2(restored);
|
|
76383
76618
|
const written = writeAppSource2(restored, dest);
|
|
76384
76619
|
const agent = await seedAgentFilesFor(dest, flags, "restore");
|
|
76385
76620
|
print({
|
|
@@ -76390,8 +76625,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76390
76625
|
files: written.length,
|
|
76391
76626
|
...agent,
|
|
76392
76627
|
...renamed ? { renamedTo: renamed } : {},
|
|
76393
|
-
...
|
|
76394
|
-
refused,
|
|
76628
|
+
...refused2.length ? {
|
|
76629
|
+
refused: refused2,
|
|
76395
76630
|
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
76631
|
} : {},
|
|
76397
76632
|
...left.length ? {
|
|
@@ -76427,7 +76662,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76427
76662
|
}
|
|
76428
76663
|
try {
|
|
76429
76664
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
76430
|
-
const opened = openPackageFile2(
|
|
76665
|
+
const opened = openPackageFile2(resolve52(file));
|
|
76431
76666
|
if (!opened.validation.ok || !opened.header) {
|
|
76432
76667
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
76433
76668
|
return 1;
|
|
@@ -76437,12 +76672,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76437
76672
|
io.error(JSON.stringify({
|
|
76438
76673
|
ok: false,
|
|
76439
76674
|
error: "refusing to share a package that carries the app's source",
|
|
76440
|
-
detail: `${
|
|
76675
|
+
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
76676
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
76442
76677
|
}));
|
|
76443
76678
|
return 1;
|
|
76444
76679
|
}
|
|
76445
|
-
const archive = readFileSync79(
|
|
76680
|
+
const archive = readFileSync79(resolve52(file));
|
|
76446
76681
|
const result = await client2().createPackageShare({
|
|
76447
76682
|
app: opened.header.app,
|
|
76448
76683
|
releaseId: opened.header.releaseId,
|
|
@@ -76581,9 +76816,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
76581
76816
|
});
|
|
76582
76817
|
await announce(run2);
|
|
76583
76818
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
76584
|
-
await new Promise((
|
|
76819
|
+
await new Promise((resolve53) => {
|
|
76585
76820
|
const stop = () => {
|
|
76586
|
-
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() =>
|
|
76821
|
+
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() => resolve53()));
|
|
76587
76822
|
};
|
|
76588
76823
|
process.once("SIGINT", stop);
|
|
76589
76824
|
process.once("SIGTERM", stop);
|
|
@@ -78623,13 +78858,13 @@ ${label2}`);
|
|
|
78623
78858
|
// advertisable for the target this report is about.
|
|
78624
78859
|
hasOwnerIssuer: (resolved2?.ownerIssue ?? "") !== ""
|
|
78625
78860
|
});
|
|
78626
|
-
const
|
|
78627
|
-
if (targetError)
|
|
78861
|
+
const report3 = buildDoctorReport({ target, version: cliVersion(), data, serve, auth, loginModes, dpxStatus, versions });
|
|
78862
|
+
if (targetError) report3.targetError = targetError;
|
|
78628
78863
|
const { agentContextStatus: agentContextStatus2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
78629
78864
|
const agentContext = agentContextStatus2(contentDir(flags), cliVersion());
|
|
78630
|
-
if (agentContext)
|
|
78865
|
+
if (agentContext) report3.agentContext = agentContext;
|
|
78631
78866
|
if (flags.json === true) {
|
|
78632
|
-
print(
|
|
78867
|
+
print(report3);
|
|
78633
78868
|
return 0;
|
|
78634
78869
|
}
|
|
78635
78870
|
const mark = (r) => r.reachable ? `reachable${r.status ? ` [${r.status}]` : ""}` : `UNREACHABLE${r.error ? ` (${r.error})` : ""}`;
|
|
@@ -78639,7 +78874,7 @@ ${label2}`);
|
|
|
78639
78874
|
io.log(` ${mark(data)}`);
|
|
78640
78875
|
io.log(` serve plane ${serveUrl || "(no serve url)"}`);
|
|
78641
78876
|
io.log(` ${mark(serve)}`);
|
|
78642
|
-
const serveCode =
|
|
78877
|
+
const serveCode = report3.servePlane.code;
|
|
78643
78878
|
if (serveCode) io.log(` ${serveCode}: ${serveUnreachableHint(target)}`);
|
|
78644
78879
|
io.log(` auth dpx session: ${auth.dpxSession ? "yes" : "no"} control token: ${auth.controlToken ? "yes" : controlHostRefused ? "REFUSED" : auth.controlTokenPresent ? "STALE" : "no"}`);
|
|
78645
78880
|
if (auth.controlTokenHint) io.log(` ${auth.controlTokenHint}`);
|
|
@@ -78662,7 +78897,7 @@ ${label2}`);
|
|
|
78662
78897
|
}
|
|
78663
78898
|
io.log(
|
|
78664
78899
|
`
|
|
78665
|
-
${
|
|
78900
|
+
${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
78901
|
);
|
|
78667
78902
|
return 0;
|
|
78668
78903
|
}
|
|
@@ -78775,9 +79010,9 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78775
79010
|
}
|
|
78776
79011
|
const scope = { app, siteId: site, environment: environment2 };
|
|
78777
79012
|
try {
|
|
78778
|
-
const
|
|
78779
|
-
print(
|
|
78780
|
-
return
|
|
79013
|
+
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 });
|
|
79014
|
+
print(report3);
|
|
79015
|
+
return report3.ok ? 0 : 1;
|
|
78781
79016
|
} catch (error) {
|
|
78782
79017
|
io.error(JSON.stringify({ error: error.message, app, site, environment: environment2, hint: "run `himi data plan` to re-read actual state before retrying" }));
|
|
78783
79018
|
return 1;
|
|
@@ -78792,6 +79027,14 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78792
79027
|
const { runNotifySetup: runNotifySetup2 } = await Promise.resolve().then(() => (init_notify_setup(), notify_setup_exports));
|
|
78793
79028
|
return runNotifySetup2(pos, flags, io);
|
|
78794
79029
|
}
|
|
79030
|
+
if (pos[1] === "send" && flags.provider !== void 0) {
|
|
79031
|
+
if (flags.provider !== "ping") {
|
|
79032
|
+
io.error(JSON.stringify({ ok: false, error: "unknown_provider", hint: "The hosted sender is --provider ping." }));
|
|
79033
|
+
return 2;
|
|
79034
|
+
}
|
|
79035
|
+
const { runNotifyPing: runNotifyPing2 } = await Promise.resolve().then(() => (init_notify_ping(), notify_ping_exports));
|
|
79036
|
+
return runNotifyPing2(flags, io);
|
|
79037
|
+
}
|
|
78795
79038
|
const { runNotify: runNotify2 } = await Promise.resolve().then(() => (init_notify(), notify_exports));
|
|
78796
79039
|
return await runNotify2(pos, flags, io);
|
|
78797
79040
|
case "cms": {
|
|
@@ -78850,9 +79093,9 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78850
79093
|
return 2;
|
|
78851
79094
|
}
|
|
78852
79095
|
const common = { app, cms, call };
|
|
78853
|
-
let
|
|
79096
|
+
let report3;
|
|
78854
79097
|
try {
|
|
78855
|
-
|
|
79098
|
+
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
79099
|
} catch (e) {
|
|
78857
79100
|
const partial = e.partial;
|
|
78858
79101
|
io.error(JSON.stringify({
|
|
@@ -78864,8 +79107,8 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
78864
79107
|
}));
|
|
78865
79108
|
return 1;
|
|
78866
79109
|
}
|
|
78867
|
-
print({ ...
|
|
78868
|
-
return
|
|
79110
|
+
print({ ...report3, site });
|
|
79111
|
+
return report3.ok ? 0 : 1;
|
|
78869
79112
|
}
|
|
78870
79113
|
case "site": {
|
|
78871
79114
|
const sub = pos[1];
|