@wix/himalaya-cli 0.1385.0 → 0.1387.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/authoring-runtime/node_modules/@wix/himalaya/dist/wix-auth.mjs +9 -0
- package/dist/cli.mjs +1254 -492
- package/guides/branded-lite-site-binding.md +12 -5
- package/guides/himi-json-output.md +13 -3
- package/guides/iap-products.md +91 -11
- package/package.json +2 -2
- package/templates/beauty-salon/README.md +8 -3
- package/templates/branded-lite/README.md +8 -3
- package/templates/community-club/README.md +8 -3
- package/templates/events-meetups/README.md +8 -3
- package/templates/gym-fitness/README.md +8 -3
- package/templates/nonprofit-cause/README.md +8 -3
- package/templates/podcast-creator/README.md +8 -3
- package/templates/portfolio-creative/README.md +8 -3
- package/templates/restaurant/README.md +8 -3
- package/templates/retail-store/README.md +8 -3
- package/templates/yoga-studio/README.md +8 -3
package/dist/cli.mjs
CHANGED
|
@@ -3738,7 +3738,7 @@ async function browserLogin(opts) {
|
|
|
3738
3738
|
const log = opts.log ?? (() => {
|
|
3739
3739
|
});
|
|
3740
3740
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3741
|
-
return await new Promise((
|
|
3741
|
+
return await new Promise((resolve65, reject) => {
|
|
3742
3742
|
let settled = false;
|
|
3743
3743
|
let loginUrl = "";
|
|
3744
3744
|
const server = createServer();
|
|
@@ -3804,7 +3804,7 @@ async function browserLogin(opts) {
|
|
|
3804
3804
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(closePage(opts.doneTitle ?? "Signed in to himi"));
|
|
3805
3805
|
const extra = {};
|
|
3806
3806
|
for (const [k2, v2] of params) if (k2 !== "token" && k2 !== "state") extra[k2] = v2;
|
|
3807
|
-
finish2(() =>
|
|
3807
|
+
finish2(() => resolve65({ token, loginUrl, extra }));
|
|
3808
3808
|
});
|
|
3809
3809
|
});
|
|
3810
3810
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -3916,7 +3916,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
3916
3916
|
tokenCache.set(cacheKey, fromEnv);
|
|
3917
3917
|
return fromEnv;
|
|
3918
3918
|
}
|
|
3919
|
-
const token = await new Promise((
|
|
3919
|
+
const token = await new Promise((resolve65, reject) => {
|
|
3920
3920
|
let child;
|
|
3921
3921
|
try {
|
|
3922
3922
|
child = spawnImpl("wix", [...args]);
|
|
@@ -3945,12 +3945,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
3945
3945
|
child.stdout?.on("data", (d2) => {
|
|
3946
3946
|
out2 += String(d2);
|
|
3947
3947
|
const m2 = out2.match(TOKEN_RE);
|
|
3948
|
-
if (m2) done(() =>
|
|
3948
|
+
if (m2) done(() => resolve65(m2[0]));
|
|
3949
3949
|
});
|
|
3950
3950
|
child.stderr?.on("data", (d2) => {
|
|
3951
3951
|
out2 += String(d2);
|
|
3952
3952
|
const m2 = out2.match(TOKEN_RE);
|
|
3953
|
-
if (m2) done(() =>
|
|
3953
|
+
if (m2) done(() => resolve65(m2[0]));
|
|
3954
3954
|
});
|
|
3955
3955
|
child.on("error", (e2) => done(() => reject(new Error(mintHelp(label2, e2.message)))));
|
|
3956
3956
|
child.on("exit", (code) => done(() => reject(new Error(
|
|
@@ -4160,8 +4160,8 @@ function committedProvisioningPath(name) {
|
|
|
4160
4160
|
function committedShellFor(path2) {
|
|
4161
4161
|
const normalized = path2.replace(/\\/g, "/");
|
|
4162
4162
|
return SHELL_NAMES2.find((name) => {
|
|
4163
|
-
const
|
|
4164
|
-
return normalized ===
|
|
4163
|
+
const relative17 = committedProvisioningPath(name);
|
|
4164
|
+
return normalized === relative17 || normalized.endsWith(`/${relative17}`);
|
|
4165
4165
|
});
|
|
4166
4166
|
}
|
|
4167
4167
|
function isBrandable(repoRoot2, name) {
|
|
@@ -6876,9 +6876,9 @@ function compileV2(html, profile, options) {
|
|
|
6876
6876
|
if (!row) error(el2, "HHP-BINDING-SCOPE", "Item bindings require a keyed list template.");
|
|
6877
6877
|
return raw;
|
|
6878
6878
|
}
|
|
6879
|
-
const
|
|
6880
|
-
if (!info4?.paths.has(
|
|
6881
|
-
return `$service:${serviceName}.${
|
|
6879
|
+
const relative17 = statePath(raw);
|
|
6880
|
+
if (!info4?.paths.has(relative17)) error(el2, "HHP-BINDING-PATH", `Unknown controller state path ${relative17}.`);
|
|
6881
|
+
return `$service:${serviceName}.${relative17}`;
|
|
6882
6882
|
}
|
|
6883
6883
|
function coerce(raw, field) {
|
|
6884
6884
|
if (field.schema.type === "boolean") return raw === "" || raw === "true" ? true : raw === "false" ? false : raw;
|
|
@@ -7708,7 +7708,6 @@ function resolveTranslation(value, catalog3, sourceCatalog) {
|
|
|
7708
7708
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
7709
7709
|
var init_bindings = __esm({
|
|
7710
7710
|
"../../core/ts/src/bindings.ts"() {
|
|
7711
|
-
"use strict";
|
|
7712
7711
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
7713
7712
|
BINDING_SIGIL_RE = new RegExp(
|
|
7714
7713
|
`^\\$(?:${BINDING_SIGILS.filter((s2) => s2 !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -10250,7 +10249,8 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
10250
10249
|
}
|
|
10251
10250
|
return value;
|
|
10252
10251
|
});
|
|
10253
|
-
}
|
|
10252
|
+
},
|
|
10253
|
+
...opts.wixApiSession ? { identityBound: opts.wixApiSession.identityBound, session: opts.wixApiSession.session } : {}
|
|
10254
10254
|
};
|
|
10255
10255
|
const dispatchHost = (action, params) => {
|
|
10256
10256
|
if (action === "himi.open" && params && typeof params.screenId === "string") {
|
|
@@ -25434,10 +25434,10 @@ var init_preview = __esm({
|
|
|
25434
25434
|
}
|
|
25435
25435
|
},
|
|
25436
25436
|
kill: (pid, signal) => process.kill(pid, signal),
|
|
25437
|
-
portFree: (port) => new Promise((
|
|
25437
|
+
portFree: (port) => new Promise((resolve65) => {
|
|
25438
25438
|
const s2 = createServer2();
|
|
25439
|
-
s2.once("error", () =>
|
|
25440
|
-
s2.listen(port, "127.0.0.1", () => s2.close(() =>
|
|
25439
|
+
s2.once("error", () => resolve65(false));
|
|
25440
|
+
s2.listen(port, "127.0.0.1", () => s2.close(() => resolve65(true)));
|
|
25441
25441
|
}),
|
|
25442
25442
|
sleep: (ms2) => new Promise((r2) => setTimeout(r2, ms2)),
|
|
25443
25443
|
servingIdentity: async (origin) => {
|
|
@@ -29428,7 +29428,7 @@ async function injectRequest(listener, request) {
|
|
|
29428
29428
|
req.headers.host ??= url.host;
|
|
29429
29429
|
if (body && body.length > 0) req.push(body);
|
|
29430
29430
|
req.push(null);
|
|
29431
|
-
return await new Promise((
|
|
29431
|
+
return await new Promise((resolve65, reject) => {
|
|
29432
29432
|
const streamed = () => {
|
|
29433
29433
|
queueMicrotask(() => {
|
|
29434
29434
|
req.emit("close");
|
|
@@ -29444,7 +29444,7 @@ async function injectRequest(listener, request) {
|
|
|
29444
29444
|
else headers2.set(name, value);
|
|
29445
29445
|
}
|
|
29446
29446
|
const bodyless = out2.status === 204 || out2.status === 304 || request.method === "HEAD";
|
|
29447
|
-
|
|
29447
|
+
resolve65(new Response(bodyless ? null : out2.body, { status: out2.status, headers: headers2 }));
|
|
29448
29448
|
}, streamed);
|
|
29449
29449
|
res.on("inject-error", reject);
|
|
29450
29450
|
try {
|
|
@@ -35581,12 +35581,12 @@ function finalizeRecording(key2, rec) {
|
|
|
35581
35581
|
if (rec.finalize) return rec.finalize;
|
|
35582
35582
|
rec.finalize = (async () => {
|
|
35583
35583
|
clearTimeout(rec.autoStop);
|
|
35584
|
-
await new Promise((
|
|
35584
|
+
await new Promise((resolve65) => {
|
|
35585
35585
|
let done = false;
|
|
35586
35586
|
const finish2 = () => {
|
|
35587
35587
|
if (!done) {
|
|
35588
35588
|
done = true;
|
|
35589
|
-
|
|
35589
|
+
resolve65();
|
|
35590
35590
|
}
|
|
35591
35591
|
};
|
|
35592
35592
|
rec.child.once("close", finish2);
|
|
@@ -35697,7 +35697,7 @@ var init_preview2 = __esm({
|
|
|
35697
35697
|
DEVICE_LIST_TIMEOUT_MS = 5e3;
|
|
35698
35698
|
defaultRunner2 = {
|
|
35699
35699
|
capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
|
|
35700
|
-
return new Promise((
|
|
35700
|
+
return new Promise((resolve65, reject) => {
|
|
35701
35701
|
const child = spawn4(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
35702
35702
|
const out2 = [];
|
|
35703
35703
|
const err = [];
|
|
@@ -35719,7 +35719,7 @@ var init_preview2 = __esm({
|
|
|
35719
35719
|
child.stderr.on("data", (b2) => err.push(b2));
|
|
35720
35720
|
child.on("error", (e2) => settle(reject, e2));
|
|
35721
35721
|
child.on("close", (code) => {
|
|
35722
|
-
if (code === 0) settle(
|
|
35722
|
+
if (code === 0) settle(resolve65, Buffer.concat(out2));
|
|
35723
35723
|
else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
|
|
35724
35724
|
});
|
|
35725
35725
|
});
|
|
@@ -38032,12 +38032,12 @@ function createRicosHostSession(o2) {
|
|
|
38032
38032
|
flush() {
|
|
38033
38033
|
if (!state.ready || state.unavailable || disposed) return Promise.resolve(null);
|
|
38034
38034
|
const requestId2 = newId();
|
|
38035
|
-
return new Promise((
|
|
38035
|
+
return new Promise((resolve65) => {
|
|
38036
38036
|
const timer = t2.setTimeout(() => {
|
|
38037
38037
|
flushes.delete(requestId2);
|
|
38038
|
-
|
|
38038
|
+
resolve65(null);
|
|
38039
38039
|
}, flushMs);
|
|
38040
|
-
flushes.set(requestId2, { resolve:
|
|
38040
|
+
flushes.set(requestId2, { resolve: resolve65, timer });
|
|
38041
38041
|
o2.send({ v: 1, type: "requestContent", requestId: requestId2 });
|
|
38042
38042
|
});
|
|
38043
38043
|
},
|
|
@@ -38096,7 +38096,7 @@ async function runRicosImageUpload(o2) {
|
|
|
38096
38096
|
};
|
|
38097
38097
|
session.insertMediaPlaceholder(requestId2);
|
|
38098
38098
|
try {
|
|
38099
|
-
const entry = await new Promise((
|
|
38099
|
+
const entry = await new Promise((resolve65) => {
|
|
38100
38100
|
let done = false;
|
|
38101
38101
|
let unsub = () => {
|
|
38102
38102
|
};
|
|
@@ -38105,7 +38105,7 @@ async function runRicosImageUpload(o2) {
|
|
|
38105
38105
|
done = true;
|
|
38106
38106
|
t2.clearTimeout(timer);
|
|
38107
38107
|
queueMicrotask(() => unsub());
|
|
38108
|
-
|
|
38108
|
+
resolve65(v2);
|
|
38109
38109
|
};
|
|
38110
38110
|
const timer = t2.setTimeout(() => finish2(null), o2.timeoutMs ?? RICOS_UPLOAD_TIMEOUT_MS);
|
|
38111
38111
|
unsub = deps.subscribe(`${svc}.uploads.${requestId2}`, (v2) => {
|
|
@@ -38627,10 +38627,10 @@ async function runMediaFieldUpload(o2) {
|
|
|
38627
38627
|
}, o2.timeoutMs ?? MEDIA_FIELD_UPLOAD_TIMEOUT_MS);
|
|
38628
38628
|
const bounded2 = (p2) => {
|
|
38629
38629
|
if (expired) return Promise.reject(new Deadline());
|
|
38630
|
-
return new Promise((
|
|
38630
|
+
return new Promise((resolve65, reject) => {
|
|
38631
38631
|
const stop = () => reject(new Deadline());
|
|
38632
38632
|
onExpire.push(stop);
|
|
38633
|
-
p2.then(
|
|
38633
|
+
p2.then(resolve65, reject).finally(() => {
|
|
38634
38634
|
onExpire = onExpire.filter((f2) => f2 !== stop);
|
|
38635
38635
|
});
|
|
38636
38636
|
});
|
|
@@ -38653,7 +38653,7 @@ async function runMediaFieldUpload(o2) {
|
|
|
38653
38653
|
const before = deps.value(urlPath);
|
|
38654
38654
|
let uploadUrl;
|
|
38655
38655
|
try {
|
|
38656
|
-
uploadUrl = await bounded2(new Promise((
|
|
38656
|
+
uploadUrl = await bounded2(new Promise((resolve65, reject) => {
|
|
38657
38657
|
let done = false;
|
|
38658
38658
|
let unsub = () => {
|
|
38659
38659
|
};
|
|
@@ -38661,7 +38661,7 @@ async function runMediaFieldUpload(o2) {
|
|
|
38661
38661
|
if (done || typeof v2 !== "string" || v2 === "" || v2 === before) return;
|
|
38662
38662
|
done = true;
|
|
38663
38663
|
queueMicrotask(() => unsub());
|
|
38664
|
-
|
|
38664
|
+
resolve65(v2);
|
|
38665
38665
|
});
|
|
38666
38666
|
onExpire.push(() => {
|
|
38667
38667
|
if (!done) {
|
|
@@ -38676,7 +38676,7 @@ async function runMediaFieldUpload(o2) {
|
|
|
38676
38676
|
if (typeof now === "string" && now !== "" && now !== before) {
|
|
38677
38677
|
done = true;
|
|
38678
38678
|
queueMicrotask(() => unsub());
|
|
38679
|
-
|
|
38679
|
+
resolve65(now);
|
|
38680
38680
|
return;
|
|
38681
38681
|
}
|
|
38682
38682
|
}
|
|
@@ -39122,7 +39122,7 @@ var init_controls = __esm({
|
|
|
39122
39122
|
}, [selectedId]);
|
|
39123
39123
|
const current = local != null && tabs.some((t2) => t2.id === local) ? local : selectedId;
|
|
39124
39124
|
const selIdx = Math.max(0, tabs.findIndex((t2) => t2.id === (current ?? tabs[0]?.id)));
|
|
39125
|
-
const
|
|
39125
|
+
const select2 = (i2) => {
|
|
39126
39126
|
if (pages2) setLocal(tabs[i2]?.id);
|
|
39127
39127
|
const act = actOf(tabs[i2], props.onChange ?? props.onSelect);
|
|
39128
39128
|
if (ctx.onAction && act) ctx.onAction(withSelection(act, { selectedId: String(tabs[i2]?.id ?? i2) }));
|
|
@@ -39135,7 +39135,7 @@ var init_controls = __esm({
|
|
|
39135
39135
|
else if (e2.key === "End") ni2 = tabs.length - 1;
|
|
39136
39136
|
else return;
|
|
39137
39137
|
e2.preventDefault();
|
|
39138
|
-
if (ni2 !== selIdx)
|
|
39138
|
+
if (ni2 !== selIdx) select2(ni2);
|
|
39139
39139
|
};
|
|
39140
39140
|
const pagerRef = React5.useRef(null);
|
|
39141
39141
|
const settle = React5.useRef(void 0);
|
|
@@ -39152,7 +39152,7 @@ var init_controls = __esm({
|
|
|
39152
39152
|
const el2 = pagerRef.current;
|
|
39153
39153
|
if (!el2 || !el2.clientWidth) return;
|
|
39154
39154
|
const i2 = Math.round(el2.scrollLeft / el2.clientWidth);
|
|
39155
|
-
if (i2 >= 0 && i2 < tabs.length && i2 !== selIdx)
|
|
39155
|
+
if (i2 >= 0 && i2 < tabs.length && i2 !== selIdx) select2(i2);
|
|
39156
39156
|
}, 120);
|
|
39157
39157
|
};
|
|
39158
39158
|
const accent = C2("accentPrimary", "#116DFF");
|
|
@@ -39167,7 +39167,7 @@ var init_controls = __esm({
|
|
|
39167
39167
|
role: "tab",
|
|
39168
39168
|
"aria-selected": on4,
|
|
39169
39169
|
tabIndex: on4 ? 0 : -1,
|
|
39170
|
-
onClick: () =>
|
|
39170
|
+
onClick: () => select2(i2),
|
|
39171
39171
|
style: { all: "unset", display: "flex", gap: 6, alignItems: "center", minWidth: 44, minHeight: 44, padding: "10px 0", fontFamily: FONT(ctx), fontWeight: 600, fontSize: pxToRem(14), cursor: "pointer", color: on4 ? activeLabel : C2("textSecondary", "#777"), borderBottom: on4 ? `2px solid ${activeTint}` : "2px solid transparent", marginBottom: -1 },
|
|
39172
39172
|
children: [
|
|
39173
39173
|
asText2(t2.label),
|
|
@@ -39210,7 +39210,7 @@ var init_controls = __esm({
|
|
|
39210
39210
|
const awaitingBinding = isBinding(props.selectedId) && resolvedSel == null;
|
|
39211
39211
|
const selId = ctx.empty || awaitingBinding ? null : resolvedSel ?? opts[0]?.id;
|
|
39212
39212
|
const selIdx = Math.max(0, opts.findIndex((o2) => o2.id === selId));
|
|
39213
|
-
const
|
|
39213
|
+
const select2 = (i2) => {
|
|
39214
39214
|
const act = actOf(opts[i2], props.onChange ?? props.onSelect);
|
|
39215
39215
|
if (ctx.onAction && act) ctx.onAction(withSelection(act, { selectedId: String(opts[i2]?.id ?? i2) }));
|
|
39216
39216
|
};
|
|
@@ -39220,7 +39220,7 @@ var init_controls = __esm({
|
|
|
39220
39220
|
else if (e2.key === "ArrowLeft" || e2.key === "ArrowUp") ni2 = (selIdx - 1 + opts.length) % opts.length;
|
|
39221
39221
|
else return;
|
|
39222
39222
|
e2.preventDefault();
|
|
39223
|
-
if (ni2 !== selIdx)
|
|
39223
|
+
if (ni2 !== selIdx) select2(ni2);
|
|
39224
39224
|
};
|
|
39225
39225
|
return /* @__PURE__ */ jsx6("div", { role: "radiogroup", onKeyDown, style: { display: "flex", background: seg.outlined ? "transparent" : C2("surfaceTertiary", "#eee"), borderRadius: radius(seg.trackRadius, "md", 8), padding: seg.trackPadding, width: "100%", boxSizing: "border-box", ...wrap }, children: opts.map((o2, i2) => {
|
|
39226
39226
|
const on4 = o2.id === selId;
|
|
@@ -39237,7 +39237,7 @@ var init_controls = __esm({
|
|
|
39237
39237
|
role: "radio",
|
|
39238
39238
|
"aria-checked": on4,
|
|
39239
39239
|
tabIndex: on4 || selId == null && i2 === 0 ? 0 : -1,
|
|
39240
|
-
onClick: () =>
|
|
39240
|
+
onClick: () => select2(i2),
|
|
39241
39241
|
style: { all: "unset", flex: 1, minWidth: 44, minHeight: seg.height - 2 * seg.trackPadding, textAlign: "center", padding: "7px 4px", borderRadius: outerR, fontFamily: FONT(ctx), fontWeight: 600, fontSize: pxToRem(13), cursor: "pointer", boxSizing: "border-box", background: on4 ? C2("surfacePrimary", "#fff") : seg.outlined ? C2(pickRole(ctx.tokens.colors, seg.roles.inactive), "#eee") : "transparent", color: on4 ? C2("textPrimary", "#111") : C2("textSecondary", "#777"), boxShadow: on4 && !seg.outlined ? "0 1px 3px rgba(0,0,0,.12)" : "none", ...outlinedShape },
|
|
39242
39242
|
children: [
|
|
39243
39243
|
on4 && seg.selectedCheck ? /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: "\u2713 " }) : null,
|
|
@@ -40825,7 +40825,7 @@ async function fetchData(url, type = "text") {
|
|
|
40825
40825
|
}
|
|
40826
40826
|
return response.text();
|
|
40827
40827
|
}
|
|
40828
|
-
return new Promise((
|
|
40828
|
+
return new Promise((resolve65, reject) => {
|
|
40829
40829
|
const request = new XMLHttpRequest();
|
|
40830
40830
|
request.open("GET", url, true);
|
|
40831
40831
|
request.responseType = type === "bytes" ? "arraybuffer" : type;
|
|
@@ -40836,14 +40836,14 @@ async function fetchData(url, type = "text") {
|
|
|
40836
40836
|
if (request.status === 200 || request.status === 0) {
|
|
40837
40837
|
switch (type) {
|
|
40838
40838
|
case "bytes":
|
|
40839
|
-
|
|
40839
|
+
resolve65(new Uint8Array(request.response));
|
|
40840
40840
|
return;
|
|
40841
40841
|
case "blob":
|
|
40842
40842
|
case "json":
|
|
40843
|
-
|
|
40843
|
+
resolve65(request.response);
|
|
40844
40844
|
return;
|
|
40845
40845
|
}
|
|
40846
|
-
|
|
40846
|
+
resolve65(request.responseText);
|
|
40847
40847
|
return;
|
|
40848
40848
|
}
|
|
40849
40849
|
reject(new Error(request.statusText));
|
|
@@ -43775,7 +43775,7 @@ var init_pdf = __esm({
|
|
|
43775
43775
|
var defineProperty = Object.defineProperty;
|
|
43776
43776
|
var stringSlice = uncurryThis("".slice);
|
|
43777
43777
|
var replace = uncurryThis("".replace);
|
|
43778
|
-
var
|
|
43778
|
+
var join88 = uncurryThis([].join);
|
|
43779
43779
|
var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
|
|
43780
43780
|
return defineProperty(function() {
|
|
43781
43781
|
}, "length", { value: 8 }).length !== 8;
|
|
@@ -43802,7 +43802,7 @@ var init_pdf = __esm({
|
|
|
43802
43802
|
}
|
|
43803
43803
|
var state = enforceInternalState(value);
|
|
43804
43804
|
if (!hasOwn(state, "source")) {
|
|
43805
|
-
state.source =
|
|
43805
|
+
state.source = join88(TEMPLATE, typeof name == "string" ? name : "");
|
|
43806
43806
|
}
|
|
43807
43807
|
return value;
|
|
43808
43808
|
};
|
|
@@ -43847,13 +43847,13 @@ var init_pdf = __esm({
|
|
|
43847
43847
|
var aCallable = __webpack_require__3(9306);
|
|
43848
43848
|
var $TypeError = TypeError;
|
|
43849
43849
|
var PromiseCapability = function(C2) {
|
|
43850
|
-
var
|
|
43850
|
+
var resolve65, reject;
|
|
43851
43851
|
this.promise = new C2(function($$resolve, $$reject) {
|
|
43852
|
-
if (
|
|
43853
|
-
|
|
43852
|
+
if (resolve65 !== void 0 || reject !== void 0) throw new $TypeError("Bad Promise constructor");
|
|
43853
|
+
resolve65 = $$resolve;
|
|
43854
43854
|
reject = $$reject;
|
|
43855
43855
|
});
|
|
43856
|
-
this.resolve = aCallable(
|
|
43856
|
+
this.resolve = aCallable(resolve65);
|
|
43857
43857
|
this.reject = aCallable(reject);
|
|
43858
43858
|
};
|
|
43859
43859
|
module.exports.f = function(C2) {
|
|
@@ -44221,8 +44221,8 @@ var init_pdf = __esm({
|
|
|
44221
44221
|
anObject(C2);
|
|
44222
44222
|
if (isObject3(x2) && x2.constructor === C2) return x2;
|
|
44223
44223
|
var promiseCapability = newPromiseCapability.f(C2);
|
|
44224
|
-
var
|
|
44225
|
-
|
|
44224
|
+
var resolve65 = promiseCapability.resolve;
|
|
44225
|
+
resolve65(x2);
|
|
44226
44226
|
return promiseCapability.promise;
|
|
44227
44227
|
};
|
|
44228
44228
|
},
|
|
@@ -46325,7 +46325,7 @@ var init_pdf = __esm({
|
|
|
46325
46325
|
var charAt = uncurryThis("".charAt);
|
|
46326
46326
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
46327
46327
|
var $Array = globalThis2.Array;
|
|
46328
|
-
var
|
|
46328
|
+
var join88 = uncurryThis([].join);
|
|
46329
46329
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toBase64 || !(function() {
|
|
46330
46330
|
try {
|
|
46331
46331
|
var target = new Uint8Array2();
|
|
@@ -46371,7 +46371,7 @@ var init_pdf = __esm({
|
|
|
46371
46371
|
result[written++] = "=";
|
|
46372
46372
|
}
|
|
46373
46373
|
}
|
|
46374
|
-
return
|
|
46374
|
+
return join88(result, "");
|
|
46375
46375
|
}
|
|
46376
46376
|
});
|
|
46377
46377
|
},
|
|
@@ -46383,7 +46383,7 @@ var init_pdf = __esm({
|
|
|
46383
46383
|
var anUint8Array = __webpack_require__3(4154);
|
|
46384
46384
|
var notDetached = __webpack_require__3(5169);
|
|
46385
46385
|
var numberToString2 = uncurryThis(1.1.toString);
|
|
46386
|
-
var
|
|
46386
|
+
var join88 = uncurryThis([].join);
|
|
46387
46387
|
var $Array = Array;
|
|
46388
46388
|
var Uint8Array2 = globalThis2.Uint8Array;
|
|
46389
46389
|
var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toHex || !(function() {
|
|
@@ -46403,7 +46403,7 @@ var init_pdf = __esm({
|
|
|
46403
46403
|
var hex2 = numberToString2(this[i2], 16);
|
|
46404
46404
|
result[i2] = hex2.length === 1 ? "0" + hex2 : hex2;
|
|
46405
46405
|
}
|
|
46406
|
-
return
|
|
46406
|
+
return join88(result, "");
|
|
46407
46407
|
}
|
|
46408
46408
|
});
|
|
46409
46409
|
},
|
|
@@ -48076,11 +48076,11 @@ var init_pdf = __esm({
|
|
|
48076
48076
|
const mustRemoveAspectRatioPromise = _ImageManager._isSVGFittingCanvas;
|
|
48077
48077
|
const fileReader = new FileReader();
|
|
48078
48078
|
const imageElement = new Image();
|
|
48079
|
-
const imagePromise = new Promise((
|
|
48079
|
+
const imagePromise = new Promise((resolve65, reject) => {
|
|
48080
48080
|
imageElement.onload = () => {
|
|
48081
48081
|
data.bitmap = imageElement;
|
|
48082
48082
|
data.isSvg = true;
|
|
48083
|
-
|
|
48083
|
+
resolve65();
|
|
48084
48084
|
};
|
|
48085
48085
|
fileReader.onload = async () => {
|
|
48086
48086
|
const url = data.svgUrl = fileReader.result;
|
|
@@ -48766,13 +48766,13 @@ var init_pdf = __esm({
|
|
|
48766
48766
|
return;
|
|
48767
48767
|
}
|
|
48768
48768
|
const {
|
|
48769
|
-
resolve:
|
|
48769
|
+
resolve: resolve65,
|
|
48770
48770
|
promise
|
|
48771
48771
|
} = Promise.withResolvers();
|
|
48772
48772
|
const onEditorsRendered = (evt) => {
|
|
48773
48773
|
if (evt.pageNumber === pageNumber) {
|
|
48774
48774
|
this._eventBus.off("editorsrendered", onEditorsRendered);
|
|
48775
|
-
|
|
48775
|
+
resolve65();
|
|
48776
48776
|
}
|
|
48777
48777
|
};
|
|
48778
48778
|
this._eventBus.on("editorsrendered", onEditorsRendered, internalOpt);
|
|
@@ -53810,8 +53810,8 @@ var init_pdf = __esm({
|
|
|
53810
53810
|
if (this.isSyncFontLoadingSupported) {
|
|
53811
53811
|
return;
|
|
53812
53812
|
}
|
|
53813
|
-
await new Promise((
|
|
53814
|
-
const request = this._queueLoadingCallback(
|
|
53813
|
+
await new Promise((resolve65) => {
|
|
53814
|
+
const request = this._queueLoadingCallback(resolve65);
|
|
53815
53815
|
this._prepareFontLoadEvent(font, request);
|
|
53816
53816
|
});
|
|
53817
53817
|
}
|
|
@@ -70851,7 +70851,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70851
70851
|
input.type = "file";
|
|
70852
70852
|
input.accept = SupportedImageMimeTypes.join(",");
|
|
70853
70853
|
const signal = this._uiManager._signal;
|
|
70854
|
-
this.#bitmapPromise = new Promise((
|
|
70854
|
+
this.#bitmapPromise = new Promise((resolve65) => {
|
|
70855
70855
|
input.addEventListener("change", async () => {
|
|
70856
70856
|
if (!input.files || input.files.length === 0) {
|
|
70857
70857
|
this.remove();
|
|
@@ -70866,13 +70866,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70866
70866
|
});
|
|
70867
70867
|
this.#getBitmapFetched(data);
|
|
70868
70868
|
}
|
|
70869
|
-
|
|
70869
|
+
resolve65();
|
|
70870
70870
|
}, {
|
|
70871
70871
|
signal
|
|
70872
70872
|
});
|
|
70873
70873
|
input.addEventListener("cancel", () => {
|
|
70874
70874
|
this.remove();
|
|
70875
|
-
|
|
70875
|
+
resolve65();
|
|
70876
70876
|
}, {
|
|
70877
70877
|
signal
|
|
70878
70878
|
});
|
|
@@ -125162,7 +125162,7 @@ var init_renderNode = __esm({
|
|
|
125162
125162
|
media.currentTime = Math.max(0, Math.min(seconds, Number.isFinite(media.duration) ? media.duration : seconds));
|
|
125163
125163
|
setPosition(media.currentTime);
|
|
125164
125164
|
}, []);
|
|
125165
|
-
const
|
|
125165
|
+
const select2 = React9.useCallback((next) => {
|
|
125166
125166
|
if (resolvedItems.length === 0) return;
|
|
125167
125167
|
const normalized = (next % resolvedItems.length + resolvedItems.length) % resolvedItems.length;
|
|
125168
125168
|
const nextItem = resolvedItems[normalized];
|
|
@@ -125213,10 +125213,10 @@ var init_renderNode = __esm({
|
|
|
125213
125213
|
seek(Number(detail.value ?? 0));
|
|
125214
125214
|
break;
|
|
125215
125215
|
case "next":
|
|
125216
|
-
|
|
125216
|
+
select2(index + 1);
|
|
125217
125217
|
break;
|
|
125218
125218
|
case "previous":
|
|
125219
|
-
|
|
125219
|
+
select2(index - 1);
|
|
125220
125220
|
break;
|
|
125221
125221
|
case "setRate": {
|
|
125222
125222
|
const next = Number(detail.value ?? 1);
|
|
@@ -125241,7 +125241,7 @@ var init_renderNode = __esm({
|
|
|
125241
125241
|
};
|
|
125242
125242
|
window.addEventListener("himalaya-media-command", listener);
|
|
125243
125243
|
return () => window.removeEventListener("himalaya-media-command", listener);
|
|
125244
|
-
}, [sessionId, index, play, pause, seek,
|
|
125244
|
+
}, [sessionId, index, play, pause, seek, select2, toggleFullscreen]);
|
|
125245
125245
|
React9.useEffect(() => {
|
|
125246
125246
|
const listener = () => {
|
|
125247
125247
|
const value = document.fullscreenElement === hostRef.current;
|
|
@@ -125297,10 +125297,10 @@ var init_renderNode = __esm({
|
|
|
125297
125297
|
seek(Number(raw.seconds ?? raw.positionSeconds ?? 0));
|
|
125298
125298
|
return;
|
|
125299
125299
|
case "media.next":
|
|
125300
|
-
|
|
125300
|
+
select2(index + 1);
|
|
125301
125301
|
return;
|
|
125302
125302
|
case "media.previous":
|
|
125303
|
-
|
|
125303
|
+
select2(index - 1);
|
|
125304
125304
|
return;
|
|
125305
125305
|
case "media.fullscreen":
|
|
125306
125306
|
void toggleFullscreen();
|
|
@@ -125343,14 +125343,14 @@ var init_renderNode = __esm({
|
|
|
125343
125343
|
return `${Math.floor(safe / 60)}:${String(Math.floor(safe % 60)).padStart(2, "0")}`;
|
|
125344
125344
|
};
|
|
125345
125345
|
const builtInControls = /* @__PURE__ */ jsxs7("div", { "data-media-controls": "builtIn", style: { display: "grid", gridTemplateColumns: "auto auto 1fr auto auto", gap: 10, alignItems: "center", width: "100%", padding: "10px 12px", boxSizing: "border-box", color: foreground, background: "linear-gradient(transparent,rgba(0,0,0,.82))" }, children: [
|
|
125346
|
-
items.length > 1 && /* @__PURE__ */ jsx10("button", { "aria-label": "Previous", onClick: () =>
|
|
125346
|
+
items.length > 1 && /* @__PURE__ */ jsx10("button", { "aria-label": "Previous", onClick: () => select2(index - 1), style: { color: "inherit", background: "transparent", border: 0, fontSize: pxToRem(18) }, children: "\u25C0\u25C0" }),
|
|
125347
125347
|
/* @__PURE__ */ jsx10("button", { "aria-label": status === "playing" ? "Pause" : "Play", onClick: () => status === "playing" ? pause() : void play(), style: { width: 38, height: 38, borderRadius: "50%", color: background, background: foreground, border: 0, fontSize: 18 }, children: status === "playing" ? "\u275A\u275A" : "\u25B6" }),
|
|
125348
125348
|
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [
|
|
125349
125349
|
/* @__PURE__ */ jsx10("span", { style: { fontSize: pxToRem(11), whiteSpace: "nowrap" }, children: time(position) }),
|
|
125350
125350
|
/* @__PURE__ */ jsx10("input", { "aria-label": "Media position", type: "range", min: 0, max: Math.max(duration2, 1), step: 0.1, value: Math.min(position, Math.max(duration2, 1)), onChange: (event) => seek(Number(event.currentTarget.value)), style: { width: "100%", accentColor: accent } }),
|
|
125351
125351
|
/* @__PURE__ */ jsx10("span", { style: { fontSize: pxToRem(11), whiteSpace: "nowrap" }, children: time(duration2) })
|
|
125352
125352
|
] }),
|
|
125353
|
-
items.length > 1 && /* @__PURE__ */ jsx10("button", { "aria-label": "Next", onClick: () =>
|
|
125353
|
+
items.length > 1 && /* @__PURE__ */ jsx10("button", { "aria-label": "Next", onClick: () => select2(index + 1), style: { color: "inherit", background: "transparent", border: 0, fontSize: pxToRem(18) }, children: "\u25B6\u25B6" }),
|
|
125354
125354
|
props.fullscreen !== "disabled" && /* @__PURE__ */ jsx10("button", { "aria-label": "Fullscreen", onClick: () => void toggleFullscreen(), style: { color: "inherit", background: "transparent", border: 0, fontSize: pxToRem(18) }, children: "\u26F6" })
|
|
125355
125355
|
] });
|
|
125356
125356
|
const customControls = chrome === "custom" ? slot("controls") : null;
|
|
@@ -125392,7 +125392,7 @@ var init_renderNode = __esm({
|
|
|
125392
125392
|
return;
|
|
125393
125393
|
}
|
|
125394
125394
|
if (props.loop === "all" || index + 1 < items.length) {
|
|
125395
|
-
|
|
125395
|
+
select2(index + 1);
|
|
125396
125396
|
return;
|
|
125397
125397
|
}
|
|
125398
125398
|
setStatus("ended");
|
|
@@ -127708,7 +127708,7 @@ var init_renderNode = __esm({
|
|
|
127708
127708
|
const currentRef = React9.useRef(current);
|
|
127709
127709
|
const itemsPath = props.itemsPath ?? props.items_path;
|
|
127710
127710
|
const boundRail = !!itemsPath && !!items[0] && !!ctx.provider;
|
|
127711
|
-
const
|
|
127711
|
+
const select2 = (index) => {
|
|
127712
127712
|
if (index === currentRef.current) return;
|
|
127713
127713
|
currentRef.current = index;
|
|
127714
127714
|
setCurrent(index);
|
|
@@ -127725,7 +127725,7 @@ var init_renderNode = __esm({
|
|
|
127725
127725
|
const timer = setInterval(() => {
|
|
127726
127726
|
const next = (currentRef.current + 1) % pages2.length;
|
|
127727
127727
|
if (rail.current) rail.current.scrollLeft = next * rail.current.clientWidth;
|
|
127728
|
-
|
|
127728
|
+
select2(next);
|
|
127729
127729
|
}, interval);
|
|
127730
127730
|
return () => clearInterval(timer);
|
|
127731
127731
|
}, [props.autoplayIntervalMs, props.__pager, boundRail, pages2.length, props.onChange, ctx]);
|
|
@@ -127742,10 +127742,10 @@ var init_renderNode = __esm({
|
|
|
127742
127742
|
event.preventDefault();
|
|
127743
127743
|
const index = event.key === "Home" ? 0 : event.key === "End" ? pages2.length - 1 : Math.max(0, Math.min(pages2.length - 1, currentRef.current + (event.key === "ArrowRight" ? 1 : -1)));
|
|
127744
127744
|
if (rail.current) rail.current.scrollLeft = index * rail.current.clientWidth;
|
|
127745
|
-
|
|
127745
|
+
select2(index);
|
|
127746
127746
|
},
|
|
127747
127747
|
onScroll: (event) => {
|
|
127748
|
-
if (!boundRail && event.currentTarget.clientWidth > 0)
|
|
127748
|
+
if (!boundRail && event.currentTarget.clientWidth > 0) select2(Math.max(0, Math.min(pages2.length - 1, Math.round(event.currentTarget.scrollLeft / event.currentTarget.clientWidth))));
|
|
127749
127749
|
},
|
|
127750
127750
|
style: { display: "flex", overflowX: "auto", scrollSnapType: boundRail ? void 0 : "x mandatory", gap: boundRail ? 12 : void 0, width: "100%" },
|
|
127751
127751
|
children: boundRail ? /* @__PURE__ */ jsx10(BoundList, { ctx, itemsPath, template: items[0], renderRow: (template, itemCtx) => /* @__PURE__ */ jsx10("div", { style: { flex: "0 0 auto" }, children: renderNode(template, itemCtx) }) }) : pages2.map((page, index) => /* @__PURE__ */ jsx10("div", { style: { minWidth: "100%", scrollSnapAlign: "start" }, children: renderNode(page, ctx) }, page?.id ?? index))
|
|
@@ -129146,13 +129146,13 @@ __export(render_descriptor_exports, {
|
|
|
129146
129146
|
stabilizePngPage: () => stabilizePngPage,
|
|
129147
129147
|
withRetry: () => withRetry2
|
|
129148
129148
|
});
|
|
129149
|
-
function a11ySemantics(type, props, modifiers, ancestorHidden,
|
|
129149
|
+
function a11ySemantics(type, props, modifiers, ancestorHidden, resolve65) {
|
|
129150
129150
|
if (!A11Y_MODIFIER_KEYS.some((k2) => modifiers[k2] !== void 0)) return void 0;
|
|
129151
129151
|
const literal = (v2) => typeof v2 === "string" && v2.trim() !== "" && !isDynamicValue(v2) ? v2 : void 0;
|
|
129152
129152
|
const spoken = (v2) => {
|
|
129153
129153
|
const lit = literal(v2);
|
|
129154
|
-
if (lit !== void 0 || !
|
|
129155
|
-
const r2 =
|
|
129154
|
+
if (lit !== void 0 || !resolve65 || typeof v2 !== "string" || !isDynamicValue(v2)) return lit;
|
|
129155
|
+
const r2 = resolve65(v2);
|
|
129156
129156
|
if (r2 === v2) return void 0;
|
|
129157
129157
|
return typeof r2 === "string" && r2.trim() !== "" ? r2 : typeof r2 === "number" ? String(r2) : void 0;
|
|
129158
129158
|
};
|
|
@@ -129166,7 +129166,7 @@ function a11ySemantics(type, props, modifiers, ancestorHidden, resolve63) {
|
|
|
129166
129166
|
if (name !== void 0 && exposure === "exposed") out2.name = name;
|
|
129167
129167
|
const hint = spoken(modifiers.accessibilityHint);
|
|
129168
129168
|
if (hint !== void 0) out2.hint = hint;
|
|
129169
|
-
const value = spoken(modifiers.accessibilityValue) ?? controlState(role, props,
|
|
129169
|
+
const value = spoken(modifiers.accessibilityValue) ?? controlState(role, props, resolve65);
|
|
129170
129170
|
if (value !== void 0) out2.value = value;
|
|
129171
129171
|
if (typeof modifiers.headingLevel === "number") out2.headingLevel = modifiers.headingLevel;
|
|
129172
129172
|
if (exposure !== "exposed") out2.exposure = exposure;
|
|
@@ -129187,13 +129187,13 @@ function a11ySemantics(type, props, modifiers, ancestorHidden, resolve63) {
|
|
|
129187
129187
|
}
|
|
129188
129188
|
return out2;
|
|
129189
129189
|
}
|
|
129190
|
-
function controlState(role, props,
|
|
129190
|
+
function controlState(role, props, resolve65) {
|
|
129191
129191
|
if (role !== "toggle" && role !== "checkbox" && role !== "radio") return void 0;
|
|
129192
129192
|
if (role === "checkbox" && props.indeterminate === true) return "mixed";
|
|
129193
129193
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && isDynamicValue(props.value) ? props.value : void 0;
|
|
129194
129194
|
let on4;
|
|
129195
129195
|
if (binding2 !== void 0) {
|
|
129196
|
-
const v2 =
|
|
129196
|
+
const v2 = resolve65 ? resolve65(binding2) : void 0;
|
|
129197
129197
|
if (v2 === true || v2 === 1 || v2 === "true" || v2 === "1") on4 = true;
|
|
129198
129198
|
else if (v2 === false || v2 === 0 || v2 === "false" || v2 === "0") on4 = false;
|
|
129199
129199
|
else return void 0;
|
|
@@ -129523,7 +129523,7 @@ async function stabilizePngPage(page, scheme) {
|
|
|
129523
129523
|
const browser = globalThis;
|
|
129524
129524
|
browser.document.documentElement.style.colorScheme = selected;
|
|
129525
129525
|
await browser.document.fonts?.ready;
|
|
129526
|
-
await new Promise((
|
|
129526
|
+
await new Promise((resolve65) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve65())));
|
|
129527
129527
|
}, scheme);
|
|
129528
129528
|
}
|
|
129529
129529
|
async function renderPngBatch(items) {
|
|
@@ -132144,7 +132144,7 @@ async function handleWebWix(req, res, state) {
|
|
|
132144
132144
|
}
|
|
132145
132145
|
if (match) {
|
|
132146
132146
|
const mocked = match.rule.response;
|
|
132147
|
-
if (mocked.delayMs) await new Promise((
|
|
132147
|
+
if (mocked.delayMs) await new Promise((resolve65) => setTimeout(resolve65, mocked.delayMs));
|
|
132148
132148
|
const payload = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
132149
132149
|
recordStream("mock", mocked.status, match.rule.id, mocked.headers);
|
|
132150
132150
|
res.statusCode = mocked.status;
|
|
@@ -132209,14 +132209,14 @@ async function handleWebWix(req, res, state) {
|
|
|
132209
132209
|
const chunk = await reader.read();
|
|
132210
132210
|
if (chunk.done) break;
|
|
132211
132211
|
if (chunk.value && !res.write(chunk.value)) {
|
|
132212
|
-
await new Promise((
|
|
132212
|
+
await new Promise((resolve65) => {
|
|
132213
132213
|
let settled = false;
|
|
132214
132214
|
const finish2 = () => {
|
|
132215
132215
|
if (settled) return;
|
|
132216
132216
|
settled = true;
|
|
132217
132217
|
res.off("drain", finish2);
|
|
132218
132218
|
res.off("close", finish2);
|
|
132219
|
-
|
|
132219
|
+
resolve65();
|
|
132220
132220
|
};
|
|
132221
132221
|
if (res.destroyed || !res.writable) finish2();
|
|
132222
132222
|
else {
|
|
@@ -132371,7 +132371,7 @@ async function handleWebWix(req, res, state) {
|
|
|
132371
132371
|
}
|
|
132372
132372
|
if (match) {
|
|
132373
132373
|
const mocked = match.rule.response;
|
|
132374
|
-
if (mocked.delayMs) await new Promise((
|
|
132374
|
+
if (mocked.delayMs) await new Promise((resolve65) => setTimeout(resolve65, mocked.delayMs));
|
|
132375
132375
|
const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
132376
132376
|
record2("mock", mocked.status, responseBody, match.rule.id, mocked.headers);
|
|
132377
132377
|
return reply(200, { status: mocked.status, body: responseBody ?? "" });
|
|
@@ -133410,8 +133410,8 @@ async function handleActionHandlerBundleGet(res, app) {
|
|
|
133410
133410
|
}
|
|
133411
133411
|
async function serveStatic(req, res, root, prefix) {
|
|
133412
133412
|
const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
|
|
133413
|
-
const
|
|
133414
|
-
const safe = normalize3(
|
|
133413
|
+
const relative17 = requested.replace(prefix, "").replace(/^\//, "");
|
|
133414
|
+
const safe = normalize3(relative17).replace(/^(\.\.[\/\\])+/, "");
|
|
133415
133415
|
const fullPath = resolve38(root, safe);
|
|
133416
133416
|
if (!fullPath.startsWith(root)) {
|
|
133417
133417
|
return send(res, 403, "forbidden");
|
|
@@ -134575,12 +134575,12 @@ var init_query = __esm({
|
|
|
134575
134575
|
});
|
|
134576
134576
|
|
|
134577
134577
|
// ../../core/dev-server/src/crawl-input.ts
|
|
134578
|
-
function resolved(v2,
|
|
134579
|
-
if (typeof v2 === "string") return v2.startsWith("$service:") ?
|
|
134578
|
+
function resolved(v2, resolve65) {
|
|
134579
|
+
if (typeof v2 === "string") return v2.startsWith("$service:") ? resolve65(v2) : v2;
|
|
134580
134580
|
if (Array.isArray(v2)) {
|
|
134581
134581
|
const out2 = v2.flatMap((el2) => {
|
|
134582
134582
|
if (typeof el2 !== "string" || !el2.startsWith("$service:")) return [el2];
|
|
134583
|
-
const r2 =
|
|
134583
|
+
const r2 = resolve65(el2);
|
|
134584
134584
|
return Array.isArray(r2) ? r2 : [r2];
|
|
134585
134585
|
});
|
|
134586
134586
|
return out2;
|
|
@@ -134594,9 +134594,9 @@ function hasRowBinding(props) {
|
|
|
134594
134594
|
return itemToken(v2) || Array.isArray(v2) && v2.some(itemToken);
|
|
134595
134595
|
});
|
|
134596
134596
|
}
|
|
134597
|
-
function declaredOptionIds(props,
|
|
134597
|
+
function declaredOptionIds(props, resolve65) {
|
|
134598
134598
|
const literal = props.options ?? props.tabs ?? props.chips;
|
|
134599
|
-
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath,
|
|
134599
|
+
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve65) : void 0;
|
|
134600
134600
|
const raw = Array.isArray(bound) ? bound : literal;
|
|
134601
134601
|
if (!Array.isArray(raw)) return [];
|
|
134602
134602
|
const out2 = [];
|
|
@@ -134639,24 +134639,24 @@ function seedTokens(state, limit = 48) {
|
|
|
134639
134639
|
walk2(state, 0);
|
|
134640
134640
|
return out2;
|
|
134641
134641
|
}
|
|
134642
|
-
function synthesizeInput(control,
|
|
134642
|
+
function synthesizeInput(control, resolve65, tokens2) {
|
|
134643
134643
|
const id = `${control.type}.${control.callback}`;
|
|
134644
134644
|
const row = SYNTHESIZED_CONTROLS[id];
|
|
134645
134645
|
if (!row) return null;
|
|
134646
134646
|
const props = control.props;
|
|
134647
134647
|
if (hasRowBinding(props)) return null;
|
|
134648
134648
|
if (row.from === "declared-options") {
|
|
134649
|
-
const ids = declaredOptionIds(props,
|
|
134649
|
+
const ids = declaredOptionIds(props, resolve65);
|
|
134650
134650
|
if (!ids.length) return null;
|
|
134651
134651
|
if (row.encoding === "string-array") {
|
|
134652
|
-
const currentRaw2 = resolved(props.selectedIds,
|
|
134652
|
+
const currentRaw2 = resolved(props.selectedIds, resolve65);
|
|
134653
134653
|
const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x2) => typeof x2 === "string");
|
|
134654
134654
|
const pick4 = ids.find((o2) => !current3.includes(o2));
|
|
134655
134655
|
if (pick4 === void 0) return null;
|
|
134656
134656
|
const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
|
|
134657
134657
|
return { key: row.key, value, from: row.from, current: current3, control: id };
|
|
134658
134658
|
}
|
|
134659
|
-
const currentRaw = resolved(props.selectedId,
|
|
134659
|
+
const currentRaw = resolved(props.selectedId, resolve65);
|
|
134660
134660
|
const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
|
|
134661
134661
|
const pick3 = ids.find((o2) => o2 !== current2);
|
|
134662
134662
|
if (pick3 === void 0) return null;
|
|
@@ -134664,7 +134664,7 @@ function synthesizeInput(control, resolve63, tokens2) {
|
|
|
134664
134664
|
}
|
|
134665
134665
|
if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
|
|
134666
134666
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
|
|
134667
|
-
const bound = binding2 === void 0 ? void 0 :
|
|
134667
|
+
const bound = binding2 === void 0 ? void 0 : resolve65(binding2);
|
|
134668
134668
|
const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
|
|
134669
134669
|
const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
|
|
134670
134670
|
const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
|
|
@@ -137284,6 +137284,7 @@ __export(build_exports2, {
|
|
|
137284
137284
|
bundleNameFromUrl: () => bundleNameFromUrl,
|
|
137285
137285
|
collectComponentTypes: () => collectComponentTypes,
|
|
137286
137286
|
contentReleaseId: () => contentReleaseId,
|
|
137287
|
+
countingHostAnswers: () => countingHostAnswers,
|
|
137287
137288
|
countingWixCall: () => countingWixCall,
|
|
137288
137289
|
declaresHostProvidedIdentity: () => declaresHostProvidedIdentity,
|
|
137289
137290
|
gitSha: () => gitSha,
|
|
@@ -137657,17 +137658,39 @@ async function buildRelease(app, dest, opts = {}) {
|
|
|
137657
137658
|
}
|
|
137658
137659
|
function countingWixCall(base) {
|
|
137659
137660
|
let returned = 0;
|
|
137661
|
+
const failed3 = [];
|
|
137660
137662
|
return {
|
|
137661
137663
|
call: async (method, path2, body) => {
|
|
137662
|
-
|
|
137664
|
+
let out2;
|
|
137665
|
+
try {
|
|
137666
|
+
out2 = await base(method, path2, body);
|
|
137667
|
+
} catch (e2) {
|
|
137668
|
+
failed3.push(`${String(method).toUpperCase()} ${String(path2).split("?")[0]}`);
|
|
137669
|
+
throw e2;
|
|
137670
|
+
}
|
|
137663
137671
|
returned += 1;
|
|
137664
137672
|
return out2;
|
|
137665
137673
|
},
|
|
137666
|
-
returned: () => returned
|
|
137674
|
+
returned: () => returned,
|
|
137675
|
+
failed: () => [...failed3]
|
|
137676
|
+
};
|
|
137677
|
+
}
|
|
137678
|
+
function countingHostAnswers(host) {
|
|
137679
|
+
let answered = 0;
|
|
137680
|
+
const { wixCall } = host;
|
|
137681
|
+
if (!wixCall) return { host, answered: () => answered };
|
|
137682
|
+
return {
|
|
137683
|
+
host: { ...host, wixCall: (method, path2, body) => {
|
|
137684
|
+
const answer = wixCall(method, path2, body);
|
|
137685
|
+
if (answer !== void 0) answered += 1;
|
|
137686
|
+
return answer;
|
|
137687
|
+
} },
|
|
137688
|
+
answered: () => answered
|
|
137667
137689
|
};
|
|
137668
137690
|
}
|
|
137669
137691
|
async function liveRenderServices(bundleJs, opts) {
|
|
137670
|
-
const
|
|
137692
|
+
const declared = declaredCapabilitiesOf(opts.descriptor);
|
|
137693
|
+
const bus = withHostAnswers(hostDispatch(opts.localDbSchema, declared), declared, opts.host);
|
|
137671
137694
|
const appear = rootOnAppear(opts.descriptor);
|
|
137672
137695
|
const fired = appear ? parseWorkerAction(appear.actionId) : null;
|
|
137673
137696
|
if (fired) {
|
|
@@ -137690,16 +137713,46 @@ async function liveRenderServices(bundleJs, opts) {
|
|
|
137690
137713
|
}
|
|
137691
137714
|
}
|
|
137692
137715
|
}
|
|
137716
|
+
if (opts.host) await settleUnawaitedWork();
|
|
137693
137717
|
return { services: snapshot(w2).state, calls: w2.calls, errors: w2.errors };
|
|
137694
137718
|
} finally {
|
|
137695
137719
|
w2.dispose();
|
|
137696
137720
|
}
|
|
137697
137721
|
}
|
|
137722
|
+
if (opts.host) return loadAndSettle(bundleJs, liveBootOptions(opts, bus));
|
|
137698
137723
|
return loadBundleServicesLive(bundleJs, liveBootOptions(opts, bus));
|
|
137699
137724
|
}
|
|
137725
|
+
async function settleUnawaitedWork() {
|
|
137726
|
+
for (let turn = 0; turn < SETTLE_TURNS; turn++) await new Promise((resolve65) => setTimeout(resolve65, 0));
|
|
137727
|
+
}
|
|
137728
|
+
async function loadAndSettle(bundleJs, options) {
|
|
137729
|
+
const w2 = await bootBundleWorker(bundleJs, options);
|
|
137730
|
+
try {
|
|
137731
|
+
await settleUnawaitedWork();
|
|
137732
|
+
return { services: snapshot(w2).state, calls: w2.calls, errors: w2.errors };
|
|
137733
|
+
} finally {
|
|
137734
|
+
w2.dispose();
|
|
137735
|
+
}
|
|
137736
|
+
}
|
|
137737
|
+
function withHostAnswers(bus, declared, host) {
|
|
137738
|
+
if (!host) return bus;
|
|
137739
|
+
return (action, params) => {
|
|
137740
|
+
const capability = /^capability\.([^.]+)\./.exec(action)?.[1];
|
|
137741
|
+
const answer = capability === void 0 || declared.has(capability) ? host.dispatch(action, params) : void 0;
|
|
137742
|
+
return answer === void 0 ? bus(action, params) : Promise.resolve(answer);
|
|
137743
|
+
};
|
|
137744
|
+
}
|
|
137745
|
+
function memoryStorage() {
|
|
137746
|
+
const items = /* @__PURE__ */ new Map();
|
|
137747
|
+
return { getItem: (key2) => items.get(key2) ?? null, setItem: (key2, value) => void items.set(key2, value) };
|
|
137748
|
+
}
|
|
137700
137749
|
function liveBootOptions(opts, bus) {
|
|
137750
|
+
const { host } = opts;
|
|
137751
|
+
const wixCall = host?.wixCall ? async (method, path2, body) => host.wixCall(method, path2, body) ?? opts.wixCall(method, path2, body) : opts.wixCall;
|
|
137701
137752
|
return {
|
|
137702
|
-
wixCall
|
|
137753
|
+
wixCall,
|
|
137754
|
+
...host ? { storage: memoryStorage() } : {},
|
|
137755
|
+
...host?.wixApiSession ? { wixApiSession: host.wixApiSession } : {},
|
|
137703
137756
|
input: opts.input,
|
|
137704
137757
|
budgetMs: opts.budgetMs,
|
|
137705
137758
|
// The capability arms, but NOT the signed-in-member arm. `hostDispatch` answers
|
|
@@ -137817,6 +137870,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137817
137870
|
let base2;
|
|
137818
137871
|
let liveCalls;
|
|
137819
137872
|
let liveReturned;
|
|
137873
|
+
let liveFailed;
|
|
137820
137874
|
let liveErrors;
|
|
137821
137875
|
let mockCalls;
|
|
137822
137876
|
let mockBootFailed;
|
|
@@ -137827,16 +137881,20 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137827
137881
|
base2 = null;
|
|
137828
137882
|
} else {
|
|
137829
137883
|
const counting = countingWixCall(await ensureLiveWixCall());
|
|
137884
|
+
const host = collect2.render.host ? countingHostAnswers(collect2.render.host) : void 0;
|
|
137830
137885
|
const live3 = await liveRenderServices(bundleJs, {
|
|
137831
137886
|
wixCall: counting.call,
|
|
137832
137887
|
input,
|
|
137833
137888
|
budgetMs: collect2.render.loadBudgetMs ?? LIVE_LOAD_BUDGET_MS,
|
|
137834
137889
|
localDbSchema: appLocalDbSchema,
|
|
137835
|
-
descriptor
|
|
137890
|
+
descriptor,
|
|
137891
|
+
...host ? { host: host.host } : {}
|
|
137836
137892
|
});
|
|
137837
137893
|
base2 = live3.services;
|
|
137838
137894
|
liveCalls = [...live3.calls];
|
|
137839
137895
|
liveReturned = counting.returned();
|
|
137896
|
+
if (host) liveReturned += host.answered();
|
|
137897
|
+
liveFailed = counting.failed();
|
|
137840
137898
|
liveErrors = live3.errors;
|
|
137841
137899
|
}
|
|
137842
137900
|
} else if (collect2?.render?.mocks && collect2.render.hydrate !== false && bundleName && readBundle(bundleName)) {
|
|
@@ -137885,7 +137943,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137885
137943
|
services[svc] = { ...services[svc] ?? {}, ...st2 };
|
|
137886
137944
|
}
|
|
137887
137945
|
}
|
|
137888
|
-
return { services, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved: mockUnserved ?? [] } : {}, ...mockBootFailed ? { mockBootFailed } : {} };
|
|
137946
|
+
return { services, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveFailed?.length ? { liveFailed } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved: mockUnserved ?? [] } : {}, ...mockBootFailed ? { mockBootFailed } : {} };
|
|
137889
137947
|
};
|
|
137890
137948
|
checkRegistry(preloaded.module.actions);
|
|
137891
137949
|
const contentManifestPath2 = join47(preloaded.dir, "himalaya.content.json");
|
|
@@ -138180,9 +138238,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
138180
138238
|
lint.push({ screenId, ok: report3.ok, issues: report3.issues });
|
|
138181
138239
|
}
|
|
138182
138240
|
if (collect2?.render && (!collect2.render.screenId || collect2.render.screenId === screenId)) {
|
|
138183
|
-
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed } = await renderServicesFor(bundleName, descriptor, screenId);
|
|
138241
|
+
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed, liveFailed } = await renderServicesFor(bundleName, descriptor, screenId);
|
|
138184
138242
|
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true);
|
|
138185
|
-
renders.push({ screenId, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
138243
|
+
renders.push({ screenId, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveFailed ? { liveFailed } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
138186
138244
|
}
|
|
138187
138245
|
}
|
|
138188
138246
|
const wantedRender = collect2?.render?.screenId;
|
|
@@ -138208,9 +138266,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
138208
138266
|
});
|
|
138209
138267
|
lint.push({ screenId: wantedRender, ok: report3.ok, issues: report3.issues });
|
|
138210
138268
|
}
|
|
138211
|
-
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed } = await renderServicesFor(bundleName, descriptor, wantedRender);
|
|
138269
|
+
const { services, liveCalls, liveReturned, liveErrors, mockCalls, mockUnserved, mockBootFailed, liveFailed } = await renderServicesFor(bundleName, descriptor, wantedRender);
|
|
138212
138270
|
const rr2 = await renderDescriptorWeb(descriptor, renderTokens, renderScheme, collect2.render.png === true, services, collect2.render.width, collect2.render.rtl === true);
|
|
138213
|
-
renders.push({ screenId: wantedRender, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
138271
|
+
renders.push({ screenId: wantedRender, scheme: renderScheme, ...rr2, ...await renderCompare(descriptor, services), ...collect2.render.dumpState && services ? { serviceState: services } : {}, ...liveCalls ? { liveCalls } : {}, ...liveReturned !== void 0 ? { liveReturned } : {}, ...liveFailed ? { liveFailed } : {}, ...liveErrors ? { liveErrors } : {}, ...mockCalls ? { mockCalls, mockUnserved } : {}, ...mockBootFailed ? { mockBootFailed } : {} });
|
|
138214
138272
|
}
|
|
138215
138273
|
}
|
|
138216
138274
|
for (const t2 of preloaded.module.screens.templated ?? []) {
|
|
@@ -138581,7 +138639,7 @@ function declaresHostProvidedIdentity(auth) {
|
|
|
138581
138639
|
const config = auth?.config;
|
|
138582
138640
|
return typeof config === "object" && config !== null && config.hostProvided === true;
|
|
138583
138641
|
}
|
|
138584
|
-
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
|
|
138642
|
+
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL, SETTLE_TURNS;
|
|
138585
138643
|
var init_build3 = __esm({
|
|
138586
138644
|
"../release-build/build.ts"() {
|
|
138587
138645
|
init_site_view_metadata();
|
|
@@ -138623,6 +138681,7 @@ var init_build3 = __esm({
|
|
|
138623
138681
|
requireFromHere = createRequire2(import.meta.url);
|
|
138624
138682
|
SOURCEMAP_ON_DEMAND_PATH = join47(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
|
|
138625
138683
|
BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
|
|
138684
|
+
SETTLE_TURNS = 20;
|
|
138626
138685
|
}
|
|
138627
138686
|
});
|
|
138628
138687
|
|
|
@@ -152745,7 +152804,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
152745
152804
|
const headers2 = Object.fromEntries(new Headers(init.headers).entries());
|
|
152746
152805
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
152747
152806
|
const hostname3 = url.hostname.replace(/^\[|\]$/g, "");
|
|
152748
|
-
return await new Promise((
|
|
152807
|
+
return await new Promise((resolve65, reject) => {
|
|
152749
152808
|
let settled = false;
|
|
152750
152809
|
const finish2 = (fn2) => {
|
|
152751
152810
|
if (settled) return;
|
|
@@ -152782,7 +152841,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
152782
152841
|
}
|
|
152783
152842
|
const responseHeaders = new Headers();
|
|
152784
152843
|
for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
|
|
152785
|
-
|
|
152844
|
+
resolve65(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
|
|
152786
152845
|
}));
|
|
152787
152846
|
});
|
|
152788
152847
|
req.once("error", (error) => finish2(() => reject(error)));
|
|
@@ -153082,7 +153141,7 @@ function createLocalTestSandbox() {
|
|
|
153082
153141
|
}
|
|
153083
153142
|
})();
|
|
153084
153143
|
`;
|
|
153085
|
-
return await new Promise((
|
|
153144
|
+
return await new Promise((resolve65, reject) => {
|
|
153086
153145
|
const { port1, port2 } = new MessageChannel();
|
|
153087
153146
|
const serializableContext = {
|
|
153088
153147
|
auth: context.auth,
|
|
@@ -153158,7 +153217,7 @@ function createLocalTestSandbox() {
|
|
|
153158
153217
|
timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
|
|
153159
153218
|
return;
|
|
153160
153219
|
}
|
|
153161
|
-
if (message.ok) finish2(() =>
|
|
153220
|
+
if (message.ok) finish2(() => resolve65({ value: message.value, durationMs: Date.now() - started }));
|
|
153162
153221
|
else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
|
|
153163
153222
|
});
|
|
153164
153223
|
worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
|
|
@@ -155057,12 +155116,12 @@ function createLoginSession(deps) {
|
|
|
155057
155116
|
current = pending;
|
|
155058
155117
|
const out2 = [];
|
|
155059
155118
|
const err = [];
|
|
155060
|
-
return new Promise((
|
|
155119
|
+
return new Promise((resolve65) => {
|
|
155061
155120
|
let answered = false;
|
|
155062
155121
|
const answer = () => {
|
|
155063
155122
|
if (answered) return;
|
|
155064
155123
|
answered = true;
|
|
155065
|
-
|
|
155124
|
+
resolve65(current);
|
|
155066
155125
|
};
|
|
155067
155126
|
let child;
|
|
155068
155127
|
try {
|
|
@@ -155185,9 +155244,9 @@ async function startMcpServer(opts) {
|
|
|
155185
155244
|
login: createLoginSession({ ...defaultLoginDeps, selfCommand: previewDeps.selfCommand, ...opts.login }),
|
|
155186
155245
|
...opts.workspace ? { workspaceBoundary: opts.workspace } : {}
|
|
155187
155246
|
};
|
|
155188
|
-
const closed = new Promise((
|
|
155189
|
-
stdin.once("end",
|
|
155190
|
-
stdin.once("close",
|
|
155247
|
+
const closed = new Promise((resolve65) => {
|
|
155248
|
+
stdin.once("end", resolve65);
|
|
155249
|
+
stdin.once("close", resolve65);
|
|
155191
155250
|
});
|
|
155192
155251
|
const handle = serveStdio(
|
|
155193
155252
|
() => {
|
|
@@ -155567,10 +155626,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
155567
155626
|
for (const source of Object.values(files)) visit(source);
|
|
155568
155627
|
return { modules, unsupported };
|
|
155569
155628
|
}
|
|
155570
|
-
function sdkSubpathReader(
|
|
155629
|
+
function sdkSubpathReader(resolve65) {
|
|
155571
155630
|
return (sub) => {
|
|
155572
155631
|
try {
|
|
155573
|
-
return readFileSync79(
|
|
155632
|
+
return readFileSync79(resolve65(`@wix/himalaya/${sub}`), "utf8");
|
|
155574
155633
|
} catch {
|
|
155575
155634
|
return null;
|
|
155576
155635
|
}
|
|
@@ -155648,7 +155707,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
155648
155707
|
const token = mintToken2(payload);
|
|
155649
155708
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
155650
155709
|
if (unusable) throw new Error(unusable);
|
|
155651
|
-
return await new Promise((
|
|
155710
|
+
return await new Promise((resolve65, reject) => {
|
|
155652
155711
|
let settled = false;
|
|
155653
155712
|
let url = "";
|
|
155654
155713
|
const server = createServer5();
|
|
@@ -155700,7 +155759,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
155700
155759
|
}
|
|
155701
155760
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
155702
155761
|
const report3 = body.result;
|
|
155703
|
-
finish2(() =>
|
|
155762
|
+
finish2(() => resolve65({ report: report3, url }));
|
|
155704
155763
|
})();
|
|
155705
155764
|
});
|
|
155706
155765
|
server.on("error", (e2) => finish2(() => reject(e2)));
|
|
@@ -158606,6 +158665,15 @@ function retryAfterMs(header, nowMs) {
|
|
|
158606
158665
|
const ms2 = /^\d+$/.test(trimmed) ? Number(trimmed) * 1e3 : Date.parse(trimmed) - nowMs;
|
|
158607
158666
|
return Number.isFinite(ms2) ? Math.min(Math.max(ms2, 0), MAX_RETRY_WAIT_MS) : void 0;
|
|
158608
158667
|
}
|
|
158668
|
+
function assetUploadUrl(operation, size) {
|
|
158669
|
+
const url = new URL(operation.url);
|
|
158670
|
+
const appleHost = url.hostname === "apple.com" || url.hostname.endsWith(".apple.com");
|
|
158671
|
+
const inFile = Number.isInteger(operation.offset) && Number.isInteger(operation.length) && operation.offset >= 0 && operation.length > 0 && operation.offset + operation.length <= size;
|
|
158672
|
+
if (url.protocol !== "https:" || !appleHost || url.username || url.password || operation.method !== "PUT" || !inFile) {
|
|
158673
|
+
throw new AscError("refused", `refusing an asset upload operation Apple would not issue (${operation.method} ${url.origin})`);
|
|
158674
|
+
}
|
|
158675
|
+
return url;
|
|
158676
|
+
}
|
|
158609
158677
|
function backoffMs(attempt) {
|
|
158610
158678
|
return Math.min(BASE_BACKOFF_MS * 2 ** (attempt - 1), MAX_RETRY_WAIT_MS);
|
|
158611
158679
|
}
|
|
@@ -158668,7 +158736,7 @@ var init_iap_client = __esm({
|
|
|
158668
158736
|
this.options = options;
|
|
158669
158737
|
this.fetchImpl = options.fetchImpl ?? ((input, init) => globalThis.fetch(input, init));
|
|
158670
158738
|
this.now = options.now ?? Date.now;
|
|
158671
|
-
this.sleep = options.sleep ?? ((ms2) => new Promise((
|
|
158739
|
+
this.sleep = options.sleep ?? ((ms2) => new Promise((resolve65) => setTimeout(resolve65, ms2)));
|
|
158672
158740
|
}
|
|
158673
158741
|
fetchImpl;
|
|
158674
158742
|
now;
|
|
@@ -158695,6 +158763,32 @@ var init_iap_client = __esm({
|
|
|
158695
158763
|
async patch(path2, body) {
|
|
158696
158764
|
return this.write("PATCH", this.resolve(path2), body);
|
|
158697
158765
|
}
|
|
158766
|
+
async delete(path2) {
|
|
158767
|
+
await this.write("DELETE", this.resolve(path2));
|
|
158768
|
+
}
|
|
158769
|
+
async uploadParts(operations, bytes2) {
|
|
158770
|
+
for (const [i2, operation] of operations.entries()) {
|
|
158771
|
+
const where = `upload of part ${i2 + 1} of ${operations.length} to Apple's asset storage`;
|
|
158772
|
+
const response = await this.putPart(operation, bytes2, where);
|
|
158773
|
+
if (response.status >= 500) throw new AscError("server", `${where} \u2192 ${response.status}`, response.status);
|
|
158774
|
+
if (!response.ok) throw new AscError("invalid", `${where} \u2192 ${response.status} \u2014 the reserved upload was refused; make a new plan, which reserves a fresh one`, response.status);
|
|
158775
|
+
}
|
|
158776
|
+
}
|
|
158777
|
+
async putPart(operation, bytes2, where) {
|
|
158778
|
+
const url = assetUploadUrl(operation, bytes2.length);
|
|
158779
|
+
const headers2 = Object.fromEntries(operation.requestHeaders.filter((h2) => h2.name.toLowerCase() !== "authorization").map((h2) => [h2.name, h2.value]));
|
|
158780
|
+
try {
|
|
158781
|
+
return await this.fetchImpl(url.href, {
|
|
158782
|
+
method: "PUT",
|
|
158783
|
+
headers: headers2,
|
|
158784
|
+
body: bytes2.slice(operation.offset, operation.offset + operation.length),
|
|
158785
|
+
redirect: "error",
|
|
158786
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
158787
|
+
});
|
|
158788
|
+
} catch (e2) {
|
|
158789
|
+
throw new AscError("network", `${where} failed before a response: ${this.scrub(e2.message)}`);
|
|
158790
|
+
}
|
|
158791
|
+
}
|
|
158698
158792
|
resolve(pathOrUrl) {
|
|
158699
158793
|
const url = new URL(pathOrUrl, ASC_ORIGIN);
|
|
158700
158794
|
const allowed2 = url.origin === ASC_ORIGIN && !url.username && !url.password && /^\/v[12]\//.test(url.pathname);
|
|
@@ -158819,6 +158913,20 @@ function toVersion(resource) {
|
|
|
158819
158913
|
function toLocalization(resource) {
|
|
158820
158914
|
return { id: resource.id, locale: attr(resource, "locale"), name: attr(resource, "name"), description: attr(resource, "description") };
|
|
158821
158915
|
}
|
|
158916
|
+
function toReviewScreenshot(resource) {
|
|
158917
|
+
const attributes = resource.attributes ?? {};
|
|
158918
|
+
const delivery = attributes.assetDeliveryState ?? {};
|
|
158919
|
+
const errors = (delivery.errors ?? []).map((e2) => [e2.code, e2.description].filter((part2) => typeof part2 === "string").join(": "));
|
|
158920
|
+
const checksum = attr(resource, "sourceFileChecksum");
|
|
158921
|
+
return {
|
|
158922
|
+
id: resource.id,
|
|
158923
|
+
fileName: attr(resource, "fileName"),
|
|
158924
|
+
fileSize: typeof attributes.fileSize === "number" ? attributes.fileSize : 0,
|
|
158925
|
+
...checksum ? { checksum } : {},
|
|
158926
|
+
state: typeof delivery.state === "string" ? delivery.state : "",
|
|
158927
|
+
errors
|
|
158928
|
+
};
|
|
158929
|
+
}
|
|
158822
158930
|
function toManualPrice(price, included) {
|
|
158823
158931
|
const point = included.find((r2) => r2.type === "inAppPurchasePricePoints" && r2.id === relatedId(price, "inAppPurchasePricePoint"));
|
|
158824
158932
|
const date = (name) => typeof price.attributes?.[name] === "string" ? price.attributes[name] : null;
|
|
@@ -158840,7 +158948,7 @@ async function readOptional(read) {
|
|
|
158840
158948
|
function createIapApi(client2) {
|
|
158841
158949
|
return new AppStoreConnectIapApi(client2);
|
|
158842
158950
|
}
|
|
158843
|
-
var APPLE_PRODUCT_TYPES, PRICE_POINT_PAGE, INITIAL_PRICE_REF, PAGE, linkage, related, enc, AppStoreConnectIapApi;
|
|
158951
|
+
var APPLE_PRODUCT_TYPES, PRICE_POINT_PAGE, INITIAL_PRICE_REF, PAGE, linkage, related, enc, AppStoreConnectIapApi, SCREENSHOTS, SCREENSHOT_TYPE, ReviewScreenshotEndpoints;
|
|
158844
158952
|
var init_iap_api = __esm({
|
|
158845
158953
|
"../store-release/iap-api.ts"() {
|
|
158846
158954
|
init_iap_client();
|
|
@@ -158854,7 +158962,9 @@ var init_iap_api = __esm({
|
|
|
158854
158962
|
AppStoreConnectIapApi = class {
|
|
158855
158963
|
constructor(client2) {
|
|
158856
158964
|
this.client = client2;
|
|
158965
|
+
this.screenshots = new ReviewScreenshotEndpoints(client2);
|
|
158857
158966
|
}
|
|
158967
|
+
screenshots;
|
|
158858
158968
|
async readApp(appId2) {
|
|
158859
158969
|
const app = requireSingle(await this.client.get(`/v1/apps/${enc(appId2)}?fields[apps]=bundleId`), "app");
|
|
158860
158970
|
return { id: app.id, bundleId: attr(app, "bundleId") };
|
|
@@ -158974,6 +159084,50 @@ var init_iap_api = __esm({
|
|
|
158974
159084
|
}
|
|
158975
159085
|
});
|
|
158976
159086
|
}
|
|
159087
|
+
async readReviewScreenshot(resourceId) {
|
|
159088
|
+
return this.screenshots.read(resourceId);
|
|
159089
|
+
}
|
|
159090
|
+
async reserveReviewScreenshot(resourceId, file2) {
|
|
159091
|
+
return this.screenshots.reserve(resourceId, file2);
|
|
159092
|
+
}
|
|
159093
|
+
async uploadReviewScreenshotParts(reservation, bytes2) {
|
|
159094
|
+
await this.client.uploadParts(reservation.uploadOperations, bytes2);
|
|
159095
|
+
}
|
|
159096
|
+
async commitReviewScreenshot(screenshotId, checksum) {
|
|
159097
|
+
return this.screenshots.commit(screenshotId, checksum);
|
|
159098
|
+
}
|
|
159099
|
+
async deleteReviewScreenshot(screenshotId) {
|
|
159100
|
+
await this.screenshots.delete(screenshotId);
|
|
159101
|
+
}
|
|
159102
|
+
};
|
|
159103
|
+
SCREENSHOTS = "/v1/inAppPurchaseAppStoreReviewScreenshots";
|
|
159104
|
+
SCREENSHOT_TYPE = "inAppPurchaseAppStoreReviewScreenshots";
|
|
159105
|
+
ReviewScreenshotEndpoints = class {
|
|
159106
|
+
constructor(client2) {
|
|
159107
|
+
this.client = client2;
|
|
159108
|
+
}
|
|
159109
|
+
async read(resourceId) {
|
|
159110
|
+
const screenshot = await readOptional(() => this.client.get(`/v2/inAppPurchases/${enc(resourceId)}/appStoreReviewScreenshot`));
|
|
159111
|
+
return screenshot && toReviewScreenshot(screenshot);
|
|
159112
|
+
}
|
|
159113
|
+
async reserve(resourceId, file2) {
|
|
159114
|
+
const doc = await this.client.post(SCREENSHOTS, {
|
|
159115
|
+
data: { type: SCREENSHOT_TYPE, attributes: file2, relationships: { inAppPurchaseV2: related("inAppPurchases", resourceId) } }
|
|
159116
|
+
});
|
|
159117
|
+
const reservation = requireSingle(doc, "review screenshot reservation");
|
|
159118
|
+
const operations = reservation.attributes?.uploadOperations;
|
|
159119
|
+
if (!Array.isArray(operations) || !operations.length) throw new AscError("server", "App Store Connect reserved the review screenshot without upload operations");
|
|
159120
|
+
return { id: reservation.id, uploadOperations: operations };
|
|
159121
|
+
}
|
|
159122
|
+
async commit(screenshotId, checksum) {
|
|
159123
|
+
const doc = await this.client.patch(`${SCREENSHOTS}/${enc(screenshotId)}`, {
|
|
159124
|
+
data: { type: SCREENSHOT_TYPE, id: screenshotId, attributes: { uploaded: true, sourceFileChecksum: checksum } }
|
|
159125
|
+
});
|
|
159126
|
+
return toReviewScreenshot(requireSingle(doc, "review screenshot"));
|
|
159127
|
+
}
|
|
159128
|
+
async delete(screenshotId) {
|
|
159129
|
+
await this.client.delete(`${SCREENSHOTS}/${enc(screenshotId)}`);
|
|
159130
|
+
}
|
|
158977
159131
|
};
|
|
158978
159132
|
}
|
|
158979
159133
|
});
|
|
@@ -159058,6 +159212,7 @@ function readItem(reader, value, index) {
|
|
|
159058
159212
|
const price = readPrice(reader, obj3, path2);
|
|
159059
159213
|
const reviewNote = reader.optionalText(obj3, "reviewNote", path2);
|
|
159060
159214
|
if (reviewNote) reader.maxLength(reviewNote, `${path2}.reviewNote`, APPLE_LIMITS.reviewNote);
|
|
159215
|
+
const reviewScreenshot = obj3.reviewScreenshot === void 0 ? void 0 : reader.text(obj3, "reviewScreenshot", path2, SCREENSHOT_PATH);
|
|
159061
159216
|
return {
|
|
159062
159217
|
...readSubject(reader, obj3, path2, type),
|
|
159063
159218
|
classification: reader.literal(obj3, "classification", path2, "digital", "physical goods and unclassified products are never registered as in-app purchases"),
|
|
@@ -159066,6 +159221,7 @@ function readItem(reader, value, index) {
|
|
|
159066
159221
|
type,
|
|
159067
159222
|
referenceName: limitedText(reader, obj3, "referenceName", path2, APPLE_LIMITS.referenceName),
|
|
159068
159223
|
...reviewNote === void 0 ? {} : { reviewNote },
|
|
159224
|
+
...reviewScreenshot === void 0 ? {} : { reviewScreenshot },
|
|
159069
159225
|
localizations: readLocalizations(reader, obj3, path2),
|
|
159070
159226
|
price,
|
|
159071
159227
|
territories: readTerritories(reader, obj3, path2, price.baseTerritory)
|
|
@@ -159128,7 +159284,7 @@ function sha256Digest(value) {
|
|
|
159128
159284
|
function manifestDigest(manifest) {
|
|
159129
159285
|
return sha256Digest(manifest);
|
|
159130
159286
|
}
|
|
159131
|
-
var IapManifestError, APPLE_APP_ID, TEAM_ID, BUNDLE_ID, PRODUCT_ID, TERRITORY, CURRENCY2, AMOUNT, LOCALE, CREDENTIAL_SHAPES, MANIFEST_KEYS, TARGET_KEYS, ITEM_KEYS, WIX_KEYS, UNLOCK_KEYS, LOCALIZATION_KEYS, PRICE_KEYS, PRODUCT_TYPES, PRICE_RULES, APPLE_LIMITS, childPath, ManifestReader;
|
|
159287
|
+
var IapManifestError, APPLE_APP_ID, TEAM_ID, BUNDLE_ID, PRODUCT_ID, TERRITORY, CURRENCY2, AMOUNT, LOCALE, SCREENSHOT_PATH, CREDENTIAL_SHAPES, MANIFEST_KEYS, TARGET_KEYS, ITEM_KEYS, WIX_KEYS, UNLOCK_KEYS, LOCALIZATION_KEYS, PRICE_KEYS, PRODUCT_TYPES, PRICE_RULES, APPLE_LIMITS, childPath, ManifestReader;
|
|
159132
159288
|
var init_iap_manifest = __esm({
|
|
159133
159289
|
"../store-release/iap-manifest.ts"() {
|
|
159134
159290
|
IapManifestError = class extends Error {
|
|
@@ -159147,6 +159303,7 @@ var init_iap_manifest = __esm({
|
|
|
159147
159303
|
CURRENCY2 = { pattern: /^[A-Z]{3}$/, hint: "an ISO 4217 currency code such as USD" };
|
|
159148
159304
|
AMOUNT = { pattern: /^\d+(\.\d+)?$/, hint: 'an exact decimal string such as "0.99"' };
|
|
159149
159305
|
LOCALE = { pattern: /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/, hint: "a locale such as en-US" };
|
|
159306
|
+
SCREENSHOT_PATH = { pattern: /\.(png|jpe?g)$/i, hint: "a path to a .png, .jpg or .jpeg file" };
|
|
159150
159307
|
CREDENTIAL_SHAPES = [
|
|
159151
159308
|
/-----BEGIN [A-Z ]*PRIVATE KEY-----/,
|
|
159152
159309
|
/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/,
|
|
@@ -159163,6 +159320,7 @@ var init_iap_manifest = __esm({
|
|
|
159163
159320
|
"type",
|
|
159164
159321
|
"referenceName",
|
|
159165
159322
|
"reviewNote",
|
|
159323
|
+
"reviewScreenshot",
|
|
159166
159324
|
"localizations",
|
|
159167
159325
|
"price",
|
|
159168
159326
|
"territories"
|
|
@@ -159312,8 +159470,16 @@ var init_iap_pricing = __esm({
|
|
|
159312
159470
|
});
|
|
159313
159471
|
|
|
159314
159472
|
// ../store-release/iap-result.ts
|
|
159315
|
-
|
|
159473
|
+
import { basename as basename18 } from "node:path";
|
|
159474
|
+
function missingMetadataRequirement(screenshotState, itemNamesFile) {
|
|
159475
|
+
if (screenshotState === void 0) return MISSING_SCREENSHOT;
|
|
159476
|
+
const leftover = LEFTOVER_STATES[screenshotState];
|
|
159477
|
+
if (!leftover) return MISSING_AFTER_SCREENSHOT;
|
|
159478
|
+
return leftover.problem + (itemNamesFile ? leftover.fix : ADD_FILE_FIRST);
|
|
159479
|
+
}
|
|
159480
|
+
function remainingRequirements(observed, itemNamesFile = true) {
|
|
159316
159481
|
if (!observed) return ["the product does not exist in App Store Connect yet"];
|
|
159482
|
+
if (observed.state === "MISSING_METADATA") return [observed.reviewScreenshotRead ? missingMetadataRequirement(observed.reviewScreenshot?.state, itemNamesFile) : MISSING_UNREAD];
|
|
159317
159483
|
const requirement = STATE_REQUIREMENTS[observed.state];
|
|
159318
159484
|
return requirement ? [requirement] : [];
|
|
159319
159485
|
}
|
|
@@ -159334,6 +159500,10 @@ function mappingFor(target, item, appleResourceId) {
|
|
|
159334
159500
|
function metadataVersion(observed) {
|
|
159335
159501
|
return observed?.versions.find((v2) => v2.id === observed.metadataVersionId);
|
|
159336
159502
|
}
|
|
159503
|
+
function screenshotReport(path2, observed) {
|
|
159504
|
+
const held = observed?.reviewScreenshot;
|
|
159505
|
+
return { requested: basename18(path2), ...held ? { observed: { fileName: held.fileName, state: held.state } } : {} };
|
|
159506
|
+
}
|
|
159337
159507
|
function itemResult(input) {
|
|
159338
159508
|
const { target, item, observed } = input;
|
|
159339
159509
|
const version4 = metadataVersion(observed);
|
|
@@ -159352,7 +159522,8 @@ function itemResult(input) {
|
|
|
159352
159522
|
...observed?.availability ? { observed: observed.availability.territories, availableInNewTerritories: observed.availability.availableInNewTerritories } : {}
|
|
159353
159523
|
},
|
|
159354
159524
|
localizations: { requested: item.localizations.map((l2) => l2.locale), observed: observed?.localizations.map((l2) => l2.locale) ?? [] },
|
|
159355
|
-
|
|
159525
|
+
...item.reviewScreenshot ? { reviewScreenshot: screenshotReport(item.reviewScreenshot, observed) } : {},
|
|
159526
|
+
remainingRequirements: [...input.requirements ?? [], ...remainingRequirements(observed, item.reviewScreenshot !== void 0)],
|
|
159356
159527
|
lastReadAt: input.readAt.toISOString()
|
|
159357
159528
|
}
|
|
159358
159529
|
};
|
|
@@ -159369,12 +159540,11 @@ function iapResult(args) {
|
|
|
159369
159540
|
items: args.items
|
|
159370
159541
|
};
|
|
159371
159542
|
}
|
|
159372
|
-
var COMPLETE_OUTCOMES, STATE_REQUIREMENTS;
|
|
159543
|
+
var COMPLETE_OUTCOMES, STATE_REQUIREMENTS, MISSING_SCREENSHOT, MISSING_UNREAD, REFUSED_SCREENSHOT, MISSING_AFTER_SCREENSHOT, UNFINISHED_SCREENSHOT, LEFTOVER_STATES, ADD_FILE_FIRST;
|
|
159373
159544
|
var init_iap_result = __esm({
|
|
159374
159545
|
"../store-release/iap-result.ts"() {
|
|
159375
159546
|
COMPLETE_OUTCOMES = /* @__PURE__ */ new Set(["created", "updated", "reused"]);
|
|
159376
159547
|
STATE_REQUIREMENTS = {
|
|
159377
|
-
MISSING_METADATA: "App Store Connect reports MISSING_METADATA \u2014 usually the App Review screenshot, which this command does not upload",
|
|
159378
159548
|
READY_TO_SUBMIT: "submit the product for App Review with an app version \u2014 this command never submits",
|
|
159379
159549
|
DEVELOPER_ACTION_NEEDED: "resolve the App Review feedback in App Store Connect",
|
|
159380
159550
|
REJECTED: "resolve the App Review rejection in App Store Connect",
|
|
@@ -159386,6 +159556,16 @@ var init_iap_result = __esm({
|
|
|
159386
159556
|
WAITING_FOR_UPLOAD: "waiting for its hosted content to be uploaded",
|
|
159387
159557
|
PROCESSING_CONTENT: "Apple is still processing its hosted content"
|
|
159388
159558
|
};
|
|
159559
|
+
MISSING_SCREENSHOT = 'App Store Connect reports MISSING_METADATA and the product has no App Review screenshot \u2014 add "reviewScreenshot" to the item and apply, or upload one in App Store Connect';
|
|
159560
|
+
MISSING_UNREAD = 'App Store Connect reports MISSING_METADATA \u2014 check the product in App Store Connect; when it lacks the App Review screenshot, add "reviewScreenshot" to the item and apply';
|
|
159561
|
+
REFUSED_SCREENSHOT = "App Store Connect reports MISSING_METADATA \u2014 Apple could not process the review screenshot";
|
|
159562
|
+
MISSING_AFTER_SCREENSHOT = "App Store Connect still reports MISSING_METADATA \u2014 Apple may still be processing the review screenshot; if it stays, check the product in App Store Connect";
|
|
159563
|
+
UNFINISHED_SCREENSHOT = "App Store Connect reports MISSING_METADATA \u2014 the review screenshot upload is unfinished";
|
|
159564
|
+
LEFTOVER_STATES = {
|
|
159565
|
+
FAILED: { problem: REFUSED_SCREENSHOT, fix: "; replace the file and apply again" },
|
|
159566
|
+
AWAITING_UPLOAD: { problem: UNFINISHED_SCREENSHOT, fix: "; rerun plan and apply to replace it" }
|
|
159567
|
+
};
|
|
159568
|
+
ADD_FILE_FIRST = ' \u2014 add "reviewScreenshot" to the item first, then plan and apply';
|
|
159389
159569
|
}
|
|
159390
159570
|
});
|
|
159391
159571
|
|
|
@@ -159429,6 +159609,99 @@ var init_iap_price_status = __esm({
|
|
|
159429
159609
|
}
|
|
159430
159610
|
});
|
|
159431
159611
|
|
|
159612
|
+
// ../store-release/screenshot-display-types.ts
|
|
159613
|
+
function displayTypeForSize(w2, h2) {
|
|
159614
|
+
const key2 = `${Math.min(w2, h2)}x${Math.max(w2, h2)}`;
|
|
159615
|
+
const map = {
|
|
159616
|
+
"1320x2868": "APP_IPHONE_67",
|
|
159617
|
+
// 6.9" → 6.7"/6.9" combined slot
|
|
159618
|
+
"1290x2796": "APP_IPHONE_67",
|
|
159619
|
+
// 6.7"
|
|
159620
|
+
"1242x2688": "APP_IPHONE_65",
|
|
159621
|
+
// 6.5"
|
|
159622
|
+
"1284x2778": "APP_IPHONE_65",
|
|
159623
|
+
"1206x2622": "APP_IPHONE_61",
|
|
159624
|
+
// 6.3"/6.1"
|
|
159625
|
+
"1179x2556": "APP_IPHONE_61",
|
|
159626
|
+
"2048x2732": "APP_IPAD_PRO_129",
|
|
159627
|
+
"2064x2752": "APP_IPAD_PRO_3GEN_129"
|
|
159628
|
+
};
|
|
159629
|
+
return map[key2] ?? null;
|
|
159630
|
+
}
|
|
159631
|
+
var init_screenshot_display_types = __esm({
|
|
159632
|
+
"../store-release/screenshot-display-types.ts"() {
|
|
159633
|
+
}
|
|
159634
|
+
});
|
|
159635
|
+
|
|
159636
|
+
// ../store-release/iap-review-screenshot.ts
|
|
159637
|
+
import { createHash as createHash38 } from "node:crypto";
|
|
159638
|
+
import { basename as basename19, resolve as resolve56 } from "node:path";
|
|
159639
|
+
function pngSize(bytes2) {
|
|
159640
|
+
const signed = PNG_SIGNATURE.every((b2, i2) => bytes2[i2] === b2);
|
|
159641
|
+
if (!signed || bytes2.length < 24 || bytes2.toString("ascii", 12, 16) !== "IHDR") return void 0;
|
|
159642
|
+
return { format: "png", width: bytes2.readUInt32BE(16), height: bytes2.readUInt32BE(20) };
|
|
159643
|
+
}
|
|
159644
|
+
function jpegSize(bytes2) {
|
|
159645
|
+
if (bytes2[0] !== 255 || bytes2[1] !== 216) return void 0;
|
|
159646
|
+
for (let at2 = 2; at2 + 9 <= bytes2.length && bytes2[at2] === 255; at2 += 2 + bytes2.readUInt16BE(at2 + 2)) {
|
|
159647
|
+
if (JPEG_SOF_MARKERS.has(bytes2[at2 + 1])) return { format: "jpeg", height: bytes2.readUInt16BE(at2 + 5), width: bytes2.readUInt16BE(at2 + 7) };
|
|
159648
|
+
}
|
|
159649
|
+
return void 0;
|
|
159650
|
+
}
|
|
159651
|
+
function readImageSize(bytes2) {
|
|
159652
|
+
const buffer = Buffer.from(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
|
|
159653
|
+
return pngSize(buffer) ?? jpegSize(buffer);
|
|
159654
|
+
}
|
|
159655
|
+
function md5Hex(bytes2) {
|
|
159656
|
+
return createHash38("md5").update(bytes2).digest("hex");
|
|
159657
|
+
}
|
|
159658
|
+
function isAppStoreScreenshotSize(file2) {
|
|
159659
|
+
return displayTypeForSize(file2.width, file2.height) !== null;
|
|
159660
|
+
}
|
|
159661
|
+
function screenshotNotes(file2) {
|
|
159662
|
+
const size = `${file2.width}\xD7${file2.height}`;
|
|
159663
|
+
const notes = [`review screenshot ${file2.fileName} (${size} ${file2.format.toUpperCase()})`];
|
|
159664
|
+
if (!isAppStoreScreenshotSize(file2)) notes.push(`${size} is not an App Store screenshot size this tool knows \u2014 Apple may refuse it; a full-size iPhone screenshot is safest`);
|
|
159665
|
+
return notes;
|
|
159666
|
+
}
|
|
159667
|
+
function readReviewScreenshot(path2, source) {
|
|
159668
|
+
if (!source.readBytes) throw new Error("this run cannot read files");
|
|
159669
|
+
const absolute = resolve56(source.manifestDir ?? process.cwd(), path2);
|
|
159670
|
+
let bytes2;
|
|
159671
|
+
try {
|
|
159672
|
+
bytes2 = source.readBytes(absolute);
|
|
159673
|
+
} catch (e2) {
|
|
159674
|
+
throw new Error(`cannot read ${absolute}: ${e2.message}`);
|
|
159675
|
+
}
|
|
159676
|
+
const size = readImageSize(bytes2);
|
|
159677
|
+
if (!size) throw new Error(`${absolute} is not a PNG or JPEG image`);
|
|
159678
|
+
return { ...size, path: absolute, fileName: basename19(absolute), bytes: bytes2, checksum: md5Hex(bytes2) };
|
|
159679
|
+
}
|
|
159680
|
+
function loadReviewScreenshots(manifest, source, indices = manifest.items.map((_2, i2) => i2)) {
|
|
159681
|
+
const files = /* @__PURE__ */ new Map();
|
|
159682
|
+
const problems = [];
|
|
159683
|
+
for (const i2 of indices) {
|
|
159684
|
+
const path2 = manifest.items[i2].reviewScreenshot;
|
|
159685
|
+
if (path2 === void 0) continue;
|
|
159686
|
+
try {
|
|
159687
|
+
files.set(i2, readReviewScreenshot(path2, source));
|
|
159688
|
+
} catch (e2) {
|
|
159689
|
+
problems.push(`items[${i2}].reviewScreenshot: ${e2.message}`);
|
|
159690
|
+
}
|
|
159691
|
+
}
|
|
159692
|
+
if (problems.length) throw new IapManifestError("the manifest", problems);
|
|
159693
|
+
return files;
|
|
159694
|
+
}
|
|
159695
|
+
var PNG_SIGNATURE, JPEG_SOF_MARKERS;
|
|
159696
|
+
var init_iap_review_screenshot = __esm({
|
|
159697
|
+
"../store-release/iap-review-screenshot.ts"() {
|
|
159698
|
+
init_iap_manifest();
|
|
159699
|
+
init_screenshot_display_types();
|
|
159700
|
+
PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
159701
|
+
JPEG_SOF_MARKERS = /* @__PURE__ */ new Set([192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207]);
|
|
159702
|
+
}
|
|
159703
|
+
});
|
|
159704
|
+
|
|
159432
159705
|
// ../store-release/iap-plan.ts
|
|
159433
159706
|
function priceNote(price, target) {
|
|
159434
159707
|
if (price.rule !== "atLeast") return CONDITIONAL_PRICE_NOTE;
|
|
@@ -159568,6 +159841,47 @@ function availabilityDiff(item, observed) {
|
|
|
159568
159841
|
function metadataDiffs(item, observed, target = exactTarget(item.price)) {
|
|
159569
159842
|
return [...localizationDiffs(item, observed), ...priceDiff(item, observed, target), ...availabilityDiff(item, observed)];
|
|
159570
159843
|
}
|
|
159844
|
+
function screenshotMatches(observed, checksum) {
|
|
159845
|
+
return observed?.checksum === checksum && observed.state !== "FAILED";
|
|
159846
|
+
}
|
|
159847
|
+
function describeScreenshotGap(observed, fileName) {
|
|
159848
|
+
if (!observed) return "the review screenshot is not uploaded";
|
|
159849
|
+
if (observed.state === "AWAITING_UPLOAD") return "the review screenshot is not uploaded \u2014 an unfinished upload is waiting";
|
|
159850
|
+
if (observed.state === "FAILED") return `Apple could not process the review screenshot: ${observed.errors.join("; ") || "no reason given"}`;
|
|
159851
|
+
return `the review screenshot differs from ${fileName}`;
|
|
159852
|
+
}
|
|
159853
|
+
function screenshotUnmet(planned2, observed) {
|
|
159854
|
+
if (!planned2 || !observed || screenshotMatches(observed.reviewScreenshot, planned2.checksum)) return [];
|
|
159855
|
+
return [describeScreenshotGap(observed.reviewScreenshot, planned2.fileName)];
|
|
159856
|
+
}
|
|
159857
|
+
async function withReviewScreenshot(api2, observed) {
|
|
159858
|
+
if (observed.reviewScreenshotRead) return observed;
|
|
159859
|
+
const reviewScreenshot = await api2.readReviewScreenshot(observed.resourceId);
|
|
159860
|
+
return { ...observed, reviewScreenshotRead: true, ...reviewScreenshot ? { reviewScreenshot } : {} };
|
|
159861
|
+
}
|
|
159862
|
+
function isScreenshotLeftover(held) {
|
|
159863
|
+
return LEFTOVER_SCREENSHOT_STATES.has(held.state);
|
|
159864
|
+
}
|
|
159865
|
+
function screenshotOp(observed, checksum) {
|
|
159866
|
+
return { kind: observed.reviewScreenshot ? "replaceReviewScreenshot" : "uploadReviewScreenshot", checksum };
|
|
159867
|
+
}
|
|
159868
|
+
async function planReviewScreenshot(api2, plan, file2) {
|
|
159869
|
+
if (!file2) return plan;
|
|
159870
|
+
const planned2 = { ...plan, notes: [...plan.notes, ...screenshotNotes(file2)], reviewScreenshot: { fileName: file2.fileName, checksum: file2.checksum } };
|
|
159871
|
+
if (plan.decision === "conflict") return plan.observed ? { ...planned2, observed: await withReviewScreenshot(api2, plan.observed) } : planned2;
|
|
159872
|
+
if (plan.decision === "create") return { ...planned2, ops: [...plan.ops, { kind: "uploadReviewScreenshot", checksum: file2.checksum }] };
|
|
159873
|
+
const observed = await withReviewScreenshot(api2, observationOf(plan));
|
|
159874
|
+
const [gap] = screenshotUnmet(planned2.reviewScreenshot, observed);
|
|
159875
|
+
if (!gap) return { ...planned2, observed };
|
|
159876
|
+
if (isLocked(observed)) {
|
|
159877
|
+
return { ...planned2, observed, decision: "conflict", ops: [], conflicts: [`${plan.productId} is ${observed.state} and this command never changes a live or in-review product: ${gap}`] };
|
|
159878
|
+
}
|
|
159879
|
+
return { ...planned2, observed, decision: "update", ops: [...plan.ops, screenshotOp(observed, file2.checksum)] };
|
|
159880
|
+
}
|
|
159881
|
+
function observationOf(plan) {
|
|
159882
|
+
if (!plan.observed) throw new Error(`internal: the plan for existing product ${plan.productId} has no observation`);
|
|
159883
|
+
return plan.observed;
|
|
159884
|
+
}
|
|
159571
159885
|
function isLocked(observed) {
|
|
159572
159886
|
return !EDITABLE_PRODUCT_STATES.has(observed.state) || observed.versions.some((v2) => LOCKED_VERSION_STATES.has(v2.state));
|
|
159573
159887
|
}
|
|
@@ -159672,11 +159986,15 @@ async function planItem(pricing, api2, item, products, today) {
|
|
|
159672
159986
|
}
|
|
159673
159987
|
async function planItemsAt(context, manifest, indices = manifest.items.map((_2, i2) => i2)) {
|
|
159674
159988
|
const pricing = context.pricing ?? new PriceGrid(context.api);
|
|
159989
|
+
const screenshots = loadReviewScreenshots(manifest, context, indices);
|
|
159675
159990
|
return withAccessContext(context.identity, manifest.target, async () => {
|
|
159676
159991
|
await verifyTarget(context.api, manifest, context.identity);
|
|
159677
159992
|
const products = await discoverProducts(context, manifest);
|
|
159678
159993
|
const plans = /* @__PURE__ */ new Map();
|
|
159679
|
-
for (const i2 of indices)
|
|
159994
|
+
for (const i2 of indices) {
|
|
159995
|
+
const planned2 = await planItem(pricing, context.api, manifest.items[i2], products, isoDay(context.now()));
|
|
159996
|
+
plans.set(i2, await planReviewScreenshot(context.api, planned2, screenshots.get(i2)));
|
|
159997
|
+
}
|
|
159680
159998
|
return plans;
|
|
159681
159999
|
});
|
|
159682
160000
|
}
|
|
@@ -159696,6 +160014,7 @@ async function planIap(manifest, context) {
|
|
|
159696
160014
|
target: manifest.target,
|
|
159697
160015
|
manifestDigest: manifestDigest(manifest),
|
|
159698
160016
|
manifest,
|
|
160017
|
+
...context.manifestDir ? { manifestDir: context.manifestDir } : {},
|
|
159699
160018
|
items
|
|
159700
160019
|
});
|
|
159701
160020
|
}
|
|
@@ -159706,13 +160025,18 @@ function verifyOps(plan, manifest) {
|
|
|
159706
160025
|
if (itemPlan2.productId !== item.productId || !Array.isArray(itemPlan2.ops)) throw planError(`plan item ${i2} does not match manifest product ${item.productId}`);
|
|
159707
160026
|
for (const op of itemPlan2.ops) {
|
|
159708
160027
|
const locales = item.localizations.map((l2) => l2.locale);
|
|
159709
|
-
const knownShape = OP_KINDS.has(op.kind) && Object.keys(op).every((k2) => k2 === "kind" || k2 === "locale" && LOCALE_OPS.has(op.kind) || op.kind === "changePrice" && (k2 === "from" || k2 === "to"));
|
|
160028
|
+
const knownShape = OP_KINDS.has(op.kind) && Object.keys(op).every((k2) => k2 === "kind" || k2 === "locale" && LOCALE_OPS.has(op.kind) || op.kind === "changePrice" && (k2 === "from" || k2 === "to") || k2 === "checksum" && SCREENSHOT_OPS.has(op.kind));
|
|
159710
160029
|
const localeOk = !LOCALE_OPS.has(op.kind) || locales.includes(op.locale);
|
|
159711
160030
|
const priceOk = op.kind !== "changePrice" || item.price.rule === "atLeast" && [op.from, op.to].every((v2) => typeof v2 === "string" && /^\d+(\.\d+)?$/.test(v2) && compareAmounts(v2, "0") > 0) && itemPlan2.observed?.priceSchedule !== void 0 && itemPlan2.targetPrice === op.to;
|
|
159712
|
-
|
|
160031
|
+
const screenshotOk = !SCREENSHOT_OPS.has(op.kind) || screenshotOpOk(op, item, itemPlan2);
|
|
160032
|
+
if (!knownShape || !localeOk || !priceOk || !screenshotOk) throw planError(`plan item ${item.productId} has an unknown operation ${JSON.stringify(op)}`);
|
|
159713
160033
|
}
|
|
159714
160034
|
});
|
|
159715
160035
|
}
|
|
160036
|
+
function screenshotOpOk(op, item, itemPlan2) {
|
|
160037
|
+
const { checksum } = op;
|
|
160038
|
+
return item.reviewScreenshot !== void 0 && typeof checksum === "string" && MD5_HEX.test(checksum) && itemPlan2.reviewScreenshot?.checksum === checksum;
|
|
160039
|
+
}
|
|
159716
160040
|
function verifyPlan2(doc) {
|
|
159717
160041
|
const plan = doc;
|
|
159718
160042
|
if (!plan || typeof plan !== "object" || plan.planVersion !== 1) throw planError("not a himi store iap plan (planVersion 1)");
|
|
@@ -159729,8 +160053,9 @@ async function statusIap(manifest, context, catalog3) {
|
|
|
159729
160053
|
const plans = await planItems({ ...context, pricing }, manifest);
|
|
159730
160054
|
const readAt2 = context.now();
|
|
159731
160055
|
const items = [];
|
|
159732
|
-
for (const [i2,
|
|
160056
|
+
for (const [i2, planned2] of plans.entries()) {
|
|
159733
160057
|
const item = manifest.items[i2];
|
|
160058
|
+
const p2 = planned2.observed ? { ...planned2, observed: await withAccessContext(context.identity, manifest.target, () => withReviewScreenshot(context.api, planned2.observed)) } : planned2;
|
|
159734
160059
|
const target = p2.observed ? await pricing.targetAmount(item.price, p2.observed.resourceId) : void 0;
|
|
159735
160060
|
const result = itemResult({
|
|
159736
160061
|
target: manifest.target,
|
|
@@ -159738,7 +160063,7 @@ async function statusIap(manifest, context, catalog3) {
|
|
|
159738
160063
|
observed: p2.observed,
|
|
159739
160064
|
outcome: STATUS_OUTCOMES[p2.decision],
|
|
159740
160065
|
conflicts: p2.conflicts,
|
|
159741
|
-
unmet: p2.observed ? metadataDiffs(item, p2.observed, target) : [],
|
|
160066
|
+
unmet: p2.observed ? [...metadataDiffs(item, p2.observed, target), ...screenshotUnmet(p2.reviewScreenshot, p2.observed)] : [],
|
|
159742
160067
|
readAt: readAt2
|
|
159743
160068
|
});
|
|
159744
160069
|
Object.assign(result.provisioning, await withAccessContext(context.identity, manifest.target, () => checkStatusPrice(item, p2.observed, pricing, catalog3)));
|
|
@@ -159746,7 +160071,7 @@ async function statusIap(manifest, context, catalog3) {
|
|
|
159746
160071
|
}
|
|
159747
160072
|
return iapResult({ target: manifest.target, identity: context.identity, items, generatedAt: readAt2 });
|
|
159748
160073
|
}
|
|
159749
|
-
var IapProvisionError, EDITABLE_VERSION_STATE, EDITABLE_PRODUCT_STATES, LOCKED_VERSION_STATES, OP_KINDS, LOCALE_OPS, CONDITIONAL_PRICE_NOTE, STATUS_OUTCOMES, isoDay, exactTarget, planError;
|
|
160074
|
+
var IapProvisionError, EDITABLE_VERSION_STATE, EDITABLE_PRODUCT_STATES, LOCKED_VERSION_STATES, SCREENSHOT_OPS, OP_KINDS, MD5_HEX, LOCALE_OPS, CONDITIONAL_PRICE_NOTE, STATUS_OUTCOMES, isoDay, exactTarget, LEFTOVER_SCREENSHOT_STATES, planError;
|
|
159750
160075
|
var init_iap_plan = __esm({
|
|
159751
160076
|
"../store-release/iap-plan.ts"() {
|
|
159752
160077
|
init_iap_api();
|
|
@@ -159755,6 +160080,7 @@ var init_iap_plan = __esm({
|
|
|
159755
160080
|
init_iap_pricing();
|
|
159756
160081
|
init_iap_result();
|
|
159757
160082
|
init_iap_price_status();
|
|
160083
|
+
init_iap_review_screenshot();
|
|
159758
160084
|
IapProvisionError = class extends Error {
|
|
159759
160085
|
constructor(reason, message) {
|
|
159760
160086
|
super(message);
|
|
@@ -159765,12 +160091,15 @@ var init_iap_plan = __esm({
|
|
|
159765
160091
|
EDITABLE_VERSION_STATE = "PREPARE_FOR_SUBMISSION";
|
|
159766
160092
|
EDITABLE_PRODUCT_STATES = /* @__PURE__ */ new Set(["MISSING_METADATA", "READY_TO_SUBMIT", "DEVELOPER_ACTION_NEEDED", "REJECTED"]);
|
|
159767
160093
|
LOCKED_VERSION_STATES = /* @__PURE__ */ new Set(["READY_FOR_REVIEW", "WAITING_FOR_REVIEW", "IN_REVIEW", "ACCEPTED", "APPROVED"]);
|
|
159768
|
-
|
|
160094
|
+
SCREENSHOT_OPS = /* @__PURE__ */ new Set(["uploadReviewScreenshot", "replaceReviewScreenshot"]);
|
|
160095
|
+
OP_KINDS = /* @__PURE__ */ new Set(["createProduct", "createVersion", "createLocalization", "updateLocalization", "setPrice", "changePrice", "setAvailability", ...SCREENSHOT_OPS]);
|
|
160096
|
+
MD5_HEX = /^[0-9a-f]{32}$/;
|
|
159769
160097
|
LOCALE_OPS = /* @__PURE__ */ new Set(["createLocalization", "updateLocalization"]);
|
|
159770
160098
|
CONDITIONAL_PRICE_NOTE = "the exact price point can only be looked up after the product exists \u2014 apply stops with a partial result if Apple has no point of exactly the requested amount";
|
|
159771
160099
|
STATUS_OUTCOMES = { create: "absent", update: "incomplete", reuse: "reused", conflict: "conflict" };
|
|
159772
160100
|
isoDay = (date) => date.toISOString().slice(0, 10);
|
|
159773
160101
|
exactTarget = (price) => price.rule === "atLeast" ? void 0 : price.amount;
|
|
160102
|
+
LEFTOVER_SCREENSHOT_STATES = /* @__PURE__ */ new Set(["AWAITING_UPLOAD", "FAILED"]);
|
|
159774
160103
|
planError = (message) => new IapProvisionError("plan", message);
|
|
159775
160104
|
}
|
|
159776
160105
|
});
|
|
@@ -159778,6 +160107,7 @@ var init_iap_plan = __esm({
|
|
|
159778
160107
|
// ../store-release/iap-apply.ts
|
|
159779
160108
|
function sameOp(a2, b2) {
|
|
159780
160109
|
if (a2.kind === "changePrice" && b2.kind === "changePrice") return a2.from === b2.from && a2.to === b2.to;
|
|
160110
|
+
if ("checksum" in a2 || "checksum" in b2) return "checksum" in a2 && "checksum" in b2 && a2.checksum === b2.checksum;
|
|
159781
160111
|
return a2.kind === b2.kind && ("locale" in a2 ? a2.locale : void 0) === ("locale" in b2 ? b2.locale : void 0);
|
|
159782
160112
|
}
|
|
159783
160113
|
function assertSameAccount(planned2, current) {
|
|
@@ -159798,9 +160128,19 @@ function driftOf(planned2, live3, today) {
|
|
|
159798
160128
|
const scheduleProblem = priceScheduleConflict(live3.observed?.priceSchedule, today);
|
|
159799
160129
|
if (scheduleProblem) return `${live3.productId}: ${scheduleProblem}`;
|
|
159800
160130
|
}
|
|
160131
|
+
const [plannedShot, liveShot] = [planned2.reviewScreenshot, live3.reviewScreenshot];
|
|
160132
|
+
if (plannedShot && liveShot && plannedShot.checksum !== liveShot.checksum) return `${live3.productId}: ${liveShot.fileName} changed since the plan was made`;
|
|
160133
|
+
if (replacesUnplannedScreenshot(planned2, live3)) return `${live3.productId}: a review screenshot was added in App Store Connect after the plan \u2014 make a new plan before replacing it`;
|
|
159801
160134
|
const unplanned = live3.ops.filter((op) => !planned2.ops.some((p2) => sameOp(p2, op)));
|
|
159802
160135
|
return unplanned.length ? `${live3.productId} now needs ${unplanned.map(describeOp).join(", ")}, which the plan did not list` : void 0;
|
|
159803
160136
|
}
|
|
160137
|
+
function replacesUnplannedScreenshot(planned2, live3) {
|
|
160138
|
+
if (!live3.ops.some((op) => op.kind === "replaceReviewScreenshot")) return false;
|
|
160139
|
+
const held = live3.observed?.reviewScreenshot;
|
|
160140
|
+
if (!held || isScreenshotLeftover(held)) return false;
|
|
160141
|
+
const seen = planned2.observed?.reviewScreenshot;
|
|
160142
|
+
return !seen || seen.id !== held.id || isScreenshotLeftover(seen);
|
|
160143
|
+
}
|
|
159804
160144
|
function assertNoDrift(plan, live3, today) {
|
|
159805
160145
|
const drift = [...live3].map(([i2, current]) => driftOf(plan.items[i2], current, today)).filter((d2) => d2 !== void 0);
|
|
159806
160146
|
if (!drift.length) return;
|
|
@@ -159853,6 +160193,50 @@ async function findLocalization(api2, versionId, locale, matchText) {
|
|
|
159853
160193
|
if (!found || matchText && (found.name !== matchText.name || found.description !== matchText.description)) return void 0;
|
|
159854
160194
|
return found;
|
|
159855
160195
|
}
|
|
160196
|
+
function plannedScreenshot(item, op, context) {
|
|
160197
|
+
const file2 = readReviewScreenshot(required(item.reviewScreenshot, "the review screenshot path"), context);
|
|
160198
|
+
if (!("checksum" in op) || file2.checksum !== op.checksum) throw new UnresolvedWriteError(`${file2.fileName} changed after the plan was made \u2014 make a new plan`);
|
|
160199
|
+
return file2;
|
|
160200
|
+
}
|
|
160201
|
+
async function reserveScreenshot(api2, resourceId, file2, overValid) {
|
|
160202
|
+
try {
|
|
160203
|
+
return await api2.reserveReviewScreenshot(resourceId, { fileName: file2.fileName, fileSize: file2.bytes.length });
|
|
160204
|
+
} catch (e2) {
|
|
160205
|
+
if (overValid && e2 instanceof AscError && e2.kind === "conflict") throw new UnresolvedWriteError(KEPT_EXISTING_SCREENSHOT);
|
|
160206
|
+
if (!(e2 instanceof AscError) || !AMBIGUOUS_WRITE_KINDS.has(e2.kind)) throw e2;
|
|
160207
|
+
throw new UnresolvedWriteError(`could not confirm the review screenshot reservation (${e2.message}). Make a new plan \u2014 it replaces an unfinished reservation.`);
|
|
160208
|
+
}
|
|
160209
|
+
}
|
|
160210
|
+
async function settledScreenshot(api2, resourceId, committed, sleep) {
|
|
160211
|
+
if (SETTLED_SCREENSHOT_STATES.has(committed.state)) return committed;
|
|
160212
|
+
const read = async () => {
|
|
160213
|
+
const current = await api2.readReviewScreenshot(resourceId);
|
|
160214
|
+
return current && SETTLED_SCREENSHOT_STATES.has(current.state) ? current : void 0;
|
|
160215
|
+
};
|
|
160216
|
+
return await pollFor(read, sleep) ?? committed;
|
|
160217
|
+
}
|
|
160218
|
+
async function uploadScreenshot(context, resourceId, file2) {
|
|
160219
|
+
const { api: api2, sleep } = context;
|
|
160220
|
+
const current = await api2.readReviewScreenshot(resourceId);
|
|
160221
|
+
if (current && screenshotMatches(current, file2.checksum)) return { state: "reconciled", resourceId: current.id };
|
|
160222
|
+
const reservation = await reserveScreenshot(api2, resourceId, file2, current !== void 0 && !isScreenshotLeftover(current));
|
|
160223
|
+
await api2.uploadReviewScreenshotParts(reservation, file2.bytes);
|
|
160224
|
+
const committed = async () => {
|
|
160225
|
+
const screenshot = await api2.readReviewScreenshot(resourceId);
|
|
160226
|
+
return screenshot?.id === reservation.id && screenshot.checksum === file2.checksum ? screenshot : void 0;
|
|
160227
|
+
};
|
|
160228
|
+
const { value, state } = await ensure({ write: () => api2.commitReviewScreenshot(reservation.id, file2.checksum), find: committed }, sleep);
|
|
160229
|
+
const settled = await settledScreenshot(api2, resourceId, value, sleep);
|
|
160230
|
+
if (settled.state === "FAILED") throw new UnresolvedWriteError(`Apple could not process the review screenshot: ${settled.errors.join("; ") || "no reason given"}`);
|
|
160231
|
+
return { state, resourceId: reservation.id };
|
|
160232
|
+
}
|
|
160233
|
+
async function deleteLeftoverScreenshot(context, resourceId) {
|
|
160234
|
+
const { api: api2, sleep } = context;
|
|
160235
|
+
const stale = await api2.readReviewScreenshot(resourceId);
|
|
160236
|
+
if (!stale || !isScreenshotLeftover(stale)) return;
|
|
160237
|
+
const gone = async () => (await api2.readReviewScreenshot(resourceId))?.id !== stale.id ? true : void 0;
|
|
160238
|
+
await ensure({ write: async () => (await api2.deleteReviewScreenshot(stale.id), true), find: gone }, sleep);
|
|
160239
|
+
}
|
|
159856
160240
|
function operationRunners(context, manifest) {
|
|
159857
160241
|
const { api: api2, sleep, pricing } = context;
|
|
159858
160242
|
const appId2 = manifest.target.appleAppId;
|
|
@@ -159918,6 +160302,13 @@ function operationRunners(context, manifest) {
|
|
|
159918
160302
|
const matches = async () => availabilityMatches(await readObservedAvailability(api2, resourceId), territories) ? true : void 0;
|
|
159919
160303
|
const { state } = await ensure({ write: async () => (await api2.createAvailability(resourceId, territories), true), find: matches }, sleep);
|
|
159920
160304
|
return { state };
|
|
160305
|
+
},
|
|
160306
|
+
uploadReviewScreenshot: async (run2, op) => uploadScreenshot(context, required(run2.resourceId, "the product id"), plannedScreenshot(run2.item, op, context)),
|
|
160307
|
+
replaceReviewScreenshot: async (run2, op) => {
|
|
160308
|
+
const resourceId = required(run2.resourceId, "the product id");
|
|
160309
|
+
const file2 = plannedScreenshot(run2.item, op, context);
|
|
160310
|
+
await deleteLeftoverScreenshot(context, resourceId);
|
|
160311
|
+
return uploadScreenshot(context, resourceId, file2);
|
|
159921
160312
|
}
|
|
159922
160313
|
};
|
|
159923
160314
|
}
|
|
@@ -159944,7 +160335,8 @@ async function runStep(runner2, run2, op, context, manifest) {
|
|
|
159944
160335
|
async function resumeFromApple(run2, remaining, context) {
|
|
159945
160336
|
const product = await context.api.readProduct(required(run2.resourceId, "the product id"));
|
|
159946
160337
|
if (!product) return { reason: "the product exists but cannot be read back yet \u2014 rerun apply later" };
|
|
159947
|
-
const
|
|
160338
|
+
const file2 = run2.item.reviewScreenshot === void 0 ? void 0 : readReviewScreenshot(run2.item.reviewScreenshot, context);
|
|
160339
|
+
const replanned = await planReviewScreenshot(context.api, await planForProduct(context.api, run2.item, product, context.pricing, context.now().toISOString().slice(0, 10)), file2);
|
|
159948
160340
|
if (replanned.decision === "conflict") return { reason: `the product already existed: ${replanned.conflicts.join("; ")}` };
|
|
159949
160341
|
const unplanned = replanned.ops.filter((op) => !remaining.some((r2) => sameOp(r2, op)));
|
|
159950
160342
|
if (unplanned.length) return { reason: `the product already existed and needs ${unplanned.map(describeOp).join(", ")}, which the plan did not list \u2014 make a new plan` };
|
|
@@ -159979,7 +160371,9 @@ async function readBack(run2, context, manifest) {
|
|
|
159979
160371
|
if (!run2.resourceId) return {};
|
|
159980
160372
|
try {
|
|
159981
160373
|
const product = await context.api.readProduct(run2.resourceId);
|
|
159982
|
-
|
|
160374
|
+
if (!product) return { failure: "Apple does not return it yet" };
|
|
160375
|
+
const observed = await observeProduct(context.api, product, context.now().toISOString().slice(0, 10));
|
|
160376
|
+
return { observed: run2.item.reviewScreenshot === void 0 ? observed : await withReviewScreenshot(context.api, observed) };
|
|
159983
160377
|
} catch (e2) {
|
|
159984
160378
|
return { failure: explainFailure(e2, context, manifest) };
|
|
159985
160379
|
}
|
|
@@ -159989,7 +160383,8 @@ async function unmetFor(item, observed, context) {
|
|
|
159989
160383
|
}
|
|
159990
160384
|
async function knownUnmetFor(item, planned2, context) {
|
|
159991
160385
|
if (!planned2.observed) return [];
|
|
159992
|
-
|
|
160386
|
+
const metadata2 = metadataDiffs(item, planned2.observed, planned2.targetPrice ?? await context.pricing.targetAmount(item.price));
|
|
160387
|
+
return [...metadata2, ...screenshotUnmet(planned2.reviewScreenshot, planned2.observed)];
|
|
159993
160388
|
}
|
|
159994
160389
|
async function applyItem(item, live3, context, manifest) {
|
|
159995
160390
|
const base = { target: manifest.target, item, readAt: context.now() };
|
|
@@ -160006,7 +160401,7 @@ async function applyItem(item, live3, context, manifest) {
|
|
|
160006
160401
|
};
|
|
160007
160402
|
const steps = await runOps(run2, live3.ops, context, manifest);
|
|
160008
160403
|
const { observed, failure } = await readBack(run2, context, manifest);
|
|
160009
|
-
const unmet = failure ? [`could not read the product back: ${failure}`] : await unmetFor(item, observed, context);
|
|
160404
|
+
const unmet = failure ? [`could not read the product back: ${failure}`] : [...await unmetFor(item, observed, context), ...screenshotUnmet(live3.reviewScreenshot, observed)];
|
|
160010
160405
|
const outcome = outcomeOf(live3.ops, steps, unmet);
|
|
160011
160406
|
return itemResult({ ...base, readAt: context.now(), observed, outcome, steps, unmet, appleResourceId: run2.resourceId });
|
|
160012
160407
|
}
|
|
@@ -160024,7 +160419,8 @@ function plannedResult(item, planned2, plan, context, manifest) {
|
|
|
160024
160419
|
async function applyIap(planDoc, applyContext) {
|
|
160025
160420
|
const plan = verifyPlan2(planDoc);
|
|
160026
160421
|
assertSameAccount(plan.identity, applyContext.identity);
|
|
160027
|
-
const
|
|
160422
|
+
const manifestDir = plan.manifestDir ?? applyContext.manifestDir;
|
|
160423
|
+
const context = { ...applyContext, ...manifestDir ? { manifestDir } : {}, pricing: applyContext.pricing ?? new PriceGrid(applyContext.api) };
|
|
160028
160424
|
const manifest = plan.manifest;
|
|
160029
160425
|
const refresh = plan.items.flatMap((planned2, i2) => needsRefresh(planned2) ? [i2] : []);
|
|
160030
160426
|
const live3 = await planItemsAt(context, manifest, refresh);
|
|
@@ -160047,23 +160443,26 @@ async function applyIap(planDoc, applyContext) {
|
|
|
160047
160443
|
}
|
|
160048
160444
|
return iapResult({ target: manifest.target, identity: context.identity, items, generatedAt: context.now() });
|
|
160049
160445
|
}
|
|
160050
|
-
var DEFERRED_REQUIREMENT, RECONCILE_READS, RECONCILE_BASE_WAIT_MS, AMBIGUOUS_WRITE_KINDS, UnresolvedWriteError, required;
|
|
160446
|
+
var DEFERRED_REQUIREMENT, RECONCILE_READS, RECONCILE_BASE_WAIT_MS, AMBIGUOUS_WRITE_KINDS, SETTLED_SCREENSHOT_STATES, UnresolvedWriteError, required, KEPT_EXISTING_SCREENSHOT;
|
|
160051
160447
|
var init_iap_apply = __esm({
|
|
160052
160448
|
"../store-release/iap-apply.ts"() {
|
|
160053
160449
|
init_iap_client();
|
|
160054
160450
|
init_iap_plan();
|
|
160055
160451
|
init_iap_pricing();
|
|
160452
|
+
init_iap_review_screenshot();
|
|
160056
160453
|
init_iap_result();
|
|
160057
160454
|
DEFERRED_REQUIREMENT = "deferred by --limit \u2014 rerun apply to continue; nothing was written for this product in this run";
|
|
160058
160455
|
RECONCILE_READS = 4;
|
|
160059
160456
|
RECONCILE_BASE_WAIT_MS = 1e3;
|
|
160060
160457
|
AMBIGUOUS_WRITE_KINDS = /* @__PURE__ */ new Set(["uncertain", "rateLimited", "conflict"]);
|
|
160458
|
+
SETTLED_SCREENSHOT_STATES = /* @__PURE__ */ new Set(["COMPLETE", "FAILED"]);
|
|
160061
160459
|
UnresolvedWriteError = class extends Error {
|
|
160062
160460
|
};
|
|
160063
160461
|
required = (value, what) => {
|
|
160064
160462
|
if (!value) throw new Error(`internal: ${what} is not known yet`);
|
|
160065
160463
|
return value;
|
|
160066
160464
|
};
|
|
160465
|
+
KEPT_EXISTING_SCREENSHOT = "Apple kept the existing review screenshot and refused a second one \u2014 replace it in App Store Connect (a review screenshot can be updated there but not removed)";
|
|
160067
160466
|
}
|
|
160068
160467
|
});
|
|
160069
160468
|
|
|
@@ -160187,11 +160586,11 @@ var init_credential_profile = __esm({
|
|
|
160187
160586
|
});
|
|
160188
160587
|
|
|
160189
160588
|
// ../store-release/iap-credentials.ts
|
|
160190
|
-
import { createHash as
|
|
160589
|
+
import { createHash as createHash39 } from "node:crypto";
|
|
160191
160590
|
import { existsSync as existsSync73, readFileSync as readFileSync88, realpathSync as realpathSync12 } from "node:fs";
|
|
160192
160591
|
import { homedir as homedir10 } from "node:os";
|
|
160193
160592
|
function accountFingerprint(keyId, issuerId) {
|
|
160194
|
-
return `sha256:${
|
|
160593
|
+
return `sha256:${createHash39("sha256").update(`${issuerId}:${keyId}`).digest("hex").slice(0, 16)}`;
|
|
160195
160594
|
}
|
|
160196
160595
|
function requireExplicitProfile(profileFlag, target) {
|
|
160197
160596
|
const profile = profileFlag?.trim();
|
|
@@ -160278,7 +160677,7 @@ var init_wix_payments_contract = __esm({
|
|
|
160278
160677
|
});
|
|
160279
160678
|
|
|
160280
160679
|
// ../store-release/iap-draft.ts
|
|
160281
|
-
import { createHash as
|
|
160680
|
+
import { createHash as createHash40 } from "node:crypto";
|
|
160282
160681
|
function fit(text9, max) {
|
|
160283
160682
|
const chars = [...text9];
|
|
160284
160683
|
return chars.length <= max ? text9 : `${chars.slice(0, max - 1).join("").trimEnd()}${ELLIPSIS}`;
|
|
@@ -160428,7 +160827,7 @@ var init_iap_draft = __esm({
|
|
|
160428
160827
|
TIER_DESCRIPTION = "Unlocks one item in the app";
|
|
160429
160828
|
ELLIPSIS = "\u2026";
|
|
160430
160829
|
entityKey = (entityType, entityId) => `${entityType}:${entityId}`;
|
|
160431
|
-
sha = (text9) =>
|
|
160830
|
+
sha = (text9) => createHash40("sha256").update(text9).digest("hex");
|
|
160432
160831
|
ENTITIES = { "&": "&", " ": " ", "<": "<", ">": ">", """: '"', "'": "'" };
|
|
160433
160832
|
MAX_SUFFIX = 24;
|
|
160434
160833
|
ReferenceNames = class {
|
|
@@ -160745,7 +161144,7 @@ var init_store_spec = __esm({
|
|
|
160745
161144
|
|
|
160746
161145
|
// src/iap-config-edit.ts
|
|
160747
161146
|
import { existsSync as existsSync74, readFileSync as readFileSync90 } from "node:fs";
|
|
160748
|
-
import { basename as
|
|
161147
|
+
import { basename as basename20, join as join75 } from "node:path";
|
|
160749
161148
|
import ts8 from "typescript";
|
|
160750
161149
|
function bindPurchasesAppInConfig(source, options) {
|
|
160751
161150
|
const fileName = options.fileName ?? "config.ts";
|
|
@@ -160832,14 +161231,14 @@ function withStoreBundle(dir, options) {
|
|
|
160832
161231
|
function previewIapConfigEdit(dir, options) {
|
|
160833
161232
|
const path2 = configEntry(dir);
|
|
160834
161233
|
if (!path2) return void 0;
|
|
160835
|
-
if (isSymlink2(path2)) return { path: path2, changed: false, applied: [], conflicts: [], instructions: [`${
|
|
160836
|
-
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync90(path2, "utf8"), { ...withStoreBundle(dir, options), fileName:
|
|
161234
|
+
if (isSymlink2(path2)) return { path: path2, changed: false, applied: [], conflicts: [], instructions: [`${basename20(path2)} is a symlink, so it would not be edited: add the purchases app in the file it points to.`] };
|
|
161235
|
+
const { changed, applied, conflicts, instructions } = bindPurchasesAppInConfig(readFileSync90(path2, "utf8"), { ...withStoreBundle(dir, options), fileName: basename20(path2) });
|
|
160837
161236
|
return { path: path2, changed, applied, conflicts, instructions };
|
|
160838
161237
|
}
|
|
160839
161238
|
async function applyIapConfigEdit(dir, options, validate4) {
|
|
160840
161239
|
const path2 = configEntry(dir);
|
|
160841
161240
|
if (!path2) return void 0;
|
|
160842
|
-
const fileName =
|
|
161241
|
+
const fileName = basename20(path2);
|
|
160843
161242
|
const refuse7 = (why) => ({ path: path2, changed: false, applied: [], conflicts: [], instructions: [why] });
|
|
160844
161243
|
if (isSymlink2(path2)) return refuse7(`${fileName} is a symlink, so it was not edited: add the purchases app in the file it points to.`);
|
|
160845
161244
|
const original = readFileSync90(path2, "utf8");
|
|
@@ -161298,6 +161697,281 @@ var init_store_iap_connect = __esm({
|
|
|
161298
161697
|
}
|
|
161299
161698
|
});
|
|
161300
161699
|
|
|
161700
|
+
// src/store-iap-screenshots.ts
|
|
161701
|
+
import { dirname as dirname40, join as join76, relative as relative15 } from "node:path";
|
|
161702
|
+
function purchaseScreensFor(item) {
|
|
161703
|
+
const screen = item.wix && PURCHASE_SCREENS[item.wix.entityType];
|
|
161704
|
+
if (!screen || !item.wix) return [];
|
|
161705
|
+
const list = LIST_SCREENS[item.wix.entityType];
|
|
161706
|
+
return [{ screenId: `${screen}_${item.wix.entityId}` }, { screenId: screen, input: { id: item.wix.entityId } }, ...list ? [{ screenId: list }] : []];
|
|
161707
|
+
}
|
|
161708
|
+
function formatApplePrice(amount, currency, locale) {
|
|
161709
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(Number(amount));
|
|
161710
|
+
}
|
|
161711
|
+
function bindingHost(target, offers) {
|
|
161712
|
+
const appId2 = target.himiApp;
|
|
161713
|
+
const byEntity = new Map(offers.flatMap((offer) => offer.item.wix ? [[offer.item.wix.entityId, offer]] : []));
|
|
161714
|
+
const product = ({ item, displayPrice }) => ({ id: item.productId, type: item.type, displayName: item.localizations[0]?.name ?? item.referenceName, displayPrice });
|
|
161715
|
+
const answers = {
|
|
161716
|
+
"capability.app_info.get": () => ({ appId: appId2, bundleId: target.bundleId, platform: "ios" }),
|
|
161717
|
+
"capability.iap.appBinding": () => ({ status: "bound", binding: { purchasesAppId: RENDER_PURCHASES_APP_ID, himalayaAppId: appId2, bundleId: target.bundleId, siteId: target.wixSiteId } }),
|
|
161718
|
+
"capability.iap.getProducts": (params) => {
|
|
161719
|
+
const asked = new Set(String(params?.productIds ?? "").split(",").map((id) => id.trim()));
|
|
161720
|
+
return { products: offers.filter((offer) => asked.has(offer.item.productId)).map(product) };
|
|
161721
|
+
},
|
|
161722
|
+
"capability.iap.getUnfinishedTransactions": () => ({ status: "ok", transactions: [] })
|
|
161723
|
+
};
|
|
161724
|
+
const member = { generation: 1, kind: "member", memberId: RENDER_MEMBER_ID, siteId: target.wixSiteId, appId: appId2, ready: true };
|
|
161725
|
+
return {
|
|
161726
|
+
dispatch: (action, params) => answers[action]?.(params),
|
|
161727
|
+
wixCall: (method, path2, body) => {
|
|
161728
|
+
if (method === "GET") return MEMBER_OWN_READS.find((read) => read.path.test(path2))?.answer;
|
|
161729
|
+
if (method !== "POST" || !MAPPINGS_PATH.test(path2)) return void 0;
|
|
161730
|
+
const asked = body?.appProductIds;
|
|
161731
|
+
const ids = Array.isArray(asked) ? asked.filter((id) => typeof id === "string" && byEntity.has(id)) : [];
|
|
161732
|
+
return { mappings: ids.map((id) => {
|
|
161733
|
+
const { item } = byEntity.get(id);
|
|
161734
|
+
return { appProductId: id, storeProductId: item.productId, type: item.type === "consumable" ? "CONSUMABLE" : "NON_CONSUMABLE", active: true };
|
|
161735
|
+
}) };
|
|
161736
|
+
},
|
|
161737
|
+
wixApiSession: { identityBound: true, session: { current: () => member, subscribe: () => () => {
|
|
161738
|
+
} } }
|
|
161739
|
+
};
|
|
161740
|
+
}
|
|
161741
|
+
function offersPurchase(fields) {
|
|
161742
|
+
return PURCHASE_FLAGS.some((flag) => fields[`${flag}Disabled`] === false && fields[`${flag}Hidden`] !== true);
|
|
161743
|
+
}
|
|
161744
|
+
function isItemRow(fields, entityId, price) {
|
|
161745
|
+
const values = Object.values(fields).filter((v2) => typeof v2 === "string");
|
|
161746
|
+
return values.some((v2) => v2.toLowerCase() === entityId.toLowerCase()) && values.some((v2) => visibleText2(v2).includes(price));
|
|
161747
|
+
}
|
|
161748
|
+
function rowOffersPurchase(value, entityId, price) {
|
|
161749
|
+
if (Array.isArray(value)) return value.some((row) => rowOffersPurchase(row, entityId, price));
|
|
161750
|
+
if (!value || typeof value !== "object") return false;
|
|
161751
|
+
const fields = value;
|
|
161752
|
+
if (isItemRow(fields, entityId, price)) return offersPurchase(fields);
|
|
161753
|
+
return Object.values(fields).some((child) => rowOffersPurchase(child, entityId, price));
|
|
161754
|
+
}
|
|
161755
|
+
function purchaseEnabled(state, entityId, price) {
|
|
161756
|
+
return Object.values(state).some((service) => {
|
|
161757
|
+
if (!service || typeof service !== "object") return false;
|
|
161758
|
+
return offersPurchase(service) || Object.values(service).some((child) => rowOffersPurchase(child, entityId, price));
|
|
161759
|
+
});
|
|
161760
|
+
}
|
|
161761
|
+
function priceFor2(item, run2) {
|
|
161762
|
+
const amount = run2.applePrice(item) ?? (item.price.rule === "atLeast" ? void 0 : item.price.amount);
|
|
161763
|
+
if (amount === void 0) {
|
|
161764
|
+
return { skipped: run2.appleRead ? "App Store Connect has no price for it yet \u2014 run himi store iap apply first" : "Apple's price for an atLeast item is only known once App Store Connect is read \u2014 pass --profile" };
|
|
161765
|
+
}
|
|
161766
|
+
return formatApplePrice(amount, item.price.currency, item.localizations[0]?.locale ?? "en-US");
|
|
161767
|
+
}
|
|
161768
|
+
function unknownOnlyIds(run2) {
|
|
161769
|
+
const known = new Set(run2.manifest.items.map((item) => item.productId));
|
|
161770
|
+
return [...run2.only ?? []].filter((id) => !known.has(id)).map((productId) => ({ productId, skipped: "not in the manifest" }));
|
|
161771
|
+
}
|
|
161772
|
+
function select(run2) {
|
|
161773
|
+
return run2.manifest.items.flatMap((item, index) => {
|
|
161774
|
+
if (run2.only && !run2.only.has(item.productId)) return [];
|
|
161775
|
+
const screens = purchaseScreensFor(item);
|
|
161776
|
+
const report3 = { productId: item.productId, ...screens[0] ? { screenId: screens[0].screenId } : {} };
|
|
161777
|
+
const selected = (extra) => [{ index, item, screens, report: { ...report3, ...extra } }];
|
|
161778
|
+
if (!screens.length) return selected({ skipped: "no purchase screen: a price tier or an entity type the templates have no detail screen for" });
|
|
161779
|
+
const locked = run2.appleLocked?.(item);
|
|
161780
|
+
if (locked) return selected({ skipped: `is ${locked} \u2014 a live or in-review product's screenshot is never changed` });
|
|
161781
|
+
if (item.reviewScreenshot && !run2.force) return selected({ skipped: `already names ${item.reviewScreenshot} \u2014 pass --force to replace it` });
|
|
161782
|
+
const price = priceFor2(item, run2);
|
|
161783
|
+
return selected(typeof price === "string" ? { price } : price);
|
|
161784
|
+
});
|
|
161785
|
+
}
|
|
161786
|
+
function offersFor(selected, run2) {
|
|
161787
|
+
const others = run2.manifest.items.flatMap((item) => {
|
|
161788
|
+
if (item === selected.item || item.wix?.entityType !== selected.item.wix?.entityType) return [];
|
|
161789
|
+
const price = priceFor2(item, run2);
|
|
161790
|
+
return typeof price === "string" ? [{ item, displayPrice: price }] : [];
|
|
161791
|
+
});
|
|
161792
|
+
return [{ item: selected.item, displayPrice: selected.report.price }, ...others];
|
|
161793
|
+
}
|
|
161794
|
+
function notAPurchase(rendered, entityId, price) {
|
|
161795
|
+
if (rendered.problems.length) return `the screen reported problems while loading: ${rendered.problems.join("; ")}`;
|
|
161796
|
+
if (!visibleText2(rendered.html).includes(price)) return `did not show the Apple price ${price} \u2014 it is not a purchase screen this command knows, or it did not load`;
|
|
161797
|
+
if (!purchaseEnabled(rendered.state, entityId, price)) return "showed the price but no enabled buy or join action for this item";
|
|
161798
|
+
return void 0;
|
|
161799
|
+
}
|
|
161800
|
+
async function renderPurchaseScreen(selected, run2) {
|
|
161801
|
+
const host = bindingHost(run2.manifest.target, offersFor(selected, run2));
|
|
161802
|
+
const price = selected.report.price;
|
|
161803
|
+
const reasons = [];
|
|
161804
|
+
for (const screen of selected.screens) {
|
|
161805
|
+
let rendered;
|
|
161806
|
+
try {
|
|
161807
|
+
rendered = await run2.renderer.render({ contentDir: run2.contentDir, host, entityId: selected.item.wix.entityId, ...screen });
|
|
161808
|
+
} catch (e2) {
|
|
161809
|
+
if (e2 instanceof MissingScreenError) continue;
|
|
161810
|
+
return { skipped: `could not render ${screen.screenId}: ${e2.message}` };
|
|
161811
|
+
}
|
|
161812
|
+
const reason = notAPurchase(rendered, selected.item.wix.entityId, price);
|
|
161813
|
+
if (!reason) return { screenId: screen.screenId, html: rendered.html };
|
|
161814
|
+
reasons.push(`${screen.screenId} ${reason}`);
|
|
161815
|
+
}
|
|
161816
|
+
if (!reasons.length) return { skipped: `the app has none of these screens: ${selected.screens.map((s2) => s2.screenId).join(", ")}` };
|
|
161817
|
+
return { skipped: reasons.join("; ") };
|
|
161818
|
+
}
|
|
161819
|
+
async function shoot(selected, run2, outDir) {
|
|
161820
|
+
const found = await renderPurchaseScreen(selected, run2);
|
|
161821
|
+
if ("skipped" in found) return { ...selected.report, skipped: found.skipped };
|
|
161822
|
+
const report3 = { ...selected.report, screenId: found.screenId };
|
|
161823
|
+
const path2 = join76(outDir, `${selected.item.productId}.png`);
|
|
161824
|
+
try {
|
|
161825
|
+
run2.writeBytes(path2, await run2.renderer.capture(found.html, run2.contentDir));
|
|
161826
|
+
} catch (e2) {
|
|
161827
|
+
return { ...report3, skipped: `could not save the screenshot: ${e2.message}` };
|
|
161828
|
+
}
|
|
161829
|
+
return { ...report3, screenshot: relative15(dirname40(run2.manifestPath), path2) };
|
|
161830
|
+
}
|
|
161831
|
+
function visibleText2(html) {
|
|
161832
|
+
return html.replace(/ | | /gi, "\xA0").replace(/&/g, "&");
|
|
161833
|
+
}
|
|
161834
|
+
function manifestWithScreenshots(text9, shot) {
|
|
161835
|
+
const doc = JSON.parse(text9);
|
|
161836
|
+
for (const [index, path2] of shot) doc.items[index].reviewScreenshot = path2;
|
|
161837
|
+
return `${JSON.stringify(doc, null, 2)}
|
|
161838
|
+
`;
|
|
161839
|
+
}
|
|
161840
|
+
async function takeReviewScreenshots(run2) {
|
|
161841
|
+
const outDir = run2.outDir ?? join76(dirname40(run2.manifestPath), DEFAULT_OUT_DIR);
|
|
161842
|
+
const items = unknownOnlyIds(run2);
|
|
161843
|
+
const shot = /* @__PURE__ */ new Map();
|
|
161844
|
+
try {
|
|
161845
|
+
for (const selected of select(run2)) {
|
|
161846
|
+
const ready = !selected.report.skipped && !run2.dryRun;
|
|
161847
|
+
const report3 = ready ? await shoot(selected, run2, outDir) : selected.report;
|
|
161848
|
+
if (report3.screenshot) shot.set(selected.index, report3.screenshot);
|
|
161849
|
+
items.push(report3);
|
|
161850
|
+
}
|
|
161851
|
+
} finally {
|
|
161852
|
+
if (shot.size) run2.writeText(run2.manifestPath, manifestWithScreenshots(run2.manifestText, shot));
|
|
161853
|
+
}
|
|
161854
|
+
return { complete: items.every((i2) => !i2.skipped), items };
|
|
161855
|
+
}
|
|
161856
|
+
var MissingScreenError, REVIEW_SCREENSHOT_FRAME, DEFAULT_OUT_DIR, PURCHASE_SCREENS, LIST_SCREENS, RENDER_PURCHASES_APP_ID, RENDER_MEMBER_ID, MAPPINGS_PATH, MEMBER_OWN_READS, PURCHASE_FLAGS;
|
|
161857
|
+
var init_store_iap_screenshots = __esm({
|
|
161858
|
+
"src/store-iap-screenshots.ts"() {
|
|
161859
|
+
MissingScreenError = class extends Error {
|
|
161860
|
+
constructor(screenId) {
|
|
161861
|
+
super(`the app has no screen ${screenId}`);
|
|
161862
|
+
this.screenId = screenId;
|
|
161863
|
+
}
|
|
161864
|
+
};
|
|
161865
|
+
REVIEW_SCREENSHOT_FRAME = { width: 430, height: 932, scale: 3 };
|
|
161866
|
+
DEFAULT_OUT_DIR = "review-screenshots";
|
|
161867
|
+
PURCHASE_SCREENS = { storesProduct: "himi_product", onlineProgram: "himi_program", pricingPlan: "himi_plan" };
|
|
161868
|
+
LIST_SCREENS = { pricingPlan: "himi_plans" };
|
|
161869
|
+
RENDER_PURCHASES_APP_ID = "00000000-0000-4000-8000-00000000a99e";
|
|
161870
|
+
RENDER_MEMBER_ID = "00000000-0000-4000-8000-0000000be4e7";
|
|
161871
|
+
MAPPINGS_PATH = /\/v1\/iap\/mappings$/;
|
|
161872
|
+
MEMBER_OWN_READS = [{ path: /^\/pricing-plans\/v2\/member\/orders(\?|$)/, answer: { orders: [] } }];
|
|
161873
|
+
PURCHASE_FLAGS = ["buy", "join"];
|
|
161874
|
+
}
|
|
161875
|
+
});
|
|
161876
|
+
|
|
161877
|
+
// src/store-iap-screenshot-render.ts
|
|
161878
|
+
import { existsSync as existsSync75, mkdtempSync as mkdtempSync4, readFileSync as readFileSync91, rmSync as rmSync18 } from "node:fs";
|
|
161879
|
+
import { tmpdir as tmpdir5 } from "node:os";
|
|
161880
|
+
import { join as join77 } from "node:path";
|
|
161881
|
+
function renderProblems(render, entityId) {
|
|
161882
|
+
const problems = (render.liveErrors ?? []).map((e2) => `${e2.service}: ${e2.message}`);
|
|
161883
|
+
const ofItem = (call) => call.toLowerCase().includes(entityId.toLowerCase());
|
|
161884
|
+
const failed3 = (render.liveFailed ?? []).filter(ofItem);
|
|
161885
|
+
const attempted = (render.liveCalls ?? []).filter(ofItem).length;
|
|
161886
|
+
if (failed3.length > 0 && attempted <= failed3.length) problems.push(`reading the item failed (${failed3[0]}), so the screen could not show it`);
|
|
161887
|
+
return problems;
|
|
161888
|
+
}
|
|
161889
|
+
function workerBundleDir(result, dir) {
|
|
161890
|
+
if (result.compileErrors.length) {
|
|
161891
|
+
const detail = result.compileErrors.map((e2) => `${e2.bundle}: ${e2.errors.map((x2) => x2.text).join("; ")}`).join(" \xB7 ");
|
|
161892
|
+
throw new Error(`the app's screen code does not compile \u2014 fix it first (himi validate): ${detail}`);
|
|
161893
|
+
}
|
|
161894
|
+
return result.built.length > 0 ? dir : void 0;
|
|
161895
|
+
}
|
|
161896
|
+
function createReviewScreenRenderer() {
|
|
161897
|
+
const bundles = /* @__PURE__ */ new Map();
|
|
161898
|
+
let browser;
|
|
161899
|
+
function workerBundles(contentDir2) {
|
|
161900
|
+
let built = bundles.get(contentDir2);
|
|
161901
|
+
if (!built) {
|
|
161902
|
+
built = (async () => {
|
|
161903
|
+
const { buildContentBundles: buildContentBundles2, bundleOutDir: bundleOutDir2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
161904
|
+
return workerBundleDir(await buildContentBundles2(contentDir2, {}), bundleOutDir2(contentDir2));
|
|
161905
|
+
})();
|
|
161906
|
+
bundles.set(contentDir2, built);
|
|
161907
|
+
}
|
|
161908
|
+
return built;
|
|
161909
|
+
}
|
|
161910
|
+
async function launch() {
|
|
161911
|
+
let chromium;
|
|
161912
|
+
try {
|
|
161913
|
+
({ chromium } = await import("playwright"));
|
|
161914
|
+
} catch {
|
|
161915
|
+
throw new Error("taking a screenshot needs Playwright's Chromium: run `npx playwright install chromium`");
|
|
161916
|
+
}
|
|
161917
|
+
return chromium.launch();
|
|
161918
|
+
}
|
|
161919
|
+
return {
|
|
161920
|
+
async render({ contentDir: contentDir2, screenId, input, host, entityId }) {
|
|
161921
|
+
const { buildReleaseFromContent: buildReleaseFromContent2 } = await Promise.resolve().then(() => (init_build3(), build_exports2));
|
|
161922
|
+
const tier5Dir = await workerBundles(contentDir2);
|
|
161923
|
+
const out2 = mkdtempSync4(join77(tmpdir5(), "himi-iap-shot-"));
|
|
161924
|
+
try {
|
|
161925
|
+
const outcome = await buildReleaseFromContent2(contentDir2, out2, {
|
|
161926
|
+
...tier5Dir ? { tier5Dir } : {},
|
|
161927
|
+
collect: { render: { screenId, scheme: "light", png: false, hydrate: true, live: true, dumpState: true, width: REVIEW_SCREENSHOT_FRAME.width, host, ...input ? { input } : {} } }
|
|
161928
|
+
});
|
|
161929
|
+
const render = (outcome.renders ?? [])[0];
|
|
161930
|
+
if (!render) throw new MissingScreenError(screenId);
|
|
161931
|
+
if (!render.renderable || !render.html) throw new Error(render.reason ?? `${screenId} is not an SDUI screen`);
|
|
161932
|
+
return { html: render.html, problems: renderProblems(render, entityId), state: render.serviceState ?? {} };
|
|
161933
|
+
} finally {
|
|
161934
|
+
rmSync18(out2, { recursive: true, force: true });
|
|
161935
|
+
}
|
|
161936
|
+
},
|
|
161937
|
+
async capture(html, contentDir2) {
|
|
161938
|
+
const { pngPageHtml: pngPageHtml2, stabilizePngPage: stabilizePngPage2 } = await Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports));
|
|
161939
|
+
const tokensPath = join77(contentDir2, "tokens.json");
|
|
161940
|
+
const tokens2 = existsSync75(tokensPath) ? JSON.parse(readFileSync91(tokensPath, "utf8")) : null;
|
|
161941
|
+
const { width, height, scale } = REVIEW_SCREENSHOT_FRAME;
|
|
161942
|
+
const page = await (await (browser ??= launch())).newPage({ viewport: { width, height }, deviceScaleFactor: scale, colorScheme: "light" });
|
|
161943
|
+
try {
|
|
161944
|
+
await page.setContent(await pngPageHtml2({ html, tokens: tokens2, hasStickyFooter: true }), { waitUntil: "load" });
|
|
161945
|
+
await stabilizePngPage2(page, "light");
|
|
161946
|
+
await page.evaluate(FILL_PAGE_WITH_SCREEN_BACKGROUND);
|
|
161947
|
+
return new Uint8Array(await page.screenshot({ fullPage: false }));
|
|
161948
|
+
} finally {
|
|
161949
|
+
await page.close().catch(() => {
|
|
161950
|
+
});
|
|
161951
|
+
}
|
|
161952
|
+
},
|
|
161953
|
+
async close() {
|
|
161954
|
+
if (browser) await (await browser.catch(() => void 0))?.close().catch(() => {
|
|
161955
|
+
});
|
|
161956
|
+
}
|
|
161957
|
+
};
|
|
161958
|
+
}
|
|
161959
|
+
var FILL_PAGE_WITH_SCREEN_BACKGROUND;
|
|
161960
|
+
var init_store_iap_screenshot_render = __esm({
|
|
161961
|
+
"src/store-iap-screenshot-render.ts"() {
|
|
161962
|
+
init_store_iap_screenshots();
|
|
161963
|
+
FILL_PAGE_WITH_SCREEN_BACKGROUND = `(() => {
|
|
161964
|
+
const root = [...document.body.children].find((el) => el.tagName !== "STYLE");
|
|
161965
|
+
if (!root) return;
|
|
161966
|
+
const style = getComputedStyle(root);
|
|
161967
|
+
for (const el of [document.documentElement, document.body]) {
|
|
161968
|
+
el.style.backgroundColor = style.backgroundColor;
|
|
161969
|
+
el.style.backgroundImage = style.backgroundImage;
|
|
161970
|
+
}
|
|
161971
|
+
})()`;
|
|
161972
|
+
}
|
|
161973
|
+
});
|
|
161974
|
+
|
|
161301
161975
|
// src/serve-preview.ts
|
|
161302
161976
|
function parsePreviewTag(value) {
|
|
161303
161977
|
if (value === void 0 || value === "") return void 0;
|
|
@@ -161339,9 +162013,9 @@ __export(store_iap_exports, {
|
|
|
161339
162013
|
runStoreIap: () => runStoreIap
|
|
161340
162014
|
});
|
|
161341
162015
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
161342
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as
|
|
162016
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync34, readFileSync as readFileSync92, realpathSync as realpathSync13, renameSync as renameSync12, rmSync as rmSync19, writeFileSync as writeFileSync30 } from "node:fs";
|
|
161343
162017
|
import { homedir as homedir11, hostname } from "node:os";
|
|
161344
|
-
import { join as
|
|
162018
|
+
import { dirname as dirname41, join as join78, resolve as resolve57 } from "node:path";
|
|
161345
162019
|
function scrubDeep(value, scrub) {
|
|
161346
162020
|
if (typeof value === "string") return scrub(value);
|
|
161347
162021
|
if (Array.isArray(value)) return value.map((v2) => scrubDeep(v2, scrub));
|
|
@@ -161349,7 +162023,7 @@ function scrubDeep(value, scrub) {
|
|
|
161349
162023
|
return value;
|
|
161350
162024
|
}
|
|
161351
162025
|
function failFrom(error, out2) {
|
|
161352
|
-
if (error instanceof IapManifestError) return out2.fail(`${error.label} is not a valid IAP manifest`, { problems: error.problems });
|
|
162026
|
+
if (error instanceof IapManifestError) return out2.fail(`${error.label} is not a valid IAP manifest`, { code: "manifest_invalid", problems: error.problems });
|
|
161353
162027
|
if (error instanceof IapProvisionError) return out2.fail(error.message, { code: error.reason, reason: error.reason }, error.reason === "drift" ? 1 : 2);
|
|
161354
162028
|
return out2.fail(error instanceof Error ? error.message : String(error));
|
|
161355
162029
|
}
|
|
@@ -161372,6 +162046,9 @@ function readInput(deps, path2, what) {
|
|
|
161372
162046
|
function readManifest2(deps, path2) {
|
|
161373
162047
|
return parseIapManifest(readInput(deps, path2, "manifest"), path2);
|
|
161374
162048
|
}
|
|
162049
|
+
function manifestDirOf(manifestPath) {
|
|
162050
|
+
return dirname41(resolve57(manifestPath));
|
|
162051
|
+
}
|
|
161375
162052
|
function readPlan(deps, path2) {
|
|
161376
162053
|
const text9 = readInput(deps, path2, "plan");
|
|
161377
162054
|
try {
|
|
@@ -161397,7 +162074,7 @@ function openSession(deps, out2, target, profile) {
|
|
|
161397
162074
|
const identity = { profile: creds.profile, team: creds.team, fingerprint: creds.fingerprint };
|
|
161398
162075
|
const api2 = deps.createApi(creds.key);
|
|
161399
162076
|
const journal2 = deps.openJournal(target.appleAppId);
|
|
161400
|
-
return { identity, api: api2, journal: journal2, planContext: { api: api2, identity, now: deps.now } };
|
|
162077
|
+
return { identity, api: api2, journal: journal2, planContext: { api: api2, identity, now: deps.now, readBytes: deps.readBytes } };
|
|
161401
162078
|
}
|
|
161402
162079
|
function printHeader(out2, identity, target) {
|
|
161403
162080
|
out2.line(` ${pad("account")}profile "${identity.profile}" \xB7 team ${identity.team} \xB7 key ${identity.fingerprint}`);
|
|
@@ -161466,6 +162143,7 @@ function printItemResult(out2, item) {
|
|
|
161466
162143
|
out2.line(` price drift: Wix ${wix} \xB7 Apple ${apple} \xB7 target ${wouldBe} ${currency} in ${baseTerritory}`);
|
|
161467
162144
|
}
|
|
161468
162145
|
for (const step of provisioning.steps.filter((s2) => s2.detail)) out2.line(` ${step.kind}${step.locale ? ` ${step.locale}` : ""} ${step.state}: ${step.detail}`);
|
|
162146
|
+
if (provisioning.reviewScreenshot?.observed) out2.line(` review screenshot: ${provisioning.reviewScreenshot.observed.fileName} ${provisioning.reviewScreenshot.observed.state}`);
|
|
161469
162147
|
for (const conflict of provisioning.conflicts) out2.line(` conflict: ${conflict}`);
|
|
161470
162148
|
for (const unmet of provisioning.unmet) out2.line(` unmet: ${unmet}`);
|
|
161471
162149
|
for (const remaining of provisioning.remainingRequirements) out2.line(` remaining: ${remaining}`);
|
|
@@ -161495,7 +162173,7 @@ async function planCommand(flags, deps, out2) {
|
|
|
161495
162173
|
const planPath = requireFlag(flags, "out", "plan");
|
|
161496
162174
|
const manifest = readManifest2(deps, manifestPath);
|
|
161497
162175
|
const session = openSession(deps, out2, manifest.target, profile);
|
|
161498
|
-
const plan = await planIap(manifest, session.planContext);
|
|
162176
|
+
const plan = await planIap(manifest, { ...session.planContext, manifestDir: manifestDirOf(manifestPath) });
|
|
161499
162177
|
writePlan(deps, out2, planPath, plan);
|
|
161500
162178
|
const summary2 = plan.items.map((i2) => ({ productId: i2.productId, decision: i2.decision, ops: i2.ops.length, conflicts: i2.conflicts }));
|
|
161501
162179
|
if (out2.json) out2.print({ ok: true, plan: planPath, items: summary2 });
|
|
@@ -161511,7 +162189,7 @@ function createLimit(flags) {
|
|
|
161511
162189
|
async function applyWithLock(deps, plan, session, limit) {
|
|
161512
162190
|
const release2 = deps.acquireLock(plan.target.appleAppId);
|
|
161513
162191
|
try {
|
|
161514
|
-
const context = {
|
|
162192
|
+
const context = { ...session.planContext, sleep: deps.sleep, journal: session.journal };
|
|
161515
162193
|
return await applyIap(plan, limit === void 0 ? context : { ...context, createLimit: limit });
|
|
161516
162194
|
} finally {
|
|
161517
162195
|
release2();
|
|
@@ -161557,7 +162235,7 @@ async function statusCommand(flags, deps, out2) {
|
|
|
161557
162235
|
return out2.fail("could not read the current Wix catalog \u2014 check owner authentication and site access; no manifest fallback was used", { ok: false, code: "wix_catalog_unavailable" });
|
|
161558
162236
|
}
|
|
161559
162237
|
}
|
|
161560
|
-
const result = await statusIap(manifest, session.planContext, catalog3?.items);
|
|
162238
|
+
const result = await statusIap(manifest, { ...session.planContext, manifestDir: manifestDirOf(manifestPath) }, catalog3?.items);
|
|
161561
162239
|
if (resultPath) writeJson(deps, out2, resultPath, result);
|
|
161562
162240
|
const code = result.complete ? void 0 : result.items.some((i2) => i2.provisioning.priceCheckIssue) ? "price_check_unavailable" : result.items.some((i2) => i2.provisioning.priceDrift) ? "price_drift" : "status_incomplete";
|
|
161563
162241
|
if (out2.json) out2.print({ ok: result.complete, ...code ? { code } : {}, result });
|
|
@@ -161797,6 +162475,71 @@ async function connectWith(flags, deps, out2) {
|
|
|
161797
162475
|
}
|
|
161798
162476
|
return code ? 1 : 0;
|
|
161799
162477
|
}
|
|
162478
|
+
async function appleFacts(flags, deps, out2, manifest) {
|
|
162479
|
+
const profile = textFlag(flags, "profile");
|
|
162480
|
+
if (!profile) return /* @__PURE__ */ new Map();
|
|
162481
|
+
const session = openSession(deps, out2, manifest.target, profile);
|
|
162482
|
+
const unscreenshotted = { ...manifest, items: manifest.items.map(({ reviewScreenshot: _shot, ...item }) => item) };
|
|
162483
|
+
const plans = await planItems(session.planContext, unscreenshotted);
|
|
162484
|
+
return new Map(plans.flatMap((plan, i2) => {
|
|
162485
|
+
const observed = plan.observed;
|
|
162486
|
+
if (!observed) return [];
|
|
162487
|
+
const base = observed.price?.baseTerritory === manifest.items[i2].price.baseTerritory && observed.price.customerPrices.length === 1;
|
|
162488
|
+
return [[plan.productId, { ...base ? { price: observed.price.customerPrices[0] } : {}, ...isLocked(observed) ? { locked: observed.state } : {} }]];
|
|
162489
|
+
}));
|
|
162490
|
+
}
|
|
162491
|
+
function printScreenshots(out2, report3, manifestPath, dryRun) {
|
|
162492
|
+
for (const item of report3.items) {
|
|
162493
|
+
if (item.skipped) out2.line(` \u2717 ${item.productId} ${item.skipped}`);
|
|
162494
|
+
else if (dryRun) out2.line(` \xB7 ${item.productId} would render ${item.screenId} at ${item.price}`);
|
|
162495
|
+
else out2.line(` \u2713 ${item.productId} ${item.screenshot} (${item.screenId}, ${item.price})`);
|
|
162496
|
+
}
|
|
162497
|
+
out2.line();
|
|
162498
|
+
if (dryRun) out2.line(" dry run \u2014 nothing was rendered or written.");
|
|
162499
|
+
else if (report3.items.some((i2) => i2.screenshot)) out2.line(` manifest updated: ${manifestPath} \u2014 next: himi store iap plan --manifest ${manifestPath} \u2026 uploads them.`);
|
|
162500
|
+
}
|
|
162501
|
+
async function screenshotsCommand(flags, deps, out2) {
|
|
162502
|
+
const manifestPath = requireFlag(flags, "manifest", "screenshots");
|
|
162503
|
+
const contentDir2 = requireFlag(flags, "content", "screenshots");
|
|
162504
|
+
const manifestText = readInput(deps, manifestPath, "manifest");
|
|
162505
|
+
const manifest = parseIapManifest(manifestText, manifestPath);
|
|
162506
|
+
const facts = await appleFacts(flags, deps, out2, manifest);
|
|
162507
|
+
const renderer = (deps.reviewScreenRenderer ?? createReviewScreenRenderer)();
|
|
162508
|
+
const only = textFlag(flags, "only");
|
|
162509
|
+
const outDir = textFlag(flags, "out-dir");
|
|
162510
|
+
const dryRun = flags["dry-run"] === true;
|
|
162511
|
+
let report3;
|
|
162512
|
+
try {
|
|
162513
|
+
report3 = await takeReviewScreenshots({
|
|
162514
|
+
manifest,
|
|
162515
|
+
manifestPath,
|
|
162516
|
+
manifestText,
|
|
162517
|
+
contentDir: contentDir2,
|
|
162518
|
+
renderer,
|
|
162519
|
+
applePrice: (item) => facts.get(item.productId)?.price,
|
|
162520
|
+
appleLocked: (item) => facts.get(item.productId)?.locked,
|
|
162521
|
+
appleRead: textFlag(flags, "profile") !== void 0,
|
|
162522
|
+
writeBytes: deps.writeBytes ?? writeBinaryFile,
|
|
162523
|
+
writeText: (path2, text9) => deps.writeFileAtomic(path2, text9),
|
|
162524
|
+
...only ? { only: new Set(only.split(",").map((id) => id.trim()).filter(Boolean)) } : {},
|
|
162525
|
+
...outDir ? { outDir: resolve57(outDir) } : {},
|
|
162526
|
+
force: flags.force === true,
|
|
162527
|
+
dryRun
|
|
162528
|
+
});
|
|
162529
|
+
} finally {
|
|
162530
|
+
await renderer.close?.();
|
|
162531
|
+
}
|
|
162532
|
+
const code = report3.complete ? void 0 : "screenshots_incomplete";
|
|
162533
|
+
if (out2.json) out2.print({ ok: report3.complete, ...code ? { code } : {}, manifest: manifestPath, items: report3.items });
|
|
162534
|
+
else printScreenshots(out2, report3, manifestPath, dryRun);
|
|
162535
|
+
return report3.complete ? 0 : 1;
|
|
162536
|
+
}
|
|
162537
|
+
function writeBinaryFile(path2, bytes2) {
|
|
162538
|
+
mkdirSync34(dirname41(path2), { recursive: true });
|
|
162539
|
+
const partial = `${path2}.${process.pid}.partial`;
|
|
162540
|
+
writeFileSync30(partial, bytes2);
|
|
162541
|
+
renameSync12(partial, path2);
|
|
162542
|
+
}
|
|
161800
162543
|
async function runStoreIap(pos, flags, io2, deps) {
|
|
161801
162544
|
const out2 = new CommandOutput(io2, flags.json === true);
|
|
161802
162545
|
const sub = pos[2];
|
|
@@ -161817,14 +162560,14 @@ function fileJournal(path2) {
|
|
|
161817
162560
|
}
|
|
161818
162561
|
function readLockSummary(path2) {
|
|
161819
162562
|
try {
|
|
161820
|
-
const { pid, host, at: at2 } = JSON.parse(
|
|
162563
|
+
const { pid, host, at: at2 } = JSON.parse(readFileSync92(path2, "utf8"));
|
|
161821
162564
|
return `pid ${pid} on ${host} since ${at2}`;
|
|
161822
162565
|
} catch {
|
|
161823
162566
|
return "unreadable lock";
|
|
161824
162567
|
}
|
|
161825
162568
|
}
|
|
161826
162569
|
function acquireApplyLock(dir, appleAppId) {
|
|
161827
|
-
const path2 =
|
|
162570
|
+
const path2 = join78(dir, "apply.lock");
|
|
161828
162571
|
const stamp = JSON.stringify({ pid: process.pid, host: hostname(), at: (/* @__PURE__ */ new Date()).toISOString(), token: randomUUID8() });
|
|
161829
162572
|
try {
|
|
161830
162573
|
writeFileSync30(path2, stamp, { flag: "wx", mode: 384 });
|
|
@@ -161837,15 +162580,15 @@ function acquireApplyLock(dir, appleAppId) {
|
|
|
161837
162580
|
return () => {
|
|
161838
162581
|
let current = "";
|
|
161839
162582
|
try {
|
|
161840
|
-
current =
|
|
162583
|
+
current = readFileSync92(path2, "utf8");
|
|
161841
162584
|
} catch {
|
|
161842
162585
|
return;
|
|
161843
162586
|
}
|
|
161844
|
-
if (current === stamp)
|
|
162587
|
+
if (current === stamp) rmSync19(path2, { force: true });
|
|
161845
162588
|
};
|
|
161846
162589
|
}
|
|
161847
162590
|
function stateDir(appleAppId) {
|
|
161848
|
-
const dir =
|
|
162591
|
+
const dir = join78(homedir11(), ".himalaya", "store-iap", appleAppId);
|
|
161849
162592
|
mkdirSync34(dir, { recursive: true, mode: 448 });
|
|
161850
162593
|
return dir;
|
|
161851
162594
|
}
|
|
@@ -161861,11 +162604,12 @@ async function confirmOnTerminal(question) {
|
|
|
161861
162604
|
}
|
|
161862
162605
|
function defaultStoreIapDeps() {
|
|
161863
162606
|
return {
|
|
161864
|
-
readFile: (path2) =>
|
|
162607
|
+
readFile: (path2) => readFileSync92(path2, "utf8"),
|
|
162608
|
+
readBytes: (path2) => readFileSync92(path2),
|
|
161865
162609
|
writeFileAtomic,
|
|
161866
162610
|
resolveCredentials: ({ profileFlag, target }) => resolveIapCredentials({ profileFlag, target }),
|
|
161867
162611
|
createApi: (key2) => createIapApi(createAscClient({ key: key2 })),
|
|
161868
|
-
openJournal: (appleAppId) => fileJournal(
|
|
162612
|
+
openJournal: (appleAppId) => fileJournal(join78(stateDir(appleAppId), "journal.jsonl")),
|
|
161869
162613
|
acquireLock: (appleAppId) => acquireApplyLock(stateDir(appleAppId), appleAppId),
|
|
161870
162614
|
canPrompt: () => process.stdin.isTTY === true,
|
|
161871
162615
|
wixTransport: (siteId) => ownerTransport(siteId),
|
|
@@ -161876,7 +162620,7 @@ function defaultStoreIapDeps() {
|
|
|
161876
162620
|
profileTeam: (profile) => resolveStoreCredentials({ app: profile, cfg: {}, profileFlag: profile, env: {} }).team,
|
|
161877
162621
|
confirm: confirmOnTerminal,
|
|
161878
162622
|
now: () => /* @__PURE__ */ new Date(),
|
|
161879
|
-
sleep: (ms2) => new Promise((
|
|
162623
|
+
sleep: (ms2) => new Promise((resolve65) => setTimeout(resolve65, ms2))
|
|
161880
162624
|
};
|
|
161881
162625
|
}
|
|
161882
162626
|
var STORE_IAP_USAGE, SUMMARY_THRESHOLD, SUMMARY_DETAIL_LIMIT, UsageError, CommandOutput, pad, DECISION_ORDER, OUTCOME_ORDER, COMPLETE, DRAFT_MODES, TERRITORY_CODE, LOCALE_CODE, GRID_UNAVAILABLE_NOTE, KeyError, CredentialsError, writesPlanned, COMMANDS;
|
|
@@ -161898,10 +162642,12 @@ var init_store_iap = __esm({
|
|
|
161898
162642
|
init_iap_config_edit();
|
|
161899
162643
|
init_store_iap_catalog();
|
|
161900
162644
|
init_store_iap_connect();
|
|
162645
|
+
init_store_iap_screenshots();
|
|
162646
|
+
init_store_iap_screenshot_render();
|
|
161901
162647
|
init_store_iap_purchases();
|
|
161902
162648
|
init_serve_preview();
|
|
161903
162649
|
init_wix_owner();
|
|
161904
|
-
STORE_IAP_USAGE = "himi store iap draft|plan|apply|status|connect \u2014 draft --site <msid> --profile <name> --apple-app <id> --bundle <id> --base-territory <ISO3> --out <manifest.json> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <manifest.json>] [--report <file>] \xB7 plan --manifest <file> --profile <name> --out <plan.json> \xB7 apply --plan <plan.json> --profile <name> --out <result.json> [--yes] [--limit <n>] \xB7 status --manifest <file> --profile <name> [--out <file>] [--refresh-wix] \xB7 connect --manifest <file> --profile <name> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <report.json>]";
|
|
162650
|
+
STORE_IAP_USAGE = "himi store iap draft|plan|apply|status|connect|screenshots \u2014 draft --site <msid> --profile <name> --apple-app <id> --bundle <id> --base-territory <ISO3> --out <manifest.json> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <manifest.json>] [--report <file>] \xB7 plan --manifest <file> --profile <name> --out <plan.json> \xB7 apply --plan <plan.json> --profile <name> --out <result.json> [--yes] [--limit <n>] \xB7 status --manifest <file> --profile <name> [--out <file>] [--refresh-wix] \xB7 connect --manifest <file> --profile <name> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <report.json>] \xB7 screenshots --manifest <file> --content <app dir> [--profile <name>] [--out-dir <dir>] [--only <productId,\u2026>] [--force] [--dry-run]";
|
|
161905
162651
|
SUMMARY_THRESHOLD = 50;
|
|
161906
162652
|
SUMMARY_DETAIL_LIMIT = 20;
|
|
161907
162653
|
UsageError = class extends Error {
|
|
@@ -161962,7 +162708,8 @@ var init_store_iap = __esm({
|
|
|
161962
162708
|
plan: planCommand,
|
|
161963
162709
|
apply: applyCommand,
|
|
161964
162710
|
status: statusCommand,
|
|
161965
|
-
connect: connectCommand
|
|
162711
|
+
connect: connectCommand,
|
|
162712
|
+
screenshots: screenshotsCommand
|
|
161966
162713
|
};
|
|
161967
162714
|
}
|
|
161968
162715
|
});
|
|
@@ -162337,15 +163084,15 @@ __export(preflight_app_exports, {
|
|
|
162337
163084
|
analyzeSubmissionRecord: () => analyzeSubmissionRecord,
|
|
162338
163085
|
appIconState: () => appIconState,
|
|
162339
163086
|
isValidAppStoreSize: () => isValidAppStoreSize,
|
|
162340
|
-
jpegSize: () =>
|
|
163087
|
+
jpegSize: () => jpegSize2,
|
|
162341
163088
|
playListingAssets: () => playListingAssets,
|
|
162342
|
-
pngSize: () =>
|
|
163089
|
+
pngSize: () => pngSize2,
|
|
162343
163090
|
preflightApp: () => preflightApp,
|
|
162344
163091
|
profileAccount: () => profileAccount
|
|
162345
163092
|
});
|
|
162346
|
-
import { readFileSync as
|
|
162347
|
-
import { createHash as
|
|
162348
|
-
import { join as
|
|
163093
|
+
import { readFileSync as readFileSync93, existsSync as existsSync76, readdirSync as readdirSync34, statSync as statSync21 } from "node:fs";
|
|
163094
|
+
import { createHash as createHash41 } from "node:crypto";
|
|
163095
|
+
import { join as join79 } from "node:path";
|
|
162349
163096
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
162350
163097
|
const f2 = [];
|
|
162351
163098
|
const has = (re2, s2) => re2.test(s2);
|
|
@@ -162409,13 +163156,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
162409
163156
|
}
|
|
162410
163157
|
}
|
|
162411
163158
|
async function preflightApp(app, opts = {}) {
|
|
162412
|
-
const projectYml =
|
|
162413
|
-
const storeConfig =
|
|
163159
|
+
const projectYml = existsSync76(iosProjectYml(app)) ? readFileSync93(iosProjectYml(app), "utf8") : "";
|
|
163160
|
+
const storeConfig = existsSync76(storeConfigPath(app)) ? readFileSync93(storeConfigPath(app), "utf8") : "";
|
|
162414
163161
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
162415
163162
|
const findings = analyze(
|
|
162416
163163
|
projectYml,
|
|
162417
163164
|
storeConfig,
|
|
162418
|
-
await appIconState(
|
|
163165
|
+
await appIconState(join79(appDir(app), "ios")),
|
|
162419
163166
|
profileAccount(app, storeConfig, opts)
|
|
162420
163167
|
);
|
|
162421
163168
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -162444,17 +163191,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
162444
163191
|
return f2;
|
|
162445
163192
|
}
|
|
162446
163193
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
162447
|
-
const root =
|
|
163194
|
+
const root = join79(storeDir(app), "metadata");
|
|
162448
163195
|
const out2 = /* @__PURE__ */ new Set();
|
|
162449
|
-
if (
|
|
163196
|
+
if (existsSync76(root)) {
|
|
162450
163197
|
for (const n2 of readdirSync34(root)) if (n2.endsWith(".txt")) out2.add(n2);
|
|
162451
163198
|
}
|
|
162452
|
-
if (
|
|
163199
|
+
if (existsSync76(join79(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
|
|
162453
163200
|
return out2;
|
|
162454
163201
|
}
|
|
162455
163202
|
function reviewInfoFiles(app) {
|
|
162456
|
-
const dir =
|
|
162457
|
-
if (!
|
|
163203
|
+
const dir = join79(storeDir(app), "review_information");
|
|
163204
|
+
if (!existsSync76(dir)) return /* @__PURE__ */ new Set();
|
|
162458
163205
|
return new Set(readdirSync34(dir).filter((n2) => n2.endsWith(".txt")));
|
|
162459
163206
|
}
|
|
162460
163207
|
function isValidAppStoreSize(w2, h2) {
|
|
@@ -162463,7 +163210,7 @@ function isValidAppStoreSize(w2, h2) {
|
|
|
162463
163210
|
function isRequired69(w2, h2) {
|
|
162464
163211
|
return w2 === 1320 && h2 === 2868 || w2 === 1290 && h2 === 2796 || w2 === 2868 && h2 === 1320 || w2 === 2796 && h2 === 1290;
|
|
162465
163212
|
}
|
|
162466
|
-
function
|
|
163213
|
+
function pngSize2(buf) {
|
|
162467
163214
|
if (buf.length < 24 || buf.toString("ascii", 12, 16) !== "IHDR") return null;
|
|
162468
163215
|
return { w: buf.readUInt32BE(16), h: buf.readUInt32BE(20) };
|
|
162469
163216
|
}
|
|
@@ -162488,7 +163235,7 @@ function jpegStructure(bytes2) {
|
|
|
162488
163235
|
}
|
|
162489
163236
|
return null;
|
|
162490
163237
|
}
|
|
162491
|
-
function
|
|
163238
|
+
function jpegSize2(buf) {
|
|
162492
163239
|
if (buf.length < 4 || buf[0] !== 255 || buf[1] !== 216) return null;
|
|
162493
163240
|
let at2 = 2;
|
|
162494
163241
|
while (at2 + 9 < buf.length) {
|
|
@@ -162520,7 +163267,7 @@ function analyzePlayListing(assets) {
|
|
|
162520
163267
|
} else {
|
|
162521
163268
|
const { name, bytes: bytes2 } = assets.featureGraphic;
|
|
162522
163269
|
const isPng = bytes2.length > 8 && bytes2.toString("ascii", 1, 4) === "PNG";
|
|
162523
|
-
const size = isPng ?
|
|
163270
|
+
const size = isPng ? pngSize2(bytes2) : jpegSize2(bytes2);
|
|
162524
163271
|
if (!size) {
|
|
162525
163272
|
f2.push({
|
|
162526
163273
|
level: "error",
|
|
@@ -162564,12 +163311,12 @@ function analyzePlayListing(assets) {
|
|
|
162564
163311
|
return f2;
|
|
162565
163312
|
}
|
|
162566
163313
|
function playListingAssets(app, locale = "en-US") {
|
|
162567
|
-
const dir =
|
|
163314
|
+
const dir = join79(storeDir(app), "play", locale, "images");
|
|
162568
163315
|
const read = (names) => {
|
|
162569
163316
|
for (const name of names) {
|
|
162570
|
-
const p2 =
|
|
163317
|
+
const p2 = join79(dir, name);
|
|
162571
163318
|
try {
|
|
162572
|
-
if (statSync21(p2).isFile()) return { name, bytes:
|
|
163319
|
+
if (statSync21(p2).isFile()) return { name, bytes: readFileSync93(p2) };
|
|
162573
163320
|
} catch {
|
|
162574
163321
|
}
|
|
162575
163322
|
}
|
|
@@ -162600,26 +163347,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
162600
163347
|
return f2;
|
|
162601
163348
|
}
|
|
162602
163349
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
162603
|
-
const dir =
|
|
162604
|
-
if (!
|
|
163350
|
+
const dir = join79(storeDir(app), "metadata", locale);
|
|
163351
|
+
if (!existsSync76(dir)) return /* @__PURE__ */ new Set();
|
|
162605
163352
|
return new Set(readdirSync34(dir).filter((n2) => n2.endsWith(".txt")));
|
|
162606
163353
|
}
|
|
162607
163354
|
function listScreenshots(app, locale = "en-US") {
|
|
162608
163355
|
const out2 = [];
|
|
162609
|
-
const flat =
|
|
162610
|
-
if (
|
|
163356
|
+
const flat = join79(storeDir(app), "screenshots", locale);
|
|
163357
|
+
if (existsSync76(flat)) {
|
|
162611
163358
|
for (const png of readdirSync34(flat).filter((n2) => n2.endsWith(".png"))) {
|
|
162612
|
-
const sz =
|
|
163359
|
+
const sz = pngSize2(readFileSync93(join79(flat, png)));
|
|
162613
163360
|
if (sz) out2.push({ name: png, w: sz.w, h: sz.h });
|
|
162614
163361
|
}
|
|
162615
163362
|
}
|
|
162616
|
-
const legacy =
|
|
162617
|
-
if (
|
|
163363
|
+
const legacy = join79(storeDir(app), "metadata", locale, "screenshots");
|
|
163364
|
+
if (existsSync76(legacy)) {
|
|
162618
163365
|
for (const deviceDir of readdirSync34(legacy)) {
|
|
162619
|
-
const d2 =
|
|
163366
|
+
const d2 = join79(legacy, deviceDir);
|
|
162620
163367
|
if (!statSync21(d2).isDirectory()) continue;
|
|
162621
163368
|
for (const png of readdirSync34(d2).filter((n2) => n2.endsWith(".png"))) {
|
|
162622
|
-
const sz =
|
|
163369
|
+
const sz = pngSize2(readFileSync93(join79(d2, png)));
|
|
162623
163370
|
if (sz) out2.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
162624
163371
|
}
|
|
162625
163372
|
}
|
|
@@ -162627,13 +163374,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
162627
163374
|
return out2;
|
|
162628
163375
|
}
|
|
162629
163376
|
function placeholderHashes2() {
|
|
162630
|
-
const templateIos =
|
|
162631
|
-
if (!
|
|
163377
|
+
const templateIos = join79(appDir("_template"), "ios");
|
|
163378
|
+
if (!existsSync76(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
162632
163379
|
for (const target of readdirSync34(templateIos)) {
|
|
162633
|
-
const p2 =
|
|
163380
|
+
const p2 = join79(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
162634
163381
|
try {
|
|
162635
163382
|
if (!statSync21(p2).isFile()) continue;
|
|
162636
|
-
return [LEGACY_PLACEHOLDER_SHA2562,
|
|
163383
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash41("sha256").update(readFileSync93(p2)).digest("hex")];
|
|
162637
163384
|
} catch {
|
|
162638
163385
|
}
|
|
162639
163386
|
}
|
|
@@ -162664,13 +163411,13 @@ async function pixelIssues(bytes2) {
|
|
|
162664
163411
|
}
|
|
162665
163412
|
}
|
|
162666
163413
|
async function appIconState(iosDir) {
|
|
162667
|
-
if (!
|
|
163414
|
+
if (!existsSync76(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
162668
163415
|
for (const target of readdirSync34(iosDir)) {
|
|
162669
|
-
const p2 =
|
|
163416
|
+
const p2 = join79(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
162670
163417
|
try {
|
|
162671
163418
|
if (!statSync21(p2).isFile()) continue;
|
|
162672
|
-
const bytes2 =
|
|
162673
|
-
const hash2 =
|
|
163419
|
+
const bytes2 = readFileSync93(p2);
|
|
163420
|
+
const hash2 = createHash41("sha256").update(bytes2).digest("hex");
|
|
162674
163421
|
const pixels = await pixelIssues(bytes2);
|
|
162675
163422
|
return {
|
|
162676
163423
|
exists: true,
|
|
@@ -162736,7 +163483,7 @@ __export(asc_status_exports, {
|
|
|
162736
163483
|
ascStatus: () => ascStatus,
|
|
162737
163484
|
buildVerdict: () => buildVerdict
|
|
162738
163485
|
});
|
|
162739
|
-
import { readFileSync as
|
|
163486
|
+
import { readFileSync as readFileSync94 } from "node:fs";
|
|
162740
163487
|
function buildVerdict(builds) {
|
|
162741
163488
|
if (!builds.length) {
|
|
162742
163489
|
return "NO builds registered \u2014 if you uploaded recently and it's been >15 min, the binary was REJECTED IN PROCESSING (reason is email-only; run validate-binary.ts / scan-purpose-strings.ts to reproduce it).";
|
|
@@ -162750,7 +163497,7 @@ function buildVerdict(builds) {
|
|
|
162750
163497
|
function client(creds) {
|
|
162751
163498
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
162752
163499
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
162753
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
163500
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync94(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
162754
163501
|
return async (path2) => {
|
|
162755
163502
|
const r2 = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
162756
163503
|
return { status: r2.status, json: await r2.json().catch(() => ({})) };
|
|
@@ -162904,7 +163651,7 @@ var init_connector_token = __esm({
|
|
|
162904
163651
|
// ../../core/functions-secrets/src/vault.ts
|
|
162905
163652
|
import { createCipheriv, createDecipheriv as createDecipheriv2, randomBytes as randomBytes6 } from "node:crypto";
|
|
162906
163653
|
import { mkdir, readFile as readFile2, rename, writeFile as writeFile2 } from "node:fs/promises";
|
|
162907
|
-
import { dirname as
|
|
163654
|
+
import { dirname as dirname42 } from "node:path";
|
|
162908
163655
|
function createJsonSecretStore(filePath) {
|
|
162909
163656
|
const read = async () => {
|
|
162910
163657
|
try {
|
|
@@ -162917,7 +163664,7 @@ function createJsonSecretStore(filePath) {
|
|
|
162917
163664
|
}
|
|
162918
163665
|
};
|
|
162919
163666
|
const write2 = async (records) => {
|
|
162920
|
-
await mkdir(
|
|
163667
|
+
await mkdir(dirname42(filePath), { recursive: true });
|
|
162921
163668
|
const temporary = `${filePath}.${process.pid}.tmp`;
|
|
162922
163669
|
await writeFile2(temporary, `${JSON.stringify(records, null, 2)}
|
|
162923
163670
|
`, { mode: 384 });
|
|
@@ -163015,7 +163762,7 @@ __export(secrets_exports, {
|
|
|
163015
163762
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
163016
163763
|
runSecretsCommand: () => runSecretsCommand
|
|
163017
163764
|
});
|
|
163018
|
-
import { readFileSync as
|
|
163765
|
+
import { readFileSync as readFileSync95 } from "node:fs";
|
|
163019
163766
|
function environment(value) {
|
|
163020
163767
|
if (value === "preview" || value === "production") return value;
|
|
163021
163768
|
throw new Error("--environment must be preview or production");
|
|
@@ -163046,7 +163793,7 @@ async function runSecretsCommand(operation, flags, io2, options = {}) {
|
|
|
163046
163793
|
io2.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
163047
163794
|
return 0;
|
|
163048
163795
|
}
|
|
163049
|
-
const value = options.readValue ? options.readValue() :
|
|
163796
|
+
const value = options.readValue ? options.readValue() : readFileSync95(0, "utf8").replace(/\r?\n$/, "");
|
|
163050
163797
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
163051
163798
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
163052
163799
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -163075,7 +163822,7 @@ async function runRemoteSecretsCommand(operation, flags, io2, options) {
|
|
|
163075
163822
|
}
|
|
163076
163823
|
let body;
|
|
163077
163824
|
if (operation !== "list") {
|
|
163078
|
-
const value = options.readValue ? options.readValue() :
|
|
163825
|
+
const value = options.readValue ? options.readValue() : readFileSync95(0, "utf8").replace(/\r?\n$/, "");
|
|
163079
163826
|
body = JSON.stringify({ value });
|
|
163080
163827
|
}
|
|
163081
163828
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -163269,7 +164016,7 @@ var init_site_member = __esm({
|
|
|
163269
164016
|
});
|
|
163270
164017
|
|
|
163271
164018
|
// src/notify-ping-all.ts
|
|
163272
|
-
import { createHash as
|
|
164019
|
+
import { createHash as createHash42 } from "node:crypto";
|
|
163273
164020
|
async function listApprovedMembers(input) {
|
|
163274
164021
|
const first = await scanMembers(input);
|
|
163275
164022
|
const second = await scanMembers(input);
|
|
@@ -163323,7 +164070,7 @@ async function scanMembers(input) {
|
|
|
163323
164070
|
}
|
|
163324
164071
|
}
|
|
163325
164072
|
function campaignRequestId(campaignId, memberId) {
|
|
163326
|
-
const bytes2 =
|
|
164073
|
+
const bytes2 = createHash42("sha256").update(JSON.stringify(["himi-push-campaign", campaignId, memberId])).digest().subarray(0, 16);
|
|
163327
164074
|
bytes2[6] = bytes2[6] & 15 | 80;
|
|
163328
164075
|
bytes2[8] = bytes2[8] & 63 | 128;
|
|
163329
164076
|
const hex2 = bytes2.toString("hex");
|
|
@@ -163373,7 +164120,7 @@ __export(notify_ping_exports, {
|
|
|
163373
164120
|
runNotifyPing: () => runNotifyPing
|
|
163374
164121
|
});
|
|
163375
164122
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
163376
|
-
import { resolve as
|
|
164123
|
+
import { resolve as resolve58 } from "node:path";
|
|
163377
164124
|
function refuse6(io2, error, hint, exit = 2, extra = {}) {
|
|
163378
164125
|
io2.error(JSON.stringify({ ok: false, error, ...hint ? { hint } : {}, ...extra }));
|
|
163379
164126
|
return exit;
|
|
@@ -163384,7 +164131,7 @@ async function runNotifyPing(flags, io2, deps = {}) {
|
|
|
163384
164131
|
const allMembers = flags["all-members"] === true;
|
|
163385
164132
|
if (allMembers && text8(flags["member-email"])) return refuse6(io2, "recipient_conflict", "Choose --all-members or --member-email.");
|
|
163386
164133
|
if (allMembers && flags["dry-run"] !== true && flags.yes !== true) return refuse6(io2, "confirmation_required", "Preview with --dry-run, then add --yes to send to every approved member.");
|
|
163387
|
-
const input = mergePushInputs(pushInputsFromContent(
|
|
164134
|
+
const input = mergePushInputs(pushInputsFromContent(resolve58(text8(flags.content) ?? process.cwd())), flags);
|
|
163388
164135
|
const missing = [...input.app ? [] : ["app"], ...input.site ? [] : ["site"], ...REQUIRED_FLAGS.filter((f2) => !(allMembers && f2 === "member-email") && !text8(flags[f2]))];
|
|
163389
164136
|
if (missing.length) return refuse6(io2, "needs_input", "Name the app and site (or --content), the member's login email, a title and a link.", 2, { missing });
|
|
163390
164137
|
const requestId2 = text8(flags["request-id"]) ?? (deps.newRequestId ?? randomUUID9)();
|
|
@@ -163470,7 +164217,7 @@ async function runAllMembers(args) {
|
|
|
163470
164217
|
const result = await sendCampaign({
|
|
163471
164218
|
recipients,
|
|
163472
164219
|
campaignId: requestId2,
|
|
163473
|
-
wait: deps.wait ?? ((ms2) => new Promise((
|
|
164220
|
+
wait: deps.wait ?? ((ms2) => new Promise((resolve65) => setTimeout(resolve65, ms2))),
|
|
163474
164221
|
onProgress: (completed) => {
|
|
163475
164222
|
if (completed % 10 === 0 || completed === recipients.length) {
|
|
163476
164223
|
io2.log(JSON.stringify({ ok: true, state: "progress", campaignId: requestId2, completed, recipients: recipients.length }));
|
|
@@ -163573,15 +164320,15 @@ __export(notify_exports, {
|
|
|
163573
164320
|
runNotify: () => runNotify,
|
|
163574
164321
|
saveAdminSession: () => saveAdminSession
|
|
163575
164322
|
});
|
|
163576
|
-
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as
|
|
164323
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync35, readFileSync as readFileSync96, writeFileSync as writeFileSync31 } from "node:fs";
|
|
163577
164324
|
import { homedir as homedir12 } from "node:os";
|
|
163578
|
-
import { dirname as
|
|
164325
|
+
import { dirname as dirname43, join as join80 } from "node:path";
|
|
163579
164326
|
function defaultSessionsPath() {
|
|
163580
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
164327
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join80(homedir12(), ".himalaya", "admin-sessions.json");
|
|
163581
164328
|
}
|
|
163582
164329
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
163583
164330
|
try {
|
|
163584
|
-
return JSON.parse(
|
|
164331
|
+
return JSON.parse(readFileSync96(path2, "utf8"));
|
|
163585
164332
|
} catch {
|
|
163586
164333
|
return {};
|
|
163587
164334
|
}
|
|
@@ -163589,10 +164336,10 @@ function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
|
163589
164336
|
function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
|
|
163590
164337
|
const file2 = loadSessionsFile(path2);
|
|
163591
164338
|
file2.sessions = { ...file2.sessions, [adminUrl]: session };
|
|
163592
|
-
mkdirSync35(
|
|
164339
|
+
mkdirSync35(dirname43(path2), { recursive: true, mode: 448 });
|
|
163593
164340
|
writeFileSync31(path2, JSON.stringify(file2, null, 2) + "\n", { mode: 384 });
|
|
163594
164341
|
try {
|
|
163595
|
-
chmodSync3(
|
|
164342
|
+
chmodSync3(dirname43(path2), 448);
|
|
163596
164343
|
chmodSync3(path2, 384);
|
|
163597
164344
|
} catch {
|
|
163598
164345
|
}
|
|
@@ -163958,20 +164705,20 @@ __export(base44_auth_exports, {
|
|
|
163958
164705
|
usableBase44Auth: () => usableBase44Auth,
|
|
163959
164706
|
writeBase44Session: () => writeBase44Session
|
|
163960
164707
|
});
|
|
163961
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
164708
|
+
import { chmodSync as chmodSync4, existsSync as existsSync77, mkdirSync as mkdirSync36, readFileSync as readFileSync97, rmSync as rmSync20, writeFileSync as writeFileSync32 } from "node:fs";
|
|
163962
164709
|
import { homedir as homedir13 } from "node:os";
|
|
163963
|
-
import { dirname as
|
|
164710
|
+
import { dirname as dirname44, join as join81 } from "node:path";
|
|
163964
164711
|
function base44ApiBase(env = process.env) {
|
|
163965
164712
|
return (env.BASE44_API_URL?.trim() || "https://app.base44.com").replace(/\/+$/, "");
|
|
163966
164713
|
}
|
|
163967
164714
|
function base44SessionPath(home = homedir13()) {
|
|
163968
|
-
return
|
|
164715
|
+
return join81(home, ".himi", "base44", "session.json");
|
|
163969
164716
|
}
|
|
163970
164717
|
function readBase44Session(home) {
|
|
163971
164718
|
const p2 = base44SessionPath(home);
|
|
163972
|
-
if (!
|
|
164719
|
+
if (!existsSync77(p2)) return void 0;
|
|
163973
164720
|
try {
|
|
163974
|
-
const s2 = JSON.parse(
|
|
164721
|
+
const s2 = JSON.parse(readFileSync97(p2, "utf8"));
|
|
163975
164722
|
return typeof s2.accessToken === "string" && s2.accessToken ? s2 : void 0;
|
|
163976
164723
|
} catch {
|
|
163977
164724
|
return void 0;
|
|
@@ -163979,7 +164726,7 @@ function readBase44Session(home) {
|
|
|
163979
164726
|
}
|
|
163980
164727
|
function writeBase44Session(session, home) {
|
|
163981
164728
|
const p2 = base44SessionPath(home);
|
|
163982
|
-
mkdirSync36(
|
|
164729
|
+
mkdirSync36(dirname44(p2), { recursive: true, mode: 448 });
|
|
163983
164730
|
writeFileSync32(p2, `${JSON.stringify(session, null, 2)}
|
|
163984
164731
|
`, { mode: 384 });
|
|
163985
164732
|
chmodSync4(p2, 384);
|
|
@@ -163987,8 +164734,8 @@ function writeBase44Session(session, home) {
|
|
|
163987
164734
|
}
|
|
163988
164735
|
function deleteBase44Session(home) {
|
|
163989
164736
|
const p2 = base44SessionPath(home);
|
|
163990
|
-
if (!
|
|
163991
|
-
|
|
164737
|
+
if (!existsSync77(p2)) return false;
|
|
164738
|
+
rmSync20(p2, { force: true });
|
|
163992
164739
|
return true;
|
|
163993
164740
|
}
|
|
163994
164741
|
function jwtClaims(token) {
|
|
@@ -164082,9 +164829,9 @@ async function base44DeviceLogin(opts) {
|
|
|
164082
164829
|
throw new Error("the Base44 sign-in code expired before it was approved \u2014 run `himi base44 login` again");
|
|
164083
164830
|
}
|
|
164084
164831
|
function importBase44CliSession(home = homedir13(), env = process.env) {
|
|
164085
|
-
const src =
|
|
164086
|
-
if (!
|
|
164087
|
-
const a2 = JSON.parse(
|
|
164832
|
+
const src = join81(home, ".base44", "auth", "auth.json");
|
|
164833
|
+
if (!existsSync77(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
|
|
164834
|
+
const a2 = JSON.parse(readFileSync97(src, "utf8"));
|
|
164088
164835
|
if (typeof a2.accessToken !== "string" || !a2.accessToken) throw new Error(`${src} holds no access token`);
|
|
164089
164836
|
const session = {
|
|
164090
164837
|
accessToken: a2.accessToken,
|
|
@@ -164255,10 +165002,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
164255
165002
|
if (refusal) throw new Error(refusal);
|
|
164256
165003
|
}
|
|
164257
165004
|
function resolveAll(hostname3) {
|
|
164258
|
-
return new Promise((
|
|
165005
|
+
return new Promise((resolve65, reject) => {
|
|
164259
165006
|
dnsLookup(hostname3, { all: true, verbatim: true }, (err, addresses) => {
|
|
164260
165007
|
if (err) reject(err);
|
|
164261
|
-
else
|
|
165008
|
+
else resolve65(addresses);
|
|
164262
165009
|
});
|
|
164263
165010
|
});
|
|
164264
165011
|
}
|
|
@@ -164266,13 +165013,13 @@ function withAbort(start, signal, what) {
|
|
|
164266
165013
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
164267
165014
|
const work = start();
|
|
164268
165015
|
if (!signal) return work;
|
|
164269
|
-
return new Promise((
|
|
165016
|
+
return new Promise((resolve65, reject) => {
|
|
164270
165017
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
164271
165018
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
164272
|
-
work.then(
|
|
165019
|
+
work.then(resolve65, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
164273
165020
|
});
|
|
164274
165021
|
}
|
|
164275
|
-
async function pinAddress(url,
|
|
165022
|
+
async function pinAddress(url, resolve65 = resolveAll, signal) {
|
|
164276
165023
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
164277
165024
|
if (ipv4Octets(host)) {
|
|
164278
165025
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -164282,7 +165029,7 @@ async function pinAddress(url, resolve63 = resolveAll, signal) {
|
|
|
164282
165029
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
164283
165030
|
return { address: host, family: 6 };
|
|
164284
165031
|
}
|
|
164285
|
-
const addresses = await withAbort(() =>
|
|
165032
|
+
const addresses = await withAbort(() => resolve65(host), signal, `${host} lookup`);
|
|
164286
165033
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
164287
165034
|
const blocked = addresses.filter((a2) => isBlockedAddress(a2.address)).map((a2) => a2.address);
|
|
164288
165035
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -164322,7 +165069,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
164322
165069
|
return out2;
|
|
164323
165070
|
}
|
|
164324
165071
|
function requestOnce(url, pinned, init) {
|
|
164325
|
-
return new Promise((
|
|
165072
|
+
return new Promise((resolve65, reject) => {
|
|
164326
165073
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
164327
165074
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
164328
165075
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -164352,7 +165099,7 @@ function requestOnce(url, pinned, init) {
|
|
|
164352
165099
|
reject(err);
|
|
164353
165100
|
return;
|
|
164354
165101
|
}
|
|
164355
|
-
|
|
165102
|
+
resolve65(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out2 }));
|
|
164356
165103
|
}
|
|
164357
165104
|
);
|
|
164358
165105
|
req.on("error", reject);
|
|
@@ -166324,7 +167071,7 @@ var init_brand_font = __esm({
|
|
|
166324
167071
|
|
|
166325
167072
|
// src/site-analyze/write-artifacts.ts
|
|
166326
167073
|
import { mkdirSync as mkdirSync37, writeFileSync as writeFileSync33 } from "node:fs";
|
|
166327
|
-
import { join as
|
|
167074
|
+
import { join as join82 } from "node:path";
|
|
166328
167075
|
function attachVeloSources(book, sources, put) {
|
|
166329
167076
|
const byPath = new Map((sources ?? []).map((s2) => [s2.path, s2.text]));
|
|
166330
167077
|
for (const f2 of book.velo.files) {
|
|
@@ -166479,12 +167226,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
166479
167226
|
}
|
|
166480
167227
|
async function writeBusinessBook(result, opts) {
|
|
166481
167228
|
const out2 = opts.outDir;
|
|
166482
|
-
mkdirSync37(
|
|
166483
|
-
mkdirSync37(
|
|
167229
|
+
mkdirSync37(join82(out2, "evidence/pages"), { recursive: true });
|
|
167230
|
+
mkdirSync37(join82(out2, "media/catalog"), { recursive: true });
|
|
166484
167231
|
const files = [];
|
|
166485
167232
|
const put = (rel, body) => {
|
|
166486
|
-
const p2 =
|
|
166487
|
-
mkdirSync37(
|
|
167233
|
+
const p2 = join82(out2, rel);
|
|
167234
|
+
mkdirSync37(join82(p2, ".."), { recursive: true });
|
|
166488
167235
|
writeFileSync33(p2, body);
|
|
166489
167236
|
files.push(rel);
|
|
166490
167237
|
};
|
|
@@ -167388,11 +168135,11 @@ var init_analyze = __esm({
|
|
|
167388
168135
|
});
|
|
167389
168136
|
|
|
167390
168137
|
// src/base44-analyze/write-artifacts.ts
|
|
167391
|
-
import { existsSync as
|
|
167392
|
-
import { dirname as
|
|
168138
|
+
import { existsSync as existsSync78, mkdirSync as mkdirSync38, readFileSync as readFileSync98, rmSync as rmSync21, writeFileSync as writeFileSync34 } from "node:fs";
|
|
168139
|
+
import { dirname as dirname45, join as join83, resolve as resolve59, sep as sep19 } from "node:path";
|
|
167393
168140
|
function isBookFolder(dir) {
|
|
167394
168141
|
try {
|
|
167395
|
-
return JSON.parse(
|
|
168142
|
+
return JSON.parse(readFileSync98(join83(dir, "book.json"), "utf8")).kind === "base44-app-book";
|
|
167396
168143
|
} catch {
|
|
167397
168144
|
return false;
|
|
167398
168145
|
}
|
|
@@ -167466,7 +168213,7 @@ function renderBookMd(book) {
|
|
|
167466
168213
|
return L2.join("\n");
|
|
167467
168214
|
}
|
|
167468
168215
|
function writeBase44Book(result, outDir, opts = {}) {
|
|
167469
|
-
const out2 =
|
|
168216
|
+
const out2 = resolve59(outDir);
|
|
167470
168217
|
const book = result.book;
|
|
167471
168218
|
const files = [];
|
|
167472
168219
|
const shots = (opts.screenshots ?? []).filter((s2) => safeRel(s2.filename) && !s2.filename.includes("/"));
|
|
@@ -167479,26 +168226,26 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
167479
168226
|
const md = renderBookMd(book);
|
|
167480
168227
|
assertNoSecrets(json6);
|
|
167481
168228
|
assertNoSecrets(md);
|
|
167482
|
-
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) =>
|
|
168229
|
+
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync78(join83(out2, n2)));
|
|
167483
168230
|
if (owned.length) {
|
|
167484
168231
|
if (!isBookFolder(out2)) throw new Error(`refusing to write the app book into ${out2}: it already has ${owned.join(", ")} that ${owned.length === 1 ? "is" : "are"} not from an app book \u2014 pick an empty --out`);
|
|
167485
|
-
for (const d2 of ["source", "screenshots"])
|
|
168232
|
+
for (const d2 of ["source", "screenshots"]) rmSync21(join83(out2, d2), { recursive: true, force: true });
|
|
167486
168233
|
}
|
|
167487
168234
|
mkdirSync38(out2, { recursive: true });
|
|
167488
|
-
writeFileSync34(
|
|
167489
|
-
writeFileSync34(
|
|
168235
|
+
writeFileSync34(join83(out2, "book.json"), json6);
|
|
168236
|
+
writeFileSync34(join83(out2, "BOOK.md"), md);
|
|
167490
168237
|
files.push("book.json", "BOOK.md");
|
|
167491
168238
|
for (const s2 of shots) {
|
|
167492
|
-
mkdirSync38(
|
|
167493
|
-
writeFileSync34(
|
|
168239
|
+
mkdirSync38(join83(out2, "screenshots"), { recursive: true });
|
|
168240
|
+
writeFileSync34(join83(out2, "screenshots", s2.filename), s2.bytes);
|
|
167494
168241
|
files.push(`screenshots/${s2.filename}`);
|
|
167495
168242
|
}
|
|
167496
|
-
const sourceRoot =
|
|
168243
|
+
const sourceRoot = join83(out2, "source");
|
|
167497
168244
|
for (const f2 of result.sourceFiles) {
|
|
167498
168245
|
if (!safeRel(f2.path)) continue;
|
|
167499
|
-
const dest =
|
|
168246
|
+
const dest = join83(sourceRoot, ...f2.path.split("/"));
|
|
167500
168247
|
if (!dest.startsWith(sourceRoot + sep19)) continue;
|
|
167501
|
-
mkdirSync38(
|
|
168248
|
+
mkdirSync38(dirname45(dest), { recursive: true });
|
|
167502
168249
|
writeFileSync34(dest, f2.bytes);
|
|
167503
168250
|
}
|
|
167504
168251
|
if (result.sourceFiles.length) files.push(`source/ (${result.sourceFiles.length} files)`);
|
|
@@ -168369,10 +169116,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
168369
169116
|
}
|
|
168370
169117
|
function createPromiseCallback(cb) {
|
|
168371
169118
|
let callback;
|
|
168372
|
-
let
|
|
169119
|
+
let resolve65;
|
|
168373
169120
|
let reject;
|
|
168374
169121
|
const promise = new Promise((_resolve, _reject) => {
|
|
168375
|
-
|
|
169122
|
+
resolve65 = _resolve;
|
|
168376
169123
|
reject = _reject;
|
|
168377
169124
|
});
|
|
168378
169125
|
if (typeof cb === "function") {
|
|
@@ -168388,7 +169135,7 @@ function createPromiseCallback(cb) {
|
|
|
168388
169135
|
callback = (err, result) => {
|
|
168389
169136
|
try {
|
|
168390
169137
|
if (err) reject(err);
|
|
168391
|
-
else
|
|
169138
|
+
else resolve65(result);
|
|
168392
169139
|
} catch (e2) {
|
|
168393
169140
|
reject(e2 instanceof Error ? e2 : new Error());
|
|
168394
169141
|
}
|
|
@@ -171040,9 +171787,9 @@ __export(cli_exports, {
|
|
|
171040
171787
|
systemTar: () => systemTar
|
|
171041
171788
|
});
|
|
171042
171789
|
import { execFile } from "node:child_process";
|
|
171043
|
-
import { mkdirSync as mkdirSync39, mkdtempSync as
|
|
171044
|
-
import { tmpdir as
|
|
171045
|
-
import { join as
|
|
171790
|
+
import { mkdirSync as mkdirSync39, mkdtempSync as mkdtempSync5, rmSync as rmSync22, writeFileSync as writeFileSync35 } from "node:fs";
|
|
171791
|
+
import { tmpdir as tmpdir6 } from "node:os";
|
|
171792
|
+
import { join as join84, resolve as resolve60 } from "node:path";
|
|
171046
171793
|
import { promisify } from "node:util";
|
|
171047
171794
|
function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
171048
171795
|
return async (appId2) => {
|
|
@@ -171055,11 +171802,11 @@ function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
|
|
|
171055
171802
|
}
|
|
171056
171803
|
const bytes2 = await readCapped(res, MAX_TARBALL_BYTES);
|
|
171057
171804
|
if (!bytes2) throw new Error(`project download is over the ${MAX_TARBALL_BYTES}-byte cap`);
|
|
171058
|
-
const root =
|
|
171059
|
-
const cleanup = () =>
|
|
171805
|
+
const root = mkdtempSync5(join84(tmpdir6(), "himi-base44-"));
|
|
171806
|
+
const cleanup = () => rmSync22(root, { recursive: true, force: true });
|
|
171060
171807
|
try {
|
|
171061
|
-
const archive =
|
|
171062
|
-
const dir =
|
|
171808
|
+
const archive = join84(root, "project.tar");
|
|
171809
|
+
const dir = join84(root, "project");
|
|
171063
171810
|
writeFileSync35(archive, bytes2);
|
|
171064
171811
|
mkdirSync39(dir);
|
|
171065
171812
|
await extract(archive, dir);
|
|
@@ -171097,7 +171844,7 @@ async function runBase44Analyze(opts) {
|
|
|
171097
171844
|
now: opts.now ?? (() => /* @__PURE__ */ new Date())
|
|
171098
171845
|
};
|
|
171099
171846
|
const result = await analyzeBase44({ url: opts.url, appId: opts.appId, sample: opts.sample }, ports);
|
|
171100
|
-
const written = writeBase44Book(result,
|
|
171847
|
+
const written = writeBase44Book(result, resolve60(opts.cwd ?? process.cwd(), opts.outDir ?? ".himi/base44-book"), { screenshots });
|
|
171101
171848
|
return { ok: true, out: written.outDir, files: written.files, mode: result.book.mode, gaps: result.book.gaps, book: result.book };
|
|
171102
171849
|
}
|
|
171103
171850
|
var MAX_TARBALL_BYTES, systemTar;
|
|
@@ -171131,7 +171878,7 @@ var init_errors2 = __esm({
|
|
|
171131
171878
|
});
|
|
171132
171879
|
|
|
171133
171880
|
// src/one-app/collect.ts
|
|
171134
|
-
import { createHash as
|
|
171881
|
+
import { createHash as createHash43 } from "node:crypto";
|
|
171135
171882
|
function isObject2(value) {
|
|
171136
171883
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
171137
171884
|
}
|
|
@@ -171203,7 +171950,7 @@ function semanticFingerprint(structure) {
|
|
|
171203
171950
|
}
|
|
171204
171951
|
return JSON.stringify(value);
|
|
171205
171952
|
};
|
|
171206
|
-
return
|
|
171953
|
+
return createHash43("sha256").update(canonical4(structure, true)).digest("hex");
|
|
171207
171954
|
}
|
|
171208
171955
|
async function collectOneApp(input, deps = {}) {
|
|
171209
171956
|
if (typeof input.metaSiteId !== "string" || !UUID.test(input.metaSiteId)) {
|
|
@@ -171616,9 +172363,9 @@ __export(cli_exports2, {
|
|
|
171616
172363
|
ONE_APP_WORKFLOW: () => ONE_APP_WORKFLOW,
|
|
171617
172364
|
runOneAppCommand: () => runOneAppCommand
|
|
171618
172365
|
});
|
|
171619
|
-
import { closeSync as closeSync7, constants as constants4, lstatSync as lstatSync21, mkdirSync as mkdirSync40, openSync as openSync6, readFileSync as
|
|
171620
|
-
import { createHash as
|
|
171621
|
-
import { dirname as
|
|
172366
|
+
import { closeSync as closeSync7, constants as constants4, lstatSync as lstatSync21, mkdirSync as mkdirSync40, openSync as openSync6, readFileSync as readFileSync99, realpathSync as realpathSync14, writeFileSync as writeFileSync36 } from "node:fs";
|
|
172367
|
+
import { createHash as createHash44 } from "node:crypto";
|
|
172368
|
+
import { dirname as dirname46, join as join85, parse as parse3, resolve as resolve61 } from "node:path";
|
|
171622
172369
|
function readOptions(argv, cwd, commandIncluded) {
|
|
171623
172370
|
let cursor = 0;
|
|
171624
172371
|
const skipGlobalSwitches = () => {
|
|
@@ -171659,10 +172406,10 @@ function readOptions(argv, cwd, commandIncluded) {
|
|
|
171659
172406
|
let prompt = flags.prompt ?? "";
|
|
171660
172407
|
if (flags["prompt-file"] !== void 0) {
|
|
171661
172408
|
try {
|
|
171662
|
-
const file2 =
|
|
172409
|
+
const file2 = resolve61(cwd, flags["prompt-file"]);
|
|
171663
172410
|
const stat2 = lstatSync21(file2);
|
|
171664
172411
|
if (!stat2.isFile() || stat2.size > MAX_PROMPT_BYTES) throw new Error("invalid prompt file");
|
|
171665
|
-
prompt =
|
|
172412
|
+
prompt = readFileSync99(file2, "utf8");
|
|
171666
172413
|
} catch {
|
|
171667
172414
|
throw new OneAppError("invalid_prompt", "Use a readable text file of at most 64 KiB for --prompt-file.");
|
|
171668
172415
|
}
|
|
@@ -171677,8 +172424,8 @@ function readOptions(argv, cwd, commandIncluded) {
|
|
|
171677
172424
|
if (flags.dir !== void 0 && !flags.dir.trim()) {
|
|
171678
172425
|
throw new OneAppError("invalid_output_path", "Pass a parent directory with --dir.");
|
|
171679
172426
|
}
|
|
171680
|
-
const parentDir =
|
|
171681
|
-
const workspace =
|
|
172427
|
+
const parentDir = resolve61(cwd, flags.dir ?? ".");
|
|
172428
|
+
const workspace = join85(parentDir, name);
|
|
171682
172429
|
assertSafeParents(parentDir);
|
|
171683
172430
|
if (pathExists(workspace)) throw new OneAppError("output_exists", "The destination already exists. Choose a new --name or --dir.");
|
|
171684
172431
|
return { metaSiteId, appInstance, prompt, name, parentDir, workspace, target };
|
|
@@ -171707,7 +172454,7 @@ function assertSafeParents(path2) {
|
|
|
171707
172454
|
throw new OneAppError("invalid_output_path", "The output parent cannot be inspected.");
|
|
171708
172455
|
}
|
|
171709
172456
|
}
|
|
171710
|
-
current =
|
|
172457
|
+
current = dirname46(current);
|
|
171711
172458
|
}
|
|
171712
172459
|
}
|
|
171713
172460
|
function writePrivate(path2, contents, append) {
|
|
@@ -171735,7 +172482,7 @@ Collect the source mobile app and hand it to the current coding agent. The agent
|
|
|
171735
172482
|
const hashes = {};
|
|
171736
172483
|
const diskWrite = deps.writeFile ?? writePrivate;
|
|
171737
172484
|
const put = (name, content) => {
|
|
171738
|
-
const path2 =
|
|
172485
|
+
const path2 = join85(evidenceDir, name);
|
|
171739
172486
|
try {
|
|
171740
172487
|
assertSafeParents(evidenceDir);
|
|
171741
172488
|
diskWrite(path2, content, false);
|
|
@@ -171743,7 +172490,7 @@ Collect the source mobile app and hand it to the current coding agent. The agent
|
|
|
171743
172490
|
throw new OneAppError("artifact_write_failed", "Could not save the migration evidence. Existing files were kept.", { stage });
|
|
171744
172491
|
}
|
|
171745
172492
|
artifacts[name] = path2;
|
|
171746
|
-
hashes[name] =
|
|
172493
|
+
hashes[name] = createHash44("sha256").update(content).digest("hex");
|
|
171747
172494
|
return path2;
|
|
171748
172495
|
};
|
|
171749
172496
|
const progress = (nextStage) => {
|
|
@@ -171751,7 +172498,7 @@ Collect the source mobile app and hand it to the current coding agent. The agent
|
|
|
171751
172498
|
if (!evidenceDir) return;
|
|
171752
172499
|
try {
|
|
171753
172500
|
assertSafeParents(evidenceDir);
|
|
171754
|
-
diskWrite(
|
|
172501
|
+
diskWrite(join85(evidenceDir, "progress.jsonl"), JSON.stringify({ stage, at: now() }) + "\n", true);
|
|
171755
172502
|
} catch {
|
|
171756
172503
|
throw new OneAppError("artifact_write_failed", "Could not record migration progress. Existing files were kept.", { stage });
|
|
171757
172504
|
}
|
|
@@ -171767,7 +172514,7 @@ Collect the source mobile app and hand it to the current coding agent. The agent
|
|
|
171767
172514
|
assertSafeParents(options.parentDir);
|
|
171768
172515
|
mkdirSync40(options.workspace, { mode: 448 });
|
|
171769
172516
|
if (realpathSync14(options.workspace) !== options.workspace) throw new Error("destination changed");
|
|
171770
|
-
evidenceDir =
|
|
172517
|
+
evidenceDir = join85(options.workspace, ".himi", "one-app");
|
|
171771
172518
|
mkdirSync40(evidenceDir, { recursive: true, mode: 448 });
|
|
171772
172519
|
} catch (error) {
|
|
171773
172520
|
if (error.code === "EEXIST") {
|
|
@@ -173583,15 +174330,15 @@ var init_customer_build = __esm({
|
|
|
173583
174330
|
});
|
|
173584
174331
|
|
|
173585
174332
|
// src/site-analyze/apply.ts
|
|
173586
|
-
import { existsSync as
|
|
173587
|
-
import { dirname as
|
|
174333
|
+
import { existsSync as existsSync79, readFileSync as readFileSync100, writeFileSync as writeFileSync37, copyFileSync as copyFileSync2, mkdirSync as mkdirSync41, realpathSync as realpathSync15, statSync as statSync22 } from "node:fs";
|
|
174334
|
+
import { dirname as dirname47, isAbsolute as isAbsolute8, join as join86, resolve as resolve62, sep as sep20 } from "node:path";
|
|
173588
174335
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
173589
174336
|
function unpairedRedirectNote(overlay) {
|
|
173590
174337
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
173591
174338
|
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)`;
|
|
173592
174339
|
}
|
|
173593
174340
|
function posix4(p2) {
|
|
173594
|
-
return
|
|
174341
|
+
return resolve62(p2).replace(/\\/g, "/");
|
|
173595
174342
|
}
|
|
173596
174343
|
function committedShellProvisioning(path2) {
|
|
173597
174344
|
return committedShellFor(posix4(path2));
|
|
@@ -173599,8 +174346,8 @@ function committedShellProvisioning(path2) {
|
|
|
173599
174346
|
function findRepoRoot(cwd) {
|
|
173600
174347
|
let dir = cwd;
|
|
173601
174348
|
for (let i2 = 0; i2 < 8; i2++) {
|
|
173602
|
-
if (SHELL_NAMES2.some((name) =>
|
|
173603
|
-
const next =
|
|
174349
|
+
if (SHELL_NAMES2.some((name) => existsSync79(join86(dir, shellAppDir(name), "package.json")))) return dir;
|
|
174350
|
+
const next = dirname47(dir);
|
|
173604
174351
|
if (next === dir) break;
|
|
173605
174352
|
dir = next;
|
|
173606
174353
|
}
|
|
@@ -173625,7 +174372,7 @@ function assertNotCommitted(path2, forbidden2) {
|
|
|
173625
174372
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
173626
174373
|
);
|
|
173627
174374
|
}
|
|
173628
|
-
if (forbidden2 &&
|
|
174375
|
+
if (forbidden2 && resolve62(path2) === resolve62(forbidden2)) {
|
|
173629
174376
|
const named = committedShellProvisioning(forbidden2);
|
|
173630
174377
|
throw new Error(
|
|
173631
174378
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden2} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -173702,24 +174449,24 @@ function sameKnownSite(previous, next) {
|
|
|
173702
174449
|
}
|
|
173703
174450
|
function buildMergedContract(options) {
|
|
173704
174451
|
const { appDir: appDir3, packageDir, overlay } = options;
|
|
173705
|
-
const committedPath =
|
|
173706
|
-
if (!
|
|
174452
|
+
const committedPath = join86(appDir3, "provisioning.json");
|
|
174453
|
+
if (!existsSync79(committedPath)) {
|
|
173707
174454
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
173708
174455
|
}
|
|
173709
|
-
const committed = JSON.parse(
|
|
174456
|
+
const committed = JSON.parse(readFileSync100(committedPath, "utf8"));
|
|
173710
174457
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
173711
174458
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
173712
174459
|
const branding = merged.branding ?? {};
|
|
173713
174460
|
const staged = [];
|
|
173714
174461
|
const contained = (root, rel) => {
|
|
173715
174462
|
if (isAbsolute8(rel)) return void 0;
|
|
173716
|
-
const full =
|
|
173717
|
-
return full.startsWith(
|
|
174463
|
+
const full = resolve62(root, rel);
|
|
174464
|
+
return full.startsWith(resolve62(root) + sep20) ? full : void 0;
|
|
173718
174465
|
};
|
|
173719
174466
|
const stage = (fromRel, toRel) => {
|
|
173720
174467
|
const from = contained(packageDir, fromRel);
|
|
173721
|
-
const to2 = contained(
|
|
173722
|
-
if (!from || !to2 || !
|
|
174468
|
+
const to2 = contained(join86(appDir3, STAGED), toRel.slice(STAGED.length + 1));
|
|
174469
|
+
if (!from || !to2 || !existsSync79(from)) return void 0;
|
|
173723
174470
|
let real;
|
|
173724
174471
|
let realRoot;
|
|
173725
174472
|
try {
|
|
@@ -173731,7 +174478,7 @@ function buildMergedContract(options) {
|
|
|
173731
174478
|
if (!real.startsWith(realRoot + sep20)) return void 0;
|
|
173732
174479
|
try {
|
|
173733
174480
|
if (!statSync22(real).isFile()) return void 0;
|
|
173734
|
-
mkdirSync41(
|
|
174481
|
+
mkdirSync41(dirname47(to2), { recursive: true });
|
|
173735
174482
|
copyFileSync2(real, to2);
|
|
173736
174483
|
} catch {
|
|
173737
174484
|
return void 0;
|
|
@@ -173741,11 +174488,11 @@ function buildMergedContract(options) {
|
|
|
173741
174488
|
};
|
|
173742
174489
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
173743
174490
|
if (icon) branding.appIconPath = icon;
|
|
173744
|
-
const facesPath =
|
|
173745
|
-
if (
|
|
174491
|
+
const facesPath = join86(packageDir, "media/fonts/faces.json");
|
|
174492
|
+
if (existsSync79(facesPath)) {
|
|
173746
174493
|
let faces = [];
|
|
173747
174494
|
try {
|
|
173748
|
-
const parsed = JSON.parse(
|
|
174495
|
+
const parsed = JSON.parse(readFileSync100(facesPath, "utf8"));
|
|
173749
174496
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
173750
174497
|
} catch {
|
|
173751
174498
|
faces = [];
|
|
@@ -173766,10 +174513,10 @@ function buildMergedContract(options) {
|
|
|
173766
174513
|
merged.branding = branding;
|
|
173767
174514
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
173768
174515
|
`;
|
|
173769
|
-
const path2 =
|
|
174516
|
+
const path2 = join86(packageDir, "provisioning.contract.json");
|
|
173770
174517
|
writeFileSync37(path2, body);
|
|
173771
|
-
const localPath2 =
|
|
173772
|
-
mkdirSync41(
|
|
174518
|
+
const localPath2 = join86(appDir3, LOCAL_CONTRACT_REL);
|
|
174519
|
+
mkdirSync41(dirname47(localPath2), { recursive: true });
|
|
173773
174520
|
writeFileSync37(localPath2, body);
|
|
173774
174521
|
staged.push(localPath2);
|
|
173775
174522
|
return { path: path2, staged };
|
|
@@ -173803,10 +174550,10 @@ function catalogTypography(overlay, template) {
|
|
|
173803
174550
|
function staticFaqFor(overlay, overlayPath) {
|
|
173804
174551
|
const own5 = overlay.faq;
|
|
173805
174552
|
if (own5 !== void 0) return deriveStaticFaq(own5);
|
|
173806
|
-
const bookPath =
|
|
173807
|
-
if (!
|
|
174553
|
+
const bookPath = join86(dirname47(resolve62(overlayPath)), "book.json");
|
|
174554
|
+
if (!existsSync79(bookPath)) return void 0;
|
|
173808
174555
|
try {
|
|
173809
|
-
const book = JSON.parse(
|
|
174556
|
+
const book = JSON.parse(readFileSync100(bookPath, "utf8"));
|
|
173810
174557
|
const copy = book?.copy;
|
|
173811
174558
|
if (!copy || typeof copy !== "object" || copy.unavailable) return void 0;
|
|
173812
174559
|
const pairs = deriveStaticFaq(copy.faq);
|
|
@@ -173820,10 +174567,10 @@ function staticGalleriesFor(overlay, overlayPath) {
|
|
|
173820
174567
|
if (overlay.galleries !== void 0) return deriveStaticGalleries(
|
|
173821
174568
|
overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
|
|
173822
174569
|
);
|
|
173823
|
-
const bookPath =
|
|
173824
|
-
if (!
|
|
174570
|
+
const bookPath = join86(dirname47(resolve62(overlayPath)), "book.json");
|
|
174571
|
+
if (!existsSync79(bookPath)) return void 0;
|
|
173825
174572
|
try {
|
|
173826
|
-
const book = JSON.parse(
|
|
174573
|
+
const book = JSON.parse(readFileSync100(bookPath, "utf8"));
|
|
173827
174574
|
if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
|
|
173828
174575
|
const galleries = deriveStaticGalleries(book.look.pages);
|
|
173829
174576
|
return galleries.length || book.look.complete === true ? galleries : void 0;
|
|
@@ -173832,11 +174579,11 @@ function staticGalleriesFor(overlay, overlayPath) {
|
|
|
173832
174579
|
}
|
|
173833
174580
|
}
|
|
173834
174581
|
async function applyOverlays(input) {
|
|
173835
|
-
const cwd =
|
|
174582
|
+
const cwd = resolve62(input.cwd);
|
|
173836
174583
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
173837
174584
|
assertKnownShell(shell);
|
|
173838
|
-
const overlay = JSON.parse(
|
|
173839
|
-
const tokens2 = JSON.parse(
|
|
174585
|
+
const overlay = JSON.parse(readFileSync100(input.overlayPath, "utf8"));
|
|
174586
|
+
const tokens2 = JSON.parse(readFileSync100(input.tokensPath, "utf8"));
|
|
173840
174587
|
const faq = staticFaqFor(overlay, input.overlayPath);
|
|
173841
174588
|
if (faq !== void 0) overlay.faq = faq;
|
|
173842
174589
|
const galleries = staticGalleriesFor(overlay, input.overlayPath);
|
|
@@ -173853,15 +174600,15 @@ async function applyOverlays(input) {
|
|
|
173853
174600
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
173854
174601
|
);
|
|
173855
174602
|
}
|
|
173856
|
-
const appDir3 =
|
|
173857
|
-
const committedPath =
|
|
173858
|
-
const committedSite =
|
|
174603
|
+
const appDir3 = join86(repoRoot2, shellAppDir(shell));
|
|
174604
|
+
const committedPath = join86(appDir3, "provisioning.json");
|
|
174605
|
+
const committedSite = existsSync79(committedPath) ? JSON.parse(readFileSync100(committedPath, "utf8")).site : void 0;
|
|
173859
174606
|
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
173860
174607
|
throw new Error(
|
|
173861
174608
|
`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.`
|
|
173862
174609
|
);
|
|
173863
174610
|
}
|
|
173864
|
-
const packageDir =
|
|
174611
|
+
const packageDir = dirname47(resolve62(input.overlayPath));
|
|
173865
174612
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir3, packageDir, overlay });
|
|
173866
174613
|
wrote.push(...staged);
|
|
173867
174614
|
const r2 = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -173882,9 +174629,9 @@ async function applyOverlays(input) {
|
|
|
173882
174629
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
173883
174630
|
};
|
|
173884
174631
|
}
|
|
173885
|
-
const pkgProv =
|
|
174632
|
+
const pkgProv = join86(cwd, "provisioning.json");
|
|
173886
174633
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
173887
|
-
const contentPath =
|
|
174634
|
+
const contentPath = join86(cwd, "himalaya.content.json");
|
|
173888
174635
|
const syncViewNames = (before, after) => {
|
|
173889
174636
|
const content = readContentManifest(cwd);
|
|
173890
174637
|
if (!content) return;
|
|
@@ -173896,8 +174643,8 @@ async function applyOverlays(input) {
|
|
|
173896
174643
|
};
|
|
173897
174644
|
let packageFaq = faq;
|
|
173898
174645
|
let packageGalleries = galleries;
|
|
173899
|
-
if (
|
|
173900
|
-
const cur = JSON.parse(
|
|
174646
|
+
if (existsSync79(pkgProv)) {
|
|
174647
|
+
const cur = JSON.parse(readFileSync100(pkgProv, "utf8"));
|
|
173901
174648
|
if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
|
|
173902
174649
|
const merged = deepMerge4(cur, overlay);
|
|
173903
174650
|
packageFaq = merged.faq;
|
|
@@ -173913,9 +174660,9 @@ async function applyOverlays(input) {
|
|
|
173913
174660
|
if (Array.isArray(packageGalleries) && packageGalleries.length && !overlay.installedVerticals.includes("galleries")) {
|
|
173914
174661
|
overlay.installedVerticals.push("galleries");
|
|
173915
174662
|
}
|
|
173916
|
-
const pkgTokens =
|
|
173917
|
-
if (
|
|
173918
|
-
const cur = JSON.parse(
|
|
174663
|
+
const pkgTokens = join86(cwd, "tokens.json");
|
|
174664
|
+
if (existsSync79(pkgTokens) && (tokens2.colors || tokens2.typography)) {
|
|
174665
|
+
const cur = JSON.parse(readFileSync100(pkgTokens, "utf8"));
|
|
173919
174666
|
let tokensIn = tokens2;
|
|
173920
174667
|
if (tokens2.typography) {
|
|
173921
174668
|
const fonts = catalogTypography(tokens2.typography, cur.typography);
|
|
@@ -173940,9 +174687,9 @@ async function applyOverlays(input) {
|
|
|
173940
174687
|
wrote.push(pkgTokens);
|
|
173941
174688
|
}
|
|
173942
174689
|
const homeAction = homeRefreshActionId(shell);
|
|
173943
|
-
const homeSrc =
|
|
173944
|
-
if (homeAction &&
|
|
173945
|
-
const prev =
|
|
174690
|
+
const homeSrc = join86(cwd, "dev/index.ts");
|
|
174691
|
+
if (homeAction && existsSync79(homeSrc)) {
|
|
174692
|
+
const prev = readFileSync100(homeSrc, "utf8");
|
|
173946
174693
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
173947
174694
|
let next = patched.src;
|
|
173948
174695
|
if (!patched.foreign && faq?.length && prev.includes('"tier5.himiBrandedFaq.load"') && !prev.includes('"staticFaq"')) {
|
|
@@ -173977,13 +174724,13 @@ async function applyOverlays(input) {
|
|
|
173977
174724
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
173978
174725
|
}
|
|
173979
174726
|
}
|
|
173980
|
-
if (!input.iconPath || !
|
|
173981
|
-
const book = input.iconPath ?
|
|
174727
|
+
if (!input.iconPath || !existsSync79(input.iconPath)) {
|
|
174728
|
+
const book = input.iconPath ? dirname47(dirname47(resolve62(input.iconPath))) : void 0;
|
|
173982
174729
|
notes.push(
|
|
173983
174730
|
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"
|
|
173984
174731
|
);
|
|
173985
174732
|
}
|
|
173986
|
-
if (input.iconPath &&
|
|
174733
|
+
if (input.iconPath && existsSync79(input.iconPath)) {
|
|
173987
174734
|
try {
|
|
173988
174735
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
173989
174736
|
wrote.push(...installed.wrote);
|
|
@@ -174941,8 +175688,8 @@ __export(cli_exports3, {
|
|
|
174941
175688
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
174942
175689
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
174943
175690
|
});
|
|
174944
|
-
import { existsSync as
|
|
174945
|
-
import { resolve as
|
|
175691
|
+
import { existsSync as existsSync80, readFileSync as readFileSync101 } from "node:fs";
|
|
175692
|
+
import { resolve as resolve63 } from "node:path";
|
|
174946
175693
|
function applyNeedsClient(shell) {
|
|
174947
175694
|
if (shell === void 0 || !SHELL_NAMES2.includes(shell)) return true;
|
|
174948
175695
|
return !isSiteShell(shell);
|
|
@@ -174966,7 +175713,7 @@ async function runSiteAnalyze(opts) {
|
|
|
174966
175713
|
const assetFetch = assetFetchFor(opts);
|
|
174967
175714
|
const siteFetch = guardedSiteFetch;
|
|
174968
175715
|
const cwd = opts.cwd ?? process.cwd();
|
|
174969
|
-
const outDir =
|
|
175716
|
+
const outDir = resolve63(cwd, opts.outDir ?? ".himi/business-book");
|
|
174970
175717
|
let ownerAuth;
|
|
174971
175718
|
let msid;
|
|
174972
175719
|
const ownerSite = ownerSiteFor(opts);
|
|
@@ -174993,14 +175740,14 @@ async function runSiteAnalyze(opts) {
|
|
|
174993
175740
|
if (opts.shell !== void 0 && isSiteShell(opts.shell)) {
|
|
174994
175741
|
try {
|
|
174995
175742
|
const kind = siteKindForOrigin(result.book.input.siteUrl);
|
|
174996
|
-
const book = kind === "base44" ? base44BookRoutes(
|
|
175743
|
+
const book = kind === "base44" ? base44BookRoutes(resolve63(cwd, ".himi/base44-book/book.json"), result.book.input.siteUrl) : void 0;
|
|
174997
175744
|
const routes = book?.routes;
|
|
174998
175745
|
if (book?.skipped) result.warnings = [...result.warnings ?? [], book.skipped];
|
|
174999
175746
|
const derived = deriveSiteShell({ siteUrl: result.book.input.siteUrl, look: result.book.look, kind, routes });
|
|
175000
|
-
const prevOverlayPath =
|
|
175001
|
-
const prevSite =
|
|
175747
|
+
const prevOverlayPath = resolve63(outDir, "provisioning.overlay.json");
|
|
175748
|
+
const prevSite = existsSync80(prevOverlayPath) ? (() => {
|
|
175002
175749
|
try {
|
|
175003
|
-
return JSON.parse(
|
|
175750
|
+
return JSON.parse(readFileSync101(prevOverlayPath, "utf8")).site;
|
|
175004
175751
|
} catch {
|
|
175005
175752
|
return void 0;
|
|
175006
175753
|
}
|
|
@@ -175017,9 +175764,9 @@ async function runSiteAnalyze(opts) {
|
|
|
175017
175764
|
];
|
|
175018
175765
|
}
|
|
175019
175766
|
}
|
|
175020
|
-
const previousOverlay =
|
|
175767
|
+
const previousOverlay = resolve63(outDir, "provisioning.overlay.json");
|
|
175021
175768
|
carryOverGoals(
|
|
175022
|
-
|
|
175769
|
+
existsSync80(previousOverlay) ? readFileSync101(previousOverlay, "utf8") : void 0,
|
|
175023
175770
|
result.provisioningOverlay
|
|
175024
175771
|
);
|
|
175025
175772
|
const ownerCall = ownerAuth ? ownerTransportFrom(fetchImpl, ownerAuth) : void 0;
|
|
@@ -175038,9 +175785,9 @@ async function runSiteAnalyze(opts) {
|
|
|
175038
175785
|
if (opts.apply) {
|
|
175039
175786
|
applied = await applyOverlays({
|
|
175040
175787
|
cwd,
|
|
175041
|
-
overlayPath:
|
|
175042
|
-
tokensPath:
|
|
175043
|
-
iconPath:
|
|
175788
|
+
overlayPath: resolve63(outDir, "provisioning.overlay.json"),
|
|
175789
|
+
tokensPath: resolve63(outDir, "tokens.overlay.json"),
|
|
175790
|
+
iconPath: resolve63(outDir, "media/icon.png"),
|
|
175044
175791
|
shell: opts.shell
|
|
175045
175792
|
});
|
|
175046
175793
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -175076,8 +175823,8 @@ async function runSiteFunctionCli(opts) {
|
|
|
175076
175823
|
const token = opts.token ?? await siteToken(msid);
|
|
175077
175824
|
let source;
|
|
175078
175825
|
if (opts.sourcePath) {
|
|
175079
|
-
const p2 =
|
|
175080
|
-
source =
|
|
175826
|
+
const p2 = resolve63(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
175827
|
+
source = readFileSync101(p2, "utf8");
|
|
175081
175828
|
}
|
|
175082
175829
|
let body;
|
|
175083
175830
|
if (opts.bodyRaw != null) {
|
|
@@ -175105,9 +175852,9 @@ async function runSiteFunctionCli(opts) {
|
|
|
175105
175852
|
});
|
|
175106
175853
|
}
|
|
175107
175854
|
function base44BookRoutes(bookPath, siteUrl) {
|
|
175108
|
-
if (!
|
|
175855
|
+
if (!existsSync80(bookPath)) return void 0;
|
|
175109
175856
|
try {
|
|
175110
|
-
const book = JSON.parse(
|
|
175857
|
+
const book = JSON.parse(readFileSync101(bookPath, "utf8"));
|
|
175111
175858
|
if (book.kind !== "base44-app-book" || !Array.isArray(book.routes)) return void 0;
|
|
175112
175859
|
const host = (u2) => {
|
|
175113
175860
|
try {
|
|
@@ -175156,7 +175903,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
175156
175903
|
cached2 = fromEnv;
|
|
175157
175904
|
return fromEnv;
|
|
175158
175905
|
}
|
|
175159
|
-
const token = await new Promise((
|
|
175906
|
+
const token = await new Promise((resolve65, reject) => {
|
|
175160
175907
|
let child;
|
|
175161
175908
|
try {
|
|
175162
175909
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -175185,7 +175932,7 @@ async function accountToken2(spawnImpl = spawn6) {
|
|
|
175185
175932
|
const scan = (d2) => {
|
|
175186
175933
|
out2 += String(d2);
|
|
175187
175934
|
const m2 = out2.match(TOKEN_RE2);
|
|
175188
|
-
if (m2) done(() =>
|
|
175935
|
+
if (m2) done(() => resolve65(m2[0]));
|
|
175189
175936
|
};
|
|
175190
175937
|
child.stdout?.on("data", scan);
|
|
175191
175938
|
child.stderr?.on("data", scan);
|
|
@@ -175362,7 +176109,7 @@ __export(site_create_exports, {
|
|
|
175362
176109
|
runSiteList: () => runSiteList,
|
|
175363
176110
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
175364
176111
|
});
|
|
175365
|
-
import { existsSync as
|
|
176112
|
+
import { existsSync as existsSync81, readFileSync as readFileSync102, writeFileSync as writeFileSync38 } from "node:fs";
|
|
175366
176113
|
import { resolve as resolvePath2 } from "node:path";
|
|
175367
176114
|
function oauthClientName(projectName) {
|
|
175368
176115
|
return `${projectName} client`;
|
|
@@ -175511,7 +176258,7 @@ async function runSiteCreate(opts) {
|
|
|
175511
176258
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
175512
176259
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
175513
176260
|
}
|
|
175514
|
-
function writeProvisioningBinding(target, binding2, fs2 = { existsSync:
|
|
176261
|
+
function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync81, readFileSync: readFileSync102, writeFileSync: writeFileSync38 }) {
|
|
175515
176262
|
const msid = binding2.siteId;
|
|
175516
176263
|
const path2 = resolvePath2(target);
|
|
175517
176264
|
const committed = committedShellProvisioning(path2);
|
|
@@ -176208,12 +176955,12 @@ var init_context = __esm({
|
|
|
176208
176955
|
});
|
|
176209
176956
|
|
|
176210
176957
|
// src/cli.ts
|
|
176211
|
-
import { mkdtempSync as
|
|
176958
|
+
import { mkdtempSync as mkdtempSync6, readFileSync as readFileSync103, mkdirSync as mkdirSync42, writeFileSync as writeFileSync39, existsSync as existsSync82, rmSync as rmSync23, readdirSync as readdirSync35, statSync as statSync23, lstatSync as lstatSync22, accessSync, constants as constants5, renameSync as renameSync13, cpSync as cpSync3 } from "node:fs";
|
|
176212
176959
|
import { execFile as execFile2, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
|
|
176213
176960
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
176214
|
-
import { createHash as
|
|
176215
|
-
import { tmpdir as
|
|
176216
|
-
import { join as
|
|
176961
|
+
import { createHash as createHash45, randomUUID as randomUUID11 } from "node:crypto";
|
|
176962
|
+
import { tmpdir as tmpdir7, homedir as homedir14, hostname as hostname2 } from "node:os";
|
|
176963
|
+
import { join as join87, resolve as resolve64, relative as relative16, basename as basename21, dirname as dirname48 } from "node:path";
|
|
176217
176964
|
import { fileURLToPath as fileURLToPath29 } from "node:url";
|
|
176218
176965
|
|
|
176219
176966
|
// ../serve-cli/src/client.ts
|
|
@@ -176510,8 +177257,16 @@ var ServeCliClient = class {
|
|
|
176510
177257
|
const { bytes: bytes2, gzip } = encodePublishBody(publishReleaseBody(payload, meta, draft));
|
|
176511
177258
|
const headers2 = { ...this.ctrlHeaders(), ...gzip ? { "content-encoding": "gzip" } : {} };
|
|
176512
177259
|
const res = await this.request("control", "POST", "/v1/admin/release", { rawBody: bytes2, headers: headers2 });
|
|
176513
|
-
|
|
176514
|
-
|
|
177260
|
+
const refusal = res.json;
|
|
177261
|
+
const decodedOverPlainCap = res.status === 413 && refusal?.error === "payload_too_large" && refusal.limit === MAX_PUBLISH_BODY_BYTES && bytes2.byteLength <= MAX_PUBLISH_BODY_BYTES;
|
|
177262
|
+
if (gzip && (res.status === 400 && refusal?.error === "bad_json" || decodedOverPlainCap)) {
|
|
177263
|
+
const json6 = {
|
|
177264
|
+
code: "compressed_publish_unsupported",
|
|
177265
|
+
error: "compressed_publish_unsupported",
|
|
177266
|
+
hint: "this body is over the plain publish cap, and the plane did not accept it compressed: either the plane predates compressed publish bodies (it needs a serve deploy), or this is a self-serve credential, which keeps the plain 8 MB cap",
|
|
177267
|
+
sentBytes: bytes2.byteLength,
|
|
177268
|
+
...typeof refusal?.bytes === "number" ? { planeCountedBytes: refusal.bytes } : {}
|
|
177269
|
+
};
|
|
176515
177270
|
return { ...res, json: json6, text: JSON.stringify(json6) };
|
|
176516
177271
|
}
|
|
176517
177272
|
return res;
|
|
@@ -178287,8 +179042,8 @@ var str9 = (v2) => typeof v2 === "string" ? v2 : void 0;
|
|
|
178287
179042
|
var num3 = (v2) => typeof v2 === "string" && v2 !== "" && Number.isFinite(Number(v2)) ? Number(v2) : void 0;
|
|
178288
179043
|
function embeddedTemplateCatalog() {
|
|
178289
179044
|
return availableTemplates().map((name) => {
|
|
178290
|
-
const path2 =
|
|
178291
|
-
const meta = JSON.parse(
|
|
179045
|
+
const path2 = join87(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
179046
|
+
const meta = JSON.parse(readFileSync103(path2, "utf8"));
|
|
178292
179047
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
178293
179048
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
178294
179049
|
}
|
|
@@ -178848,6 +179603,13 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
178848
179603
|
conflict, never overwritten. --content records the
|
|
178849
179604
|
purchases app as wixIap in the app's config.ts.
|
|
178850
179605
|
No build, signing or repo checkout. Guide: himi docs iap-products
|
|
179606
|
+
himi store iap screenshots --manifest <file> --content <app dir> [--profile <name>] [--out-dir <dir>]
|
|
179607
|
+
[--only <productId,\u2026>] [--force] [--dry-run] [--json]
|
|
179608
|
+
render each product's purchase screen from the app, as a
|
|
179609
|
+
signed-in member sees it on a bound iPhone (Apple price, buy
|
|
179610
|
+
button), save it at 1290\xD72796 and name it as the item's
|
|
179611
|
+
reviewScreenshot. --profile reads Apple's price (read-only)
|
|
179612
|
+
and skips live products. Guide: himi docs iap-products
|
|
178851
179613
|
himi logout [--target <t>] clear the stored control token for a target
|
|
178852
179614
|
himi notify setup --content <dir> [--target wix] [--yes] [--no-push-setup]
|
|
178853
179615
|
Optional Branded/Ping setup. Prompts for site, native IDs and APNs key file.
|
|
@@ -179158,7 +179920,7 @@ var COMMANDS2 = [
|
|
|
179158
179920
|
{ name: "visibility", summary: "read (no value) or set whether the public registry (/v1/apps + the Himi Player picker) LISTS the app. `public` lists it for everyone; `unlisted` hides it from listings while direct reads by app id \u2014 deep links, previews \u2014 keep working. App from --app or the content dir. Setting it needs no republish.", required: "[public|unlisted] [--app <a>] [--content <dir>] (--control-token)" },
|
|
179159
179921
|
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | brandy | base44 | player | demo-app) and defaults to the content package's himalaya.content.json `shell` (templates carry the one they were written for), else branded-lite. The per-app shells ADD the release's declared capabilities to the binary, while Himi Player and demo-app refuse a release declaring one they lack; `--plan` previews it without building; `brandy` is the site shell \u2014 the customer's own website as native-framed tabs. `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo --site <id>` reuses an existing customer ad-hoc profile and certificate for iOS; requires an owned site and a completed personal signing binding. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|brandy|base44|player|demo-app] [--signing wix-managed|byo] [--site <id>] [--android-signing qa-keystore|wix-keystore|debug] [--borrow-ios-id <bundleId>] [--no-wait] [--force] [--plan] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
179160
179922
|
{ name: "testflight", summary: 'build, sign and upload an app to TestFlight (internal testers \u2014 no Beta App Review), then WAIT until App Store Connect finishes processing it. Sugar for `store upload --track testflight`. Prompts first: a build number is consumed permanently on a real Apple account and cannot be reused \u2014 `--yes` for CI, `--dry-run` to see the plan without touching anything. The wait is the real check, not a nicety: fastlane prints "Successfully uploaded" for a binary App Store Connect then rejects in processing, and a rejected binary leaves NO build record at all (the reason is emailed). Public App Store review is deliberately NOT automatable here \u2014 `--track appstore` is refused; use /submit-ios-app when you mean to go public', required: "<app> [--track testflight|internal] [--profile <name>] [--yes] [--dry-run] [--skip-build] [--no-wait] [--json]" },
|
|
179161
|
-
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo. `iap draft|plan|apply|status|connect` registers an app owner's digital products as in-app purchases (non-consumables, or consumable price tiers): draft reads the Wix catalog and writes the manifest, plan and status only read, apply is the one App Store mutation boundary, connect readies the Wix site to sell them (purchases app, In-App Purchase key, appleIAP provider, product mappings; --preview-tag routes only its Serve calls to a deploy preview), and none of them builds, signs or needs a checkout (`himi docs iap-products`)", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>] | iap draft --site <msid> --profile <n> --apple-app <id> --bundle <id> --base-territory <t> --out <f> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <f>] [--report <f>] [--json] | iap plan --manifest <f> --profile <n> --out <f> [--json] | iap apply --plan <f> --profile <n> --out <f> [--yes] [--limit <n>] [--json] | iap status --manifest <f> --profile <n> [--out <f>] [--json] | iap connect --manifest <f> --profile <n> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <f>] [--json]" },
|
|
179923
|
+
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo. `iap draft|plan|apply|status|connect|screenshots` registers an app owner's digital products as in-app purchases (non-consumables, or consumable price tiers): draft reads the Wix catalog and writes the manifest, plan and status only read, apply is the one App Store mutation boundary, connect readies the Wix site to sell them (purchases app, In-App Purchase key, appleIAP provider, product mappings; --preview-tag routes only its Serve calls to a deploy preview), screenshots renders each product's purchase screen from the app (--content) as a bound iPhone shows it to a signed-in member and names the 1290\xD72796 PNG as the item's App Review screenshot, and none of them builds, signs or needs a checkout (`himi docs iap-products`)", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>] | iap draft --site <msid> --profile <n> --apple-app <id> --bundle <id> --base-territory <t> --out <f> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <f>] [--report <f>] [--json] | iap plan --manifest <f> --profile <n> --out <f> [--json] | iap apply --plan <f> --profile <n> --out <f> [--yes] [--limit <n>] [--json] | iap status --manifest <f> --profile <n> [--out <f>] [--json] | iap connect --manifest <f> --profile <n> [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <f>] [--json] | iap screenshots --manifest <f> --content <dir> [--profile <n>] [--out-dir <d>] [--only <id,\u2026>] [--force] [--dry-run] [--json]" },
|
|
179162
179924
|
{ name: "guide", summary: "print the Himalaya overview + headless dev loop + available topics (offline)", required: "[--json]" },
|
|
179163
179925
|
{ name: "docs", summary: "print bundled/verified cached guides offline; status reports kit identity; refresh downloads compatible reference content independently of CLI without changing app source", required: "[<topic>|catalog [kind]|status|refresh] [--pin <version|digest>] [--unpin] [--no-network] [--json]" },
|
|
179164
179926
|
{ name: "components", summary: "print the SDUI component vocabulary + props; a name = that component (offline)", required: "[<Name>] [--json]" },
|
|
@@ -179175,7 +179937,7 @@ var COMMANDS2 = [
|
|
|
179175
179937
|
];
|
|
179176
179938
|
function cliVersion() {
|
|
179177
179939
|
try {
|
|
179178
|
-
return JSON.parse(
|
|
179940
|
+
return JSON.parse(readFileSync103(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
179179
179941
|
} catch {
|
|
179180
179942
|
return "unknown";
|
|
179181
179943
|
}
|
|
@@ -179226,18 +179988,18 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
179226
179988
|
}
|
|
179227
179989
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
179228
179990
|
function execNpmConfig(file2, args, options) {
|
|
179229
|
-
return new Promise((
|
|
179230
|
-
execFile2(file2, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) :
|
|
179991
|
+
return new Promise((resolve65, reject) => {
|
|
179992
|
+
execFile2(file2, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve65(String(stdout)));
|
|
179231
179993
|
});
|
|
179232
179994
|
}
|
|
179233
179995
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
179234
179996
|
async function scopedRegistryBefore(lookup3, deadline, onTimeout) {
|
|
179235
179997
|
let cancel = () => {
|
|
179236
179998
|
};
|
|
179237
|
-
const expired = new Promise((
|
|
179999
|
+
const expired = new Promise((resolve65) => {
|
|
179238
180000
|
const timer = setTimeout(() => {
|
|
179239
180001
|
onTimeout?.();
|
|
179240
|
-
|
|
180002
|
+
resolve65(void 0);
|
|
179241
180003
|
}, Math.max(0, deadline - Date.now()));
|
|
179242
180004
|
cancel = () => clearTimeout(timer);
|
|
179243
180005
|
});
|
|
@@ -179300,18 +180062,18 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
179300
180062
|
}
|
|
179301
180063
|
function packageVersion(path2) {
|
|
179302
180064
|
try {
|
|
179303
|
-
const version4 = JSON.parse(
|
|
180065
|
+
const version4 = JSON.parse(readFileSync103(path2, "utf8")).version;
|
|
179304
180066
|
return typeof version4 === "string" && version4 ? version4 : void 0;
|
|
179305
180067
|
} catch {
|
|
179306
180068
|
return void 0;
|
|
179307
180069
|
}
|
|
179308
180070
|
}
|
|
179309
180071
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
179310
|
-
let dir =
|
|
180072
|
+
let dir = resolve64(fromDir);
|
|
179311
180073
|
for (; ; ) {
|
|
179312
|
-
const version4 = packageVersion(
|
|
180074
|
+
const version4 = packageVersion(join87(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
179313
180075
|
if (version4) return { version: version4, source: "local" };
|
|
179314
|
-
const parent =
|
|
180076
|
+
const parent = dirname48(dir);
|
|
179315
180077
|
if (parent === dir) break;
|
|
179316
180078
|
dir = parent;
|
|
179317
180079
|
}
|
|
@@ -179319,7 +180081,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
179319
180081
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
179320
180082
|
try {
|
|
179321
180083
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
179322
|
-
const version4 = root ? packageVersion(
|
|
180084
|
+
const version4 = root ? packageVersion(join87(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
179323
180085
|
return version4 ? { version: version4, source: "global" } : {};
|
|
179324
180086
|
} catch {
|
|
179325
180087
|
return {};
|
|
@@ -179366,11 +180128,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
179366
180128
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
179367
180129
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
179368
180130
|
function updateCachePath(env = process.env) {
|
|
179369
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
180131
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join87(homedir14(), ".himalaya", "update-check.json");
|
|
179370
180132
|
}
|
|
179371
180133
|
function readUpdateCache(path2) {
|
|
179372
180134
|
try {
|
|
179373
|
-
const parsed = JSON.parse(
|
|
180135
|
+
const parsed = JSON.parse(readFileSync103(path2, "utf8"));
|
|
179374
180136
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
179375
180137
|
} catch {
|
|
179376
180138
|
return {};
|
|
@@ -179378,7 +180140,7 @@ function readUpdateCache(path2) {
|
|
|
179378
180140
|
}
|
|
179379
180141
|
function writeUpdateCache(path2, cache) {
|
|
179380
180142
|
try {
|
|
179381
|
-
mkdirSync42(
|
|
180143
|
+
mkdirSync42(dirname48(path2), { recursive: true, mode: 448 });
|
|
179382
180144
|
writeFileSync39(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
|
|
179383
180145
|
} catch {
|
|
179384
180146
|
}
|
|
@@ -179439,12 +180201,12 @@ function createUpdateRunner(spawn8 = spawnSync5) {
|
|
|
179439
180201
|
},
|
|
179440
180202
|
installedVersion: () => {
|
|
179441
180203
|
const root = globalNodeModulesRoot();
|
|
179442
|
-
return root ? packageVersion(
|
|
180204
|
+
return root ? packageVersion(join87(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
179443
180205
|
},
|
|
179444
180206
|
reexec: (argv) => {
|
|
179445
180207
|
const root = globalNodeModulesRoot();
|
|
179446
|
-
const entry = root ?
|
|
179447
|
-
if (!entry || !
|
|
180208
|
+
const entry = root ? join87(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
180209
|
+
if (!entry || !existsSync82(entry)) return void 0;
|
|
179448
180210
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
179449
180211
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
179450
180212
|
stdio: "inherit",
|
|
@@ -179491,7 +180253,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
179491
180253
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
179492
180254
|
let content;
|
|
179493
180255
|
try {
|
|
179494
|
-
content =
|
|
180256
|
+
content = readFileSync103(path2, "utf8");
|
|
179495
180257
|
} catch {
|
|
179496
180258
|
continue;
|
|
179497
180259
|
}
|
|
@@ -179514,7 +180276,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
179514
180276
|
const mine = lockStamp(now);
|
|
179515
180277
|
const readLock = (path2) => {
|
|
179516
180278
|
try {
|
|
179517
|
-
return
|
|
180279
|
+
return readFileSync103(path2, "utf8");
|
|
179518
180280
|
} catch {
|
|
179519
180281
|
return void 0;
|
|
179520
180282
|
}
|
|
@@ -179529,13 +180291,13 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
179529
180291
|
};
|
|
179530
180292
|
const removeIfMine = (path2) => {
|
|
179531
180293
|
try {
|
|
179532
|
-
if (readLock(path2) === mine)
|
|
180294
|
+
if (readLock(path2) === mine) rmSync23(path2, { force: true });
|
|
179533
180295
|
} catch {
|
|
179534
180296
|
}
|
|
179535
180297
|
};
|
|
179536
180298
|
const release2 = () => removeIfMine(lockPath);
|
|
179537
180299
|
try {
|
|
179538
|
-
mkdirSync42(
|
|
180300
|
+
mkdirSync42(dirname48(lockPath), { recursive: true, mode: 448 });
|
|
179539
180301
|
} catch {
|
|
179540
180302
|
return () => {
|
|
179541
180303
|
};
|
|
@@ -179552,7 +180314,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
179552
180314
|
hooks.underBreakLock?.();
|
|
179553
180315
|
if (current === void 0) return tryCreate(lockPath) ? release2 : void 0;
|
|
179554
180316
|
if (!isAbandoned(current)) return void 0;
|
|
179555
|
-
|
|
180317
|
+
rmSync23(lockPath, { force: true });
|
|
179556
180318
|
return tryCreate(lockPath) ? release2 : void 0;
|
|
179557
180319
|
} finally {
|
|
179558
180320
|
removeIfMine(breakPath);
|
|
@@ -179648,7 +180410,7 @@ function createTrimValidator(deps = {}, spawnFn = spawn7) {
|
|
|
179648
180410
|
return { code, counts, ...errors ? { errors } : {}, ...code !== 0 ? { tail: said.slice(-4e3) } : {} };
|
|
179649
180411
|
};
|
|
179650
180412
|
return async (dir, opts = {}) => {
|
|
179651
|
-
const argv = ["validate", "--content",
|
|
180413
|
+
const argv = ["validate", "--content", resolve64(dir), "--strict", "--skip-version-check"];
|
|
179652
180414
|
if (!opts.fresh) {
|
|
179653
180415
|
const out2 = [];
|
|
179654
180416
|
const err = [];
|
|
@@ -180106,7 +180868,7 @@ function executableOnPath(name, env = process.env) {
|
|
|
180106
180868
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
180107
180869
|
for (const dir of entries) {
|
|
180108
180870
|
for (const suffix of suffixes) {
|
|
180109
|
-
const candidate =
|
|
180871
|
+
const candidate = join87(dir, `${name}${suffix}`);
|
|
180110
180872
|
try {
|
|
180111
180873
|
if (!statSync23(candidate).isFile()) continue;
|
|
180112
180874
|
if (process.platform !== "win32") accessSync(candidate, constants5.X_OK);
|
|
@@ -180215,7 +180977,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
180215
180977
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths2(), paths_exports));
|
|
180216
180978
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
180217
180979
|
const iosYmlPath = iosProjectYml2(app);
|
|
180218
|
-
const iosYml =
|
|
180980
|
+
const iosYml = existsSync82(iosYmlPath) ? readFileSync103(iosYmlPath, "utf8") : "";
|
|
180219
180981
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
180220
180982
|
if (!optedIn) {
|
|
180221
180983
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -180229,13 +180991,13 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
180229
180991
|
}
|
|
180230
180992
|
function readConfigSource(dir) {
|
|
180231
180993
|
try {
|
|
180232
|
-
return
|
|
180994
|
+
return readFileSync103(join87(dir, "config.ts"), "utf8");
|
|
180233
180995
|
} catch {
|
|
180234
180996
|
return null;
|
|
180235
180997
|
}
|
|
180236
180998
|
}
|
|
180237
180999
|
function writePngFile(path2, base64) {
|
|
180238
|
-
mkdirSync42(
|
|
181000
|
+
mkdirSync42(dirname48(path2), { recursive: true });
|
|
180239
181001
|
writeFileSync39(path2, Buffer.from(base64, "base64"));
|
|
180240
181002
|
return path2;
|
|
180241
181003
|
}
|
|
@@ -180282,8 +181044,8 @@ function keptPlan(kept) {
|
|
|
180282
181044
|
var NoBase44SlotError = class extends Error {
|
|
180283
181045
|
};
|
|
180284
181046
|
async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {}) {
|
|
180285
|
-
const dir =
|
|
180286
|
-
if (
|
|
181047
|
+
const dir = resolve64(parentDir, name);
|
|
181048
|
+
if (existsSync82(join87(dir, "himalaya.content.json"))) {
|
|
180287
181049
|
throw new Error(`content package already exists at ${dir}`);
|
|
180288
181050
|
}
|
|
180289
181051
|
const r2 = await c2.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -180298,7 +181060,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {})
|
|
|
180298
181060
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
180299
181061
|
}
|
|
180300
181062
|
function contentDir(flags) {
|
|
180301
|
-
return
|
|
181063
|
+
return resolve64(str9(flags.content) ?? process.cwd());
|
|
180302
181064
|
}
|
|
180303
181065
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
180304
181066
|
const text9 = {};
|
|
@@ -180329,7 +181091,7 @@ function symlinkDestinationIssue(dest) {
|
|
|
180329
181091
|
function restoreDestinationIssue(dest, force) {
|
|
180330
181092
|
const link = symlinkDestinationIssue(dest);
|
|
180331
181093
|
if (link) return link;
|
|
180332
|
-
if (!
|
|
181094
|
+
if (!existsSync82(dest)) return null;
|
|
180333
181095
|
if (!statSync23(dest).isDirectory()) {
|
|
180334
181096
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
180335
181097
|
}
|
|
@@ -180342,10 +181104,10 @@ function restoreDestinationIssue(dest, force) {
|
|
|
180342
181104
|
return null;
|
|
180343
181105
|
}
|
|
180344
181106
|
function isHimalayaMonorepoCheckout(start) {
|
|
180345
|
-
let dir =
|
|
181107
|
+
let dir = resolve64(start);
|
|
180346
181108
|
for (; ; ) {
|
|
180347
|
-
if (
|
|
180348
|
-
const parent =
|
|
181109
|
+
if (existsSync82(join87(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync82(join87(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
181110
|
+
const parent = dirname48(dir);
|
|
180349
181111
|
if (parent === dir) return false;
|
|
180350
181112
|
dir = parent;
|
|
180351
181113
|
}
|
|
@@ -180382,7 +181144,7 @@ function shellShaDivergenceWarnings(jobs) {
|
|
|
180382
181144
|
}
|
|
180383
181145
|
async function templatePublishName(sourceDir) {
|
|
180384
181146
|
const id = await appId(sourceDir);
|
|
180385
|
-
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ?
|
|
181147
|
+
return IDENTITY_SENTINELS.some((s2) => id.includes(s2)) ? basename21(sourceDir) : id;
|
|
180386
181148
|
}
|
|
180387
181149
|
function templateNameError(name, from) {
|
|
180388
181150
|
if (name.startsWith(TEMPLATE_APP_PREFIX)) {
|
|
@@ -180404,8 +181166,8 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
180404
181166
|
const forBuild = Object.fromEntries(
|
|
180405
181167
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
180406
181168
|
);
|
|
180407
|
-
const repoRoot2 =
|
|
180408
|
-
const root =
|
|
181169
|
+
const repoRoot2 = resolve64(fileURLToPath29(new URL("../../..", import.meta.url)));
|
|
181170
|
+
const root = join87(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
180409
181171
|
const stillRunning = (pid) => {
|
|
180410
181172
|
try {
|
|
180411
181173
|
process.kill(pid, 0);
|
|
@@ -180419,35 +181181,35 @@ function materializeForPreview(appDir3, slug, displayName2) {
|
|
|
180419
181181
|
if (!entry.isDirectory()) continue;
|
|
180420
181182
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
180421
181183
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
180422
|
-
|
|
181184
|
+
rmSync23(join87(root, entry.name), { recursive: true, force: true });
|
|
180423
181185
|
}
|
|
180424
181186
|
}
|
|
180425
181187
|
} catch {
|
|
180426
181188
|
}
|
|
180427
|
-
const dest =
|
|
180428
|
-
|
|
181189
|
+
const dest = join87(root, `${slug}-${process.pid}`);
|
|
181190
|
+
rmSync23(dest, { recursive: true, force: true });
|
|
180429
181191
|
mkdirSync42(dest, { recursive: true });
|
|
180430
181192
|
try {
|
|
180431
181193
|
materializeSource(forBuild, displayName2, dest, slug);
|
|
180432
181194
|
} catch (e2) {
|
|
180433
|
-
|
|
181195
|
+
rmSync23(dest, { recursive: true, force: true });
|
|
180434
181196
|
throw e2;
|
|
180435
181197
|
}
|
|
180436
181198
|
return dest;
|
|
180437
181199
|
}
|
|
180438
181200
|
async function appId(dir) {
|
|
180439
181201
|
try {
|
|
180440
|
-
const { readFileSync:
|
|
180441
|
-
const m2 = JSON.parse(
|
|
181202
|
+
const { readFileSync: readFileSync104 } = await import("node:fs");
|
|
181203
|
+
const m2 = JSON.parse(readFileSync104(join87(dir, "himalaya.content.json"), "utf8"));
|
|
180442
181204
|
if (m2.name) return m2.name;
|
|
180443
181205
|
} catch {
|
|
180444
181206
|
}
|
|
180445
|
-
return
|
|
181207
|
+
return basename21(dir);
|
|
180446
181208
|
}
|
|
180447
181209
|
async function contentVisibility(dir) {
|
|
180448
181210
|
try {
|
|
180449
|
-
const { readFileSync:
|
|
180450
|
-
const m2 = JSON.parse(
|
|
181211
|
+
const { readFileSync: readFileSync104 } = await import("node:fs");
|
|
181212
|
+
const m2 = JSON.parse(readFileSync104(join87(dir, "himalaya.content.json"), "utf8"));
|
|
180451
181213
|
if (m2.visibility === "public" || m2.visibility === "unlisted") return m2.visibility;
|
|
180452
181214
|
} catch {
|
|
180453
181215
|
}
|
|
@@ -180717,7 +181479,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
180717
181479
|
return 0;
|
|
180718
181480
|
}
|
|
180719
181481
|
case "agent-init": {
|
|
180720
|
-
const dir =
|
|
181482
|
+
const dir = resolve64(str9(flags.dir) ?? process.cwd());
|
|
180721
181483
|
const { seedAgentFiles: seedAgentFiles2, NotAContentPackage: NotAContentPackage2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
180722
181484
|
let res;
|
|
180723
181485
|
try {
|
|
@@ -180739,7 +181501,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
180739
181501
|
...res.removed.length ? { removed: res.removed, note: "older copies at the app root, moved to .himi/legacy-agent-files/ (a backup, in case one became app code) \u2014 the current ones live in .agents/skills/himalaya/" } : {},
|
|
180740
181502
|
// In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
|
|
180741
181503
|
// hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
|
|
180742
|
-
...
|
|
181504
|
+
...existsSync82(join87(dir, ".himi", "attestations", "latest.json")) ? { next: "if `himi push` then refuses the attestation as stale, re-run `himi test` \u2014 in a git checkout this refresh changed the tree it covered" } : {},
|
|
180743
181505
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
180744
181506
|
portalUrl: idx.portalUrl
|
|
180745
181507
|
});
|
|
@@ -180762,7 +181524,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
180762
181524
|
try {
|
|
180763
181525
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
180764
181526
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
180765
|
-
out2 =
|
|
181527
|
+
out2 = mkdtempSync6(join87(tmpdir7(), "himi-ux-record-"));
|
|
180766
181528
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
180767
181529
|
const outcome = await buildReleaseFromContent2(dir, out2, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
180768
181530
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -180775,7 +181537,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
180775
181537
|
return null;
|
|
180776
181538
|
} finally {
|
|
180777
181539
|
if (out2 !== void 0) try {
|
|
180778
|
-
|
|
181540
|
+
rmSync23(out2, { recursive: true, force: true });
|
|
180779
181541
|
} catch {
|
|
180780
181542
|
}
|
|
180781
181543
|
}
|
|
@@ -180941,7 +181703,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
180941
181703
|
let js2;
|
|
180942
181704
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
180943
181705
|
try {
|
|
180944
|
-
js2 =
|
|
181706
|
+
js2 = readFileSync103(join87(outDir, candidate), "utf8");
|
|
180945
181707
|
break;
|
|
180946
181708
|
} catch {
|
|
180947
181709
|
}
|
|
@@ -180972,7 +181734,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
180972
181734
|
}
|
|
180973
181735
|
return { families, source: "dist/bundles" };
|
|
180974
181736
|
}
|
|
180975
|
-
var boardOpen = (dir) =>
|
|
181737
|
+
var boardOpen = (dir) => existsSync82(join87(dir, ".himi", "studio", "index.html"));
|
|
180976
181738
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
180977
181739
|
async function leaveForBoard(dir, record2, value) {
|
|
180978
181740
|
if (!boardOpen(dir)) return;
|
|
@@ -180996,7 +181758,7 @@ async function liveMapFor(dir) {
|
|
|
180996
181758
|
}
|
|
180997
181759
|
var commandScratch = new AsyncLocalStorage2();
|
|
180998
181760
|
function commandScratchDir(prefix) {
|
|
180999
|
-
const dir =
|
|
181761
|
+
const dir = mkdtempSync6(join87(tmpdir7(), prefix));
|
|
181000
181762
|
commandScratch.getStore()?.push(dir);
|
|
181001
181763
|
return dir;
|
|
181002
181764
|
}
|
|
@@ -181007,7 +181769,7 @@ async function run(argv, io2 = defaultIO, deps = {}) {
|
|
|
181007
181769
|
code = await commandScratch.run(scratch, () => runCommand(argv, io2, deps));
|
|
181008
181770
|
} finally {
|
|
181009
181771
|
for (const dir of scratch) try {
|
|
181010
|
-
|
|
181772
|
+
rmSync23(dir, { recursive: true, force: true });
|
|
181011
181773
|
} catch {
|
|
181012
181774
|
}
|
|
181013
181775
|
}
|
|
@@ -181307,7 +182069,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
181307
182069
|
return 2;
|
|
181308
182070
|
}
|
|
181309
182071
|
const template = str9(flags.template);
|
|
181310
|
-
const parentDir =
|
|
182072
|
+
const parentDir = resolve64(str9(flags.dir) ?? process.cwd());
|
|
181311
182073
|
const base44AppId = flags["base44-app-id"] === void 0 ? void 0 : String(flags["base44-app-id"]);
|
|
181312
182074
|
const base44AppUrl = flags["base44-app-url"] === void 0 ? void 0 : String(flags["base44-app-url"]);
|
|
181313
182075
|
if (base44AppUrl !== void 0) {
|
|
@@ -181350,7 +182112,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
181350
182112
|
const owed = openApprovals2(readApprovals2(dir).events).length;
|
|
181351
182113
|
next.push(`carried the planning journal into the app (${carried.join(", ")}${owed ? `; ${owed} approval${owed === 1 ? "" : "s"} still owed` : ""}) \u2014 \`himi progress --brief\` there shows it`);
|
|
181352
182114
|
}
|
|
181353
|
-
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) =>
|
|
182115
|
+
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync82(join87(parentDir, f2)));
|
|
181354
182116
|
if (planInParent.length) {
|
|
181355
182117
|
next.push(`${planInParent.join(" and ")} in ${parentDir} ${planInParent.length > 1 ? "are" : "is"} not the app's \u2014 if that is the approved plan, move it over the template's boilerplate in ${dir}`);
|
|
181356
182118
|
}
|
|
@@ -181511,13 +182273,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181511
182273
|
if (adding) {
|
|
181512
182274
|
const from = str9(flags.from);
|
|
181513
182275
|
if (!from) throw new TrimRefusal2('--add <id> needs --from <file> holding the whole new SCREENS entry (` "<id>": { "screenId": "<id>", \u2026 },`)');
|
|
181514
|
-
print(adopt.addScreen(dir, adding,
|
|
182276
|
+
print(adopt.addScreen(dir, adding, readFileSync103(from, "utf8"), { parent: str9(flags.parent), tab: str9(flags.tab), displayName: str9(flags["display-name"]) }));
|
|
181515
182277
|
return 0;
|
|
181516
182278
|
}
|
|
181517
182279
|
if (target) {
|
|
181518
182280
|
const from = str9(flags.from);
|
|
181519
182281
|
if (!from) throw new TrimRefusal2("--write <id> needs --from <file> holding the whole entry, as --show prints it");
|
|
181520
|
-
print(adopt.replaceScreen(dir, target,
|
|
182282
|
+
print(adopt.replaceScreen(dir, target, readFileSync103(from, "utf8")));
|
|
181521
182283
|
return 0;
|
|
181522
182284
|
}
|
|
181523
182285
|
if (show) {
|
|
@@ -181599,7 +182361,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181599
182361
|
const { keepFromSpec: keepFromSpec2 } = await Promise.resolve().then(() => (init_template_adopt(), template_adopt_exports));
|
|
181600
182362
|
const dir = contentDir(flags);
|
|
181601
182363
|
try {
|
|
181602
|
-
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ??
|
|
182364
|
+
const spec = keepFromSpec2(dir, str9(flags["from-spec"]) ?? join87(dir, "SPEC.md"));
|
|
181603
182365
|
const own5 = typeof keep === "string" ? keep.split(",").map((k2) => k2.trim()).filter(Boolean) : [];
|
|
181604
182366
|
keep = [.../* @__PURE__ */ new Set([...spec.keep, ...own5])].join(",");
|
|
181605
182367
|
fromSpec = { fromSpec: {
|
|
@@ -181640,7 +182402,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181640
182402
|
const result = { ...outcome.result, ...fromSpec };
|
|
181641
182403
|
const adoptDir = contentDir(flags);
|
|
181642
182404
|
const kept = flags["dry-run"] !== true && (outcome.code === 0 || outcome.result.forcedKeep === true);
|
|
181643
|
-
if (kept &&
|
|
182405
|
+
if (kept && existsSync82(join87(adoptDir, adoptBits.ADOPT_FILE))) {
|
|
181644
182406
|
try {
|
|
181645
182407
|
const inv = adoptBits.inspectApp(adoptDir);
|
|
181646
182408
|
adoptBits.writeInventory(adoptDir, inv, { companions: "if-missing" });
|
|
@@ -181665,11 +182427,11 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181665
182427
|
return 2;
|
|
181666
182428
|
}
|
|
181667
182429
|
}
|
|
181668
|
-
const appDir3 =
|
|
181669
|
-
const sourceDir =
|
|
182430
|
+
const appDir3 = resolve64(str9(flags.dir) ?? process.cwd());
|
|
182431
|
+
const sourceDir = resolve64(str9(flags["source-dir"]) ?? appDir3);
|
|
181670
182432
|
let meta;
|
|
181671
182433
|
try {
|
|
181672
|
-
meta = JSON.parse(
|
|
182434
|
+
meta = JSON.parse(readFileSync103(join87(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
181673
182435
|
} catch {
|
|
181674
182436
|
io2.error(JSON.stringify({ error: `no ${TEMPLATE_META_FILE} in ${sourceDir} \u2014 a template must declare { title, description, tags } to be published`, hint: `add ${TEMPLATE_META_FILE} next to himalaya.content.json (or pass --source-dir <dir>)` }));
|
|
181675
182437
|
return 2;
|
|
@@ -181679,7 +182441,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181679
182441
|
return 2;
|
|
181680
182442
|
}
|
|
181681
182443
|
try {
|
|
181682
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
182444
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync103(join87(sourceDir, "tokens.json"), "utf8")));
|
|
181683
182445
|
meta = { ...appearance, ...meta };
|
|
181684
182446
|
} catch {
|
|
181685
182447
|
}
|
|
@@ -181701,14 +182463,14 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181701
182463
|
const force = flags.force === true;
|
|
181702
182464
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
181703
182465
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
181704
|
-
const out2 =
|
|
182466
|
+
const out2 = mkdtempSync6(join87(tmpdir7(), "himi-template-"));
|
|
181705
182467
|
publishScratch.push(out2);
|
|
181706
182468
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
181707
182469
|
const outcome = await buildReleaseFromContent2(buildDir, out2, {
|
|
181708
182470
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
181709
182471
|
collect: { lint: true, strict }
|
|
181710
182472
|
});
|
|
181711
|
-
const scaffoldSourceFindings =
|
|
182473
|
+
const scaffoldSourceFindings = resolve64(sourceDir) === resolve64(appDir3) ? [] : [
|
|
181712
182474
|
...(await Promise.resolve().then(() => (init_capabilities(), capabilities_exports))).capabilityConfigFindings(sourceDir, buildDir),
|
|
181713
182475
|
...tokenColorIssues(sourceDir),
|
|
181714
182476
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
@@ -181754,13 +182516,13 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181754
182516
|
}));
|
|
181755
182517
|
return 1;
|
|
181756
182518
|
}
|
|
181757
|
-
const iconPath = str9(flags.icon) ?
|
|
182519
|
+
const iconPath = str9(flags.icon) ? resolve64(str9(flags.icon)) : templateIconPath(name);
|
|
181758
182520
|
let iconHash;
|
|
181759
182521
|
if (iconPath) {
|
|
181760
182522
|
try {
|
|
181761
|
-
const bytes2 =
|
|
182523
|
+
const bytes2 = readFileSync103(iconPath);
|
|
181762
182524
|
payload.icon = bytes2.toString("base64");
|
|
181763
|
-
iconHash =
|
|
182525
|
+
iconHash = createHash45("sha256").update(bytes2).digest("hex");
|
|
181764
182526
|
} catch {
|
|
181765
182527
|
}
|
|
181766
182528
|
}
|
|
@@ -181936,7 +182698,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
181936
182698
|
} finally {
|
|
181937
182699
|
for (const dir of publishScratch) {
|
|
181938
182700
|
try {
|
|
181939
|
-
|
|
182701
|
+
rmSync23(dir, { recursive: true, force: true });
|
|
181940
182702
|
} catch (e2) {
|
|
181941
182703
|
io2.error(JSON.stringify({ warning: `could not remove temp dir ${dir}: ${e2.message}` }));
|
|
181942
182704
|
}
|
|
@@ -182062,7 +182824,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
182062
182824
|
const path2 = dpxSessionTokenPath();
|
|
182063
182825
|
let raw;
|
|
182064
182826
|
try {
|
|
182065
|
-
raw =
|
|
182827
|
+
raw = readFileSync103(path2, "utf8");
|
|
182066
182828
|
} catch {
|
|
182067
182829
|
throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
|
|
182068
182830
|
}
|
|
@@ -182193,11 +182955,11 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
182193
182955
|
return 1;
|
|
182194
182956
|
}
|
|
182195
182957
|
const { himiPluginFiles: himiPluginFiles2 } = await Promise.resolve().then(() => (init_claude_plugin(), claude_plugin_exports));
|
|
182196
|
-
const dir =
|
|
182958
|
+
const dir = resolve64(out2);
|
|
182197
182959
|
const files = himiPluginFiles2(skills.skillMd);
|
|
182198
182960
|
for (const f2 of files) {
|
|
182199
|
-
mkdirSync42(
|
|
182200
|
-
writeFileSync39(
|
|
182961
|
+
mkdirSync42(dirname48(join87(dir, f2.path)), { recursive: true });
|
|
182962
|
+
writeFileSync39(join87(dir, f2.path), f2.text);
|
|
182201
182963
|
}
|
|
182202
182964
|
print({ ok: true, dir, files: files.map((f2) => f2.path), next: [`claude plugin validate ${dir}`, `claude --plugin-dir ${dir}`] });
|
|
182203
182965
|
return 0;
|
|
@@ -182207,22 +182969,22 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
182207
182969
|
run,
|
|
182208
182970
|
version: cliVersion(),
|
|
182209
182971
|
withFiles: flags["with-files"] === true,
|
|
182210
|
-
...process.env.HIMI_WORKSPACE ? { workspace:
|
|
182972
|
+
...process.env.HIMI_WORKSPACE ? { workspace: resolve64(process.env.HIMI_WORKSPACE) } : {}
|
|
182211
182973
|
});
|
|
182212
182974
|
return 0;
|
|
182213
182975
|
}
|
|
182214
182976
|
case "studio": {
|
|
182215
182977
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
182216
182978
|
const dir = contentDir(flags);
|
|
182217
|
-
if (!
|
|
182979
|
+
if (!existsSync82(join87(dir, "himalaya.content.json"))) {
|
|
182218
182980
|
io2.error(JSON.stringify({ ok: false, error: "not_a_content_package", dir, hint: "run from the app directory (or pass --content <dir>) \u2014 the board reads that package's .himi/" }));
|
|
182219
182981
|
return 2;
|
|
182220
182982
|
}
|
|
182221
182983
|
if (pos[1] === "reel") {
|
|
182222
182984
|
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
182223
|
-
const out2 =
|
|
182985
|
+
const out2 = resolve64(str9(flags.out) ?? join87(dir, ".himi", "making-of.html"));
|
|
182224
182986
|
const { html, plan } = buildReel2(dir);
|
|
182225
|
-
mkdirSync42(
|
|
182987
|
+
mkdirSync42(dirname48(out2), { recursive: true });
|
|
182226
182988
|
writeFileSync39(out2, html);
|
|
182227
182989
|
const { pathToFileURL: pathToFileURL9 } = await import("node:url");
|
|
182228
182990
|
const url2 = pathToFileURL9(out2).href;
|
|
@@ -182231,7 +182993,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
182231
182993
|
const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
|
|
182232
182994
|
openUrl2(url2);
|
|
182233
182995
|
}
|
|
182234
|
-
const handover = { file: out2, hint: `hand ${
|
|
182996
|
+
const handover = { file: out2, hint: `hand ${basename21(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` };
|
|
182235
182997
|
const report3 = {
|
|
182236
182998
|
ok: true,
|
|
182237
182999
|
file: out2,
|
|
@@ -182292,7 +183054,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182292
183054
|
} = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
182293
183055
|
const dir = contentDir(flags);
|
|
182294
183056
|
const journal2 = journalPath2(dir);
|
|
182295
|
-
const isContentPackage =
|
|
183057
|
+
const isContentPackage = existsSync82(join87(dir, "himalaya.content.json"));
|
|
182296
183058
|
const hint = isContentPackage ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
|
|
182297
183059
|
const message = pos.slice(1).join(" ").trim();
|
|
182298
183060
|
const approvalFlags = ["approve", "done", "drop"].filter((f2) => flags[f2] !== void 0);
|
|
@@ -182444,7 +183206,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182444
183206
|
case "test": {
|
|
182445
183207
|
const dir = contentDir(flags);
|
|
182446
183208
|
const structuredOutput = flags.json === true || io2.isTTY !== true;
|
|
182447
|
-
if (
|
|
183209
|
+
if (existsSync82(join87(dir, "functions"))) {
|
|
182448
183210
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
182449
183211
|
const loaded = await loadFunctionsApp2(dir);
|
|
182450
183212
|
const results = [];
|
|
@@ -182576,7 +183338,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182576
183338
|
io2.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
182577
183339
|
return 2;
|
|
182578
183340
|
}
|
|
182579
|
-
const sources = collectWorkerSources2(
|
|
183341
|
+
const sources = collectWorkerSources2(join87(dir, "tier5-src"), screen.bundleName);
|
|
182580
183342
|
if (!sources) {
|
|
182581
183343
|
io2.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
182582
183344
|
return 2;
|
|
@@ -182754,7 +183516,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182754
183516
|
const sp = await runShotsPass2({
|
|
182755
183517
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
182756
183518
|
tokens: outcome.tokens,
|
|
182757
|
-
outDir:
|
|
183519
|
+
outDir: join87(dir, ".himi", "shots"),
|
|
182758
183520
|
width: 390,
|
|
182759
183521
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
182760
183522
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -182765,7 +183527,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182765
183527
|
renderPngBatch: renderPngBatch2,
|
|
182766
183528
|
isUnserved: isUnservedRequest2,
|
|
182767
183529
|
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
182768
|
-
clearDir: (d2) =>
|
|
183530
|
+
clearDir: (d2) => rmSync23(d2, { recursive: true, force: true })
|
|
182769
183531
|
}
|
|
182770
183532
|
});
|
|
182771
183533
|
writtenShots = sp.written;
|
|
@@ -182794,7 +183556,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
182794
183556
|
releaseId: result.releaseId,
|
|
182795
183557
|
releasePayload: release2,
|
|
182796
183558
|
descriptors: attestedDescriptors,
|
|
182797
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
183559
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join87(dir, ".himi", "shots", name)])),
|
|
182798
183560
|
coverage: {
|
|
182799
183561
|
screens: crawledScreens.size,
|
|
182800
183562
|
actionsDispatched: result.actions.exercised,
|
|
@@ -182919,7 +183681,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
182919
183681
|
return 2;
|
|
182920
183682
|
}
|
|
182921
183683
|
try {
|
|
182922
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
183684
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync103(stateArg.replace(/^@/, ""), "utf8");
|
|
182923
183685
|
injectedState = JSON.parse(raw);
|
|
182924
183686
|
} catch (e2) {
|
|
182925
183687
|
io2.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e2.message}` }));
|
|
@@ -182934,7 +183696,7 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
182934
183696
|
return 2;
|
|
182935
183697
|
}
|
|
182936
183698
|
try {
|
|
182937
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
183699
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync103(inputArg.replace(/^@/, ""), "utf8");
|
|
182938
183700
|
const parsed = JSON.parse(raw);
|
|
182939
183701
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
182940
183702
|
injectedInput = parsed;
|
|
@@ -183016,11 +183778,11 @@ ${[...afterRun.next, ...testReminder ? [testReminder] : []].join("\n")}`);
|
|
|
183016
183778
|
const diagnostics = (outcome.lint ?? []).find((s2) => s2.screenId === screenId)?.issues ?? [];
|
|
183017
183779
|
let pngFile;
|
|
183018
183780
|
let attestationPngFile;
|
|
183019
|
-
const shotPath =
|
|
183781
|
+
const shotPath = join87(dir, ".himi", "shots", `${screenId}.png`);
|
|
183020
183782
|
const pngTarget = typeof flags.png === "string" ? str9(flags.png) : flags.png === true ? shotPath : void 0;
|
|
183021
183783
|
if (pngTarget && r2.pngBase64) {
|
|
183022
183784
|
pngFile = writePngFile(pngTarget, r2.pngBase64);
|
|
183023
|
-
attestationPngFile =
|
|
183785
|
+
attestationPngFile = resolve64(pngTarget) === resolve64(shotPath) ? pngFile : writePngFile(shotPath, r2.pngBase64);
|
|
183024
183786
|
}
|
|
183025
183787
|
if (renderWidth !== void 0 && r2.renderable) {
|
|
183026
183788
|
recordRenderWidth(dir, {
|
|
@@ -183367,7 +184129,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
183367
184129
|
return 2;
|
|
183368
184130
|
}
|
|
183369
184131
|
const renamed = str9(flags.name);
|
|
183370
|
-
const dest =
|
|
184132
|
+
const dest = resolve64(str9(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
183371
184133
|
const replace = flags.replace === true;
|
|
183372
184134
|
const force = replace || flags.force === true;
|
|
183373
184135
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -183375,7 +184137,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
183375
184137
|
io2.error(JSON.stringify(linked));
|
|
183376
184138
|
return 1;
|
|
183377
184139
|
}
|
|
183378
|
-
if (
|
|
184140
|
+
if (existsSync82(dest)) {
|
|
183379
184141
|
if (!statSync23(dest).isDirectory()) {
|
|
183380
184142
|
io2.error(JSON.stringify({
|
|
183381
184143
|
error: `${dest} exists and is not a directory`,
|
|
@@ -183388,7 +184150,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
183388
184150
|
io2.error(JSON.stringify({ error: `${dest} already exists and is not empty`, hint: "pass --force to write into it anyway (merging, and naming what it keeps), --replace to restore exactly what was archived, or --out/--name to land somewhere else" }));
|
|
183389
184151
|
return 1;
|
|
183390
184152
|
}
|
|
183391
|
-
if (replace && occupied && !
|
|
184153
|
+
if (replace && occupied && !existsSync82(join87(dest, "himalaya.content.json"))) {
|
|
183392
184154
|
io2.error(JSON.stringify({
|
|
183393
184155
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
183394
184156
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -183557,7 +184319,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
183557
184319
|
const manifest = outcome.manifest;
|
|
183558
184320
|
const payload = await loadReleaseFromDir(declared, out2);
|
|
183559
184321
|
const { shellQuote: shellQuote3 } = await Promise.resolve().then(() => (init_shell_quote(), shell_quote_exports));
|
|
183560
|
-
const contentRel =
|
|
184322
|
+
const contentRel = relative16(process.cwd(), dir) || ".";
|
|
183561
184323
|
const contentArg2 = shellQuote3(contentRel);
|
|
183562
184324
|
if (onlyRaw !== void 0) {
|
|
183563
184325
|
const onlyDraft = flags.draft === true;
|
|
@@ -183619,7 +184381,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
183619
184381
|
let localSourceHash;
|
|
183620
184382
|
try {
|
|
183621
184383
|
const { collectAppSource: collectAppSource2, zipAppSource: zipAppSource2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
183622
|
-
localSourceHash =
|
|
184384
|
+
localSourceHash = createHash45("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
|
|
183623
184385
|
} catch {
|
|
183624
184386
|
}
|
|
183625
184387
|
return runReleasePatch({
|
|
@@ -184047,7 +184809,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184047
184809
|
return 2;
|
|
184048
184810
|
}
|
|
184049
184811
|
try {
|
|
184050
|
-
const res = writePack(
|
|
184812
|
+
const res = writePack(resolve64(releaseDir), only, resolve64(str9(flags.out) ?? process.cwd()));
|
|
184051
184813
|
print({
|
|
184052
184814
|
ok: true,
|
|
184053
184815
|
app: res.app,
|
|
@@ -184096,7 +184858,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184096
184858
|
}
|
|
184097
184859
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
184098
184860
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
184099
|
-
const built =
|
|
184861
|
+
const built = mkdtempSync6(join87(tmpdir7(), "himi-pack-"));
|
|
184100
184862
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
184101
184863
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
184102
184864
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -184115,12 +184877,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184115
184877
|
...await navIssues2(dir, strict)
|
|
184116
184878
|
]);
|
|
184117
184879
|
if (hasErrors && !force) {
|
|
184118
|
-
|
|
184880
|
+
rmSync23(built, { recursive: true, force: true });
|
|
184119
184881
|
print({ ...report3, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
184120
184882
|
return 1;
|
|
184121
184883
|
}
|
|
184122
184884
|
try {
|
|
184123
|
-
const res = writePack(built, app,
|
|
184885
|
+
const res = writePack(built, app, resolve64(str9(flags.out) ?? dir), sourceArchive);
|
|
184124
184886
|
print({
|
|
184125
184887
|
ok: true,
|
|
184126
184888
|
app: res.app,
|
|
@@ -184151,7 +184913,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184151
184913
|
io2.error(JSON.stringify({ error: e2.message }));
|
|
184152
184914
|
return 1;
|
|
184153
184915
|
} finally {
|
|
184154
|
-
|
|
184916
|
+
rmSync23(built, { recursive: true, force: true });
|
|
184155
184917
|
}
|
|
184156
184918
|
}
|
|
184157
184919
|
// ---- himi import — turn a dev .himi back into an editable content package ----
|
|
@@ -184165,7 +184927,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184165
184927
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
184166
184928
|
let opened;
|
|
184167
184929
|
try {
|
|
184168
|
-
opened = openPackageFile2(
|
|
184930
|
+
opened = openPackageFile2(resolve64(file2));
|
|
184169
184931
|
} catch (e2) {
|
|
184170
184932
|
io2.error(JSON.stringify({ error: e2.message }));
|
|
184171
184933
|
return 1;
|
|
@@ -184178,7 +184940,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184178
184940
|
io2.error(JSON.stringify({
|
|
184179
184941
|
ok: false,
|
|
184180
184942
|
error: "app_source_not_in_package",
|
|
184181
|
-
detail: `${
|
|
184943
|
+
detail: `${resolve64(file2)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
184182
184944
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
184183
184945
|
}));
|
|
184184
184946
|
return 1;
|
|
@@ -184201,7 +184963,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184201
184963
|
return 1;
|
|
184202
184964
|
}
|
|
184203
184965
|
}
|
|
184204
|
-
const dest =
|
|
184966
|
+
const dest = resolve64(str9(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
184205
184967
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
184206
184968
|
if (issue2) {
|
|
184207
184969
|
io2.error(JSON.stringify(issue2));
|
|
@@ -184288,7 +185050,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184288
185050
|
}
|
|
184289
185051
|
try {
|
|
184290
185052
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
184291
|
-
const opened = openPackageFile2(
|
|
185053
|
+
const opened = openPackageFile2(resolve64(file2));
|
|
184292
185054
|
if (!opened.validation.ok || !opened.header) {
|
|
184293
185055
|
io2.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
184294
185056
|
return 1;
|
|
@@ -184298,12 +185060,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184298
185060
|
io2.error(JSON.stringify({
|
|
184299
185061
|
ok: false,
|
|
184300
185062
|
error: "refusing to share a package that carries the app's source",
|
|
184301
|
-
detail: `${
|
|
185063
|
+
detail: `${resolve64(file2)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
|
|
184302
185064
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
184303
185065
|
}));
|
|
184304
185066
|
return 1;
|
|
184305
185067
|
}
|
|
184306
|
-
const archive =
|
|
185068
|
+
const archive = readFileSync103(resolve64(file2));
|
|
184307
185069
|
const result = await client2().createPackageShare({
|
|
184308
185070
|
app: opened.header.app,
|
|
184309
185071
|
releaseId: opened.header.releaseId,
|
|
@@ -184400,11 +185162,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184400
185162
|
const app = await appId(dir2);
|
|
184401
185163
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
184402
185164
|
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
184403
|
-
temp =
|
|
185165
|
+
temp = mkdtempSync6(join87(tmpdir7(), "himi-run-build-"));
|
|
184404
185166
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
184405
185167
|
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
184406
185168
|
servedMissing = initial.missingBundles;
|
|
184407
|
-
source =
|
|
185169
|
+
source = join87(temp, app);
|
|
184408
185170
|
}
|
|
184409
185171
|
const chromeArg = str9(flags.chrome) ?? "preview";
|
|
184410
185172
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -184443,7 +185205,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184443
185205
|
if (!recordKit) return;
|
|
184444
185206
|
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
184445
185207
|
const failure = record2(served2, { ok: true, at: startedAt });
|
|
184446
|
-
if (!recorded) io2.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${
|
|
185208
|
+
if (!recorded) io2.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${join87(dir, ".himi")} is not a real directory`}, so the build board will not frame this preview.` }));
|
|
184447
185209
|
await refreshBoard();
|
|
184448
185210
|
};
|
|
184449
185211
|
const retract = async () => {
|
|
@@ -184466,9 +185228,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184466
185228
|
});
|
|
184467
185229
|
await announce(run2);
|
|
184468
185230
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
184469
|
-
await new Promise((
|
|
185231
|
+
await new Promise((resolve65) => {
|
|
184470
185232
|
const stop = () => {
|
|
184471
|
-
void retract().catch((e2) => io2.error(JSON.stringify({ run: "stop_cleanup_failed", message: e2.message }))).finally(() => run2.close().finally(() =>
|
|
185233
|
+
void retract().catch((e2) => io2.error(JSON.stringify({ run: "stop_cleanup_failed", message: e2.message }))).finally(() => run2.close().finally(() => resolve65()));
|
|
184472
185234
|
};
|
|
184473
185235
|
dropEarlySignals?.();
|
|
184474
185236
|
process.once("SIGINT", stop);
|
|
@@ -184479,7 +185241,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184479
185241
|
const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
184480
185242
|
const hhpPreviewRoute = watch2 ? (await Promise.resolve().then(() => (init_hhp_preview(), hhp_preview_exports))).hhpPreviewResponse : null;
|
|
184481
185243
|
const bus = watchKit ? new watchKit.ReloadBus() : void 0;
|
|
184482
|
-
if (watch2) served =
|
|
185244
|
+
if (watch2) served = mkdtempSync6(join87(tmpdir7(), "himi-run-served-"));
|
|
184483
185245
|
const running = await runPackage2(source, {
|
|
184484
185246
|
port,
|
|
184485
185247
|
chrome: chromeArg,
|
|
@@ -184508,8 +185270,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184508
185270
|
await announce(running);
|
|
184509
185271
|
if (watchKit && bus) {
|
|
184510
185272
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
184511
|
-
const live3 =
|
|
184512
|
-
const manifestOf = (tree) => JSON.parse(
|
|
185273
|
+
const live3 = join87(running.releaseRoot, running.app);
|
|
185274
|
+
const manifestOf = (tree) => JSON.parse(readFileSync103(join87(tree, "release-manifest.json"), "utf8"));
|
|
184513
185275
|
let current = manifestOf(live3);
|
|
184514
185276
|
const failed3 = async (message) => {
|
|
184515
185277
|
if (stopping) return;
|
|
@@ -184520,7 +185282,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184520
185282
|
};
|
|
184521
185283
|
rebuild = watchKit.serialize(async () => {
|
|
184522
185284
|
const t0 = Date.now();
|
|
184523
|
-
const next =
|
|
185285
|
+
const next = mkdtempSync6(join87(tmpdir7(), "himi-run-build-"));
|
|
184524
185286
|
try {
|
|
184525
185287
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
184526
185288
|
if (bres.compileErrors.length) {
|
|
@@ -184537,18 +185299,18 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184537
185299
|
return;
|
|
184538
185300
|
}
|
|
184539
185301
|
if (stopping) return;
|
|
184540
|
-
const fresh = manifestOf(
|
|
185302
|
+
const fresh = manifestOf(join87(next, running.app));
|
|
184541
185303
|
const diff = watchKit.diffReleases(current, fresh);
|
|
184542
185304
|
const { describeChanges: describeChanges2, headline: headline2 } = await Promise.resolve().then(() => (init_build_changes(), build_changes_exports));
|
|
184543
|
-
const changes = describeChanges2(live3,
|
|
185305
|
+
const changes = describeChanges2(live3, join87(next, running.app), diff);
|
|
184544
185306
|
const retired = `${live3}.retired-${Date.now()}`;
|
|
184545
|
-
|
|
185307
|
+
renameSync13(live3, retired);
|
|
184546
185308
|
try {
|
|
184547
|
-
|
|
185309
|
+
renameSync13(join87(next, running.app), live3);
|
|
184548
185310
|
} catch {
|
|
184549
|
-
cpSync3(
|
|
185311
|
+
cpSync3(join87(next, running.app), live3, { recursive: true });
|
|
184550
185312
|
}
|
|
184551
|
-
|
|
185313
|
+
rmSync23(retired, { recursive: true, force: true });
|
|
184552
185314
|
current = fresh;
|
|
184553
185315
|
servedMissing = outcome.missingBundles;
|
|
184554
185316
|
for (const [event, data] of watchKit.reloadEvents(diff)) bus.publish(event, data);
|
|
@@ -184558,7 +185320,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184558
185320
|
} catch (e2) {
|
|
184559
185321
|
await failed3(e2.message.split("\n")[0]);
|
|
184560
185322
|
} finally {
|
|
184561
|
-
|
|
185323
|
+
rmSync23(next, { recursive: true, force: true });
|
|
184562
185324
|
}
|
|
184563
185325
|
});
|
|
184564
185326
|
watcher2 = watchKit.watchContent(dir, () => {
|
|
@@ -184629,9 +185391,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
184629
185391
|
} finally {
|
|
184630
185392
|
dropEarlySignals?.();
|
|
184631
185393
|
dropInitRecord?.();
|
|
184632
|
-
if (temp)
|
|
184633
|
-
if (served)
|
|
184634
|
-
if (browserCopy)
|
|
185394
|
+
if (temp) rmSync23(temp, { recursive: true, force: true });
|
|
185395
|
+
if (served) rmSync23(served, { recursive: true, force: true });
|
|
185396
|
+
if (browserCopy) rmSync23(browserCopy, { recursive: true, force: true });
|
|
184635
185397
|
}
|
|
184636
185398
|
}
|
|
184637
185399
|
case "preview": {
|
|
@@ -185173,7 +185935,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185173
185935
|
io2.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
185174
185936
|
return 2;
|
|
185175
185937
|
}
|
|
185176
|
-
if (!
|
|
185938
|
+
if (!existsSync82(file2)) {
|
|
185177
185939
|
io2.error(JSON.stringify({ error: `no such file: ${file2}` }));
|
|
185178
185940
|
return 2;
|
|
185179
185941
|
}
|
|
@@ -185229,7 +185991,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185229
185991
|
lintNote: "`himi patch` sends a raw file. Nothing here built or linted your app \u2014 `himi push --only <selector>` is the same edit with the full lint gate in front of it."
|
|
185230
185992
|
};
|
|
185231
185993
|
if (kind === "tokens" || kind === "app-config") {
|
|
185232
|
-
const body =
|
|
185994
|
+
const body = readFileSync103(file2, "utf8");
|
|
185233
185995
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
185234
185996
|
return runReleasePatch({
|
|
185235
185997
|
...common,
|
|
@@ -185244,7 +186006,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185244
186006
|
io2.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
185245
186007
|
return 2;
|
|
185246
186008
|
}
|
|
185247
|
-
const descriptor =
|
|
186009
|
+
const descriptor = readFileSync103(file2, "utf8");
|
|
185248
186010
|
try {
|
|
185249
186011
|
JSON.parse(descriptor);
|
|
185250
186012
|
} catch (e2) {
|
|
@@ -185284,8 +186046,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185284
186046
|
extra: { kind, screen: id, file: { path: file2, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
185285
186047
|
});
|
|
185286
186048
|
}
|
|
185287
|
-
const bytes2 =
|
|
185288
|
-
const sha2 =
|
|
186049
|
+
const bytes2 = readFileSync103(file2);
|
|
186050
|
+
const sha2 = createHash45("sha256").update(bytes2).digest("hex");
|
|
185289
186051
|
const forScreens = (str9(flags["for-screen"]) ?? "").split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
185290
186052
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
185291
186053
|
io2.error(JSON.stringify({ ok: false, error: "no_rebind_takes_no_value", message: "--no-rebind is a switch and takes no value; pass it bare.", usage: PATCH_USAGE }));
|
|
@@ -185428,7 +186190,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185428
186190
|
}
|
|
185429
186191
|
let def;
|
|
185430
186192
|
try {
|
|
185431
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
186193
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync103(arg.slice(1), "utf8") : arg);
|
|
185432
186194
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
185433
186195
|
io2.error(JSON.stringify({ error: "invalid_definition", problems: [`--definition must be a JSON object, got ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`] }));
|
|
185434
186196
|
return 2;
|
|
@@ -185710,7 +186472,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
185710
186472
|
const rememberLastDist = async (jobs2) => {
|
|
185711
186473
|
try {
|
|
185712
186474
|
const dir = contentDir(flags);
|
|
185713
|
-
if (!
|
|
186475
|
+
if (!existsSync82(join87(dir, "himalaya.content.json"))) return;
|
|
185714
186476
|
const { lastDistFromJob: lastDistFromJob2, writeLastDist: writeLastDist2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
|
|
185715
186477
|
const own5 = await appId(dir);
|
|
185716
186478
|
for (const job of jobs2) {
|
|
@@ -185950,7 +186712,7 @@ ${label2}`);
|
|
|
185950
186712
|
const platform = str9(flags.platform)?.split(",").map((p2) => p2.trim()).filter(Boolean);
|
|
185951
186713
|
{
|
|
185952
186714
|
const distDir = contentDir(flags);
|
|
185953
|
-
if (
|
|
186715
|
+
if (existsSync82(join87(distDir, "himalaya.content.json"))) {
|
|
185954
186716
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
185955
186717
|
const errors = issues.filter((i2) => i2.severity === "error");
|
|
185956
186718
|
for (const i2 of issues.filter((i3) => i3.severity === "warning")) {
|
|
@@ -186290,7 +187052,7 @@ ${label2}`);
|
|
|
186290
187052
|
const dpxPath = dpxSessionTokenPath();
|
|
186291
187053
|
let dpx;
|
|
186292
187054
|
try {
|
|
186293
|
-
dpx =
|
|
187055
|
+
dpx = readFileSync103(dpxPath, "utf8").trim();
|
|
186294
187056
|
} catch {
|
|
186295
187057
|
io2.error(JSON.stringify({ error: `no dpx session at ${dpxPath} \u2014 run \`dpx auth login\` then \`dpx auth token > ${dpxPath}\` (dpx 2.x keeps its own state in ~/.dpx/auth.json and does NOT write the legacy session file), or omit --dpx` }));
|
|
186296
187058
|
return 1;
|
|
@@ -186753,7 +187515,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
|
|
|
186753
187515
|
const path2 = dpxSessionTokenPath();
|
|
186754
187516
|
let raw;
|
|
186755
187517
|
try {
|
|
186756
|
-
raw =
|
|
187518
|
+
raw = readFileSync103(path2, "utf8");
|
|
186757
187519
|
} catch {
|
|
186758
187520
|
io2.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
186759
187521
|
return 1;
|