@wix/himalaya-cli 0.856.0 → 0.857.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 +803 -699
- package/guides/mobile-ux.md +38 -7
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -920,7 +920,7 @@ function hasUnterminatedComment(mobile) {
|
|
|
920
920
|
i = close + 3;
|
|
921
921
|
}
|
|
922
922
|
}
|
|
923
|
-
function mobileUxMarkerFindings(mobile) {
|
|
923
|
+
function mobileUxMarkerFindings(mobile, renderedWidths = []) {
|
|
924
924
|
const text2 = mobileUxDocumentBody(mobile);
|
|
925
925
|
const findings = [];
|
|
926
926
|
if (!/^## Implementation acceptance\b/im.test(text2)) {
|
|
@@ -938,8 +938,8 @@ function mobileUxMarkerFindings(mobile) {
|
|
|
938
938
|
});
|
|
939
939
|
}
|
|
940
940
|
}
|
|
941
|
-
if (!hasWidthEvidence(text2)) {
|
|
942
|
-
findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(text2) });
|
|
941
|
+
if (!hasWidthEvidence(text2, renderedWidths)) {
|
|
942
|
+
findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(text2, renderedWidths) });
|
|
943
943
|
}
|
|
944
944
|
if (findings.length && hasUnterminatedComment(mobile)) {
|
|
945
945
|
return [{
|
|
@@ -987,13 +987,33 @@ function closestWidthPair(mentions) {
|
|
|
987
987
|
}
|
|
988
988
|
return best;
|
|
989
989
|
}
|
|
990
|
-
function
|
|
990
|
+
function recordedWidthSpan(widths) {
|
|
991
|
+
const compact = widths.find((width) => inRange(width) && width <= COMPACT_MAX);
|
|
992
|
+
const wider = widths.find((width) => inRange(width) && width >= WIDER_MIN);
|
|
993
|
+
return compact !== void 0 && wider !== void 0 ? { compact, wider } : null;
|
|
994
|
+
}
|
|
995
|
+
function hasWidthEvidence(mobile, renderedWidths) {
|
|
996
|
+
if (recordedWidthSpan(renderedWidths)) return true;
|
|
991
997
|
if (WIDTH_LITERAL.test(mobile)) return true;
|
|
992
998
|
const pair = closestWidthPair(widthMentions(mobile));
|
|
993
999
|
return pair !== null && pair.gap <= WIDTH_WINDOW;
|
|
994
1000
|
}
|
|
995
|
-
function
|
|
996
|
-
|
|
1001
|
+
function recordedRenderNote(renderedWidths) {
|
|
1002
|
+
if (renderedWidths.length === 0) return "";
|
|
1003
|
+
const list = (values) => {
|
|
1004
|
+
const unique = [...new Set(values)].sort((a, b) => a - b);
|
|
1005
|
+
const shown2 = unique.slice(0, 6).map((width) => `${width}px`).join(", ");
|
|
1006
|
+
return unique.length > 6 ? `${shown2}, \u2026` : shown2;
|
|
1007
|
+
};
|
|
1008
|
+
const plausible = renderedWidths.filter(inRange);
|
|
1009
|
+
const held = `The render record in \`${UX_EVIDENCE_PATH}\` holds`;
|
|
1010
|
+
if (plausible.length === 0) {
|
|
1011
|
+
return ` ${held} ${list(renderedWidths)}, and none of those is a plausible viewport (${PLAUSIBLE_WIDTH.min}-${PLAUSIBLE_WIDTH.max}px), so the record proves nothing about a size class.`;
|
|
1012
|
+
}
|
|
1013
|
+
return ` ${held} ${list(plausible)} \u2014 ` + (plausible.some((width) => width <= COMPACT_MAX) ? `compact only. Render the same screen again at ${WIDER_MIN}px or wider \u2014 \`himi render <screenId> --device ipad\`.` : `wider than compact only. Render the same screen again at ${COMPACT_MAX}px or less \u2014 \`himi render <screenId> --device iphone\`.`);
|
|
1014
|
+
}
|
|
1015
|
+
function widthEvidenceMessage(mobile, renderedWidths) {
|
|
1016
|
+
const base = `MOBILE-UX.md has no width evidence. The shortest way to supply it is to RENDER: \`himi render <screenId> --content <dir> --device iphone\` and again \`--device ipad\` (or any two \`--width\`s spanning the bands below) write the widths they rendered into \`${UX_EVIDENCE_PATH}\`, and a recorded compact render plus a wider one satisfy this marker with no prose at all. Otherwise write the widths you actually rendered into this document \u2014 one at most ${COMPACT_MAX}px (compact) and one at least ${WIDER_MIN}px (medium or expanded), within ~${WIDTH_WINDOW} characters of each other so they read as one statement. A number counts only where it is spelled as a width on itself: a unit (\`320px\`, \`320 pt\`, \`320 dp\`, \`320 pixels\`, \`320 wide\`) or a screenshot filename (\`home-320.png\`). For example: \`Rendered 320px and 834px (home-320.png, home-834.png)\`. The scaffold's \`compact (320/360) \u2026 expanded\` sentence is still accepted as-is.` + recordedRenderNote(renderedWidths);
|
|
997
1017
|
if (/compact \(320\/360\)/i.test(mobile)) {
|
|
998
1018
|
return base + " `compact (320/360)` is present, but no `expanded` follows it within ~400 characters \u2014 keep them in the same sentence.";
|
|
999
1019
|
}
|
|
@@ -1012,9 +1032,10 @@ function widthEvidenceMessage(mobile) {
|
|
|
1012
1032
|
}
|
|
1013
1033
|
return base;
|
|
1014
1034
|
}
|
|
1015
|
-
var SPEC_TEMPLATE, MOBILE_UX_MARKER_NOTE, MOBILE_UX_TEMPLATE, section, DELIMITER_ROW, splitCells, WIDTH_LITERAL, COMPACT_MAX, WIDER_MIN, PLAUSIBLE_WIDTH, YEAR, inRange, looksLikeYear, UNIT_ATTACHED, UNIT_WORD_ATTACHED, WIDTH_WINDOW, EDGE_WINDOW, FILENAME_AFTER, ANTI_CUE_BEFORE, PAIR_HEIGHT_BEFORE, ANTI_CUE_AFTER, isCompact, isWider;
|
|
1035
|
+
var UX_EVIDENCE_PATH, SPEC_TEMPLATE, MOBILE_UX_MARKER_NOTE, MOBILE_UX_TEMPLATE, section, DELIMITER_ROW, splitCells, WIDTH_LITERAL, COMPACT_MAX, WIDER_MIN, PLAUSIBLE_WIDTH, YEAR, inRange, looksLikeYear, UNIT_ATTACHED, UNIT_WORD_ATTACHED, WIDTH_WINDOW, EDGE_WINDOW, FILENAME_AFTER, ANTI_CUE_BEFORE, PAIR_HEIGHT_BEFORE, ANTI_CUE_AFTER, isCompact, isWider;
|
|
1016
1036
|
var init_mobile_ux_contract = __esm({
|
|
1017
1037
|
"src/mobile-ux-contract.ts"() {
|
|
1038
|
+
UX_EVIDENCE_PATH = ".himi/ux-audit.json";
|
|
1018
1039
|
SPEC_TEMPLATE = `# App specification
|
|
1019
1040
|
|
|
1020
1041
|
## User and outcome
|
|
@@ -1052,7 +1073,11 @@ var init_mobile_ux_contract = __esm({
|
|
|
1052
1073
|
2. One primary CTA per state \u2014 EITHER the phrase \`one primary CTA per state\`, OR a
|
|
1053
1074
|
\`Primary CTA\` column in the acceptance table below, with a row for every state you
|
|
1054
1075
|
declare under \`## Screen contract\` and exactly one CTA named in each row's cell.
|
|
1055
|
-
3. Width evidence \u2014 EITHER the
|
|
1076
|
+
3. Width evidence \u2014 EITHER a RECORDED RENDER, which is the shortest way and needs no prose
|
|
1077
|
+
at all: \`himi render <screenId> --device iphone\` and again \`--device ipad\` each append
|
|
1078
|
+
the width they rendered to \`.himi/ux-audit.json\`, and one below 600px plus one at 600px
|
|
1079
|
+
or wider satisfies this on their own. OR the scaffold's own sentence,
|
|
1080
|
+
\`compact (320/360)\` followed by
|
|
1056
1081
|
\`expanded\`, OR two widths you actually rendered, EACH SPELLED AS A WIDTH ON ITSELF:
|
|
1057
1082
|
one below 600px and one at 600px or wider, within about 400 characters of each other.
|
|
1058
1083
|
A number is spelled as a width when it carries a unit (\`320px\`, \`834 pt\`,
|
|
@@ -2212,7 +2237,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2212
2237
|
tokenCache.set(cacheKey, fromEnv);
|
|
2213
2238
|
return fromEnv;
|
|
2214
2239
|
}
|
|
2215
|
-
const token = await new Promise((
|
|
2240
|
+
const token = await new Promise((resolve42, reject) => {
|
|
2216
2241
|
let child;
|
|
2217
2242
|
try {
|
|
2218
2243
|
child = spawnImpl("wix", [...args]);
|
|
@@ -2241,12 +2266,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2241
2266
|
child.stdout?.on("data", (d) => {
|
|
2242
2267
|
out += String(d);
|
|
2243
2268
|
const m = out.match(TOKEN_RE);
|
|
2244
|
-
if (m) done(() =>
|
|
2269
|
+
if (m) done(() => resolve42(m[0]));
|
|
2245
2270
|
});
|
|
2246
2271
|
child.stderr?.on("data", (d) => {
|
|
2247
2272
|
out += String(d);
|
|
2248
2273
|
const m = out.match(TOKEN_RE);
|
|
2249
|
-
if (m) done(() =>
|
|
2274
|
+
if (m) done(() => resolve42(m[0]));
|
|
2250
2275
|
});
|
|
2251
2276
|
child.on("error", (e) => done(() => reject(new Error(mintHelp(label2, e.message)))));
|
|
2252
2277
|
child.on("exit", (code) => done(() => reject(new Error(
|
|
@@ -2427,8 +2452,8 @@ function committedProvisioningPath(name) {
|
|
|
2427
2452
|
function committedShellFor(path) {
|
|
2428
2453
|
const normalized = path.replace(/\\/g, "/");
|
|
2429
2454
|
return SHELL_NAMES2.find((name) => {
|
|
2430
|
-
const
|
|
2431
|
-
return normalized ===
|
|
2455
|
+
const relative8 = committedProvisioningPath(name);
|
|
2456
|
+
return normalized === relative8 || normalized.endsWith(`/${relative8}`);
|
|
2432
2457
|
});
|
|
2433
2458
|
}
|
|
2434
2459
|
function isBrandable(repoRoot2, name) {
|
|
@@ -9131,8 +9156,8 @@ Lifetime used`) : new QuickJSUseAfterFree("Lifetime not alive");
|
|
|
9131
9156
|
this.dispose = () => {
|
|
9132
9157
|
this.handle.alive && this.handle.dispose(), this.disposeResolvers();
|
|
9133
9158
|
};
|
|
9134
|
-
this.context = args.context, this.owner = args.context.runtime, this.handle = args.promiseHandle, this.settled = new Promise((
|
|
9135
|
-
this.onSettled =
|
|
9159
|
+
this.context = args.context, this.owner = args.context.runtime, this.handle = args.promiseHandle, this.settled = new Promise((resolve42) => {
|
|
9160
|
+
this.onSettled = resolve42;
|
|
9136
9161
|
}), this.resolveHandle = args.resolveHandle, this.rejectHandle = args.rejectHandle;
|
|
9137
9162
|
}
|
|
9138
9163
|
get alive() {
|
|
@@ -9496,12 +9521,12 @@ Lifetime used`) : new QuickJSUseAfterFree("Lifetime not alive");
|
|
|
9496
9521
|
let vmPromise = scope.manage(this.getProp(this.global, "Promise")), vmPromiseResolve = scope.manage(this.getProp(vmPromise, "resolve"));
|
|
9497
9522
|
return this.callFunction(vmPromiseResolve, vmPromise, promiseLikeHandle);
|
|
9498
9523
|
});
|
|
9499
|
-
return vmResolveResult.error ? Promise.resolve(vmResolveResult) : new Promise((
|
|
9524
|
+
return vmResolveResult.error ? Promise.resolve(vmResolveResult) : new Promise((resolve42) => {
|
|
9500
9525
|
Scope.withScope((scope) => {
|
|
9501
9526
|
let resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
|
|
9502
|
-
|
|
9527
|
+
resolve42(this.success(value && value.dup()));
|
|
9503
9528
|
})), rejectHandle = scope.manage(this.newFunction("reject", (error) => {
|
|
9504
|
-
|
|
9529
|
+
resolve42(this.fail(error && error.dup()));
|
|
9505
9530
|
})), promiseHandle = scope.manage(vmResolveResult.value), promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
|
|
9506
9531
|
this.callFunction(promiseThenHandle, promiseHandle, resolveHandle, rejectHandle).unwrap().dispose();
|
|
9507
9532
|
});
|
|
@@ -10347,13 +10372,13 @@ async function QuickJSRaw(moduleArg = {}) {
|
|
|
10347
10372
|
}
|
|
10348
10373
|
readAsync = async (url) => {
|
|
10349
10374
|
if (isFileURI(url)) {
|
|
10350
|
-
return new Promise((
|
|
10375
|
+
return new Promise((resolve42, reject) => {
|
|
10351
10376
|
var xhr = new XMLHttpRequest();
|
|
10352
10377
|
xhr.open("GET", url, true);
|
|
10353
10378
|
xhr.responseType = "arraybuffer";
|
|
10354
10379
|
xhr.onload = () => {
|
|
10355
10380
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
10356
|
-
|
|
10381
|
+
resolve42(xhr.response);
|
|
10357
10382
|
return;
|
|
10358
10383
|
}
|
|
10359
10384
|
reject(xhr.status);
|
|
@@ -10641,10 +10666,10 @@ async function QuickJSRaw(moduleArg = {}) {
|
|
|
10641
10666
|
}
|
|
10642
10667
|
var info = getWasmImports();
|
|
10643
10668
|
if (Module["instantiateWasm"]) {
|
|
10644
|
-
return new Promise((
|
|
10669
|
+
return new Promise((resolve42, reject) => {
|
|
10645
10670
|
try {
|
|
10646
10671
|
Module["instantiateWasm"](info, (inst, mod) => {
|
|
10647
|
-
|
|
10672
|
+
resolve42(receiveInstance(inst, mod));
|
|
10648
10673
|
});
|
|
10649
10674
|
} catch (e) {
|
|
10650
10675
|
err(`Module.instantiateWasm callback failed with error: ${e}`);
|
|
@@ -10817,15 +10842,15 @@ async function QuickJSRaw(moduleArg = {}) {
|
|
|
10817
10842
|
return parts;
|
|
10818
10843
|
},
|
|
10819
10844
|
normalize: (path) => {
|
|
10820
|
-
var
|
|
10821
|
-
path = PATH.normalizeArray(path.split("/").filter((p) => !!p), !
|
|
10822
|
-
if (!path && !
|
|
10845
|
+
var isAbsolute5 = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/";
|
|
10846
|
+
path = PATH.normalizeArray(path.split("/").filter((p) => !!p), !isAbsolute5).join("/");
|
|
10847
|
+
if (!path && !isAbsolute5) {
|
|
10823
10848
|
path = ".";
|
|
10824
10849
|
}
|
|
10825
10850
|
if (path && trailingSlash) {
|
|
10826
10851
|
path += "/";
|
|
10827
10852
|
}
|
|
10828
|
-
return (
|
|
10853
|
+
return (isAbsolute5 ? "/" : "") + path;
|
|
10829
10854
|
},
|
|
10830
10855
|
dirname: (path) => {
|
|
10831
10856
|
var result = PATH.splitPath(path), root = result[0], dir = result[1];
|
|
@@ -12291,12 +12316,12 @@ async function QuickJSRaw(moduleArg = {}) {
|
|
|
12291
12316
|
throw new FS.ErrnoError(75);
|
|
12292
12317
|
}
|
|
12293
12318
|
var old_node = FS.lookupNode(old_dir, old_name);
|
|
12294
|
-
var
|
|
12295
|
-
if (
|
|
12319
|
+
var relative8 = PATH_FS.relative(old_path, new_dirname);
|
|
12320
|
+
if (relative8.charAt(0) !== ".") {
|
|
12296
12321
|
throw new FS.ErrnoError(28);
|
|
12297
12322
|
}
|
|
12298
|
-
|
|
12299
|
-
if (
|
|
12323
|
+
relative8 = PATH_FS.relative(new_path, old_dirname);
|
|
12324
|
+
if (relative8.charAt(0) !== ".") {
|
|
12300
12325
|
throw new FS.ErrnoError(55);
|
|
12301
12326
|
}
|
|
12302
12327
|
var new_node;
|
|
@@ -14705,8 +14730,8 @@ async function QuickJSRaw(moduleArg = {}) {
|
|
|
14705
14730
|
if (runtimeInitialized) {
|
|
14706
14731
|
moduleRtn = Module;
|
|
14707
14732
|
} else {
|
|
14708
|
-
moduleRtn = new Promise((
|
|
14709
|
-
readyPromiseResolve =
|
|
14733
|
+
moduleRtn = new Promise((resolve42, reject) => {
|
|
14734
|
+
readyPromiseResolve = resolve42;
|
|
14710
14735
|
readyPromiseReject = reject;
|
|
14711
14736
|
});
|
|
14712
14737
|
}
|
|
@@ -15570,13 +15595,13 @@ async function QuickJSRaw3(moduleArg = {}) {
|
|
|
15570
15595
|
}
|
|
15571
15596
|
readAsync = async (url) => {
|
|
15572
15597
|
if (isFileURI(url)) {
|
|
15573
|
-
return new Promise((
|
|
15598
|
+
return new Promise((resolve42, reject) => {
|
|
15574
15599
|
var xhr = new XMLHttpRequest();
|
|
15575
15600
|
xhr.open("GET", url, true);
|
|
15576
15601
|
xhr.responseType = "arraybuffer";
|
|
15577
15602
|
xhr.onload = () => {
|
|
15578
15603
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
15579
|
-
|
|
15604
|
+
resolve42(xhr.response);
|
|
15580
15605
|
return;
|
|
15581
15606
|
}
|
|
15582
15607
|
reject(xhr.status);
|
|
@@ -15843,10 +15868,10 @@ async function QuickJSRaw3(moduleArg = {}) {
|
|
|
15843
15868
|
}
|
|
15844
15869
|
var info = getWasmImports();
|
|
15845
15870
|
if (Module["instantiateWasm"]) {
|
|
15846
|
-
return new Promise((
|
|
15871
|
+
return new Promise((resolve42, reject) => {
|
|
15847
15872
|
try {
|
|
15848
15873
|
Module["instantiateWasm"](info, (inst, mod) => {
|
|
15849
|
-
|
|
15874
|
+
resolve42(receiveInstance(inst, mod));
|
|
15850
15875
|
});
|
|
15851
15876
|
} catch (e) {
|
|
15852
15877
|
err(`Module.instantiateWasm callback failed with error: ${e}`);
|
|
@@ -16274,8 +16299,8 @@ async function QuickJSRaw3(moduleArg = {}) {
|
|
|
16274
16299
|
}, whenDone() {
|
|
16275
16300
|
assert(Asyncify.currData, "Tried to wait for an async operation when none is in progress.");
|
|
16276
16301
|
assert(!Asyncify.asyncPromiseHandlers, "Cannot have multiple async operations in flight at once");
|
|
16277
|
-
return new Promise((
|
|
16278
|
-
Asyncify.asyncPromiseHandlers = { resolve:
|
|
16302
|
+
return new Promise((resolve42, reject) => {
|
|
16303
|
+
Asyncify.asyncPromiseHandlers = { resolve: resolve42, reject };
|
|
16279
16304
|
});
|
|
16280
16305
|
}, allocateData() {
|
|
16281
16306
|
var ptr = _malloc(12 + Asyncify.StackSize);
|
|
@@ -16903,8 +16928,8 @@ async function QuickJSRaw3(moduleArg = {}) {
|
|
|
16903
16928
|
if (runtimeInitialized) {
|
|
16904
16929
|
moduleRtn = Module;
|
|
16905
16930
|
} else {
|
|
16906
|
-
moduleRtn = new Promise((
|
|
16907
|
-
readyPromiseResolve =
|
|
16931
|
+
moduleRtn = new Promise((resolve42, reject) => {
|
|
16932
|
+
readyPromiseResolve = resolve42;
|
|
16908
16933
|
readyPromiseReject = reject;
|
|
16909
16934
|
});
|
|
16910
16935
|
}
|
|
@@ -20597,6 +20622,101 @@ var init_wix_gateway_rules = __esm({
|
|
|
20597
20622
|
}
|
|
20598
20623
|
});
|
|
20599
20624
|
|
|
20625
|
+
// src/ux-evidence.ts
|
|
20626
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync23, writeFileSync as writeFileSync9 } from "node:fs";
|
|
20627
|
+
import { dirname as dirname15, isAbsolute as isAbsolute2, join as join25, relative as relative3, resolve as resolve15 } from "node:path";
|
|
20628
|
+
function readText(path) {
|
|
20629
|
+
try {
|
|
20630
|
+
return existsSync21(path) ? readFileSync23(path, "utf8") : null;
|
|
20631
|
+
} catch {
|
|
20632
|
+
return null;
|
|
20633
|
+
}
|
|
20634
|
+
}
|
|
20635
|
+
function parseEvidence(path) {
|
|
20636
|
+
const raw = readText(path);
|
|
20637
|
+
if (raw === null) return { evidence: null };
|
|
20638
|
+
try {
|
|
20639
|
+
const value = JSON.parse(raw);
|
|
20640
|
+
if (value.version !== 1 || !value.platforms || typeof value.platforms !== "object") {
|
|
20641
|
+
return { evidence: null, error: "must be an object with version: 1 and a platforms object" };
|
|
20642
|
+
}
|
|
20643
|
+
return { evidence: value };
|
|
20644
|
+
} catch (error) {
|
|
20645
|
+
return { evidence: null, error: `is not valid JSON: ${error.message}` };
|
|
20646
|
+
}
|
|
20647
|
+
}
|
|
20648
|
+
function uxEvidencePath(content) {
|
|
20649
|
+
return join25(resolve15(content), UX_EVIDENCE_PATH);
|
|
20650
|
+
}
|
|
20651
|
+
function isRenderEntry(value) {
|
|
20652
|
+
if (!value || typeof value !== "object") return false;
|
|
20653
|
+
const entry = value;
|
|
20654
|
+
return typeof entry.screenId === "string" && entry.screenId.length > 0 && typeof entry.width === "number" && Number.isFinite(entry.width) && entry.width > 0 && typeof entry.recordedAt === "string" && entry.recordedAt.length > 0;
|
|
20655
|
+
}
|
|
20656
|
+
function renderEvidenceEntries(evidence) {
|
|
20657
|
+
const raw = evidence?.renders;
|
|
20658
|
+
return Array.isArray(raw) ? raw.filter(isRenderEntry) : [];
|
|
20659
|
+
}
|
|
20660
|
+
function recordedRenderWidths(content) {
|
|
20661
|
+
const { evidence } = parseEvidence(uxEvidencePath(content));
|
|
20662
|
+
return renderEvidenceEntries(evidence).map((entry) => entry.width);
|
|
20663
|
+
}
|
|
20664
|
+
function writeEvidence(path, evidence) {
|
|
20665
|
+
mkdirSync10(dirname15(path), { recursive: true });
|
|
20666
|
+
writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
|
|
20667
|
+
}
|
|
20668
|
+
function recordedFilePath(dir, file) {
|
|
20669
|
+
const rel = relative3(dir, resolve15(file));
|
|
20670
|
+
return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : file;
|
|
20671
|
+
}
|
|
20672
|
+
function recordRenderWidth(content, entry) {
|
|
20673
|
+
try {
|
|
20674
|
+
if (!entry.screenId || !Number.isFinite(entry.width) || entry.width <= 0) return null;
|
|
20675
|
+
const dir = resolve15(content);
|
|
20676
|
+
const path = join25(dir, UX_EVIDENCE_PATH);
|
|
20677
|
+
const parsed = parseEvidence(path);
|
|
20678
|
+
if (parsed.error) return null;
|
|
20679
|
+
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
20680
|
+
const width = entry.width;
|
|
20681
|
+
const written = {
|
|
20682
|
+
screenId: entry.screenId,
|
|
20683
|
+
width,
|
|
20684
|
+
...entry.device ? { device: entry.device } : {},
|
|
20685
|
+
...entry.file ? { file: recordedFilePath(dir, entry.file) } : {},
|
|
20686
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20687
|
+
};
|
|
20688
|
+
const renders = renderEvidenceEntries(evidence);
|
|
20689
|
+
const at = renders.findIndex((existing) => existing.screenId === written.screenId && existing.width === width);
|
|
20690
|
+
if (at >= 0) renders[at] = written;
|
|
20691
|
+
else renders.push(written);
|
|
20692
|
+
evidence.renders = renders;
|
|
20693
|
+
writeEvidence(path, evidence);
|
|
20694
|
+
return written;
|
|
20695
|
+
} catch {
|
|
20696
|
+
return null;
|
|
20697
|
+
}
|
|
20698
|
+
}
|
|
20699
|
+
function recordNativeAudit(content, platform, status, checks, reason) {
|
|
20700
|
+
const normalizedChecks = status === "unavailable" ? [] : [...new Set(checks.map((check) => check.trim()).filter(Boolean))];
|
|
20701
|
+
if (status !== "unavailable" && !normalizedChecks.length) {
|
|
20702
|
+
throw new Error("--checks needs at least one comma-separated check (for example: back,keyboard,voiceover)");
|
|
20703
|
+
}
|
|
20704
|
+
if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
|
|
20705
|
+
const dir = resolve15(content);
|
|
20706
|
+
const path = join25(dir, UX_EVIDENCE_PATH);
|
|
20707
|
+
const parsed = parseEvidence(path);
|
|
20708
|
+
if (parsed.error) throw new Error(`${UX_EVIDENCE_PATH} ${parsed.error}`);
|
|
20709
|
+
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
20710
|
+
evidence.platforms[platform] = { status, checks: normalizedChecks, ...reason?.trim() ? { reason: reason.trim() } : {}, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
20711
|
+
writeEvidence(path, evidence);
|
|
20712
|
+
return evidence;
|
|
20713
|
+
}
|
|
20714
|
+
var init_ux_evidence = __esm({
|
|
20715
|
+
"src/ux-evidence.ts"() {
|
|
20716
|
+
init_mobile_ux_contract();
|
|
20717
|
+
}
|
|
20718
|
+
});
|
|
20719
|
+
|
|
20600
20720
|
// ../../core/sdk/capability-catalog/src/types.ts
|
|
20601
20721
|
var init_types = __esm({
|
|
20602
20722
|
"../../core/sdk/capability-catalog/src/types.ts"() {
|
|
@@ -21323,9 +21443,9 @@ var init_src2 = __esm({
|
|
|
21323
21443
|
});
|
|
21324
21444
|
|
|
21325
21445
|
// ../app-icons/plan.ts
|
|
21326
|
-
import { existsSync as
|
|
21446
|
+
import { existsSync as existsSync24, readFileSync as readFileSync26, readdirSync as readdirSync12 } from "node:fs";
|
|
21327
21447
|
import { createHash as createHash7 } from "node:crypto";
|
|
21328
|
-
import { dirname as
|
|
21448
|
+
import { dirname as dirname17, join as join28, resolve as resolve18 } from "node:path";
|
|
21329
21449
|
function stripComments(src) {
|
|
21330
21450
|
let out = "";
|
|
21331
21451
|
let i = 0;
|
|
@@ -21454,15 +21574,15 @@ function rotateHue(hex2, deg) {
|
|
|
21454
21574
|
}
|
|
21455
21575
|
function resolveTokensPath(app, configTs) {
|
|
21456
21576
|
const literal = /^ {2}designTokensPath\s*:\s*["']([^"']+)["']/m.exec(stripComments(configTs))?.[1];
|
|
21457
|
-
if (literal) return { path:
|
|
21458
|
-
return { path:
|
|
21577
|
+
if (literal) return { path: resolve18(appDir(app), literal), source: "declared" };
|
|
21578
|
+
return { path: join28(appDir(app), "tokens.json"), source: "assumed" };
|
|
21459
21579
|
}
|
|
21460
21580
|
function resolveToken(app, token, tokensPathOverride) {
|
|
21461
|
-
const tokensPath = tokensPathOverride ??
|
|
21462
|
-
if (!
|
|
21581
|
+
const tokensPath = tokensPathOverride ?? join28(appDir(app), "tokens.json");
|
|
21582
|
+
if (!existsSync24(tokensPath)) {
|
|
21463
21583
|
throw new Error(`app-icons: ${app} has no tokens.json at ${tokensPath} (needed to resolve "${token}").`);
|
|
21464
21584
|
}
|
|
21465
|
-
const tokens = JSON.parse(
|
|
21585
|
+
const tokens = JSON.parse(readFileSync26(tokensPath, "utf8"));
|
|
21466
21586
|
const value = tokens.colors?.[token];
|
|
21467
21587
|
if (value === void 0) {
|
|
21468
21588
|
throw new Error(`app-icons: ${app} references icon colour token "${token}" but tokens.json has no such color.`);
|
|
@@ -21503,8 +21623,8 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
|
|
|
21503
21623
|
assertIconContract(app, cfg);
|
|
21504
21624
|
const tokens = tokensPathOverride ?? resolveTokensPath(app, configTs).path;
|
|
21505
21625
|
if (cfg.source) {
|
|
21506
|
-
const abs =
|
|
21507
|
-
if (!
|
|
21626
|
+
const abs = resolve18(appDir(app), cfg.source);
|
|
21627
|
+
if (!existsSync24(abs)) {
|
|
21508
21628
|
throw new Error(`app-icons: ${app} declares icon.source "${cfg.source}" but ${abs} does not exist.`);
|
|
21509
21629
|
}
|
|
21510
21630
|
return {
|
|
@@ -21541,17 +21661,17 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
|
|
|
21541
21661
|
};
|
|
21542
21662
|
}
|
|
21543
21663
|
function iosAssetCatalog2(app) {
|
|
21544
|
-
return assetCatalogIn(
|
|
21664
|
+
return assetCatalogIn(join28(appDir(app), "ios"));
|
|
21545
21665
|
}
|
|
21546
21666
|
function assetCatalogIn(platformDir) {
|
|
21547
|
-
if (!
|
|
21667
|
+
if (!existsSync24(platformDir)) return void 0;
|
|
21548
21668
|
const children = readdirSync12(platformDir).filter((c) => !c.startsWith("build")).sort();
|
|
21549
|
-
const catalogs = children.map((c) =>
|
|
21669
|
+
const catalogs = children.map((c) => join28(platformDir, c, "Assets.xcassets")).filter(existsSync24);
|
|
21550
21670
|
if (catalogs.length === 1) return catalogs[0];
|
|
21551
21671
|
if (catalogs.length > 1) return void 0;
|
|
21552
21672
|
const targets = [];
|
|
21553
21673
|
for (const child of children) {
|
|
21554
|
-
const dir =
|
|
21674
|
+
const dir = join28(platformDir, child);
|
|
21555
21675
|
let entries;
|
|
21556
21676
|
try {
|
|
21557
21677
|
entries = readdirSync12(dir);
|
|
@@ -21559,29 +21679,29 @@ function assetCatalogIn(platformDir) {
|
|
|
21559
21679
|
continue;
|
|
21560
21680
|
}
|
|
21561
21681
|
if (entries.includes("Info.plist") || entries.some((e) => e.endsWith(".swift"))) {
|
|
21562
|
-
targets.push(
|
|
21682
|
+
targets.push(join28(dir, "Assets.xcassets"));
|
|
21563
21683
|
}
|
|
21564
21684
|
}
|
|
21565
21685
|
return targets.length === 1 ? targets[0] : void 0;
|
|
21566
21686
|
}
|
|
21567
21687
|
function androidResDir2(manifestPath) {
|
|
21568
|
-
return
|
|
21688
|
+
return join28(dirname17(manifestPath), "res");
|
|
21569
21689
|
}
|
|
21570
21690
|
function androidManifestPath(app) {
|
|
21571
|
-
const androidDir =
|
|
21572
|
-
if (!
|
|
21573
|
-
const preferred =
|
|
21574
|
-
if (
|
|
21575
|
-
const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) =>
|
|
21691
|
+
const androidDir = join28(appDir(app), "android");
|
|
21692
|
+
if (!existsSync24(androidDir)) return void 0;
|
|
21693
|
+
const preferred = join28(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
21694
|
+
if (existsSync24(preferred)) return preferred;
|
|
21695
|
+
const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join28(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync24);
|
|
21576
21696
|
return candidates.length === 1 ? candidates[0] : void 0;
|
|
21577
21697
|
}
|
|
21578
21698
|
function androidOptedIn2(manifestPath) {
|
|
21579
|
-
if (!manifestPath || !
|
|
21580
|
-
return
|
|
21699
|
+
if (!manifestPath || !existsSync24(manifestPath)) return false;
|
|
21700
|
+
return readFileSync26(manifestPath, "utf8").includes("@mipmap/ic_launcher");
|
|
21581
21701
|
}
|
|
21582
21702
|
function templateIconSha256() {
|
|
21583
21703
|
const cat = iosAssetCatalog2("_template");
|
|
21584
|
-
return cat ? fileSha256(
|
|
21704
|
+
return cat ? fileSha256(join28(cat, "AppIcon.appiconset", "icon_1024.png")) : null;
|
|
21585
21705
|
}
|
|
21586
21706
|
function placeholderHashes() {
|
|
21587
21707
|
const current = templateIconSha256();
|
|
@@ -21589,7 +21709,7 @@ function placeholderHashes() {
|
|
|
21589
21709
|
}
|
|
21590
21710
|
function fileSha256(path) {
|
|
21591
21711
|
try {
|
|
21592
|
-
return createHash7("sha256").update(
|
|
21712
|
+
return createHash7("sha256").update(readFileSync26(path)).digest("hex");
|
|
21593
21713
|
} catch {
|
|
21594
21714
|
return null;
|
|
21595
21715
|
}
|
|
@@ -21600,8 +21720,8 @@ function generationAllowed(app, configTs, opts = {}) {
|
|
|
21600
21720
|
return { allowed: true, reason: "declares an icon block" };
|
|
21601
21721
|
}
|
|
21602
21722
|
const iosCat = iosAssetCatalog2(app);
|
|
21603
|
-
const iosIcon = iosCat ?
|
|
21604
|
-
if (!iosIcon || !
|
|
21723
|
+
const iosIcon = iosCat ? join28(iosCat, "AppIcon.appiconset", "icon_1024.png") : void 0;
|
|
21724
|
+
if (!iosIcon || !existsSync24(iosIcon)) return { allowed: true, reason: "no icon yet" };
|
|
21605
21725
|
const hash = fileSha256(iosIcon);
|
|
21606
21726
|
const placeholders = opts.placeholderHashes ?? placeholderHashes();
|
|
21607
21727
|
if (app === "_template") return { allowed: true, reason: "the template itself" };
|
|
@@ -21625,8 +21745,8 @@ var init_plan2 = __esm({
|
|
|
21625
21745
|
});
|
|
21626
21746
|
|
|
21627
21747
|
// ../native-config/icon.ts
|
|
21628
|
-
import { existsSync as
|
|
21629
|
-
import { join as
|
|
21748
|
+
import { existsSync as existsSync25, readFileSync as readFileSync27 } from "node:fs";
|
|
21749
|
+
import { join as join29 } from "node:path";
|
|
21630
21750
|
function androidAdaptiveIconXml() {
|
|
21631
21751
|
return [
|
|
21632
21752
|
'<?xml version="1.0" encoding="utf-8"?>',
|
|
@@ -21653,8 +21773,8 @@ function androidIconArtifacts(app, configTs) {
|
|
|
21653
21773
|
if (!androidOptedIn2(manifest)) return [];
|
|
21654
21774
|
if (!generationAllowed(app, configTs).allowed) return [];
|
|
21655
21775
|
const res = androidResDir2(manifest);
|
|
21656
|
-
const foreground =
|
|
21657
|
-
if (!
|
|
21776
|
+
const foreground = join29(res, "mipmap-mdpi", "ic_launcher_foreground.png");
|
|
21777
|
+
if (!existsSync25(foreground)) {
|
|
21658
21778
|
throw new Error(
|
|
21659
21779
|
`native-config icon: ${app} opts into @mipmap/ic_launcher but has no mipmap-*/ic_launcher_foreground.png. Run \`npm run app-icons -- ${app}\` first \u2014 the XML emitted here points at those rasters.`
|
|
21660
21780
|
);
|
|
@@ -21663,11 +21783,11 @@ function androidIconArtifacts(app, configTs) {
|
|
|
21663
21783
|
const spec = iconSpec(app, configTs, id, resolveTokensPath(app, configTs).path);
|
|
21664
21784
|
return [
|
|
21665
21785
|
...ANDROID_ADAPTIVE_FILES.map((name) => ({
|
|
21666
|
-
path:
|
|
21786
|
+
path: join29(res, "mipmap-anydpi-v26", name),
|
|
21667
21787
|
content: androidAdaptiveIconXml()
|
|
21668
21788
|
})),
|
|
21669
21789
|
{
|
|
21670
|
-
path:
|
|
21790
|
+
path: join29(res, "values", ANDROID_ICON_BACKGROUND_FILE),
|
|
21671
21791
|
content: androidIconBackgroundXml(spec.background)
|
|
21672
21792
|
}
|
|
21673
21793
|
];
|
|
@@ -21901,8 +22021,8 @@ __export(gen_native_config_exports, {
|
|
|
21901
22021
|
tvInfoPlan: () => tvInfoPlan,
|
|
21902
22022
|
watchInfoPlan: () => watchInfoPlan
|
|
21903
22023
|
});
|
|
21904
|
-
import { existsSync as
|
|
21905
|
-
import { dirname as
|
|
22024
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync12, readFileSync as readFileSync28, readdirSync as readdirSync13, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
22025
|
+
import { dirname as dirname18, join as join30 } from "node:path";
|
|
21906
22026
|
function parseStringArray(configTs, field) {
|
|
21907
22027
|
const m = new RegExp(`${field}:\\s*\\[([^\\]]*)\\]`).exec(configTs);
|
|
21908
22028
|
if (!m) return [];
|
|
@@ -21974,9 +22094,9 @@ function buildSet(capabilities, envelope = []) {
|
|
|
21974
22094
|
return [...new Set([...capabilities, ...envelope].map(catalogKey))].sort();
|
|
21975
22095
|
}
|
|
21976
22096
|
function loadOverrides(app) {
|
|
21977
|
-
const p =
|
|
21978
|
-
if (!
|
|
21979
|
-
return JSON.parse(
|
|
22097
|
+
const p = join30(appDir(app), "native-config.overrides.json");
|
|
22098
|
+
if (!existsSync26(p)) return {};
|
|
22099
|
+
return JSON.parse(readFileSync28(p, "utf8"));
|
|
21980
22100
|
}
|
|
21981
22101
|
function needsQuote(s) {
|
|
21982
22102
|
if (s === "") return true;
|
|
@@ -22031,19 +22151,19 @@ function endText(kind, label2, indent) {
|
|
|
22031
22151
|
return kind === "yaml" ? `${indent}# <<< ${label2} <<<` : `${indent}<!-- <<< ${label2} <<< -->`;
|
|
22032
22152
|
}
|
|
22033
22153
|
function hostAppliesDeferredWidgetActions(app) {
|
|
22034
|
-
const root =
|
|
22035
|
-
if (!
|
|
22154
|
+
const root = join30(appDir(app), "ios");
|
|
22155
|
+
if (!existsSync26(root)) return false;
|
|
22036
22156
|
const stack = [root];
|
|
22037
22157
|
while (stack.length) {
|
|
22038
22158
|
const dir = stack.pop();
|
|
22039
22159
|
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
22040
22160
|
if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
|
|
22041
|
-
const path =
|
|
22161
|
+
const path = join30(dir, entry.name);
|
|
22042
22162
|
if (entry.isDirectory()) {
|
|
22043
22163
|
if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
|
|
22044
22164
|
stack.push(path);
|
|
22045
22165
|
} else if (entry.name.endsWith(".swift")) {
|
|
22046
|
-
if (
|
|
22166
|
+
if (readFileSync28(path, "utf8").includes("WidgetActionRelay.drain(")) return true;
|
|
22047
22167
|
}
|
|
22048
22168
|
}
|
|
22049
22169
|
}
|
|
@@ -22065,18 +22185,18 @@ function injectBlock(text2, kind, label2, render) {
|
|
|
22065
22185
|
return [...lines.slice(0, beginIdx), ...block, ...lines.slice(endIdx + 1)].join("\n");
|
|
22066
22186
|
}
|
|
22067
22187
|
function androidManifestPath2(app) {
|
|
22068
|
-
const androidDir =
|
|
22069
|
-
const preferred =
|
|
22070
|
-
if (
|
|
22071
|
-
const candidates =
|
|
22188
|
+
const androidDir = join30(appDir(app), "android");
|
|
22189
|
+
const preferred = join30(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
22190
|
+
if (existsSync26(preferred)) return preferred;
|
|
22191
|
+
const candidates = existsSync26(androidDir) ? readdirSync13(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join30(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync26) : [];
|
|
22072
22192
|
return candidates.length === 1 ? candidates[0] : preferred;
|
|
22073
22193
|
}
|
|
22074
22194
|
function automotiveAppDescPath(app) {
|
|
22075
|
-
return
|
|
22195
|
+
return join30(dirname18(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
|
|
22076
22196
|
}
|
|
22077
22197
|
function applyToFile(path, kind, label2, render, check) {
|
|
22078
|
-
if (!
|
|
22079
|
-
const before =
|
|
22198
|
+
if (!existsSync26(path)) return { path, outcome: "skipped" };
|
|
22199
|
+
const before = readFileSync28(path, "utf8");
|
|
22080
22200
|
if (!hasMarkers(before, kind, label2)) return { path, outcome: "skipped" };
|
|
22081
22201
|
const after = injectBlock(before, kind, label2, render);
|
|
22082
22202
|
if (after === before) return { path, outcome: "unchanged" };
|
|
@@ -22085,15 +22205,15 @@ function applyToFile(path, kind, label2, render, check) {
|
|
|
22085
22205
|
return { path, outcome: "written" };
|
|
22086
22206
|
}
|
|
22087
22207
|
function applyWholeFile(path, content, check) {
|
|
22088
|
-
const current =
|
|
22208
|
+
const current = existsSync26(path) ? readFileSync28(path, "utf8") : null;
|
|
22089
22209
|
if (current === content) return { path, outcome: "unchanged" };
|
|
22090
22210
|
if (check) return { path, outcome: "drift" };
|
|
22091
|
-
mkdirSync12(
|
|
22211
|
+
mkdirSync12(dirname18(path), { recursive: true });
|
|
22092
22212
|
writeFileSync11(path, content);
|
|
22093
22213
|
return { path, outcome: "written" };
|
|
22094
22214
|
}
|
|
22095
22215
|
function removeWholeFile(path, check) {
|
|
22096
|
-
if (!
|
|
22216
|
+
if (!existsSync26(path)) return { path, outcome: "skipped" };
|
|
22097
22217
|
if (check) return { path, outcome: "drift" };
|
|
22098
22218
|
rmSync3(path);
|
|
22099
22219
|
return { path, outcome: "removed" };
|
|
@@ -22101,7 +22221,7 @@ function removeWholeFile(path, check) {
|
|
|
22101
22221
|
function genNativeConfig(app, opts = {}) {
|
|
22102
22222
|
const check = opts.check ?? false;
|
|
22103
22223
|
const configPath = appConfigTs(app);
|
|
22104
|
-
const configTs =
|
|
22224
|
+
const configTs = existsSync26(configPath) ? readFileSync28(configPath, "utf8") : "";
|
|
22105
22225
|
const capabilities = parseStringArray(configTs, "capabilities");
|
|
22106
22226
|
const envelope = parseStringArray(configTs, "capabilityEnvelope");
|
|
22107
22227
|
const ids = buildSet(capabilities, envelope);
|
|
@@ -22117,7 +22237,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
22117
22237
|
const carBlock = applyToFile(carManifestPath, "xml", LABEL_CAR, (i) => renderCarManifestXml(carCategory, i), check);
|
|
22118
22238
|
assertCarBlockLanded(app, carCategory, carManifestPath, carBlock.outcome, LABEL_CAR);
|
|
22119
22239
|
const iosYml = iosProjectYml(app);
|
|
22120
|
-
const project =
|
|
22240
|
+
const project = existsSync26(iosYml) ? readFileSync28(iosYml, "utf8") : "";
|
|
22121
22241
|
const targetManaged = hasMarkers(project, "yaml", LABEL_LIVE_TARGET);
|
|
22122
22242
|
const embedManaged = hasMarkers(project, "yaml", LABEL_LIVE_EMBED);
|
|
22123
22243
|
if (targetManaged !== embedManaged) throw new Error(`${app}: Live Activity target and embedding markers must be installed together`);
|
|
@@ -22171,12 +22291,12 @@ function genNativeConfig(app, opts = {}) {
|
|
|
22171
22291
|
const plan = live2;
|
|
22172
22292
|
files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_TARGET, (i) => plan.target.map((line) => i + line), check));
|
|
22173
22293
|
files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_EMBED, (i) => plan.embed.map((line) => i + line), check));
|
|
22174
|
-
const source =
|
|
22294
|
+
const source = join30(dirname18(iosYml), LIVE_SOURCE_PATH);
|
|
22175
22295
|
files.push(plan.source ? applyWholeFile(source, plan.source, check) : removeWholeFile(source, check));
|
|
22176
|
-
const entitlements =
|
|
22296
|
+
const entitlements = join30(dirname18(iosYml), LIVE_ENTITLEMENTS_PATH);
|
|
22177
22297
|
files.push(plan.entitlements ? applyWholeFile(entitlements, plan.entitlements, check) : removeWholeFile(entitlements, check));
|
|
22178
22298
|
}
|
|
22179
|
-
const iosSplashManaged =
|
|
22299
|
+
const iosSplashManaged = existsSync26(iosYml) && hasMarkers(readFileSync28(iosYml, "utf8"), "yaml", LABEL_IOS_SPLASH);
|
|
22180
22300
|
const manifest = androidManifestPath2(app);
|
|
22181
22301
|
const splash = splashPlan(app, configTs, manifest, iosSplashManaged);
|
|
22182
22302
|
for (const artifact of splash.artifacts) files.push(applyWholeFile(artifact.path, artifact.content, check));
|
|
@@ -22264,8 +22384,8 @@ var init_app_module = __esm({
|
|
|
22264
22384
|
});
|
|
22265
22385
|
|
|
22266
22386
|
// ../../core/dev-server/src/loader.ts
|
|
22267
|
-
import { resolve as
|
|
22268
|
-
import { existsSync as
|
|
22387
|
+
import { resolve as resolve19, basename as basename7, dirname as dirname19 } from "node:path";
|
|
22388
|
+
import { existsSync as existsSync27, readdirSync as readdirSync14, readFileSync as readFileSync29, mkdirSync as mkdirSync13 } from "node:fs";
|
|
22269
22389
|
import { pathToFileURL as pathToFileURL5, fileURLToPath as fileURLToPath11 } from "node:url";
|
|
22270
22390
|
function resolveWixWebAuthConfig(app) {
|
|
22271
22391
|
const auth = app?.meta.auth;
|
|
@@ -22294,17 +22414,17 @@ function resolveWixClientId(app) {
|
|
|
22294
22414
|
}
|
|
22295
22415
|
function resolveDevEntry(name) {
|
|
22296
22416
|
for (const base of APP_ROOTS2) {
|
|
22297
|
-
const dir =
|
|
22298
|
-
const entry =
|
|
22299
|
-
if (
|
|
22417
|
+
const dir = resolve19(ROOT2, base, name);
|
|
22418
|
+
const entry = resolve19(dir, "dev/index.ts");
|
|
22419
|
+
if (existsSync27(entry)) return { entry, dir };
|
|
22300
22420
|
}
|
|
22301
22421
|
return null;
|
|
22302
22422
|
}
|
|
22303
22423
|
async function devModuleUrl(entry, dir) {
|
|
22304
22424
|
const hasTypeScriptLoader = process.execArgv.some((arg) => arg.includes("tsx"));
|
|
22305
22425
|
if (!isOffRepo() && hasTypeScriptLoader) return pathToFileURL5(entry).href;
|
|
22306
|
-
const out =
|
|
22307
|
-
mkdirSync13(
|
|
22426
|
+
const out = resolve19(dir, "dist/.himi/dev.mjs");
|
|
22427
|
+
mkdirSync13(dirname19(out), { recursive: true });
|
|
22308
22428
|
await buildAppEntry(entry, out, {
|
|
22309
22429
|
// Plain Node must resolve the published-style umbrella entry points for
|
|
22310
22430
|
// both standalone and in-repo CLI content. In-repo workspace packages
|
|
@@ -22326,7 +22446,7 @@ async function importDevModule(name, entry, dir) {
|
|
|
22326
22446
|
}
|
|
22327
22447
|
function readPlatformsJson(dir) {
|
|
22328
22448
|
try {
|
|
22329
|
-
const raw = JSON.parse(
|
|
22449
|
+
const raw = JSON.parse(readFileSync29(resolve19(dir, "platforms.json"), "utf8"));
|
|
22330
22450
|
return Object.fromEntries(
|
|
22331
22451
|
Object.entries(raw).filter(([k, v]) => VALID_PLATFORM_KEYS2.has(k) && typeof v === "boolean")
|
|
22332
22452
|
);
|
|
@@ -22335,17 +22455,17 @@ function readPlatformsJson(dir) {
|
|
|
22335
22455
|
}
|
|
22336
22456
|
}
|
|
22337
22457
|
async function loadContent(dir) {
|
|
22338
|
-
const absDir =
|
|
22339
|
-
const entry =
|
|
22340
|
-
if (!
|
|
22458
|
+
const absDir = resolve19(dir);
|
|
22459
|
+
const entry = resolve19(absDir, "dev/index.ts");
|
|
22460
|
+
if (!existsSync27(entry)) {
|
|
22341
22461
|
throw new Error(`No content package at "${absDir}": expected ${entry}.`);
|
|
22342
22462
|
}
|
|
22343
22463
|
let name = basename7(absDir);
|
|
22344
|
-
const manifestPath =
|
|
22345
|
-
if (
|
|
22464
|
+
const manifestPath = resolve19(absDir, "himalaya.content.json");
|
|
22465
|
+
if (existsSync27(manifestPath)) {
|
|
22346
22466
|
let manifest;
|
|
22347
22467
|
try {
|
|
22348
|
-
manifest = JSON.parse(
|
|
22468
|
+
manifest = JSON.parse(readFileSync29(manifestPath, "utf8"));
|
|
22349
22469
|
} catch (e) {
|
|
22350
22470
|
throw new Error(`Invalid himalaya.content.json at ${manifestPath}: ${e.message}`);
|
|
22351
22471
|
}
|
|
@@ -22371,11 +22491,11 @@ function listAvailableApps() {
|
|
|
22371
22491
|
const out = [];
|
|
22372
22492
|
const seen = /* @__PURE__ */ new Set();
|
|
22373
22493
|
for (const base of APP_ROOTS2) {
|
|
22374
|
-
const baseDir =
|
|
22375
|
-
if (!
|
|
22494
|
+
const baseDir = resolve19(ROOT2, base);
|
|
22495
|
+
if (!existsSync27(baseDir)) continue;
|
|
22376
22496
|
for (const name of readdirSync14(baseDir)) {
|
|
22377
22497
|
if (name.startsWith("_") || name.startsWith(".") || seen.has(name)) continue;
|
|
22378
|
-
if (
|
|
22498
|
+
if (existsSync27(resolve19(baseDir, name, "dev/index.ts"))) {
|
|
22379
22499
|
seen.add(name);
|
|
22380
22500
|
out.push({ name, root: base, kind: base === "test-apps" ? "test" : "app" });
|
|
22381
22501
|
}
|
|
@@ -22389,7 +22509,7 @@ var init_loader = __esm({
|
|
|
22389
22509
|
init_app_module();
|
|
22390
22510
|
init_preview_surfaces();
|
|
22391
22511
|
init_build_lib();
|
|
22392
|
-
ROOT2 =
|
|
22512
|
+
ROOT2 = resolve19(fileURLToPath11(new URL("../../..", import.meta.url)));
|
|
22393
22513
|
APP_ROOTS2 = ["apps", "test-apps"];
|
|
22394
22514
|
VALID_PLATFORM_KEYS2 = /* @__PURE__ */ new Set([
|
|
22395
22515
|
...PREVIEW_SURFACES.map((s) => s.platformKey).filter((k) => k !== null),
|
|
@@ -22434,8 +22554,8 @@ var init_build_sha = __esm({
|
|
|
22434
22554
|
|
|
22435
22555
|
// ../../core/dev-server/src/app-assets.ts
|
|
22436
22556
|
import { createHash as createHash8 } from "node:crypto";
|
|
22437
|
-
import { existsSync as
|
|
22438
|
-
import { join as
|
|
22557
|
+
import { existsSync as existsSync28, lstatSync as lstatSync3, readFileSync as readFileSync30, readdirSync as readdirSync15, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
|
|
22558
|
+
import { join as join31, resolve as resolve20, sep as sep5 } from "node:path";
|
|
22439
22559
|
function contentTypeFor(name) {
|
|
22440
22560
|
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
22441
22561
|
return CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
@@ -22449,19 +22569,19 @@ function assetSha256(bytes2) {
|
|
|
22449
22569
|
function findAssetsDir(appDir2) {
|
|
22450
22570
|
let declared;
|
|
22451
22571
|
try {
|
|
22452
|
-
declared = JSON.parse(
|
|
22572
|
+
declared = JSON.parse(readFileSync30(join31(appDir2, "himalaya.content.json"), "utf8")).assets;
|
|
22453
22573
|
} catch {
|
|
22454
22574
|
declared = void 0;
|
|
22455
22575
|
}
|
|
22456
22576
|
const rel = typeof declared === "string" && declared ? declared : "assets";
|
|
22457
|
-
const abs =
|
|
22458
|
-
const base =
|
|
22577
|
+
const abs = resolve20(appDir2, rel);
|
|
22578
|
+
const base = resolve20(appDir2);
|
|
22459
22579
|
if (abs !== base && !abs.startsWith(base + sep5)) return null;
|
|
22460
|
-
return
|
|
22580
|
+
return existsSync28(abs) && statSync5(abs).isDirectory() ? abs : null;
|
|
22461
22581
|
}
|
|
22462
22582
|
function readOtaOnlyPatterns(appDir2) {
|
|
22463
22583
|
try {
|
|
22464
|
-
const raw = JSON.parse(
|
|
22584
|
+
const raw = JSON.parse(readFileSync30(join31(appDir2, "assets.json"), "utf8"));
|
|
22465
22585
|
return Array.isArray(raw.otaOnly) ? raw.otaOnly.filter((p) => typeof p === "string") : [];
|
|
22466
22586
|
} catch {
|
|
22467
22587
|
return [];
|
|
@@ -22479,7 +22599,7 @@ function collectAssets(appDir2) {
|
|
|
22479
22599
|
const walk2 = (abs, prefix) => {
|
|
22480
22600
|
for (const entry of readdirSync15(abs, { withFileTypes: true })) {
|
|
22481
22601
|
if (entry.name.startsWith(".")) continue;
|
|
22482
|
-
const child =
|
|
22602
|
+
const child = join31(abs, entry.name);
|
|
22483
22603
|
const name = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
22484
22604
|
if (entry.isDirectory()) {
|
|
22485
22605
|
walk2(child, name);
|
|
@@ -22488,7 +22608,7 @@ function collectAssets(appDir2) {
|
|
|
22488
22608
|
if (!entry.isFile()) continue;
|
|
22489
22609
|
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
22490
22610
|
const baked = !OTA_ONLY_BY_DEFAULT.has(ext) && !otaOnly.some((p) => matchesPattern(name, p));
|
|
22491
|
-
out.push({ name, path: child, bytes:
|
|
22611
|
+
out.push({ name, path: child, bytes: statSync5(child).size, contentType: contentTypeFor(name), baked });
|
|
22492
22612
|
}
|
|
22493
22613
|
};
|
|
22494
22614
|
walk2(dir, "");
|
|
@@ -22497,7 +22617,7 @@ function collectAssets(appDir2) {
|
|
|
22497
22617
|
function collectBrandFonts(appDir2) {
|
|
22498
22618
|
let faces;
|
|
22499
22619
|
try {
|
|
22500
|
-
faces = JSON.parse(
|
|
22620
|
+
faces = JSON.parse(readFileSync30(join31(appDir2, "media/fonts/faces.json"), "utf8"));
|
|
22501
22621
|
} catch {
|
|
22502
22622
|
return [];
|
|
22503
22623
|
}
|
|
@@ -22510,7 +22630,7 @@ function collectBrandFonts(appDir2) {
|
|
|
22510
22630
|
const rel = typeof raw?.file === "string" ? raw.file : "";
|
|
22511
22631
|
if (!family || !postscriptName || !rel) continue;
|
|
22512
22632
|
if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
|
|
22513
|
-
const path =
|
|
22633
|
+
const path = join31(appDir2, rel);
|
|
22514
22634
|
try {
|
|
22515
22635
|
if (!lstatSync3(path).isFile()) continue;
|
|
22516
22636
|
const root = realpathSync3(appDir2);
|
|
@@ -22546,7 +22666,7 @@ function resolveAssetForBuild(appDir2, name, serverBaseUrl, appId2) {
|
|
|
22546
22666
|
if (!hit) return null;
|
|
22547
22667
|
let bytes2;
|
|
22548
22668
|
try {
|
|
22549
|
-
bytes2 =
|
|
22669
|
+
bytes2 = readFileSync30(hit.path);
|
|
22550
22670
|
} catch {
|
|
22551
22671
|
return null;
|
|
22552
22672
|
}
|
|
@@ -22620,7 +22740,7 @@ async function injectRequest(listener, request) {
|
|
|
22620
22740
|
req.headers.host ??= url.host;
|
|
22621
22741
|
if (body && body.length > 0) req.push(body);
|
|
22622
22742
|
req.push(null);
|
|
22623
|
-
return await new Promise((
|
|
22743
|
+
return await new Promise((resolve42, reject) => {
|
|
22624
22744
|
const streamed = () => {
|
|
22625
22745
|
queueMicrotask(() => {
|
|
22626
22746
|
req.emit("close");
|
|
@@ -22636,7 +22756,7 @@ async function injectRequest(listener, request) {
|
|
|
22636
22756
|
else headers2.set(name, value);
|
|
22637
22757
|
}
|
|
22638
22758
|
const bodyless = out.status === 204 || out.status === 304 || request.method === "HEAD";
|
|
22639
|
-
|
|
22759
|
+
resolve42(new Response(bodyless ? null : out.body, { status: out.status, headers: headers2 }));
|
|
22640
22760
|
}, streamed);
|
|
22641
22761
|
res.on("inject-error", reject);
|
|
22642
22762
|
try {
|
|
@@ -22739,25 +22859,25 @@ var init_inject = __esm({
|
|
|
22739
22859
|
|
|
22740
22860
|
// ../../core/dev-server/src/store.ts
|
|
22741
22861
|
import { mkdirSync as mkdirSync14 } from "node:fs";
|
|
22742
|
-
import { dirname as
|
|
22862
|
+
import { dirname as dirname20, resolve as resolve21 } from "node:path";
|
|
22743
22863
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
22744
22864
|
import { createRequire } from "node:module";
|
|
22745
22865
|
var nodeRequire, ROOT3, Store;
|
|
22746
22866
|
var init_store2 = __esm({
|
|
22747
22867
|
"../../core/dev-server/src/store.ts"() {
|
|
22748
22868
|
nodeRequire = createRequire(import.meta.url);
|
|
22749
|
-
ROOT3 =
|
|
22869
|
+
ROOT3 = resolve21(fileURLToPath12(new URL("../../..", import.meta.url)));
|
|
22750
22870
|
Store = class {
|
|
22751
22871
|
_db;
|
|
22752
22872
|
dbPath;
|
|
22753
22873
|
constructor(appName) {
|
|
22754
|
-
const dataRoot = process.env.HIMALAYA_DEV_STORE_DIR ?
|
|
22755
|
-
this.dbPath =
|
|
22874
|
+
const dataRoot = process.env.HIMALAYA_DEV_STORE_DIR ? resolve21(process.env.HIMALAYA_DEV_STORE_DIR) : resolve21(ROOT3, "core/dev-server/data");
|
|
22875
|
+
this.dbPath = resolve21(dataRoot, `${appName}.sqlite`);
|
|
22756
22876
|
}
|
|
22757
22877
|
/** The node:sqlite handle — opened, bootstrapped, and seeded on first access. */
|
|
22758
22878
|
get db() {
|
|
22759
22879
|
if (this._db) return this._db;
|
|
22760
|
-
mkdirSync14(
|
|
22880
|
+
mkdirSync14(dirname20(this.dbPath), { recursive: true });
|
|
22761
22881
|
const { DatabaseSync } = nodeRequire("node:sqlite");
|
|
22762
22882
|
this._db = new DatabaseSync(this.dbPath, { timeout: 5e3 });
|
|
22763
22883
|
this.bootstrap();
|
|
@@ -23096,15 +23216,15 @@ var init_store2 = __esm({
|
|
|
23096
23216
|
});
|
|
23097
23217
|
|
|
23098
23218
|
// ../../core/dev-server/src/derive-transport-capability.ts
|
|
23099
|
-
import { readFileSync as
|
|
23100
|
-
import { resolve as
|
|
23219
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
23220
|
+
import { resolve as resolve22 } from "node:path";
|
|
23101
23221
|
function bundleRidesWixTransport(bundleJs) {
|
|
23102
23222
|
return /himalaya\.wixApi|wixApi\.call/.test(bundleJs);
|
|
23103
23223
|
}
|
|
23104
23224
|
function readFirst(roots, file) {
|
|
23105
23225
|
for (const root of typeof roots === "string" ? [roots] : roots) {
|
|
23106
23226
|
try {
|
|
23107
|
-
return
|
|
23227
|
+
return readFileSync31(resolve22(root, file), "utf8");
|
|
23108
23228
|
} catch {
|
|
23109
23229
|
}
|
|
23110
23230
|
}
|
|
@@ -23272,7 +23392,7 @@ var init_wix_member_login = __esm({
|
|
|
23272
23392
|
});
|
|
23273
23393
|
|
|
23274
23394
|
// ../../core/dev-server/src/wix-gateway.ts
|
|
23275
|
-
import { readFileSync as
|
|
23395
|
+
import { readFileSync as readFileSync32, existsSync as existsSync29 } from "node:fs";
|
|
23276
23396
|
function redactJsonValue(v) {
|
|
23277
23397
|
if (Array.isArray(v)) return v.map(redactJsonValue);
|
|
23278
23398
|
if (v && typeof v === "object") {
|
|
@@ -23311,8 +23431,8 @@ function resolveNetMocks(fileMocks, appDeclared) {
|
|
|
23311
23431
|
}
|
|
23312
23432
|
function readNetMocksFile(path) {
|
|
23313
23433
|
try {
|
|
23314
|
-
if (!
|
|
23315
|
-
const raw = JSON.parse(
|
|
23434
|
+
if (!existsSync29(path)) return null;
|
|
23435
|
+
const raw = JSON.parse(readFileSync32(path, "utf-8"));
|
|
23316
23436
|
if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
|
|
23317
23437
|
if (raw && typeof raw === "object") {
|
|
23318
23438
|
const o = raw;
|
|
@@ -24112,13 +24232,13 @@ var init_l10n_catalog = __esm({
|
|
|
24112
24232
|
});
|
|
24113
24233
|
|
|
24114
24234
|
// ../../core/dev-server/src/l10n.ts
|
|
24115
|
-
import { readFileSync as
|
|
24116
|
-
import { resolve as
|
|
24235
|
+
import { readFileSync as readFileSync33, existsSync as existsSync30 } from "node:fs";
|
|
24236
|
+
import { resolve as resolve23 } from "node:path";
|
|
24117
24237
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
24118
24238
|
function loadCatalog2(tag) {
|
|
24119
24239
|
if (catalogCache.has(tag)) return catalogCache.get(tag);
|
|
24120
|
-
const path =
|
|
24121
|
-
const map =
|
|
24240
|
+
const path = resolve23(ROOT4, `tools/l10n/catalog.${tag}.json`);
|
|
24241
|
+
const map = existsSync30(path) ? sourceMap(parseCatalog(readFileSync33(path, "utf8"))) : /* @__PURE__ */ new Map();
|
|
24122
24242
|
catalogCache.set(tag, map);
|
|
24123
24243
|
return map;
|
|
24124
24244
|
}
|
|
@@ -24127,8 +24247,8 @@ function pickLocale(acceptLanguage) {
|
|
|
24127
24247
|
const tags = acceptLanguage.split(",").map((s) => s.split(";")[0].trim().toLowerCase()).map((s) => s.split("-")[0]).filter((s) => s.length > 0);
|
|
24128
24248
|
for (const tag of tags) {
|
|
24129
24249
|
if (tag === "en") continue;
|
|
24130
|
-
const path =
|
|
24131
|
-
if (
|
|
24250
|
+
const path = resolve23(ROOT4, `tools/l10n/catalog.${tag}.json`);
|
|
24251
|
+
if (existsSync30(path)) return tag;
|
|
24132
24252
|
}
|
|
24133
24253
|
return null;
|
|
24134
24254
|
}
|
|
@@ -24184,7 +24304,7 @@ var init_l10n = __esm({
|
|
|
24184
24304
|
"../../core/dev-server/src/l10n.ts"() {
|
|
24185
24305
|
init_l10n_strings();
|
|
24186
24306
|
init_l10n_catalog();
|
|
24187
|
-
ROOT4 =
|
|
24307
|
+
ROOT4 = resolve23(fileURLToPath13(new URL("../../..", import.meta.url)));
|
|
24188
24308
|
catalogCache = /* @__PURE__ */ new Map();
|
|
24189
24309
|
}
|
|
24190
24310
|
});
|
|
@@ -24248,13 +24368,13 @@ var init_stable_ids = __esm({
|
|
|
24248
24368
|
// ../../core/dev-server/src/preview.ts
|
|
24249
24369
|
import { spawn as spawn2 } from "node:child_process";
|
|
24250
24370
|
import { createHash as createHash11 } from "node:crypto";
|
|
24251
|
-
import { existsSync as
|
|
24371
|
+
import { existsSync as existsSync31, createReadStream, statSync as statSync6, readFileSync as readFileSync34, renameSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
24252
24372
|
import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
|
|
24253
|
-
import { resolve as resolvePath, dirname as
|
|
24373
|
+
import { resolve as resolvePath, dirname as dirname21 } from "node:path";
|
|
24254
24374
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
24255
24375
|
function firstExisting(paths) {
|
|
24256
24376
|
for (const p of paths) {
|
|
24257
|
-
if (p &&
|
|
24377
|
+
if (p && existsSync31(p)) return p;
|
|
24258
24378
|
}
|
|
24259
24379
|
return null;
|
|
24260
24380
|
}
|
|
@@ -24263,7 +24383,7 @@ function macosWinlistBin() {
|
|
|
24263
24383
|
}
|
|
24264
24384
|
function macosWinlistSourceHash() {
|
|
24265
24385
|
try {
|
|
24266
|
-
return createHash11("sha1").update(
|
|
24386
|
+
return createHash11("sha1").update(readFileSync34(MACOS_WINLIST)).digest("hex").slice(0, 12);
|
|
24267
24387
|
} catch {
|
|
24268
24388
|
return "missing";
|
|
24269
24389
|
}
|
|
@@ -24293,7 +24413,7 @@ function isHimalayaAppWindow(w) {
|
|
|
24293
24413
|
}
|
|
24294
24414
|
async function macosWinlistCommand() {
|
|
24295
24415
|
const bin = macosWinlistBin();
|
|
24296
|
-
if (
|
|
24416
|
+
if (existsSync31(bin)) return compiledWinlist(bin);
|
|
24297
24417
|
if (macosWinlistCompileFailed) return interpretWinlist();
|
|
24298
24418
|
if (!macosWinlistInFlight) {
|
|
24299
24419
|
macosWinlistInFlight = buildMacosWinlist(bin).finally(() => {
|
|
@@ -24321,7 +24441,7 @@ async function buildMacosWinlist(bin) {
|
|
|
24321
24441
|
unlinkSync2(staging);
|
|
24322
24442
|
} catch {
|
|
24323
24443
|
}
|
|
24324
|
-
return
|
|
24444
|
+
return existsSync31(bin) ? compiledWinlist(bin) : interpretWinlist();
|
|
24325
24445
|
}
|
|
24326
24446
|
return compiledWinlist(bin);
|
|
24327
24447
|
}
|
|
@@ -24408,7 +24528,7 @@ async function captureFrame(params, format = "png") {
|
|
|
24408
24528
|
const tmp = resolvePath(tmpdir2(), `himalaya-macos-preview-${windowId}-${process.pid}-${++macosCaptureSeq}.png`);
|
|
24409
24529
|
try {
|
|
24410
24530
|
await runner.capture(SCREENCAPTURE_BIN, ["-o", "-x", `-l${windowId}`, tmp]);
|
|
24411
|
-
return { buf:
|
|
24531
|
+
return { buf: readFileSync34(tmp), mime: "image/png" };
|
|
24412
24532
|
} finally {
|
|
24413
24533
|
try {
|
|
24414
24534
|
unlinkSync2(tmp);
|
|
@@ -24921,12 +25041,12 @@ function finalizeRecording(key2, rec) {
|
|
|
24921
25041
|
if (rec.finalize) return rec.finalize;
|
|
24922
25042
|
rec.finalize = (async () => {
|
|
24923
25043
|
clearTimeout(rec.autoStop);
|
|
24924
|
-
await new Promise((
|
|
25044
|
+
await new Promise((resolve42) => {
|
|
24925
25045
|
let done = false;
|
|
24926
25046
|
const finish2 = () => {
|
|
24927
25047
|
if (!done) {
|
|
24928
25048
|
done = true;
|
|
24929
|
-
|
|
25049
|
+
resolve42();
|
|
24930
25050
|
}
|
|
24931
25051
|
};
|
|
24932
25052
|
rec.child.once("close", finish2);
|
|
@@ -24946,7 +25066,7 @@ function finalizeRecording(key2, rec) {
|
|
|
24946
25066
|
} catch {
|
|
24947
25067
|
}
|
|
24948
25068
|
}
|
|
24949
|
-
const sizeBytes =
|
|
25069
|
+
const sizeBytes = existsSync31(rec.localPath) ? statSync6(rec.localPath).size : 0;
|
|
24950
25070
|
clips.set(rec.id, { path: rec.localPath, mime: rec.mime });
|
|
24951
25071
|
recordings.delete(key2);
|
|
24952
25072
|
return { sizeBytes };
|
|
@@ -25018,12 +25138,12 @@ async function handlePreviewClip(res, url) {
|
|
|
25018
25138
|
const q = new URLSearchParams(url.split("?")[1] ?? "");
|
|
25019
25139
|
const id = q.get("id") ?? "";
|
|
25020
25140
|
const clip = clips.get(id);
|
|
25021
|
-
if (!clip || !
|
|
25141
|
+
if (!clip || !existsSync31(clip.path)) {
|
|
25022
25142
|
res.statusCode = 404;
|
|
25023
25143
|
res.setHeader("content-type", "application/json");
|
|
25024
25144
|
return void res.end(JSON.stringify({ error: "clip_not_found", id }));
|
|
25025
25145
|
}
|
|
25026
|
-
const size =
|
|
25146
|
+
const size = statSync6(clip.path).size;
|
|
25027
25147
|
res.statusCode = 200;
|
|
25028
25148
|
res.setHeader("content-type", clip.mime);
|
|
25029
25149
|
res.setHeader("content-length", String(size));
|
|
@@ -25037,7 +25157,7 @@ var init_preview = __esm({
|
|
|
25037
25157
|
DEVICE_LIST_TIMEOUT_MS = 5e3;
|
|
25038
25158
|
defaultRunner2 = {
|
|
25039
25159
|
capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
|
|
25040
|
-
return new Promise((
|
|
25160
|
+
return new Promise((resolve42, reject) => {
|
|
25041
25161
|
const child = spawn2(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
25042
25162
|
const out = [];
|
|
25043
25163
|
const err = [];
|
|
@@ -25059,7 +25179,7 @@ var init_preview = __esm({
|
|
|
25059
25179
|
child.stderr.on("data", (b) => err.push(b));
|
|
25060
25180
|
child.on("error", (e) => settle(reject, e));
|
|
25061
25181
|
child.on("close", (code) => {
|
|
25062
|
-
if (code === 0) settle(
|
|
25182
|
+
if (code === 0) settle(resolve42, Buffer.concat(out));
|
|
25063
25183
|
else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
|
|
25064
25184
|
});
|
|
25065
25185
|
});
|
|
@@ -25079,7 +25199,7 @@ var init_preview = __esm({
|
|
|
25079
25199
|
SWIFT_BIN = process.env.HIMALAYA_SWIFT_PATH ?? "swift";
|
|
25080
25200
|
SWIFTC_BIN = process.env.HIMALAYA_SWIFTC_PATH ?? "swiftc";
|
|
25081
25201
|
SCREENCAPTURE_BIN = process.env.HIMALAYA_SCREENCAPTURE_PATH ?? "screencapture";
|
|
25082
|
-
MACOS_WINLIST = resolvePath(
|
|
25202
|
+
MACOS_WINLIST = resolvePath(dirname21(fileURLToPath14(import.meta.url)), "../scripts/macos-winshot.swift");
|
|
25083
25203
|
MACOS_WINLIST_BUILD_TIMEOUT_MS = 12e4;
|
|
25084
25204
|
MACOS_WINLIST_INTERPRET_TIMEOUT_MS = 3e4;
|
|
25085
25205
|
HIMALAYA_MAC_BUNDLE_ID = /^(com\.himalaya\.|com\.wix\.himi\.|dev\.himalaya\.)/i;
|
|
@@ -25136,8 +25256,8 @@ var init_tier4_integrity = __esm({
|
|
|
25136
25256
|
});
|
|
25137
25257
|
|
|
25138
25258
|
// ../../core/dev-server/src/tier4-verifier.ts
|
|
25139
|
-
import { readFileSync as
|
|
25140
|
-
import { resolve as
|
|
25259
|
+
import { readFileSync as readFileSync35, existsSync as existsSync32 } from "node:fs";
|
|
25260
|
+
import { resolve as resolve24 } from "node:path";
|
|
25141
25261
|
var TierFourVerifier;
|
|
25142
25262
|
var init_tier4_verifier = __esm({
|
|
25143
25263
|
"../../core/dev-server/src/tier4-verifier.ts"() {
|
|
@@ -25153,8 +25273,8 @@ var init_tier4_verifier = __esm({
|
|
|
25153
25273
|
async verifyServedFile(bundleId, relPath, providedBytes) {
|
|
25154
25274
|
const expected = this.expectedSri(bundleId, relPath);
|
|
25155
25275
|
if (!expected) return { ok: true };
|
|
25156
|
-
const path =
|
|
25157
|
-
const bytes2 = providedBytes ?? (
|
|
25276
|
+
const path = resolve24(this.tier4Root, bundleId, relPath);
|
|
25277
|
+
const bytes2 = providedBytes ?? (existsSync32(path) ? readFileSync35(path) : null);
|
|
25158
25278
|
if (!bytes2) return { ok: false, reason: "file not found" };
|
|
25159
25279
|
if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
|
|
25160
25280
|
return { ok: true };
|
|
@@ -25162,9 +25282,9 @@ var init_tier4_verifier = __esm({
|
|
|
25162
25282
|
bundle(bundleId) {
|
|
25163
25283
|
let cached3 = this.cache.get(bundleId);
|
|
25164
25284
|
if (cached3) return cached3;
|
|
25165
|
-
const manifestPath =
|
|
25166
|
-
if (!
|
|
25167
|
-
const manifest = JSON.parse(
|
|
25285
|
+
const manifestPath = resolve24(this.tier4Root, bundleId, "manifest.json");
|
|
25286
|
+
if (!existsSync32(manifestPath)) return void 0;
|
|
25287
|
+
const manifest = JSON.parse(readFileSync35(manifestPath, "utf8"));
|
|
25168
25288
|
cached3 = { integrity: parseManifestIntegrity(manifest) };
|
|
25169
25289
|
this.cache.set(bundleId, cached3);
|
|
25170
25290
|
return cached3;
|
|
@@ -26603,6 +26723,7 @@ function shouldRevealError(args) {
|
|
|
26603
26723
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
26604
26724
|
var init_validation = __esm({
|
|
26605
26725
|
"../../core/ts/src/validation.ts"() {
|
|
26726
|
+
"use strict";
|
|
26606
26727
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
26607
26728
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
26608
26729
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -30025,6 +30146,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
30025
30146
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
30026
30147
|
var init_worker_subtree = __esm({
|
|
30027
30148
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
30149
|
+
"use strict";
|
|
30028
30150
|
init_worker_subtree_safe_types_generated();
|
|
30029
30151
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
30030
30152
|
maxEncodedBytes: 65536,
|
|
@@ -35742,7 +35864,7 @@ async function stabilizePngPage(page, scheme) {
|
|
|
35742
35864
|
const browser = globalThis;
|
|
35743
35865
|
browser.document.documentElement.style.colorScheme = selected;
|
|
35744
35866
|
await browser.document.fonts?.ready;
|
|
35745
|
-
await new Promise((
|
|
35867
|
+
await new Promise((resolve42) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve42())));
|
|
35746
35868
|
}, scheme);
|
|
35747
35869
|
}
|
|
35748
35870
|
async function renderPngBatch(items) {
|
|
@@ -36686,8 +36808,8 @@ var init_src5 = __esm({
|
|
|
36686
36808
|
});
|
|
36687
36809
|
|
|
36688
36810
|
// ../../core/dev-server/src/flags/index.ts
|
|
36689
|
-
import { readFileSync as
|
|
36690
|
-
import { resolve as
|
|
36811
|
+
import { readFileSync as readFileSync36 } from "node:fs";
|
|
36812
|
+
import { resolve as resolve25 } from "node:path";
|
|
36691
36813
|
function selectProvider(config, store) {
|
|
36692
36814
|
const local = new LocalFlagProvider(store, () => config?.overrides);
|
|
36693
36815
|
if (!config || config.provider === "local") return local;
|
|
@@ -36782,7 +36904,7 @@ var init_flags2 = __esm({
|
|
|
36782
36904
|
if (now - this.lastFetch < this.ttlMs) return;
|
|
36783
36905
|
this.lastFetch = now;
|
|
36784
36906
|
try {
|
|
36785
|
-
const defs = JSON.parse(
|
|
36907
|
+
const defs = JSON.parse(readFileSync36(resolve25(appDir2, "flags.json"), "utf8"));
|
|
36786
36908
|
if (Array.isArray(defs) && defs.length > 0) store.replaceAll(defs);
|
|
36787
36909
|
} catch {
|
|
36788
36910
|
}
|
|
@@ -36832,19 +36954,19 @@ var init_motion_flags = __esm({
|
|
|
36832
36954
|
});
|
|
36833
36955
|
|
|
36834
36956
|
// ../../core/dev-server/src/kits.ts
|
|
36835
|
-
import { readdirSync as readdirSync16, readFileSync as
|
|
36836
|
-
import { resolve as
|
|
36957
|
+
import { readdirSync as readdirSync16, readFileSync as readFileSync37 } from "node:fs";
|
|
36958
|
+
import { resolve as resolve26, join as join32 } from "node:path";
|
|
36837
36959
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
36838
36960
|
function listKits() {
|
|
36839
36961
|
return readdirSync16(CATALOG).filter((f) => f.endsWith(".json")).map((f) => {
|
|
36840
|
-
const { tokens, ...meta } = JSON.parse(
|
|
36962
|
+
const { tokens, ...meta } = JSON.parse(readFileSync37(join32(CATALOG, f), "utf8"));
|
|
36841
36963
|
return meta;
|
|
36842
36964
|
});
|
|
36843
36965
|
}
|
|
36844
36966
|
function readKit(id) {
|
|
36845
36967
|
if (!/^[a-z0-9-]+$/.test(id)) return null;
|
|
36846
36968
|
try {
|
|
36847
|
-
return JSON.parse(
|
|
36969
|
+
return JSON.parse(readFileSync37(join32(CATALOG, `${id}.json`), "utf8"));
|
|
36848
36970
|
} catch {
|
|
36849
36971
|
return null;
|
|
36850
36972
|
}
|
|
@@ -36852,8 +36974,8 @@ function readKit(id) {
|
|
|
36852
36974
|
var ROOT5, CATALOG;
|
|
36853
36975
|
var init_kits = __esm({
|
|
36854
36976
|
"../../core/dev-server/src/kits.ts"() {
|
|
36855
|
-
ROOT5 =
|
|
36856
|
-
CATALOG =
|
|
36977
|
+
ROOT5 = resolve26(fileURLToPath15(new URL("../../..", import.meta.url)));
|
|
36978
|
+
CATALOG = join32(ROOT5, "stdlib/design-kits");
|
|
36857
36979
|
}
|
|
36858
36980
|
});
|
|
36859
36981
|
|
|
@@ -37221,12 +37343,12 @@ __export(validate_descriptor_exports, {
|
|
|
37221
37343
|
validateScreenDescriptor: () => validateScreenDescriptor,
|
|
37222
37344
|
workerSubtreeAllowed: () => workerSubtreeAllowed
|
|
37223
37345
|
});
|
|
37224
|
-
import { readFileSync as
|
|
37225
|
-
import { resolve as
|
|
37346
|
+
import { readFileSync as readFileSync38, existsSync as existsSync33, readdirSync as readdirSync17 } from "node:fs";
|
|
37347
|
+
import { resolve as resolve27 } from "node:path";
|
|
37226
37348
|
import { runInNewContext as runInNewContext2 } from "node:vm";
|
|
37227
37349
|
async function loadAllowedComponents(appDir2) {
|
|
37228
|
-
const modPath =
|
|
37229
|
-
if (!
|
|
37350
|
+
const modPath = resolve27(appDir2, "components.ts");
|
|
37351
|
+
if (!existsSync33(modPath)) return void 0;
|
|
37230
37352
|
try {
|
|
37231
37353
|
const { pathToFileURL: pathToFileURL8 } = await import("node:url");
|
|
37232
37354
|
const mod = await import(pathToFileURL8(modPath).href);
|
|
@@ -37238,8 +37360,8 @@ async function loadAllowedComponents(appDir2) {
|
|
|
37238
37360
|
return void 0;
|
|
37239
37361
|
}
|
|
37240
37362
|
function readBuiltBundle(tier5Root, bundleName) {
|
|
37241
|
-
const p =
|
|
37242
|
-
return
|
|
37363
|
+
const p = resolve27(tier5Root, `${bundleName}.bundle.js`);
|
|
37364
|
+
return existsSync33(p) ? readFileSync38(p, "utf8") : void 0;
|
|
37243
37365
|
}
|
|
37244
37366
|
function bundleNameFromUrl(url) {
|
|
37245
37367
|
if (typeof url !== "string") return null;
|
|
@@ -37266,11 +37388,11 @@ function appWorkerActionsFor(config, tier5Root) {
|
|
|
37266
37388
|
}
|
|
37267
37389
|
}
|
|
37268
37390
|
function readBuiltBundleMap(tier5Root, bundleName) {
|
|
37269
|
-
const p =
|
|
37270
|
-
return
|
|
37391
|
+
const p = resolve27(tier5Root, `${bundleName}.bundle.js.map`);
|
|
37392
|
+
return existsSync33(p) ? readFileSync38(p, "utf8") : void 0;
|
|
37271
37393
|
}
|
|
37272
37394
|
function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
|
|
37273
|
-
if (!
|
|
37395
|
+
if (!existsSync33(directory)) return [];
|
|
37274
37396
|
let entries;
|
|
37275
37397
|
try {
|
|
37276
37398
|
entries = readdirSync17(directory, { withFileTypes: true });
|
|
@@ -37281,7 +37403,7 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
|
|
|
37281
37403
|
return entries.flatMap((entry) => {
|
|
37282
37404
|
if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
|
|
37283
37405
|
if (entry.name === BUILD_OUTPUT_DIR && depth <= buildDirMaxDepth) return [];
|
|
37284
|
-
const path =
|
|
37406
|
+
const path = resolve27(directory, entry.name);
|
|
37285
37407
|
if (entry.isDirectory()) return nativeSourceFiles(path, extension, buildDirMaxDepth, depth + 1);
|
|
37286
37408
|
return entry.name.endsWith(extension) ? [path] : [];
|
|
37287
37409
|
});
|
|
@@ -37290,12 +37412,12 @@ function registeredActions(source) {
|
|
|
37290
37412
|
return [...source.matchAll(/ActionDispatcher(?:\.shared)?\s*\.\s*register\s*\(\s*"([A-Za-z0-9_.]+)"/g)].map((match) => match[1]);
|
|
37291
37413
|
}
|
|
37292
37414
|
function discoverNativeActions(appDir2) {
|
|
37293
|
-
const roots = NATIVE_SOURCE_ROOTS.filter(({ directory }) =>
|
|
37294
|
-
const sources = roots.flatMap(({ directory, extension, buildDirMaxDepth }) => nativeSourceFiles(
|
|
37415
|
+
const roots = NATIVE_SOURCE_ROOTS.filter(({ directory }) => existsSync33(resolve27(appDir2, directory)));
|
|
37416
|
+
const sources = roots.flatMap(({ directory, extension, buildDirMaxDepth }) => nativeSourceFiles(resolve27(appDir2, directory), extension, buildDirMaxDepth));
|
|
37295
37417
|
const registered = sources.flatMap((source) => {
|
|
37296
37418
|
let text2;
|
|
37297
37419
|
try {
|
|
37298
|
-
text2 =
|
|
37420
|
+
text2 = readFileSync38(source, "utf8");
|
|
37299
37421
|
} catch (err) {
|
|
37300
37422
|
if (!vanished(err)) throw err;
|
|
37301
37423
|
return [];
|
|
@@ -37411,8 +37533,8 @@ __export(config_exports, {
|
|
|
37411
37533
|
serializeRolloutYaml: () => serializeRolloutYaml,
|
|
37412
37534
|
validateOverlayPatch: () => validateOverlayPatch
|
|
37413
37535
|
});
|
|
37414
|
-
import { mkdirSync as mkdirSync15, readFileSync as
|
|
37415
|
-
import { dirname as
|
|
37536
|
+
import { mkdirSync as mkdirSync15, readFileSync as readFileSync39, writeFileSync as writeFileSync12 } from "node:fs";
|
|
37537
|
+
import { dirname as dirname22, join as join33, resolve as resolve28 } from "node:path";
|
|
37416
37538
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
37417
37539
|
function strip(line) {
|
|
37418
37540
|
const h = line.indexOf("#");
|
|
@@ -37477,14 +37599,14 @@ function parseRevocationsYaml(text2) {
|
|
|
37477
37599
|
function appConfigPath(app, file, root = REPO_ROOT6) {
|
|
37478
37600
|
assertAppId(app, "appConfigPath");
|
|
37479
37601
|
for (const base of ["apps", "test-apps"]) {
|
|
37480
|
-
const p =
|
|
37602
|
+
const p = join33(root, base, app, file);
|
|
37481
37603
|
try {
|
|
37482
|
-
|
|
37604
|
+
readFileSync39(p);
|
|
37483
37605
|
return p;
|
|
37484
37606
|
} catch {
|
|
37485
37607
|
}
|
|
37486
37608
|
}
|
|
37487
|
-
return
|
|
37609
|
+
return join33(root, "apps", app, file);
|
|
37488
37610
|
}
|
|
37489
37611
|
function serializeRolloutYaml(cfg) {
|
|
37490
37612
|
const lines = [`app: ${cfg.app}`, "rings:"];
|
|
@@ -37519,14 +37641,14 @@ function validateOverlayPatch(patch) {
|
|
|
37519
37641
|
}
|
|
37520
37642
|
function readJsonAt(app, file, root) {
|
|
37521
37643
|
try {
|
|
37522
|
-
return JSON.parse(
|
|
37644
|
+
return JSON.parse(readFileSync39(appConfigPath(app, file, root), "utf8"));
|
|
37523
37645
|
} catch {
|
|
37524
37646
|
return null;
|
|
37525
37647
|
}
|
|
37526
37648
|
}
|
|
37527
37649
|
function writeJsonAt(app, file, root, value) {
|
|
37528
37650
|
const path = appConfigPath(app, file, root);
|
|
37529
|
-
mkdirSync15(
|
|
37651
|
+
mkdirSync15(dirname22(path), { recursive: true });
|
|
37530
37652
|
writeFileSync12(path, JSON.stringify(value, null, 2) + "\n");
|
|
37531
37653
|
return path;
|
|
37532
37654
|
}
|
|
@@ -37549,14 +37671,14 @@ function saveLocalFlags(app, defs, root = REPO_ROOT6) {
|
|
|
37549
37671
|
}
|
|
37550
37672
|
function loadRollout(app) {
|
|
37551
37673
|
try {
|
|
37552
|
-
return parseRolloutYaml(
|
|
37674
|
+
return parseRolloutYaml(readFileSync39(appConfigPath(app, "rollout.yaml"), "utf8"));
|
|
37553
37675
|
} catch {
|
|
37554
37676
|
return null;
|
|
37555
37677
|
}
|
|
37556
37678
|
}
|
|
37557
37679
|
function loadRevocations(app) {
|
|
37558
37680
|
try {
|
|
37559
|
-
return parseRevocationsYaml(
|
|
37681
|
+
return parseRevocationsYaml(readFileSync39(appConfigPath(app, "revocations.yaml"), "utf8")).revoked;
|
|
37560
37682
|
} catch {
|
|
37561
37683
|
return [];
|
|
37562
37684
|
}
|
|
@@ -37566,7 +37688,7 @@ var init_config2 = __esm({
|
|
|
37566
37688
|
"../../core/serve-control/src/config.ts"() {
|
|
37567
37689
|
init_errors();
|
|
37568
37690
|
init_contract();
|
|
37569
|
-
REPO_ROOT6 =
|
|
37691
|
+
REPO_ROOT6 = resolve28(dirname22(fileURLToPath16(import.meta.url)), "../../..");
|
|
37570
37692
|
OPERATIONAL_OVERLAY_KEYS = /* @__PURE__ */ new Set([
|
|
37571
37693
|
"wixCachePolicy",
|
|
37572
37694
|
"telemetryConfig",
|
|
@@ -37627,8 +37749,8 @@ var init_config2 = __esm({
|
|
|
37627
37749
|
// ../../core/dev-server/src/index.ts
|
|
37628
37750
|
import { createServer as createServer2 } from "node:http";
|
|
37629
37751
|
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
37630
|
-
import { readFileSync as
|
|
37631
|
-
import { extname, resolve as
|
|
37752
|
+
import { readFileSync as readFileSync40, existsSync as existsSync34, watch, mkdirSync as mkdirSync16, rmSync as rmSync4 } from "node:fs";
|
|
37753
|
+
import { extname, resolve as resolve29, normalize as normalize3, sep as sep6, join as join34 } from "node:path";
|
|
37632
37754
|
import { createHash as createHash15, randomUUID } from "node:crypto";
|
|
37633
37755
|
import { fileURLToPath as fileURLToPath17, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
37634
37756
|
function deepMerge2(base, patch) {
|
|
@@ -37677,8 +37799,8 @@ function makeEtag(body) {
|
|
|
37677
37799
|
function readAppTokens(state) {
|
|
37678
37800
|
if (!state.app) return null;
|
|
37679
37801
|
try {
|
|
37680
|
-
const tokenPath = state.app.module.designTokensPath ??
|
|
37681
|
-
const parsed = JSON.parse(
|
|
37802
|
+
const tokenPath = state.app.module.designTokensPath ?? resolve29(state.app.dir, state.app.module.config.designTokensPath ?? "tokens.json");
|
|
37803
|
+
const parsed = JSON.parse(readFileSync40(tokenPath, "utf8"));
|
|
37682
37804
|
delete parsed._meta;
|
|
37683
37805
|
return parsed;
|
|
37684
37806
|
} catch {
|
|
@@ -37690,7 +37812,7 @@ function effectiveAppConfigOverride(state) {
|
|
|
37690
37812
|
if (state.app) {
|
|
37691
37813
|
try {
|
|
37692
37814
|
gitOverlay = JSON.parse(
|
|
37693
|
-
|
|
37815
|
+
readFileSync40(resolve29(state.app.dir, "app-config.overlay.json"), "utf8")
|
|
37694
37816
|
);
|
|
37695
37817
|
} catch {
|
|
37696
37818
|
}
|
|
@@ -37746,8 +37868,8 @@ function handleL10nRequest(req, res, state) {
|
|
|
37746
37868
|
if (!state.app || app !== state.app.name) {
|
|
37747
37869
|
return sendJson(res, 404, { error: "unknown_app", app }, cors);
|
|
37748
37870
|
}
|
|
37749
|
-
const path =
|
|
37750
|
-
if (!
|
|
37871
|
+
const path = resolve29(state.app.dir, "l10n", `${tag}.json`);
|
|
37872
|
+
if (!existsSync34(path)) {
|
|
37751
37873
|
res.writeHead(204, cors);
|
|
37752
37874
|
res.end();
|
|
37753
37875
|
return;
|
|
@@ -37756,7 +37878,7 @@ function handleL10nRequest(req, res, state) {
|
|
|
37756
37878
|
let messages;
|
|
37757
37879
|
try {
|
|
37758
37880
|
messages = Object.fromEntries(
|
|
37759
|
-
keyMap(parseCatalog(
|
|
37881
|
+
keyMap(parseCatalog(readFileSync40(path, "utf8")), { sourceFallback: tag === sourceLocale })
|
|
37760
37882
|
);
|
|
37761
37883
|
} catch {
|
|
37762
37884
|
return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
|
|
@@ -37803,8 +37925,8 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
37803
37925
|
}
|
|
37804
37926
|
function servedFontFaces(appDir2, tokens) {
|
|
37805
37927
|
try {
|
|
37806
|
-
const policyPath =
|
|
37807
|
-
const policy =
|
|
37928
|
+
const policyPath = join34(appDir2, "fonts.json");
|
|
37929
|
+
const policy = existsSync34(policyPath) ? JSON.parse(readFileSync40(policyPath, "utf8")) : {};
|
|
37808
37930
|
const plan = planFonts(tokens, policy);
|
|
37809
37931
|
if (plan.families.length === 0) return void 0;
|
|
37810
37932
|
return servedProjection(plan);
|
|
@@ -37819,7 +37941,7 @@ function fontFaceBytesBySha(_appDir, sha) {
|
|
|
37819
37941
|
for (const face of family.faces) {
|
|
37820
37942
|
if (face.sha256 !== sha) continue;
|
|
37821
37943
|
const src = faceSource(face.file, face.sha256);
|
|
37822
|
-
if (src) return
|
|
37944
|
+
if (src) return readFileSync40(src);
|
|
37823
37945
|
}
|
|
37824
37946
|
}
|
|
37825
37947
|
} catch {
|
|
@@ -38166,7 +38288,7 @@ async function buildDescriptorForScreenId(state, screenId, query = new URLSearch
|
|
|
38166
38288
|
function bundleIntegritySync(name, dir) {
|
|
38167
38289
|
for (const root of dir ? [dir, TIER5_ROOT] : [TIER5_ROOT]) {
|
|
38168
38290
|
try {
|
|
38169
|
-
const bytes2 =
|
|
38291
|
+
const bytes2 = readFileSync40(resolve29(root, `${name}.bundle.js`));
|
|
38170
38292
|
return "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
|
|
38171
38293
|
} catch {
|
|
38172
38294
|
}
|
|
@@ -38416,7 +38538,7 @@ function startBundleArtifactWatcher(state) {
|
|
|
38416
38538
|
}
|
|
38417
38539
|
}
|
|
38418
38540
|
async function rebuildBundleSource(name) {
|
|
38419
|
-
const lib = await import(pathToFileURL6(
|
|
38541
|
+
const lib = await import(pathToFileURL6(resolve29(TIER5_SRC_ROOT, "build-lib.mjs")).href);
|
|
38420
38542
|
await lib.buildBundle(name);
|
|
38421
38543
|
}
|
|
38422
38544
|
function startBundleSourceWatcher(state) {
|
|
@@ -38471,11 +38593,11 @@ function applyTopBarDefault(descriptor, config) {
|
|
|
38471
38593
|
async function reloadAppModule(state, opts) {
|
|
38472
38594
|
const current = state.app;
|
|
38473
38595
|
if (!current) return { ok: false, error: "no_app" };
|
|
38474
|
-
const entry =
|
|
38596
|
+
const entry = resolve29(current.dir, "dev/index.ts");
|
|
38475
38597
|
mkdirSync16(HMR_TMP_DIR, { recursive: true });
|
|
38476
|
-
const outfile =
|
|
38598
|
+
const outfile = resolve29(HMR_TMP_DIR, `${current.name}-${++appReloadSeq}.mjs`);
|
|
38477
38599
|
try {
|
|
38478
|
-
const lib = await import(pathToFileURL6(
|
|
38600
|
+
const lib = await import(pathToFileURL6(resolve29(TIER5_SRC_ROOT, "build-lib.mjs")).href);
|
|
38479
38601
|
await lib.buildAppEntry(entry, outfile, { confineTo: current.dir });
|
|
38480
38602
|
const mod = await import(pathToFileURL6(outfile).href);
|
|
38481
38603
|
const next = mod.default;
|
|
@@ -38748,7 +38870,7 @@ async function handleWebWix(req, res, state) {
|
|
|
38748
38870
|
}
|
|
38749
38871
|
if (match && (match.rule.kind ?? "mock") === "mock") {
|
|
38750
38872
|
const mocked = match.rule.response;
|
|
38751
|
-
if (mocked.delayMs) await new Promise((
|
|
38873
|
+
if (mocked.delayMs) await new Promise((resolve42) => setTimeout(resolve42, mocked.delayMs));
|
|
38752
38874
|
const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
38753
38875
|
recordWixTraffic(state.wix, state.appName, state.adminUrl, {
|
|
38754
38876
|
ts: started,
|
|
@@ -39239,7 +39361,7 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
39239
39361
|
const name = decodeURIComponent(sampleMatch[1]);
|
|
39240
39362
|
if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
|
|
39241
39363
|
try {
|
|
39242
|
-
const body = await readFile2(
|
|
39364
|
+
const body = await readFile2(resolve29(SAMPLES_ROOT, name), "utf-8");
|
|
39243
39365
|
return sendJson(res, 200, JSON.parse(body));
|
|
39244
39366
|
} catch {
|
|
39245
39367
|
return sendJson(res, 404, { error: "sample_not_found", name });
|
|
@@ -39509,9 +39631,9 @@ async function readBundleFile(name, dir) {
|
|
|
39509
39631
|
if (!/^[A-Za-z0-9_.\-]+$/.test(name)) return null;
|
|
39510
39632
|
const roots = dir ? [dir, TIER5_ROOT] : [TIER5_ROOT];
|
|
39511
39633
|
const candidates = roots.flatMap((root) => [
|
|
39512
|
-
|
|
39513
|
-
|
|
39514
|
-
|
|
39634
|
+
resolve29(root, `${name}.bundle.js`),
|
|
39635
|
+
resolve29(root, `${name}.js`),
|
|
39636
|
+
resolve29(root, name)
|
|
39515
39637
|
]);
|
|
39516
39638
|
for (const path of candidates) {
|
|
39517
39639
|
if (!roots.some((root) => path.startsWith(root))) continue;
|
|
@@ -39662,14 +39784,14 @@ async function handleWidgetClearPreview(res, state, widgetId) {
|
|
|
39662
39784
|
}
|
|
39663
39785
|
function readActionHandlerManifest(app) {
|
|
39664
39786
|
if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return { handlers: [] };
|
|
39665
|
-
const manifestPath =
|
|
39666
|
-
const bundlePath =
|
|
39787
|
+
const manifestPath = resolve29(ACTION_HANDLERS_ROOT, `${app}.manifest.json`);
|
|
39788
|
+
const bundlePath = resolve29(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
|
|
39667
39789
|
if (!manifestPath.startsWith(ACTION_HANDLERS_ROOT) || !bundlePath.startsWith(ACTION_HANDLERS_ROOT)) return { handlers: [] };
|
|
39668
39790
|
let decls;
|
|
39669
39791
|
let bytes2;
|
|
39670
39792
|
try {
|
|
39671
|
-
decls = JSON.parse(
|
|
39672
|
-
bytes2 =
|
|
39793
|
+
decls = JSON.parse(readFileSync40(manifestPath, "utf8"));
|
|
39794
|
+
bytes2 = readFileSync40(bundlePath);
|
|
39673
39795
|
} catch {
|
|
39674
39796
|
return { handlers: [] };
|
|
39675
39797
|
}
|
|
@@ -39682,7 +39804,7 @@ function handleActionHandlersManifest(res, app) {
|
|
|
39682
39804
|
}
|
|
39683
39805
|
async function handleActionHandlerBundleGet(res, app) {
|
|
39684
39806
|
if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return sendJson(res, 404, { error: "not_found" });
|
|
39685
|
-
const path =
|
|
39807
|
+
const path = resolve29(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
|
|
39686
39808
|
if (!path.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
|
|
39687
39809
|
try {
|
|
39688
39810
|
const bytes2 = await readFile2(path);
|
|
@@ -39699,9 +39821,9 @@ async function handleActionHandlerBundleGet(res, app) {
|
|
|
39699
39821
|
}
|
|
39700
39822
|
async function serveStatic(req, res, root, prefix) {
|
|
39701
39823
|
const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
|
|
39702
|
-
const
|
|
39703
|
-
const safe = normalize3(
|
|
39704
|
-
const fullPath =
|
|
39824
|
+
const relative8 = requested.replace(prefix, "").replace(/^\//, "");
|
|
39825
|
+
const safe = normalize3(relative8).replace(/^(\.\.[\/\\])+/, "");
|
|
39826
|
+
const fullPath = resolve29(root, safe);
|
|
39705
39827
|
if (!fullPath.startsWith(root)) {
|
|
39706
39828
|
return send(res, 403, "forbidden");
|
|
39707
39829
|
}
|
|
@@ -39907,7 +40029,7 @@ function createDevServer(opts = {}) {
|
|
|
39907
40029
|
};
|
|
39908
40030
|
const netMocksDisabled = opts.netMocks === false;
|
|
39909
40031
|
const explicitNetMocksPath = typeof opts.netMocks === "string" ? opts.netMocks : process.env.HIMALAYA_NET_MOCKS;
|
|
39910
|
-
const netMocksPath = netMocksDisabled ? void 0 : explicitNetMocksPath ?? (state.app?.meta.devGateway?.enabled === false ? void 0 : state.app ?
|
|
40032
|
+
const netMocksPath = netMocksDisabled ? void 0 : explicitNetMocksPath ?? (state.app?.meta.devGateway?.enabled === false ? void 0 : state.app ? resolve29(state.app.dir, "dev/net-mocks.json") : void 0);
|
|
39911
40033
|
const resolved2 = netMocksDisabled ? null : resolveNetMocks(
|
|
39912
40034
|
netMocksPath ? readNetMocksFile(netMocksPath) : null,
|
|
39913
40035
|
state.app?.meta.devGateway
|
|
@@ -39967,7 +40089,7 @@ function createDevServer(opts = {}) {
|
|
|
39967
40089
|
const q = new URLSearchParams(url.split("?")[1] ?? "");
|
|
39968
40090
|
const assetApp = q.get("app") ?? state.appName;
|
|
39969
40091
|
const assetDir = state.app && assetApp === state.app.name ? state.app.dir : resolveAppDir(assetApp);
|
|
39970
|
-
const hit = assetDir ? collectAssets(assetDir).find((a) => assetSha256(
|
|
40092
|
+
const hit = assetDir ? collectAssets(assetDir).find((a) => assetSha256(readFileSync40(a.path)) === sha) : void 0;
|
|
39971
40093
|
if (!hit && assetDir) {
|
|
39972
40094
|
const fontBytes = fontFaceBytesBySha(assetDir, sha);
|
|
39973
40095
|
if (fontBytes) {
|
|
@@ -39990,7 +40112,7 @@ function createDevServer(opts = {}) {
|
|
|
39990
40112
|
res.end(JSON.stringify({ error: "asset_not_found", app: assetApp, sha }));
|
|
39991
40113
|
return;
|
|
39992
40114
|
}
|
|
39993
|
-
const bytes2 =
|
|
40115
|
+
const bytes2 = readFileSync40(hit.path);
|
|
39994
40116
|
res.writeHead(200, {
|
|
39995
40117
|
"content-type": hit.contentType,
|
|
39996
40118
|
"content-length": String(bytes2.length),
|
|
@@ -40076,8 +40198,8 @@ function createDevServer(opts = {}) {
|
|
|
40076
40198
|
}
|
|
40077
40199
|
if (url === "/v1/schema/screen-descriptor.json" && req.method === "GET") {
|
|
40078
40200
|
try {
|
|
40079
|
-
const schemaPath =
|
|
40080
|
-
const body =
|
|
40201
|
+
const schemaPath = resolve29(ROOT6, "core/schema/generated/screen-descriptor.schema.json");
|
|
40202
|
+
const body = readFileSync40(schemaPath, "utf8");
|
|
40081
40203
|
return send(res, 200, body, {
|
|
40082
40204
|
"content-type": "application/schema+json; charset=utf-8",
|
|
40083
40205
|
"cache-control": "no-store",
|
|
@@ -40111,7 +40233,7 @@ function createDevServer(opts = {}) {
|
|
|
40111
40233
|
try {
|
|
40112
40234
|
const { parseRevocationsYaml: parseRevocationsYaml2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
40113
40235
|
revoked = parseRevocationsYaml2(
|
|
40114
|
-
|
|
40236
|
+
readFileSync40(resolve29(state.app.dir, "revocations.yaml"), "utf8")
|
|
40115
40237
|
).revoked;
|
|
40116
40238
|
} catch {
|
|
40117
40239
|
}
|
|
@@ -40343,18 +40465,18 @@ var init_src6 = __esm({
|
|
|
40343
40465
|
init_src5();
|
|
40344
40466
|
init_kits();
|
|
40345
40467
|
init_widgets();
|
|
40346
|
-
ROOT6 =
|
|
40347
|
-
TIER3_ROOT =
|
|
40348
|
-
TIER4_ROOT =
|
|
40468
|
+
ROOT6 = resolve29(fileURLToPath17(new URL("../../..", import.meta.url)));
|
|
40469
|
+
TIER3_ROOT = resolve29(ROOT6, "core/dev-server/web");
|
|
40470
|
+
TIER4_ROOT = resolve29(ROOT6, "core/dev-server/tier4-bundles");
|
|
40349
40471
|
tier4Verifier = new TierFourVerifier(TIER4_ROOT);
|
|
40350
|
-
TIER5_ROOT =
|
|
40351
|
-
ACTION_HANDLERS_ROOT =
|
|
40352
|
-
SAMPLES_ROOT =
|
|
40472
|
+
TIER5_ROOT = resolve29(ROOT6, "core/dev-server/tier5-bundles");
|
|
40473
|
+
ACTION_HANDLERS_ROOT = resolve29(ROOT6, "core/dev-server/action-handlers");
|
|
40474
|
+
SAMPLES_ROOT = resolve29(ROOT6, "core/dev-server/sdui-samples");
|
|
40353
40475
|
TELEMETRY_BUFFER_CAP = 1e3;
|
|
40354
40476
|
overrideHistorySeq = 0;
|
|
40355
40477
|
CACHE_CONTROL = "max-age=600, stale-while-revalidate=86400";
|
|
40356
|
-
TIER5_SRC_ROOT =
|
|
40357
|
-
HMR_TMP_DIR =
|
|
40478
|
+
TIER5_SRC_ROOT = resolve29(ROOT6, "core/dev-server/tier5-bundles-src");
|
|
40479
|
+
HMR_TMP_DIR = resolve29(ROOT6, "node_modules/.cache/himalaya-hmr");
|
|
40358
40480
|
appReloadSeq = 0;
|
|
40359
40481
|
WEBWIX_CLIENT_ID = process.env.DEMO_APP_WIX_CLIENT_ID ?? "4f58d461-c1f5-4a5d-a467-62cc2329e4dd";
|
|
40360
40482
|
WEBWIX_REDIRECT = "himalaya-demo-app://oauth/callback";
|
|
@@ -40719,12 +40841,12 @@ var init_query = __esm({
|
|
|
40719
40841
|
});
|
|
40720
40842
|
|
|
40721
40843
|
// ../../core/dev-server/src/crawl-input.ts
|
|
40722
|
-
function resolved(v,
|
|
40723
|
-
if (typeof v === "string") return v.startsWith("$service:") ?
|
|
40844
|
+
function resolved(v, resolve42) {
|
|
40845
|
+
if (typeof v === "string") return v.startsWith("$service:") ? resolve42(v) : v;
|
|
40724
40846
|
if (Array.isArray(v)) {
|
|
40725
40847
|
const out = v.flatMap((el) => {
|
|
40726
40848
|
if (typeof el !== "string" || !el.startsWith("$service:")) return [el];
|
|
40727
|
-
const r =
|
|
40849
|
+
const r = resolve42(el);
|
|
40728
40850
|
return Array.isArray(r) ? r : [r];
|
|
40729
40851
|
});
|
|
40730
40852
|
return out;
|
|
@@ -40738,9 +40860,9 @@ function hasRowBinding(props) {
|
|
|
40738
40860
|
return itemToken(v) || Array.isArray(v) && v.some(itemToken);
|
|
40739
40861
|
});
|
|
40740
40862
|
}
|
|
40741
|
-
function declaredOptionIds(props,
|
|
40863
|
+
function declaredOptionIds(props, resolve42) {
|
|
40742
40864
|
const literal = props.options ?? props.tabs ?? props.chips;
|
|
40743
|
-
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath,
|
|
40865
|
+
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve42) : void 0;
|
|
40744
40866
|
const raw = Array.isArray(bound) ? bound : literal;
|
|
40745
40867
|
if (!Array.isArray(raw)) return [];
|
|
40746
40868
|
const out = [];
|
|
@@ -40783,24 +40905,24 @@ function seedTokens(state, limit = 48) {
|
|
|
40783
40905
|
walk2(state, 0);
|
|
40784
40906
|
return out;
|
|
40785
40907
|
}
|
|
40786
|
-
function synthesizeInput(control,
|
|
40908
|
+
function synthesizeInput(control, resolve42, tokens) {
|
|
40787
40909
|
const id = `${control.type}.${control.callback}`;
|
|
40788
40910
|
const row = SYNTHESIZED_CONTROLS[id];
|
|
40789
40911
|
if (!row) return null;
|
|
40790
40912
|
const props = control.props;
|
|
40791
40913
|
if (hasRowBinding(props)) return null;
|
|
40792
40914
|
if (row.from === "declared-options") {
|
|
40793
|
-
const ids = declaredOptionIds(props,
|
|
40915
|
+
const ids = declaredOptionIds(props, resolve42);
|
|
40794
40916
|
if (!ids.length) return null;
|
|
40795
40917
|
if (row.encoding === "string-array") {
|
|
40796
|
-
const currentRaw2 = resolved(props.selectedIds,
|
|
40918
|
+
const currentRaw2 = resolved(props.selectedIds, resolve42);
|
|
40797
40919
|
const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x) => typeof x === "string");
|
|
40798
40920
|
const pick4 = ids.find((o) => !current3.includes(o));
|
|
40799
40921
|
if (pick4 === void 0) return null;
|
|
40800
40922
|
const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
|
|
40801
40923
|
return { key: row.key, value, from: row.from, current: current3, control: id };
|
|
40802
40924
|
}
|
|
40803
|
-
const currentRaw = resolved(props.selectedId,
|
|
40925
|
+
const currentRaw = resolved(props.selectedId, resolve42);
|
|
40804
40926
|
const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
|
|
40805
40927
|
const pick3 = ids.find((o) => o !== current2);
|
|
40806
40928
|
if (pick3 === void 0) return null;
|
|
@@ -40808,7 +40930,7 @@ function synthesizeInput(control, resolve41, tokens) {
|
|
|
40808
40930
|
}
|
|
40809
40931
|
if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
|
|
40810
40932
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
|
|
40811
|
-
const bound = binding2 === void 0 ? void 0 :
|
|
40933
|
+
const bound = binding2 === void 0 ? void 0 : resolve42(binding2);
|
|
40812
40934
|
const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
|
|
40813
40935
|
const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
|
|
40814
40936
|
const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
|
|
@@ -43025,8 +43147,8 @@ __export(build_exports2, {
|
|
|
43025
43147
|
withStoreNavBundle: () => withStoreNavBundle
|
|
43026
43148
|
});
|
|
43027
43149
|
import { createHash as createHash18 } from "node:crypto";
|
|
43028
|
-
import { readFileSync as
|
|
43029
|
-
import { dirname as
|
|
43150
|
+
import { readFileSync as readFileSync41, readdirSync as readdirSync18, existsSync as existsSync35 } from "node:fs";
|
|
43151
|
+
import { dirname as dirname23, join as join35, resolve as resolve30 } from "node:path";
|
|
43030
43152
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
43031
43153
|
import { createRequire as createRequire2 } from "node:module";
|
|
43032
43154
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -43048,7 +43170,7 @@ function bundleMapFor(tier5Dir, bundleName) {
|
|
|
43048
43170
|
if (!bundleName) return { bundleMap: null };
|
|
43049
43171
|
const built = readBuiltBundleMap(tier5Dir, bundleName);
|
|
43050
43172
|
if (built) return { bundleMap: built };
|
|
43051
|
-
if (
|
|
43173
|
+
if (resolve30(tier5Dir) !== TIER5_DIR) return { bundleMap: null };
|
|
43052
43174
|
let r;
|
|
43053
43175
|
try {
|
|
43054
43176
|
const { sourcemapForCommittedBundleSync } = requireFromHere(SOURCEMAP_ON_DEMAND_PATH);
|
|
@@ -43064,10 +43186,10 @@ function l10nLintOptions(locale, appDir2) {
|
|
|
43064
43186
|
const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
|
|
43065
43187
|
const catalog = /* @__PURE__ */ new Set();
|
|
43066
43188
|
for (const tag of tags) {
|
|
43067
|
-
const path =
|
|
43068
|
-
if (!
|
|
43189
|
+
const path = join35(appDir2, "l10n", `${tag}.json`);
|
|
43190
|
+
if (!existsSync35(path)) continue;
|
|
43069
43191
|
try {
|
|
43070
|
-
const parsed = JSON.parse(
|
|
43192
|
+
const parsed = JSON.parse(readFileSync41(path, "utf8"));
|
|
43071
43193
|
for (const m of Object.values(parsed.messages ?? {})) {
|
|
43072
43194
|
if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
|
|
43073
43195
|
catalog.add(m.source);
|
|
@@ -43232,7 +43354,7 @@ function shellSha(root = REPO_ROOT7) {
|
|
|
43232
43354
|
function isMonorepoCheckout(dir) {
|
|
43233
43355
|
try {
|
|
43234
43356
|
const top = execFileSync4("git", ["rev-parse", "--show-toplevel"], { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
43235
|
-
return top.length > 0 &&
|
|
43357
|
+
return top.length > 0 && existsSync35(join35(top, "core", "schema", "core.proto"));
|
|
43236
43358
|
} catch {
|
|
43237
43359
|
return false;
|
|
43238
43360
|
}
|
|
@@ -43365,8 +43487,8 @@ async function buildReleaseFromContent(contentDir2, dest, opts = {}) {
|
|
|
43365
43487
|
}
|
|
43366
43488
|
function readTokensForLint(preloaded) {
|
|
43367
43489
|
try {
|
|
43368
|
-
const tokenPath = preloaded.module.designTokensPath ??
|
|
43369
|
-
const parsed = JSON.parse(
|
|
43490
|
+
const tokenPath = preloaded.module.designTokensPath ?? resolve30(preloaded.dir, preloaded.module.config.designTokensPath ?? "tokens.json");
|
|
43491
|
+
const parsed = JSON.parse(readFileSync41(tokenPath, "utf8"));
|
|
43370
43492
|
delete parsed._meta;
|
|
43371
43493
|
return parsed;
|
|
43372
43494
|
} catch {
|
|
@@ -43503,7 +43625,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43503
43625
|
if (addrCache.has(name)) return addrCache.get(name);
|
|
43504
43626
|
let bytes2;
|
|
43505
43627
|
try {
|
|
43506
|
-
bytes2 =
|
|
43628
|
+
bytes2 = readFileSync41(join35(tier5Dir, `${name}.bundle.js`));
|
|
43507
43629
|
} catch {
|
|
43508
43630
|
return null;
|
|
43509
43631
|
}
|
|
@@ -43524,9 +43646,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43524
43646
|
const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
|
|
43525
43647
|
if (store.putDoc) {
|
|
43526
43648
|
for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
|
|
43527
|
-
const path =
|
|
43528
|
-
if (!
|
|
43529
|
-
const bytes2 =
|
|
43649
|
+
const path = join35(preloaded.dir, file);
|
|
43650
|
+
if (!existsSync35(path)) continue;
|
|
43651
|
+
const bytes2 = readFileSync41(path);
|
|
43530
43652
|
if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
|
|
43531
43653
|
throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
|
|
43532
43654
|
}
|
|
@@ -43541,7 +43663,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43541
43663
|
const iconPath = resolveAppDirIcon(preloaded.dir);
|
|
43542
43664
|
if (iconPath) {
|
|
43543
43665
|
try {
|
|
43544
|
-
const bytes2 =
|
|
43666
|
+
const bytes2 = readFileSync41(iconPath);
|
|
43545
43667
|
await store.putIcon(app, bytes2);
|
|
43546
43668
|
iconHash = sha2564(bytes2);
|
|
43547
43669
|
} catch {
|
|
@@ -43563,7 +43685,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43563
43685
|
}
|
|
43564
43686
|
const seenAssetSha = /* @__PURE__ */ new Set();
|
|
43565
43687
|
for (const a of collected) {
|
|
43566
|
-
const bytes2 =
|
|
43688
|
+
const bytes2 = readFileSync41(a.path);
|
|
43567
43689
|
const hash = sha2564(bytes2);
|
|
43568
43690
|
if (!seenAssetSha.has(hash)) {
|
|
43569
43691
|
await store.putAsset(app, hash, bytes2, a.contentType);
|
|
@@ -43584,7 +43706,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43584
43706
|
const canEmitFonts = hasVendoredFloor();
|
|
43585
43707
|
try {
|
|
43586
43708
|
const appTokens = readTokensForLint(preloaded) ?? {};
|
|
43587
|
-
const policy =
|
|
43709
|
+
const policy = existsSync35(join35(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync41(join35(preloaded.dir, "fonts.json"), "utf8")) : {};
|
|
43588
43710
|
fontPlan = planFonts(appTokens, policy);
|
|
43589
43711
|
} catch (err) {
|
|
43590
43712
|
throw new Error(
|
|
@@ -43600,7 +43722,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43600
43722
|
`[release-build] ${family.name} face ${face.postScriptName} has no local bytes (sha ${face.sha256.slice(0, 12)}\u2026), so the release would declare a face the asset route cannot serve. Run \`npm run fonts:catalog\` to warm the cache before publishing.`
|
|
43601
43723
|
);
|
|
43602
43724
|
}
|
|
43603
|
-
const bytes2 =
|
|
43725
|
+
const bytes2 = readFileSync41(src);
|
|
43604
43726
|
const hash = sha2564(bytes2);
|
|
43605
43727
|
if (hash !== face.sha256) {
|
|
43606
43728
|
throw new Error(
|
|
@@ -43624,7 +43746,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
43624
43746
|
if (store.putAsset) {
|
|
43625
43747
|
for (const face of collectBrandFonts(preloaded.dir)) {
|
|
43626
43748
|
try {
|
|
43627
|
-
const bytes2 =
|
|
43749
|
+
const bytes2 = readFileSync41(face.path);
|
|
43628
43750
|
if (bytes2.length === 0) continue;
|
|
43629
43751
|
const hash = sha2564(bytes2);
|
|
43630
43752
|
await store.putAsset(app, hash, bytes2, "font/ttf");
|
|
@@ -44046,10 +44168,10 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
|
|
|
44046
44168
|
await store.reset(app);
|
|
44047
44169
|
const sources = {};
|
|
44048
44170
|
for (const definition of config.functions.functions) {
|
|
44049
|
-
const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) =>
|
|
44050
|
-
const source = candidates.find((candidate) =>
|
|
44171
|
+
const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join35(preloaded.dir, "functions", `${definition.name}${extension}`));
|
|
44172
|
+
const source = candidates.find((candidate) => existsSync35(candidate));
|
|
44051
44173
|
if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
|
|
44052
|
-
sources[definition.name] =
|
|
44174
|
+
sources[definition.name] = readFileSync41(source, "utf8");
|
|
44053
44175
|
}
|
|
44054
44176
|
const built = await buildFunctions(config.functions.functions, sources);
|
|
44055
44177
|
const bundles = {};
|
|
@@ -44077,7 +44199,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
|
|
|
44077
44199
|
return { manifest, failedToBuild: [], missingBundles: [], auth: {} };
|
|
44078
44200
|
}
|
|
44079
44201
|
function listBuildableApps() {
|
|
44080
|
-
const appsDir =
|
|
44202
|
+
const appsDir = join35(REPO_ROOT7, "apps");
|
|
44081
44203
|
return readdirSync18(appsDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_")).map((d) => d.name);
|
|
44082
44204
|
}
|
|
44083
44205
|
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
|
|
@@ -44108,10 +44230,10 @@ var init_build3 = __esm({
|
|
|
44108
44230
|
BAKE_OFFLINE_BASE = "http://himalaya-bake.invalid";
|
|
44109
44231
|
KNOWN_ICON_NAMES = [...ICON_NAMES].sort();
|
|
44110
44232
|
KNOWN_ICONS = new Set(KNOWN_ICON_NAMES);
|
|
44111
|
-
REPO_ROOT7 =
|
|
44112
|
-
TIER5_DIR =
|
|
44233
|
+
REPO_ROOT7 = resolve30(dirname23(fileURLToPath18(import.meta.url)), "../..");
|
|
44234
|
+
TIER5_DIR = join35(REPO_ROOT7, "core/dev-server/tier5-bundles");
|
|
44113
44235
|
requireFromHere = createRequire2(import.meta.url);
|
|
44114
|
-
SOURCEMAP_ON_DEMAND_PATH =
|
|
44236
|
+
SOURCEMAP_ON_DEMAND_PATH = join35(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
|
|
44115
44237
|
BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
|
|
44116
44238
|
}
|
|
44117
44239
|
});
|
|
@@ -44288,18 +44410,18 @@ __export(captcha_exports, {
|
|
|
44288
44410
|
captchaContentInput: () => captchaContentInput,
|
|
44289
44411
|
runCaptcha: () => runCaptcha
|
|
44290
44412
|
});
|
|
44291
|
-
import { readFileSync as
|
|
44292
|
-
import { resolve as
|
|
44413
|
+
import { readFileSync as readFileSync42 } from "node:fs";
|
|
44414
|
+
import { resolve as resolve31 } from "node:path";
|
|
44293
44415
|
function readObject(path) {
|
|
44294
44416
|
try {
|
|
44295
|
-
return JSON.parse(
|
|
44417
|
+
return JSON.parse(readFileSync42(path, "utf8"));
|
|
44296
44418
|
} catch {
|
|
44297
44419
|
return {};
|
|
44298
44420
|
}
|
|
44299
44421
|
}
|
|
44300
44422
|
function captchaContentInput(dir) {
|
|
44301
|
-
const content = readObject(
|
|
44302
|
-
const provisioning = readObject(
|
|
44423
|
+
const content = readObject(resolve31(dir, "himalaya.content.json"));
|
|
44424
|
+
const provisioning = readObject(resolve31(dir, "provisioning.json"));
|
|
44303
44425
|
return {
|
|
44304
44426
|
app: text(content.name),
|
|
44305
44427
|
siteId: text(provisioning.siteId),
|
|
@@ -44951,8 +45073,8 @@ __export(pack_exports, {
|
|
|
44951
45073
|
});
|
|
44952
45074
|
import { createHash as createHash19 } from "node:crypto";
|
|
44953
45075
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
44954
|
-
import { existsSync as
|
|
44955
|
-
import { dirname as
|
|
45076
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync17, readFileSync as readFileSync43, readdirSync as readdirSync19, rmSync as rmSync5, statSync as statSync7, writeFileSync as writeFileSync13 } from "node:fs";
|
|
45077
|
+
import { dirname as dirname24, join as join36, resolve as resolve32 } from "node:path";
|
|
44956
45078
|
function writeZip(entries) {
|
|
44957
45079
|
const sorted = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
44958
45080
|
const total = sorted.reduce((n, e) => n + e.bytes.length, 0);
|
|
@@ -45046,13 +45168,13 @@ function inflateEntry(buf, entry) {
|
|
|
45046
45168
|
return bytes2;
|
|
45047
45169
|
}
|
|
45048
45170
|
function readIf(path) {
|
|
45049
|
-
return
|
|
45171
|
+
return existsSync36(path) && statSync7(path).isFile() ? readFileSync43(path) : null;
|
|
45050
45172
|
}
|
|
45051
45173
|
function listDir(dir) {
|
|
45052
|
-
return
|
|
45174
|
+
return existsSync36(dir) ? readdirSync19(dir).filter((f) => statSync7(join36(dir, f)).isFile()) : [];
|
|
45053
45175
|
}
|
|
45054
45176
|
function gatherReleaseEntries(appDir2) {
|
|
45055
|
-
const manifestPath =
|
|
45177
|
+
const manifestPath = join36(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
|
|
45056
45178
|
const manifestBytes = readIf(manifestPath);
|
|
45057
45179
|
if (!manifestBytes) throw new Error(`no ${HIMI_PACKAGE_MANIFEST_PATH} in ${appDir2} \u2014 build a release there first`);
|
|
45058
45180
|
const manifest = JSON.parse(manifestBytes.toString("utf8"));
|
|
@@ -45076,7 +45198,7 @@ function gatherReleaseEntries(appDir2) {
|
|
|
45076
45198
|
}
|
|
45077
45199
|
const missing = [];
|
|
45078
45200
|
for (const rel of wanted) {
|
|
45079
|
-
const bytes2 = readIf(
|
|
45201
|
+
const bytes2 = readIf(join36(appDir2, rel));
|
|
45080
45202
|
if (bytes2) entries.push({ path: rel, bytes: bytes2 });
|
|
45081
45203
|
else missing.push(rel);
|
|
45082
45204
|
}
|
|
@@ -45087,12 +45209,12 @@ function gatherReleaseEntries(appDir2) {
|
|
|
45087
45209
|
);
|
|
45088
45210
|
}
|
|
45089
45211
|
for (const name of SINGLETONS) {
|
|
45090
|
-
const bytes2 = readIf(
|
|
45212
|
+
const bytes2 = readIf(join36(appDir2, name));
|
|
45091
45213
|
if (bytes2) entries.push({ path: name, bytes: bytes2 });
|
|
45092
45214
|
}
|
|
45093
45215
|
const skipped = [];
|
|
45094
45216
|
for (const sub of ["screens", "bundles", "assets", "widgets"]) {
|
|
45095
|
-
for (const f of listDir(
|
|
45217
|
+
for (const f of listDir(join36(appDir2, sub))) {
|
|
45096
45218
|
if (!wanted.has(`${sub}/${f}`)) skipped.push(`${sub}/${f}`);
|
|
45097
45219
|
}
|
|
45098
45220
|
}
|
|
@@ -45125,18 +45247,18 @@ function buildEntries(appDir2, app, opts) {
|
|
|
45125
45247
|
return { all, header, manifest, skipped };
|
|
45126
45248
|
}
|
|
45127
45249
|
function packRelease(releaseRoot, app, out, opts = {}) {
|
|
45128
|
-
const appDir2 =
|
|
45250
|
+
const appDir2 = join36(resolve32(releaseRoot), app);
|
|
45129
45251
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
45130
45252
|
const buf = writeZip(all);
|
|
45131
|
-
const isDir =
|
|
45132
|
-
const outFile = isDir ?
|
|
45133
|
-
mkdirSync17(
|
|
45253
|
+
const isDir = existsSync36(out) && statSync7(out).isDirectory();
|
|
45254
|
+
const outFile = isDir ? join36(resolve32(out), packageFileName(app, header.releaseId)) : resolve32(out);
|
|
45255
|
+
mkdirSync17(dirname24(outFile), { recursive: true });
|
|
45134
45256
|
writeFileSync13(outFile, buf);
|
|
45135
45257
|
return { app, releaseId: header.releaseId, header, out: outFile, bytes: buf.length, entryCount: all.length, skipped };
|
|
45136
45258
|
}
|
|
45137
45259
|
function resolvePackageDirDest(outDir, app, releaseId) {
|
|
45138
45260
|
const packagedApp = (dir) => {
|
|
45139
|
-
const bytes2 = readIf(
|
|
45261
|
+
const bytes2 = readIf(join36(dir, HIMI_PACKAGE_HEADER_PATH));
|
|
45140
45262
|
if (!bytes2) return void 0;
|
|
45141
45263
|
try {
|
|
45142
45264
|
return JSON.parse(bytes2.toString("utf8")).app;
|
|
@@ -45145,15 +45267,15 @@ function resolvePackageDirDest(outDir, app, releaseId) {
|
|
|
45145
45267
|
}
|
|
45146
45268
|
};
|
|
45147
45269
|
const replaceable = (dir) => {
|
|
45148
|
-
if (!
|
|
45149
|
-
if (!
|
|
45270
|
+
if (!existsSync36(dir)) return true;
|
|
45271
|
+
if (!statSync7(dir).isDirectory()) return false;
|
|
45150
45272
|
return readdirSync19(dir).length === 0 || packagedApp(dir) === app;
|
|
45151
45273
|
};
|
|
45152
|
-
if (
|
|
45274
|
+
if (existsSync36(outDir) && !statSync7(outDir).isDirectory()) {
|
|
45153
45275
|
throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
|
|
45154
45276
|
}
|
|
45155
45277
|
if (replaceable(outDir)) return outDir;
|
|
45156
|
-
const child =
|
|
45278
|
+
const child = join36(outDir, packageDirName(app, releaseId));
|
|
45157
45279
|
if (!replaceable(child)) {
|
|
45158
45280
|
throw new Error(
|
|
45159
45281
|
`refusing to replace ${child}: it is not empty and is not a ${app} package (no ${HIMI_PACKAGE_HEADER_PATH}). Pass --out to a new or empty directory.`
|
|
@@ -45167,14 +45289,14 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
|
45167
45289
|
"a package carrying the app's source has no --format dir form: readers that predate the source entry drop it before hashing a directory and refuse the package as tampered. Pack it as a .himi archive."
|
|
45168
45290
|
);
|
|
45169
45291
|
}
|
|
45170
|
-
const appDir2 =
|
|
45292
|
+
const appDir2 = join36(resolve32(releaseRoot), app);
|
|
45171
45293
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
45172
|
-
const dest = resolvePackageDirDest(
|
|
45294
|
+
const dest = resolvePackageDirDest(resolve32(outDir), app, header.releaseId);
|
|
45173
45295
|
rmSync5(dest, { recursive: true, force: true });
|
|
45174
45296
|
let bytes2 = 0;
|
|
45175
45297
|
for (const entry of all) {
|
|
45176
|
-
const target =
|
|
45177
|
-
mkdirSync17(
|
|
45298
|
+
const target = join36(dest, entry.path);
|
|
45299
|
+
mkdirSync17(dirname24(target), { recursive: true });
|
|
45178
45300
|
writeFileSync13(target, entry.bytes);
|
|
45179
45301
|
bytes2 += entry.bytes.length;
|
|
45180
45302
|
}
|
|
@@ -45196,21 +45318,21 @@ function openPackageBuffer(buf) {
|
|
|
45196
45318
|
return openFromEntries(readZip(buf), { requireHeader: true });
|
|
45197
45319
|
}
|
|
45198
45320
|
function openPackageFile(file) {
|
|
45199
|
-
return openPackageBuffer(
|
|
45321
|
+
return openPackageBuffer(readFileSync43(file));
|
|
45200
45322
|
}
|
|
45201
45323
|
function openPackageDir(dir) {
|
|
45202
|
-
const root =
|
|
45324
|
+
const root = resolve32(dir);
|
|
45203
45325
|
const entries = /* @__PURE__ */ new Map();
|
|
45204
45326
|
const walk2 = (rel) => {
|
|
45205
|
-
const abs = rel ?
|
|
45327
|
+
const abs = rel ? join36(root, rel) : root;
|
|
45206
45328
|
for (const name of readdirSync19(abs)) {
|
|
45207
45329
|
const childRel = rel ? `${rel}/${name}` : name;
|
|
45208
|
-
const childAbs =
|
|
45209
|
-
if (
|
|
45210
|
-
else if (isSafeEntryName(childRel)) entries.set(childRel,
|
|
45330
|
+
const childAbs = join36(abs, name);
|
|
45331
|
+
if (statSync7(childAbs).isDirectory()) walk2(childRel);
|
|
45332
|
+
else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync43(childAbs));
|
|
45211
45333
|
}
|
|
45212
45334
|
};
|
|
45213
|
-
if (!
|
|
45335
|
+
if (!existsSync36(root)) throw new Error(`no such package directory: ${root}`);
|
|
45214
45336
|
walk2("");
|
|
45215
45337
|
const manifestBytes = entries.get(HIMI_PACKAGE_MANIFEST_PATH);
|
|
45216
45338
|
if (manifestBytes) {
|
|
@@ -45251,12 +45373,12 @@ function unpackTo(buf, dest, appFallback) {
|
|
|
45251
45373
|
const app = header.app ?? manifest?.app ?? appFallback;
|
|
45252
45374
|
if (!app) throw new Error("package declares no app id (no himi-package.json and no manifest.app)");
|
|
45253
45375
|
if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
|
|
45254
|
-
const root =
|
|
45255
|
-
const appDir2 =
|
|
45376
|
+
const root = resolve32(dest);
|
|
45377
|
+
const appDir2 = join36(root, app);
|
|
45256
45378
|
rmSync5(appDir2, { recursive: true, force: true });
|
|
45257
45379
|
for (const [rel, bytes2] of entries) {
|
|
45258
|
-
const target =
|
|
45259
|
-
mkdirSync17(
|
|
45380
|
+
const target = join36(appDir2, rel);
|
|
45381
|
+
mkdirSync17(dirname24(target), { recursive: true });
|
|
45260
45382
|
writeFileSync13(target, bytes2);
|
|
45261
45383
|
}
|
|
45262
45384
|
return { root, appDir: appDir2, app };
|
|
@@ -45290,19 +45412,19 @@ __export(app_source_exports, {
|
|
|
45290
45412
|
writeConflicts: () => writeConflicts,
|
|
45291
45413
|
zipAppSource: () => zipAppSource
|
|
45292
45414
|
});
|
|
45293
|
-
import { readdirSync as readdirSync20, lstatSync as lstatSync4, readFileSync as
|
|
45294
|
-
import { join as
|
|
45415
|
+
import { readdirSync as readdirSync20, lstatSync as lstatSync4, readFileSync as readFileSync44, mkdirSync as mkdirSync18, writeFileSync as writeFileSync14, existsSync as existsSync37, rmSync as rmSync6, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
45416
|
+
import { join as join37, resolve as resolve33, sep as sep7 } from "node:path";
|
|
45295
45417
|
function walkSourceTree(dir, file, skip) {
|
|
45296
45418
|
const walk2 = (relDir) => {
|
|
45297
|
-
for (const name of readdirSync20(
|
|
45298
|
-
const rel = relDir ?
|
|
45299
|
-
const st = lstatSync4(
|
|
45419
|
+
for (const name of readdirSync20(join37(dir, relDir))) {
|
|
45420
|
+
const rel = relDir ? join37(relDir, name) : name;
|
|
45421
|
+
const st = lstatSync4(join37(dir, rel));
|
|
45300
45422
|
if (st.isSymbolicLink()) {
|
|
45301
45423
|
skip(rel);
|
|
45302
45424
|
continue;
|
|
45303
45425
|
}
|
|
45304
45426
|
if (st.isDirectory()) {
|
|
45305
|
-
if (isDeniedSourceDir(name) ||
|
|
45427
|
+
if (isDeniedSourceDir(name) || existsSync37(join37(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
|
|
45306
45428
|
else walk2(rel);
|
|
45307
45429
|
continue;
|
|
45308
45430
|
}
|
|
@@ -45320,7 +45442,7 @@ function collectAppSource(dir) {
|
|
|
45320
45442
|
const skipped = [];
|
|
45321
45443
|
walkSourceTree(
|
|
45322
45444
|
dir,
|
|
45323
|
-
(archivePath, hostRel) => entries.push({ path: archivePath, bytes:
|
|
45445
|
+
(archivePath, hostRel) => entries.push({ path: archivePath, bytes: readFileSync44(join37(dir, hostRel)) }),
|
|
45324
45446
|
(hostRel) => skipped.push(hostRel)
|
|
45325
45447
|
);
|
|
45326
45448
|
entries.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -45350,7 +45472,7 @@ function pathKind(p) {
|
|
|
45350
45472
|
}
|
|
45351
45473
|
}
|
|
45352
45474
|
function writeAppSource(entries, destDir) {
|
|
45353
|
-
const root =
|
|
45475
|
+
const root = resolve33(destDir);
|
|
45354
45476
|
if (pathKind(root)?.isSymbolicLink()) {
|
|
45355
45477
|
throw new Error(
|
|
45356
45478
|
`refusing to restore into ${root}: the destination itself is a symlink, so every file would be written outside it. Remove it, or pass --out/--name somewhere else.`
|
|
@@ -45363,13 +45485,13 @@ function writeAppSource(entries, destDir) {
|
|
|
45363
45485
|
const segments = entry.path.split("/");
|
|
45364
45486
|
let dir = root;
|
|
45365
45487
|
for (const segment of segments.slice(0, -1)) {
|
|
45366
|
-
dir =
|
|
45488
|
+
dir = join37(dir, segment);
|
|
45367
45489
|
const kind = pathKind(dir);
|
|
45368
45490
|
if (kind?.isSymbolicLink()) unlinkSync3(dir);
|
|
45369
45491
|
else if (kind) continue;
|
|
45370
45492
|
mkdirSync18(dir);
|
|
45371
45493
|
}
|
|
45372
|
-
const target =
|
|
45494
|
+
const target = join37(root, ...segments);
|
|
45373
45495
|
if (pathKind(target)?.isSymbolicLink()) unlinkSync3(target);
|
|
45374
45496
|
writeFileSync14(target, entry.bytes);
|
|
45375
45497
|
written.push(entry.path);
|
|
@@ -45377,7 +45499,7 @@ function writeAppSource(entries, destDir) {
|
|
|
45377
45499
|
return written;
|
|
45378
45500
|
}
|
|
45379
45501
|
function staleSourcePaths(entries, destDir) {
|
|
45380
|
-
if (!
|
|
45502
|
+
if (!existsSync37(destDir)) return [];
|
|
45381
45503
|
const archived = new Set(entries.map((e) => e.path));
|
|
45382
45504
|
const stale = [];
|
|
45383
45505
|
walkSourceTree(destDir, (archivePath) => {
|
|
@@ -45390,7 +45512,7 @@ function deniedArchivePaths(entries) {
|
|
|
45390
45512
|
return entries.filter((e) => isDeniedSourcePath(e.path)).map((e) => e.path).sort();
|
|
45391
45513
|
}
|
|
45392
45514
|
function writeConflicts(entries, destDir) {
|
|
45393
|
-
const root =
|
|
45515
|
+
const root = resolve33(destDir);
|
|
45394
45516
|
const conflicts = [];
|
|
45395
45517
|
const seen = /* @__PURE__ */ new Set();
|
|
45396
45518
|
const say = (rel, what) => {
|
|
@@ -45404,7 +45526,7 @@ function writeConflicts(entries, destDir) {
|
|
|
45404
45526
|
let dir = root;
|
|
45405
45527
|
let stop = false;
|
|
45406
45528
|
for (const [i, segment] of segments.slice(0, -1).entries()) {
|
|
45407
|
-
dir =
|
|
45529
|
+
dir = join37(dir, segment);
|
|
45408
45530
|
const kind2 = pathKind(dir);
|
|
45409
45531
|
if (!kind2 || kind2.isSymbolicLink()) {
|
|
45410
45532
|
stop = true;
|
|
@@ -45416,7 +45538,7 @@ function writeConflicts(entries, destDir) {
|
|
|
45416
45538
|
break;
|
|
45417
45539
|
}
|
|
45418
45540
|
if (stop) continue;
|
|
45419
|
-
const kind = pathKind(
|
|
45541
|
+
const kind = pathKind(join37(root, ...segments));
|
|
45420
45542
|
if (kind && !kind.isSymbolicLink() && kind.isDirectory()) {
|
|
45421
45543
|
say(entry.path, "is a directory here, but the release has a file at that path");
|
|
45422
45544
|
}
|
|
@@ -45424,24 +45546,24 @@ function writeConflicts(entries, destDir) {
|
|
|
45424
45546
|
return conflicts;
|
|
45425
45547
|
}
|
|
45426
45548
|
function removeStaleSource(entries, destDir) {
|
|
45427
|
-
const root =
|
|
45549
|
+
const root = resolve33(destDir);
|
|
45428
45550
|
const removed = staleSourcePaths(entries, root);
|
|
45429
|
-
for (const rel of removed) rmSync6(
|
|
45551
|
+
for (const rel of removed) rmSync6(join37(root, ...rel.split("/")), { force: true });
|
|
45430
45552
|
const needed = /* @__PURE__ */ new Set();
|
|
45431
45553
|
for (const entry of entries) {
|
|
45432
45554
|
if (isDeniedSourcePath(entry.path)) continue;
|
|
45433
45555
|
const segments = entry.path.split("/");
|
|
45434
45556
|
for (let i = 1; i < segments.length; i++) needed.add(segments.slice(0, i).join("/"));
|
|
45435
45557
|
}
|
|
45436
|
-
if (
|
|
45558
|
+
if (existsSync37(root)) pruneEmptyDirs(root, "", needed, removed);
|
|
45437
45559
|
return removed.sort();
|
|
45438
45560
|
}
|
|
45439
45561
|
function pruneEmptyDirs(root, rel, needed, removed) {
|
|
45440
45562
|
let empty = true;
|
|
45441
|
-
for (const name of readdirSync20(rel ?
|
|
45442
|
-
const childRel = rel ?
|
|
45563
|
+
for (const name of readdirSync20(rel ? join37(root, rel) : root)) {
|
|
45564
|
+
const childRel = rel ? join37(rel, name) : name;
|
|
45443
45565
|
const posix3 = childRel.split(sep7).join("/");
|
|
45444
|
-
const kind = lstatSync4(
|
|
45566
|
+
const kind = lstatSync4(join37(root, childRel));
|
|
45445
45567
|
if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name)) {
|
|
45446
45568
|
empty = false;
|
|
45447
45569
|
continue;
|
|
@@ -45451,7 +45573,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
|
|
|
45451
45573
|
empty = false;
|
|
45452
45574
|
continue;
|
|
45453
45575
|
}
|
|
45454
|
-
rmdirSync(
|
|
45576
|
+
rmdirSync(join37(root, childRel));
|
|
45455
45577
|
removed.push(`${posix3}/`);
|
|
45456
45578
|
}
|
|
45457
45579
|
return empty;
|
|
@@ -45479,13 +45601,13 @@ __export(eject_exports, {
|
|
|
45479
45601
|
EJECTABLE: () => EJECTABLE,
|
|
45480
45602
|
ejectModule: () => ejectModule
|
|
45481
45603
|
});
|
|
45482
|
-
import { existsSync as
|
|
45483
|
-
import { dirname as
|
|
45604
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync19, readFileSync as readFileSync45, writeFileSync as writeFileSync15 } from "node:fs";
|
|
45605
|
+
import { dirname as dirname25, join as join38, relative as relative5, resolve as resolve34, sep as sep8 } from "node:path";
|
|
45484
45606
|
function locate(repoRootOrCwd, mod) {
|
|
45485
|
-
const inRepo =
|
|
45486
|
-
if (
|
|
45487
|
-
const dist =
|
|
45488
|
-
if (
|
|
45607
|
+
const inRepo = resolve34(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
45608
|
+
if (existsSync38(inRepo)) return { path: inRepo, form: "source" };
|
|
45609
|
+
const dist = resolve34(repoRootOrCwd, `node_modules/@wix/himalaya/dist/${mod}.mjs`);
|
|
45610
|
+
if (existsSync38(dist)) return { path: dist, form: "bundle" };
|
|
45489
45611
|
return null;
|
|
45490
45612
|
}
|
|
45491
45613
|
function specifiersFor(mod) {
|
|
@@ -45509,8 +45631,8 @@ function ejectModule(opts) {
|
|
|
45509
45631
|
};
|
|
45510
45632
|
}
|
|
45511
45633
|
const ext = found.form === "source" ? "ts" : "mjs";
|
|
45512
|
-
const target =
|
|
45513
|
-
mkdirSync19(
|
|
45634
|
+
const target = join38(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
|
|
45635
|
+
mkdirSync19(dirname25(target), { recursive: true });
|
|
45514
45636
|
const banner = `// EJECTED from @wix/himalaya/${mod}. This app owns this file now.
|
|
45515
45637
|
//
|
|
45516
45638
|
// Central fixes to @wix/himalaya/${mod} NO LONGER REACH THIS APP \u2014 including any
|
|
@@ -45523,17 +45645,17 @@ function ejectModule(opts) {
|
|
|
45523
45645
|
// gate still applies. Ejecting buys layout and flow, never the floor.
|
|
45524
45646
|
|
|
45525
45647
|
`;
|
|
45526
|
-
const normalized =
|
|
45648
|
+
const normalized = readFileSync45(found.path, "utf8").replace(
|
|
45527
45649
|
/(["'])@himalaya\/([a-z0-9-]+(?:\/[a-z0-9-]+)?)\1/g,
|
|
45528
45650
|
(_m, q, sub) => `${q}@wix/himalaya/${sub}${q}`
|
|
45529
45651
|
);
|
|
45530
45652
|
writeFileSync15(target, banner + normalized);
|
|
45531
45653
|
const rewired = [];
|
|
45532
45654
|
for (const f of files) {
|
|
45533
|
-
if (!
|
|
45534
|
-
const before =
|
|
45655
|
+
if (!existsSync38(f)) continue;
|
|
45656
|
+
const before = readFileSync45(f, "utf8");
|
|
45535
45657
|
let after = before;
|
|
45536
|
-
let rel =
|
|
45658
|
+
let rel = relative5(dirname25(f), target).split(sep8).join("/").replace(/\.tsx?$/, ".js");
|
|
45537
45659
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
45538
45660
|
for (const spec of specifiersFor(mod)) {
|
|
45539
45661
|
const q = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -45579,14 +45701,14 @@ __export(test_exports, {
|
|
|
45579
45701
|
scopeDescriptors: () => scopeDescriptors,
|
|
45580
45702
|
writeRecordedMocks: () => writeRecordedMocks
|
|
45581
45703
|
});
|
|
45582
|
-
import { existsSync as
|
|
45583
|
-
import { join as
|
|
45704
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync20, readFileSync as readFileSync46, writeFileSync as writeFileSync16 } from "node:fs";
|
|
45705
|
+
import { join as join39, resolve as resolve35 } from "node:path";
|
|
45584
45706
|
function readTestConfig(dir) {
|
|
45585
|
-
const p =
|
|
45586
|
-
if (!
|
|
45707
|
+
const p = resolve35(dir, TEST_CONFIG_FILE);
|
|
45708
|
+
if (!existsSync39(p)) return {};
|
|
45587
45709
|
let parsed;
|
|
45588
45710
|
try {
|
|
45589
|
-
parsed = JSON.parse(
|
|
45711
|
+
parsed = JSON.parse(readFileSync46(p, "utf8"));
|
|
45590
45712
|
} catch (e) {
|
|
45591
45713
|
throw new Error(`${TEST_CONFIG_FILE} is not valid JSON \u2014 ${e.message}`);
|
|
45592
45714
|
}
|
|
@@ -45629,7 +45751,7 @@ function readTestConfig(dir) {
|
|
|
45629
45751
|
function readNetRules(path) {
|
|
45630
45752
|
let parsed;
|
|
45631
45753
|
try {
|
|
45632
|
-
parsed = JSON.parse(
|
|
45754
|
+
parsed = JSON.parse(readFileSync46(path, "utf8"));
|
|
45633
45755
|
} catch (e) {
|
|
45634
45756
|
throw new Error(`--net ${path} could not be read as JSON \u2014 ${e.message}`);
|
|
45635
45757
|
}
|
|
@@ -45649,8 +45771,8 @@ function readNetRules(path) {
|
|
|
45649
45771
|
}
|
|
45650
45772
|
function defaultNetRules(dir) {
|
|
45651
45773
|
for (const rel of ["dev/net-mocks.json", "tests/net-mocks.json"]) {
|
|
45652
|
-
const p =
|
|
45653
|
-
if (
|
|
45774
|
+
const p = resolve35(dir, rel);
|
|
45775
|
+
if (existsSync39(p)) {
|
|
45654
45776
|
const rules = readNetRules(p);
|
|
45655
45777
|
if (rules.length) return { rules, from: rel };
|
|
45656
45778
|
}
|
|
@@ -45666,7 +45788,7 @@ function readCannedResponses() {
|
|
|
45666
45788
|
];
|
|
45667
45789
|
for (const url of candidates) {
|
|
45668
45790
|
try {
|
|
45669
|
-
const parsed = JSON.parse(
|
|
45791
|
+
const parsed = JSON.parse(readFileSync46(url, "utf8"));
|
|
45670
45792
|
const byKey = {};
|
|
45671
45793
|
for (const [k, v] of Object.entries(parsed)) {
|
|
45672
45794
|
if (!k.startsWith("//")) byKey[k] = v;
|
|
@@ -45758,8 +45880,8 @@ function writeRecordedMocks(opts) {
|
|
|
45758
45880
|
mkdir: (p) => mkdirSync20(p, { recursive: true }),
|
|
45759
45881
|
write: (p, s) => writeFileSync16(p, s)
|
|
45760
45882
|
};
|
|
45761
|
-
fs.mkdir(
|
|
45762
|
-
fs.write(
|
|
45883
|
+
fs.mkdir(join39(opts.dir, "dev"));
|
|
45884
|
+
fs.write(join39(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
|
|
45763
45885
|
return { ok: true, rules, to: "dev/net-mocks.json" };
|
|
45764
45886
|
}
|
|
45765
45887
|
function scopeDescriptors(descriptors, requestedIds, invalidScreens) {
|
|
@@ -45822,7 +45944,7 @@ async function runCrawl(opts) {
|
|
|
45822
45944
|
if (list.length > 1) collapsed.push({ representative: rep.screenId, instances: list.length });
|
|
45823
45945
|
}
|
|
45824
45946
|
}
|
|
45825
|
-
const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(
|
|
45947
|
+
const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve35(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
|
|
45826
45948
|
const suppressions = opts.config?.skip ?? [];
|
|
45827
45949
|
const suppressed = [];
|
|
45828
45950
|
const matchSuppression = (screen, actionId, componentId, invariant) => suppressions.find((s) => (s.screen === void 0 || s.screen === screen) && (s.action === void 0 || s.action === actionId) && (s.component === void 0 || s.component === componentId) && (s.invariant === void 0 || s.invariant === invariant));
|
|
@@ -46216,19 +46338,19 @@ var mobile_ux_lint_exports = {};
|
|
|
46216
46338
|
__export(mobile_ux_lint_exports, {
|
|
46217
46339
|
mobileUxIssues: () => mobileUxIssues
|
|
46218
46340
|
});
|
|
46219
|
-
import { existsSync as
|
|
46220
|
-
import { join as
|
|
46341
|
+
import { existsSync as existsSync40, readFileSync as readFileSync47 } from "node:fs";
|
|
46342
|
+
import { join as join40 } from "node:path";
|
|
46221
46343
|
function mobileUxIssues(dir, strict) {
|
|
46222
|
-
const file =
|
|
46223
|
-
if (!
|
|
46344
|
+
const file = join40(dir, "MOBILE-UX.md");
|
|
46345
|
+
if (!existsSync40(file)) return [];
|
|
46224
46346
|
let text2;
|
|
46225
46347
|
try {
|
|
46226
|
-
text2 =
|
|
46348
|
+
text2 = readFileSync47(file, "utf8");
|
|
46227
46349
|
} catch {
|
|
46228
46350
|
return [];
|
|
46229
46351
|
}
|
|
46230
46352
|
if (!text2) return [];
|
|
46231
|
-
return mobileUxMarkerFindings(text2).map((finding) => ({
|
|
46353
|
+
return mobileUxMarkerFindings(text2, recordedRenderWidths(dir)).map((finding) => ({
|
|
46232
46354
|
screen: null,
|
|
46233
46355
|
pass: "mobile-ux",
|
|
46234
46356
|
ruleCode: finding.code,
|
|
@@ -46244,6 +46366,7 @@ function mobileUxIssues(dir, strict) {
|
|
|
46244
46366
|
var init_mobile_ux_lint = __esm({
|
|
46245
46367
|
"src/mobile-ux-lint.ts"() {
|
|
46246
46368
|
init_mobile_ux_contract();
|
|
46369
|
+
init_ux_evidence();
|
|
46247
46370
|
}
|
|
46248
46371
|
});
|
|
46249
46372
|
|
|
@@ -46502,7 +46625,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
46502
46625
|
const headers2 = Object.fromEntries(new Headers(init.headers).entries());
|
|
46503
46626
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
46504
46627
|
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
46505
|
-
return await new Promise((
|
|
46628
|
+
return await new Promise((resolve42, reject) => {
|
|
46506
46629
|
let settled = false;
|
|
46507
46630
|
const finish2 = (fn) => {
|
|
46508
46631
|
if (settled) return;
|
|
@@ -46539,7 +46662,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
46539
46662
|
}
|
|
46540
46663
|
const responseHeaders = new Headers();
|
|
46541
46664
|
for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
|
|
46542
|
-
|
|
46665
|
+
resolve42(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
|
|
46543
46666
|
}));
|
|
46544
46667
|
});
|
|
46545
46668
|
req.once("error", (error) => finish2(() => reject(error)));
|
|
@@ -46839,7 +46962,7 @@ function createLocalTestSandbox() {
|
|
|
46839
46962
|
}
|
|
46840
46963
|
})();
|
|
46841
46964
|
`;
|
|
46842
|
-
return await new Promise((
|
|
46965
|
+
return await new Promise((resolve42, reject) => {
|
|
46843
46966
|
const { port1, port2 } = new MessageChannel();
|
|
46844
46967
|
const serializableContext = {
|
|
46845
46968
|
auth: context.auth,
|
|
@@ -46915,7 +47038,7 @@ function createLocalTestSandbox() {
|
|
|
46915
47038
|
timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
|
|
46916
47039
|
return;
|
|
46917
47040
|
}
|
|
46918
|
-
if (message.ok) finish2(() =>
|
|
47041
|
+
if (message.ok) finish2(() => resolve42({ value: message.value, durationMs: Date.now() - started }));
|
|
46919
47042
|
else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
|
|
46920
47043
|
});
|
|
46921
47044
|
worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
|
|
@@ -47882,8 +48005,8 @@ __export(functions_exports, {
|
|
|
47882
48005
|
resolveFunctionsTarget: () => resolveFunctionsTarget,
|
|
47883
48006
|
runRemoteFunctionOperation: () => runRemoteFunctionOperation
|
|
47884
48007
|
});
|
|
47885
|
-
import { readFileSync as
|
|
47886
|
-
import { join as
|
|
48008
|
+
import { readFileSync as readFileSync48, existsSync as existsSync41 } from "node:fs";
|
|
48009
|
+
import { join as join41, resolve as resolve36 } from "node:path";
|
|
47887
48010
|
function resolveFunctionsTarget(input) {
|
|
47888
48011
|
const explicitUrl = input.functionsUrl?.trim();
|
|
47889
48012
|
if (explicitUrl) return { mode: "remote", baseUrl: explicitUrl };
|
|
@@ -47895,16 +48018,16 @@ function resolveFunctionsTarget(input) {
|
|
|
47895
48018
|
return { mode: "local" };
|
|
47896
48019
|
}
|
|
47897
48020
|
async function loadFunctionsApp(dir) {
|
|
47898
|
-
const loaded = await loadContent(
|
|
48021
|
+
const loaded = await loadContent(resolve36(dir));
|
|
47899
48022
|
const config = loaded.module.config;
|
|
47900
48023
|
if (config.kind !== "functions" || !Array.isArray(config.functions?.functions)) {
|
|
47901
48024
|
throw new Error(`content package "${dir}" is not a functions-only app`);
|
|
47902
48025
|
}
|
|
47903
48026
|
const sources = {};
|
|
47904
48027
|
for (const definition of config.functions.functions) {
|
|
47905
|
-
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) =>
|
|
48028
|
+
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join41(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync41);
|
|
47906
48029
|
if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
|
|
47907
|
-
sources[definition.name] =
|
|
48030
|
+
sources[definition.name] = readFileSync48(source, "utf8");
|
|
47908
48031
|
}
|
|
47909
48032
|
const data = config.cms || config.data ? mergeDataResources(config) : void 0;
|
|
47910
48033
|
const dataErrors = validateDataResources(data, loaded.name).filter((issue2) => issue2.severity === "error");
|
|
@@ -48059,9 +48182,9 @@ __export(native_decode_exports, {
|
|
|
48059
48182
|
runNativeDecode: () => runNativeDecode
|
|
48060
48183
|
});
|
|
48061
48184
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
48062
|
-
import { existsSync as
|
|
48185
|
+
import { existsSync as existsSync42, mkdtempSync as mkdtempSync2, readFileSync as readFileSync49, rmSync as rmSync7, writeFileSync as writeFileSync17 } from "node:fs";
|
|
48063
48186
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
48064
|
-
import { join as
|
|
48187
|
+
import { join as join42 } from "node:path";
|
|
48065
48188
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
48066
48189
|
function nativeDecodePackageDir() {
|
|
48067
48190
|
return fileURLToPath19(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
|
|
@@ -48071,8 +48194,8 @@ function nativeDecodeAndroidHarnessDir() {
|
|
|
48071
48194
|
}
|
|
48072
48195
|
function nativeOracleShipped() {
|
|
48073
48196
|
return {
|
|
48074
|
-
ios:
|
|
48075
|
-
android:
|
|
48197
|
+
ios: existsSync42(join42(nativeDecodePackageDir(), "Package.swift")),
|
|
48198
|
+
android: existsSync42(join42(nativeDecodeAndroidHarnessDir(), "gradlew"))
|
|
48076
48199
|
};
|
|
48077
48200
|
}
|
|
48078
48201
|
function detectNativeDecode(options = {}) {
|
|
@@ -48083,7 +48206,7 @@ function detectNativeDecode(options = {}) {
|
|
|
48083
48206
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
48084
48207
|
}
|
|
48085
48208
|
if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
|
|
48086
|
-
const packageAvailable = options.packageAvailable ??
|
|
48209
|
+
const packageAvailable = options.packageAvailable ?? existsSync42(join42(packageDir, "Package.swift"));
|
|
48087
48210
|
if (!packageAvailable) {
|
|
48088
48211
|
return {
|
|
48089
48212
|
platform: "ios",
|
|
@@ -48095,7 +48218,7 @@ function detectNativeDecode(options = {}) {
|
|
|
48095
48218
|
}
|
|
48096
48219
|
function localPropertiesSdk(harnessDir) {
|
|
48097
48220
|
try {
|
|
48098
|
-
const match =
|
|
48221
|
+
const match = readFileSync49(join42(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
|
|
48099
48222
|
return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
|
|
48100
48223
|
} catch {
|
|
48101
48224
|
return null;
|
|
@@ -48103,8 +48226,8 @@ function localPropertiesSdk(harnessDir) {
|
|
|
48103
48226
|
}
|
|
48104
48227
|
function detectAndroidNativeDecode(options = {}) {
|
|
48105
48228
|
const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
|
|
48106
|
-
const gradlew =
|
|
48107
|
-
const gradlewAvailable = options.gradlewAvailable ??
|
|
48229
|
+
const gradlew = join42(harnessDir, "gradlew");
|
|
48230
|
+
const gradlewAvailable = options.gradlewAvailable ?? existsSync42(gradlew);
|
|
48108
48231
|
if (!gradlewAvailable) {
|
|
48109
48232
|
return {
|
|
48110
48233
|
platform: "android",
|
|
@@ -48114,7 +48237,7 @@ function detectAndroidNativeDecode(options = {}) {
|
|
|
48114
48237
|
}
|
|
48115
48238
|
const androidHome = options.androidHome ?? process.env.ANDROID_HOME ?? "";
|
|
48116
48239
|
const sdk = androidHome.trim() || (options.localPropertiesSdk !== void 0 ? options.localPropertiesSdk : localPropertiesSdk(harnessDir));
|
|
48117
|
-
const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 &&
|
|
48240
|
+
const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 && existsSync42(sdk));
|
|
48118
48241
|
if (!sdkAvailable) {
|
|
48119
48242
|
return {
|
|
48120
48243
|
platform: "android",
|
|
@@ -48186,14 +48309,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
|
|
|
48186
48309
|
return verdicts;
|
|
48187
48310
|
}
|
|
48188
48311
|
function runNativeDecode(options) {
|
|
48189
|
-
const descriptorDir = mkdtempSync2(
|
|
48312
|
+
const descriptorDir = mkdtempSync2(join42(tmpdir3(), "himi-native-decode-"));
|
|
48190
48313
|
const startedAt = Date.now();
|
|
48191
48314
|
try {
|
|
48192
48315
|
for (const descriptor of options.descriptors) {
|
|
48193
48316
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
48194
48317
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
48195
48318
|
}
|
|
48196
|
-
writeFileSync17(
|
|
48319
|
+
writeFileSync17(join42(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
48197
48320
|
}
|
|
48198
48321
|
options.progress?.("building cached Swift oracle");
|
|
48199
48322
|
execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
|
|
@@ -48205,7 +48328,7 @@ function runNativeDecode(options) {
|
|
|
48205
48328
|
encoding: "utf8"
|
|
48206
48329
|
}).trim();
|
|
48207
48330
|
options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
48208
|
-
const stdout = execFileSync5(
|
|
48331
|
+
const stdout = execFileSync5(join42(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
|
|
48209
48332
|
stdio: ["ignore", "pipe", "pipe"],
|
|
48210
48333
|
encoding: "utf8"
|
|
48211
48334
|
});
|
|
@@ -48223,15 +48346,15 @@ function runNativeDecode(options) {
|
|
|
48223
48346
|
}
|
|
48224
48347
|
}
|
|
48225
48348
|
function runAndroidNativeDecode(options) {
|
|
48226
|
-
const descriptorDir = mkdtempSync2(
|
|
48227
|
-
const outputPath =
|
|
48349
|
+
const descriptorDir = mkdtempSync2(join42(tmpdir3(), "himi-native-decode-android-"));
|
|
48350
|
+
const outputPath = join42(descriptorDir, "verdicts.ndjson");
|
|
48228
48351
|
const startedAt = Date.now();
|
|
48229
48352
|
try {
|
|
48230
48353
|
for (const descriptor of options.descriptors) {
|
|
48231
48354
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
48232
48355
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
48233
48356
|
}
|
|
48234
|
-
writeFileSync17(
|
|
48357
|
+
writeFileSync17(join42(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
48235
48358
|
}
|
|
48236
48359
|
options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
48237
48360
|
execFileSync5(options.gradlew, [
|
|
@@ -48246,7 +48369,7 @@ function runAndroidNativeDecode(options) {
|
|
|
48246
48369
|
stdio: ["ignore", "ignore", "pipe"],
|
|
48247
48370
|
encoding: "utf8"
|
|
48248
48371
|
});
|
|
48249
|
-
const stdout =
|
|
48372
|
+
const stdout = readFileSync49(outputPath, "utf8");
|
|
48250
48373
|
return {
|
|
48251
48374
|
platform: "android",
|
|
48252
48375
|
verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
|
|
@@ -48317,13 +48440,13 @@ __export(browser_authoring_exports, {
|
|
|
48317
48440
|
import { createServer as createServer3 } from "node:http";
|
|
48318
48441
|
import { createHash as createHash22, randomBytes as randomBytes5 } from "node:crypto";
|
|
48319
48442
|
import { execFile as execFile2 } from "node:child_process";
|
|
48320
|
-
import { existsSync as
|
|
48321
|
-
import { join as
|
|
48443
|
+
import { existsSync as existsSync43, readdirSync as readdirSync21, readFileSync as readFileSync50, realpathSync as realpathSync4, statSync as statSync8 } from "node:fs";
|
|
48444
|
+
import { join as join43, posix, relative as relative6, sep as sep9 } from "node:path";
|
|
48322
48445
|
function humanMs(ms) {
|
|
48323
48446
|
return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
|
|
48324
48447
|
}
|
|
48325
48448
|
function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
48326
|
-
const root =
|
|
48449
|
+
const root = join43(tier5SrcDir, bundleName);
|
|
48327
48450
|
const files = {};
|
|
48328
48451
|
const visitedDirs = /* @__PURE__ */ new Set();
|
|
48329
48452
|
const walk2 = (abs, rel) => {
|
|
@@ -48331,16 +48454,16 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
|
48331
48454
|
if (visitedDirs.has(real)) return;
|
|
48332
48455
|
visitedDirs.add(real);
|
|
48333
48456
|
for (const name of readdirSync21(abs).sort()) {
|
|
48334
|
-
const childAbs =
|
|
48457
|
+
const childAbs = join43(abs, name);
|
|
48335
48458
|
const childRel = posix.join(rel, name);
|
|
48336
|
-
if (
|
|
48459
|
+
if (statSync8(childAbs).isDirectory()) {
|
|
48337
48460
|
walk2(childAbs, childRel);
|
|
48338
48461
|
} else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
|
|
48339
|
-
files[childRel] =
|
|
48462
|
+
files[childRel] = readFileSync50(childAbs, "utf8");
|
|
48340
48463
|
}
|
|
48341
48464
|
}
|
|
48342
48465
|
};
|
|
48343
|
-
if (!
|
|
48466
|
+
if (!existsSync43(root)) return null;
|
|
48344
48467
|
walk2(root, `/tier5-src/${bundleName}`);
|
|
48345
48468
|
const entry = [`/tier5-src/${bundleName}/index.ts`, `/tier5-src/${bundleName}/index.js`].find((p) => p in files);
|
|
48346
48469
|
if (!entry) return null;
|
|
@@ -48357,20 +48480,20 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
48357
48480
|
const spec = m[1];
|
|
48358
48481
|
const virtual = posix.normalize(posix.join(dir, spec));
|
|
48359
48482
|
if (!virtual.startsWith("/tier5-src/")) continue;
|
|
48360
|
-
const onDisk =
|
|
48483
|
+
const onDisk = join43(tier5SrcDir, virtual.slice("/tier5-src/".length));
|
|
48361
48484
|
const candidates = [
|
|
48362
48485
|
onDisk,
|
|
48363
48486
|
`${onDisk}.ts`,
|
|
48364
48487
|
`${onDisk}.js`,
|
|
48365
48488
|
onDisk.replace(/\.js$/, ".ts"),
|
|
48366
|
-
|
|
48367
|
-
|
|
48489
|
+
join43(onDisk, "index.ts"),
|
|
48490
|
+
join43(onDisk, "index.js")
|
|
48368
48491
|
];
|
|
48369
48492
|
for (const abs of candidates) {
|
|
48370
|
-
if (!
|
|
48371
|
-
const key2 = `/tier5-src/${
|
|
48493
|
+
if (!existsSync43(abs) || statSync8(abs).isDirectory()) continue;
|
|
48494
|
+
const key2 = `/tier5-src/${relative6(tier5SrcDir, abs).split(sep9).join(posix.sep)}`;
|
|
48372
48495
|
if (key2 in files) break;
|
|
48373
|
-
files[key2] =
|
|
48496
|
+
files[key2] = readFileSync50(abs, "utf8");
|
|
48374
48497
|
queue.push(key2);
|
|
48375
48498
|
break;
|
|
48376
48499
|
}
|
|
@@ -48402,10 +48525,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
48402
48525
|
for (const source of Object.values(files)) visit(source);
|
|
48403
48526
|
return { modules, unsupported };
|
|
48404
48527
|
}
|
|
48405
|
-
function sdkSubpathReader(
|
|
48528
|
+
function sdkSubpathReader(resolve42) {
|
|
48406
48529
|
return (sub) => {
|
|
48407
48530
|
try {
|
|
48408
|
-
return
|
|
48531
|
+
return readFileSync50(resolve42(`@wix/himalaya/${sub}`), "utf8");
|
|
48409
48532
|
} catch {
|
|
48410
48533
|
return null;
|
|
48411
48534
|
}
|
|
@@ -48486,7 +48609,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
48486
48609
|
const token = mintToken2(payload);
|
|
48487
48610
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
48488
48611
|
if (unusable) throw new Error(unusable);
|
|
48489
|
-
return await new Promise((
|
|
48612
|
+
return await new Promise((resolve42, reject) => {
|
|
48490
48613
|
let settled = false;
|
|
48491
48614
|
let url = "";
|
|
48492
48615
|
const server = createServer3();
|
|
@@ -48538,7 +48661,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
48538
48661
|
}
|
|
48539
48662
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
48540
48663
|
const report = body.result;
|
|
48541
|
-
finish2(() =>
|
|
48664
|
+
finish2(() => resolve42({ report, url }));
|
|
48542
48665
|
})();
|
|
48543
48666
|
});
|
|
48544
48667
|
server.on("error", (e) => finish2(() => reject(e)));
|
|
@@ -48579,8 +48702,8 @@ __export(coverage_exports, {
|
|
|
48579
48702
|
suppressedNativeKeys: () => suppressedNativeKeys,
|
|
48580
48703
|
trendAndStore: () => trendAndStore
|
|
48581
48704
|
});
|
|
48582
|
-
import { existsSync as
|
|
48583
|
-
import { dirname as
|
|
48705
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync21, readFileSync as readFileSync51, writeFileSync as writeFileSync18 } from "node:fs";
|
|
48706
|
+
import { dirname as dirname26, join as join44 } from "node:path";
|
|
48584
48707
|
function suppressedNativeKeys(oracle) {
|
|
48585
48708
|
return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
|
|
48586
48709
|
}
|
|
@@ -48750,11 +48873,11 @@ function assembleLedger(r, options = {}) {
|
|
|
48750
48873
|
return out;
|
|
48751
48874
|
}
|
|
48752
48875
|
function trendAndStore(dir, entries, suppressed) {
|
|
48753
|
-
const p =
|
|
48876
|
+
const p = join44(dir, LEDGER_FILE);
|
|
48754
48877
|
let previous = null;
|
|
48755
48878
|
try {
|
|
48756
|
-
if (
|
|
48757
|
-
const parsed = JSON.parse(
|
|
48879
|
+
if (existsSync44(p)) {
|
|
48880
|
+
const parsed = JSON.parse(readFileSync51(p, "utf8"));
|
|
48758
48881
|
if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k) => typeof k === "string");
|
|
48759
48882
|
}
|
|
48760
48883
|
} catch {
|
|
@@ -48762,7 +48885,7 @@ function trendAndStore(dir, entries, suppressed) {
|
|
|
48762
48885
|
const current = entries.map((e) => e.key);
|
|
48763
48886
|
const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key2) => (suppressed ?? []).includes(key2))])];
|
|
48764
48887
|
try {
|
|
48765
|
-
mkdirSync21(
|
|
48888
|
+
mkdirSync21(dirname26(p), { recursive: true });
|
|
48766
48889
|
writeFileSync18(p, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
48767
48890
|
} catch {
|
|
48768
48891
|
return null;
|
|
@@ -48793,11 +48916,11 @@ function formatLedger(entries, trend) {
|
|
|
48793
48916
|
return out.join("\n");
|
|
48794
48917
|
}
|
|
48795
48918
|
function diffAndStoreObservations(dir, current) {
|
|
48796
|
-
const p =
|
|
48919
|
+
const p = join44(dir, OBS_FILE);
|
|
48797
48920
|
let previous = null;
|
|
48798
48921
|
try {
|
|
48799
|
-
if (
|
|
48800
|
-
const parsed = JSON.parse(
|
|
48922
|
+
if (existsSync44(p)) {
|
|
48923
|
+
const parsed = JSON.parse(readFileSync51(p, "utf8"));
|
|
48801
48924
|
if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
|
|
48802
48925
|
(v) => Array.isArray(v) && v.every((l) => typeof l === "string")
|
|
48803
48926
|
)) {
|
|
@@ -48807,7 +48930,7 @@ function diffAndStoreObservations(dir, current) {
|
|
|
48807
48930
|
} catch {
|
|
48808
48931
|
}
|
|
48809
48932
|
try {
|
|
48810
|
-
mkdirSync21(
|
|
48933
|
+
mkdirSync21(dirname26(p), { recursive: true });
|
|
48811
48934
|
writeFileSync18(p, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
48812
48935
|
} catch {
|
|
48813
48936
|
return null;
|
|
@@ -48846,8 +48969,8 @@ var LEDGER_FILE, OBS_FILE;
|
|
|
48846
48969
|
var init_coverage = __esm({
|
|
48847
48970
|
"src/coverage.ts"() {
|
|
48848
48971
|
init_native_decode();
|
|
48849
|
-
LEDGER_FILE =
|
|
48850
|
-
OBS_FILE =
|
|
48972
|
+
LEDGER_FILE = join44(".himi", "test-ledger.json");
|
|
48973
|
+
OBS_FILE = join44(".himi", "test-observations.json");
|
|
48851
48974
|
}
|
|
48852
48975
|
});
|
|
48853
48976
|
|
|
@@ -48860,11 +48983,11 @@ __export(assets_exports, {
|
|
|
48860
48983
|
removeAssetPayload: () => removeAssetPayload,
|
|
48861
48984
|
verifyReport: () => verifyReport
|
|
48862
48985
|
});
|
|
48863
|
-
import { readFileSync as
|
|
48986
|
+
import { readFileSync as readFileSync52 } from "node:fs";
|
|
48864
48987
|
import { basename as basename8 } from "node:path";
|
|
48865
48988
|
function declaredAssets(dir) {
|
|
48866
48989
|
return collectAssets(dir).map((a) => {
|
|
48867
|
-
const bytes2 =
|
|
48990
|
+
const bytes2 = readFileSync52(a.path);
|
|
48868
48991
|
return {
|
|
48869
48992
|
name: a.name,
|
|
48870
48993
|
sha256: assetSha256(bytes2),
|
|
@@ -48940,7 +49063,7 @@ function verifyReport(dir, app, manifest) {
|
|
|
48940
49063
|
};
|
|
48941
49064
|
}
|
|
48942
49065
|
function addAssetPayload(manifest, filePath, opts) {
|
|
48943
|
-
const bytes2 =
|
|
49066
|
+
const bytes2 = readFileSync52(filePath);
|
|
48944
49067
|
const name = opts.name ?? basename8(filePath);
|
|
48945
49068
|
const sha2565 = assetSha256(bytes2);
|
|
48946
49069
|
const record2 = {
|
|
@@ -50354,9 +50477,9 @@ __export(run_exports, {
|
|
|
50354
50477
|
runPackage: () => runPackage,
|
|
50355
50478
|
withoutProdServe: () => withoutProdServe
|
|
50356
50479
|
});
|
|
50357
|
-
import { cpSync, existsSync as
|
|
50480
|
+
import { cpSync, existsSync as existsSync45, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync3, readFileSync as readFileSync53, rmSync as rmSync8, statSync as statSync9 } from "node:fs";
|
|
50358
50481
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
50359
|
-
import { join as
|
|
50482
|
+
import { join as join45 } from "node:path";
|
|
50360
50483
|
import { spawn as spawn3 } from "node:child_process";
|
|
50361
50484
|
function makePackageRunHandler(opts) {
|
|
50362
50485
|
return makeRunHandler({
|
|
@@ -50374,9 +50497,9 @@ async function fetchBytes(url) {
|
|
|
50374
50497
|
}
|
|
50375
50498
|
async function resolvePackage(source, workDir) {
|
|
50376
50499
|
const isUrl2 = /^https?:\/\//i.test(source);
|
|
50377
|
-
if (!isUrl2 &&
|
|
50378
|
-
const appDirManifest =
|
|
50379
|
-
if (
|
|
50500
|
+
if (!isUrl2 && existsSync45(source) && statSync9(source).isDirectory()) {
|
|
50501
|
+
const appDirManifest = join45(source, "release-manifest.json");
|
|
50502
|
+
if (existsSync45(appDirManifest)) {
|
|
50380
50503
|
const opened2 = openPackageDir(source);
|
|
50381
50504
|
if (!opened2.validation.ok) {
|
|
50382
50505
|
throw new Error(`package is not valid:
|
|
@@ -50385,9 +50508,9 @@ async function resolvePackage(source, workDir) {
|
|
|
50385
50508
|
const app2 = opened2.header?.app ?? opened2.manifest?.app;
|
|
50386
50509
|
if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
|
|
50387
50510
|
if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
|
|
50388
|
-
const root2 = workDir ?? mkdtempSync3(
|
|
50389
|
-
const target =
|
|
50390
|
-
if (
|
|
50511
|
+
const root2 = workDir ?? mkdtempSync3(join45(tmpdir4(), "himi-run-"));
|
|
50512
|
+
const target = join45(root2, app2);
|
|
50513
|
+
if (join45(source) !== target) {
|
|
50391
50514
|
mkdirSync22(root2, { recursive: true });
|
|
50392
50515
|
rmSync8(target, { recursive: true, force: true });
|
|
50393
50516
|
cpSync(source, target, { recursive: true });
|
|
@@ -50404,8 +50527,8 @@ async function resolvePackage(source, workDir) {
|
|
|
50404
50527
|
}
|
|
50405
50528
|
throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
|
|
50406
50529
|
}
|
|
50407
|
-
const bytes2 = isUrl2 ? await fetchBytes(source) :
|
|
50408
|
-
const root = workDir ?? mkdtempSync3(
|
|
50530
|
+
const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync53(source);
|
|
50531
|
+
const root = workDir ?? mkdtempSync3(join45(tmpdir4(), "himi-run-"));
|
|
50409
50532
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
50410
50533
|
const opened = openPackageDir(appDir2);
|
|
50411
50534
|
if (!opened.validation.ok) {
|
|
@@ -50505,19 +50628,19 @@ __export(run_browser_exports, {
|
|
|
50505
50628
|
runInBrowser: () => runInBrowser
|
|
50506
50629
|
});
|
|
50507
50630
|
import { createServer as createServer5 } from "node:http";
|
|
50508
|
-
import { existsSync as
|
|
50631
|
+
import { existsSync as existsSync46, readFileSync as readFileSync54 } from "node:fs";
|
|
50509
50632
|
import { spawnSync as spawnSync3, execFile as execFile3 } from "node:child_process";
|
|
50510
|
-
import { dirname as
|
|
50633
|
+
import { dirname as dirname27, resolve as resolve37 } from "node:path";
|
|
50511
50634
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
50512
50635
|
function stagedDir() {
|
|
50513
|
-
return process.env.HIMI_BROWSER_PLANE_OUT ?
|
|
50636
|
+
return process.env.HIMI_BROWSER_PLANE_OUT ? resolve37(process.env.HIMI_BROWSER_PLANE_OUT) : resolve37(REPO, "packages", "serve", "dist", "browser-plane");
|
|
50514
50637
|
}
|
|
50515
50638
|
function missingStaged() {
|
|
50516
|
-
return [...SERVED].filter((f) => !
|
|
50639
|
+
return [...SERVED].filter((f) => !existsSync46(resolve37(stagedDir(), f))).sort();
|
|
50517
50640
|
}
|
|
50518
50641
|
function ensureBrowserPlaneStaged() {
|
|
50519
50642
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
50520
|
-
const r = spawnSync3(process.execPath, [
|
|
50643
|
+
const r = spawnSync3(process.execPath, [resolve37(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
50521
50644
|
cwd: REPO,
|
|
50522
50645
|
encoding: "utf8"
|
|
50523
50646
|
});
|
|
@@ -50603,7 +50726,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
50603
50726
|
}
|
|
50604
50727
|
const name = path === "/" || path === "/index.html" ? "host.html" : path.slice(1);
|
|
50605
50728
|
if (SERVED.has(name)) {
|
|
50606
|
-
if (!
|
|
50729
|
+
if (!existsSync46(resolve37(stagedDir(), name))) {
|
|
50607
50730
|
const restaged = ensureBrowserPlaneStaged();
|
|
50608
50731
|
if (!restaged.ok) {
|
|
50609
50732
|
res.writeHead(503, { "content-type": "application/json" });
|
|
@@ -50613,7 +50736,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
50613
50736
|
}
|
|
50614
50737
|
let bytes2;
|
|
50615
50738
|
try {
|
|
50616
|
-
bytes2 =
|
|
50739
|
+
bytes2 = readFileSync54(resolve37(stagedDir(), name));
|
|
50617
50740
|
} catch (e) {
|
|
50618
50741
|
res.writeHead(503, { "content-type": "application/json" });
|
|
50619
50742
|
res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
|
|
@@ -50656,8 +50779,8 @@ var HERE, REPO, SERVED;
|
|
|
50656
50779
|
var init_run_browser = __esm({
|
|
50657
50780
|
"src/run-browser.ts"() {
|
|
50658
50781
|
init_file_store();
|
|
50659
|
-
HERE =
|
|
50660
|
-
REPO =
|
|
50782
|
+
HERE = dirname27(fileURLToPath20(import.meta.url));
|
|
50783
|
+
REPO = resolve37(HERE, "..", "..", "..");
|
|
50661
50784
|
SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
|
|
50662
50785
|
}
|
|
50663
50786
|
});
|
|
@@ -51031,11 +51154,11 @@ __export(preflight_exports, {
|
|
|
51031
51154
|
parseStoreConfig: () => parseStoreConfig,
|
|
51032
51155
|
requireEnv: () => requireEnv
|
|
51033
51156
|
});
|
|
51034
|
-
import { existsSync as
|
|
51035
|
-
import { isAbsolute as
|
|
51157
|
+
import { existsSync as existsSync47, readFileSync as readFileSync55 } from "node:fs";
|
|
51158
|
+
import { isAbsolute as isAbsolute3, relative as relative7, resolve as resolve38 } from "node:path";
|
|
51036
51159
|
function isInsideRepo(p) {
|
|
51037
|
-
const rel =
|
|
51038
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
51160
|
+
const rel = relative7(REPO_ROOT3, resolve38(p));
|
|
51161
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
|
|
51039
51162
|
}
|
|
51040
51163
|
function assertCredentialOutsideRepo(label2, p) {
|
|
51041
51164
|
if (isInsideRepo(p)) {
|
|
@@ -51088,10 +51211,10 @@ function parseStoreConfig(text2) {
|
|
|
51088
51211
|
}
|
|
51089
51212
|
function loadStoreConfig(app) {
|
|
51090
51213
|
const p = storeConfigPath(app);
|
|
51091
|
-
if (!
|
|
51214
|
+
if (!existsSync47(p)) {
|
|
51092
51215
|
throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
51093
51216
|
}
|
|
51094
|
-
return parseStoreConfig(
|
|
51217
|
+
return parseStoreConfig(readFileSync55(p, "utf8"));
|
|
51095
51218
|
}
|
|
51096
51219
|
var init_preflight = __esm({
|
|
51097
51220
|
"../store-release/preflight.ts"() {
|
|
@@ -51114,9 +51237,9 @@ __export(preflight_app_exports, {
|
|
|
51114
51237
|
pngSize: () => pngSize,
|
|
51115
51238
|
preflightApp: () => preflightApp
|
|
51116
51239
|
});
|
|
51117
|
-
import { readFileSync as
|
|
51240
|
+
import { readFileSync as readFileSync56, existsSync as existsSync48, readdirSync as readdirSync22, statSync as statSync10 } from "node:fs";
|
|
51118
51241
|
import { createHash as createHash23 } from "node:crypto";
|
|
51119
|
-
import { join as
|
|
51242
|
+
import { join as join46 } from "node:path";
|
|
51120
51243
|
function analyze(projectYml, storeConfig, icon) {
|
|
51121
51244
|
const f = [];
|
|
51122
51245
|
const has = (re, s) => re.test(s);
|
|
@@ -51164,10 +51287,10 @@ function analyze(projectYml, storeConfig, icon) {
|
|
|
51164
51287
|
return f;
|
|
51165
51288
|
}
|
|
51166
51289
|
async function preflightApp(app) {
|
|
51167
|
-
const projectYml =
|
|
51168
|
-
const storeConfig =
|
|
51290
|
+
const projectYml = existsSync48(iosProjectYml(app)) ? readFileSync56(iosProjectYml(app), "utf8") : "";
|
|
51291
|
+
const storeConfig = existsSync48(storeConfigPath(app)) ? readFileSync56(storeConfigPath(app), "utf8") : "";
|
|
51169
51292
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
51170
|
-
const findings = analyze(projectYml, storeConfig, await appIconState(
|
|
51293
|
+
const findings = analyze(projectYml, storeConfig, await appIconState(join46(appDir(app), "ios")));
|
|
51171
51294
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
51172
51295
|
findings.push(
|
|
51173
51296
|
...analyzePlayListing(playListingAssets(app)).map((finding) => ({ ...finding, level: "warn" }))
|
|
@@ -51194,17 +51317,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
51194
51317
|
return f;
|
|
51195
51318
|
}
|
|
51196
51319
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
51197
|
-
const root =
|
|
51320
|
+
const root = join46(storeDir(app), "metadata");
|
|
51198
51321
|
const out = /* @__PURE__ */ new Set();
|
|
51199
|
-
if (
|
|
51322
|
+
if (existsSync48(root)) {
|
|
51200
51323
|
for (const n of readdirSync22(root)) if (n.endsWith(".txt")) out.add(n);
|
|
51201
51324
|
}
|
|
51202
|
-
if (
|
|
51325
|
+
if (existsSync48(join46(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
51203
51326
|
return out;
|
|
51204
51327
|
}
|
|
51205
51328
|
function reviewInfoFiles(app) {
|
|
51206
|
-
const dir =
|
|
51207
|
-
if (!
|
|
51329
|
+
const dir = join46(storeDir(app), "review_information");
|
|
51330
|
+
if (!existsSync48(dir)) return /* @__PURE__ */ new Set();
|
|
51208
51331
|
return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
|
|
51209
51332
|
}
|
|
51210
51333
|
function isValidAppStoreSize(w, h) {
|
|
@@ -51314,12 +51437,12 @@ function analyzePlayListing(assets) {
|
|
|
51314
51437
|
return f;
|
|
51315
51438
|
}
|
|
51316
51439
|
function playListingAssets(app, locale = "en-US") {
|
|
51317
|
-
const dir =
|
|
51440
|
+
const dir = join46(storeDir(app), "play", locale, "images");
|
|
51318
51441
|
const read = (names) => {
|
|
51319
51442
|
for (const name of names) {
|
|
51320
|
-
const p =
|
|
51443
|
+
const p = join46(dir, name);
|
|
51321
51444
|
try {
|
|
51322
|
-
if (
|
|
51445
|
+
if (statSync10(p).isFile()) return { name, bytes: readFileSync56(p) };
|
|
51323
51446
|
} catch {
|
|
51324
51447
|
}
|
|
51325
51448
|
}
|
|
@@ -51350,26 +51473,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
51350
51473
|
return f;
|
|
51351
51474
|
}
|
|
51352
51475
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
51353
|
-
const dir =
|
|
51354
|
-
if (!
|
|
51476
|
+
const dir = join46(storeDir(app), "metadata", locale);
|
|
51477
|
+
if (!existsSync48(dir)) return /* @__PURE__ */ new Set();
|
|
51355
51478
|
return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
|
|
51356
51479
|
}
|
|
51357
51480
|
function listScreenshots(app, locale = "en-US") {
|
|
51358
51481
|
const out = [];
|
|
51359
|
-
const flat =
|
|
51360
|
-
if (
|
|
51482
|
+
const flat = join46(storeDir(app), "screenshots", locale);
|
|
51483
|
+
if (existsSync48(flat)) {
|
|
51361
51484
|
for (const png of readdirSync22(flat).filter((n) => n.endsWith(".png"))) {
|
|
51362
|
-
const sz = pngSize(
|
|
51485
|
+
const sz = pngSize(readFileSync56(join46(flat, png)));
|
|
51363
51486
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
51364
51487
|
}
|
|
51365
51488
|
}
|
|
51366
|
-
const legacy =
|
|
51367
|
-
if (
|
|
51489
|
+
const legacy = join46(storeDir(app), "metadata", locale, "screenshots");
|
|
51490
|
+
if (existsSync48(legacy)) {
|
|
51368
51491
|
for (const deviceDir of readdirSync22(legacy)) {
|
|
51369
|
-
const d =
|
|
51370
|
-
if (!
|
|
51492
|
+
const d = join46(legacy, deviceDir);
|
|
51493
|
+
if (!statSync10(d).isDirectory()) continue;
|
|
51371
51494
|
for (const png of readdirSync22(d).filter((n) => n.endsWith(".png"))) {
|
|
51372
|
-
const sz = pngSize(
|
|
51495
|
+
const sz = pngSize(readFileSync56(join46(d, png)));
|
|
51373
51496
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
51374
51497
|
}
|
|
51375
51498
|
}
|
|
@@ -51377,13 +51500,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
51377
51500
|
return out;
|
|
51378
51501
|
}
|
|
51379
51502
|
function placeholderHashes2() {
|
|
51380
|
-
const templateIos =
|
|
51381
|
-
if (!
|
|
51503
|
+
const templateIos = join46(appDir("_template"), "ios");
|
|
51504
|
+
if (!existsSync48(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
51382
51505
|
for (const target of readdirSync22(templateIos)) {
|
|
51383
|
-
const p =
|
|
51506
|
+
const p = join46(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
51384
51507
|
try {
|
|
51385
|
-
if (!
|
|
51386
|
-
return [LEGACY_PLACEHOLDER_SHA2562, createHash23("sha256").update(
|
|
51508
|
+
if (!statSync10(p).isFile()) continue;
|
|
51509
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash23("sha256").update(readFileSync56(p)).digest("hex")];
|
|
51387
51510
|
} catch {
|
|
51388
51511
|
}
|
|
51389
51512
|
}
|
|
@@ -51414,12 +51537,12 @@ async function pixelIssues(bytes2) {
|
|
|
51414
51537
|
}
|
|
51415
51538
|
}
|
|
51416
51539
|
async function appIconState(iosDir) {
|
|
51417
|
-
if (!
|
|
51540
|
+
if (!existsSync48(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
51418
51541
|
for (const target of readdirSync22(iosDir)) {
|
|
51419
|
-
const p =
|
|
51542
|
+
const p = join46(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
51420
51543
|
try {
|
|
51421
|
-
if (!
|
|
51422
|
-
const bytes2 =
|
|
51544
|
+
if (!statSync10(p).isFile()) continue;
|
|
51545
|
+
const bytes2 = readFileSync56(p);
|
|
51423
51546
|
const hash = createHash23("sha256").update(bytes2).digest("hex");
|
|
51424
51547
|
const pixels = await pixelIssues(bytes2);
|
|
51425
51548
|
return {
|
|
@@ -51489,14 +51612,14 @@ __export(credential_profile_exports, {
|
|
|
51489
51612
|
profilePath: () => profilePath,
|
|
51490
51613
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
51491
51614
|
});
|
|
51492
|
-
import { existsSync as
|
|
51615
|
+
import { existsSync as existsSync49, readFileSync as readFileSync57 } from "node:fs";
|
|
51493
51616
|
import { homedir as homedir6 } from "node:os";
|
|
51494
|
-
import { join as
|
|
51617
|
+
import { join as join47 } from "node:path";
|
|
51495
51618
|
function credentialsDir(home = homedir6()) {
|
|
51496
|
-
return
|
|
51619
|
+
return join47(home, ".himalaya", "store-credentials");
|
|
51497
51620
|
}
|
|
51498
51621
|
function profilePath(name, home = homedir6()) {
|
|
51499
|
-
return
|
|
51622
|
+
return join47(credentialsDir(home), `${name}.json`);
|
|
51500
51623
|
}
|
|
51501
51624
|
function parseProfile(text2, label2) {
|
|
51502
51625
|
let doc;
|
|
@@ -51523,8 +51646,8 @@ function resolveStoreCredentials(opts) {
|
|
|
51523
51646
|
const { app, cfg } = opts;
|
|
51524
51647
|
const env = opts.env ?? process.env;
|
|
51525
51648
|
const home = opts.home ?? homedir6();
|
|
51526
|
-
const read = opts.readProfile ?? ((p) =>
|
|
51527
|
-
const exists = opts.profileExists ??
|
|
51649
|
+
const read = opts.readProfile ?? ((p) => readFileSync57(p, "utf8"));
|
|
51650
|
+
const exists = opts.profileExists ?? existsSync49;
|
|
51528
51651
|
const ios = cfg.ios ?? {};
|
|
51529
51652
|
const flagName = opts.profileFlag?.trim();
|
|
51530
51653
|
const named = flagName || ios.credentialProfile?.trim();
|
|
@@ -51598,7 +51721,7 @@ __export(version_exports, {
|
|
|
51598
51721
|
setAndroidVersion: () => setAndroidVersion,
|
|
51599
51722
|
setIosVersion: () => setIosVersion
|
|
51600
51723
|
});
|
|
51601
|
-
import { readFileSync as
|
|
51724
|
+
import { readFileSync as readFileSync58, writeFileSync as writeFileSync19 } from "node:fs";
|
|
51602
51725
|
function readIosVersion(projectYml) {
|
|
51603
51726
|
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
51604
51727
|
const build2 = matchScalar(projectYml, "CFBundleVersion");
|
|
@@ -51656,8 +51779,8 @@ function setAndroidVersion(gradle, v) {
|
|
|
51656
51779
|
function bumpVersion(app, opts) {
|
|
51657
51780
|
const iosPath = iosProjectYml(app);
|
|
51658
51781
|
const gradlePath = androidGradle(app);
|
|
51659
|
-
const iosYml =
|
|
51660
|
-
const gradle =
|
|
51782
|
+
const iosYml = readFileSync58(iosPath, "utf8");
|
|
51783
|
+
const gradle = readFileSync58(gradlePath, "utf8");
|
|
51661
51784
|
const current = readIosVersion(iosYml);
|
|
51662
51785
|
const next = {
|
|
51663
51786
|
marketing: opts.marketing ?? current.marketing,
|
|
@@ -51674,7 +51797,7 @@ var init_version = __esm({
|
|
|
51674
51797
|
});
|
|
51675
51798
|
|
|
51676
51799
|
// ../store-release/register-bundle.ts
|
|
51677
|
-
import { readFileSync as
|
|
51800
|
+
import { readFileSync as readFileSync59 } from "node:fs";
|
|
51678
51801
|
import { createPrivateKey, sign } from "node:crypto";
|
|
51679
51802
|
function b64url2(b) {
|
|
51680
51803
|
return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -51692,7 +51815,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
|
|
|
51692
51815
|
async function registerBundleId(opts) {
|
|
51693
51816
|
const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
51694
51817
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
51695
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
51818
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync59(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
51696
51819
|
const res = await fetch(`${ASC_API}/v1/bundleIds`, {
|
|
51697
51820
|
method: "POST",
|
|
51698
51821
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
@@ -51746,7 +51869,7 @@ __export(asc_status_exports, {
|
|
|
51746
51869
|
ascStatus: () => ascStatus,
|
|
51747
51870
|
buildVerdict: () => buildVerdict
|
|
51748
51871
|
});
|
|
51749
|
-
import { readFileSync as
|
|
51872
|
+
import { readFileSync as readFileSync60 } from "node:fs";
|
|
51750
51873
|
function buildVerdict(builds) {
|
|
51751
51874
|
if (!builds.length) {
|
|
51752
51875
|
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).";
|
|
@@ -51760,7 +51883,7 @@ function buildVerdict(builds) {
|
|
|
51760
51883
|
function client2(creds) {
|
|
51761
51884
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
51762
51885
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
51763
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
51886
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync60(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
51764
51887
|
return async (path) => {
|
|
51765
51888
|
const r = await fetch(`${ASC}${path}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
51766
51889
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
@@ -54850,10 +54973,10 @@ function isFetchableFontUrl(raw) {
|
|
|
54850
54973
|
return true;
|
|
54851
54974
|
}
|
|
54852
54975
|
function resolveAll(hostname) {
|
|
54853
|
-
return new Promise((
|
|
54976
|
+
return new Promise((resolve42, reject) => {
|
|
54854
54977
|
dnsLookup(hostname, { all: true, verbatim: true }, (err, addresses) => {
|
|
54855
54978
|
if (err) reject(err);
|
|
54856
|
-
else
|
|
54979
|
+
else resolve42(addresses);
|
|
54857
54980
|
});
|
|
54858
54981
|
});
|
|
54859
54982
|
}
|
|
@@ -54861,13 +54984,13 @@ function withAbort(start, signal, what) {
|
|
|
54861
54984
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
54862
54985
|
const work = start();
|
|
54863
54986
|
if (!signal) return work;
|
|
54864
|
-
return new Promise((
|
|
54987
|
+
return new Promise((resolve42, reject) => {
|
|
54865
54988
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
54866
54989
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
54867
|
-
work.then(
|
|
54990
|
+
work.then(resolve42, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
54868
54991
|
});
|
|
54869
54992
|
}
|
|
54870
|
-
async function pinAddress(url,
|
|
54993
|
+
async function pinAddress(url, resolve42 = resolveAll, signal) {
|
|
54871
54994
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
54872
54995
|
if (ipv4Octets(host)) {
|
|
54873
54996
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -54877,7 +55000,7 @@ async function pinAddress(url, resolve41 = resolveAll, signal) {
|
|
|
54877
55000
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
54878
55001
|
return { address: host, family: 6 };
|
|
54879
55002
|
}
|
|
54880
|
-
const addresses = await withAbort(() =>
|
|
55003
|
+
const addresses = await withAbort(() => resolve42(host), signal, `${host} lookup`);
|
|
54881
55004
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
54882
55005
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
54883
55006
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -54900,7 +55023,7 @@ function decodedBody(res, hasBody) {
|
|
|
54900
55023
|
return out;
|
|
54901
55024
|
}
|
|
54902
55025
|
function requestOnce(url, pinned, init) {
|
|
54903
|
-
return new Promise((
|
|
55026
|
+
return new Promise((resolve42, reject) => {
|
|
54904
55027
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
54905
55028
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
54906
55029
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -54934,7 +55057,7 @@ function requestOnce(url, pinned, init) {
|
|
|
54934
55057
|
reject(err);
|
|
54935
55058
|
return;
|
|
54936
55059
|
}
|
|
54937
|
-
|
|
55060
|
+
resolve42(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
|
|
54938
55061
|
}
|
|
54939
55062
|
);
|
|
54940
55063
|
req.on("error", reject);
|
|
@@ -55043,7 +55166,7 @@ var init_brand_font = __esm({
|
|
|
55043
55166
|
|
|
55044
55167
|
// src/site-analyze/write-artifacts.ts
|
|
55045
55168
|
import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync20 } from "node:fs";
|
|
55046
|
-
import { join as
|
|
55169
|
+
import { join as join48 } from "node:path";
|
|
55047
55170
|
function attachVeloSources(book, sources, put) {
|
|
55048
55171
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
55049
55172
|
for (const f of book.velo.files) {
|
|
@@ -55198,12 +55321,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
55198
55321
|
}
|
|
55199
55322
|
async function writeBusinessBook(result, opts) {
|
|
55200
55323
|
const out = opts.outDir;
|
|
55201
|
-
mkdirSync23(
|
|
55202
|
-
mkdirSync23(
|
|
55324
|
+
mkdirSync23(join48(out, "evidence/pages"), { recursive: true });
|
|
55325
|
+
mkdirSync23(join48(out, "media/catalog"), { recursive: true });
|
|
55203
55326
|
const files = [];
|
|
55204
55327
|
const put = (rel, body) => {
|
|
55205
|
-
const p =
|
|
55206
|
-
mkdirSync23(
|
|
55328
|
+
const p = join48(out, rel);
|
|
55329
|
+
mkdirSync23(join48(p, ".."), { recursive: true });
|
|
55207
55330
|
writeFileSync20(p, body);
|
|
55208
55331
|
files.push(rel);
|
|
55209
55332
|
};
|
|
@@ -55534,15 +55657,15 @@ var init_home_descriptor = __esm({
|
|
|
55534
55657
|
});
|
|
55535
55658
|
|
|
55536
55659
|
// src/site-analyze/apply.ts
|
|
55537
|
-
import { existsSync as
|
|
55538
|
-
import { dirname as
|
|
55660
|
+
import { existsSync as existsSync50, readFileSync as readFileSync61, writeFileSync as writeFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync24, realpathSync as realpathSync5, statSync as statSync11 } from "node:fs";
|
|
55661
|
+
import { dirname as dirname28, isAbsolute as isAbsolute4, join as join49, resolve as resolve39, sep as sep10 } from "node:path";
|
|
55539
55662
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
55540
55663
|
function unpairedRedirectNote(overlay) {
|
|
55541
55664
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
55542
55665
|
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)`;
|
|
55543
55666
|
}
|
|
55544
55667
|
function posix2(p) {
|
|
55545
|
-
return
|
|
55668
|
+
return resolve39(p).replace(/\\/g, "/");
|
|
55546
55669
|
}
|
|
55547
55670
|
function committedShellProvisioning(path) {
|
|
55548
55671
|
return committedShellFor(posix2(path));
|
|
@@ -55550,8 +55673,8 @@ function committedShellProvisioning(path) {
|
|
|
55550
55673
|
function findRepoRoot(cwd) {
|
|
55551
55674
|
let dir = cwd;
|
|
55552
55675
|
for (let i = 0; i < 8; i++) {
|
|
55553
|
-
if (SHELL_NAMES2.some((name) =>
|
|
55554
|
-
const next =
|
|
55676
|
+
if (SHELL_NAMES2.some((name) => existsSync50(join49(dir, shellAppDir(name), "package.json")))) return dir;
|
|
55677
|
+
const next = dirname28(dir);
|
|
55555
55678
|
if (next === dir) break;
|
|
55556
55679
|
dir = next;
|
|
55557
55680
|
}
|
|
@@ -55576,7 +55699,7 @@ function assertNotCommitted(path, forbidden) {
|
|
|
55576
55699
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
55577
55700
|
);
|
|
55578
55701
|
}
|
|
55579
|
-
if (forbidden &&
|
|
55702
|
+
if (forbidden && resolve39(path) === resolve39(forbidden)) {
|
|
55580
55703
|
const named = committedShellProvisioning(forbidden);
|
|
55581
55704
|
throw new Error(
|
|
55582
55705
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -55618,24 +55741,24 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
55618
55741
|
}
|
|
55619
55742
|
function buildMergedContract(options) {
|
|
55620
55743
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
55621
|
-
const committedPath =
|
|
55622
|
-
if (!
|
|
55744
|
+
const committedPath = join49(appDir2, "provisioning.json");
|
|
55745
|
+
if (!existsSync50(committedPath)) {
|
|
55623
55746
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
55624
55747
|
}
|
|
55625
|
-
const committed = JSON.parse(
|
|
55748
|
+
const committed = JSON.parse(readFileSync61(committedPath, "utf8"));
|
|
55626
55749
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
55627
55750
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
55628
55751
|
const branding = merged.branding ?? {};
|
|
55629
55752
|
const staged = [];
|
|
55630
55753
|
const contained = (root, rel) => {
|
|
55631
|
-
if (
|
|
55632
|
-
const full =
|
|
55633
|
-
return full.startsWith(
|
|
55754
|
+
if (isAbsolute4(rel)) return void 0;
|
|
55755
|
+
const full = resolve39(root, rel);
|
|
55756
|
+
return full.startsWith(resolve39(root) + sep10) ? full : void 0;
|
|
55634
55757
|
};
|
|
55635
55758
|
const stage = (fromRel, toRel) => {
|
|
55636
55759
|
const from = contained(packageDir, fromRel);
|
|
55637
|
-
const to = contained(
|
|
55638
|
-
if (!from || !to || !
|
|
55760
|
+
const to = contained(join49(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
55761
|
+
if (!from || !to || !existsSync50(from)) return void 0;
|
|
55639
55762
|
let real;
|
|
55640
55763
|
let realRoot;
|
|
55641
55764
|
try {
|
|
@@ -55646,8 +55769,8 @@ function buildMergedContract(options) {
|
|
|
55646
55769
|
}
|
|
55647
55770
|
if (!real.startsWith(realRoot + sep10)) return void 0;
|
|
55648
55771
|
try {
|
|
55649
|
-
if (!
|
|
55650
|
-
mkdirSync24(
|
|
55772
|
+
if (!statSync11(real).isFile()) return void 0;
|
|
55773
|
+
mkdirSync24(dirname28(to), { recursive: true });
|
|
55651
55774
|
copyFileSync3(real, to);
|
|
55652
55775
|
} catch {
|
|
55653
55776
|
return void 0;
|
|
@@ -55657,11 +55780,11 @@ function buildMergedContract(options) {
|
|
|
55657
55780
|
};
|
|
55658
55781
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
55659
55782
|
if (icon) branding.appIconPath = icon;
|
|
55660
|
-
const facesPath =
|
|
55661
|
-
if (
|
|
55783
|
+
const facesPath = join49(packageDir, "media/fonts/faces.json");
|
|
55784
|
+
if (existsSync50(facesPath)) {
|
|
55662
55785
|
let faces = [];
|
|
55663
55786
|
try {
|
|
55664
|
-
const parsed = JSON.parse(
|
|
55787
|
+
const parsed = JSON.parse(readFileSync61(facesPath, "utf8"));
|
|
55665
55788
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
55666
55789
|
} catch {
|
|
55667
55790
|
faces = [];
|
|
@@ -55682,20 +55805,20 @@ function buildMergedContract(options) {
|
|
|
55682
55805
|
merged.branding = branding;
|
|
55683
55806
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
55684
55807
|
`;
|
|
55685
|
-
const path =
|
|
55808
|
+
const path = join49(packageDir, "provisioning.contract.json");
|
|
55686
55809
|
writeFileSync21(path, body);
|
|
55687
|
-
const localPath =
|
|
55688
|
-
mkdirSync24(
|
|
55810
|
+
const localPath = join49(appDir2, LOCAL_CONTRACT_REL);
|
|
55811
|
+
mkdirSync24(dirname28(localPath), { recursive: true });
|
|
55689
55812
|
writeFileSync21(localPath, body);
|
|
55690
55813
|
staged.push(localPath);
|
|
55691
55814
|
return { path, staged };
|
|
55692
55815
|
}
|
|
55693
55816
|
async function applyOverlays(input) {
|
|
55694
|
-
const cwd =
|
|
55817
|
+
const cwd = resolve39(input.cwd);
|
|
55695
55818
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
55696
55819
|
assertKnownShell(shell);
|
|
55697
|
-
const overlay = JSON.parse(
|
|
55698
|
-
const tokens = JSON.parse(
|
|
55820
|
+
const overlay = JSON.parse(readFileSync61(input.overlayPath, "utf8"));
|
|
55821
|
+
const tokens = JSON.parse(readFileSync61(input.tokensPath, "utf8"));
|
|
55699
55822
|
const wrote = [];
|
|
55700
55823
|
const notes = [];
|
|
55701
55824
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -55705,8 +55828,8 @@ async function applyOverlays(input) {
|
|
|
55705
55828
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
55706
55829
|
);
|
|
55707
55830
|
}
|
|
55708
|
-
const appDir2 =
|
|
55709
|
-
const packageDir =
|
|
55831
|
+
const appDir2 = join49(repoRoot2, shellAppDir(shell));
|
|
55832
|
+
const packageDir = dirname28(resolve39(input.overlayPath));
|
|
55710
55833
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
55711
55834
|
wrote.push(...staged);
|
|
55712
55835
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -55727,10 +55850,10 @@ async function applyOverlays(input) {
|
|
|
55727
55850
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
55728
55851
|
};
|
|
55729
55852
|
}
|
|
55730
|
-
const pkgProv =
|
|
55853
|
+
const pkgProv = join49(cwd, "provisioning.json");
|
|
55731
55854
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
55732
|
-
if (
|
|
55733
|
-
const cur = JSON.parse(
|
|
55855
|
+
if (existsSync50(pkgProv)) {
|
|
55856
|
+
const cur = JSON.parse(readFileSync61(pkgProv, "utf8"));
|
|
55734
55857
|
const merged = deepMerge3(cur, overlay);
|
|
55735
55858
|
writeFileSync21(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
55736
55859
|
wrote.push(pkgProv);
|
|
@@ -55738,17 +55861,17 @@ async function applyOverlays(input) {
|
|
|
55738
55861
|
writeFileSync21(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
55739
55862
|
wrote.push(pkgProv);
|
|
55740
55863
|
}
|
|
55741
|
-
const pkgTokens =
|
|
55742
|
-
if (
|
|
55743
|
-
const cur = JSON.parse(
|
|
55864
|
+
const pkgTokens = join49(cwd, "tokens.json");
|
|
55865
|
+
if (existsSync50(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
55866
|
+
const cur = JSON.parse(readFileSync61(pkgTokens, "utf8"));
|
|
55744
55867
|
const merged = deepMerge3(cur, tokens);
|
|
55745
55868
|
writeFileSync21(pkgTokens, JSON.stringify(merged, null, 2) + "\n");
|
|
55746
55869
|
wrote.push(pkgTokens);
|
|
55747
55870
|
}
|
|
55748
55871
|
const homeAction = homeRefreshActionId(shell);
|
|
55749
|
-
const homeSrc =
|
|
55750
|
-
if (homeAction &&
|
|
55751
|
-
const prev =
|
|
55872
|
+
const homeSrc = join49(cwd, "dev/index.ts");
|
|
55873
|
+
if (homeAction && existsSync50(homeSrc)) {
|
|
55874
|
+
const prev = readFileSync61(homeSrc, "utf8");
|
|
55752
55875
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
55753
55876
|
let next = patched.src;
|
|
55754
55877
|
if (!patched.foreign && overlay.installedVerticals?.length) {
|
|
@@ -55768,13 +55891,13 @@ async function applyOverlays(input) {
|
|
|
55768
55891
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
55769
55892
|
}
|
|
55770
55893
|
}
|
|
55771
|
-
if (!input.iconPath || !
|
|
55772
|
-
const book = input.iconPath ?
|
|
55894
|
+
if (!input.iconPath || !existsSync50(input.iconPath)) {
|
|
55895
|
+
const book = input.iconPath ? dirname28(dirname28(resolve39(input.iconPath))) : void 0;
|
|
55773
55896
|
notes.push(
|
|
55774
55897
|
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"
|
|
55775
55898
|
);
|
|
55776
55899
|
}
|
|
55777
|
-
if (input.iconPath &&
|
|
55900
|
+
if (input.iconPath && existsSync50(input.iconPath)) {
|
|
55778
55901
|
try {
|
|
55779
55902
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
55780
55903
|
wrote.push(...installed.wrote);
|
|
@@ -56908,13 +57031,13 @@ __export(cli_exports, {
|
|
|
56908
57031
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
56909
57032
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
56910
57033
|
});
|
|
56911
|
-
import { readFileSync as
|
|
56912
|
-
import { resolve as
|
|
57034
|
+
import { readFileSync as readFileSync62 } from "node:fs";
|
|
57035
|
+
import { resolve as resolve40 } from "node:path";
|
|
56913
57036
|
async function runSiteAnalyze(opts) {
|
|
56914
57037
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
56915
57038
|
const assetFetch = opts.fetchImpl ?? pinnedFetch2;
|
|
56916
57039
|
const cwd = opts.cwd ?? process.cwd();
|
|
56917
|
-
const outDir =
|
|
57040
|
+
const outDir = resolve40(cwd, opts.outDir ?? ".himi/business-book");
|
|
56918
57041
|
let ownerAuth;
|
|
56919
57042
|
let msid;
|
|
56920
57043
|
try {
|
|
@@ -56951,9 +57074,9 @@ async function runSiteAnalyze(opts) {
|
|
|
56951
57074
|
if (opts.apply) {
|
|
56952
57075
|
applied = await applyOverlays({
|
|
56953
57076
|
cwd,
|
|
56954
|
-
overlayPath:
|
|
56955
|
-
tokensPath:
|
|
56956
|
-
iconPath:
|
|
57077
|
+
overlayPath: resolve40(outDir, "provisioning.overlay.json"),
|
|
57078
|
+
tokensPath: resolve40(outDir, "tokens.overlay.json"),
|
|
57079
|
+
iconPath: resolve40(outDir, "media/icon.png"),
|
|
56957
57080
|
shell: opts.shell
|
|
56958
57081
|
});
|
|
56959
57082
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -56989,8 +57112,8 @@ async function runSiteFunctionCli(opts) {
|
|
|
56989
57112
|
const token = opts.token ?? await siteToken(msid);
|
|
56990
57113
|
let source;
|
|
56991
57114
|
if (opts.sourcePath) {
|
|
56992
|
-
const p =
|
|
56993
|
-
source =
|
|
57115
|
+
const p = resolve40(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
57116
|
+
source = readFileSync62(p, "utf8");
|
|
56994
57117
|
}
|
|
56995
57118
|
let body;
|
|
56996
57119
|
if (opts.bodyRaw != null) {
|
|
@@ -57041,7 +57164,7 @@ async function accountToken2(spawnImpl = spawn4) {
|
|
|
57041
57164
|
cached2 = fromEnv;
|
|
57042
57165
|
return fromEnv;
|
|
57043
57166
|
}
|
|
57044
|
-
const token = await new Promise((
|
|
57167
|
+
const token = await new Promise((resolve42, reject) => {
|
|
57045
57168
|
let child;
|
|
57046
57169
|
try {
|
|
57047
57170
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -57070,7 +57193,7 @@ async function accountToken2(spawnImpl = spawn4) {
|
|
|
57070
57193
|
const scan = (d) => {
|
|
57071
57194
|
out += String(d);
|
|
57072
57195
|
const m = out.match(TOKEN_RE2);
|
|
57073
|
-
if (m) done(() =>
|
|
57196
|
+
if (m) done(() => resolve42(m[0]));
|
|
57074
57197
|
};
|
|
57075
57198
|
child.stdout?.on("data", scan);
|
|
57076
57199
|
child.stderr?.on("data", scan);
|
|
@@ -57247,7 +57370,7 @@ __export(site_create_exports, {
|
|
|
57247
57370
|
runSiteList: () => runSiteList,
|
|
57248
57371
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
57249
57372
|
});
|
|
57250
|
-
import { existsSync as
|
|
57373
|
+
import { existsSync as existsSync51, readFileSync as readFileSync63, writeFileSync as writeFileSync22 } from "node:fs";
|
|
57251
57374
|
import { resolve as resolvePath2 } from "node:path";
|
|
57252
57375
|
function oauthClientName(projectName) {
|
|
57253
57376
|
return `${projectName} client`;
|
|
@@ -57396,7 +57519,7 @@ async function runSiteCreate(opts) {
|
|
|
57396
57519
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
57397
57520
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
57398
57521
|
}
|
|
57399
|
-
function writeProvisioningBinding(target, binding2, fs = { existsSync:
|
|
57522
|
+
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync51, readFileSync: readFileSync63, writeFileSync: writeFileSync22 }) {
|
|
57400
57523
|
const msid = binding2.siteId;
|
|
57401
57524
|
const path = resolvePath2(target);
|
|
57402
57525
|
const committed = committedShellProvisioning(path);
|
|
@@ -57730,11 +57853,11 @@ var init_site_oauth_client = __esm({
|
|
|
57730
57853
|
});
|
|
57731
57854
|
|
|
57732
57855
|
// src/cli.ts
|
|
57733
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as
|
|
57856
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync64, mkdirSync as mkdirSync25, writeFileSync as writeFileSync23, existsSync as existsSync52, rmSync as rmSync9, readdirSync as readdirSync23, statSync as statSync12, lstatSync as lstatSync5 } from "node:fs";
|
|
57734
57857
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
57735
57858
|
import { createHash as createHash24 } from "node:crypto";
|
|
57736
57859
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
57737
|
-
import { join as
|
|
57860
|
+
import { join as join50, resolve as resolve41, basename as basename9, dirname as dirname29 } from "node:path";
|
|
57738
57861
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
57739
57862
|
|
|
57740
57863
|
// ../serve-cli/src/client.ts
|
|
@@ -59250,7 +59373,7 @@ async function browserLogin(opts) {
|
|
|
59250
59373
|
const log = opts.log ?? (() => {
|
|
59251
59374
|
});
|
|
59252
59375
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
59253
|
-
return await new Promise((
|
|
59376
|
+
return await new Promise((resolve42, reject) => {
|
|
59254
59377
|
let settled = false;
|
|
59255
59378
|
let loginUrl = "";
|
|
59256
59379
|
const server = createServer();
|
|
@@ -59314,7 +59437,7 @@ async function browserLogin(opts) {
|
|
|
59314
59437
|
return;
|
|
59315
59438
|
}
|
|
59316
59439
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
59317
|
-
finish2(() =>
|
|
59440
|
+
finish2(() => resolve42({ token, loginUrl }));
|
|
59318
59441
|
});
|
|
59319
59442
|
});
|
|
59320
59443
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -60724,17 +60847,18 @@ init_crawl_layers();
|
|
|
60724
60847
|
// src/ux-audit.ts
|
|
60725
60848
|
init_wix_gateway_rules();
|
|
60726
60849
|
init_mobile_ux_contract();
|
|
60727
|
-
|
|
60728
|
-
|
|
60729
|
-
|
|
60850
|
+
init_ux_evidence();
|
|
60851
|
+
init_ux_evidence();
|
|
60852
|
+
import { existsSync as existsSync22, readFileSync as readFileSync24, readdirSync as readdirSync11 } from "node:fs";
|
|
60853
|
+
import { join as join26, relative as relative4, resolve as resolve16 } from "node:path";
|
|
60730
60854
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
|
|
60731
60855
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
|
|
60732
60856
|
function issue(issues, strict, code, message, path) {
|
|
60733
60857
|
issues.push({ code, message, ...path ? { path } : {}, severity: strict ? "error" : "warning" });
|
|
60734
60858
|
}
|
|
60735
|
-
function
|
|
60859
|
+
function readText2(path) {
|
|
60736
60860
|
try {
|
|
60737
|
-
return
|
|
60861
|
+
return existsSync22(path) ? readFileSync24(path, "utf8") : null;
|
|
60738
60862
|
} catch {
|
|
60739
60863
|
return null;
|
|
60740
60864
|
}
|
|
@@ -60743,30 +60867,17 @@ function walkSource(dir, root = dir) {
|
|
|
60743
60867
|
const found = [];
|
|
60744
60868
|
for (const entry of readdirSync11(dir, { withFileTypes: true })) {
|
|
60745
60869
|
if (entry.isDirectory()) {
|
|
60746
|
-
if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(
|
|
60870
|
+
if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(join26(dir, entry.name), root));
|
|
60747
60871
|
continue;
|
|
60748
60872
|
}
|
|
60749
60873
|
const ext = entry.name.slice(entry.name.lastIndexOf("."));
|
|
60750
60874
|
if (!SOURCE_EXTENSIONS.has(ext)) continue;
|
|
60751
|
-
const absolute =
|
|
60752
|
-
const text2 =
|
|
60753
|
-
if (text2 !== null) found.push({ path:
|
|
60875
|
+
const absolute = join26(dir, entry.name);
|
|
60876
|
+
const text2 = readText2(absolute);
|
|
60877
|
+
if (text2 !== null) found.push({ path: relative4(root, absolute), text: text2 });
|
|
60754
60878
|
}
|
|
60755
60879
|
return found;
|
|
60756
60880
|
}
|
|
60757
|
-
function parseEvidence(path) {
|
|
60758
|
-
const raw = readText(path);
|
|
60759
|
-
if (raw === null) return { evidence: null };
|
|
60760
|
-
try {
|
|
60761
|
-
const value = JSON.parse(raw);
|
|
60762
|
-
if (value.version !== 1 || !value.platforms || typeof value.platforms !== "object") {
|
|
60763
|
-
return { evidence: null, error: "must be an object with version: 1 and a platforms object" };
|
|
60764
|
-
}
|
|
60765
|
-
return { evidence: value };
|
|
60766
|
-
} catch (error) {
|
|
60767
|
-
return { evidence: null, error: `is not valid JSON: ${error.message}` };
|
|
60768
|
-
}
|
|
60769
|
-
}
|
|
60770
60881
|
function blankMatrixRows(text2) {
|
|
60771
60882
|
const acceptance = mobileUxSection(mobileUxDocumentBody(text2), "Implementation acceptance") ?? "";
|
|
60772
60883
|
return /\|\s*(?:Ready|Empty|Add\s*\/\s*edit|Saved\s*\/\s*completed|Error\s*\/\s*recovery)\s*\|\s*\|\s*\|\s*\|\s*\|/i.test(acceptance);
|
|
@@ -60776,40 +60887,41 @@ function usesAppNetwork(source) {
|
|
|
60776
60887
|
return source.some(({ text: text2 }) => /\bwixApi\b|(?:from|import)\s*["']@(?:himalaya|wix\/himalaya)\/wix-[^"']+["']/.test(code(text2)));
|
|
60777
60888
|
}
|
|
60778
60889
|
function auditUx(content, strict = false) {
|
|
60779
|
-
const dir =
|
|
60890
|
+
const dir = resolve16(content);
|
|
60780
60891
|
const issues = [];
|
|
60781
|
-
const evidencePath =
|
|
60782
|
-
const
|
|
60783
|
-
const
|
|
60892
|
+
const evidencePath = join26(dir, UX_EVIDENCE_PATH);
|
|
60893
|
+
const parsed = parseEvidence(evidencePath);
|
|
60894
|
+
const renderedWidths = renderEvidenceEntries(parsed.evidence).map((entry) => entry.width);
|
|
60895
|
+
const spec = readText2(join26(dir, "SPEC.md"));
|
|
60896
|
+
const mobile = readText2(join26(dir, "MOBILE-UX.md"));
|
|
60784
60897
|
if (!spec) issue(issues, strict, "missing-spec", "SPEC.md is missing; define the customer task before calling this UX-ready.", "SPEC.md");
|
|
60785
60898
|
if (!mobile) {
|
|
60786
60899
|
issue(issues, strict, "missing-mobile-ux", "MOBILE-UX.md is missing; add the mobile state and platform contract.", "MOBILE-UX.md");
|
|
60787
60900
|
} else {
|
|
60788
|
-
for (const finding of mobileUxMarkerFindings(mobile)) issue(issues, strict, finding.code, finding.message, "MOBILE-UX.md");
|
|
60901
|
+
for (const finding of mobileUxMarkerFindings(mobile, renderedWidths)) issue(issues, strict, finding.code, finding.message, "MOBILE-UX.md");
|
|
60789
60902
|
if (blankMatrixRows(mobile)) issue(issues, strict, "blank-acceptance-matrix", "The seeded acceptance rows are still blank; replace them with this app's flows and visible results.", "MOBILE-UX.md");
|
|
60790
60903
|
}
|
|
60791
|
-
const parsed = parseEvidence(evidencePath);
|
|
60792
60904
|
if (parsed.error) {
|
|
60793
|
-
issues.push({ code: "invalid-native-evidence", message: `${
|
|
60905
|
+
issues.push({ code: "invalid-native-evidence", message: `${UX_EVIDENCE_PATH} ${parsed.error}.`, path: UX_EVIDENCE_PATH, severity: "error" });
|
|
60794
60906
|
}
|
|
60795
60907
|
for (const platform of ["ios", "android"]) {
|
|
60796
60908
|
const record2 = parsed.evidence?.platforms[platform];
|
|
60797
60909
|
if (!record2) {
|
|
60798
|
-
issue(issues, strict, `missing-${platform}-audit`, `No ${platform} native audit is recorded. Use \`himi ux record --platform ${platform} \u2026\` after driving the installed app.`,
|
|
60910
|
+
issue(issues, strict, `missing-${platform}-audit`, `No ${platform} native audit is recorded. Use \`himi ux record --platform ${platform} \u2026\` after driving the installed app.`, UX_EVIDENCE_PATH);
|
|
60799
60911
|
continue;
|
|
60800
60912
|
}
|
|
60801
60913
|
if (!["passed", "failed", "unavailable"].includes(record2.status)) {
|
|
60802
|
-
issues.push({ code: `invalid-${platform}-status`, message: `${platform} audit has an invalid status.`, path:
|
|
60914
|
+
issues.push({ code: `invalid-${platform}-status`, message: `${platform} audit has an invalid status.`, path: UX_EVIDENCE_PATH, severity: "error" });
|
|
60803
60915
|
} else if (record2.status === "failed") {
|
|
60804
|
-
issues.push({ code: `${platform}-audit-failed`, message: `${platform} native audit is recorded as failed; fix it or record a justified unavailable platform.`, path:
|
|
60916
|
+
issues.push({ code: `${platform}-audit-failed`, message: `${platform} native audit is recorded as failed; fix it or record a justified unavailable platform.`, path: UX_EVIDENCE_PATH, severity: "error" });
|
|
60805
60917
|
}
|
|
60806
60918
|
const malformedChecks = record2.checks !== void 0 && !Array.isArray(record2.checks);
|
|
60807
60919
|
if (malformedChecks || record2.status !== "unavailable" && (record2.checks ?? []).length === 0) {
|
|
60808
60920
|
const message = malformedChecks ? `${platform} audit has a malformed checks list; it must be an array.` : `${platform} audit needs the checks that were driven.`;
|
|
60809
|
-
issues.push({ code: `missing-${platform}-checks`, message, path:
|
|
60921
|
+
issues.push({ code: `missing-${platform}-checks`, message, path: UX_EVIDENCE_PATH, severity: "error" });
|
|
60810
60922
|
}
|
|
60811
60923
|
if (record2.status === "unavailable" && !record2.reason?.trim()) {
|
|
60812
|
-
issues.push({ code: `missing-${platform}-reason`, message: `${platform} is unavailable but has no reason.`, path:
|
|
60924
|
+
issues.push({ code: `missing-${platform}-reason`, message: `${platform} is unavailable but has no reason.`, path: UX_EVIDENCE_PATH, severity: "error" });
|
|
60813
60925
|
}
|
|
60814
60926
|
}
|
|
60815
60927
|
const source = walkSource(dir);
|
|
@@ -60821,12 +60933,12 @@ function auditUx(content, strict = false) {
|
|
|
60821
60933
|
const preview = matches(previewControl);
|
|
60822
60934
|
if (preview) issue(issues, strict, "possible-preview-control", "Possible customer-visible test/demo state control found. Keep scenario controls out of shipping UI, or document a capability-limited fallback.", preview.path);
|
|
60823
60935
|
if (usesAppNetwork(source)) {
|
|
60824
|
-
const mocksPath =
|
|
60825
|
-
if (!
|
|
60936
|
+
const mocksPath = join26(dir, "dev", "net-mocks.json");
|
|
60937
|
+
if (!existsSync22(mocksPath)) {
|
|
60826
60938
|
issue(issues, strict, "missing-app-mocks", "This package uses a Wix/network client but has no app-specific dev/net-mocks.json. Add fixtures for dynamic, entitlement, or recovery flows.", "dev/net-mocks.json");
|
|
60827
60939
|
} else {
|
|
60828
60940
|
try {
|
|
60829
|
-
const parsed2 = JSON.parse(
|
|
60941
|
+
const parsed2 = JSON.parse(readFileSync24(mocksPath, "utf8"));
|
|
60830
60942
|
const errors2 = Array.isArray(parsed2?.rules) ? wixMockRuleErrors(parsed2.rules) : ['missing top-level "rules" array'];
|
|
60831
60943
|
if (errors2.length) issue(issues, strict, "invalid-app-mocks", `dev/net-mocks.json cannot serve the flows it claims to mock: ${errors2.join("; ")}`, "dev/net-mocks.json");
|
|
60832
60944
|
} catch (error) {
|
|
@@ -60836,49 +60948,33 @@ function auditUx(content, strict = false) {
|
|
|
60836
60948
|
}
|
|
60837
60949
|
const errors = issues.filter((item) => item.severity === "error");
|
|
60838
60950
|
const warnings = issues.filter((item) => item.severity === "warning");
|
|
60839
|
-
return { ok: errors.length === 0, strict, content: dir, evidencePath:
|
|
60840
|
-
}
|
|
60841
|
-
function recordNativeAudit(content, platform, status, checks, reason) {
|
|
60842
|
-
const normalizedChecks = status === "unavailable" ? [] : [...new Set(checks.map((check) => check.trim()).filter(Boolean))];
|
|
60843
|
-
if (status !== "unavailable" && !normalizedChecks.length) {
|
|
60844
|
-
throw new Error("--checks needs at least one comma-separated check (for example: back,keyboard,voiceover)");
|
|
60845
|
-
}
|
|
60846
|
-
if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
|
|
60847
|
-
const dir = resolve15(content);
|
|
60848
|
-
const path = join25(dir, EVIDENCE_RELATIVE_PATH);
|
|
60849
|
-
const parsed = parseEvidence(path);
|
|
60850
|
-
if (parsed.error) throw new Error(`${EVIDENCE_RELATIVE_PATH} ${parsed.error}`);
|
|
60851
|
-
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
60852
|
-
evidence.platforms[platform] = { status, checks: normalizedChecks, ...reason?.trim() ? { reason: reason.trim() } : {}, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
60853
|
-
mkdirSync10(join25(dir, ".himi"), { recursive: true });
|
|
60854
|
-
writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
|
|
60855
|
-
return evidence;
|
|
60951
|
+
return { ok: errors.length === 0, strict, content: dir, evidencePath: UX_EVIDENCE_PATH, errors, warnings, counts: { errors: errors.length, warnings: warnings.length } };
|
|
60856
60952
|
}
|
|
60857
60953
|
|
|
60858
60954
|
// src/guides.ts
|
|
60859
60955
|
init_mobile_ux_contract();
|
|
60860
|
-
import { readFileSync as
|
|
60956
|
+
import { readFileSync as readFileSync25, existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, copyFileSync as copyFileSync2 } from "node:fs";
|
|
60861
60957
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
60862
|
-
import { dirname as
|
|
60863
|
-
var GUIDES_DIR =
|
|
60958
|
+
import { dirname as dirname16, join as join27, resolve as resolve17 } from "node:path";
|
|
60959
|
+
var GUIDES_DIR = resolve17(dirname16(fileURLToPath10(import.meta.url)), "../guides");
|
|
60864
60960
|
function guidesAvailable() {
|
|
60865
|
-
return
|
|
60961
|
+
return existsSync23(join27(GUIDES_DIR, "index.json"));
|
|
60866
60962
|
}
|
|
60867
60963
|
function loadIndex() {
|
|
60868
|
-
return JSON.parse(
|
|
60964
|
+
return JSON.parse(readFileSync25(join27(GUIDES_DIR, "index.json"), "utf8"));
|
|
60869
60965
|
}
|
|
60870
60966
|
function readGuide(id) {
|
|
60871
60967
|
const meta = loadIndex().guides.find((g) => g.id === id);
|
|
60872
60968
|
if (!meta) return null;
|
|
60873
|
-
return
|
|
60969
|
+
return readFileSync25(join27(GUIDES_DIR, meta.file), "utf8");
|
|
60874
60970
|
}
|
|
60875
60971
|
function loadComponentReference() {
|
|
60876
60972
|
const idx = loadIndex();
|
|
60877
|
-
return JSON.parse(
|
|
60973
|
+
return JSON.parse(readFileSync25(join27(GUIDES_DIR, idx.componentReferenceFile), "utf8"));
|
|
60878
60974
|
}
|
|
60879
60975
|
function loadSdkReference() {
|
|
60880
60976
|
const idx = loadIndex();
|
|
60881
|
-
return JSON.parse(
|
|
60977
|
+
return JSON.parse(readFileSync25(join27(GUIDES_DIR, idx.sdkReferenceFile), "utf8"));
|
|
60882
60978
|
}
|
|
60883
60979
|
function buildAgentPrimer() {
|
|
60884
60980
|
const idx = loadIndex();
|
|
@@ -60987,19 +61083,19 @@ function writeAgentContext(targetDir) {
|
|
|
60987
61083
|
const idx = loadIndex();
|
|
60988
61084
|
const files = [];
|
|
60989
61085
|
const write2 = (rel, body) => {
|
|
60990
|
-
const p =
|
|
60991
|
-
mkdirSync11(
|
|
61086
|
+
const p = join27(targetDir, rel);
|
|
61087
|
+
mkdirSync11(dirname16(p), { recursive: true });
|
|
60992
61088
|
writeFileSync10(p, body);
|
|
60993
61089
|
files.push(rel);
|
|
60994
61090
|
};
|
|
60995
61091
|
const copy = (srcRel, destRel) => {
|
|
60996
|
-
const p =
|
|
60997
|
-
mkdirSync11(
|
|
60998
|
-
copyFileSync2(
|
|
61092
|
+
const p = join27(targetDir, destRel);
|
|
61093
|
+
mkdirSync11(dirname16(p), { recursive: true });
|
|
61094
|
+
copyFileSync2(join27(GUIDES_DIR, srcRel), p);
|
|
60999
61095
|
files.push(destRel);
|
|
61000
61096
|
};
|
|
61001
61097
|
const writeIfMissing = (rel, body) => {
|
|
61002
|
-
if (
|
|
61098
|
+
if (existsSync23(join27(targetDir, rel))) return;
|
|
61003
61099
|
write2(rel, body);
|
|
61004
61100
|
};
|
|
61005
61101
|
write2("HIMALAYA.md", buildAgentPrimer());
|
|
@@ -61060,8 +61156,8 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
61060
61156
|
var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
61061
61157
|
function embeddedTemplateCatalog() {
|
|
61062
61158
|
return availableTemplates().map((name) => {
|
|
61063
|
-
const path =
|
|
61064
|
-
const meta = JSON.parse(
|
|
61159
|
+
const path = join50(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
61160
|
+
const meta = JSON.parse(readFileSync64(path, "utf8"));
|
|
61065
61161
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
61066
61162
|
throw new Error(`${path} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
61067
61163
|
}
|
|
@@ -61564,7 +61660,7 @@ var COMMANDS = [
|
|
|
61564
61660
|
];
|
|
61565
61661
|
function cliVersion() {
|
|
61566
61662
|
try {
|
|
61567
|
-
return JSON.parse(
|
|
61663
|
+
return JSON.parse(readFileSync64(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
61568
61664
|
} catch {
|
|
61569
61665
|
return "unknown";
|
|
61570
61666
|
}
|
|
@@ -61580,18 +61676,18 @@ function compareVersions2(a, b) {
|
|
|
61580
61676
|
}
|
|
61581
61677
|
function packageVersion(path) {
|
|
61582
61678
|
try {
|
|
61583
|
-
const version = JSON.parse(
|
|
61679
|
+
const version = JSON.parse(readFileSync64(path, "utf8")).version;
|
|
61584
61680
|
return typeof version === "string" && version ? version : void 0;
|
|
61585
61681
|
} catch {
|
|
61586
61682
|
return void 0;
|
|
61587
61683
|
}
|
|
61588
61684
|
}
|
|
61589
61685
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
61590
|
-
let dir =
|
|
61686
|
+
let dir = resolve41(fromDir);
|
|
61591
61687
|
for (; ; ) {
|
|
61592
|
-
const version = packageVersion(
|
|
61688
|
+
const version = packageVersion(join50(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
61593
61689
|
if (version) return { version, source: "local" };
|
|
61594
|
-
const parent =
|
|
61690
|
+
const parent = dirname29(dir);
|
|
61595
61691
|
if (parent === dir) break;
|
|
61596
61692
|
dir = parent;
|
|
61597
61693
|
}
|
|
@@ -61599,7 +61695,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
61599
61695
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
61600
61696
|
try {
|
|
61601
61697
|
const root = execFileSync6("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
61602
|
-
const version = root ? packageVersion(
|
|
61698
|
+
const version = root ? packageVersion(join50(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
61603
61699
|
return version ? { version, source: "global" } : {};
|
|
61604
61700
|
} catch {
|
|
61605
61701
|
return {};
|
|
@@ -62013,7 +62109,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
62013
62109
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
62014
62110
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
62015
62111
|
const iosYmlPath = iosProjectYml2(app);
|
|
62016
|
-
const iosYml =
|
|
62112
|
+
const iosYml = existsSync52(iosYmlPath) ? readFileSync64(iosYmlPath, "utf8") : "";
|
|
62017
62113
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
62018
62114
|
if (!optedIn) {
|
|
62019
62115
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -62027,19 +62123,19 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
62027
62123
|
}
|
|
62028
62124
|
function readConfigSource(dir) {
|
|
62029
62125
|
try {
|
|
62030
|
-
return
|
|
62126
|
+
return readFileSync64(join50(dir, "config.ts"), "utf8");
|
|
62031
62127
|
} catch {
|
|
62032
62128
|
return null;
|
|
62033
62129
|
}
|
|
62034
62130
|
}
|
|
62035
62131
|
function writePngFile(path, base64) {
|
|
62036
|
-
mkdirSync25(
|
|
62132
|
+
mkdirSync25(dirname29(path), { recursive: true });
|
|
62037
62133
|
writeFileSync23(path, Buffer.from(base64, "base64"));
|
|
62038
62134
|
return path;
|
|
62039
62135
|
}
|
|
62040
62136
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
62041
|
-
const dir =
|
|
62042
|
-
if (
|
|
62137
|
+
const dir = resolve41(parentDir, name);
|
|
62138
|
+
if (existsSync52(join50(dir, "himalaya.content.json"))) {
|
|
62043
62139
|
throw new Error(`content package already exists at ${dir}`);
|
|
62044
62140
|
}
|
|
62045
62141
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -62051,7 +62147,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
62051
62147
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
62052
62148
|
}
|
|
62053
62149
|
function contentDir(flags) {
|
|
62054
|
-
return
|
|
62150
|
+
return resolve41(str5(flags.content) ?? process.cwd());
|
|
62055
62151
|
}
|
|
62056
62152
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
62057
62153
|
const text2 = {};
|
|
@@ -62082,8 +62178,8 @@ function symlinkDestinationIssue(dest) {
|
|
|
62082
62178
|
function restoreDestinationIssue(dest, force) {
|
|
62083
62179
|
const link = symlinkDestinationIssue(dest);
|
|
62084
62180
|
if (link) return link;
|
|
62085
|
-
if (!
|
|
62086
|
-
if (!
|
|
62181
|
+
if (!existsSync52(dest)) return null;
|
|
62182
|
+
if (!statSync12(dest).isDirectory()) {
|
|
62087
62183
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
62088
62184
|
}
|
|
62089
62185
|
if (readdirSync23(dest).length > 0 && !force) {
|
|
@@ -62095,10 +62191,10 @@ function restoreDestinationIssue(dest, force) {
|
|
|
62095
62191
|
return null;
|
|
62096
62192
|
}
|
|
62097
62193
|
function isHimalayaMonorepoCheckout(start) {
|
|
62098
|
-
let dir =
|
|
62194
|
+
let dir = resolve41(start);
|
|
62099
62195
|
for (; ; ) {
|
|
62100
|
-
if (
|
|
62101
|
-
const parent =
|
|
62196
|
+
if (existsSync52(join50(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync52(join50(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
62197
|
+
const parent = dirname29(dir);
|
|
62102
62198
|
if (parent === dir) return false;
|
|
62103
62199
|
dir = parent;
|
|
62104
62200
|
}
|
|
@@ -62128,8 +62224,8 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
62128
62224
|
const forBuild = Object.fromEntries(
|
|
62129
62225
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
62130
62226
|
);
|
|
62131
|
-
const repoRoot2 =
|
|
62132
|
-
const dest =
|
|
62227
|
+
const repoRoot2 = resolve41(fileURLToPath21(new URL("../../..", import.meta.url)));
|
|
62228
|
+
const dest = join50(repoRoot2, "node_modules", ".cache", "himi-template-preview", slug);
|
|
62133
62229
|
rmSync9(dest, { recursive: true, force: true });
|
|
62134
62230
|
mkdirSync25(dest, { recursive: true });
|
|
62135
62231
|
materializeSource(forBuild, displayName, dest, slug);
|
|
@@ -62137,8 +62233,8 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
62137
62233
|
}
|
|
62138
62234
|
async function appId(dir) {
|
|
62139
62235
|
try {
|
|
62140
|
-
const { readFileSync:
|
|
62141
|
-
const m = JSON.parse(
|
|
62236
|
+
const { readFileSync: readFileSync65 } = await import("node:fs");
|
|
62237
|
+
const m = JSON.parse(readFileSync65(join50(dir, "himalaya.content.json"), "utf8"));
|
|
62142
62238
|
if (m.name) return m.name;
|
|
62143
62239
|
} catch {
|
|
62144
62240
|
}
|
|
@@ -62146,8 +62242,8 @@ async function appId(dir) {
|
|
|
62146
62242
|
}
|
|
62147
62243
|
async function contentVisibility(dir) {
|
|
62148
62244
|
try {
|
|
62149
|
-
const { readFileSync:
|
|
62150
|
-
const m = JSON.parse(
|
|
62245
|
+
const { readFileSync: readFileSync65 } = await import("node:fs");
|
|
62246
|
+
const m = JSON.parse(readFileSync65(join50(dir, "himalaya.content.json"), "utf8"));
|
|
62151
62247
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
62152
62248
|
} catch {
|
|
62153
62249
|
}
|
|
@@ -62348,7 +62444,7 @@ Seed your coding agent with \`himi agent-init\`. Portal: ${idx.portalUrl}`);
|
|
|
62348
62444
|
return 0;
|
|
62349
62445
|
}
|
|
62350
62446
|
case "agent-init": {
|
|
62351
|
-
const dir =
|
|
62447
|
+
const dir = resolve41(str5(flags.dir) ?? process.cwd());
|
|
62352
62448
|
const res = writeAgentContext(dir);
|
|
62353
62449
|
print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
|
|
62354
62450
|
return 0;
|
|
@@ -62434,7 +62530,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
62434
62530
|
let js;
|
|
62435
62531
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
62436
62532
|
try {
|
|
62437
|
-
js =
|
|
62533
|
+
js = readFileSync64(join50(outDir, candidate), "utf8");
|
|
62438
62534
|
break;
|
|
62439
62535
|
} catch {
|
|
62440
62536
|
}
|
|
@@ -62524,7 +62620,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62524
62620
|
return 2;
|
|
62525
62621
|
}
|
|
62526
62622
|
const template = str5(flags.template);
|
|
62527
|
-
const parentDir =
|
|
62623
|
+
const parentDir = resolve41(str5(flags.dir) ?? process.cwd());
|
|
62528
62624
|
if (template && flags.remote === true) {
|
|
62529
62625
|
try {
|
|
62530
62626
|
const res2 = await initFromRemoteTemplate(name, parentDir, template, client3());
|
|
@@ -62612,11 +62708,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62612
62708
|
return 0;
|
|
62613
62709
|
}
|
|
62614
62710
|
if (sub === "publish") {
|
|
62615
|
-
const appDir2 =
|
|
62616
|
-
const sourceDir =
|
|
62711
|
+
const appDir2 = resolve41(str5(flags.dir) ?? process.cwd());
|
|
62712
|
+
const sourceDir = resolve41(str5(flags["source-dir"]) ?? appDir2);
|
|
62617
62713
|
let meta;
|
|
62618
62714
|
try {
|
|
62619
|
-
meta = JSON.parse(
|
|
62715
|
+
meta = JSON.parse(readFileSync64(join50(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
62620
62716
|
} catch {
|
|
62621
62717
|
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>)` }));
|
|
62622
62718
|
return 2;
|
|
@@ -62626,7 +62722,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62626
62722
|
return 2;
|
|
62627
62723
|
}
|
|
62628
62724
|
try {
|
|
62629
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
62725
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync64(join50(sourceDir, "tokens.json"), "utf8")));
|
|
62630
62726
|
meta = { ...appearance, ...meta };
|
|
62631
62727
|
} catch {
|
|
62632
62728
|
}
|
|
@@ -62638,13 +62734,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62638
62734
|
const force = flags.force === true;
|
|
62639
62735
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
62640
62736
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
62641
|
-
const out = mkdtempSync4(
|
|
62737
|
+
const out = mkdtempSync4(join50(tmpdir5(), "himi-template-"));
|
|
62642
62738
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
62643
62739
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
62644
62740
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
62645
62741
|
collect: { lint: true, strict }
|
|
62646
62742
|
});
|
|
62647
|
-
const scaffoldSourceFindings =
|
|
62743
|
+
const scaffoldSourceFindings = resolve41(sourceDir) === resolve41(appDir2) ? [] : [
|
|
62648
62744
|
...tokenColorIssues(sourceDir),
|
|
62649
62745
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
62650
62746
|
...fontIssues(sourceDir, strict),
|
|
@@ -62687,11 +62783,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62687
62783
|
}));
|
|
62688
62784
|
return 1;
|
|
62689
62785
|
}
|
|
62690
|
-
const iconPath = str5(flags.icon) ?
|
|
62786
|
+
const iconPath = str5(flags.icon) ? resolve41(str5(flags.icon)) : templateIconPath(name);
|
|
62691
62787
|
let iconHash;
|
|
62692
62788
|
if (iconPath) {
|
|
62693
62789
|
try {
|
|
62694
|
-
const bytes2 =
|
|
62790
|
+
const bytes2 = readFileSync64(iconPath);
|
|
62695
62791
|
payload.icon = bytes2.toString("base64");
|
|
62696
62792
|
iconHash = createHash24("sha256").update(bytes2).digest("hex");
|
|
62697
62793
|
} catch {
|
|
@@ -62890,7 +62986,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62890
62986
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
62891
62987
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
62892
62988
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
62893
|
-
const out = mkdtempSync4(
|
|
62989
|
+
const out = mkdtempSync4(join50(tmpdir5(), "himi-validate-"));
|
|
62894
62990
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
62895
62991
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
62896
62992
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -62927,7 +63023,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
62927
63023
|
const path = dpxSessionTokenPath();
|
|
62928
63024
|
let raw;
|
|
62929
63025
|
try {
|
|
62930
|
-
raw =
|
|
63026
|
+
raw = readFileSync64(path, "utf8");
|
|
62931
63027
|
} catch {
|
|
62932
63028
|
throw new Error(`no DPX BO session at ${path}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
|
|
62933
63029
|
}
|
|
@@ -63079,7 +63175,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63079
63175
|
case "test": {
|
|
63080
63176
|
const dir = contentDir(flags);
|
|
63081
63177
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
63082
|
-
if (
|
|
63178
|
+
if (existsSync52(join50(dir, "functions"))) {
|
|
63083
63179
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
63084
63180
|
const loaded = await loadFunctionsApp2(dir);
|
|
63085
63181
|
const results = [];
|
|
@@ -63166,7 +63262,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63166
63262
|
}
|
|
63167
63263
|
}
|
|
63168
63264
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
63169
|
-
const out = mkdtempSync4(
|
|
63265
|
+
const out = mkdtempSync4(join50(tmpdir5(), "himi-test-"));
|
|
63170
63266
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63171
63267
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
63172
63268
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -63211,7 +63307,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63211
63307
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
63212
63308
|
return 2;
|
|
63213
63309
|
}
|
|
63214
|
-
const sources = collectWorkerSources2(
|
|
63310
|
+
const sources = collectWorkerSources2(join50(dir, "tier5-src"), screen.bundleName);
|
|
63215
63311
|
if (!sources) {
|
|
63216
63312
|
io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
63217
63313
|
return 2;
|
|
@@ -63372,7 +63468,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63372
63468
|
const sp = await runShotsPass2({
|
|
63373
63469
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
63374
63470
|
tokens: outcome.tokens,
|
|
63375
|
-
outDir:
|
|
63471
|
+
outDir: join50(dir, ".himi", "shots"),
|
|
63376
63472
|
width: 390,
|
|
63377
63473
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
63378
63474
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -63410,7 +63506,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63410
63506
|
releaseId: result.releaseId,
|
|
63411
63507
|
releasePayload: release,
|
|
63412
63508
|
descriptors: attestedDescriptors,
|
|
63413
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
63509
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join50(dir, ".himi", "shots", name)])),
|
|
63414
63510
|
coverage: {
|
|
63415
63511
|
screens: crawledScreens.size,
|
|
63416
63512
|
actionsDispatched: result.actions.exercised,
|
|
@@ -63499,7 +63595,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63499
63595
|
return 2;
|
|
63500
63596
|
}
|
|
63501
63597
|
try {
|
|
63502
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
63598
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync64(stateArg.replace(/^@/, ""), "utf8");
|
|
63503
63599
|
injectedState = JSON.parse(raw);
|
|
63504
63600
|
} catch (e) {
|
|
63505
63601
|
io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
|
|
@@ -63514,7 +63610,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63514
63610
|
return 2;
|
|
63515
63611
|
}
|
|
63516
63612
|
try {
|
|
63517
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
63613
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync64(inputArg.replace(/^@/, ""), "utf8");
|
|
63518
63614
|
const parsed = JSON.parse(raw);
|
|
63519
63615
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
63520
63616
|
injectedInput = parsed;
|
|
@@ -63547,7 +63643,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63547
63643
|
return 2;
|
|
63548
63644
|
}
|
|
63549
63645
|
} else if (typeof flags.width === "string" && flags.width) {
|
|
63550
|
-
renderWidth = Number(flags.width);
|
|
63646
|
+
renderWidth = Math.round(Number(flags.width));
|
|
63551
63647
|
if (!Number.isFinite(renderWidth) || renderWidth <= 0) {
|
|
63552
63648
|
io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${str5(flags.width)}")` }));
|
|
63553
63649
|
return 2;
|
|
@@ -63563,7 +63659,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63563
63659
|
}
|
|
63564
63660
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63565
63661
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
63566
|
-
const out = mkdtempSync4(
|
|
63662
|
+
const out = mkdtempSync4(join50(tmpdir5(), "himi-render-"));
|
|
63567
63663
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63568
63664
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
63569
63665
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -63579,7 +63675,15 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
63579
63675
|
let attestationPngFile;
|
|
63580
63676
|
if (typeof flags.png === "string" && r.pngBase64) {
|
|
63581
63677
|
pngFile = writePngFile(str5(flags.png), r.pngBase64);
|
|
63582
|
-
attestationPngFile = writePngFile(
|
|
63678
|
+
attestationPngFile = writePngFile(join50(dir, ".himi", "shots", `${screenId}.png`), r.pngBase64);
|
|
63679
|
+
}
|
|
63680
|
+
if (renderWidth !== void 0 && r.renderable) {
|
|
63681
|
+
recordRenderWidth(dir, {
|
|
63682
|
+
screenId,
|
|
63683
|
+
width: renderWidth,
|
|
63684
|
+
...deviceName ? { device: deviceName } : {},
|
|
63685
|
+
...pngFile ? { file: pngFile } : {}
|
|
63686
|
+
});
|
|
63583
63687
|
}
|
|
63584
63688
|
const legacyRender = {
|
|
63585
63689
|
ok: r.renderable,
|
|
@@ -63884,7 +63988,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
63884
63988
|
return 2;
|
|
63885
63989
|
}
|
|
63886
63990
|
const renamed = str5(flags.name);
|
|
63887
|
-
const dest =
|
|
63991
|
+
const dest = resolve41(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
63888
63992
|
const replace = flags.replace === true;
|
|
63889
63993
|
const force = replace || flags.force === true;
|
|
63890
63994
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -63892,8 +63996,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
63892
63996
|
io.error(JSON.stringify(linked));
|
|
63893
63997
|
return 1;
|
|
63894
63998
|
}
|
|
63895
|
-
if (
|
|
63896
|
-
if (!
|
|
63999
|
+
if (existsSync52(dest)) {
|
|
64000
|
+
if (!statSync12(dest).isDirectory()) {
|
|
63897
64001
|
io.error(JSON.stringify({
|
|
63898
64002
|
error: `${dest} exists and is not a directory`,
|
|
63899
64003
|
hint: "pass --out/--name to land somewhere else, or remove the file"
|
|
@@ -63905,7 +64009,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
63905
64009
|
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" }));
|
|
63906
64010
|
return 1;
|
|
63907
64011
|
}
|
|
63908
|
-
if (replace && occupied && !
|
|
64012
|
+
if (replace && occupied && !existsSync52(join50(dest, "himalaya.content.json"))) {
|
|
63909
64013
|
io.error(JSON.stringify({
|
|
63910
64014
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
63911
64015
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -63999,7 +64103,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
63999
64103
|
const force = flags.force === true;
|
|
64000
64104
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64001
64105
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
64002
|
-
const out = mkdtempSync4(
|
|
64106
|
+
const out = mkdtempSync4(join50(tmpdir5(), "himi-push-"));
|
|
64003
64107
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64004
64108
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
64005
64109
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64318,7 +64422,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64318
64422
|
return 2;
|
|
64319
64423
|
}
|
|
64320
64424
|
try {
|
|
64321
|
-
const res = writePack(
|
|
64425
|
+
const res = writePack(resolve41(releaseDir), only, resolve41(str5(flags.out) ?? process.cwd()));
|
|
64322
64426
|
print({
|
|
64323
64427
|
ok: true,
|
|
64324
64428
|
app: res.app,
|
|
@@ -64367,7 +64471,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64367
64471
|
}
|
|
64368
64472
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64369
64473
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
64370
|
-
const built = mkdtempSync4(
|
|
64474
|
+
const built = mkdtempSync4(join50(tmpdir5(), "himi-pack-"));
|
|
64371
64475
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64372
64476
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
64373
64477
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64389,7 +64493,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64389
64493
|
return 1;
|
|
64390
64494
|
}
|
|
64391
64495
|
try {
|
|
64392
|
-
const res = writePack(built, app,
|
|
64496
|
+
const res = writePack(built, app, resolve41(str5(flags.out) ?? dir), sourceArchive);
|
|
64393
64497
|
print({
|
|
64394
64498
|
ok: true,
|
|
64395
64499
|
app: res.app,
|
|
@@ -64434,7 +64538,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64434
64538
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
64435
64539
|
let opened;
|
|
64436
64540
|
try {
|
|
64437
|
-
opened = openPackageFile2(
|
|
64541
|
+
opened = openPackageFile2(resolve41(file));
|
|
64438
64542
|
} catch (e) {
|
|
64439
64543
|
io.error(JSON.stringify({ error: e.message }));
|
|
64440
64544
|
return 1;
|
|
@@ -64447,7 +64551,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64447
64551
|
io.error(JSON.stringify({
|
|
64448
64552
|
ok: false,
|
|
64449
64553
|
error: "app_source_not_in_package",
|
|
64450
|
-
detail: `${
|
|
64554
|
+
detail: `${resolve41(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
64451
64555
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
64452
64556
|
}));
|
|
64453
64557
|
return 1;
|
|
@@ -64470,7 +64574,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64470
64574
|
return 1;
|
|
64471
64575
|
}
|
|
64472
64576
|
}
|
|
64473
|
-
const dest =
|
|
64577
|
+
const dest = resolve41(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
64474
64578
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
64475
64579
|
if (issue2) {
|
|
64476
64580
|
io.error(JSON.stringify(issue2));
|
|
@@ -64555,7 +64659,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64555
64659
|
}
|
|
64556
64660
|
try {
|
|
64557
64661
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
64558
|
-
const opened = openPackageFile2(
|
|
64662
|
+
const opened = openPackageFile2(resolve41(file));
|
|
64559
64663
|
if (!opened.validation.ok || !opened.header) {
|
|
64560
64664
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
64561
64665
|
return 1;
|
|
@@ -64565,12 +64669,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64565
64669
|
io.error(JSON.stringify({
|
|
64566
64670
|
ok: false,
|
|
64567
64671
|
error: "refusing to share a package that carries the app's source",
|
|
64568
|
-
detail: `${
|
|
64672
|
+
detail: `${resolve41(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
|
|
64569
64673
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
64570
64674
|
}));
|
|
64571
64675
|
return 1;
|
|
64572
64676
|
}
|
|
64573
|
-
const archive =
|
|
64677
|
+
const archive = readFileSync64(resolve41(file));
|
|
64574
64678
|
const result = await client3().createPackageShare({
|
|
64575
64679
|
app: opened.header.app,
|
|
64576
64680
|
releaseId: opened.header.releaseId,
|
|
@@ -64607,10 +64711,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64607
64711
|
const app = await appId(dir);
|
|
64608
64712
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64609
64713
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
64610
|
-
temp = mkdtempSync4(
|
|
64714
|
+
temp = mkdtempSync4(join50(tmpdir5(), "himi-run-build-"));
|
|
64611
64715
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64612
64716
|
await buildReleaseFromContent2(dir, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
|
|
64613
|
-
source =
|
|
64717
|
+
source = join50(temp, app);
|
|
64614
64718
|
}
|
|
64615
64719
|
const chromeArg = str5(flags.chrome) ?? "preview";
|
|
64616
64720
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -64635,9 +64739,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
64635
64739
|
open: flags["no-open"] !== true
|
|
64636
64740
|
});
|
|
64637
64741
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
64638
|
-
await new Promise((
|
|
64742
|
+
await new Promise((resolve42) => {
|
|
64639
64743
|
const stop = () => {
|
|
64640
|
-
void run2.close().finally(() =>
|
|
64744
|
+
void run2.close().finally(() => resolve42());
|
|
64641
64745
|
};
|
|
64642
64746
|
process.once("SIGINT", stop);
|
|
64643
64747
|
process.once("SIGTERM", stop);
|
|
@@ -65466,7 +65570,7 @@ ${label2}`);
|
|
|
65466
65570
|
const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
65467
65571
|
{
|
|
65468
65572
|
const distDir = contentDir(flags);
|
|
65469
|
-
if (
|
|
65573
|
+
if (existsSync52(join50(distDir, "himalaya.content.json"))) {
|
|
65470
65574
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
65471
65575
|
const errors = issues.filter((i) => i.severity === "error");
|
|
65472
65576
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|
|
@@ -65736,7 +65840,7 @@ ${label2}`);
|
|
|
65736
65840
|
const dpxPath = dpxSessionTokenPath();
|
|
65737
65841
|
let dpx;
|
|
65738
65842
|
try {
|
|
65739
|
-
dpx =
|
|
65843
|
+
dpx = readFileSync64(dpxPath, "utf8").trim();
|
|
65740
65844
|
} catch {
|
|
65741
65845
|
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` }));
|
|
65742
65846
|
return 1;
|
|
@@ -66023,7 +66127,7 @@ ${report.ok ? "OK \u2014 data + serve plane reachable." : typeof report.hint ===
|
|
|
66023
66127
|
const path = dpxSessionTokenPath();
|
|
66024
66128
|
let raw;
|
|
66025
66129
|
try {
|
|
66026
|
-
raw =
|
|
66130
|
+
raw = readFileSync64(path, "utf8");
|
|
66027
66131
|
} catch {
|
|
66028
66132
|
io.error(JSON.stringify({ error: `no DPX BO session at ${path}` }));
|
|
66029
66133
|
return 1;
|