@wix/himalaya-cli 0.1008.0 → 0.1010.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs
CHANGED
|
@@ -1341,7 +1341,7 @@ function sentinelizeIdentity(body, identity) {
|
|
|
1341
1341
|
}
|
|
1342
1342
|
if (identity.name) {
|
|
1343
1343
|
const re = new RegExp(`\\b(${NAME_FIELDS.join("|")})(["']?\\s*[:=]\\s*)(["'])${escapeRe(identity.name)}\\3`, "g");
|
|
1344
|
-
out = out.replace(re, (_m, key2,
|
|
1344
|
+
out = out.replace(re, (_m, key2, sep13, q) => `${key2}${sep13}${q}__HIMI_APP_NAME__${q}`);
|
|
1345
1345
|
}
|
|
1346
1346
|
return out;
|
|
1347
1347
|
}
|
|
@@ -2341,7 +2341,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2341
2341
|
tokenCache.set(cacheKey, fromEnv);
|
|
2342
2342
|
return fromEnv;
|
|
2343
2343
|
}
|
|
2344
|
-
const token = await new Promise((
|
|
2344
|
+
const token = await new Promise((resolve46, reject) => {
|
|
2345
2345
|
let child;
|
|
2346
2346
|
try {
|
|
2347
2347
|
child = spawnImpl("wix", [...args]);
|
|
@@ -2370,12 +2370,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2370
2370
|
child.stdout?.on("data", (d) => {
|
|
2371
2371
|
out += String(d);
|
|
2372
2372
|
const m = out.match(TOKEN_RE);
|
|
2373
|
-
if (m) done(() =>
|
|
2373
|
+
if (m) done(() => resolve46(m[0]));
|
|
2374
2374
|
});
|
|
2375
2375
|
child.stderr?.on("data", (d) => {
|
|
2376
2376
|
out += String(d);
|
|
2377
2377
|
const m = out.match(TOKEN_RE);
|
|
2378
|
-
if (m) done(() =>
|
|
2378
|
+
if (m) done(() => resolve46(m[0]));
|
|
2379
2379
|
});
|
|
2380
2380
|
child.on("error", (e) => done(() => reject(new Error(mintHelp(label2, e.message)))));
|
|
2381
2381
|
child.on("exit", (code) => done(() => reject(new Error(
|
|
@@ -2556,8 +2556,8 @@ function committedProvisioningPath(name) {
|
|
|
2556
2556
|
function committedShellFor(path2) {
|
|
2557
2557
|
const normalized = path2.replace(/\\/g, "/");
|
|
2558
2558
|
return SHELL_NAMES2.find((name) => {
|
|
2559
|
-
const
|
|
2560
|
-
return normalized ===
|
|
2559
|
+
const relative10 = committedProvisioningPath(name);
|
|
2560
|
+
return normalized === relative10 || normalized.endsWith(`/${relative10}`);
|
|
2561
2561
|
});
|
|
2562
2562
|
}
|
|
2563
2563
|
function isBrandable(repoRoot2, name) {
|
|
@@ -5318,7 +5318,6 @@ function walk(node, registry, path2, out) {
|
|
|
5318
5318
|
var SYSTEM_FONT_FAMILY;
|
|
5319
5319
|
var init_tokens = __esm({
|
|
5320
5320
|
"../../core/ts/src/tokens.ts"() {
|
|
5321
|
-
"use strict";
|
|
5322
5321
|
SYSTEM_FONT_FAMILY = "$system";
|
|
5323
5322
|
}
|
|
5324
5323
|
});
|
|
@@ -5344,7 +5343,6 @@ function resolveTranslation(value, catalog, sourceCatalog) {
|
|
|
5344
5343
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
5345
5344
|
var init_bindings = __esm({
|
|
5346
5345
|
"../../core/ts/src/bindings.ts"() {
|
|
5347
|
-
"use strict";
|
|
5348
5346
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
5349
5347
|
BINDING_SIGIL_RE = new RegExp(
|
|
5350
5348
|
`^\\$(?:${BINDING_SIGILS.filter((s) => s !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -15566,7 +15564,7 @@ async function injectRequest(listener, request) {
|
|
|
15566
15564
|
req.headers.host ??= url.host;
|
|
15567
15565
|
if (body && body.length > 0) req.push(body);
|
|
15568
15566
|
req.push(null);
|
|
15569
|
-
return await new Promise((
|
|
15567
|
+
return await new Promise((resolve46, reject) => {
|
|
15570
15568
|
const streamed = () => {
|
|
15571
15569
|
queueMicrotask(() => {
|
|
15572
15570
|
req.emit("close");
|
|
@@ -15582,7 +15580,7 @@ async function injectRequest(listener, request) {
|
|
|
15582
15580
|
else headers2.set(name, value);
|
|
15583
15581
|
}
|
|
15584
15582
|
const bodyless = out.status === 204 || out.status === 304 || request.method === "HEAD";
|
|
15585
|
-
|
|
15583
|
+
resolve46(new Response(bodyless ? null : out.body, { status: out.status, headers: headers2 }));
|
|
15586
15584
|
}, streamed);
|
|
15587
15585
|
res.on("inject-error", reject);
|
|
15588
15586
|
try {
|
|
@@ -16277,7 +16275,7 @@ function redactBodyString(body) {
|
|
|
16277
16275
|
} catch {
|
|
16278
16276
|
}
|
|
16279
16277
|
}
|
|
16280
|
-
return body.replace(FORM_ASSIGNMENT_RE, (m, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m).replace(JSON_FIELD_RE, (m, name,
|
|
16278
|
+
return body.replace(FORM_ASSIGNMENT_RE, (m, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m).replace(JSON_FIELD_RE, (m, name, sep13) => isSensitiveBodyName(name) ? `"${name}"${sep13}"${REDACTED}"` : m).replace(JSON_FIELD_UNTERMINATED_RE, (m, name, sep13) => isSensitiveBodyName(name) ? `"${name}"${sep13}"${REDACTED}` : m).replace(BEARER_RE, (_m, s) => `${s} ${REDACTED}`);
|
|
16281
16279
|
}
|
|
16282
16280
|
function createWixGatewayState() {
|
|
16283
16281
|
return { mode: "record", rules: [], traffic: [], clients: /* @__PURE__ */ new Set(), seq: 0, ruleSeq: 0 };
|
|
@@ -16874,7 +16872,7 @@ function wixClientIdOf(appConfigJson) {
|
|
|
16874
16872
|
if (typeof clientId !== "string" || !clientId) return { error: "no_client_id" };
|
|
16875
16873
|
return { clientId };
|
|
16876
16874
|
}
|
|
16877
|
-
var WIX_API, ONE_APP_SESSION, OWNER_SCOPED_WIX_HOST, VisitorTokenCache, OWNER_REFRESH_MARGIN_MS, OwnerInstanceCache, OWNER_SITES_QUERY_PATH, OWNER_SITES_COUNT_PATH, OwnerSitesCache;
|
|
16875
|
+
var WIX_API, ONE_APP_SESSION, OWNER_SCOPED_WIX_HOST, VisitorTokenCache, OWNER_REFRESH_MARGIN_MS, OWNER_RENEW_MIN_AGE_MS, OWNER_MINT_TIMEOUT_MS, OwnerInstanceCache, OWNER_SITES_QUERY_PATH, OWNER_SITES_COUNT_PATH, OwnerSitesCache;
|
|
16878
16876
|
var init_wix_bridge = __esm({
|
|
16879
16877
|
"../../core/serve-runtime/src/wix-bridge.ts"() {
|
|
16880
16878
|
init_sha256();
|
|
@@ -16912,12 +16910,19 @@ var init_wix_bridge = __esm({
|
|
|
16912
16910
|
}
|
|
16913
16911
|
};
|
|
16914
16912
|
OWNER_REFRESH_MARGIN_MS = 6e4;
|
|
16913
|
+
OWNER_RENEW_MIN_AGE_MS = 5e3;
|
|
16914
|
+
OWNER_MINT_TIMEOUT_MS = 8e3;
|
|
16915
16915
|
OwnerInstanceCache = class {
|
|
16916
|
-
constructor(fetchImpl = fetch, ttlMs = 5 * 6e4) {
|
|
16916
|
+
constructor(fetchImpl = fetch, ttlMs = 5 * 6e4, mintTimeoutMs = OWNER_MINT_TIMEOUT_MS, elapsedClock = () => performance.now()) {
|
|
16917
16917
|
this.fetchImpl = fetchImpl;
|
|
16918
16918
|
this.ttlMs = ttlMs;
|
|
16919
|
+
this.mintTimeoutMs = mintTimeoutMs;
|
|
16920
|
+
this.elapsedClock = elapsedClock;
|
|
16919
16921
|
}
|
|
16920
16922
|
cache = /* @__PURE__ */ new Map();
|
|
16923
|
+
/** The one mint on its way per (business, session). Every caller, plain or renewing, joins it:
|
|
16924
|
+
* it started after whatever is cached was minted, so it is the fresh instance. */
|
|
16925
|
+
inflight = /* @__PURE__ */ new Map();
|
|
16921
16926
|
/** Keyed on the SESSION (`wixSession2`), not the whole cookie header: manage.wix.com's jar churns
|
|
16922
16927
|
* (analytics, experiments), and keying on all of it re-minted on nearly every call (#3044). A
|
|
16923
16928
|
* header with no session cookie falls back to itself — callers refuse that case before here. */
|
|
@@ -16929,28 +16934,62 @@ ${session}`);
|
|
|
16929
16934
|
async instance(msid, cookieHeader, now = Date.now()) {
|
|
16930
16935
|
return (await this.entry(msid, cookieHeader, now)).instance;
|
|
16931
16936
|
}
|
|
16932
|
-
/** The instance and the time this cache stops trusting it (#3044: the web host caches until then).
|
|
16933
|
-
|
|
16937
|
+
/** The instance and the time this cache stops trusting it (#3044: the web host caches until then).
|
|
16938
|
+
* `renew`: Wix refused the instance this cache handed out (the route's `renew=1`, #3140) — mint a
|
|
16939
|
+
* new one, unless the cached one is younger than OWNER_RENEW_MIN_AGE_MS or a mint is already on
|
|
16940
|
+
* its way, in which case that IS the new one. */
|
|
16941
|
+
async entry(msid, cookieHeader, now = Date.now(), opts = {}) {
|
|
16934
16942
|
const key2 = this.key(msid, cookieHeader);
|
|
16935
|
-
const
|
|
16943
|
+
const pending = this.inflight.get(key2);
|
|
16944
|
+
if (pending) return { ...await pending };
|
|
16945
|
+
let hit = this.cache.get(key2);
|
|
16946
|
+
if (opts.renew && hit && now - hit.mintedAt >= OWNER_RENEW_MIN_AGE_MS) hit = void 0;
|
|
16936
16947
|
if (hit && hit.expiresAt - OWNER_REFRESH_MARGIN_MS > now) return { instance: hit.instance, expiresAt: hit.expiresAt };
|
|
16937
|
-
const
|
|
16938
|
-
|
|
16939
|
-
|
|
16948
|
+
const mint = this.mint(key2, msid, cookieHeader, now).finally(() => this.inflight.delete(key2));
|
|
16949
|
+
this.inflight.set(key2, mint);
|
|
16950
|
+
return { ...await mint };
|
|
16951
|
+
}
|
|
16952
|
+
async mint(key2, msid, cookieHeader, now) {
|
|
16953
|
+
const startedAt = this.elapsedClock();
|
|
16954
|
+
const abort = new AbortController();
|
|
16955
|
+
let timer;
|
|
16956
|
+
const timedOut = new Promise((_, reject) => {
|
|
16957
|
+
timer = setTimeout(() => {
|
|
16958
|
+
abort.abort();
|
|
16959
|
+
reject(new Error(`owner mint timed out after ${this.mintTimeoutMs}ms`));
|
|
16960
|
+
}, this.mintTimeoutMs);
|
|
16940
16961
|
});
|
|
16941
|
-
const text4 = await res.text();
|
|
16942
|
-
let j = {};
|
|
16943
16962
|
try {
|
|
16944
|
-
|
|
16945
|
-
|
|
16963
|
+
const res = await Promise.race([
|
|
16964
|
+
this.fetchImpl(`${ONE_APP_SESSION}/${msid}/signed-instance?signed_instance_type=User`, {
|
|
16965
|
+
method: "GET",
|
|
16966
|
+
headers: { Cookie: cookieHeader },
|
|
16967
|
+
signal: abort.signal
|
|
16968
|
+
}),
|
|
16969
|
+
timedOut
|
|
16970
|
+
]);
|
|
16971
|
+
const text4 = await Promise.race([res.text(), timedOut]);
|
|
16972
|
+
let j = {};
|
|
16973
|
+
try {
|
|
16974
|
+
j = text4 ? JSON.parse(text4) : {};
|
|
16975
|
+
} catch {
|
|
16976
|
+
}
|
|
16977
|
+
if (res.status < 200 || res.status >= 300 || !j.signedInstance)
|
|
16978
|
+
throw new Error(`owner mint failed (${res.status})`);
|
|
16979
|
+
const elapsed = Math.max(0, this.elapsedClock() - startedAt);
|
|
16980
|
+
const mintedAt = now + elapsed;
|
|
16981
|
+
const entry = { instance: j.signedInstance, expiresAt: now + Math.floor(elapsed / 1e3) * 1e3 + this.ttlMs };
|
|
16982
|
+
this.cache.set(key2, { ...entry, mintedAt });
|
|
16983
|
+
return entry;
|
|
16984
|
+
} catch (e) {
|
|
16985
|
+
this.cache.delete(key2);
|
|
16986
|
+
throw e;
|
|
16987
|
+
} finally {
|
|
16988
|
+
clearTimeout(timer);
|
|
16946
16989
|
}
|
|
16947
|
-
if (res.status < 200 || res.status >= 300 || !j.signedInstance)
|
|
16948
|
-
throw new Error(`owner mint failed (${res.status})`);
|
|
16949
|
-
const entry = { instance: j.signedInstance, expiresAt: now + this.ttlMs };
|
|
16950
|
-
this.cache.set(key2, entry);
|
|
16951
|
-
return { ...entry };
|
|
16952
16990
|
}
|
|
16953
|
-
/** Drop a cached instance
|
|
16991
|
+
/** Drop a cached instance so the next call re-mints. The envelope owner branch's own 401 retry;
|
|
16992
|
+
* the route's `renew=1` goes through `entry(…, { renew: true })` instead. */
|
|
16954
16993
|
invalidate(msid, cookieHeader) {
|
|
16955
16994
|
this.cache.delete(this.key(msid, cookieHeader));
|
|
16956
16995
|
}
|
|
@@ -17928,12 +17967,12 @@ function finalizeRecording(key2, rec) {
|
|
|
17928
17967
|
if (rec.finalize) return rec.finalize;
|
|
17929
17968
|
rec.finalize = (async () => {
|
|
17930
17969
|
clearTimeout(rec.autoStop);
|
|
17931
|
-
await new Promise((
|
|
17970
|
+
await new Promise((resolve46) => {
|
|
17932
17971
|
let done = false;
|
|
17933
17972
|
const finish2 = () => {
|
|
17934
17973
|
if (!done) {
|
|
17935
17974
|
done = true;
|
|
17936
|
-
|
|
17975
|
+
resolve46();
|
|
17937
17976
|
}
|
|
17938
17977
|
};
|
|
17939
17978
|
rec.child.once("close", finish2);
|
|
@@ -18044,7 +18083,7 @@ var init_preview = __esm({
|
|
|
18044
18083
|
DEVICE_LIST_TIMEOUT_MS = 5e3;
|
|
18045
18084
|
defaultRunner2 = {
|
|
18046
18085
|
capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
|
|
18047
|
-
return new Promise((
|
|
18086
|
+
return new Promise((resolve46, reject) => {
|
|
18048
18087
|
const child = spawn2(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
18049
18088
|
const out = [];
|
|
18050
18089
|
const err = [];
|
|
@@ -18066,7 +18105,7 @@ var init_preview = __esm({
|
|
|
18066
18105
|
child.stderr.on("data", (b) => err.push(b));
|
|
18067
18106
|
child.on("error", (e) => settle(reject, e));
|
|
18068
18107
|
child.on("close", (code) => {
|
|
18069
|
-
if (code === 0) settle(
|
|
18108
|
+
if (code === 0) settle(resolve46, Buffer.concat(out));
|
|
18070
18109
|
else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
|
|
18071
18110
|
});
|
|
18072
18111
|
});
|
|
@@ -23121,8 +23160,8 @@ function ensureCountUpRuntime() {
|
|
|
23121
23160
|
const neg = fixed.startsWith("-");
|
|
23122
23161
|
const body = neg ? fixed.slice(1) : fixed;
|
|
23123
23162
|
const [int, frac] = body.split(".");
|
|
23124
|
-
const
|
|
23125
|
-
return (neg ? "-" : "") +
|
|
23163
|
+
const sep13 = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
23164
|
+
return (neg ? "-" : "") + sep13 + (frac ? "." + frac : "");
|
|
23126
23165
|
};
|
|
23127
23166
|
const animateEl = (el) => {
|
|
23128
23167
|
const node = el;
|
|
@@ -28846,7 +28885,7 @@ async function stabilizePngPage(page, scheme) {
|
|
|
28846
28885
|
const browser = globalThis;
|
|
28847
28886
|
browser.document.documentElement.style.colorScheme = selected;
|
|
28848
28887
|
await browser.document.fonts?.ready;
|
|
28849
|
-
await new Promise((
|
|
28888
|
+
await new Promise((resolve46) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve46())));
|
|
28850
28889
|
}, scheme);
|
|
28851
28890
|
}
|
|
28852
28891
|
async function renderPngBatch(items) {
|
|
@@ -32418,7 +32457,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32418
32457
|
}
|
|
32419
32458
|
if (match && (match.rule.kind ?? "mock") === "mock") {
|
|
32420
32459
|
const mocked = match.rule.response;
|
|
32421
|
-
if (mocked.delayMs) await new Promise((
|
|
32460
|
+
if (mocked.delayMs) await new Promise((resolve46) => setTimeout(resolve46, mocked.delayMs));
|
|
32422
32461
|
const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
32423
32462
|
recordWixTraffic(state.wix, state.appName, state.adminUrl, {
|
|
32424
32463
|
ts: started,
|
|
@@ -33384,8 +33423,8 @@ async function handleActionHandlerBundleGet(res, app) {
|
|
|
33384
33423
|
}
|
|
33385
33424
|
async function serveStatic(req, res, root, prefix) {
|
|
33386
33425
|
const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
|
|
33387
|
-
const
|
|
33388
|
-
const safe = normalize3(
|
|
33426
|
+
const relative10 = requested.replace(prefix, "").replace(/^\//, "");
|
|
33427
|
+
const safe = normalize3(relative10).replace(/^(\.\.[\/\\])+/, "");
|
|
33389
33428
|
const fullPath = resolve30(root, safe);
|
|
33390
33429
|
if (!fullPath.startsWith(root)) {
|
|
33391
33430
|
return send(res, 403, "forbidden");
|
|
@@ -34420,12 +34459,12 @@ var init_query = __esm({
|
|
|
34420
34459
|
});
|
|
34421
34460
|
|
|
34422
34461
|
// ../../core/dev-server/src/crawl-input.ts
|
|
34423
|
-
function resolved(v,
|
|
34424
|
-
if (typeof v === "string") return v.startsWith("$service:") ?
|
|
34462
|
+
function resolved(v, resolve46) {
|
|
34463
|
+
if (typeof v === "string") return v.startsWith("$service:") ? resolve46(v) : v;
|
|
34425
34464
|
if (Array.isArray(v)) {
|
|
34426
34465
|
const out = v.flatMap((el) => {
|
|
34427
34466
|
if (typeof el !== "string" || !el.startsWith("$service:")) return [el];
|
|
34428
|
-
const r =
|
|
34467
|
+
const r = resolve46(el);
|
|
34429
34468
|
return Array.isArray(r) ? r : [r];
|
|
34430
34469
|
});
|
|
34431
34470
|
return out;
|
|
@@ -34439,9 +34478,9 @@ function hasRowBinding(props) {
|
|
|
34439
34478
|
return itemToken(v) || Array.isArray(v) && v.some(itemToken);
|
|
34440
34479
|
});
|
|
34441
34480
|
}
|
|
34442
|
-
function declaredOptionIds(props,
|
|
34481
|
+
function declaredOptionIds(props, resolve46) {
|
|
34443
34482
|
const literal = props.options ?? props.tabs ?? props.chips;
|
|
34444
|
-
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath,
|
|
34483
|
+
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve46) : void 0;
|
|
34445
34484
|
const raw = Array.isArray(bound) ? bound : literal;
|
|
34446
34485
|
if (!Array.isArray(raw)) return [];
|
|
34447
34486
|
const out = [];
|
|
@@ -34484,24 +34523,24 @@ function seedTokens(state, limit = 48) {
|
|
|
34484
34523
|
walk2(state, 0);
|
|
34485
34524
|
return out;
|
|
34486
34525
|
}
|
|
34487
|
-
function synthesizeInput(control,
|
|
34526
|
+
function synthesizeInput(control, resolve46, tokens) {
|
|
34488
34527
|
const id = `${control.type}.${control.callback}`;
|
|
34489
34528
|
const row = SYNTHESIZED_CONTROLS[id];
|
|
34490
34529
|
if (!row) return null;
|
|
34491
34530
|
const props = control.props;
|
|
34492
34531
|
if (hasRowBinding(props)) return null;
|
|
34493
34532
|
if (row.from === "declared-options") {
|
|
34494
|
-
const ids = declaredOptionIds(props,
|
|
34533
|
+
const ids = declaredOptionIds(props, resolve46);
|
|
34495
34534
|
if (!ids.length) return null;
|
|
34496
34535
|
if (row.encoding === "string-array") {
|
|
34497
|
-
const currentRaw2 = resolved(props.selectedIds,
|
|
34536
|
+
const currentRaw2 = resolved(props.selectedIds, resolve46);
|
|
34498
34537
|
const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x) => typeof x === "string");
|
|
34499
34538
|
const pick4 = ids.find((o) => !current3.includes(o));
|
|
34500
34539
|
if (pick4 === void 0) return null;
|
|
34501
34540
|
const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
|
|
34502
34541
|
return { key: row.key, value, from: row.from, current: current3, control: id };
|
|
34503
34542
|
}
|
|
34504
|
-
const currentRaw = resolved(props.selectedId,
|
|
34543
|
+
const currentRaw = resolved(props.selectedId, resolve46);
|
|
34505
34544
|
const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
|
|
34506
34545
|
const pick3 = ids.find((o) => o !== current2);
|
|
34507
34546
|
if (pick3 === void 0) return null;
|
|
@@ -34509,7 +34548,7 @@ function synthesizeInput(control, resolve45, tokens) {
|
|
|
34509
34548
|
}
|
|
34510
34549
|
if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
|
|
34511
34550
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
|
|
34512
|
-
const bound = binding2 === void 0 ? void 0 :
|
|
34551
|
+
const bound = binding2 === void 0 ? void 0 : resolve46(binding2);
|
|
34513
34552
|
const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
|
|
34514
34553
|
const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
|
|
34515
34554
|
const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
|
|
@@ -35767,8 +35806,8 @@ async function crawlScreenInner(opts) {
|
|
|
35767
35806
|
if (linkable.has(target)) return true;
|
|
35768
35807
|
for (const base of linkable) {
|
|
35769
35808
|
if (target.length > base.length + 1 && target.startsWith(base)) {
|
|
35770
|
-
const
|
|
35771
|
-
if (
|
|
35809
|
+
const sep13 = target[base.length];
|
|
35810
|
+
if (sep13 === "_" || sep13 === "/") return true;
|
|
35772
35811
|
}
|
|
35773
35812
|
}
|
|
35774
35813
|
return false;
|
|
@@ -42660,7 +42699,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
42660
42699
|
const headers2 = Object.fromEntries(new Headers(init.headers).entries());
|
|
42661
42700
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
42662
42701
|
const hostname2 = url.hostname.replace(/^\[|\]$/g, "");
|
|
42663
|
-
return await new Promise((
|
|
42702
|
+
return await new Promise((resolve46, reject) => {
|
|
42664
42703
|
let settled = false;
|
|
42665
42704
|
const finish2 = (fn) => {
|
|
42666
42705
|
if (settled) return;
|
|
@@ -42697,7 +42736,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
42697
42736
|
}
|
|
42698
42737
|
const responseHeaders = new Headers();
|
|
42699
42738
|
for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
|
|
42700
|
-
|
|
42739
|
+
resolve46(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
|
|
42701
42740
|
}));
|
|
42702
42741
|
});
|
|
42703
42742
|
req.once("error", (error) => finish2(() => reject(error)));
|
|
@@ -42997,7 +43036,7 @@ function createLocalTestSandbox() {
|
|
|
42997
43036
|
}
|
|
42998
43037
|
})();
|
|
42999
43038
|
`;
|
|
43000
|
-
return await new Promise((
|
|
43039
|
+
return await new Promise((resolve46, reject) => {
|
|
43001
43040
|
const { port1, port2 } = new MessageChannel();
|
|
43002
43041
|
const serializableContext = {
|
|
43003
43042
|
auth: context.auth,
|
|
@@ -43073,7 +43112,7 @@ function createLocalTestSandbox() {
|
|
|
43073
43112
|
timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
|
|
43074
43113
|
return;
|
|
43075
43114
|
}
|
|
43076
|
-
if (message.ok) finish2(() =>
|
|
43115
|
+
if (message.ok) finish2(() => resolve46({ value: message.value, durationMs: Date.now() - started }));
|
|
43077
43116
|
else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
|
|
43078
43117
|
});
|
|
43079
43118
|
worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
|
|
@@ -44203,6 +44242,213 @@ var init_functions = __esm({
|
|
|
44203
44242
|
}
|
|
44204
44243
|
});
|
|
44205
44244
|
|
|
44245
|
+
// src/progress.ts
|
|
44246
|
+
var progress_exports = {};
|
|
44247
|
+
__export(progress_exports, {
|
|
44248
|
+
HISTORY_DIR: () => HISTORY_DIR,
|
|
44249
|
+
JOURNEY_STEPS: () => JOURNEY_STEPS,
|
|
44250
|
+
MAX_IMAGE_BYTES: () => MAX_IMAGE_BYTES,
|
|
44251
|
+
MAX_MESSAGE_CHARS: () => MAX_MESSAGE_CHARS,
|
|
44252
|
+
PROGRESS_FILE: () => PROGRESS_FILE,
|
|
44253
|
+
ProgressError: () => ProgressError,
|
|
44254
|
+
appLabel: () => appLabel,
|
|
44255
|
+
appendProgress: () => appendProgress,
|
|
44256
|
+
appleScriptString: () => appleScriptString,
|
|
44257
|
+
archiveBytes: () => archiveBytes,
|
|
44258
|
+
archiveImage: () => archiveImage,
|
|
44259
|
+
journalPath: () => journalPath,
|
|
44260
|
+
notifyDesktop: () => notifyDesktop,
|
|
44261
|
+
parseStep: () => parseStep,
|
|
44262
|
+
readProgress: () => readProgress,
|
|
44263
|
+
summarizeProgress: () => summarizeProgress
|
|
44264
|
+
});
|
|
44265
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
44266
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
44267
|
+
import { appendFileSync, closeSync, existsSync as existsSync46, mkdirSync as mkdirSync23, openSync, readFileSync as readFileSync50, readSync, renameSync as renameSync4, statSync as statSync10, writeFileSync as writeFileSync19 } from "node:fs";
|
|
44268
|
+
import { join as join43, relative as relative6, resolve as resolve40, sep as sep10 } from "node:path";
|
|
44269
|
+
function parseStep(raw) {
|
|
44270
|
+
const v = raw.trim().toLowerCase();
|
|
44271
|
+
if (/^[1-8]$/.test(v)) return JOURNEY_STEPS[Number(v) - 1];
|
|
44272
|
+
return JOURNEY_STEPS.includes(v) ? v : null;
|
|
44273
|
+
}
|
|
44274
|
+
function imageExtension(buf) {
|
|
44275
|
+
const starts = (...bytes2) => bytes2.every((b, i) => buf[i] === b);
|
|
44276
|
+
if (starts(137, 80, 78, 71, 13, 10, 26, 10)) return "png";
|
|
44277
|
+
if (starts(255, 216, 255)) return "jpg";
|
|
44278
|
+
if (starts(71, 73, 70, 56)) return "gif";
|
|
44279
|
+
if (starts(82, 73, 70, 70) && buf.subarray(8, 12).toString("ascii") === "WEBP") return "webp";
|
|
44280
|
+
return null;
|
|
44281
|
+
}
|
|
44282
|
+
function locateImage(dir, src) {
|
|
44283
|
+
for (const candidate of [resolve40(src), resolve40(dir, src)]) {
|
|
44284
|
+
if (existsSync46(candidate) && statSync10(candidate).isFile()) return candidate;
|
|
44285
|
+
}
|
|
44286
|
+
return null;
|
|
44287
|
+
}
|
|
44288
|
+
function archiveImage(dir, src) {
|
|
44289
|
+
const abs = locateImage(dir, src);
|
|
44290
|
+
if (!abs) throw new ProgressError("image_not_found", `no image at ${src} (looked relative to the current directory and to ${dir})`);
|
|
44291
|
+
const size = statSync10(abs).size;
|
|
44292
|
+
if (size > MAX_IMAGE_BYTES) {
|
|
44293
|
+
throw new ProgressError("image_too_large", `${src} is ${size} bytes; a progress image is capped at ${MAX_IMAGE_BYTES} \u2014 render at phone width (--device iphone)`);
|
|
44294
|
+
}
|
|
44295
|
+
const archived = archiveBytes(dir, readFileSync50(abs));
|
|
44296
|
+
if (!archived) throw new ProgressError("not_an_image", `${src} is not a PNG, JPEG, GIF or WebP image`);
|
|
44297
|
+
return { file: archived.file, sha256: archived.sha256, source: src };
|
|
44298
|
+
}
|
|
44299
|
+
function archiveBytes(dir, bytes2) {
|
|
44300
|
+
const ext = imageExtension(bytes2);
|
|
44301
|
+
if (!ext) return null;
|
|
44302
|
+
const sha2565 = createHash22("sha256").update(bytes2).digest("hex");
|
|
44303
|
+
const rel = join43(HISTORY_DIR, `${sha2565}.${ext}`);
|
|
44304
|
+
const dest = join43(dir, rel);
|
|
44305
|
+
if (!existsSync46(dest)) {
|
|
44306
|
+
mkdirSync23(join43(dir, HISTORY_DIR), { recursive: true });
|
|
44307
|
+
const tmp = `${dest}.${process.pid}.tmp`;
|
|
44308
|
+
writeFileSync19(tmp, bytes2);
|
|
44309
|
+
renameSync4(tmp, dest);
|
|
44310
|
+
}
|
|
44311
|
+
return { sha256: sha2565, ext, file: toPosix(rel) };
|
|
44312
|
+
}
|
|
44313
|
+
function appendProgress(dir, input) {
|
|
44314
|
+
const message = input.message.trim();
|
|
44315
|
+
if (!message) throw new ProgressError("message_required", "a progress entry needs a message");
|
|
44316
|
+
if (message.length > MAX_MESSAGE_CHARS) {
|
|
44317
|
+
throw new ProgressError(
|
|
44318
|
+
"message_too_long",
|
|
44319
|
+
`a postcard is a line or two (${message.length} chars; the cap is ${MAX_MESSAGE_CHARS}) \u2014 put the detail in your reply and journal the headline`
|
|
44320
|
+
);
|
|
44321
|
+
}
|
|
44322
|
+
const images = (input.images ?? []).map((src) => archiveImage(dir, src));
|
|
44323
|
+
const entry = {
|
|
44324
|
+
ts: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
44325
|
+
message,
|
|
44326
|
+
...input.step ? { step: input.step, stepNumber: JOURNEY_STEPS.indexOf(input.step) + 1 } : {},
|
|
44327
|
+
...images.length ? { images } : {}
|
|
44328
|
+
};
|
|
44329
|
+
mkdirSync23(join43(dir, ".himi"), { recursive: true });
|
|
44330
|
+
const file = join43(dir, PROGRESS_FILE);
|
|
44331
|
+
appendFileSync(file, `${endsWithNewline(file) ? "" : "\n"}${JSON.stringify(entry)}
|
|
44332
|
+
`);
|
|
44333
|
+
return entry;
|
|
44334
|
+
}
|
|
44335
|
+
function endsWithNewline(file) {
|
|
44336
|
+
if (!existsSync46(file)) return true;
|
|
44337
|
+
const size = statSync10(file).size;
|
|
44338
|
+
if (size === 0) return true;
|
|
44339
|
+
const fd = openSync(file, "r");
|
|
44340
|
+
try {
|
|
44341
|
+
const last = Buffer.alloc(1);
|
|
44342
|
+
readSync(fd, last, 0, 1, size - 1);
|
|
44343
|
+
return last[0] === 10;
|
|
44344
|
+
} finally {
|
|
44345
|
+
closeSync(fd);
|
|
44346
|
+
}
|
|
44347
|
+
}
|
|
44348
|
+
function isEntry(v) {
|
|
44349
|
+
if (!v || typeof v !== "object") return false;
|
|
44350
|
+
const e = v;
|
|
44351
|
+
return typeof e.ts === "string" && typeof e.message === "string";
|
|
44352
|
+
}
|
|
44353
|
+
function readProgress(dir) {
|
|
44354
|
+
const file = join43(dir, PROGRESS_FILE);
|
|
44355
|
+
if (!existsSync46(file)) return { entries: [], skipped: 0 };
|
|
44356
|
+
const entries = [];
|
|
44357
|
+
let skipped = 0;
|
|
44358
|
+
for (const line of readFileSync50(file, "utf8").split("\n")) {
|
|
44359
|
+
if (!line.trim()) continue;
|
|
44360
|
+
try {
|
|
44361
|
+
const parsed = JSON.parse(line);
|
|
44362
|
+
if (isEntry(parsed)) entries.push(parsed);
|
|
44363
|
+
else skipped++;
|
|
44364
|
+
} catch {
|
|
44365
|
+
skipped++;
|
|
44366
|
+
}
|
|
44367
|
+
}
|
|
44368
|
+
return { entries, skipped };
|
|
44369
|
+
}
|
|
44370
|
+
function summarizeProgress(entries) {
|
|
44371
|
+
if (!entries.length) return { count: 0 };
|
|
44372
|
+
const stepped = [...entries].reverse().find((e) => e.step && JOURNEY_STEPS.includes(e.step));
|
|
44373
|
+
const first = entries[0];
|
|
44374
|
+
const last = entries[entries.length - 1];
|
|
44375
|
+
const elapsed = Date.parse(last.ts) - Date.parse(first.ts);
|
|
44376
|
+
return {
|
|
44377
|
+
count: entries.length,
|
|
44378
|
+
...stepped?.step ? { current: { step: stepped.step, stepNumber: JOURNEY_STEPS.indexOf(stepped.step) + 1, of: JOURNEY_STEPS.length } } : {},
|
|
44379
|
+
startedAt: first.ts,
|
|
44380
|
+
lastAt: last.ts,
|
|
44381
|
+
...Number.isFinite(elapsed) ? { elapsedMs: elapsed } : {},
|
|
44382
|
+
last
|
|
44383
|
+
};
|
|
44384
|
+
}
|
|
44385
|
+
function appleScriptString(s) {
|
|
44386
|
+
return `"${s.replace(/[\r\n]+/g, " ").replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
44387
|
+
}
|
|
44388
|
+
function runNotifier(cmd, args) {
|
|
44389
|
+
return new Promise((done) => {
|
|
44390
|
+
let settled = false;
|
|
44391
|
+
const finish2 = (ok) => {
|
|
44392
|
+
if (!settled) {
|
|
44393
|
+
settled = true;
|
|
44394
|
+
clearTimeout(timer);
|
|
44395
|
+
done(ok);
|
|
44396
|
+
}
|
|
44397
|
+
};
|
|
44398
|
+
const child = spawn3(cmd, args, { stdio: "ignore" });
|
|
44399
|
+
const timer = setTimeout(() => {
|
|
44400
|
+
child.kill();
|
|
44401
|
+
finish2(false);
|
|
44402
|
+
}, NOTIFY_TIMEOUT_MS);
|
|
44403
|
+
child.on("error", () => finish2(false));
|
|
44404
|
+
child.on("exit", (code) => finish2(code === 0));
|
|
44405
|
+
});
|
|
44406
|
+
}
|
|
44407
|
+
async function notifyDesktop(title, body, deps = {}) {
|
|
44408
|
+
const platform = deps.platform ?? process.platform;
|
|
44409
|
+
const run2 = deps.run ?? runNotifier;
|
|
44410
|
+
try {
|
|
44411
|
+
if (platform === "darwin") {
|
|
44412
|
+
return await run2("osascript", ["-e", `display notification ${appleScriptString(body)} with title ${appleScriptString(title)}`]);
|
|
44413
|
+
}
|
|
44414
|
+
if (platform === "linux") return await run2("notify-send", [title, body]);
|
|
44415
|
+
} catch {
|
|
44416
|
+
return false;
|
|
44417
|
+
}
|
|
44418
|
+
return false;
|
|
44419
|
+
}
|
|
44420
|
+
function appLabel(dir) {
|
|
44421
|
+
try {
|
|
44422
|
+
const manifest = JSON.parse(readFileSync50(join43(dir, "himalaya.content.json"), "utf8"));
|
|
44423
|
+
return typeof manifest.name === "string" && manifest.name ? manifest.name : null;
|
|
44424
|
+
} catch {
|
|
44425
|
+
return null;
|
|
44426
|
+
}
|
|
44427
|
+
}
|
|
44428
|
+
function journalPath(dir) {
|
|
44429
|
+
const abs = join43(dir, PROGRESS_FILE);
|
|
44430
|
+
const rel = relative6(process.cwd(), abs);
|
|
44431
|
+
return rel && !rel.startsWith("..") ? rel : abs;
|
|
44432
|
+
}
|
|
44433
|
+
var JOURNEY_STEPS, PROGRESS_FILE, HISTORY_DIR, MAX_MESSAGE_CHARS, MAX_IMAGE_BYTES, ProgressError, toPosix, NOTIFY_TIMEOUT_MS;
|
|
44434
|
+
var init_progress = __esm({
|
|
44435
|
+
"src/progress.ts"() {
|
|
44436
|
+
JOURNEY_STEPS = ["discover", "classify", "plan", "implement", "brand", "validate", "review", "download"];
|
|
44437
|
+
PROGRESS_FILE = join43(".himi", "progress.jsonl");
|
|
44438
|
+
HISTORY_DIR = join43(".himi", "history");
|
|
44439
|
+
MAX_MESSAGE_CHARS = 500;
|
|
44440
|
+
MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
44441
|
+
ProgressError = class extends Error {
|
|
44442
|
+
constructor(code, message) {
|
|
44443
|
+
super(message);
|
|
44444
|
+
this.code = code;
|
|
44445
|
+
}
|
|
44446
|
+
};
|
|
44447
|
+
toPosix = (p) => p.split(sep10).join("/");
|
|
44448
|
+
NOTIFY_TIMEOUT_MS = 3e3;
|
|
44449
|
+
}
|
|
44450
|
+
});
|
|
44451
|
+
|
|
44206
44452
|
// src/native-decode.ts
|
|
44207
44453
|
var native_decode_exports = {};
|
|
44208
44454
|
__export(native_decode_exports, {
|
|
@@ -44218,9 +44464,9 @@ __export(native_decode_exports, {
|
|
|
44218
44464
|
runNativeDecode: () => runNativeDecode
|
|
44219
44465
|
});
|
|
44220
44466
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
44221
|
-
import { existsSync as
|
|
44467
|
+
import { existsSync as existsSync47, mkdtempSync as mkdtempSync2, readFileSync as readFileSync51, rmSync as rmSync9, writeFileSync as writeFileSync20 } from "node:fs";
|
|
44222
44468
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
44223
|
-
import { join as
|
|
44469
|
+
import { join as join44 } from "node:path";
|
|
44224
44470
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
44225
44471
|
function nativeDecodePackageDir() {
|
|
44226
44472
|
return fileURLToPath20(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
|
|
@@ -44230,8 +44476,8 @@ function nativeDecodeAndroidHarnessDir() {
|
|
|
44230
44476
|
}
|
|
44231
44477
|
function nativeOracleShipped() {
|
|
44232
44478
|
return {
|
|
44233
|
-
ios:
|
|
44234
|
-
android:
|
|
44479
|
+
ios: existsSync47(join44(nativeDecodePackageDir(), "Package.swift")),
|
|
44480
|
+
android: existsSync47(join44(nativeDecodeAndroidHarnessDir(), "gradlew"))
|
|
44235
44481
|
};
|
|
44236
44482
|
}
|
|
44237
44483
|
function detectNativeDecode(options = {}) {
|
|
@@ -44242,7 +44488,7 @@ function detectNativeDecode(options = {}) {
|
|
|
44242
44488
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
44243
44489
|
}
|
|
44244
44490
|
if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
|
|
44245
|
-
const packageAvailable = options.packageAvailable ??
|
|
44491
|
+
const packageAvailable = options.packageAvailable ?? existsSync47(join44(packageDir, "Package.swift"));
|
|
44246
44492
|
if (!packageAvailable) {
|
|
44247
44493
|
return {
|
|
44248
44494
|
platform: "ios",
|
|
@@ -44254,7 +44500,7 @@ function detectNativeDecode(options = {}) {
|
|
|
44254
44500
|
}
|
|
44255
44501
|
function localPropertiesSdk(harnessDir) {
|
|
44256
44502
|
try {
|
|
44257
|
-
const match =
|
|
44503
|
+
const match = readFileSync51(join44(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
|
|
44258
44504
|
return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
|
|
44259
44505
|
} catch {
|
|
44260
44506
|
return null;
|
|
@@ -44262,8 +44508,8 @@ function localPropertiesSdk(harnessDir) {
|
|
|
44262
44508
|
}
|
|
44263
44509
|
function detectAndroidNativeDecode(options = {}) {
|
|
44264
44510
|
const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
|
|
44265
|
-
const gradlew =
|
|
44266
|
-
const gradlewAvailable = options.gradlewAvailable ??
|
|
44511
|
+
const gradlew = join44(harnessDir, "gradlew");
|
|
44512
|
+
const gradlewAvailable = options.gradlewAvailable ?? existsSync47(gradlew);
|
|
44267
44513
|
if (!gradlewAvailable) {
|
|
44268
44514
|
return {
|
|
44269
44515
|
platform: "android",
|
|
@@ -44273,7 +44519,7 @@ function detectAndroidNativeDecode(options = {}) {
|
|
|
44273
44519
|
}
|
|
44274
44520
|
const androidHome = options.androidHome ?? process.env.ANDROID_HOME ?? "";
|
|
44275
44521
|
const sdk = androidHome.trim() || (options.localPropertiesSdk !== void 0 ? options.localPropertiesSdk : localPropertiesSdk(harnessDir));
|
|
44276
|
-
const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 &&
|
|
44522
|
+
const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 && existsSync47(sdk));
|
|
44277
44523
|
if (!sdkAvailable) {
|
|
44278
44524
|
return {
|
|
44279
44525
|
platform: "android",
|
|
@@ -44345,14 +44591,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
|
|
|
44345
44591
|
return verdicts;
|
|
44346
44592
|
}
|
|
44347
44593
|
function runNativeDecode(options) {
|
|
44348
|
-
const descriptorDir = mkdtempSync2(
|
|
44594
|
+
const descriptorDir = mkdtempSync2(join44(tmpdir3(), "himi-native-decode-"));
|
|
44349
44595
|
const startedAt = Date.now();
|
|
44350
44596
|
try {
|
|
44351
44597
|
for (const descriptor of options.descriptors) {
|
|
44352
44598
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
44353
44599
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
44354
44600
|
}
|
|
44355
|
-
|
|
44601
|
+
writeFileSync20(join44(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
44356
44602
|
}
|
|
44357
44603
|
options.progress?.("building cached Swift oracle");
|
|
44358
44604
|
execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
|
|
@@ -44364,7 +44610,7 @@ function runNativeDecode(options) {
|
|
|
44364
44610
|
encoding: "utf8"
|
|
44365
44611
|
}).trim();
|
|
44366
44612
|
options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
44367
|
-
const stdout = execFileSync5(
|
|
44613
|
+
const stdout = execFileSync5(join44(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
|
|
44368
44614
|
stdio: ["ignore", "pipe", "pipe"],
|
|
44369
44615
|
encoding: "utf8"
|
|
44370
44616
|
});
|
|
@@ -44382,15 +44628,15 @@ function runNativeDecode(options) {
|
|
|
44382
44628
|
}
|
|
44383
44629
|
}
|
|
44384
44630
|
function runAndroidNativeDecode(options) {
|
|
44385
|
-
const descriptorDir = mkdtempSync2(
|
|
44386
|
-
const outputPath =
|
|
44631
|
+
const descriptorDir = mkdtempSync2(join44(tmpdir3(), "himi-native-decode-android-"));
|
|
44632
|
+
const outputPath = join44(descriptorDir, "verdicts.ndjson");
|
|
44387
44633
|
const startedAt = Date.now();
|
|
44388
44634
|
try {
|
|
44389
44635
|
for (const descriptor of options.descriptors) {
|
|
44390
44636
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
44391
44637
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
44392
44638
|
}
|
|
44393
|
-
|
|
44639
|
+
writeFileSync20(join44(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
44394
44640
|
}
|
|
44395
44641
|
options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
44396
44642
|
execFileSync5(options.gradlew, [
|
|
@@ -44405,7 +44651,7 @@ function runAndroidNativeDecode(options) {
|
|
|
44405
44651
|
stdio: ["ignore", "ignore", "pipe"],
|
|
44406
44652
|
encoding: "utf8"
|
|
44407
44653
|
});
|
|
44408
|
-
const stdout =
|
|
44654
|
+
const stdout = readFileSync51(outputPath, "utf8");
|
|
44409
44655
|
return {
|
|
44410
44656
|
platform: "android",
|
|
44411
44657
|
verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
|
|
@@ -44474,15 +44720,15 @@ __export(browser_authoring_exports, {
|
|
|
44474
44720
|
sdkSubpathReader: () => sdkSubpathReader
|
|
44475
44721
|
});
|
|
44476
44722
|
import { createServer as createServer3 } from "node:http";
|
|
44477
|
-
import { createHash as
|
|
44723
|
+
import { createHash as createHash23, randomBytes as randomBytes4 } from "node:crypto";
|
|
44478
44724
|
import { execFile as execFile2 } from "node:child_process";
|
|
44479
|
-
import { existsSync as
|
|
44480
|
-
import { join as
|
|
44725
|
+
import { existsSync as existsSync48, readdirSync as readdirSync23, readFileSync as readFileSync52, realpathSync as realpathSync4, statSync as statSync11 } from "node:fs";
|
|
44726
|
+
import { join as join45, posix, relative as relative7, sep as sep11 } from "node:path";
|
|
44481
44727
|
function humanMs(ms) {
|
|
44482
44728
|
return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
|
|
44483
44729
|
}
|
|
44484
44730
|
function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
44485
|
-
const root =
|
|
44731
|
+
const root = join45(tier5SrcDir, bundleName);
|
|
44486
44732
|
const files = {};
|
|
44487
44733
|
const visitedDirs = /* @__PURE__ */ new Set();
|
|
44488
44734
|
const walk2 = (abs, rel) => {
|
|
@@ -44490,16 +44736,16 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
|
44490
44736
|
if (visitedDirs.has(real)) return;
|
|
44491
44737
|
visitedDirs.add(real);
|
|
44492
44738
|
for (const name of readdirSync23(abs).sort()) {
|
|
44493
|
-
const childAbs =
|
|
44739
|
+
const childAbs = join45(abs, name);
|
|
44494
44740
|
const childRel = posix.join(rel, name);
|
|
44495
|
-
if (
|
|
44741
|
+
if (statSync11(childAbs).isDirectory()) {
|
|
44496
44742
|
walk2(childAbs, childRel);
|
|
44497
44743
|
} else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
|
|
44498
|
-
files[childRel] =
|
|
44744
|
+
files[childRel] = readFileSync52(childAbs, "utf8");
|
|
44499
44745
|
}
|
|
44500
44746
|
}
|
|
44501
44747
|
};
|
|
44502
|
-
if (!
|
|
44748
|
+
if (!existsSync48(root)) return null;
|
|
44503
44749
|
walk2(root, `/tier5-src/${bundleName}`);
|
|
44504
44750
|
const entry = [`/tier5-src/${bundleName}/index.ts`, `/tier5-src/${bundleName}/index.js`].find((p) => p in files);
|
|
44505
44751
|
if (!entry) return null;
|
|
@@ -44516,20 +44762,20 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
44516
44762
|
const spec = m[1];
|
|
44517
44763
|
const virtual = posix.normalize(posix.join(dir, spec));
|
|
44518
44764
|
if (!virtual.startsWith("/tier5-src/")) continue;
|
|
44519
|
-
const onDisk =
|
|
44765
|
+
const onDisk = join45(tier5SrcDir, virtual.slice("/tier5-src/".length));
|
|
44520
44766
|
const candidates = [
|
|
44521
44767
|
onDisk,
|
|
44522
44768
|
`${onDisk}.ts`,
|
|
44523
44769
|
`${onDisk}.js`,
|
|
44524
44770
|
onDisk.replace(/\.js$/, ".ts"),
|
|
44525
|
-
|
|
44526
|
-
|
|
44771
|
+
join45(onDisk, "index.ts"),
|
|
44772
|
+
join45(onDisk, "index.js")
|
|
44527
44773
|
];
|
|
44528
44774
|
for (const abs of candidates) {
|
|
44529
|
-
if (!
|
|
44530
|
-
const key2 = `/tier5-src/${
|
|
44775
|
+
if (!existsSync48(abs) || statSync11(abs).isDirectory()) continue;
|
|
44776
|
+
const key2 = `/tier5-src/${relative7(tier5SrcDir, abs).split(sep11).join(posix.sep)}`;
|
|
44531
44777
|
if (key2 in files) break;
|
|
44532
|
-
files[key2] =
|
|
44778
|
+
files[key2] = readFileSync52(abs, "utf8");
|
|
44533
44779
|
queue.push(key2);
|
|
44534
44780
|
break;
|
|
44535
44781
|
}
|
|
@@ -44561,10 +44807,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
44561
44807
|
for (const source of Object.values(files)) visit(source);
|
|
44562
44808
|
return { modules, unsupported };
|
|
44563
44809
|
}
|
|
44564
|
-
function sdkSubpathReader(
|
|
44810
|
+
function sdkSubpathReader(resolve46) {
|
|
44565
44811
|
return (sub) => {
|
|
44566
44812
|
try {
|
|
44567
|
-
return
|
|
44813
|
+
return readFileSync52(resolve46(`@wix/himalaya/${sub}`), "utf8");
|
|
44568
44814
|
} catch {
|
|
44569
44815
|
return null;
|
|
44570
44816
|
}
|
|
@@ -44574,7 +44820,7 @@ function encodeJob(job) {
|
|
|
44574
44820
|
return Buffer.from(JSON.stringify(job), "utf8").toString("base64");
|
|
44575
44821
|
}
|
|
44576
44822
|
function mintToken2(payload, nonce = randomBytes4(16).toString("hex")) {
|
|
44577
|
-
const digest2 =
|
|
44823
|
+
const digest2 = createHash23("sha256").update(payload, "utf8").digest("base64url");
|
|
44578
44824
|
return `${nonce}.${digest2}`;
|
|
44579
44825
|
}
|
|
44580
44826
|
function defaultOpenBrowser2(url) {
|
|
@@ -44645,7 +44891,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
44645
44891
|
const token = mintToken2(payload);
|
|
44646
44892
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
44647
44893
|
if (unusable) throw new Error(unusable);
|
|
44648
|
-
return await new Promise((
|
|
44894
|
+
return await new Promise((resolve46, reject) => {
|
|
44649
44895
|
let settled = false;
|
|
44650
44896
|
let url = "";
|
|
44651
44897
|
const server = createServer3();
|
|
@@ -44697,7 +44943,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
44697
44943
|
}
|
|
44698
44944
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
44699
44945
|
const report2 = body.result;
|
|
44700
|
-
finish2(() =>
|
|
44946
|
+
finish2(() => resolve46({ report: report2, url }));
|
|
44701
44947
|
})();
|
|
44702
44948
|
});
|
|
44703
44949
|
server.on("error", (e) => finish2(() => reject(e)));
|
|
@@ -44738,8 +44984,8 @@ __export(coverage_exports, {
|
|
|
44738
44984
|
suppressedNativeKeys: () => suppressedNativeKeys,
|
|
44739
44985
|
trendAndStore: () => trendAndStore
|
|
44740
44986
|
});
|
|
44741
|
-
import { existsSync as
|
|
44742
|
-
import { dirname as dirname26, join as
|
|
44987
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync24, readFileSync as readFileSync53, writeFileSync as writeFileSync21 } from "node:fs";
|
|
44988
|
+
import { dirname as dirname26, join as join46 } from "node:path";
|
|
44743
44989
|
function suppressedNativeKeys(oracle) {
|
|
44744
44990
|
return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
|
|
44745
44991
|
}
|
|
@@ -44909,11 +45155,11 @@ function assembleLedger(r, options = {}) {
|
|
|
44909
45155
|
return out;
|
|
44910
45156
|
}
|
|
44911
45157
|
function trendAndStore(dir, entries, suppressed) {
|
|
44912
|
-
const p =
|
|
45158
|
+
const p = join46(dir, LEDGER_FILE);
|
|
44913
45159
|
let previous = null;
|
|
44914
45160
|
try {
|
|
44915
|
-
if (
|
|
44916
|
-
const parsed = JSON.parse(
|
|
45161
|
+
if (existsSync49(p)) {
|
|
45162
|
+
const parsed = JSON.parse(readFileSync53(p, "utf8"));
|
|
44917
45163
|
if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k) => typeof k === "string");
|
|
44918
45164
|
}
|
|
44919
45165
|
} catch {
|
|
@@ -44921,8 +45167,8 @@ function trendAndStore(dir, entries, suppressed) {
|
|
|
44921
45167
|
const current = entries.map((e) => e.key);
|
|
44922
45168
|
const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key2) => (suppressed ?? []).includes(key2))])];
|
|
44923
45169
|
try {
|
|
44924
|
-
|
|
44925
|
-
|
|
45170
|
+
mkdirSync24(dirname26(p), { recursive: true });
|
|
45171
|
+
writeFileSync21(p, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
44926
45172
|
} catch {
|
|
44927
45173
|
return null;
|
|
44928
45174
|
}
|
|
@@ -44952,11 +45198,11 @@ function formatLedger(entries, trend) {
|
|
|
44952
45198
|
return out.join("\n");
|
|
44953
45199
|
}
|
|
44954
45200
|
function diffAndStoreObservations(dir, current) {
|
|
44955
|
-
const p =
|
|
45201
|
+
const p = join46(dir, OBS_FILE);
|
|
44956
45202
|
let previous = null;
|
|
44957
45203
|
try {
|
|
44958
|
-
if (
|
|
44959
|
-
const parsed = JSON.parse(
|
|
45204
|
+
if (existsSync49(p)) {
|
|
45205
|
+
const parsed = JSON.parse(readFileSync53(p, "utf8"));
|
|
44960
45206
|
if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
|
|
44961
45207
|
(v) => Array.isArray(v) && v.every((l) => typeof l === "string")
|
|
44962
45208
|
)) {
|
|
@@ -44966,8 +45212,8 @@ function diffAndStoreObservations(dir, current) {
|
|
|
44966
45212
|
} catch {
|
|
44967
45213
|
}
|
|
44968
45214
|
try {
|
|
44969
|
-
|
|
44970
|
-
|
|
45215
|
+
mkdirSync24(dirname26(p), { recursive: true });
|
|
45216
|
+
writeFileSync21(p, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
44971
45217
|
} catch {
|
|
44972
45218
|
return null;
|
|
44973
45219
|
}
|
|
@@ -45005,8 +45251,8 @@ var LEDGER_FILE, OBS_FILE;
|
|
|
45005
45251
|
var init_coverage = __esm({
|
|
45006
45252
|
"src/coverage.ts"() {
|
|
45007
45253
|
init_native_decode();
|
|
45008
|
-
LEDGER_FILE =
|
|
45009
|
-
OBS_FILE =
|
|
45254
|
+
LEDGER_FILE = join46(".himi", "test-ledger.json");
|
|
45255
|
+
OBS_FILE = join46(".himi", "test-observations.json");
|
|
45010
45256
|
}
|
|
45011
45257
|
});
|
|
45012
45258
|
|
|
@@ -45017,11 +45263,11 @@ __export(design_kits_exports, {
|
|
|
45017
45263
|
kitsDir: () => kitsDir,
|
|
45018
45264
|
listKits: () => listKits2
|
|
45019
45265
|
});
|
|
45020
|
-
import { existsSync as
|
|
45021
|
-
import { join as
|
|
45266
|
+
import { existsSync as existsSync50, readFileSync as readFileSync54, readdirSync as readdirSync24 } from "node:fs";
|
|
45267
|
+
import { join as join47, basename as basename10 } from "node:path";
|
|
45022
45268
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
45023
45269
|
function kitsDir() {
|
|
45024
|
-
return KIT_DIR_CANDIDATES.find((p) =>
|
|
45270
|
+
return KIT_DIR_CANDIDATES.find((p) => existsSync50(p));
|
|
45025
45271
|
}
|
|
45026
45272
|
function listKits2() {
|
|
45027
45273
|
const dir = kitsDir();
|
|
@@ -45045,7 +45291,7 @@ In a published @wix/himalaya-cli this is a packaging bug \u2014 the kits should
|
|
|
45045
45291
|
if (!kits.includes(name)) {
|
|
45046
45292
|
return { ok: false, kit: name, kits, problems: [`no design kit named "${name}". Available: ${kits.join(", ")}`] };
|
|
45047
45293
|
}
|
|
45048
|
-
const raw =
|
|
45294
|
+
const raw = readFileSync54(join47(dir, `${name}.json`), "utf8");
|
|
45049
45295
|
let parsed;
|
|
45050
45296
|
try {
|
|
45051
45297
|
parsed = JSON.parse(raw);
|
|
@@ -45069,9 +45315,9 @@ var init_design_kits = __esm({
|
|
|
45069
45315
|
"src/design-kits.ts"() {
|
|
45070
45316
|
KIT_DIR_CANDIDATES = [
|
|
45071
45317
|
// in-repo: tools/himi-cli/src/design-kits.ts → <repo>/stdlib/design-kits/
|
|
45072
|
-
|
|
45318
|
+
join47(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
|
|
45073
45319
|
// published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/design-kits/
|
|
45074
|
-
|
|
45320
|
+
join47(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
|
|
45075
45321
|
];
|
|
45076
45322
|
}
|
|
45077
45323
|
});
|
|
@@ -45085,11 +45331,11 @@ __export(assets_exports, {
|
|
|
45085
45331
|
removeAssetPayload: () => removeAssetPayload,
|
|
45086
45332
|
verifyReport: () => verifyReport
|
|
45087
45333
|
});
|
|
45088
|
-
import { readFileSync as
|
|
45334
|
+
import { readFileSync as readFileSync55 } from "node:fs";
|
|
45089
45335
|
import { basename as basename11 } from "node:path";
|
|
45090
45336
|
function declaredAssets(dir) {
|
|
45091
45337
|
return collectAssets(dir).map((a) => {
|
|
45092
|
-
const bytes2 =
|
|
45338
|
+
const bytes2 = readFileSync55(a.path);
|
|
45093
45339
|
return {
|
|
45094
45340
|
name: a.name,
|
|
45095
45341
|
sha256: assetSha256(bytes2),
|
|
@@ -45166,7 +45412,7 @@ function verifyReport(dir, app, manifest) {
|
|
|
45166
45412
|
};
|
|
45167
45413
|
}
|
|
45168
45414
|
function addAssetPayload(manifest, filePath, opts) {
|
|
45169
|
-
const bytes2 =
|
|
45415
|
+
const bytes2 = readFileSync55(filePath);
|
|
45170
45416
|
const name = opts.name ?? basename11(filePath);
|
|
45171
45417
|
const sha2565 = assetSha256(bytes2);
|
|
45172
45418
|
const record2 = {
|
|
@@ -45863,9 +46109,9 @@ ${releaseId}`;
|
|
|
45863
46109
|
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
45864
46110
|
const cookie = request.headers.get("cookie") ?? "";
|
|
45865
46111
|
if (!/wixSession2=/.test(cookie)) return json3(401, { error: "webwix_owner_no_session" });
|
|
45866
|
-
|
|
46112
|
+
const renew = url.searchParams.get("renew") === "1";
|
|
45867
46113
|
try {
|
|
45868
|
-
const entry = await webwixOwnerInstances.entry(msid, cookie);
|
|
46114
|
+
const entry = await webwixOwnerInstances.entry(msid, cookie, Date.now(), { renew });
|
|
45869
46115
|
return json3(200, { ...entry, expiresInMs: Math.max(0, entry.expiresAt - Date.now()) }, { "cache-control": "no-store" });
|
|
45870
46116
|
} catch (e) {
|
|
45871
46117
|
const msg = String(e?.message ?? e);
|
|
@@ -46642,19 +46888,19 @@ var init_preview_assets_generated = __esm({
|
|
|
46642
46888
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
46643
46889
|
init_preview_assets_format();
|
|
46644
46890
|
PREVIEW_ASSET_MANIFEST = [
|
|
46645
|
-
{ key: "assets/index-
|
|
46646
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
46647
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
46648
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
46649
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
46650
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
46651
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
46652
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
46653
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
46654
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
46655
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
46656
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
46657
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
46891
|
+
{ key: "assets/index-tPdez24X.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1012335, sha256: "9af3d246668e3b69acbdbaebf33129e45f99fdaa32230f782b675fcdeeb38773" },
|
|
46892
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1012343, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
46893
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1103267, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
46894
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1194251, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
46895
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1285231, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
46896
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1376103, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
46897
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1467083, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
46898
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1575719, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
46899
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1684803, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
46900
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1793851, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
46901
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1901551, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
46902
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 1989659, length: 4448, sha256: "c4235c7ba4a7bdea831017711424c9e4f8a8b33466bef53f4def1bfcea6a3b15" },
|
|
46903
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1994107, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
46658
46904
|
];
|
|
46659
46905
|
}
|
|
46660
46906
|
});
|
|
@@ -46670,11 +46916,11 @@ __export(run_exports, {
|
|
|
46670
46916
|
runPackage: () => runPackage,
|
|
46671
46917
|
withoutProdServe: () => withoutProdServe
|
|
46672
46918
|
});
|
|
46673
|
-
import { cpSync as cpSync2, existsSync as
|
|
46919
|
+
import { cpSync as cpSync2, existsSync as existsSync51, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync56, rmSync as rmSync10, statSync as statSync12 } from "node:fs";
|
|
46674
46920
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
46675
|
-
import { dirname as dirname27, join as
|
|
46921
|
+
import { dirname as dirname27, join as join48 } from "node:path";
|
|
46676
46922
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
46677
|
-
import { spawn as
|
|
46923
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
46678
46924
|
function makePackageRunHandler(opts) {
|
|
46679
46925
|
return makeRunHandler({
|
|
46680
46926
|
store: new FileReleaseStore(opts.releaseRoot),
|
|
@@ -46691,9 +46937,9 @@ async function fetchBytes(url) {
|
|
|
46691
46937
|
}
|
|
46692
46938
|
async function resolvePackage(source, workDir) {
|
|
46693
46939
|
const isUrl2 = /^https?:\/\//i.test(source);
|
|
46694
|
-
if (!isUrl2 &&
|
|
46695
|
-
const appDirManifest =
|
|
46696
|
-
if (
|
|
46940
|
+
if (!isUrl2 && existsSync51(source) && statSync12(source).isDirectory()) {
|
|
46941
|
+
const appDirManifest = join48(source, "release-manifest.json");
|
|
46942
|
+
if (existsSync51(appDirManifest)) {
|
|
46697
46943
|
const opened2 = openPackageDir(source);
|
|
46698
46944
|
if (!opened2.validation.ok) {
|
|
46699
46945
|
throw new Error(`package is not valid:
|
|
@@ -46702,10 +46948,10 @@ async function resolvePackage(source, workDir) {
|
|
|
46702
46948
|
const app2 = opened2.header?.app ?? opened2.manifest?.app;
|
|
46703
46949
|
if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
|
|
46704
46950
|
if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
|
|
46705
|
-
const root2 = workDir ?? mkdtempSync3(
|
|
46706
|
-
const target =
|
|
46707
|
-
if (
|
|
46708
|
-
|
|
46951
|
+
const root2 = workDir ?? mkdtempSync3(join48(tmpdir4(), "himi-run-"));
|
|
46952
|
+
const target = join48(root2, app2);
|
|
46953
|
+
if (join48(source) !== target) {
|
|
46954
|
+
mkdirSync25(root2, { recursive: true });
|
|
46709
46955
|
rmSync10(target, { recursive: true, force: true });
|
|
46710
46956
|
cpSync2(source, target, { recursive: true });
|
|
46711
46957
|
}
|
|
@@ -46721,8 +46967,8 @@ async function resolvePackage(source, workDir) {
|
|
|
46721
46967
|
}
|
|
46722
46968
|
throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
|
|
46723
46969
|
}
|
|
46724
|
-
const bytes2 = isUrl2 ? await fetchBytes(source) :
|
|
46725
|
-
const root = workDir ?? mkdtempSync3(
|
|
46970
|
+
const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync56(source);
|
|
46971
|
+
const root = workDir ?? mkdtempSync3(join48(tmpdir4(), "himi-run-"));
|
|
46726
46972
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
46727
46973
|
const opened = openPackageDir(appDir2);
|
|
46728
46974
|
if (!opened.validation.ok) {
|
|
@@ -46745,14 +46991,14 @@ async function loadPreviewAssets() {
|
|
|
46745
46991
|
const mod = await Promise.resolve().then(() => (init_preview_assets_generated(), preview_assets_generated_exports));
|
|
46746
46992
|
const here = dirname27(fileURLToPath22(import.meta.url));
|
|
46747
46993
|
const candidates = [
|
|
46748
|
-
|
|
46994
|
+
join48(here, "preview-assets.generated.bin"),
|
|
46749
46995
|
// published: copied next to the bundled CLI
|
|
46750
|
-
|
|
46996
|
+
join48(here, "../../../packages/serve/src/preview-assets.generated.bin")
|
|
46751
46997
|
// in-repo checkout
|
|
46752
46998
|
];
|
|
46753
46999
|
for (const path2 of candidates) {
|
|
46754
|
-
if (!
|
|
46755
|
-
const blob =
|
|
47000
|
+
if (!existsSync51(path2)) continue;
|
|
47001
|
+
const blob = readFileSync56(path2);
|
|
46756
47002
|
return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
46757
47003
|
}
|
|
46758
47004
|
return /* @__PURE__ */ new Map();
|
|
@@ -46769,7 +47015,7 @@ function packageUrl(origin, app, opts = {}) {
|
|
|
46769
47015
|
function openBrowser(url) {
|
|
46770
47016
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
46771
47017
|
try {
|
|
46772
|
-
|
|
47018
|
+
spawn4(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
|
|
46773
47019
|
} catch {
|
|
46774
47020
|
}
|
|
46775
47021
|
}
|
|
@@ -46834,19 +47080,19 @@ __export(run_browser_exports, {
|
|
|
46834
47080
|
runInBrowser: () => runInBrowser
|
|
46835
47081
|
});
|
|
46836
47082
|
import { createServer as createServer5 } from "node:http";
|
|
46837
|
-
import { existsSync as
|
|
47083
|
+
import { existsSync as existsSync52, readFileSync as readFileSync57 } from "node:fs";
|
|
46838
47084
|
import { spawnSync as spawnSync3, execFile as execFile3 } from "node:child_process";
|
|
46839
|
-
import { dirname as dirname28, resolve as
|
|
47085
|
+
import { dirname as dirname28, resolve as resolve41 } from "node:path";
|
|
46840
47086
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
46841
47087
|
function stagedDir() {
|
|
46842
|
-
return process.env.HIMI_BROWSER_PLANE_OUT ?
|
|
47088
|
+
return process.env.HIMI_BROWSER_PLANE_OUT ? resolve41(process.env.HIMI_BROWSER_PLANE_OUT) : resolve41(REPO, "packages", "serve", "dist", "browser-plane");
|
|
46843
47089
|
}
|
|
46844
47090
|
function missingStaged() {
|
|
46845
|
-
return [...SERVED].filter((f) => !
|
|
47091
|
+
return [...SERVED].filter((f) => !existsSync52(resolve41(stagedDir(), f))).sort();
|
|
46846
47092
|
}
|
|
46847
47093
|
function ensureBrowserPlaneStaged() {
|
|
46848
47094
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
46849
|
-
const r = spawnSync3(process.execPath, [
|
|
47095
|
+
const r = spawnSync3(process.execPath, [resolve41(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
46850
47096
|
cwd: REPO,
|
|
46851
47097
|
encoding: "utf8"
|
|
46852
47098
|
});
|
|
@@ -46932,7 +47178,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
46932
47178
|
}
|
|
46933
47179
|
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
46934
47180
|
if (SERVED.has(name)) {
|
|
46935
|
-
if (!
|
|
47181
|
+
if (!existsSync52(resolve41(stagedDir(), name))) {
|
|
46936
47182
|
const restaged = ensureBrowserPlaneStaged();
|
|
46937
47183
|
if (!restaged.ok) {
|
|
46938
47184
|
res.writeHead(503, { "content-type": "application/json" });
|
|
@@ -46942,7 +47188,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
46942
47188
|
}
|
|
46943
47189
|
let bytes2;
|
|
46944
47190
|
try {
|
|
46945
|
-
bytes2 =
|
|
47191
|
+
bytes2 = readFileSync57(resolve41(stagedDir(), name));
|
|
46946
47192
|
} catch (e) {
|
|
46947
47193
|
res.writeHead(503, { "content-type": "application/json" });
|
|
46948
47194
|
res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
|
|
@@ -46986,7 +47232,7 @@ var init_run_browser = __esm({
|
|
|
46986
47232
|
"src/run-browser.ts"() {
|
|
46987
47233
|
init_file_store();
|
|
46988
47234
|
HERE = dirname28(fileURLToPath23(import.meta.url));
|
|
46989
|
-
REPO =
|
|
47235
|
+
REPO = resolve41(HERE, "..", "..", "..");
|
|
46990
47236
|
SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
|
|
46991
47237
|
}
|
|
46992
47238
|
});
|
|
@@ -47405,10 +47651,10 @@ __export(preflight_exports, {
|
|
|
47405
47651
|
parseStoreConfig: () => parseStoreConfig,
|
|
47406
47652
|
requireEnv: () => requireEnv
|
|
47407
47653
|
});
|
|
47408
|
-
import { existsSync as
|
|
47409
|
-
import { isAbsolute as isAbsolute3, relative as
|
|
47654
|
+
import { existsSync as existsSync53, readFileSync as readFileSync58 } from "node:fs";
|
|
47655
|
+
import { isAbsolute as isAbsolute3, relative as relative8, resolve as resolve42 } from "node:path";
|
|
47410
47656
|
function isInsideRepo(p) {
|
|
47411
|
-
const rel =
|
|
47657
|
+
const rel = relative8(REPO_ROOT3, resolve42(p));
|
|
47412
47658
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
|
|
47413
47659
|
}
|
|
47414
47660
|
function assertCredentialOutsideRepo(label2, p) {
|
|
@@ -47462,10 +47708,10 @@ function parseStoreConfig(text4) {
|
|
|
47462
47708
|
}
|
|
47463
47709
|
function loadStoreConfig(app) {
|
|
47464
47710
|
const p = storeConfigPath(app);
|
|
47465
|
-
if (!
|
|
47711
|
+
if (!existsSync53(p)) {
|
|
47466
47712
|
throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
47467
47713
|
}
|
|
47468
|
-
return parseStoreConfig(
|
|
47714
|
+
return parseStoreConfig(readFileSync58(p, "utf8"));
|
|
47469
47715
|
}
|
|
47470
47716
|
var init_preflight = __esm({
|
|
47471
47717
|
"../store-release/preflight.ts"() {
|
|
@@ -47484,19 +47730,19 @@ __export(credential_profile_exports, {
|
|
|
47484
47730
|
profilePath: () => profilePath,
|
|
47485
47731
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
47486
47732
|
});
|
|
47487
|
-
import { existsSync as
|
|
47733
|
+
import { existsSync as existsSync54, readFileSync as readFileSync59 } from "node:fs";
|
|
47488
47734
|
import { homedir as homedir5 } from "node:os";
|
|
47489
|
-
import { join as
|
|
47735
|
+
import { join as join49 } from "node:path";
|
|
47490
47736
|
function credentialsDir(home = homedir5()) {
|
|
47491
|
-
return
|
|
47737
|
+
return join49(home, ".himalaya", "store-credentials");
|
|
47492
47738
|
}
|
|
47493
47739
|
function profilePath(name, home = homedir5()) {
|
|
47494
47740
|
if (!PROFILE_NAME.test(name)) {
|
|
47495
47741
|
throw new Error(
|
|
47496
|
-
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${
|
|
47742
|
+
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join49(credentialsDir(home), "<name>.json")}; it is never a path.`
|
|
47497
47743
|
);
|
|
47498
47744
|
}
|
|
47499
|
-
return
|
|
47745
|
+
return join49(credentialsDir(home), `${name}.json`);
|
|
47500
47746
|
}
|
|
47501
47747
|
function parseProfile(text4, label2) {
|
|
47502
47748
|
let doc;
|
|
@@ -47527,8 +47773,8 @@ function resolveStoreCredentials(opts) {
|
|
|
47527
47773
|
const { app, cfg } = opts;
|
|
47528
47774
|
const env = opts.env ?? process.env;
|
|
47529
47775
|
const home = opts.home ?? homedir5();
|
|
47530
|
-
const read = opts.readProfile ?? ((p) =>
|
|
47531
|
-
const exists = opts.profileExists ??
|
|
47776
|
+
const read = opts.readProfile ?? ((p) => readFileSync59(p, "utf8"));
|
|
47777
|
+
const exists = opts.profileExists ?? existsSync54;
|
|
47532
47778
|
const ios = cfg.ios ?? {};
|
|
47533
47779
|
const flagName = opts.profileFlag?.trim();
|
|
47534
47780
|
const named = namedProfile(cfg, opts.profileFlag);
|
|
@@ -47608,9 +47854,9 @@ __export(preflight_app_exports, {
|
|
|
47608
47854
|
preflightApp: () => preflightApp,
|
|
47609
47855
|
profileAccount: () => profileAccount
|
|
47610
47856
|
});
|
|
47611
|
-
import { readFileSync as
|
|
47612
|
-
import { createHash as
|
|
47613
|
-
import { join as
|
|
47857
|
+
import { readFileSync as readFileSync60, existsSync as existsSync55, readdirSync as readdirSync25, statSync as statSync13 } from "node:fs";
|
|
47858
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
47859
|
+
import { join as join50 } from "node:path";
|
|
47614
47860
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
47615
47861
|
const f = [];
|
|
47616
47862
|
const has = (re, s) => re.test(s);
|
|
@@ -47674,13 +47920,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
47674
47920
|
}
|
|
47675
47921
|
}
|
|
47676
47922
|
async function preflightApp(app, opts = {}) {
|
|
47677
|
-
const projectYml =
|
|
47678
|
-
const storeConfig =
|
|
47923
|
+
const projectYml = existsSync55(iosProjectYml(app)) ? readFileSync60(iosProjectYml(app), "utf8") : "";
|
|
47924
|
+
const storeConfig = existsSync55(storeConfigPath(app)) ? readFileSync60(storeConfigPath(app), "utf8") : "";
|
|
47679
47925
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
47680
47926
|
const findings = analyze(
|
|
47681
47927
|
projectYml,
|
|
47682
47928
|
storeConfig,
|
|
47683
|
-
await appIconState(
|
|
47929
|
+
await appIconState(join50(appDir(app), "ios")),
|
|
47684
47930
|
profileAccount(app, storeConfig, opts)
|
|
47685
47931
|
);
|
|
47686
47932
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -47709,17 +47955,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
47709
47955
|
return f;
|
|
47710
47956
|
}
|
|
47711
47957
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
47712
|
-
const root =
|
|
47958
|
+
const root = join50(storeDir(app), "metadata");
|
|
47713
47959
|
const out = /* @__PURE__ */ new Set();
|
|
47714
|
-
if (
|
|
47960
|
+
if (existsSync55(root)) {
|
|
47715
47961
|
for (const n of readdirSync25(root)) if (n.endsWith(".txt")) out.add(n);
|
|
47716
47962
|
}
|
|
47717
|
-
if (
|
|
47963
|
+
if (existsSync55(join50(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
47718
47964
|
return out;
|
|
47719
47965
|
}
|
|
47720
47966
|
function reviewInfoFiles(app) {
|
|
47721
|
-
const dir =
|
|
47722
|
-
if (!
|
|
47967
|
+
const dir = join50(storeDir(app), "review_information");
|
|
47968
|
+
if (!existsSync55(dir)) return /* @__PURE__ */ new Set();
|
|
47723
47969
|
return new Set(readdirSync25(dir).filter((n) => n.endsWith(".txt")));
|
|
47724
47970
|
}
|
|
47725
47971
|
function isValidAppStoreSize(w, h) {
|
|
@@ -47829,12 +48075,12 @@ function analyzePlayListing(assets) {
|
|
|
47829
48075
|
return f;
|
|
47830
48076
|
}
|
|
47831
48077
|
function playListingAssets(app, locale = "en-US") {
|
|
47832
|
-
const dir =
|
|
48078
|
+
const dir = join50(storeDir(app), "play", locale, "images");
|
|
47833
48079
|
const read = (names) => {
|
|
47834
48080
|
for (const name of names) {
|
|
47835
|
-
const p =
|
|
48081
|
+
const p = join50(dir, name);
|
|
47836
48082
|
try {
|
|
47837
|
-
if (
|
|
48083
|
+
if (statSync13(p).isFile()) return { name, bytes: readFileSync60(p) };
|
|
47838
48084
|
} catch {
|
|
47839
48085
|
}
|
|
47840
48086
|
}
|
|
@@ -47865,26 +48111,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
47865
48111
|
return f;
|
|
47866
48112
|
}
|
|
47867
48113
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
47868
|
-
const dir =
|
|
47869
|
-
if (!
|
|
48114
|
+
const dir = join50(storeDir(app), "metadata", locale);
|
|
48115
|
+
if (!existsSync55(dir)) return /* @__PURE__ */ new Set();
|
|
47870
48116
|
return new Set(readdirSync25(dir).filter((n) => n.endsWith(".txt")));
|
|
47871
48117
|
}
|
|
47872
48118
|
function listScreenshots(app, locale = "en-US") {
|
|
47873
48119
|
const out = [];
|
|
47874
|
-
const flat =
|
|
47875
|
-
if (
|
|
48120
|
+
const flat = join50(storeDir(app), "screenshots", locale);
|
|
48121
|
+
if (existsSync55(flat)) {
|
|
47876
48122
|
for (const png of readdirSync25(flat).filter((n) => n.endsWith(".png"))) {
|
|
47877
|
-
const sz = pngSize(
|
|
48123
|
+
const sz = pngSize(readFileSync60(join50(flat, png)));
|
|
47878
48124
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
47879
48125
|
}
|
|
47880
48126
|
}
|
|
47881
|
-
const legacy =
|
|
47882
|
-
if (
|
|
48127
|
+
const legacy = join50(storeDir(app), "metadata", locale, "screenshots");
|
|
48128
|
+
if (existsSync55(legacy)) {
|
|
47883
48129
|
for (const deviceDir of readdirSync25(legacy)) {
|
|
47884
|
-
const d =
|
|
47885
|
-
if (!
|
|
48130
|
+
const d = join50(legacy, deviceDir);
|
|
48131
|
+
if (!statSync13(d).isDirectory()) continue;
|
|
47886
48132
|
for (const png of readdirSync25(d).filter((n) => n.endsWith(".png"))) {
|
|
47887
|
-
const sz = pngSize(
|
|
48133
|
+
const sz = pngSize(readFileSync60(join50(d, png)));
|
|
47888
48134
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
47889
48135
|
}
|
|
47890
48136
|
}
|
|
@@ -47892,13 +48138,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
47892
48138
|
return out;
|
|
47893
48139
|
}
|
|
47894
48140
|
function placeholderHashes2() {
|
|
47895
|
-
const templateIos =
|
|
47896
|
-
if (!
|
|
48141
|
+
const templateIos = join50(appDir("_template"), "ios");
|
|
48142
|
+
if (!existsSync55(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
47897
48143
|
for (const target of readdirSync25(templateIos)) {
|
|
47898
|
-
const p =
|
|
48144
|
+
const p = join50(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
47899
48145
|
try {
|
|
47900
|
-
if (!
|
|
47901
|
-
return [LEGACY_PLACEHOLDER_SHA2562,
|
|
48146
|
+
if (!statSync13(p).isFile()) continue;
|
|
48147
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash24("sha256").update(readFileSync60(p)).digest("hex")];
|
|
47902
48148
|
} catch {
|
|
47903
48149
|
}
|
|
47904
48150
|
}
|
|
@@ -47929,13 +48175,13 @@ async function pixelIssues(bytes2) {
|
|
|
47929
48175
|
}
|
|
47930
48176
|
}
|
|
47931
48177
|
async function appIconState(iosDir) {
|
|
47932
|
-
if (!
|
|
48178
|
+
if (!existsSync55(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
47933
48179
|
for (const target of readdirSync25(iosDir)) {
|
|
47934
|
-
const p =
|
|
48180
|
+
const p = join50(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
47935
48181
|
try {
|
|
47936
|
-
if (!
|
|
47937
|
-
const bytes2 =
|
|
47938
|
-
const hash =
|
|
48182
|
+
if (!statSync13(p).isFile()) continue;
|
|
48183
|
+
const bytes2 = readFileSync60(p);
|
|
48184
|
+
const hash = createHash24("sha256").update(bytes2).digest("hex");
|
|
47939
48185
|
const pixels = await pixelIssues(bytes2);
|
|
47940
48186
|
return {
|
|
47941
48187
|
exists: true,
|
|
@@ -48006,7 +48252,7 @@ __export(version_exports, {
|
|
|
48006
48252
|
setAndroidVersion: () => setAndroidVersion,
|
|
48007
48253
|
setIosVersion: () => setIosVersion
|
|
48008
48254
|
});
|
|
48009
|
-
import { readFileSync as
|
|
48255
|
+
import { readFileSync as readFileSync61, writeFileSync as writeFileSync22 } from "node:fs";
|
|
48010
48256
|
function readIosVersion(projectYml) {
|
|
48011
48257
|
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
48012
48258
|
const build2 = matchScalar(projectYml, "CFBundleVersion");
|
|
@@ -48064,15 +48310,15 @@ function setAndroidVersion(gradle, v) {
|
|
|
48064
48310
|
function bumpVersion(app, opts) {
|
|
48065
48311
|
const iosPath = iosProjectYml(app);
|
|
48066
48312
|
const gradlePath = androidGradle(app);
|
|
48067
|
-
const iosYml =
|
|
48068
|
-
const gradle =
|
|
48313
|
+
const iosYml = readFileSync61(iosPath, "utf8");
|
|
48314
|
+
const gradle = readFileSync61(gradlePath, "utf8");
|
|
48069
48315
|
const current = readIosVersion(iosYml);
|
|
48070
48316
|
const next = {
|
|
48071
48317
|
marketing: opts.marketing ?? current.marketing,
|
|
48072
48318
|
build: opts.build === "increment" || opts.build === void 0 ? current.build + (opts.build === "increment" ? 1 : 0) : opts.build
|
|
48073
48319
|
};
|
|
48074
|
-
|
|
48075
|
-
|
|
48320
|
+
writeFileSync22(iosPath, setIosVersion(iosYml, next));
|
|
48321
|
+
writeFileSync22(gradlePath, setAndroidVersion(gradle, next));
|
|
48076
48322
|
return next;
|
|
48077
48323
|
}
|
|
48078
48324
|
var init_version = __esm({
|
|
@@ -48082,7 +48328,7 @@ var init_version = __esm({
|
|
|
48082
48328
|
});
|
|
48083
48329
|
|
|
48084
48330
|
// ../store-release/register-bundle.ts
|
|
48085
|
-
import { readFileSync as
|
|
48331
|
+
import { readFileSync as readFileSync62 } from "node:fs";
|
|
48086
48332
|
import { createPrivateKey as createPrivateKey2, sign } from "node:crypto";
|
|
48087
48333
|
function b64url2(b) {
|
|
48088
48334
|
return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -48100,7 +48346,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
|
|
|
48100
48346
|
async function registerBundleId(opts) {
|
|
48101
48347
|
const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48102
48348
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48103
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
48349
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync62(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
48104
48350
|
const res = await fetch(`${ASC_API}/v1/bundleIds`, {
|
|
48105
48351
|
method: "POST",
|
|
48106
48352
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
@@ -48154,7 +48400,7 @@ __export(asc_status_exports, {
|
|
|
48154
48400
|
ascStatus: () => ascStatus,
|
|
48155
48401
|
buildVerdict: () => buildVerdict
|
|
48156
48402
|
});
|
|
48157
|
-
import { readFileSync as
|
|
48403
|
+
import { readFileSync as readFileSync63 } from "node:fs";
|
|
48158
48404
|
function buildVerdict(builds) {
|
|
48159
48405
|
if (!builds.length) {
|
|
48160
48406
|
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).";
|
|
@@ -48168,7 +48414,7 @@ function buildVerdict(builds) {
|
|
|
48168
48414
|
function client(creds) {
|
|
48169
48415
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48170
48416
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48171
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
48417
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync63(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
48172
48418
|
return async (path2) => {
|
|
48173
48419
|
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
48174
48420
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
@@ -48328,7 +48574,7 @@ __export(secrets_exports, {
|
|
|
48328
48574
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
48329
48575
|
runSecretsCommand: () => runSecretsCommand
|
|
48330
48576
|
});
|
|
48331
|
-
import { readFileSync as
|
|
48577
|
+
import { readFileSync as readFileSync64 } from "node:fs";
|
|
48332
48578
|
function environment(value) {
|
|
48333
48579
|
if (value === "preview" || value === "production") return value;
|
|
48334
48580
|
throw new Error("--environment must be preview or production");
|
|
@@ -48359,7 +48605,7 @@ async function runSecretsCommand(operation, flags, io, options = {}) {
|
|
|
48359
48605
|
io.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
48360
48606
|
return 0;
|
|
48361
48607
|
}
|
|
48362
|
-
const value = options.readValue ? options.readValue() :
|
|
48608
|
+
const value = options.readValue ? options.readValue() : readFileSync64(0, "utf8").replace(/\r?\n$/, "");
|
|
48363
48609
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
48364
48610
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
48365
48611
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -48388,7 +48634,7 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
48388
48634
|
}
|
|
48389
48635
|
let body;
|
|
48390
48636
|
if (operation !== "list") {
|
|
48391
|
-
const value = options.readValue ? options.readValue() :
|
|
48637
|
+
const value = options.readValue ? options.readValue() : readFileSync64(0, "utf8").replace(/\r?\n$/, "");
|
|
48392
48638
|
body = JSON.stringify({ value });
|
|
48393
48639
|
}
|
|
48394
48640
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -48424,15 +48670,15 @@ __export(notify_exports, {
|
|
|
48424
48670
|
runNotify: () => runNotify,
|
|
48425
48671
|
saveAdminSession: () => saveAdminSession
|
|
48426
48672
|
});
|
|
48427
|
-
import { chmodSync as chmodSync3, mkdirSync as
|
|
48673
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync26, readFileSync as readFileSync65, writeFileSync as writeFileSync23 } from "node:fs";
|
|
48428
48674
|
import { homedir as homedir6 } from "node:os";
|
|
48429
|
-
import { dirname as dirname30, join as
|
|
48675
|
+
import { dirname as dirname30, join as join51 } from "node:path";
|
|
48430
48676
|
function defaultSessionsPath() {
|
|
48431
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
48677
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join51(homedir6(), ".himalaya", "admin-sessions.json");
|
|
48432
48678
|
}
|
|
48433
48679
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
48434
48680
|
try {
|
|
48435
|
-
return JSON.parse(
|
|
48681
|
+
return JSON.parse(readFileSync65(path2, "utf8"));
|
|
48436
48682
|
} catch {
|
|
48437
48683
|
return {};
|
|
48438
48684
|
}
|
|
@@ -48440,8 +48686,8 @@ function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
|
48440
48686
|
function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
|
|
48441
48687
|
const file = loadSessionsFile(path2);
|
|
48442
48688
|
file.sessions = { ...file.sessions, [adminUrl]: session };
|
|
48443
|
-
|
|
48444
|
-
|
|
48689
|
+
mkdirSync26(dirname30(path2), { recursive: true, mode: 448 });
|
|
48690
|
+
writeFileSync23(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
48445
48691
|
try {
|
|
48446
48692
|
chmodSync3(dirname30(path2), 448);
|
|
48447
48693
|
chmodSync3(path2, 384);
|
|
@@ -49979,6 +50225,26 @@ function tuneHighContrastAccent(brand, surface) {
|
|
|
49979
50225
|
}
|
|
49980
50226
|
return candidate;
|
|
49981
50227
|
}
|
|
50228
|
+
function stripBrandFromIdiom(tokens) {
|
|
50229
|
+
const idiom = tokens.idiom;
|
|
50230
|
+
if (!idiom || typeof idiom !== "object" || Array.isArray(idiom)) return;
|
|
50231
|
+
for (const overlay of Object.values(idiom)) {
|
|
50232
|
+
if (!overlay || typeof overlay !== "object" || Array.isArray(overlay)) continue;
|
|
50233
|
+
const o = overlay;
|
|
50234
|
+
const colors = o.colors;
|
|
50235
|
+
if (colors && typeof colors === "object" && !Array.isArray(colors)) {
|
|
50236
|
+
for (const key2 of BRAND_COLOR_TOKENS) delete colors[key2];
|
|
50237
|
+
if (Object.keys(colors).length === 0) delete o.colors;
|
|
50238
|
+
}
|
|
50239
|
+
const shadows = o.shadows;
|
|
50240
|
+
const glow = shadows && typeof shadows === "object" && !Array.isArray(shadows) ? shadows[BRAND_GLOW_SHADOW] : void 0;
|
|
50241
|
+
if (glow && typeof glow === "object" && !Array.isArray(glow) && "color" in glow) {
|
|
50242
|
+
delete glow.color;
|
|
50243
|
+
if (Object.keys(glow).length === 0) delete shadows[BRAND_GLOW_SHADOW];
|
|
50244
|
+
if (Object.keys(shadows).length === 0) delete o.shadows;
|
|
50245
|
+
}
|
|
50246
|
+
}
|
|
50247
|
+
}
|
|
49982
50248
|
function deriveAccentFamily(primary, secondary, surfaces) {
|
|
49983
50249
|
const primaryDark = tuneDarkAccent(primary, surfaces.dark, surfaces.light);
|
|
49984
50250
|
const secondaryDark = tuneDarkAccent(secondary, surfaces.dark, surfaces.light);
|
|
@@ -49999,7 +50265,7 @@ function deriveAccentFamily(primary, secondary, surfaces) {
|
|
|
49999
50265
|
}
|
|
50000
50266
|
};
|
|
50001
50267
|
}
|
|
50002
|
-
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET;
|
|
50268
|
+
var ACCENT_SURFACE_MIN_DELTA, ACCENT_SURFACE_LIGHT_WEIGHT, SECONDARY_SHADE_WEIGHT, SECONDARY_MIN_LSTAR, DARK_ARM_MIN_LIFT, DARK_ARM_TARGET_CONTRAST, DARK_ARM_FLOOR_CONTRAST, DARK_ARM_LSTAR_CAP, HIGH_CONTRAST_TARGET, BRAND_COLOR_TOKENS, BRAND_GLOW_SHADOW;
|
|
50003
50269
|
var init_brand_color_math = __esm({
|
|
50004
50270
|
"../../core/ts/src/brand-color-math.ts"() {
|
|
50005
50271
|
ACCENT_SURFACE_MIN_DELTA = 1.08;
|
|
@@ -50011,6 +50277,8 @@ var init_brand_color_math = __esm({
|
|
|
50011
50277
|
DARK_ARM_FLOOR_CONTRAST = 3;
|
|
50012
50278
|
DARK_ARM_LSTAR_CAP = 80;
|
|
50013
50279
|
HIGH_CONTRAST_TARGET = 8.5;
|
|
50280
|
+
BRAND_COLOR_TOKENS = ["accentPrimary", "accentSecondary", "accentSurface", "textOnAccent"];
|
|
50281
|
+
BRAND_GLOW_SHADOW = "glow";
|
|
50014
50282
|
}
|
|
50015
50283
|
});
|
|
50016
50284
|
|
|
@@ -51067,10 +51335,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
51067
51335
|
if (refusal) throw new Error(refusal);
|
|
51068
51336
|
}
|
|
51069
51337
|
function resolveAll(hostname2) {
|
|
51070
|
-
return new Promise((
|
|
51338
|
+
return new Promise((resolve46, reject) => {
|
|
51071
51339
|
dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
|
|
51072
51340
|
if (err) reject(err);
|
|
51073
|
-
else
|
|
51341
|
+
else resolve46(addresses);
|
|
51074
51342
|
});
|
|
51075
51343
|
});
|
|
51076
51344
|
}
|
|
@@ -51078,13 +51346,13 @@ function withAbort(start, signal, what) {
|
|
|
51078
51346
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
51079
51347
|
const work = start();
|
|
51080
51348
|
if (!signal) return work;
|
|
51081
|
-
return new Promise((
|
|
51349
|
+
return new Promise((resolve46, reject) => {
|
|
51082
51350
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
51083
51351
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
51084
|
-
work.then(
|
|
51352
|
+
work.then(resolve46, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
51085
51353
|
});
|
|
51086
51354
|
}
|
|
51087
|
-
async function pinAddress(url,
|
|
51355
|
+
async function pinAddress(url, resolve46 = resolveAll, signal) {
|
|
51088
51356
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
51089
51357
|
if (ipv4Octets(host)) {
|
|
51090
51358
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -51094,7 +51362,7 @@ async function pinAddress(url, resolve45 = resolveAll, signal) {
|
|
|
51094
51362
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
51095
51363
|
return { address: host, family: 6 };
|
|
51096
51364
|
}
|
|
51097
|
-
const addresses = await withAbort(() =>
|
|
51365
|
+
const addresses = await withAbort(() => resolve46(host), signal, `${host} lookup`);
|
|
51098
51366
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
51099
51367
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
51100
51368
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -51134,7 +51402,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
51134
51402
|
return out;
|
|
51135
51403
|
}
|
|
51136
51404
|
function requestOnce(url, pinned, init) {
|
|
51137
|
-
return new Promise((
|
|
51405
|
+
return new Promise((resolve46, reject) => {
|
|
51138
51406
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
51139
51407
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
51140
51408
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -51164,7 +51432,7 @@ function requestOnce(url, pinned, init) {
|
|
|
51164
51432
|
reject(err);
|
|
51165
51433
|
return;
|
|
51166
51434
|
}
|
|
51167
|
-
|
|
51435
|
+
resolve46(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
|
|
51168
51436
|
}
|
|
51169
51437
|
);
|
|
51170
51438
|
req.on("error", reject);
|
|
@@ -51967,8 +52235,8 @@ var init_brand_font = __esm({
|
|
|
51967
52235
|
});
|
|
51968
52236
|
|
|
51969
52237
|
// src/site-analyze/write-artifacts.ts
|
|
51970
|
-
import { mkdirSync as
|
|
51971
|
-
import { join as
|
|
52238
|
+
import { mkdirSync as mkdirSync27, writeFileSync as writeFileSync24 } from "node:fs";
|
|
52239
|
+
import { join as join52 } from "node:path";
|
|
51972
52240
|
function attachVeloSources(book, sources, put) {
|
|
51973
52241
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
51974
52242
|
for (const f of book.velo.files) {
|
|
@@ -52123,13 +52391,13 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
52123
52391
|
}
|
|
52124
52392
|
async function writeBusinessBook(result, opts) {
|
|
52125
52393
|
const out = opts.outDir;
|
|
52126
|
-
|
|
52127
|
-
|
|
52394
|
+
mkdirSync27(join52(out, "evidence/pages"), { recursive: true });
|
|
52395
|
+
mkdirSync27(join52(out, "media/catalog"), { recursive: true });
|
|
52128
52396
|
const files = [];
|
|
52129
52397
|
const put = (rel, body) => {
|
|
52130
|
-
const p =
|
|
52131
|
-
|
|
52132
|
-
|
|
52398
|
+
const p = join52(out, rel);
|
|
52399
|
+
mkdirSync27(join52(p, ".."), { recursive: true });
|
|
52400
|
+
writeFileSync24(p, body);
|
|
52133
52401
|
files.push(rel);
|
|
52134
52402
|
};
|
|
52135
52403
|
const book = result.book;
|
|
@@ -52222,15 +52490,15 @@ var init_customer_build = __esm({
|
|
|
52222
52490
|
});
|
|
52223
52491
|
|
|
52224
52492
|
// src/site-analyze/apply.ts
|
|
52225
|
-
import { existsSync as
|
|
52226
|
-
import { dirname as dirname31, isAbsolute as isAbsolute4, join as
|
|
52493
|
+
import { existsSync as existsSync56, readFileSync as readFileSync66, writeFileSync as writeFileSync25, copyFileSync as copyFileSync3, mkdirSync as mkdirSync28, realpathSync as realpathSync5, statSync as statSync14 } from "node:fs";
|
|
52494
|
+
import { dirname as dirname31, isAbsolute as isAbsolute4, join as join53, resolve as resolve43, sep as sep12 } from "node:path";
|
|
52227
52495
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
52228
52496
|
function unpairedRedirectNote(overlay) {
|
|
52229
52497
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
52230
52498
|
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)`;
|
|
52231
52499
|
}
|
|
52232
52500
|
function posix2(p) {
|
|
52233
|
-
return
|
|
52501
|
+
return resolve43(p).replace(/\\/g, "/");
|
|
52234
52502
|
}
|
|
52235
52503
|
function committedShellProvisioning(path2) {
|
|
52236
52504
|
return committedShellFor(posix2(path2));
|
|
@@ -52238,7 +52506,7 @@ function committedShellProvisioning(path2) {
|
|
|
52238
52506
|
function findRepoRoot(cwd) {
|
|
52239
52507
|
let dir = cwd;
|
|
52240
52508
|
for (let i = 0; i < 8; i++) {
|
|
52241
|
-
if (SHELL_NAMES2.some((name) =>
|
|
52509
|
+
if (SHELL_NAMES2.some((name) => existsSync56(join53(dir, shellAppDir(name), "package.json")))) return dir;
|
|
52242
52510
|
const next = dirname31(dir);
|
|
52243
52511
|
if (next === dir) break;
|
|
52244
52512
|
dir = next;
|
|
@@ -52264,7 +52532,7 @@ function assertNotCommitted(path2, forbidden) {
|
|
|
52264
52532
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
52265
52533
|
);
|
|
52266
52534
|
}
|
|
52267
|
-
if (forbidden &&
|
|
52535
|
+
if (forbidden && resolve43(path2) === resolve43(forbidden)) {
|
|
52268
52536
|
const named = committedShellProvisioning(forbidden);
|
|
52269
52537
|
throw new Error(
|
|
52270
52538
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -52306,24 +52574,24 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
52306
52574
|
}
|
|
52307
52575
|
function buildMergedContract(options) {
|
|
52308
52576
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
52309
|
-
const committedPath =
|
|
52310
|
-
if (!
|
|
52577
|
+
const committedPath = join53(appDir2, "provisioning.json");
|
|
52578
|
+
if (!existsSync56(committedPath)) {
|
|
52311
52579
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
52312
52580
|
}
|
|
52313
|
-
const committed = JSON.parse(
|
|
52581
|
+
const committed = JSON.parse(readFileSync66(committedPath, "utf8"));
|
|
52314
52582
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
52315
52583
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
52316
52584
|
const branding = merged.branding ?? {};
|
|
52317
52585
|
const staged = [];
|
|
52318
52586
|
const contained = (root, rel) => {
|
|
52319
52587
|
if (isAbsolute4(rel)) return void 0;
|
|
52320
|
-
const full =
|
|
52321
|
-
return full.startsWith(
|
|
52588
|
+
const full = resolve43(root, rel);
|
|
52589
|
+
return full.startsWith(resolve43(root) + sep12) ? full : void 0;
|
|
52322
52590
|
};
|
|
52323
52591
|
const stage = (fromRel, toRel) => {
|
|
52324
52592
|
const from = contained(packageDir, fromRel);
|
|
52325
|
-
const to = contained(
|
|
52326
|
-
if (!from || !to || !
|
|
52593
|
+
const to = contained(join53(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
52594
|
+
if (!from || !to || !existsSync56(from)) return void 0;
|
|
52327
52595
|
let real;
|
|
52328
52596
|
let realRoot;
|
|
52329
52597
|
try {
|
|
@@ -52332,10 +52600,10 @@ function buildMergedContract(options) {
|
|
|
52332
52600
|
} catch {
|
|
52333
52601
|
return void 0;
|
|
52334
52602
|
}
|
|
52335
|
-
if (!real.startsWith(realRoot +
|
|
52603
|
+
if (!real.startsWith(realRoot + sep12)) return void 0;
|
|
52336
52604
|
try {
|
|
52337
|
-
if (!
|
|
52338
|
-
|
|
52605
|
+
if (!statSync14(real).isFile()) return void 0;
|
|
52606
|
+
mkdirSync28(dirname31(to), { recursive: true });
|
|
52339
52607
|
copyFileSync3(real, to);
|
|
52340
52608
|
} catch {
|
|
52341
52609
|
return void 0;
|
|
@@ -52345,11 +52613,11 @@ function buildMergedContract(options) {
|
|
|
52345
52613
|
};
|
|
52346
52614
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
52347
52615
|
if (icon) branding.appIconPath = icon;
|
|
52348
|
-
const facesPath =
|
|
52349
|
-
if (
|
|
52616
|
+
const facesPath = join53(packageDir, "media/fonts/faces.json");
|
|
52617
|
+
if (existsSync56(facesPath)) {
|
|
52350
52618
|
let faces = [];
|
|
52351
52619
|
try {
|
|
52352
|
-
const parsed = JSON.parse(
|
|
52620
|
+
const parsed = JSON.parse(readFileSync66(facesPath, "utf8"));
|
|
52353
52621
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
52354
52622
|
} catch {
|
|
52355
52623
|
faces = [];
|
|
@@ -52370,20 +52638,20 @@ function buildMergedContract(options) {
|
|
|
52370
52638
|
merged.branding = branding;
|
|
52371
52639
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
52372
52640
|
`;
|
|
52373
|
-
const path2 =
|
|
52374
|
-
|
|
52375
|
-
const localPath =
|
|
52376
|
-
|
|
52377
|
-
|
|
52641
|
+
const path2 = join53(packageDir, "provisioning.contract.json");
|
|
52642
|
+
writeFileSync25(path2, body);
|
|
52643
|
+
const localPath = join53(appDir2, LOCAL_CONTRACT_REL);
|
|
52644
|
+
mkdirSync28(dirname31(localPath), { recursive: true });
|
|
52645
|
+
writeFileSync25(localPath, body);
|
|
52378
52646
|
staged.push(localPath);
|
|
52379
52647
|
return { path: path2, staged };
|
|
52380
52648
|
}
|
|
52381
52649
|
async function applyOverlays(input) {
|
|
52382
|
-
const cwd =
|
|
52650
|
+
const cwd = resolve43(input.cwd);
|
|
52383
52651
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
52384
52652
|
assertKnownShell(shell);
|
|
52385
|
-
const overlay = JSON.parse(
|
|
52386
|
-
const tokens = JSON.parse(
|
|
52653
|
+
const overlay = JSON.parse(readFileSync66(input.overlayPath, "utf8"));
|
|
52654
|
+
const tokens = JSON.parse(readFileSync66(input.tokensPath, "utf8"));
|
|
52387
52655
|
const wrote = [];
|
|
52388
52656
|
const notes = [];
|
|
52389
52657
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -52393,8 +52661,8 @@ async function applyOverlays(input) {
|
|
|
52393
52661
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
52394
52662
|
);
|
|
52395
52663
|
}
|
|
52396
|
-
const appDir2 =
|
|
52397
|
-
const packageDir = dirname31(
|
|
52664
|
+
const appDir2 = join53(repoRoot2, shellAppDir(shell));
|
|
52665
|
+
const packageDir = dirname31(resolve43(input.overlayPath));
|
|
52398
52666
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
52399
52667
|
wrote.push(...staged);
|
|
52400
52668
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -52415,32 +52683,41 @@ async function applyOverlays(input) {
|
|
|
52415
52683
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
52416
52684
|
};
|
|
52417
52685
|
}
|
|
52418
|
-
const pkgProv =
|
|
52686
|
+
const pkgProv = join53(cwd, "provisioning.json");
|
|
52419
52687
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
52420
|
-
if (
|
|
52421
|
-
const cur = JSON.parse(
|
|
52688
|
+
if (existsSync56(pkgProv)) {
|
|
52689
|
+
const cur = JSON.parse(readFileSync66(pkgProv, "utf8"));
|
|
52422
52690
|
const merged = deepMerge4(cur, overlay);
|
|
52423
|
-
|
|
52691
|
+
writeFileSync25(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
52424
52692
|
wrote.push(pkgProv);
|
|
52425
52693
|
} else {
|
|
52426
|
-
|
|
52694
|
+
writeFileSync25(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
52427
52695
|
wrote.push(pkgProv);
|
|
52428
52696
|
}
|
|
52429
|
-
const pkgTokens =
|
|
52430
|
-
if (
|
|
52431
|
-
const cur = JSON.parse(
|
|
52697
|
+
const pkgTokens = join53(cwd, "tokens.json");
|
|
52698
|
+
if (existsSync56(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
52699
|
+
const cur = JSON.parse(readFileSync66(pkgTokens, "utf8"));
|
|
52432
52700
|
const merged = deepMerge4(cur, tokens);
|
|
52433
52701
|
const mergedColors = merged.colors;
|
|
52434
52702
|
if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
|
|
52435
52703
|
merged.colors = alignAccentsToSurfaces(mergedColors, tokens.colors);
|
|
52436
52704
|
}
|
|
52437
|
-
|
|
52705
|
+
const bringsBrand = Object.keys(tokens.colors ?? {}).some((k) => BRAND_COLOR_TOKENS.includes(k));
|
|
52706
|
+
if (bringsBrand) {
|
|
52707
|
+
const accent = tokens.colors?.accentPrimary;
|
|
52708
|
+
const primary = typeof accent === "string" ? accent : accent?.light;
|
|
52709
|
+
const shadows = merged.shadows;
|
|
52710
|
+
const glow = shadows && typeof shadows === "object" && !Array.isArray(shadows) ? shadows[BRAND_GLOW_SHADOW] : void 0;
|
|
52711
|
+
if (primary && glow && typeof glow.color === "string") glow.color = primary;
|
|
52712
|
+
stripBrandFromIdiom(merged);
|
|
52713
|
+
}
|
|
52714
|
+
writeFileSync25(pkgTokens, JSON.stringify(merged, null, 2) + "\n");
|
|
52438
52715
|
wrote.push(pkgTokens);
|
|
52439
52716
|
}
|
|
52440
52717
|
const homeAction = homeRefreshActionId(shell);
|
|
52441
|
-
const homeSrc =
|
|
52442
|
-
if (homeAction &&
|
|
52443
|
-
const prev =
|
|
52718
|
+
const homeSrc = join53(cwd, "dev/index.ts");
|
|
52719
|
+
if (homeAction && existsSync56(homeSrc)) {
|
|
52720
|
+
const prev = readFileSync66(homeSrc, "utf8");
|
|
52444
52721
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
52445
52722
|
let next = patched.src;
|
|
52446
52723
|
if (!patched.foreign && overlay.installedVerticals?.length) {
|
|
@@ -52456,20 +52733,20 @@ async function applyOverlays(input) {
|
|
|
52456
52733
|
}
|
|
52457
52734
|
}
|
|
52458
52735
|
if (next !== prev) {
|
|
52459
|
-
|
|
52736
|
+
writeFileSync25(homeSrc, next);
|
|
52460
52737
|
wrote.push(homeSrc);
|
|
52461
52738
|
}
|
|
52462
52739
|
if (patched.unparsed) {
|
|
52463
52740
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
52464
52741
|
}
|
|
52465
52742
|
}
|
|
52466
|
-
if (!input.iconPath || !
|
|
52467
|
-
const book = input.iconPath ? dirname31(dirname31(
|
|
52743
|
+
if (!input.iconPath || !existsSync56(input.iconPath)) {
|
|
52744
|
+
const book = input.iconPath ? dirname31(dirname31(resolve43(input.iconPath))) : void 0;
|
|
52468
52745
|
notes.push(
|
|
52469
52746
|
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"
|
|
52470
52747
|
);
|
|
52471
52748
|
}
|
|
52472
|
-
if (input.iconPath &&
|
|
52749
|
+
if (input.iconPath && existsSync56(input.iconPath)) {
|
|
52473
52750
|
try {
|
|
52474
52751
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
52475
52752
|
wrote.push(...installed.wrote);
|
|
@@ -52554,6 +52831,7 @@ var init_apply2 = __esm({
|
|
|
52554
52831
|
init_brandable_shells();
|
|
52555
52832
|
init_customer_build();
|
|
52556
52833
|
init_branding_derive();
|
|
52834
|
+
init_brand_color_math();
|
|
52557
52835
|
init_home_descriptor();
|
|
52558
52836
|
STAGED = ".himi/brand";
|
|
52559
52837
|
}
|
|
@@ -53406,10 +53684,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
53406
53684
|
}
|
|
53407
53685
|
function createPromiseCallback(cb) {
|
|
53408
53686
|
let callback;
|
|
53409
|
-
let
|
|
53687
|
+
let resolve46;
|
|
53410
53688
|
let reject;
|
|
53411
53689
|
const promise = new Promise((_resolve, _reject) => {
|
|
53412
|
-
|
|
53690
|
+
resolve46 = _resolve;
|
|
53413
53691
|
reject = _reject;
|
|
53414
53692
|
});
|
|
53415
53693
|
if (typeof cb === "function") {
|
|
@@ -53425,7 +53703,7 @@ function createPromiseCallback(cb) {
|
|
|
53425
53703
|
callback = (err, result) => {
|
|
53426
53704
|
try {
|
|
53427
53705
|
if (err) reject(err);
|
|
53428
|
-
else
|
|
53706
|
+
else resolve46(result);
|
|
53429
53707
|
} catch (e) {
|
|
53430
53708
|
reject(e instanceof Error ? e : new Error());
|
|
53431
53709
|
}
|
|
@@ -56623,8 +56901,8 @@ __export(cli_exports, {
|
|
|
56623
56901
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
56624
56902
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
56625
56903
|
});
|
|
56626
|
-
import { readFileSync as
|
|
56627
|
-
import { resolve as
|
|
56904
|
+
import { readFileSync as readFileSync67 } from "node:fs";
|
|
56905
|
+
import { resolve as resolve44 } from "node:path";
|
|
56628
56906
|
function assetFetchFor(_opts) {
|
|
56629
56907
|
return pinnedFetch2;
|
|
56630
56908
|
}
|
|
@@ -56633,7 +56911,7 @@ async function runSiteAnalyze(opts) {
|
|
|
56633
56911
|
const assetFetch = assetFetchFor(opts);
|
|
56634
56912
|
const siteFetch = guardedSiteFetch;
|
|
56635
56913
|
const cwd = opts.cwd ?? process.cwd();
|
|
56636
|
-
const outDir =
|
|
56914
|
+
const outDir = resolve44(cwd, opts.outDir ?? ".himi/business-book");
|
|
56637
56915
|
let ownerAuth;
|
|
56638
56916
|
let msid;
|
|
56639
56917
|
try {
|
|
@@ -56671,9 +56949,9 @@ async function runSiteAnalyze(opts) {
|
|
|
56671
56949
|
if (opts.apply) {
|
|
56672
56950
|
applied = await applyOverlays({
|
|
56673
56951
|
cwd,
|
|
56674
|
-
overlayPath:
|
|
56675
|
-
tokensPath:
|
|
56676
|
-
iconPath:
|
|
56952
|
+
overlayPath: resolve44(outDir, "provisioning.overlay.json"),
|
|
56953
|
+
tokensPath: resolve44(outDir, "tokens.overlay.json"),
|
|
56954
|
+
iconPath: resolve44(outDir, "media/icon.png"),
|
|
56677
56955
|
shell: opts.shell
|
|
56678
56956
|
});
|
|
56679
56957
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -56709,8 +56987,8 @@ async function runSiteFunctionCli(opts) {
|
|
|
56709
56987
|
const token = opts.token ?? await siteToken(msid);
|
|
56710
56988
|
let source;
|
|
56711
56989
|
if (opts.sourcePath) {
|
|
56712
|
-
const p =
|
|
56713
|
-
source =
|
|
56990
|
+
const p = resolve44(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
56991
|
+
source = readFileSync67(p, "utf8");
|
|
56714
56992
|
}
|
|
56715
56993
|
let body;
|
|
56716
56994
|
if (opts.bodyRaw != null) {
|
|
@@ -56753,15 +57031,15 @@ var init_cli = __esm({
|
|
|
56753
57031
|
});
|
|
56754
57032
|
|
|
56755
57033
|
// src/wix-account.ts
|
|
56756
|
-
import { spawn as
|
|
56757
|
-
async function accountToken2(spawnImpl =
|
|
57034
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
57035
|
+
async function accountToken2(spawnImpl = spawn5) {
|
|
56758
57036
|
if (cached2) return cached2;
|
|
56759
57037
|
const fromEnv = process.env.WIX_TEST_TOKEN?.trim();
|
|
56760
57038
|
if (fromEnv) {
|
|
56761
57039
|
cached2 = fromEnv;
|
|
56762
57040
|
return fromEnv;
|
|
56763
57041
|
}
|
|
56764
|
-
const token = await new Promise((
|
|
57042
|
+
const token = await new Promise((resolve46, reject) => {
|
|
56765
57043
|
let child;
|
|
56766
57044
|
try {
|
|
56767
57045
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -56790,7 +57068,7 @@ async function accountToken2(spawnImpl = spawn4) {
|
|
|
56790
57068
|
const scan = (d) => {
|
|
56791
57069
|
out += String(d);
|
|
56792
57070
|
const m = out.match(TOKEN_RE2);
|
|
56793
|
-
if (m) done(() =>
|
|
57071
|
+
if (m) done(() => resolve46(m[0]));
|
|
56794
57072
|
};
|
|
56795
57073
|
child.stdout?.on("data", scan);
|
|
56796
57074
|
child.stderr?.on("data", scan);
|
|
@@ -56810,7 +57088,7 @@ function apiKeyAuth(env = process.env) {
|
|
|
56810
57088
|
const accountId = env.WIX_ACCOUNT_ID?.trim();
|
|
56811
57089
|
return key2 && accountId ? { key: key2, accountId } : void 0;
|
|
56812
57090
|
}
|
|
56813
|
-
function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl =
|
|
57091
|
+
function accountTransport(fetchImpl = fetch, timeoutMs = DEFAULT_TIMEOUT_MS5, spawnImpl = spawn5) {
|
|
56814
57092
|
return async (method, path2, body) => {
|
|
56815
57093
|
const viaKey = apiKeyAuth();
|
|
56816
57094
|
const headers2 = viaKey ? { Authorization: viaKey.key, "wix-account-id": viaKey.accountId, Accept: "application/json" } : { Authorization: await accountToken2(spawnImpl), Accept: "application/json" };
|
|
@@ -56967,7 +57245,7 @@ __export(site_create_exports, {
|
|
|
56967
57245
|
runSiteList: () => runSiteList,
|
|
56968
57246
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
56969
57247
|
});
|
|
56970
|
-
import { existsSync as
|
|
57248
|
+
import { existsSync as existsSync57, readFileSync as readFileSync68, writeFileSync as writeFileSync26 } from "node:fs";
|
|
56971
57249
|
import { resolve as resolvePath2 } from "node:path";
|
|
56972
57250
|
function oauthClientName(projectName) {
|
|
56973
57251
|
return `${projectName} client`;
|
|
@@ -57116,7 +57394,7 @@ async function runSiteCreate(opts) {
|
|
|
57116
57394
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
57117
57395
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
57118
57396
|
}
|
|
57119
|
-
function writeProvisioningBinding(target, binding2, fs = { existsSync:
|
|
57397
|
+
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync57, readFileSync: readFileSync68, writeFileSync: writeFileSync26 }) {
|
|
57120
57398
|
const msid = binding2.siteId;
|
|
57121
57399
|
const path2 = resolvePath2(target);
|
|
57122
57400
|
const committed = committedShellProvisioning(path2);
|
|
@@ -57789,11 +58067,11 @@ var init_context = __esm({
|
|
|
57789
58067
|
});
|
|
57790
58068
|
|
|
57791
58069
|
// src/cli.ts
|
|
57792
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as
|
|
57793
|
-
import { execFile as execFile4, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as
|
|
57794
|
-
import { createHash as
|
|
58070
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync69, mkdirSync as mkdirSync29, writeFileSync as writeFileSync27, existsSync as existsSync58, rmSync as rmSync11, readdirSync as readdirSync26, statSync as statSync15, lstatSync as lstatSync6, accessSync, constants } from "node:fs";
|
|
58071
|
+
import { execFile as execFile4, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
|
|
58072
|
+
import { createHash as createHash25, randomUUID as randomUUID3 } from "node:crypto";
|
|
57795
58073
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
57796
|
-
import { join as
|
|
58074
|
+
import { join as join54, resolve as resolve45, relative as relative9, basename as basename12, dirname as dirname32 } from "node:path";
|
|
57797
58075
|
import { fileURLToPath as fileURLToPath24 } from "node:url";
|
|
57798
58076
|
|
|
57799
58077
|
// ../serve-cli/src/client.ts
|
|
@@ -59505,7 +59783,7 @@ async function browserLogin(opts) {
|
|
|
59505
59783
|
const log = opts.log ?? (() => {
|
|
59506
59784
|
});
|
|
59507
59785
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
59508
|
-
return await new Promise((
|
|
59786
|
+
return await new Promise((resolve46, reject) => {
|
|
59509
59787
|
let settled = false;
|
|
59510
59788
|
let loginUrl = "";
|
|
59511
59789
|
const server = createServer();
|
|
@@ -59569,7 +59847,7 @@ async function browserLogin(opts) {
|
|
|
59569
59847
|
return;
|
|
59570
59848
|
}
|
|
59571
59849
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
59572
|
-
finish2(() =>
|
|
59850
|
+
finish2(() => resolve46({ token, loginUrl }));
|
|
59573
59851
|
});
|
|
59574
59852
|
});
|
|
59575
59853
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -60935,7 +61213,7 @@ function writeAgentContext(targetDir) {
|
|
|
60935
61213
|
// src/cli.ts
|
|
60936
61214
|
init_wix_placeholders();
|
|
60937
61215
|
var defaultIO = { log: (l) => console.log(l), error: (l) => console.error(l), isTTY: process.stdout.isTTY === true };
|
|
60938
|
-
var REPEATABLE_FLAGS = /* @__PURE__ */ new Set(["data"]);
|
|
61216
|
+
var REPEATABLE_FLAGS = /* @__PURE__ */ new Set(["data", "image"]);
|
|
60939
61217
|
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
60940
61218
|
"browser",
|
|
60941
61219
|
"no-open",
|
|
@@ -61002,7 +61280,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
61002
61280
|
"refresh",
|
|
61003
61281
|
"push-setup",
|
|
61004
61282
|
"no-push-setup",
|
|
61005
|
-
"apple-signing"
|
|
61283
|
+
"apple-signing",
|
|
61284
|
+
"notify"
|
|
61006
61285
|
]);
|
|
61007
61286
|
var SHELL_ENUM = SHELL_NAMES2.join("|");
|
|
61008
61287
|
var SWITCH_FLAGS = new Set([...BOOLEAN_FLAGS].filter((name) => name !== "deep"));
|
|
@@ -61071,8 +61350,8 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
61071
61350
|
var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
61072
61351
|
function embeddedTemplateCatalog() {
|
|
61073
61352
|
return availableTemplates().map((name) => {
|
|
61074
|
-
const path2 =
|
|
61075
|
-
const meta = JSON.parse(
|
|
61353
|
+
const path2 = join54(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
61354
|
+
const meta = JSON.parse(readFileSync69(path2, "utf8"));
|
|
61076
61355
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
61077
61356
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
61078
61357
|
}
|
|
@@ -61129,6 +61408,11 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
61129
61408
|
verticals; zero network). Catches the wrong reducers
|
|
61130
61409
|
validate/render pass (NaN totals, stuck skeletons, dead
|
|
61131
61410
|
taps). Exit 1 on any error. Run it after every edit.
|
|
61411
|
+
himi progress ["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]
|
|
61412
|
+
journal a postcard for the owner (.himi/progress.jsonl): what
|
|
61413
|
+
changed, which journey step, and the image that shows it (copied
|
|
61414
|
+
into .himi/history/ so later renders cannot replace it). Bare
|
|
61415
|
+
prints the journal, the current step and the elapsed time.
|
|
61132
61416
|
himi ux audit [--content <dir>] [--strict] [--json]
|
|
61133
61417
|
inspect the mobile UX contract, template placeholders, app fixtures,
|
|
61134
61418
|
and recorded iOS/Android audit evidence. Advisory by default; --strict
|
|
@@ -61673,6 +61957,7 @@ var COMMANDS = [
|
|
|
61673
61957
|
{ name: "validate", summary: "lint the content package (no push): fixed-contract TypeScript checking for tier5-src workers + schema/proto + token refs + component allowlist + $service bindings + strict-enum foot-guns + capability decls + worker boot dry-run + build/compile failures. Type issues are advisory warnings normally; --strict promotes them and hygiene warnings to errors. Exit 1 on any error. Off-repo, the CLI supplies its compiler and SDK declarations.", required: "[--content <dir>] [--strict]" },
|
|
61674
61958
|
{ name: "test", summary: "DERIVED behavioral crawl \u2014 no test files to write. Boots each screen's real worker, replays its onAppear, then dispatches every action site the descriptor already declares (each from a fresh boot) and checks a narrow set of unambiguous invariants: no uncaught throw, never stuck on `loading`, no `$service:` token or NaN/undefined/[object Object] reaching visible text, no binding aimed at state the worker never defines, no nav param silently dropped, no dead nav target. Catches what validate/render cannot \u2014 a WRONG REDUCER passes both with ok:true. Runs the worker in a DEVICE-PARITY sandbox (no setTimeout/setInterval, as on JSC/WebView) so a bundle that would die on device fails here. Crawls on HERMETIC DATA by default \u2014 zero network: the app's own dev/net-mocks.json first (--net <file> overrides), then the config's CMS `seed:` rows, then a canned fixture of frozen real vertical responses shipped with the CLI (exercises code paths, not API-contract truth) \u2014 so the success/mapping path runs, not just the failure UI. Two boot-only HOSTILE passes (every list empty; every request 500) then check the failure/empty day \u2014 corpus-proven, so their findings are errors. NAV EDGES are followed too: every himi.open site ($item params resolved against row 0 of its list, $service against worker state) and worker _nav directive is harvested, and each baked target is booted WITH the params the source sends \u2014 detail screens finally run their content arm; edge findings are errors tagged edge:<source>. --native runs both real native decoders over the exact baked JSON bytes; --native ios or --native android selects one. It is explicit, runs only from a Himalaya SOURCE CHECKOUT (the decoder oracles are that tree's own HimalayaCore Swift package and Gradle harness, which a published install does not ship), and needs the selected local toolchain. From a source checkout, default runs name missing native verdicts in the coverage ledger; elsewhere the ledger stays silent about them rather than offering a remedy you cannot run. --offline strips all data layers (the old reject-all axis); --no-hostile skips the hostile passes. --record (EXPLICIT, never automatic) refreshes dev/net-mocks.json from live reads first: it boots each screen (load + root onAppear ONLY \u2014 nothing the app's own launch would not fire; the tap/action crawl never sees the live transport, and only proven reads \u2014 GET, or read-shaped POST (/query, /search, /list*, \u2026) \u2014 ever reach the wire), freezes the round-trips, then crawls hermetically on the fresh fixture; record against a QA site, not production. Nodes it cannot judge headless are named, never silently passed. Exit 1 on any error. The CLI carries the authoring runtime off-repo; no per-app SDK install is required. --browser runs the whole loop (build \u2192 extract \u2192 validate \u2192 render \u2192 test) in YOUR browser instead of here, so the source never reaches a pod: it opens one screen's worker + descriptor in a tab, blocks on a loopback callback, and prints the report it posts back. One screen per tab \u2014 name it. --no-open prints the URL rather than launching a browser (SSH); --timeout <ms> bounds the wait, which matters because the page has no execution deadline of its own and an infinite loop in the worker hangs the tab.", required: "[<screenId>\u2026] [--content <dir>] [--net <file>] [--budget <ms>] [--deep [n]] [--record] [--native [ios|android]] [--no-shots] [--offline] [--no-hostile] [--all-screens] [--browser] [--no-open] [--timeout <ms>] [--json]" },
|
|
61675
61959
|
{ name: "ux", summary: "audit or record mobile UX evidence. `audit` checks the public-safe contract, seeded blank acceptance rows, placeholder source copy, app-specific mocks, and iOS/Android audit records. It warns while existing templates migrate; `--strict` promotes missing evidence. `record` stores checks performed on an installed iOS/Android build: `--checks` is required for passed|failed and empty for unavailable, which drove nothing and needs a `--reason` instead. `record` also STAMPS the release it audited (it resolves the id from a build, the same one a push would publish), because an unforced `himi push` of a release with screens refuses when no drive is recorded for THAT release, or when the one that is recorded says `failed` \u2014 the artifact stopped being advice nobody reads (#2955). `unavailable` still satisfies it; only `failed` refuses.", required: "audit [--content <dir>] [--strict] [--json] | record --content <dir> --platform ios|android --status passed|failed|unavailable [--checks back,keyboard,...] [--reason <text>]" },
|
|
61960
|
+
{ name: "progress", summary: 'the build JOURNAL an agent keeps for the owner while it works. `himi progress "<what changed>" --step <1-8|name> --image <png>` appends one postcard to .himi/progress.jsonl \u2014 the step is one of the customer journey\'s eight (discover, classify, plan, implement, brand, validate, review, download) \u2014 and COPIES each image, content-addressed, into .himi/history/, because .himi/shots/ is overwritten by every render and cleared by every full `himi test`, so a path into it would later show a different picture than the one the owner was sent. --image repeats. --notify also raises a best-effort desktop notification for an owner who stepped away. A bare `himi progress` prints the journal with the current step and elapsed time \u2014 also how an agent recovers its place after its context was compacted. Local only: nothing is sent anywhere.', required: '["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]' },
|
|
61676
61961
|
{ name: "render", summary: "headless-render a screen with the web renderer: render-tree + diagnostics, optional --png <file>, --scheme dark, --tree. Local by default (content dir). Pass --remote --app --release to hit GET /v1/preview/\u2026/render on the serve plane after a push. Boots the worker so $service bindings resolve; --static raw bindings; --live real Wix fetches; --state injects worker state; --input supplies pre-boot navigation params; --width/--device for PNG viewport; --rtl for dir=rtl + $env:isRTL.", required: "<screenId> [--content <dir>] [--scheme dark] [--png <file>] [--tree] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--remote --app --release]" },
|
|
61677
61962
|
{ name: "cms", summary: "inspect, provision, and seed the app's CMS (Wix Data) collections, declared as a `cms` block in config.ts. `query` is READ-ONLY \u2014 by default it fetches ONLY the physical ids `config.ts` declares (item counts + schema drift) and reports `siteScanned: false`; it never lists the site, so an UNDECLARED `himi_<app>_` collection this app owns is not reached without `--all`. `--all` SCANS the site \u2014 every collection it lists is labeled `owned`/`adopted`/`foreign`, and it describes every foreign one \u2014 id, non-system field keys + types, and the site's read role \u2014 so an app with no `cms` block at all can DISCOVER a collection to adopt (`--all` is the one case where a missing `cms` block is not 'nothing to do'). Foreign collections are described up to a cap and are never item-counted (`itemCount: null`), because a row count is one query each; `foreign.count` is how many the scan LISTED \u2014 it follows the list endpoint's pages, and `listingIncomplete: true` says when the walk stopped short of the end, with `unlistedCollections` counting what it left out when Wix gave a paging total \u2014 and `foreign.truncated` says how many of those went undescribed, each still NAMED in `foreign.others` (id + displayName), so a collection the site already has is never hidden behind the cap. The scan is OWNER-scoped \u2014 it needs --site <msid> (or WIX_SITE_ID) plus owner auth via `wix token`; a visitor token can read a public collection's ITEMS but can never enumerate collections, so there is no tokenless discovery path. `create` reconciles declared collections additively and idempotently, and REFUSES any id outside the app's `himi_<app>_` namespace, so it is safe against a production site. It reports declared-vs-site `permissionDrift` but never writes permissions unless asked with --apply-permissions, so a field reconcile can't silently revert access control changed in the dashboard. `seed` inserts the git-tracked `seed:` rows into EMPTY owned collections (--force to add to a non-empty one; --ai writes placeholder rows plus a refinement prompt for you to review). Adopted collections (declared by `wixId`) are read-only and never created, updated, or seeded. Site from --site <msid> or WIX_SITE_ID; owner auth via `wix token`.", required: "query|create|seed [--site <msid>] [--content <dir>] [--all] [--dry-run] [--force] [--allow-destructive] [--apply-permissions] [--only <id>] [--ai] [--count <n>]" },
|
|
61678
61963
|
{ name: "data", summary: "read-only plan or explicitly provision/seed declared KV and Wix Data resources. Preview and production are separate scopes. KV administration uses the operator data plane from --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN; draft push never calls it.", required: "plan|create|seed [--site <msid>] [--environment preview|production] [--content <dir>] [--data-url <url>] [--dry-run] [--force]" },
|
|
@@ -61721,7 +62006,7 @@ var COMMANDS = [
|
|
|
61721
62006
|
];
|
|
61722
62007
|
function cliVersion() {
|
|
61723
62008
|
try {
|
|
61724
|
-
return JSON.parse(
|
|
62009
|
+
return JSON.parse(readFileSync69(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
61725
62010
|
} catch {
|
|
61726
62011
|
return "unknown";
|
|
61727
62012
|
}
|
|
@@ -61772,16 +62057,16 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
61772
62057
|
}
|
|
61773
62058
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
61774
62059
|
function execNpmConfig(file, args, options) {
|
|
61775
|
-
return new Promise((
|
|
61776
|
-
execFile4(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) :
|
|
62060
|
+
return new Promise((resolve46, reject) => {
|
|
62061
|
+
execFile4(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve46(String(stdout)));
|
|
61777
62062
|
});
|
|
61778
62063
|
}
|
|
61779
62064
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
61780
62065
|
async function scopedRegistryBefore(lookup2, deadline) {
|
|
61781
62066
|
let cancel = () => {
|
|
61782
62067
|
};
|
|
61783
|
-
const expired = new Promise((
|
|
61784
|
-
const timer = setTimeout(() =>
|
|
62068
|
+
const expired = new Promise((resolve46) => {
|
|
62069
|
+
const timer = setTimeout(() => resolve46(void 0), Math.max(0, deadline - Date.now()));
|
|
61785
62070
|
cancel = () => clearTimeout(timer);
|
|
61786
62071
|
});
|
|
61787
62072
|
try {
|
|
@@ -61839,16 +62124,16 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
61839
62124
|
}
|
|
61840
62125
|
function packageVersion(path2) {
|
|
61841
62126
|
try {
|
|
61842
|
-
const version2 = JSON.parse(
|
|
62127
|
+
const version2 = JSON.parse(readFileSync69(path2, "utf8")).version;
|
|
61843
62128
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
61844
62129
|
} catch {
|
|
61845
62130
|
return void 0;
|
|
61846
62131
|
}
|
|
61847
62132
|
}
|
|
61848
62133
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
61849
|
-
let dir =
|
|
62134
|
+
let dir = resolve45(fromDir);
|
|
61850
62135
|
for (; ; ) {
|
|
61851
|
-
const version2 = packageVersion(
|
|
62136
|
+
const version2 = packageVersion(join54(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
61852
62137
|
if (version2) return { version: version2, source: "local" };
|
|
61853
62138
|
const parent = dirname32(dir);
|
|
61854
62139
|
if (parent === dir) break;
|
|
@@ -61858,7 +62143,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
61858
62143
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
61859
62144
|
try {
|
|
61860
62145
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
61861
|
-
const version2 = root ? packageVersion(
|
|
62146
|
+
const version2 = root ? packageVersion(join54(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
61862
62147
|
return version2 ? { version: version2, source: "global" } : {};
|
|
61863
62148
|
} catch {
|
|
61864
62149
|
return {};
|
|
@@ -61905,11 +62190,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
61905
62190
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
61906
62191
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
61907
62192
|
function updateCachePath(env = process.env) {
|
|
61908
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
62193
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join54(homedir7(), ".himalaya", "update-check.json");
|
|
61909
62194
|
}
|
|
61910
62195
|
function readUpdateCache(path2) {
|
|
61911
62196
|
try {
|
|
61912
|
-
const parsed = JSON.parse(
|
|
62197
|
+
const parsed = JSON.parse(readFileSync69(path2, "utf8"));
|
|
61913
62198
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
61914
62199
|
} catch {
|
|
61915
62200
|
return {};
|
|
@@ -61917,8 +62202,8 @@ function readUpdateCache(path2) {
|
|
|
61917
62202
|
}
|
|
61918
62203
|
function writeUpdateCache(path2, cache) {
|
|
61919
62204
|
try {
|
|
61920
|
-
|
|
61921
|
-
|
|
62205
|
+
mkdirSync29(dirname32(path2), { recursive: true, mode: 448 });
|
|
62206
|
+
writeFileSync27(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
|
|
61922
62207
|
} catch {
|
|
61923
62208
|
}
|
|
61924
62209
|
}
|
|
@@ -61959,12 +62244,12 @@ function npmInstallArgs(registry, version2) {
|
|
|
61959
62244
|
return ["i", "-g", `${CLI_PACKAGE}@${version2}`, `--registry=${pinned}`, `--@wix:registry=${pinned}`];
|
|
61960
62245
|
}
|
|
61961
62246
|
var INSTALLABLE_SPEC = /^(?:latest|\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/;
|
|
61962
|
-
function createUpdateRunner(
|
|
62247
|
+
function createUpdateRunner(spawn7 = spawnSync5) {
|
|
61963
62248
|
return {
|
|
61964
62249
|
install: async (registry, version2) => {
|
|
61965
62250
|
if (!isTrustedRegistry(registry)) return { ok: false, detail: `refusing untrusted registry ${registry}` };
|
|
61966
62251
|
if (!INSTALLABLE_SPEC.test(version2)) return { ok: false, detail: `refusing install spec ${JSON.stringify(version2)}` };
|
|
61967
|
-
const result =
|
|
62252
|
+
const result = spawn7("npm", npmInstallArgs(registry, version2), {
|
|
61968
62253
|
// npm's stdout goes to OUR stderr: in `himi <cmd> --json | jq` (and `himi upgrade --json`) its
|
|
61969
62254
|
// "added 212 packages" would otherwise land in stdout ahead of the envelope and break the
|
|
61970
62255
|
// parse — the agent case this whole feature exists for (#2985 review). And no stdin: an
|
|
@@ -61977,12 +62262,12 @@ function createUpdateRunner(spawn6 = spawnSync5) {
|
|
|
61977
62262
|
},
|
|
61978
62263
|
installedVersion: () => {
|
|
61979
62264
|
const root = globalNodeModulesRoot();
|
|
61980
|
-
return root ? packageVersion(
|
|
62265
|
+
return root ? packageVersion(join54(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
61981
62266
|
},
|
|
61982
62267
|
reexec: (argv) => {
|
|
61983
62268
|
const root = globalNodeModulesRoot();
|
|
61984
|
-
const entry = root ?
|
|
61985
|
-
if (!entry || !
|
|
62269
|
+
const entry = root ? join54(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
62270
|
+
if (!entry || !existsSync58(entry)) return void 0;
|
|
61986
62271
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
61987
62272
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
61988
62273
|
stdio: "inherit",
|
|
@@ -62029,7 +62314,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62029
62314
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
62030
62315
|
let content;
|
|
62031
62316
|
try {
|
|
62032
|
-
content =
|
|
62317
|
+
content = readFileSync69(path2, "utf8");
|
|
62033
62318
|
} catch {
|
|
62034
62319
|
continue;
|
|
62035
62320
|
}
|
|
@@ -62037,7 +62322,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62037
62322
|
let since = stamped;
|
|
62038
62323
|
if (!Number.isFinite(since)) {
|
|
62039
62324
|
try {
|
|
62040
|
-
since =
|
|
62325
|
+
since = statSync15(path2).mtimeMs;
|
|
62041
62326
|
} catch {
|
|
62042
62327
|
continue;
|
|
62043
62328
|
}
|
|
@@ -62052,14 +62337,14 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62052
62337
|
const mine = lockStamp(now);
|
|
62053
62338
|
const readLock = (path2) => {
|
|
62054
62339
|
try {
|
|
62055
|
-
return
|
|
62340
|
+
return readFileSync69(path2, "utf8");
|
|
62056
62341
|
} catch {
|
|
62057
62342
|
return void 0;
|
|
62058
62343
|
}
|
|
62059
62344
|
};
|
|
62060
62345
|
const tryCreate = (path2) => {
|
|
62061
62346
|
try {
|
|
62062
|
-
|
|
62347
|
+
writeFileSync27(path2, mine, { flag: "wx", mode: 384 });
|
|
62063
62348
|
return true;
|
|
62064
62349
|
} catch {
|
|
62065
62350
|
return false;
|
|
@@ -62073,7 +62358,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62073
62358
|
};
|
|
62074
62359
|
const release = () => removeIfMine(lockPath);
|
|
62075
62360
|
try {
|
|
62076
|
-
|
|
62361
|
+
mkdirSync29(dirname32(lockPath), { recursive: true, mode: 448 });
|
|
62077
62362
|
} catch {
|
|
62078
62363
|
return () => {
|
|
62079
62364
|
};
|
|
@@ -62137,7 +62422,7 @@ function supersededInCache(current, latest, now) {
|
|
|
62137
62422
|
const checkedAt = current.checkedAt ? Date.parse(current.checkedAt) : Number.NaN;
|
|
62138
62423
|
return Number.isFinite(checkedAt) && now - checkedAt < UPDATE_CHECK_INTERVAL_MS;
|
|
62139
62424
|
}
|
|
62140
|
-
function createUpdateRefreshSpawner(spawnFn =
|
|
62425
|
+
function createUpdateRefreshSpawner(spawnFn = spawn6, execArgv = process.execArgv) {
|
|
62141
62426
|
return () => {
|
|
62142
62427
|
try {
|
|
62143
62428
|
const child = spawnFn(process.execPath, [...loaderArgs(execArgv), fileURLToPath24(import.meta.url), UPDATE_REFRESH_COMMAND], {
|
|
@@ -62590,9 +62875,9 @@ function executableOnPath(name, env = process.env) {
|
|
|
62590
62875
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
62591
62876
|
for (const dir of entries) {
|
|
62592
62877
|
for (const suffix of suffixes) {
|
|
62593
|
-
const candidate =
|
|
62878
|
+
const candidate = join54(dir, `${name}${suffix}`);
|
|
62594
62879
|
try {
|
|
62595
|
-
if (!
|
|
62880
|
+
if (!statSync15(candidate).isFile()) continue;
|
|
62596
62881
|
if (process.platform !== "win32") accessSync(candidate, constants.X_OK);
|
|
62597
62882
|
return true;
|
|
62598
62883
|
} catch {
|
|
@@ -62699,7 +62984,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
62699
62984
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
62700
62985
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
62701
62986
|
const iosYmlPath = iosProjectYml2(app);
|
|
62702
|
-
const iosYml =
|
|
62987
|
+
const iosYml = existsSync58(iosYmlPath) ? readFileSync69(iosYmlPath, "utf8") : "";
|
|
62703
62988
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
62704
62989
|
if (!optedIn) {
|
|
62705
62990
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -62713,19 +62998,19 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
62713
62998
|
}
|
|
62714
62999
|
function readConfigSource(dir) {
|
|
62715
63000
|
try {
|
|
62716
|
-
return
|
|
63001
|
+
return readFileSync69(join54(dir, "config.ts"), "utf8");
|
|
62717
63002
|
} catch {
|
|
62718
63003
|
return null;
|
|
62719
63004
|
}
|
|
62720
63005
|
}
|
|
62721
63006
|
function writePngFile(path2, base64) {
|
|
62722
|
-
|
|
62723
|
-
|
|
63007
|
+
mkdirSync29(dirname32(path2), { recursive: true });
|
|
63008
|
+
writeFileSync27(path2, Buffer.from(base64, "base64"));
|
|
62724
63009
|
return path2;
|
|
62725
63010
|
}
|
|
62726
63011
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
62727
|
-
const dir =
|
|
62728
|
-
if (
|
|
63012
|
+
const dir = resolve45(parentDir, name);
|
|
63013
|
+
if (existsSync58(join54(dir, "himalaya.content.json"))) {
|
|
62729
63014
|
throw new Error(`content package already exists at ${dir}`);
|
|
62730
63015
|
}
|
|
62731
63016
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -62737,7 +63022,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
62737
63022
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
62738
63023
|
}
|
|
62739
63024
|
function contentDir(flags) {
|
|
62740
|
-
return
|
|
63025
|
+
return resolve45(str5(flags.content) ?? process.cwd());
|
|
62741
63026
|
}
|
|
62742
63027
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
62743
63028
|
const text4 = {};
|
|
@@ -62768,8 +63053,8 @@ function symlinkDestinationIssue(dest) {
|
|
|
62768
63053
|
function restoreDestinationIssue(dest, force) {
|
|
62769
63054
|
const link = symlinkDestinationIssue(dest);
|
|
62770
63055
|
if (link) return link;
|
|
62771
|
-
if (!
|
|
62772
|
-
if (!
|
|
63056
|
+
if (!existsSync58(dest)) return null;
|
|
63057
|
+
if (!statSync15(dest).isDirectory()) {
|
|
62773
63058
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
62774
63059
|
}
|
|
62775
63060
|
if (readdirSync26(dest).length > 0 && !force) {
|
|
@@ -62781,9 +63066,9 @@ function restoreDestinationIssue(dest, force) {
|
|
|
62781
63066
|
return null;
|
|
62782
63067
|
}
|
|
62783
63068
|
function isHimalayaMonorepoCheckout(start) {
|
|
62784
|
-
let dir =
|
|
63069
|
+
let dir = resolve45(start);
|
|
62785
63070
|
for (; ; ) {
|
|
62786
|
-
if (
|
|
63071
|
+
if (existsSync58(join54(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync58(join54(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
62787
63072
|
const parent = dirname32(dir);
|
|
62788
63073
|
if (parent === dir) return false;
|
|
62789
63074
|
dir = parent;
|
|
@@ -62825,8 +63110,8 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
62825
63110
|
const forBuild = Object.fromEntries(
|
|
62826
63111
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
62827
63112
|
);
|
|
62828
|
-
const repoRoot2 =
|
|
62829
|
-
const root =
|
|
63113
|
+
const repoRoot2 = resolve45(fileURLToPath24(new URL("../../..", import.meta.url)));
|
|
63114
|
+
const root = join54(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
62830
63115
|
const stillRunning = (pid) => {
|
|
62831
63116
|
try {
|
|
62832
63117
|
process.kill(pid, 0);
|
|
@@ -62840,21 +63125,21 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
62840
63125
|
if (!entry.isDirectory()) continue;
|
|
62841
63126
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
62842
63127
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
62843
|
-
rmSync11(
|
|
63128
|
+
rmSync11(join54(root, entry.name), { recursive: true, force: true });
|
|
62844
63129
|
}
|
|
62845
63130
|
}
|
|
62846
63131
|
} catch {
|
|
62847
63132
|
}
|
|
62848
|
-
const dest =
|
|
63133
|
+
const dest = join54(root, `${slug}-${process.pid}`);
|
|
62849
63134
|
rmSync11(dest, { recursive: true, force: true });
|
|
62850
|
-
|
|
63135
|
+
mkdirSync29(dest, { recursive: true });
|
|
62851
63136
|
materializeSource(forBuild, displayName, dest, slug);
|
|
62852
63137
|
return dest;
|
|
62853
63138
|
}
|
|
62854
63139
|
async function appId(dir) {
|
|
62855
63140
|
try {
|
|
62856
|
-
const { readFileSync:
|
|
62857
|
-
const m = JSON.parse(
|
|
63141
|
+
const { readFileSync: readFileSync70 } = await import("node:fs");
|
|
63142
|
+
const m = JSON.parse(readFileSync70(join54(dir, "himalaya.content.json"), "utf8"));
|
|
62858
63143
|
if (m.name) return m.name;
|
|
62859
63144
|
} catch {
|
|
62860
63145
|
}
|
|
@@ -62862,8 +63147,8 @@ async function appId(dir) {
|
|
|
62862
63147
|
}
|
|
62863
63148
|
async function contentVisibility(dir) {
|
|
62864
63149
|
try {
|
|
62865
|
-
const { readFileSync:
|
|
62866
|
-
const m = JSON.parse(
|
|
63150
|
+
const { readFileSync: readFileSync70 } = await import("node:fs");
|
|
63151
|
+
const m = JSON.parse(readFileSync70(join54(dir, "himalaya.content.json"), "utf8"));
|
|
62867
63152
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
62868
63153
|
} catch {
|
|
62869
63154
|
}
|
|
@@ -63065,7 +63350,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
63065
63350
|
return 0;
|
|
63066
63351
|
}
|
|
63067
63352
|
case "agent-init": {
|
|
63068
|
-
const dir =
|
|
63353
|
+
const dir = resolve45(str5(flags.dir) ?? process.cwd());
|
|
63069
63354
|
const res = writeAgentContext(dir);
|
|
63070
63355
|
print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
|
|
63071
63356
|
return 0;
|
|
@@ -63087,7 +63372,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
63087
63372
|
try {
|
|
63088
63373
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63089
63374
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
63090
|
-
out = mkdtempSync4(
|
|
63375
|
+
out = mkdtempSync4(join54(tmpdir5(), "himi-ux-record-"));
|
|
63091
63376
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63092
63377
|
const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
63093
63378
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -63265,7 +63550,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
63265
63550
|
let js;
|
|
63266
63551
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
63267
63552
|
try {
|
|
63268
|
-
js =
|
|
63553
|
+
js = readFileSync69(join54(outDir, candidate), "utf8");
|
|
63269
63554
|
break;
|
|
63270
63555
|
} catch {
|
|
63271
63556
|
}
|
|
@@ -63541,7 +63826,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63541
63826
|
return 2;
|
|
63542
63827
|
}
|
|
63543
63828
|
const template = str5(flags.template);
|
|
63544
|
-
const parentDir =
|
|
63829
|
+
const parentDir = resolve45(str5(flags.dir) ?? process.cwd());
|
|
63545
63830
|
if (template && flags.remote === true) {
|
|
63546
63831
|
try {
|
|
63547
63832
|
const res2 = await initFromRemoteTemplate(name, parentDir, template, client2());
|
|
@@ -63658,11 +63943,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63658
63943
|
return outcome.code;
|
|
63659
63944
|
}
|
|
63660
63945
|
if (sub === "publish") {
|
|
63661
|
-
const appDir2 =
|
|
63662
|
-
const sourceDir =
|
|
63946
|
+
const appDir2 = resolve45(str5(flags.dir) ?? process.cwd());
|
|
63947
|
+
const sourceDir = resolve45(str5(flags["source-dir"]) ?? appDir2);
|
|
63663
63948
|
let meta;
|
|
63664
63949
|
try {
|
|
63665
|
-
meta = JSON.parse(
|
|
63950
|
+
meta = JSON.parse(readFileSync69(join54(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
63666
63951
|
} catch {
|
|
63667
63952
|
io.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>)` }));
|
|
63668
63953
|
return 2;
|
|
@@ -63672,7 +63957,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63672
63957
|
return 2;
|
|
63673
63958
|
}
|
|
63674
63959
|
try {
|
|
63675
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
63960
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync69(join54(sourceDir, "tokens.json"), "utf8")));
|
|
63676
63961
|
meta = { ...appearance, ...meta };
|
|
63677
63962
|
} catch {
|
|
63678
63963
|
}
|
|
@@ -63684,13 +63969,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63684
63969
|
const force = flags.force === true;
|
|
63685
63970
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63686
63971
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
63687
|
-
const out = mkdtempSync4(
|
|
63972
|
+
const out = mkdtempSync4(join54(tmpdir5(), "himi-template-"));
|
|
63688
63973
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63689
63974
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
63690
63975
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
63691
63976
|
collect: { lint: true, strict }
|
|
63692
63977
|
});
|
|
63693
|
-
const scaffoldSourceFindings =
|
|
63978
|
+
const scaffoldSourceFindings = resolve45(sourceDir) === resolve45(appDir2) ? [] : [
|
|
63694
63979
|
...tokenColorIssues(sourceDir),
|
|
63695
63980
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
63696
63981
|
...await fontIssues(sourceDir, strict),
|
|
@@ -63733,13 +64018,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63733
64018
|
}));
|
|
63734
64019
|
return 1;
|
|
63735
64020
|
}
|
|
63736
|
-
const iconPath = str5(flags.icon) ?
|
|
64021
|
+
const iconPath = str5(flags.icon) ? resolve45(str5(flags.icon)) : templateIconPath(name);
|
|
63737
64022
|
let iconHash;
|
|
63738
64023
|
if (iconPath) {
|
|
63739
64024
|
try {
|
|
63740
|
-
const bytes2 =
|
|
64025
|
+
const bytes2 = readFileSync69(iconPath);
|
|
63741
64026
|
payload.icon = bytes2.toString("base64");
|
|
63742
|
-
iconHash =
|
|
64027
|
+
iconHash = createHash25("sha256").update(bytes2).digest("hex");
|
|
63743
64028
|
} catch {
|
|
63744
64029
|
}
|
|
63745
64030
|
}
|
|
@@ -63970,7 +64255,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63970
64255
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
63971
64256
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63972
64257
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
63973
|
-
const out = mkdtempSync4(
|
|
64258
|
+
const out = mkdtempSync4(join54(tmpdir5(), "himi-validate-"));
|
|
63974
64259
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63975
64260
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
63976
64261
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64007,7 +64292,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64007
64292
|
const path2 = dpxSessionTokenPath();
|
|
64008
64293
|
let raw;
|
|
64009
64294
|
try {
|
|
64010
|
-
raw =
|
|
64295
|
+
raw = readFileSync69(path2, "utf8");
|
|
64011
64296
|
} catch {
|
|
64012
64297
|
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`);
|
|
64013
64298
|
}
|
|
@@ -64124,6 +64409,49 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64124
64409
|
print({ ok: invoked.response.ok, app: loaded.app, releaseId: invoked.releaseId, status: invoked.response.status, body });
|
|
64125
64410
|
return invoked.response.ok ? 0 : 1;
|
|
64126
64411
|
}
|
|
64412
|
+
case "progress": {
|
|
64413
|
+
const { appendProgress: appendProgress2, readProgress: readProgress2, summarizeProgress: summarizeProgress2, parseStep: parseStep2, notifyDesktop: notifyDesktop2, appLabel: appLabel2, journalPath: journalPath2, ProgressError: ProgressError2, JOURNEY_STEPS: JOURNEY_STEPS2 } = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
64414
|
+
const dir = contentDir(flags);
|
|
64415
|
+
const journal = journalPath2(dir);
|
|
64416
|
+
const hint = existsSync58(join54(dir, "himalaya.content.json")) ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
|
|
64417
|
+
const message = pos.slice(1).join(" ").trim();
|
|
64418
|
+
if (!message) {
|
|
64419
|
+
if (flags.step !== void 0 || flags.image !== void 0 || flags.notify === true) {
|
|
64420
|
+
io.error(JSON.stringify({ ok: false, error: "message_required", hint: 'progress "<what changed>" --step <n> --image <png>' }));
|
|
64421
|
+
return 2;
|
|
64422
|
+
}
|
|
64423
|
+
const { entries, skipped } = readProgress2(dir);
|
|
64424
|
+
print({ ok: true, journal, ...summarizeProgress2(entries), entries, ...skipped ? { skipped } : {}, ...hint });
|
|
64425
|
+
return 0;
|
|
64426
|
+
}
|
|
64427
|
+
let step;
|
|
64428
|
+
if (flags.step !== void 0) {
|
|
64429
|
+
step = typeof flags.step === "string" ? parseStep2(flags.step) : null;
|
|
64430
|
+
if (!step) {
|
|
64431
|
+
io.error(JSON.stringify({ ok: false, error: "invalid_step", got: flags.step, expected: `1-8 or ${JOURNEY_STEPS2.join("|")}` }));
|
|
64432
|
+
return 2;
|
|
64433
|
+
}
|
|
64434
|
+
}
|
|
64435
|
+
const rawImages = flags.image;
|
|
64436
|
+
const images = rawImages === void 0 ? [] : Array.isArray(rawImages) ? rawImages : typeof rawImages === "string" ? [rawImages] : null;
|
|
64437
|
+
if (!images) {
|
|
64438
|
+
io.error(JSON.stringify({ ok: false, error: "image_path_required", hint: "--image <png>, repeatable" }));
|
|
64439
|
+
return 2;
|
|
64440
|
+
}
|
|
64441
|
+
try {
|
|
64442
|
+
const entry = appendProgress2(dir, { message, ...step ? { step } : {}, images });
|
|
64443
|
+
const notified = flags.notify === true ? await notifyDesktop2(`himi \xB7 ${appLabel2(dir) ?? "your app"}`, message) : void 0;
|
|
64444
|
+
const { count } = summarizeProgress2(readProgress2(dir).entries);
|
|
64445
|
+
print({ ok: true, entry, journal, count, ...notified === void 0 ? {} : { notified }, ...hint });
|
|
64446
|
+
return 0;
|
|
64447
|
+
} catch (e) {
|
|
64448
|
+
if (e instanceof ProgressError2) {
|
|
64449
|
+
io.error(JSON.stringify({ ok: false, error: e.code, message: e.message }));
|
|
64450
|
+
return 2;
|
|
64451
|
+
}
|
|
64452
|
+
throw e;
|
|
64453
|
+
}
|
|
64454
|
+
}
|
|
64127
64455
|
case "ux": {
|
|
64128
64456
|
const sub = pos[1] ?? "audit";
|
|
64129
64457
|
const dir = contentDir(flags);
|
|
@@ -64177,7 +64505,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64177
64505
|
case "test": {
|
|
64178
64506
|
const dir = contentDir(flags);
|
|
64179
64507
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
64180
|
-
if (
|
|
64508
|
+
if (existsSync58(join54(dir, "functions"))) {
|
|
64181
64509
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
64182
64510
|
const loaded = await loadFunctionsApp2(dir);
|
|
64183
64511
|
const results = [];
|
|
@@ -64264,7 +64592,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64264
64592
|
}
|
|
64265
64593
|
}
|
|
64266
64594
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
64267
|
-
const out = mkdtempSync4(
|
|
64595
|
+
const out = mkdtempSync4(join54(tmpdir5(), "himi-test-"));
|
|
64268
64596
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64269
64597
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
64270
64598
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64309,7 +64637,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64309
64637
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
64310
64638
|
return 2;
|
|
64311
64639
|
}
|
|
64312
|
-
const sources = collectWorkerSources2(
|
|
64640
|
+
const sources = collectWorkerSources2(join54(dir, "tier5-src"), screen.bundleName);
|
|
64313
64641
|
if (!sources) {
|
|
64314
64642
|
io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
64315
64643
|
return 2;
|
|
@@ -64470,7 +64798,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64470
64798
|
const sp = await runShotsPass2({
|
|
64471
64799
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
64472
64800
|
tokens: outcome.tokens,
|
|
64473
|
-
outDir:
|
|
64801
|
+
outDir: join54(dir, ".himi", "shots"),
|
|
64474
64802
|
width: 390,
|
|
64475
64803
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
64476
64804
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -64508,7 +64836,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64508
64836
|
releaseId: result.releaseId,
|
|
64509
64837
|
releasePayload: release,
|
|
64510
64838
|
descriptors: attestedDescriptors,
|
|
64511
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
64839
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join54(dir, ".himi", "shots", name)])),
|
|
64512
64840
|
coverage: {
|
|
64513
64841
|
screens: crawledScreens.size,
|
|
64514
64842
|
actionsDispatched: result.actions.exercised,
|
|
@@ -64597,7 +64925,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64597
64925
|
return 2;
|
|
64598
64926
|
}
|
|
64599
64927
|
try {
|
|
64600
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
64928
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync69(stateArg.replace(/^@/, ""), "utf8");
|
|
64601
64929
|
injectedState = JSON.parse(raw);
|
|
64602
64930
|
} catch (e) {
|
|
64603
64931
|
io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
|
|
@@ -64612,7 +64940,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64612
64940
|
return 2;
|
|
64613
64941
|
}
|
|
64614
64942
|
try {
|
|
64615
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
64943
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync69(inputArg.replace(/^@/, ""), "utf8");
|
|
64616
64944
|
const parsed = JSON.parse(raw);
|
|
64617
64945
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
64618
64946
|
injectedInput = parsed;
|
|
@@ -64661,7 +64989,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64661
64989
|
}
|
|
64662
64990
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64663
64991
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
64664
|
-
const out = mkdtempSync4(
|
|
64992
|
+
const out = mkdtempSync4(join54(tmpdir5(), "himi-render-"));
|
|
64665
64993
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64666
64994
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
64667
64995
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64677,7 +65005,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64677
65005
|
let attestationPngFile;
|
|
64678
65006
|
if (typeof flags.png === "string" && r.pngBase64) {
|
|
64679
65007
|
pngFile = writePngFile(str5(flags.png), r.pngBase64);
|
|
64680
|
-
attestationPngFile = writePngFile(
|
|
65008
|
+
attestationPngFile = writePngFile(join54(dir, ".himi", "shots", `${screenId}.png`), r.pngBase64);
|
|
64681
65009
|
}
|
|
64682
65010
|
if (renderWidth !== void 0 && r.renderable) {
|
|
64683
65011
|
recordRenderWidth(dir, {
|
|
@@ -65001,7 +65329,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65001
65329
|
return 2;
|
|
65002
65330
|
}
|
|
65003
65331
|
const renamed = str5(flags.name);
|
|
65004
|
-
const dest =
|
|
65332
|
+
const dest = resolve45(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
65005
65333
|
const replace = flags.replace === true;
|
|
65006
65334
|
const force = replace || flags.force === true;
|
|
65007
65335
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -65009,8 +65337,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65009
65337
|
io.error(JSON.stringify(linked));
|
|
65010
65338
|
return 1;
|
|
65011
65339
|
}
|
|
65012
|
-
if (
|
|
65013
|
-
if (!
|
|
65340
|
+
if (existsSync58(dest)) {
|
|
65341
|
+
if (!statSync15(dest).isDirectory()) {
|
|
65014
65342
|
io.error(JSON.stringify({
|
|
65015
65343
|
error: `${dest} exists and is not a directory`,
|
|
65016
65344
|
hint: "pass --out/--name to land somewhere else, or remove the file"
|
|
@@ -65022,7 +65350,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65022
65350
|
io.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" }));
|
|
65023
65351
|
return 1;
|
|
65024
65352
|
}
|
|
65025
|
-
if (replace && occupied && !
|
|
65353
|
+
if (replace && occupied && !existsSync58(join54(dest, "himalaya.content.json"))) {
|
|
65026
65354
|
io.error(JSON.stringify({
|
|
65027
65355
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
65028
65356
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -65161,7 +65489,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65161
65489
|
const force = flags.force === true;
|
|
65162
65490
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65163
65491
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
65164
|
-
const out = mkdtempSync4(
|
|
65492
|
+
const out = mkdtempSync4(join54(tmpdir5(), "himi-push-"));
|
|
65165
65493
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65166
65494
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65167
65495
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65187,7 +65515,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65187
65515
|
const manifest = outcome.manifest;
|
|
65188
65516
|
const payload = await loadReleaseFromDir(declared, out);
|
|
65189
65517
|
const { shellQuote: shellQuote2 } = await Promise.resolve().then(() => (init_shell_quote(), shell_quote_exports));
|
|
65190
|
-
const contentRel =
|
|
65518
|
+
const contentRel = relative9(process.cwd(), dir) || ".";
|
|
65191
65519
|
const contentArg = shellQuote2(contentRel);
|
|
65192
65520
|
if (onlyRaw !== void 0) {
|
|
65193
65521
|
const onlyDraft = flags.draft === true;
|
|
@@ -65249,7 +65577,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65249
65577
|
let localSourceHash;
|
|
65250
65578
|
try {
|
|
65251
65579
|
const { collectAppSource: collectAppSource2, zipAppSource: zipAppSource2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
65252
|
-
localSourceHash =
|
|
65580
|
+
localSourceHash = createHash25("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
|
|
65253
65581
|
} catch {
|
|
65254
65582
|
}
|
|
65255
65583
|
return runReleasePatch({
|
|
@@ -65632,7 +65960,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65632
65960
|
return 2;
|
|
65633
65961
|
}
|
|
65634
65962
|
try {
|
|
65635
|
-
const res = writePack(
|
|
65963
|
+
const res = writePack(resolve45(releaseDir), only, resolve45(str5(flags.out) ?? process.cwd()));
|
|
65636
65964
|
print({
|
|
65637
65965
|
ok: true,
|
|
65638
65966
|
app: res.app,
|
|
@@ -65681,7 +66009,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65681
66009
|
}
|
|
65682
66010
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65683
66011
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
65684
|
-
const built = mkdtempSync4(
|
|
66012
|
+
const built = mkdtempSync4(join54(tmpdir5(), "himi-pack-"));
|
|
65685
66013
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65686
66014
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
65687
66015
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65703,7 +66031,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65703
66031
|
return 1;
|
|
65704
66032
|
}
|
|
65705
66033
|
try {
|
|
65706
|
-
const res = writePack(built, app,
|
|
66034
|
+
const res = writePack(built, app, resolve45(str5(flags.out) ?? dir), sourceArchive);
|
|
65707
66035
|
print({
|
|
65708
66036
|
ok: true,
|
|
65709
66037
|
app: res.app,
|
|
@@ -65748,7 +66076,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65748
66076
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
65749
66077
|
let opened;
|
|
65750
66078
|
try {
|
|
65751
|
-
opened = openPackageFile2(
|
|
66079
|
+
opened = openPackageFile2(resolve45(file));
|
|
65752
66080
|
} catch (e) {
|
|
65753
66081
|
io.error(JSON.stringify({ error: e.message }));
|
|
65754
66082
|
return 1;
|
|
@@ -65761,7 +66089,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65761
66089
|
io.error(JSON.stringify({
|
|
65762
66090
|
ok: false,
|
|
65763
66091
|
error: "app_source_not_in_package",
|
|
65764
|
-
detail: `${
|
|
66092
|
+
detail: `${resolve45(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
65765
66093
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
65766
66094
|
}));
|
|
65767
66095
|
return 1;
|
|
@@ -65784,7 +66112,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65784
66112
|
return 1;
|
|
65785
66113
|
}
|
|
65786
66114
|
}
|
|
65787
|
-
const dest =
|
|
66115
|
+
const dest = resolve45(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
65788
66116
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
65789
66117
|
if (issue2) {
|
|
65790
66118
|
io.error(JSON.stringify(issue2));
|
|
@@ -65869,7 +66197,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65869
66197
|
}
|
|
65870
66198
|
try {
|
|
65871
66199
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
65872
|
-
const opened = openPackageFile2(
|
|
66200
|
+
const opened = openPackageFile2(resolve45(file));
|
|
65873
66201
|
if (!opened.validation.ok || !opened.header) {
|
|
65874
66202
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
65875
66203
|
return 1;
|
|
@@ -65879,12 +66207,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65879
66207
|
io.error(JSON.stringify({
|
|
65880
66208
|
ok: false,
|
|
65881
66209
|
error: "refusing to share a package that carries the app's source",
|
|
65882
|
-
detail: `${
|
|
66210
|
+
detail: `${resolve45(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
|
|
65883
66211
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
65884
66212
|
}));
|
|
65885
66213
|
return 1;
|
|
65886
66214
|
}
|
|
65887
|
-
const archive =
|
|
66215
|
+
const archive = readFileSync69(resolve45(file));
|
|
65888
66216
|
const result = await client2().createPackageShare({
|
|
65889
66217
|
app: opened.header.app,
|
|
65890
66218
|
releaseId: opened.header.releaseId,
|
|
@@ -65921,10 +66249,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65921
66249
|
const app = await appId(dir);
|
|
65922
66250
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65923
66251
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65924
|
-
temp = mkdtempSync4(
|
|
66252
|
+
temp = mkdtempSync4(join54(tmpdir5(), "himi-run-build-"));
|
|
65925
66253
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65926
66254
|
await buildReleaseFromContent2(dir, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
|
|
65927
|
-
source =
|
|
66255
|
+
source = join54(temp, app);
|
|
65928
66256
|
}
|
|
65929
66257
|
const chromeArg = str5(flags.chrome) ?? "preview";
|
|
65930
66258
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -65949,9 +66277,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65949
66277
|
open: flags["no-open"] !== true
|
|
65950
66278
|
});
|
|
65951
66279
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
65952
|
-
await new Promise((
|
|
66280
|
+
await new Promise((resolve46) => {
|
|
65953
66281
|
const stop = () => {
|
|
65954
|
-
void run2.close().finally(() =>
|
|
66282
|
+
void run2.close().finally(() => resolve46());
|
|
65955
66283
|
};
|
|
65956
66284
|
process.once("SIGINT", stop);
|
|
65957
66285
|
process.once("SIGTERM", stop);
|
|
@@ -66528,7 +66856,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66528
66856
|
io.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
66529
66857
|
return 2;
|
|
66530
66858
|
}
|
|
66531
|
-
if (!
|
|
66859
|
+
if (!existsSync58(file)) {
|
|
66532
66860
|
io.error(JSON.stringify({ error: `no such file: ${file}` }));
|
|
66533
66861
|
return 2;
|
|
66534
66862
|
}
|
|
@@ -66584,7 +66912,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66584
66912
|
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."
|
|
66585
66913
|
};
|
|
66586
66914
|
if (kind === "tokens" || kind === "app-config") {
|
|
66587
|
-
const body =
|
|
66915
|
+
const body = readFileSync69(file, "utf8");
|
|
66588
66916
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
66589
66917
|
return runReleasePatch({
|
|
66590
66918
|
...common,
|
|
@@ -66599,7 +66927,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66599
66927
|
io.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
66600
66928
|
return 2;
|
|
66601
66929
|
}
|
|
66602
|
-
const descriptor =
|
|
66930
|
+
const descriptor = readFileSync69(file, "utf8");
|
|
66603
66931
|
try {
|
|
66604
66932
|
JSON.parse(descriptor);
|
|
66605
66933
|
} catch (e) {
|
|
@@ -66639,8 +66967,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66639
66967
|
extra: { kind, screen: id, file: { path: file, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
66640
66968
|
});
|
|
66641
66969
|
}
|
|
66642
|
-
const bytes2 =
|
|
66643
|
-
const sha =
|
|
66970
|
+
const bytes2 = readFileSync69(file);
|
|
66971
|
+
const sha = createHash25("sha256").update(bytes2).digest("hex");
|
|
66644
66972
|
const forScreens = (str5(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
66645
66973
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
66646
66974
|
io.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 }));
|
|
@@ -66783,7 +67111,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66783
67111
|
}
|
|
66784
67112
|
let def;
|
|
66785
67113
|
try {
|
|
66786
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
67114
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync69(arg.slice(1), "utf8") : arg);
|
|
66787
67115
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
66788
67116
|
io.error(JSON.stringify({ error: "invalid_definition", problems: [`--definition must be a JSON object, got ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`] }));
|
|
66789
67117
|
return 2;
|
|
@@ -67247,7 +67575,7 @@ ${label2}`);
|
|
|
67247
67575
|
const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
67248
67576
|
{
|
|
67249
67577
|
const distDir = contentDir(flags);
|
|
67250
|
-
if (
|
|
67578
|
+
if (existsSync58(join54(distDir, "himalaya.content.json"))) {
|
|
67251
67579
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
67252
67580
|
const errors = issues.filter((i) => i.severity === "error");
|
|
67253
67581
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|
|
@@ -67516,7 +67844,7 @@ ${label2}`);
|
|
|
67516
67844
|
const dpxPath = dpxSessionTokenPath();
|
|
67517
67845
|
let dpx;
|
|
67518
67846
|
try {
|
|
67519
|
-
dpx =
|
|
67847
|
+
dpx = readFileSync69(dpxPath, "utf8").trim();
|
|
67520
67848
|
} catch {
|
|
67521
67849
|
io.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` }));
|
|
67522
67850
|
return 1;
|
|
@@ -67918,7 +68246,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
67918
68246
|
const path2 = dpxSessionTokenPath();
|
|
67919
68247
|
let raw;
|
|
67920
68248
|
try {
|
|
67921
|
-
raw =
|
|
68249
|
+
raw = readFileSync69(path2, "utf8");
|
|
67922
68250
|
} catch {
|
|
67923
68251
|
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
67924
68252
|
return 1;
|