@wix/himalaya-cli 0.1014.0 → 0.1015.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 +942 -467
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/headless-loop.md +5 -1
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -1341,7 +1341,7 @@ function sentinelizeIdentity(body, identity) {
|
|
|
1341
1341
|
}
|
|
1342
1342
|
if (identity.name) {
|
|
1343
1343
|
const re = new RegExp(`\\b(${NAME_FIELDS.join("|")})(["']?\\s*[:=]\\s*)(["'])${escapeRe(identity.name)}\\3`, "g");
|
|
1344
|
-
out = out.replace(re, (_m, key2,
|
|
1344
|
+
out = out.replace(re, (_m, key2, sep15, q) => `${key2}${sep15}${q}__HIMI_APP_NAME__${q}`);
|
|
1345
1345
|
}
|
|
1346
1346
|
return out;
|
|
1347
1347
|
}
|
|
@@ -2368,7 +2368,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2368
2368
|
tokenCache.set(cacheKey, fromEnv);
|
|
2369
2369
|
return fromEnv;
|
|
2370
2370
|
}
|
|
2371
|
-
const token = await new Promise((
|
|
2371
|
+
const token = await new Promise((resolve48, reject) => {
|
|
2372
2372
|
let child;
|
|
2373
2373
|
try {
|
|
2374
2374
|
child = spawnImpl("wix", [...args]);
|
|
@@ -2397,12 +2397,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
|
|
|
2397
2397
|
child.stdout?.on("data", (d) => {
|
|
2398
2398
|
out += String(d);
|
|
2399
2399
|
const m = out.match(TOKEN_RE);
|
|
2400
|
-
if (m) done(() =>
|
|
2400
|
+
if (m) done(() => resolve48(m[0]));
|
|
2401
2401
|
});
|
|
2402
2402
|
child.stderr?.on("data", (d) => {
|
|
2403
2403
|
out += String(d);
|
|
2404
2404
|
const m = out.match(TOKEN_RE);
|
|
2405
|
-
if (m) done(() =>
|
|
2405
|
+
if (m) done(() => resolve48(m[0]));
|
|
2406
2406
|
});
|
|
2407
2407
|
child.on("error", (e) => done(() => reject(new Error(mintHelp(label2, e.message)))));
|
|
2408
2408
|
child.on("exit", (code) => done(() => reject(new Error(
|
|
@@ -5345,7 +5345,6 @@ function walk(node, registry, path2, out) {
|
|
|
5345
5345
|
var SYSTEM_FONT_FAMILY;
|
|
5346
5346
|
var init_tokens = __esm({
|
|
5347
5347
|
"../../core/ts/src/tokens.ts"() {
|
|
5348
|
-
"use strict";
|
|
5349
5348
|
SYSTEM_FONT_FAMILY = "$system";
|
|
5350
5349
|
}
|
|
5351
5350
|
});
|
|
@@ -15593,7 +15592,7 @@ async function injectRequest(listener, request) {
|
|
|
15593
15592
|
req.headers.host ??= url.host;
|
|
15594
15593
|
if (body && body.length > 0) req.push(body);
|
|
15595
15594
|
req.push(null);
|
|
15596
|
-
return await new Promise((
|
|
15595
|
+
return await new Promise((resolve48, reject) => {
|
|
15597
15596
|
const streamed = () => {
|
|
15598
15597
|
queueMicrotask(() => {
|
|
15599
15598
|
req.emit("close");
|
|
@@ -15609,7 +15608,7 @@ async function injectRequest(listener, request) {
|
|
|
15609
15608
|
else headers2.set(name, value);
|
|
15610
15609
|
}
|
|
15611
15610
|
const bodyless = out.status === 204 || out.status === 304 || request.method === "HEAD";
|
|
15612
|
-
|
|
15611
|
+
resolve48(new Response(bodyless ? null : out.body, { status: out.status, headers: headers2 }));
|
|
15613
15612
|
}, streamed);
|
|
15614
15613
|
res.on("inject-error", reject);
|
|
15615
15614
|
try {
|
|
@@ -16304,7 +16303,7 @@ function redactBodyString(body) {
|
|
|
16304
16303
|
} catch {
|
|
16305
16304
|
}
|
|
16306
16305
|
}
|
|
16307
|
-
return body.replace(FORM_ASSIGNMENT_RE, (m, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m).replace(JSON_FIELD_RE, (m, name,
|
|
16306
|
+
return body.replace(FORM_ASSIGNMENT_RE, (m, name) => isSensitiveBodyName(name) ? `${name}=${REDACTED}` : m).replace(JSON_FIELD_RE, (m, name, sep15) => isSensitiveBodyName(name) ? `"${name}"${sep15}"${REDACTED}"` : m).replace(JSON_FIELD_UNTERMINATED_RE, (m, name, sep15) => isSensitiveBodyName(name) ? `"${name}"${sep15}"${REDACTED}` : m).replace(BEARER_RE, (_m, s) => `${s} ${REDACTED}`);
|
|
16308
16307
|
}
|
|
16309
16308
|
function createWixGatewayState() {
|
|
16310
16309
|
return { mode: "record", rules: [], traffic: [], clients: /* @__PURE__ */ new Set(), seq: 0, ruleSeq: 0 };
|
|
@@ -17996,12 +17995,12 @@ function finalizeRecording(key2, rec) {
|
|
|
17996
17995
|
if (rec.finalize) return rec.finalize;
|
|
17997
17996
|
rec.finalize = (async () => {
|
|
17998
17997
|
clearTimeout(rec.autoStop);
|
|
17999
|
-
await new Promise((
|
|
17998
|
+
await new Promise((resolve48) => {
|
|
18000
17999
|
let done = false;
|
|
18001
18000
|
const finish2 = () => {
|
|
18002
18001
|
if (!done) {
|
|
18003
18002
|
done = true;
|
|
18004
|
-
|
|
18003
|
+
resolve48();
|
|
18005
18004
|
}
|
|
18006
18005
|
};
|
|
18007
18006
|
rec.child.once("close", finish2);
|
|
@@ -18112,7 +18111,7 @@ var init_preview = __esm({
|
|
|
18112
18111
|
DEVICE_LIST_TIMEOUT_MS = 5e3;
|
|
18113
18112
|
defaultRunner2 = {
|
|
18114
18113
|
capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
|
|
18115
|
-
return new Promise((
|
|
18114
|
+
return new Promise((resolve48, reject) => {
|
|
18116
18115
|
const child = spawn3(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
18117
18116
|
const out = [];
|
|
18118
18117
|
const err = [];
|
|
@@ -18134,7 +18133,7 @@ var init_preview = __esm({
|
|
|
18134
18133
|
child.stderr.on("data", (b) => err.push(b));
|
|
18135
18134
|
child.on("error", (e) => settle(reject, e));
|
|
18136
18135
|
child.on("close", (code) => {
|
|
18137
|
-
if (code === 0) settle(
|
|
18136
|
+
if (code === 0) settle(resolve48, Buffer.concat(out));
|
|
18138
18137
|
else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
|
|
18139
18138
|
});
|
|
18140
18139
|
});
|
|
@@ -23189,8 +23188,8 @@ function ensureCountUpRuntime() {
|
|
|
23189
23188
|
const neg = fixed.startsWith("-");
|
|
23190
23189
|
const body = neg ? fixed.slice(1) : fixed;
|
|
23191
23190
|
const [int, frac] = body.split(".");
|
|
23192
|
-
const
|
|
23193
|
-
return (neg ? "-" : "") +
|
|
23191
|
+
const sep15 = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
23192
|
+
return (neg ? "-" : "") + sep15 + (frac ? "." + frac : "");
|
|
23194
23193
|
};
|
|
23195
23194
|
const animateEl = (el) => {
|
|
23196
23195
|
const node = el;
|
|
@@ -28914,7 +28913,7 @@ async function stabilizePngPage(page, scheme) {
|
|
|
28914
28913
|
const browser = globalThis;
|
|
28915
28914
|
browser.document.documentElement.style.colorScheme = selected;
|
|
28916
28915
|
await browser.document.fonts?.ready;
|
|
28917
|
-
await new Promise((
|
|
28916
|
+
await new Promise((resolve48) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve48())));
|
|
28918
28917
|
}, scheme);
|
|
28919
28918
|
}
|
|
28920
28919
|
async function renderPngBatch(items) {
|
|
@@ -32486,7 +32485,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32486
32485
|
}
|
|
32487
32486
|
if (match && (match.rule.kind ?? "mock") === "mock") {
|
|
32488
32487
|
const mocked = match.rule.response;
|
|
32489
|
-
if (mocked.delayMs) await new Promise((
|
|
32488
|
+
if (mocked.delayMs) await new Promise((resolve48) => setTimeout(resolve48, mocked.delayMs));
|
|
32490
32489
|
const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
|
|
32491
32490
|
recordWixTraffic(state.wix, state.appName, state.adminUrl, {
|
|
32492
32491
|
ts: started,
|
|
@@ -34488,12 +34487,12 @@ var init_query = __esm({
|
|
|
34488
34487
|
});
|
|
34489
34488
|
|
|
34490
34489
|
// ../../core/dev-server/src/crawl-input.ts
|
|
34491
|
-
function resolved(v,
|
|
34492
|
-
if (typeof v === "string") return v.startsWith("$service:") ?
|
|
34490
|
+
function resolved(v, resolve48) {
|
|
34491
|
+
if (typeof v === "string") return v.startsWith("$service:") ? resolve48(v) : v;
|
|
34493
34492
|
if (Array.isArray(v)) {
|
|
34494
34493
|
const out = v.flatMap((el) => {
|
|
34495
34494
|
if (typeof el !== "string" || !el.startsWith("$service:")) return [el];
|
|
34496
|
-
const r =
|
|
34495
|
+
const r = resolve48(el);
|
|
34497
34496
|
return Array.isArray(r) ? r : [r];
|
|
34498
34497
|
});
|
|
34499
34498
|
return out;
|
|
@@ -34507,9 +34506,9 @@ function hasRowBinding(props) {
|
|
|
34507
34506
|
return itemToken(v) || Array.isArray(v) && v.some(itemToken);
|
|
34508
34507
|
});
|
|
34509
34508
|
}
|
|
34510
|
-
function declaredOptionIds(props,
|
|
34509
|
+
function declaredOptionIds(props, resolve48) {
|
|
34511
34510
|
const literal = props.options ?? props.tabs ?? props.chips;
|
|
34512
|
-
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath,
|
|
34511
|
+
const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve48) : void 0;
|
|
34513
34512
|
const raw = Array.isArray(bound) ? bound : literal;
|
|
34514
34513
|
if (!Array.isArray(raw)) return [];
|
|
34515
34514
|
const out = [];
|
|
@@ -34552,24 +34551,24 @@ function seedTokens(state, limit = 48) {
|
|
|
34552
34551
|
walk2(state, 0);
|
|
34553
34552
|
return out;
|
|
34554
34553
|
}
|
|
34555
|
-
function synthesizeInput(control,
|
|
34554
|
+
function synthesizeInput(control, resolve48, tokens) {
|
|
34556
34555
|
const id = `${control.type}.${control.callback}`;
|
|
34557
34556
|
const row = SYNTHESIZED_CONTROLS[id];
|
|
34558
34557
|
if (!row) return null;
|
|
34559
34558
|
const props = control.props;
|
|
34560
34559
|
if (hasRowBinding(props)) return null;
|
|
34561
34560
|
if (row.from === "declared-options") {
|
|
34562
|
-
const ids = declaredOptionIds(props,
|
|
34561
|
+
const ids = declaredOptionIds(props, resolve48);
|
|
34563
34562
|
if (!ids.length) return null;
|
|
34564
34563
|
if (row.encoding === "string-array") {
|
|
34565
|
-
const currentRaw2 = resolved(props.selectedIds,
|
|
34564
|
+
const currentRaw2 = resolved(props.selectedIds, resolve48);
|
|
34566
34565
|
const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x) => typeof x === "string");
|
|
34567
34566
|
const pick4 = ids.find((o) => !current3.includes(o));
|
|
34568
34567
|
if (pick4 === void 0) return null;
|
|
34569
34568
|
const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
|
|
34570
34569
|
return { key: row.key, value, from: row.from, current: current3, control: id };
|
|
34571
34570
|
}
|
|
34572
|
-
const currentRaw = resolved(props.selectedId,
|
|
34571
|
+
const currentRaw = resolved(props.selectedId, resolve48);
|
|
34573
34572
|
const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
|
|
34574
34573
|
const pick3 = ids.find((o) => o !== current2);
|
|
34575
34574
|
if (pick3 === void 0) return null;
|
|
@@ -34577,7 +34576,7 @@ function synthesizeInput(control, resolve47, tokens) {
|
|
|
34577
34576
|
}
|
|
34578
34577
|
if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
|
|
34579
34578
|
const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
|
|
34580
|
-
const bound = binding2 === void 0 ? void 0 :
|
|
34579
|
+
const bound = binding2 === void 0 ? void 0 : resolve48(binding2);
|
|
34581
34580
|
const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
|
|
34582
34581
|
const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
|
|
34583
34582
|
const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
|
|
@@ -35835,8 +35834,8 @@ async function crawlScreenInner(opts) {
|
|
|
35835
35834
|
if (linkable.has(target)) return true;
|
|
35836
35835
|
for (const base of linkable) {
|
|
35837
35836
|
if (target.length > base.length + 1 && target.startsWith(base)) {
|
|
35838
|
-
const
|
|
35839
|
-
if (
|
|
35837
|
+
const sep15 = target[base.length];
|
|
35838
|
+
if (sep15 === "_" || sep15 === "/") return true;
|
|
35840
35839
|
}
|
|
35841
35840
|
}
|
|
35842
35841
|
return false;
|
|
@@ -38090,6 +38089,7 @@ __export(progress_exports, {
|
|
|
38090
38089
|
MAX_MESSAGE_CHARS: () => MAX_MESSAGE_CHARS,
|
|
38091
38090
|
PROGRESS_FILE: () => PROGRESS_FILE,
|
|
38092
38091
|
ProgressError: () => ProgressError,
|
|
38092
|
+
UnsafeHimiDirError: () => UnsafeHimiDirError,
|
|
38093
38093
|
appLabel: () => appLabel,
|
|
38094
38094
|
appendProgress: () => appendProgress,
|
|
38095
38095
|
appleScriptString: () => appleScriptString,
|
|
@@ -38099,11 +38099,14 @@ __export(progress_exports, {
|
|
|
38099
38099
|
notifyDesktop: () => notifyDesktop,
|
|
38100
38100
|
parseStep: () => parseStep,
|
|
38101
38101
|
readProgress: () => readProgress,
|
|
38102
|
-
|
|
38102
|
+
realDirIn: () => realDirIn,
|
|
38103
|
+
summarizeProgress: () => summarizeProgress,
|
|
38104
|
+
writeFileAtomic: () => writeFileAtomic
|
|
38103
38105
|
});
|
|
38104
38106
|
import { spawn as spawn4 } from "node:child_process";
|
|
38105
38107
|
import { createHash as createHash19 } from "node:crypto";
|
|
38106
|
-
import {
|
|
38108
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
38109
|
+
import { appendFileSync, closeSync, existsSync as existsSync38, lstatSync as lstatSync5, mkdirSync as mkdirSync17, openSync, readFileSync as readFileSync41, readSync, renameSync as renameSync3, rmSync as rmSync6, statSync as statSync7, writeFileSync as writeFileSync13 } from "node:fs";
|
|
38107
38110
|
import { join as join35, relative as relative5, resolve as resolve32, sep as sep8 } from "node:path";
|
|
38108
38111
|
function parseStep(raw) {
|
|
38109
38112
|
const v = raw.trim().toLowerCase();
|
|
@@ -38131,21 +38134,49 @@ function archiveImage(dir, src) {
|
|
|
38131
38134
|
if (size > MAX_IMAGE_BYTES) {
|
|
38132
38135
|
throw new ProgressError("image_too_large", `${src} is ${size} bytes; a progress image is capped at ${MAX_IMAGE_BYTES} \u2014 render at phone width (--device iphone)`);
|
|
38133
38136
|
}
|
|
38134
|
-
|
|
38137
|
+
let archived;
|
|
38138
|
+
try {
|
|
38139
|
+
archived = archiveBytes(dir, readFileSync41(abs));
|
|
38140
|
+
} catch (e) {
|
|
38141
|
+
if (e instanceof UnsafeHimiDirError) throw new ProgressError("unsafe_himi_dir", e.message);
|
|
38142
|
+
throw e;
|
|
38143
|
+
}
|
|
38135
38144
|
if (!archived) throw new ProgressError("not_an_image", `${src} is not a PNG, JPEG, GIF or WebP image`);
|
|
38136
38145
|
return { file: archived.file, sha256: archived.sha256, source: src };
|
|
38137
38146
|
}
|
|
38147
|
+
function realDirIn(dir, rel) {
|
|
38148
|
+
let at = dir;
|
|
38149
|
+
for (const part of rel.split(/[\\/]+/).filter(Boolean)) {
|
|
38150
|
+
at = join35(at, part);
|
|
38151
|
+
try {
|
|
38152
|
+
if (!lstatSync5(at).isDirectory()) return null;
|
|
38153
|
+
} catch (e) {
|
|
38154
|
+
if (e.code !== "ENOENT") return null;
|
|
38155
|
+
mkdirSync17(at);
|
|
38156
|
+
if (!lstatSync5(at).isDirectory()) return null;
|
|
38157
|
+
}
|
|
38158
|
+
}
|
|
38159
|
+
return at;
|
|
38160
|
+
}
|
|
38161
|
+
function writeFileAtomic(file, content) {
|
|
38162
|
+
const tmp = `${file}.${process.pid}.${randomUUID2()}.tmp`;
|
|
38163
|
+
try {
|
|
38164
|
+
writeFileSync13(tmp, content, { flag: "wx" });
|
|
38165
|
+
renameSync3(tmp, file);
|
|
38166
|
+
} catch (e) {
|
|
38167
|
+
rmSync6(tmp, { force: true });
|
|
38168
|
+
throw e;
|
|
38169
|
+
}
|
|
38170
|
+
}
|
|
38138
38171
|
function archiveBytes(dir, bytes2) {
|
|
38139
38172
|
const ext = imageExtension(bytes2);
|
|
38140
38173
|
if (!ext) return null;
|
|
38141
38174
|
const sha2565 = createHash19("sha256").update(bytes2).digest("hex");
|
|
38142
38175
|
const rel = join35(HISTORY_DIR, `${sha2565}.${ext}`);
|
|
38143
38176
|
const dest = join35(dir, rel);
|
|
38177
|
+
if (!realDirIn(dir, HISTORY_DIR)) throw new UnsafeHimiDirError(HISTORY_DIR);
|
|
38144
38178
|
if (!existsSync38(dest)) {
|
|
38145
|
-
|
|
38146
|
-
const tmp = `${dest}.${process.pid}.tmp`;
|
|
38147
|
-
writeFileSync13(tmp, bytes2);
|
|
38148
|
-
renameSync3(tmp, dest);
|
|
38179
|
+
writeFileAtomic(dest, bytes2);
|
|
38149
38180
|
}
|
|
38150
38181
|
return { sha256: sha2565, ext, file: toPosix(rel) };
|
|
38151
38182
|
}
|
|
@@ -38165,8 +38196,9 @@ function appendProgress(dir, input) {
|
|
|
38165
38196
|
...input.step ? { step: input.step, stepNumber: JOURNEY_STEPS.indexOf(input.step) + 1 } : {},
|
|
38166
38197
|
...images.length ? { images } : {}
|
|
38167
38198
|
};
|
|
38168
|
-
|
|
38199
|
+
if (!realDirIn(dir, ".himi")) throw new ProgressError("unsafe_himi_dir", new UnsafeHimiDirError(".himi").message);
|
|
38169
38200
|
const file = join35(dir, PROGRESS_FILE);
|
|
38201
|
+
if (existsSync38(file) && lstatSync5(file).isSymbolicLink()) throw new ProgressError("unsafe_himi_dir", `${PROGRESS_FILE} is a symlink \u2014 refusing to append through it`);
|
|
38170
38202
|
appendFileSync(file, `${endsWithNewline(file) ? "" : "\n"}${JSON.stringify(entry)}
|
|
38171
38203
|
`);
|
|
38172
38204
|
return entry;
|
|
@@ -38269,7 +38301,7 @@ function journalPath(dir) {
|
|
|
38269
38301
|
const rel = relative5(process.cwd(), abs);
|
|
38270
38302
|
return rel && !rel.startsWith("..") ? rel : abs;
|
|
38271
38303
|
}
|
|
38272
|
-
var JOURNEY_STEPS, PROGRESS_FILE, HISTORY_DIR, MAX_MESSAGE_CHARS, MAX_IMAGE_BYTES, ProgressError, toPosix, NOTIFY_TIMEOUT_MS;
|
|
38304
|
+
var JOURNEY_STEPS, PROGRESS_FILE, HISTORY_DIR, MAX_MESSAGE_CHARS, MAX_IMAGE_BYTES, ProgressError, toPosix, UnsafeHimiDirError, NOTIFY_TIMEOUT_MS;
|
|
38273
38305
|
var init_progress = __esm({
|
|
38274
38306
|
"src/progress.ts"() {
|
|
38275
38307
|
JOURNEY_STEPS = ["discover", "classify", "plan", "implement", "brand", "validate", "review", "download"];
|
|
@@ -38284,6 +38316,11 @@ var init_progress = __esm({
|
|
|
38284
38316
|
}
|
|
38285
38317
|
};
|
|
38286
38318
|
toPosix = (p) => p.split(sep8).join("/");
|
|
38319
|
+
UnsafeHimiDirError = class extends Error {
|
|
38320
|
+
constructor(rel) {
|
|
38321
|
+
super(`${rel} is not a real directory inside the content package (a symlink?) \u2014 refusing to write through it`);
|
|
38322
|
+
}
|
|
38323
|
+
};
|
|
38287
38324
|
NOTIFY_TIMEOUT_MS = 3e3;
|
|
38288
38325
|
}
|
|
38289
38326
|
});
|
|
@@ -38305,7 +38342,7 @@ __export(studio_exports, {
|
|
|
38305
38342
|
writeStudioRecord: () => writeStudioRecord
|
|
38306
38343
|
});
|
|
38307
38344
|
import { createHash as createHash20 } from "node:crypto";
|
|
38308
|
-
import { existsSync as existsSync39,
|
|
38345
|
+
import { existsSync as existsSync39, readdirSync as readdirSync20, readFileSync as readFileSync42, realpathSync as realpathSync4, statSync as statSync8 } from "node:fs";
|
|
38309
38346
|
import { basename as basename9, extname as extname3, join as join36, relative as relative6, resolve as resolve33, sep as sep9 } from "node:path";
|
|
38310
38347
|
import { pathToFileURL as pathToFileURL7 } from "node:url";
|
|
38311
38348
|
function realInside(dir, abs) {
|
|
@@ -38433,9 +38470,10 @@ function liveRun(dir) {
|
|
|
38433
38470
|
const url = text(rec?.url);
|
|
38434
38471
|
const pid = rec?.pid;
|
|
38435
38472
|
if (!url || !/^https?:\/\//i.test(url) || typeof pid !== "number") return null;
|
|
38473
|
+
const build2 = obj(rec?.build);
|
|
38436
38474
|
try {
|
|
38437
38475
|
process.kill(pid, 0);
|
|
38438
|
-
return { url };
|
|
38476
|
+
return { url, buildError: build2?.ok === false ? text(build2.error) ?? "the last rebuild failed" : null };
|
|
38439
38477
|
} catch {
|
|
38440
38478
|
return null;
|
|
38441
38479
|
}
|
|
@@ -38509,14 +38547,13 @@ function buildView(dir, memory, now) {
|
|
|
38509
38547
|
return { v, ...view };
|
|
38510
38548
|
}
|
|
38511
38549
|
function writeAtomic(file, content) {
|
|
38512
|
-
|
|
38513
|
-
writeFileSync14(tmp, content);
|
|
38514
|
-
renameSync4(tmp, file);
|
|
38550
|
+
writeFileAtomic(file, content);
|
|
38515
38551
|
}
|
|
38516
38552
|
function writeBoard(dir, now) {
|
|
38553
|
+
if (!realDirIn(dir, STUDIO_DIR)) throw new UnsafeHimiDirError(STUDIO_DIR);
|
|
38554
|
+
if (!realDirIn(dir, HISTORY_DIR)) throw new UnsafeHimiDirError(HISTORY_DIR);
|
|
38517
38555
|
const memory = observeShots(dir, loadMemory(dir, now), now);
|
|
38518
38556
|
const view = buildView(dir, memory, now);
|
|
38519
|
-
mkdirSync18(join36(dir, STUDIO_DIR), { recursive: true });
|
|
38520
38557
|
writeAtomic(join36(dir, MEMORY_FILE), JSON.stringify(memory));
|
|
38521
38558
|
writeAtomic(join36(dir, STATE_FILE), `window.__himiStudio && window.__himiStudio(${scriptJson(view)});
|
|
38522
38559
|
`);
|
|
@@ -38538,7 +38575,7 @@ function openStudio(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
38538
38575
|
}
|
|
38539
38576
|
function writeStudioRecord(dir, record2, value) {
|
|
38540
38577
|
try {
|
|
38541
|
-
|
|
38578
|
+
if (!realDirIn(dir, ".himi")) return;
|
|
38542
38579
|
writeAtomic(join36(dir, record2), `${JSON.stringify(value, null, 2)}
|
|
38543
38580
|
`);
|
|
38544
38581
|
} catch {
|
|
@@ -38624,7 +38661,7 @@ function render(s){
|
|
|
38624
38661
|
$("nowmsg").textContent=last?last.message:"Waiting for the first postcard.";
|
|
38625
38662
|
$("nowmeta").textContent=last?("Now \xB7 "+(last.step?("step "+last.stepNumber+" of 8, "+last.step+" \xB7 "):"")+ago(last.ts)):"Now";
|
|
38626
38663
|
var focus=$("focus");clear(focus);var film=$("film");clear(film);
|
|
38627
|
-
if(s.live){$("focuslbl").textContent="Live preview";var f=el("div","phone");var fr=document.createElement("iframe");fr.src=s.live.url;fr.title="Live preview";f.appendChild(fr);focus.appendChild(f);focus.appendChild(el("div","cap","Repaints as the app is edited \xB7 "+s.live.url))}
|
|
38664
|
+
if(s.live){$("focuslbl").textContent="Live preview";var f=el("div","phone");var fr=document.createElement("iframe");fr.src=s.live.url;fr.title="Live preview";f.appendChild(fr);focus.appendChild(f);if(s.live.buildError){var be=el("div","chip bad",null);be.style.display="block";be.style.marginTop="8px";be.textContent="Last edit did not build, still showing the last good version: "+s.live.buildError;focus.appendChild(be)}focus.appendChild(el("div","cap","Repaints as the app is edited \xB7 "+s.live.url))}
|
|
38628
38665
|
else if(s.focus&&s.focus.frames.length){var fl=s.focus.frames;$("focuslbl").textContent="Latest \xB7 "+s.focus.id;var p=el("div","phone");p.appendChild(img(fl[fl.length-1].img));focus.appendChild(p);focus.appendChild(el("div","cap",fl.length+(fl.length===1?" version":" versions")+" so far"))}
|
|
38629
38666
|
else{$("focuslbl").textContent="Latest";focus.appendChild(el("div","empty","The first render appears here."))}
|
|
38630
38667
|
if(s.focus&&s.focus.frames.length>1)s.focus.frames.forEach(function(fm){film.appendChild(img(fm.img))});
|
|
@@ -39318,7 +39355,7 @@ var init_push_setup_apple_credentials = __esm({
|
|
|
39318
39355
|
});
|
|
39319
39356
|
|
|
39320
39357
|
// src/push-onboarding.ts
|
|
39321
|
-
import { existsSync as existsSync40, mkdirSync as
|
|
39358
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync18, readFileSync as readFileSync44, statSync as statSync9, writeFileSync as writeFileSync14, chmodSync as chmodSync2 } from "node:fs";
|
|
39322
39359
|
import { basename as basename10, dirname as dirname22, join as join37, resolve as resolve35 } from "node:path";
|
|
39323
39360
|
function readJson3(path2) {
|
|
39324
39361
|
try {
|
|
@@ -39468,8 +39505,8 @@ function readPushOnboarding(dir) {
|
|
|
39468
39505
|
}
|
|
39469
39506
|
function writeFile(dir, file) {
|
|
39470
39507
|
const path2 = join37(resolve35(dir), PUSH_ONBOARDING_PATH);
|
|
39471
|
-
|
|
39472
|
-
|
|
39508
|
+
mkdirSync18(dirname22(path2), { recursive: true, mode: 448 });
|
|
39509
|
+
writeFileSync14(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
|
|
39473
39510
|
try {
|
|
39474
39511
|
chmodSync2(path2, 384);
|
|
39475
39512
|
} catch {
|
|
@@ -40230,7 +40267,7 @@ __export(template_trim_exports, {
|
|
|
40230
40267
|
routeMatcher: () => routeMatcher,
|
|
40231
40268
|
runTemplateTrim: () => runTemplateTrim
|
|
40232
40269
|
});
|
|
40233
|
-
import { cpSync, existsSync as existsSync41, mkdirSync as
|
|
40270
|
+
import { cpSync, existsSync as existsSync41, mkdirSync as mkdirSync19, readdirSync as readdirSync21, readFileSync as readFileSync45, renameSync as renameSync4, rmSync as rmSync7, statSync as statSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
40234
40271
|
import { dirname as dirname23, join as join38 } from "node:path";
|
|
40235
40272
|
function routeMatcher(pattern) {
|
|
40236
40273
|
const detail = /^\^([A-Za-z0-9_]+)\(\?:\[_\/\]\(\.\+\)\)\?\$$/.exec(pattern);
|
|
@@ -40988,16 +41025,16 @@ async function runTemplateTrim(req, deps) {
|
|
|
40988
41025
|
const restore = () => {
|
|
40989
41026
|
for (const [path2, rel] of originals) {
|
|
40990
41027
|
const original = readFileSync45(join38(backup, rel));
|
|
40991
|
-
if (!existsSync41(path2) || !readFileSync45(path2).equals(original))
|
|
41028
|
+
if (!existsSync41(path2) || !readFileSync45(path2).equals(original)) writeFileSync15(path2, original);
|
|
40992
41029
|
}
|
|
40993
|
-
for (const name of [...moved].reverse())
|
|
41030
|
+
for (const name of [...moved].reverse()) renameSync4(join38(backup, "tier5-src", name), join38(dir, "tier5-src", name));
|
|
40994
41031
|
};
|
|
40995
41032
|
const dropBackup = () => {
|
|
40996
|
-
|
|
41033
|
+
rmSync7(backup, { recursive: true, force: true });
|
|
40997
41034
|
for (const d of [dirname23(backup), join38(dir, ".himi")]) {
|
|
40998
41035
|
if (d === join38(dir, ".himi") && hadHimi) break;
|
|
40999
41036
|
try {
|
|
41000
|
-
if (!readdirSync21(d).length)
|
|
41037
|
+
if (!readdirSync21(d).length) rmSync7(d, { recursive: true });
|
|
41001
41038
|
} catch {
|
|
41002
41039
|
}
|
|
41003
41040
|
}
|
|
@@ -41021,21 +41058,21 @@ async function runTemplateTrim(req, deps) {
|
|
|
41021
41058
|
return { code: 1, result: { ok: false, error: `${error} (${message}); every file was restored`, rolledBack: true, ...base(validate4) } };
|
|
41022
41059
|
};
|
|
41023
41060
|
try {
|
|
41024
|
-
|
|
41061
|
+
mkdirSync19(join38(backup, "dev"), { recursive: true });
|
|
41025
41062
|
for (const [path2, rel] of originals) cpSync(path2, join38(backup, rel));
|
|
41026
|
-
if (plan.removedWorkers.length)
|
|
41063
|
+
if (plan.removedWorkers.length) mkdirSync19(join38(backup, "tier5-src"), { recursive: true });
|
|
41027
41064
|
} catch (e) {
|
|
41028
41065
|
dropBackup();
|
|
41029
41066
|
return { code: 1, result: { ok: false, error: `could not back up the app before trimming it (${e.message}); nothing was changed`, rolledBack: true, ...base() } };
|
|
41030
41067
|
}
|
|
41031
41068
|
try {
|
|
41032
|
-
const moveDir = deps.moveDir ??
|
|
41069
|
+
const moveDir = deps.moveDir ?? renameSync4;
|
|
41033
41070
|
for (const name of plan.removedWorkers) {
|
|
41034
41071
|
moveDir(join38(dir, "tier5-src", name), join38(backup, "tier5-src", name));
|
|
41035
41072
|
moved.push(name);
|
|
41036
41073
|
}
|
|
41037
|
-
if (plan.dev !== dev)
|
|
41038
|
-
if (plan.config !== config)
|
|
41074
|
+
if (plan.dev !== dev) writeFileSync15(devPath, plan.dev);
|
|
41075
|
+
if (plan.config !== config) writeFileSync15(configPath, plan.config);
|
|
41039
41076
|
} catch (e) {
|
|
41040
41077
|
return abort("the trim failed while writing", e);
|
|
41041
41078
|
}
|
|
@@ -41736,7 +41773,7 @@ __export(pack_exports, {
|
|
|
41736
41773
|
});
|
|
41737
41774
|
import { createHash as createHash21 } from "node:crypto";
|
|
41738
41775
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
41739
|
-
import { existsSync as existsSync42, mkdirSync as
|
|
41776
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync20, readFileSync as readFileSync46, readdirSync as readdirSync22, rmSync as rmSync8, statSync as statSync11, writeFileSync as writeFileSync16 } from "node:fs";
|
|
41740
41777
|
import { dirname as dirname24, join as join39, resolve as resolve37 } from "node:path";
|
|
41741
41778
|
function writeZip(entries) {
|
|
41742
41779
|
const sorted2 = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -41913,10 +41950,10 @@ function packRelease(releaseRoot, app, out, opts = {}) {
|
|
|
41913
41950
|
const appDir2 = join39(resolve37(releaseRoot), app);
|
|
41914
41951
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
41915
41952
|
const buf = writeZip(all);
|
|
41916
|
-
const
|
|
41917
|
-
const outFile =
|
|
41918
|
-
|
|
41919
|
-
|
|
41953
|
+
const isDir2 = existsSync42(out) && statSync11(out).isDirectory();
|
|
41954
|
+
const outFile = isDir2 ? join39(resolve37(out), packageFileName(app, header.releaseId)) : resolve37(out);
|
|
41955
|
+
mkdirSync20(dirname24(outFile), { recursive: true });
|
|
41956
|
+
writeFileSync16(outFile, buf);
|
|
41920
41957
|
return { app, releaseId: header.releaseId, header, out: outFile, bytes: buf.length, entryCount: all.length, skipped };
|
|
41921
41958
|
}
|
|
41922
41959
|
function resolvePackageDirDest(outDir, app, releaseId) {
|
|
@@ -41955,12 +41992,12 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
|
41955
41992
|
const appDir2 = join39(resolve37(releaseRoot), app);
|
|
41956
41993
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
41957
41994
|
const dest = resolvePackageDirDest(resolve37(outDir), app, header.releaseId);
|
|
41958
|
-
|
|
41995
|
+
rmSync8(dest, { recursive: true, force: true });
|
|
41959
41996
|
let bytes2 = 0;
|
|
41960
41997
|
for (const entry of all) {
|
|
41961
41998
|
const target = join39(dest, entry.path);
|
|
41962
|
-
|
|
41963
|
-
|
|
41999
|
+
mkdirSync20(dirname24(target), { recursive: true });
|
|
42000
|
+
writeFileSync16(target, entry.bytes);
|
|
41964
42001
|
bytes2 += entry.bytes.length;
|
|
41965
42002
|
}
|
|
41966
42003
|
return { app, releaseId: header.releaseId, header, out: dest, bytes: bytes2, entryCount: all.length, skipped };
|
|
@@ -42038,11 +42075,11 @@ function unpackTo(buf, dest, appFallback) {
|
|
|
42038
42075
|
if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
|
|
42039
42076
|
const root = resolve37(dest);
|
|
42040
42077
|
const appDir2 = join39(root, app);
|
|
42041
|
-
|
|
42078
|
+
rmSync8(appDir2, { recursive: true, force: true });
|
|
42042
42079
|
for (const [rel, bytes2] of entries) {
|
|
42043
42080
|
const target = join39(appDir2, rel);
|
|
42044
|
-
|
|
42045
|
-
|
|
42081
|
+
mkdirSync20(dirname24(target), { recursive: true });
|
|
42082
|
+
writeFileSync16(target, bytes2);
|
|
42046
42083
|
}
|
|
42047
42084
|
return { root, appDir: appDir2, app };
|
|
42048
42085
|
}
|
|
@@ -42076,14 +42113,14 @@ __export(app_source_exports, {
|
|
|
42076
42113
|
writeConflicts: () => writeConflicts,
|
|
42077
42114
|
zipAppSource: () => zipAppSource
|
|
42078
42115
|
});
|
|
42079
|
-
import { readdirSync as readdirSync23, lstatSync as
|
|
42116
|
+
import { readdirSync as readdirSync23, lstatSync as lstatSync6, readFileSync as readFileSync47, mkdirSync as mkdirSync21, writeFileSync as writeFileSync17, existsSync as existsSync43, rmSync as rmSync9, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
42080
42117
|
import { join as join40, resolve as resolve38, sep as sep10 } from "node:path";
|
|
42081
42118
|
import { deflateRawSync as deflateRawSync2 } from "node:zlib";
|
|
42082
42119
|
function walkSourceTree(dir, file, skip) {
|
|
42083
42120
|
const walk2 = (relDir) => {
|
|
42084
42121
|
for (const name of readdirSync23(join40(dir, relDir))) {
|
|
42085
42122
|
const rel = relDir ? join40(relDir, name) : name;
|
|
42086
|
-
const st =
|
|
42123
|
+
const st = lstatSync6(join40(dir, rel));
|
|
42087
42124
|
if (st.isSymbolicLink()) {
|
|
42088
42125
|
skip(rel);
|
|
42089
42126
|
continue;
|
|
@@ -42142,7 +42179,7 @@ function readAppSource(zip) {
|
|
|
42142
42179
|
}
|
|
42143
42180
|
function pathKind(p) {
|
|
42144
42181
|
try {
|
|
42145
|
-
return
|
|
42182
|
+
return lstatSync6(p);
|
|
42146
42183
|
} catch {
|
|
42147
42184
|
return null;
|
|
42148
42185
|
}
|
|
@@ -42154,7 +42191,7 @@ function writeAppSource(entries, destDir) {
|
|
|
42154
42191
|
`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.`
|
|
42155
42192
|
);
|
|
42156
42193
|
}
|
|
42157
|
-
|
|
42194
|
+
mkdirSync21(root, { recursive: true });
|
|
42158
42195
|
const written = [];
|
|
42159
42196
|
for (const entry of entries) {
|
|
42160
42197
|
if (isDeniedSourcePath(entry.path)) continue;
|
|
@@ -42165,11 +42202,11 @@ function writeAppSource(entries, destDir) {
|
|
|
42165
42202
|
const kind = pathKind(dir);
|
|
42166
42203
|
if (kind?.isSymbolicLink()) unlinkSync3(dir);
|
|
42167
42204
|
else if (kind) continue;
|
|
42168
|
-
|
|
42205
|
+
mkdirSync21(dir);
|
|
42169
42206
|
}
|
|
42170
42207
|
const target = join40(root, ...segments);
|
|
42171
42208
|
if (pathKind(target)?.isSymbolicLink()) unlinkSync3(target);
|
|
42172
|
-
|
|
42209
|
+
writeFileSync17(target, entry.bytes);
|
|
42173
42210
|
written.push(entry.path);
|
|
42174
42211
|
}
|
|
42175
42212
|
return written;
|
|
@@ -42224,7 +42261,7 @@ function writeConflicts(entries, destDir) {
|
|
|
42224
42261
|
function removeStaleSource(entries, destDir) {
|
|
42225
42262
|
const root = resolve38(destDir);
|
|
42226
42263
|
const removed = staleSourcePaths(entries, root);
|
|
42227
|
-
for (const rel of removed)
|
|
42264
|
+
for (const rel of removed) rmSync9(join40(root, ...rel.split("/")), { force: true });
|
|
42228
42265
|
const needed = /* @__PURE__ */ new Set();
|
|
42229
42266
|
for (const entry of entries) {
|
|
42230
42267
|
if (isDeniedSourcePath(entry.path)) continue;
|
|
@@ -42239,7 +42276,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
|
|
|
42239
42276
|
for (const name of readdirSync23(rel ? join40(root, rel) : root)) {
|
|
42240
42277
|
const childRel = rel ? join40(rel, name) : name;
|
|
42241
42278
|
const posix3 = childRel.split(sep10).join("/");
|
|
42242
|
-
const kind =
|
|
42279
|
+
const kind = lstatSync6(join40(root, childRel));
|
|
42243
42280
|
if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name, rel)) {
|
|
42244
42281
|
empty = false;
|
|
42245
42282
|
continue;
|
|
@@ -42304,7 +42341,7 @@ __export(eject_exports, {
|
|
|
42304
42341
|
EJECTABLE: () => EJECTABLE,
|
|
42305
42342
|
ejectModule: () => ejectModule
|
|
42306
42343
|
});
|
|
42307
|
-
import { existsSync as existsSync44, mkdirSync as
|
|
42344
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync22, readFileSync as readFileSync48, writeFileSync as writeFileSync18 } from "node:fs";
|
|
42308
42345
|
import { dirname as dirname25, join as join41, relative as relative7, resolve as resolve39, sep as sep11 } from "node:path";
|
|
42309
42346
|
function locate(repoRootOrCwd, mod) {
|
|
42310
42347
|
const inRepo = resolve39(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
@@ -42335,7 +42372,7 @@ function ejectModule(opts) {
|
|
|
42335
42372
|
}
|
|
42336
42373
|
const ext = found.form === "source" ? "ts" : "mjs";
|
|
42337
42374
|
const target = join41(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
|
|
42338
|
-
|
|
42375
|
+
mkdirSync22(dirname25(target), { recursive: true });
|
|
42339
42376
|
const banner = `// EJECTED from @wix/himalaya/${mod}. This app owns this file now.
|
|
42340
42377
|
//
|
|
42341
42378
|
// Central fixes to @wix/himalaya/${mod} NO LONGER REACH THIS APP \u2014 including any
|
|
@@ -42352,7 +42389,7 @@ function ejectModule(opts) {
|
|
|
42352
42389
|
/(["'])@himalaya\/([a-z0-9-]+(?:\/[a-z0-9-]+)?)\1/g,
|
|
42353
42390
|
(_m, q, sub) => `${q}@wix/himalaya/${sub}${q}`
|
|
42354
42391
|
);
|
|
42355
|
-
|
|
42392
|
+
writeFileSync18(target, banner + normalized);
|
|
42356
42393
|
const rewired = [];
|
|
42357
42394
|
for (const f of files) {
|
|
42358
42395
|
if (!existsSync44(f)) continue;
|
|
@@ -42368,7 +42405,7 @@ function ejectModule(opts) {
|
|
|
42368
42405
|
);
|
|
42369
42406
|
}
|
|
42370
42407
|
if (after !== before) {
|
|
42371
|
-
|
|
42408
|
+
writeFileSync18(f, after);
|
|
42372
42409
|
rewired.push(f);
|
|
42373
42410
|
}
|
|
42374
42411
|
}
|
|
@@ -42404,7 +42441,7 @@ __export(test_exports, {
|
|
|
42404
42441
|
scopeDescriptors: () => scopeDescriptors,
|
|
42405
42442
|
writeRecordedMocks: () => writeRecordedMocks
|
|
42406
42443
|
});
|
|
42407
|
-
import { existsSync as existsSync45, mkdirSync as
|
|
42444
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync23, readFileSync as readFileSync49, writeFileSync as writeFileSync19 } from "node:fs";
|
|
42408
42445
|
import { join as join42, resolve as resolve40 } from "node:path";
|
|
42409
42446
|
function readTestConfig(dir) {
|
|
42410
42447
|
const p = resolve40(dir, TEST_CONFIG_FILE);
|
|
@@ -42580,8 +42617,8 @@ function writeRecordedMocks(opts) {
|
|
|
42580
42617
|
};
|
|
42581
42618
|
}
|
|
42582
42619
|
const fs = opts.io ?? {
|
|
42583
|
-
mkdir: (p) =>
|
|
42584
|
-
write: (p, s) =>
|
|
42620
|
+
mkdir: (p) => mkdirSync23(p, { recursive: true }),
|
|
42621
|
+
write: (p, s) => writeFileSync19(p, s)
|
|
42585
42622
|
};
|
|
42586
42623
|
fs.mkdir(join42(opts.dir, "dev"));
|
|
42587
42624
|
fs.write(join42(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
|
|
@@ -43342,7 +43379,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
43342
43379
|
const headers2 = Object.fromEntries(new Headers(init.headers).entries());
|
|
43343
43380
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
43344
43381
|
const hostname2 = url.hostname.replace(/^\[|\]$/g, "");
|
|
43345
|
-
return await new Promise((
|
|
43382
|
+
return await new Promise((resolve48, reject) => {
|
|
43346
43383
|
let settled = false;
|
|
43347
43384
|
const finish2 = (fn) => {
|
|
43348
43385
|
if (settled) return;
|
|
@@ -43379,7 +43416,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
|
|
|
43379
43416
|
}
|
|
43380
43417
|
const responseHeaders = new Headers();
|
|
43381
43418
|
for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
|
|
43382
|
-
|
|
43419
|
+
resolve48(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
|
|
43383
43420
|
}));
|
|
43384
43421
|
});
|
|
43385
43422
|
req.once("error", (error) => finish2(() => reject(error)));
|
|
@@ -43679,7 +43716,7 @@ function createLocalTestSandbox() {
|
|
|
43679
43716
|
}
|
|
43680
43717
|
})();
|
|
43681
43718
|
`;
|
|
43682
|
-
return await new Promise((
|
|
43719
|
+
return await new Promise((resolve48, reject) => {
|
|
43683
43720
|
const { port1, port2 } = new MessageChannel();
|
|
43684
43721
|
const serializableContext = {
|
|
43685
43722
|
auth: context.auth,
|
|
@@ -43755,7 +43792,7 @@ function createLocalTestSandbox() {
|
|
|
43755
43792
|
timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
|
|
43756
43793
|
return;
|
|
43757
43794
|
}
|
|
43758
|
-
if (message.ok) finish2(() =>
|
|
43795
|
+
if (message.ok) finish2(() => resolve48({ value: message.value, durationMs: Date.now() - started }));
|
|
43759
43796
|
else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
|
|
43760
43797
|
});
|
|
43761
43798
|
worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
|
|
@@ -44900,7 +44937,7 @@ __export(native_decode_exports, {
|
|
|
44900
44937
|
runNativeDecode: () => runNativeDecode
|
|
44901
44938
|
});
|
|
44902
44939
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
44903
|
-
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync52, rmSync as
|
|
44940
|
+
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync52, rmSync as rmSync10, writeFileSync as writeFileSync20 } from "node:fs";
|
|
44904
44941
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
44905
44942
|
import { join as join45 } from "node:path";
|
|
44906
44943
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
@@ -45034,7 +45071,7 @@ function runNativeDecode(options) {
|
|
|
45034
45071
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
45035
45072
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
45036
45073
|
}
|
|
45037
|
-
|
|
45074
|
+
writeFileSync20(join45(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
45038
45075
|
}
|
|
45039
45076
|
options.progress?.("building cached Swift oracle");
|
|
45040
45077
|
execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
|
|
@@ -45060,7 +45097,7 @@ function runNativeDecode(options) {
|
|
|
45060
45097
|
const stderr = failure.stderr ? ` \u2014 ${String(failure.stderr).trim().slice(0, 2e3)}` : "";
|
|
45061
45098
|
throw new Error(`iOS decoder oracle failed: ${failure.message}${stderr}`);
|
|
45062
45099
|
} finally {
|
|
45063
|
-
|
|
45100
|
+
rmSync10(descriptorDir, { recursive: true, force: true });
|
|
45064
45101
|
}
|
|
45065
45102
|
}
|
|
45066
45103
|
function runAndroidNativeDecode(options) {
|
|
@@ -45072,7 +45109,7 @@ function runAndroidNativeDecode(options) {
|
|
|
45072
45109
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
45073
45110
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
45074
45111
|
}
|
|
45075
|
-
|
|
45112
|
+
writeFileSync20(join45(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
45076
45113
|
}
|
|
45077
45114
|
options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
45078
45115
|
execFileSync5(options.gradlew, [
|
|
@@ -45098,7 +45135,7 @@ function runAndroidNativeDecode(options) {
|
|
|
45098
45135
|
const stderr = failure.stderr ? ` \u2014 ${String(failure.stderr).trim().slice(0, 2e3)}` : "";
|
|
45099
45136
|
throw new Error(`Android decoder oracle failed: ${failure.message}${stderr}`);
|
|
45100
45137
|
} finally {
|
|
45101
|
-
|
|
45138
|
+
rmSync10(descriptorDir, { recursive: true, force: true });
|
|
45102
45139
|
}
|
|
45103
45140
|
}
|
|
45104
45141
|
function fieldAt(path2) {
|
|
@@ -45242,10 +45279,10 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
45242
45279
|
for (const source of Object.values(files)) visit(source);
|
|
45243
45280
|
return { modules, unsupported };
|
|
45244
45281
|
}
|
|
45245
|
-
function sdkSubpathReader(
|
|
45282
|
+
function sdkSubpathReader(resolve48) {
|
|
45246
45283
|
return (sub) => {
|
|
45247
45284
|
try {
|
|
45248
|
-
return readFileSync53(
|
|
45285
|
+
return readFileSync53(resolve48(`@wix/himalaya/${sub}`), "utf8");
|
|
45249
45286
|
} catch {
|
|
45250
45287
|
return null;
|
|
45251
45288
|
}
|
|
@@ -45323,7 +45360,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
45323
45360
|
const token = mintToken2(payload);
|
|
45324
45361
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
45325
45362
|
if (unusable) throw new Error(unusable);
|
|
45326
|
-
return await new Promise((
|
|
45363
|
+
return await new Promise((resolve48, reject) => {
|
|
45327
45364
|
let settled = false;
|
|
45328
45365
|
let url = "";
|
|
45329
45366
|
const server = createServer3();
|
|
@@ -45375,7 +45412,7 @@ async function runBrowserAuthoring(opts) {
|
|
|
45375
45412
|
}
|
|
45376
45413
|
res.writeHead(200, { "content-type": "text/plain" }).end("ok");
|
|
45377
45414
|
const report2 = body.result;
|
|
45378
|
-
finish2(() =>
|
|
45415
|
+
finish2(() => resolve48({ report: report2, url }));
|
|
45379
45416
|
})();
|
|
45380
45417
|
});
|
|
45381
45418
|
server.on("error", (e) => finish2(() => reject(e)));
|
|
@@ -45417,7 +45454,7 @@ __export(coverage_exports, {
|
|
|
45417
45454
|
suppressedNativeKeys: () => suppressedNativeKeys,
|
|
45418
45455
|
trendAndStore: () => trendAndStore
|
|
45419
45456
|
});
|
|
45420
|
-
import { existsSync as existsSync50, mkdirSync as
|
|
45457
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync24, readFileSync as readFileSync54, writeFileSync as writeFileSync21 } from "node:fs";
|
|
45421
45458
|
import { dirname as dirname26, join as join47 } from "node:path";
|
|
45422
45459
|
function suppressedNativeKeys(oracle) {
|
|
45423
45460
|
return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
|
|
@@ -45600,8 +45637,8 @@ function trendAndStore(dir, entries, suppressed) {
|
|
|
45600
45637
|
const current = entries.map((e) => e.key);
|
|
45601
45638
|
const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key2) => (suppressed ?? []).includes(key2))])];
|
|
45602
45639
|
try {
|
|
45603
|
-
|
|
45604
|
-
|
|
45640
|
+
mkdirSync24(dirname26(p), { recursive: true });
|
|
45641
|
+
writeFileSync21(p, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
45605
45642
|
} catch {
|
|
45606
45643
|
return null;
|
|
45607
45644
|
}
|
|
@@ -45645,8 +45682,8 @@ function diffAndStoreObservations(dir, current) {
|
|
|
45645
45682
|
} catch {
|
|
45646
45683
|
}
|
|
45647
45684
|
try {
|
|
45648
|
-
|
|
45649
|
-
|
|
45685
|
+
mkdirSync24(dirname26(p), { recursive: true });
|
|
45686
|
+
writeFileSync21(p, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
45650
45687
|
} catch {
|
|
45651
45688
|
return null;
|
|
45652
45689
|
}
|
|
@@ -46116,6 +46153,15 @@ function json3(status, body, headers2 = {}) {
|
|
|
46116
46153
|
function isCookieAuthorizedPath(path2) {
|
|
46117
46154
|
return path2 === "/v1/__webwix/call" || path2 === "/v1/owner" || path2.startsWith("/v1/owner/") || path2 === "/v1/__webwix/identity" || path2 === "/v1/__webwix/login" || path2 === "/v1/__webwix/register" || path2 === "/v1/__webwix/logout" || path2 === MEMBER_CALLBACK_PATH;
|
|
46118
46155
|
}
|
|
46156
|
+
function webwixCallLog(served, status) {
|
|
46157
|
+
const directRung = served.rung === "visitor" || served.rung === "owner";
|
|
46158
|
+
return {
|
|
46159
|
+
rung: served.rung,
|
|
46160
|
+
...directRung ? { fallback: served.fallback === true } : {},
|
|
46161
|
+
...served.app ? { app: served.app } : {},
|
|
46162
|
+
status
|
|
46163
|
+
};
|
|
46164
|
+
}
|
|
46119
46165
|
function makeServeHandler(opts) {
|
|
46120
46166
|
let storePromise = null;
|
|
46121
46167
|
const getStore = () => storePromise ??= (async () => {
|
|
@@ -46422,83 +46468,109 @@ ${releaseId}`;
|
|
|
46422
46468
|
return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
|
|
46423
46469
|
}
|
|
46424
46470
|
if (request.method === "POST" && path2 === "/v1/__webwix/call") {
|
|
46425
|
-
|
|
46426
|
-
|
|
46427
|
-
}
|
|
46428
|
-
const app2 = resolveApp(request, url);
|
|
46429
|
-
if (!app2) return json3(400, { error: "app_required" });
|
|
46430
|
-
const resolvedCfg = await appConfigFor(request, url, app2);
|
|
46431
|
-
if (!resolvedCfg.ok) return resolvedCfg.response;
|
|
46432
|
-
const cfgBytes = resolvedCfg.bytes;
|
|
46433
|
-
let call;
|
|
46471
|
+
const served = { rung: "none" };
|
|
46472
|
+
let status = 500;
|
|
46434
46473
|
try {
|
|
46435
|
-
|
|
46436
|
-
|
|
46437
|
-
|
|
46438
|
-
|
|
46439
|
-
|
|
46440
|
-
|
|
46441
|
-
|
|
46442
|
-
|
|
46443
|
-
|
|
46444
|
-
|
|
46445
|
-
|
|
46446
|
-
|
|
46447
|
-
|
|
46448
|
-
|
|
46449
|
-
|
|
46450
|
-
if (envelope.status >= 200 && envelope.status < 300) return json3(200, envelope);
|
|
46451
|
-
return json3(200, {
|
|
46452
|
-
status: 501,
|
|
46453
|
-
body: JSON.stringify({ error: "webwix_owner_sites_failed", upstream: envelope.status })
|
|
46454
|
-
});
|
|
46455
|
-
} catch (e) {
|
|
46456
|
-
return json3(200, {
|
|
46457
|
-
status: 501,
|
|
46458
|
-
body: JSON.stringify({ error: "webwix_owner_sites_failed", detail: String(e?.message ?? e).slice(0, 200) })
|
|
46459
|
-
});
|
|
46460
|
-
}
|
|
46461
|
-
}
|
|
46462
|
-
if (call.ownerMsid !== void 0) {
|
|
46463
|
-
if (!webwixOwnerRungOn()) {
|
|
46464
|
-
return json3(503, { error: "webwix_owner_disabled" });
|
|
46465
|
-
}
|
|
46466
|
-
const msid = String(call.ownerMsid);
|
|
46467
|
-
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
46468
|
-
const cookie = request.headers.get("cookie") ?? "";
|
|
46469
|
-
if (!/wixSession2=/.test(cookie)) return json3(501, { error: "webwix_owner_no_session", app: app2 });
|
|
46470
|
-
try {
|
|
46471
|
-
const instance = await webwixOwnerInstances.instance(msid, cookie);
|
|
46472
|
-
if (call.checkOwnerSession === true) return json3(200, { status: 200, body: JSON.stringify({ ready: true }) }, { "cache-control": "no-store" });
|
|
46473
|
-
const first = await wixVisitorCall(method, reqPath, body, instance, webwixFetch, forwardedHeaders);
|
|
46474
|
-
if (first.status !== 401) return json3(200, first);
|
|
46475
|
-
webwixOwnerInstances.invalidate(msid, cookie);
|
|
46476
|
-
const fresh = await webwixOwnerInstances.instance(msid, cookie);
|
|
46477
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46478
|
-
} catch (e) {
|
|
46479
|
-
const msg = String(e?.message ?? e);
|
|
46480
|
-
if (msg.includes("absolute URLs")) {
|
|
46481
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
46474
|
+
const res = await (async () => {
|
|
46475
|
+
if (opts.webwixBridge === false) {
|
|
46476
|
+
return json3(503, { error: "webwix_bridge_disabled" });
|
|
46477
|
+
}
|
|
46478
|
+
const app2 = resolveApp(request, url);
|
|
46479
|
+
if (!app2) return json3(400, { error: "app_required" });
|
|
46480
|
+
const resolvedCfg = await appConfigFor(request, url, app2);
|
|
46481
|
+
if (!resolvedCfg.ok) return resolvedCfg.response;
|
|
46482
|
+
served.app = app2;
|
|
46483
|
+
const cfgBytes = resolvedCfg.bytes;
|
|
46484
|
+
let call;
|
|
46485
|
+
try {
|
|
46486
|
+
call = await request.json();
|
|
46487
|
+
} catch {
|
|
46488
|
+
return json3(400, { error: "invalid_json" });
|
|
46482
46489
|
}
|
|
46483
|
-
|
|
46484
|
-
|
|
46485
|
-
return json3(
|
|
46490
|
+
served.fallback = call.fallback === true;
|
|
46491
|
+
if (call.checkOwnerSession !== void 0 && (typeof call.checkOwnerSession !== "boolean" || call.checkOwnerSession && call.ownerMsid === void 0)) {
|
|
46492
|
+
return json3(400, { error: "invalid_owner_session_check" });
|
|
46493
|
+
}
|
|
46494
|
+
const method = String(call.method ?? "GET").toUpperCase();
|
|
46495
|
+
const reqPath = String(call.path ?? "/");
|
|
46496
|
+
const body = call.body === void 0 ? void 0 : typeof call.body === "string" ? call.body : JSON.stringify(call.body);
|
|
46497
|
+
const forwardedHeaders = normalizeWixForwardedHeaders(call.headers);
|
|
46498
|
+
const callerCookie = request.headers.get("cookie") ?? "";
|
|
46499
|
+
if (!call.checkOwnerSession && webwixOwnerRungOn() && method === "POST" && isOwnerSitesPath(reqPath) && /wixSession2=/.test(callerCookie)) {
|
|
46500
|
+
served.rung = "sites";
|
|
46501
|
+
try {
|
|
46502
|
+
const envelope = await wixOwnerSitesCall(reqPath, callerCookie, body, webwixFetch);
|
|
46503
|
+
if (envelope.status >= 200 && envelope.status < 300) return json3(200, envelope);
|
|
46504
|
+
return json3(200, {
|
|
46505
|
+
status: 501,
|
|
46506
|
+
body: JSON.stringify({ error: "webwix_owner_sites_failed", upstream: envelope.status })
|
|
46507
|
+
});
|
|
46508
|
+
} catch (e) {
|
|
46509
|
+
return json3(200, {
|
|
46510
|
+
status: 501,
|
|
46511
|
+
body: JSON.stringify({ error: "webwix_owner_sites_failed", detail: String(e?.message ?? e).slice(0, 200) })
|
|
46512
|
+
});
|
|
46513
|
+
}
|
|
46514
|
+
}
|
|
46515
|
+
if (call.ownerMsid !== void 0) {
|
|
46516
|
+
served.rung = call.checkOwnerSession === true ? "gate" : "owner";
|
|
46517
|
+
if (!webwixOwnerRungOn()) {
|
|
46518
|
+
return json3(503, { error: "webwix_owner_disabled" });
|
|
46519
|
+
}
|
|
46520
|
+
const msid = String(call.ownerMsid);
|
|
46521
|
+
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
46522
|
+
const cookie = request.headers.get("cookie") ?? "";
|
|
46523
|
+
if (!/wixSession2=/.test(cookie)) return json3(501, { error: "webwix_owner_no_session", app: app2 });
|
|
46524
|
+
try {
|
|
46525
|
+
const instance = await webwixOwnerInstances.instance(msid, cookie);
|
|
46526
|
+
if (call.checkOwnerSession === true) return json3(200, { status: 200, body: JSON.stringify({ ready: true }) }, { "cache-control": "no-store" });
|
|
46527
|
+
const first = await wixVisitorCall(method, reqPath, body, instance, webwixFetch, forwardedHeaders);
|
|
46528
|
+
if (first.status !== 401) return json3(200, first);
|
|
46529
|
+
webwixOwnerInstances.invalidate(msid, cookie);
|
|
46530
|
+
const fresh = await webwixOwnerInstances.instance(msid, cookie);
|
|
46531
|
+
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46532
|
+
} catch (e) {
|
|
46533
|
+
const msg = String(e?.message ?? e);
|
|
46534
|
+
if (msg.includes("absolute URLs")) {
|
|
46535
|
+
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
46536
|
+
}
|
|
46537
|
+
if (msg.includes("owner mint failed")) {
|
|
46538
|
+
if (/owner mint failed \(5\d\d\)/.test(msg)) return json3(502, { error: "webwix_bridge_upstream_failed" });
|
|
46539
|
+
return json3(501, { error: "webwix_owner_mint_failed", app: app2 });
|
|
46540
|
+
}
|
|
46541
|
+
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46542
|
+
}
|
|
46543
|
+
}
|
|
46544
|
+
const resolved2 = wixClientIdOf(utf8Decode(cfgBytes));
|
|
46545
|
+
if ("error" in resolved2) {
|
|
46546
|
+
return json3(501, { error: `webwix_bridge_${resolved2.error}`, app: app2 });
|
|
46547
|
+
}
|
|
46548
|
+
served.rung = "visitor";
|
|
46549
|
+
const memberStore = memberSessions();
|
|
46550
|
+
const memberBoundApp = memberApp(request);
|
|
46551
|
+
if (memberAuthOn() && memberStore && memberBoundApp !== null && memberBoundApp === app2) {
|
|
46552
|
+
const nowAuth = wixMemberAuthOf(utf8Decode(cfgBytes), callbackUrlFor(url));
|
|
46553
|
+
const memberToken = nowAuth.ok ? await memberTokenFor(memberStore, readSessionCookie(request.headers.get("cookie")), memberBoundApp, nowAuth.config.clientId) : null;
|
|
46554
|
+
if (memberToken) {
|
|
46555
|
+
served.rung = "member";
|
|
46556
|
+
try {
|
|
46557
|
+
return json3(200, await wixVisitorCall(method, reqPath, body, memberToken, webwixFetch, forwardedHeaders), { "cache-control": "no-store" });
|
|
46558
|
+
} catch (e) {
|
|
46559
|
+
const msg = String(e?.message ?? e);
|
|
46560
|
+
if (msg.includes("absolute URLs")) {
|
|
46561
|
+
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
46562
|
+
}
|
|
46563
|
+
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46564
|
+
}
|
|
46565
|
+
}
|
|
46486
46566
|
}
|
|
46487
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46488
|
-
}
|
|
46489
|
-
}
|
|
46490
|
-
const resolved2 = wixClientIdOf(utf8Decode(cfgBytes));
|
|
46491
|
-
if ("error" in resolved2) {
|
|
46492
|
-
return json3(501, { error: `webwix_bridge_${resolved2.error}`, app: app2 });
|
|
46493
|
-
}
|
|
46494
|
-
const memberStore = memberSessions();
|
|
46495
|
-
const memberBoundApp = memberApp(request);
|
|
46496
|
-
if (memberAuthOn() && memberStore && memberBoundApp !== null && memberBoundApp === app2) {
|
|
46497
|
-
const nowAuth = wixMemberAuthOf(utf8Decode(cfgBytes), callbackUrlFor(url));
|
|
46498
|
-
const memberToken = nowAuth.ok ? await memberTokenFor(memberStore, readSessionCookie(request.headers.get("cookie")), memberBoundApp, nowAuth.config.clientId) : null;
|
|
46499
|
-
if (memberToken) {
|
|
46500
46567
|
try {
|
|
46501
|
-
|
|
46568
|
+
const token = await webwixTokens.token(resolved2.clientId);
|
|
46569
|
+
const first = await wixVisitorCall(method, reqPath, body, token, webwixFetch, forwardedHeaders);
|
|
46570
|
+
if (first.status !== 401) return json3(200, first);
|
|
46571
|
+
webwixTokens.invalidate(resolved2.clientId);
|
|
46572
|
+
const fresh = await webwixTokens.token(resolved2.clientId);
|
|
46573
|
+
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46502
46574
|
} catch (e) {
|
|
46503
46575
|
const msg = String(e?.message ?? e);
|
|
46504
46576
|
if (msg.includes("absolute URLs")) {
|
|
@@ -46506,22 +46578,15 @@ ${releaseId}`;
|
|
|
46506
46578
|
}
|
|
46507
46579
|
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46508
46580
|
}
|
|
46581
|
+
})();
|
|
46582
|
+
status = res.status;
|
|
46583
|
+
return res;
|
|
46584
|
+
} finally {
|
|
46585
|
+
try {
|
|
46586
|
+
opts.onWebwixCall?.(webwixCallLog(served, status));
|
|
46587
|
+
} catch {
|
|
46509
46588
|
}
|
|
46510
46589
|
}
|
|
46511
|
-
try {
|
|
46512
|
-
const token = await webwixTokens.token(resolved2.clientId);
|
|
46513
|
-
const first = await wixVisitorCall(method, reqPath, body, token, webwixFetch, forwardedHeaders);
|
|
46514
|
-
if (first.status !== 401) return json3(200, first);
|
|
46515
|
-
webwixTokens.invalidate(resolved2.clientId);
|
|
46516
|
-
const fresh = await webwixTokens.token(resolved2.clientId);
|
|
46517
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46518
|
-
} catch (e) {
|
|
46519
|
-
const msg = String(e?.message ?? e);
|
|
46520
|
-
if (msg.includes("absolute URLs")) {
|
|
46521
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
46522
|
-
}
|
|
46523
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46524
|
-
}
|
|
46525
46590
|
}
|
|
46526
46591
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
46527
46592
|
if (path2 === "/__health") return json3(200, { ok: true });
|
|
@@ -46556,6 +46621,11 @@ ${releaseId}`;
|
|
|
46556
46621
|
}
|
|
46557
46622
|
if (path2 === "/v1/owner/instance") {
|
|
46558
46623
|
if (opts.webwixBridge === false) return json3(503, { error: "webwix_bridge_disabled" });
|
|
46624
|
+
const gateApp = url.searchParams.get("app");
|
|
46625
|
+
if (gateApp) {
|
|
46626
|
+
const cfg = await appConfigFor(request, url, gateApp);
|
|
46627
|
+
if (!cfg.ok) return cfg.response;
|
|
46628
|
+
}
|
|
46559
46629
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
46560
46630
|
const msid = url.searchParams.get("msid") ?? "";
|
|
46561
46631
|
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
@@ -47214,8 +47284,29 @@ function makeRunHandler(opts) {
|
|
|
47214
47284
|
return new Response(null, { status: 204 });
|
|
47215
47285
|
}
|
|
47216
47286
|
if (path2 === "/v1/screen-events") {
|
|
47217
|
-
|
|
47218
|
-
|
|
47287
|
+
const source = opts.screenEvents;
|
|
47288
|
+
let unsubscribe;
|
|
47289
|
+
const body = new ReadableStream({
|
|
47290
|
+
start(controller) {
|
|
47291
|
+
if (!source) return;
|
|
47292
|
+
const encoder = new TextEncoder();
|
|
47293
|
+
controller.enqueue(encoder.encode(": himi run --watch\n\n"));
|
|
47294
|
+
unsubscribe = source.subscribe((event, data) => {
|
|
47295
|
+
try {
|
|
47296
|
+
controller.enqueue(encoder.encode(`event: ${event}
|
|
47297
|
+
data: ${JSON.stringify(data ?? {})}
|
|
47298
|
+
|
|
47299
|
+
`));
|
|
47300
|
+
} catch {
|
|
47301
|
+
unsubscribe?.();
|
|
47302
|
+
}
|
|
47303
|
+
});
|
|
47304
|
+
},
|
|
47305
|
+
cancel() {
|
|
47306
|
+
unsubscribe?.();
|
|
47307
|
+
}
|
|
47308
|
+
});
|
|
47309
|
+
return new Response(body, {
|
|
47219
47310
|
status: 200,
|
|
47220
47311
|
headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
|
|
47221
47312
|
});
|
|
@@ -47278,6 +47369,24 @@ async function toRequest(req) {
|
|
|
47278
47369
|
async function writeResponse(res, response) {
|
|
47279
47370
|
res.statusCode = response.status;
|
|
47280
47371
|
response.headers.forEach((value, key2) => res.setHeader(key2, value));
|
|
47372
|
+
if (response.body && /^text\/event-stream\b/i.test(response.headers.get("content-type") ?? "")) {
|
|
47373
|
+
res.flushHeaders();
|
|
47374
|
+
const reader = response.body.getReader();
|
|
47375
|
+
res.on("close", () => {
|
|
47376
|
+
void reader.cancel().catch(() => {
|
|
47377
|
+
});
|
|
47378
|
+
});
|
|
47379
|
+
try {
|
|
47380
|
+
for (; ; ) {
|
|
47381
|
+
const { done, value } = await reader.read();
|
|
47382
|
+
if (done) break;
|
|
47383
|
+
res.write(value);
|
|
47384
|
+
}
|
|
47385
|
+
} catch {
|
|
47386
|
+
}
|
|
47387
|
+
res.end();
|
|
47388
|
+
return;
|
|
47389
|
+
}
|
|
47281
47390
|
const ab = await response.arrayBuffer();
|
|
47282
47391
|
res.end(ab.byteLength ? Buffer.from(ab) : void 0);
|
|
47283
47392
|
}
|
|
@@ -47340,19 +47449,19 @@ var init_preview_assets_generated = __esm({
|
|
|
47340
47449
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
47341
47450
|
init_preview_assets_format();
|
|
47342
47451
|
PREVIEW_ASSET_MANIFEST = [
|
|
47343
|
-
{ key: "assets/index-
|
|
47344
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
47345
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47346
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
47347
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
47348
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47349
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
47350
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47351
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
47352
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
47353
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47354
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
47355
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
47452
|
+
{ key: "assets/index-TpXF5JLO.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1013412, sha256: "e6d1da59c13ca586b7834f4d08ca9e136b7fea8be9355d952d757fc66fc779a5" },
|
|
47453
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1013420, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
47454
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1104344, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
47455
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1195328, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
47456
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1286308, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
47457
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1377180, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
47458
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1468160, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
47459
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1576796, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
47460
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1685880, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
47461
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1794928, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
47462
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1902628, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
47463
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 1990736, length: 4448, sha256: "5f0ee56640a5dfc73d3b2b78526aa1f7966de1bec39fe746e0d9ba39d57d829e" },
|
|
47464
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1995184, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
47356
47465
|
];
|
|
47357
47466
|
}
|
|
47358
47467
|
});
|
|
@@ -47368,7 +47477,7 @@ __export(run_exports, {
|
|
|
47368
47477
|
runPackage: () => runPackage,
|
|
47369
47478
|
withoutProdServe: () => withoutProdServe
|
|
47370
47479
|
});
|
|
47371
|
-
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as
|
|
47480
|
+
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync57, rmSync as rmSync11, statSync as statSync13 } from "node:fs";
|
|
47372
47481
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
47373
47482
|
import { dirname as dirname27, join as join49 } from "node:path";
|
|
47374
47483
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
@@ -47378,7 +47487,8 @@ function makePackageRunHandler(opts) {
|
|
|
47378
47487
|
app: opts.app,
|
|
47379
47488
|
assets: opts.assets,
|
|
47380
47489
|
...opts.chrome ? { chrome: opts.chrome } : {},
|
|
47381
|
-
header: opts.header ?? null
|
|
47490
|
+
header: opts.header ?? null,
|
|
47491
|
+
...opts.screenEvents ? { screenEvents: opts.screenEvents } : {}
|
|
47382
47492
|
});
|
|
47383
47493
|
}
|
|
47384
47494
|
async function fetchBytes(url) {
|
|
@@ -47402,8 +47512,8 @@ async function resolvePackage(source, workDir) {
|
|
|
47402
47512
|
const root2 = workDir ?? mkdtempSync3(join49(tmpdir4(), "himi-run-"));
|
|
47403
47513
|
const target = join49(root2, app2);
|
|
47404
47514
|
if (join49(source) !== target) {
|
|
47405
|
-
|
|
47406
|
-
|
|
47515
|
+
mkdirSync25(root2, { recursive: true });
|
|
47516
|
+
rmSync11(target, { recursive: true, force: true });
|
|
47407
47517
|
cpSync2(source, target, { recursive: true });
|
|
47408
47518
|
}
|
|
47409
47519
|
return {
|
|
@@ -47423,7 +47533,7 @@ async function resolvePackage(source, workDir) {
|
|
|
47423
47533
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
47424
47534
|
const opened = openPackageDir(appDir2);
|
|
47425
47535
|
if (!opened.validation.ok) {
|
|
47426
|
-
|
|
47536
|
+
rmSync11(workDir ? appDir2 : root, { recursive: true, force: true });
|
|
47427
47537
|
throw new Error(`package is not valid:
|
|
47428
47538
|
${opened.validation.errors.join("\n ")}`);
|
|
47429
47539
|
}
|
|
@@ -47470,16 +47580,19 @@ async function runPackage(source, opts = {}) {
|
|
|
47470
47580
|
const resolved2 = await resolvePackage(source, opts.workDir);
|
|
47471
47581
|
const assets = opts.assets ?? (opts.spa ? /* @__PURE__ */ new Map() : await loadPreviewAssets());
|
|
47472
47582
|
if (!opts.spa && assets.size === 0) {
|
|
47473
|
-
if (resolved2.temp)
|
|
47583
|
+
if (resolved2.temp) rmSync11(resolved2.temp, { recursive: true, force: true });
|
|
47474
47584
|
throw new Error(NO_SPA_MESSAGE);
|
|
47475
47585
|
}
|
|
47476
|
-
const
|
|
47586
|
+
const plane = makePackageRunHandler({
|
|
47477
47587
|
releaseRoot: resolved2.releaseRoot,
|
|
47478
47588
|
app: resolved2.app,
|
|
47479
47589
|
assets,
|
|
47480
47590
|
chrome: opts.chrome,
|
|
47481
|
-
header: resolved2.header
|
|
47591
|
+
header: resolved2.header,
|
|
47592
|
+
...opts.screenEvents ? { screenEvents: opts.screenEvents } : {}
|
|
47482
47593
|
});
|
|
47594
|
+
const extra = opts.extraRoutes;
|
|
47595
|
+
const handler = extra ? (request) => extra(request) ?? plane(request) : plane;
|
|
47483
47596
|
const server = nodeAdapter(handler);
|
|
47484
47597
|
const host = opts.host ?? "127.0.0.1";
|
|
47485
47598
|
const port = await new Promise((resolvePort, reject) => {
|
|
@@ -47497,10 +47610,13 @@ async function runPackage(source, opts = {}) {
|
|
|
47497
47610
|
releaseId: resolved2.releaseId,
|
|
47498
47611
|
port,
|
|
47499
47612
|
url,
|
|
47613
|
+
releaseRoot: resolved2.releaseRoot,
|
|
47614
|
+
origin,
|
|
47500
47615
|
warnings: resolved2.warnings,
|
|
47501
47616
|
close: () => new Promise((done) => {
|
|
47617
|
+
server.closeAllConnections?.();
|
|
47502
47618
|
server.close(() => {
|
|
47503
|
-
if (resolved2.temp)
|
|
47619
|
+
if (resolved2.temp) rmSync11(resolved2.temp, { recursive: true, force: true });
|
|
47504
47620
|
done();
|
|
47505
47621
|
});
|
|
47506
47622
|
})
|
|
@@ -47520,6 +47636,250 @@ var init_run = __esm({
|
|
|
47520
47636
|
}
|
|
47521
47637
|
});
|
|
47522
47638
|
|
|
47639
|
+
// src/run-watch.ts
|
|
47640
|
+
var run_watch_exports = {};
|
|
47641
|
+
__export(run_watch_exports, {
|
|
47642
|
+
ReloadBus: () => ReloadBus,
|
|
47643
|
+
boardFile: () => boardFile,
|
|
47644
|
+
diffReleases: () => diffReleases,
|
|
47645
|
+
himiDir: () => himiDir,
|
|
47646
|
+
ignoredChange: () => ignoredChange,
|
|
47647
|
+
isEmptyDiff: () => isEmptyDiff,
|
|
47648
|
+
rebuildBlocker: () => rebuildBlocker,
|
|
47649
|
+
reloadEvents: () => reloadEvents,
|
|
47650
|
+
removeRunRecord: () => removeRunRecord,
|
|
47651
|
+
serialize: () => serialize,
|
|
47652
|
+
watchContent: () => watchContent,
|
|
47653
|
+
watchFlagConflict: () => watchFlagConflict,
|
|
47654
|
+
watchedContentDir: () => watchedContentDir,
|
|
47655
|
+
writeRunRecord: () => writeRunRecord
|
|
47656
|
+
});
|
|
47657
|
+
import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync7, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync58, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as rmSync12, writeFileSync as writeFileSync22, watch as fsWatch } from "node:fs";
|
|
47658
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
47659
|
+
import { extname as extname4, join as join50, resolve as resolve42, sep as sep13 } from "node:path";
|
|
47660
|
+
function diffReleases(prev, next) {
|
|
47661
|
+
const bundles = Object.keys(next.bundles).filter((b) => prev.bundles[b]?.sha256 !== next.bundles[b].sha256).sort();
|
|
47662
|
+
const changedBundles = new Set(bundles);
|
|
47663
|
+
const screens = Object.entries(next.screens).filter(([id, s]) => {
|
|
47664
|
+
const before = prev.screens[id];
|
|
47665
|
+
return !before || before.descriptorHash !== s.descriptorHash || before.bundle !== s.bundle || s.bundle !== null && changedBundles.has(s.bundle);
|
|
47666
|
+
}).map(([id]) => id).sort();
|
|
47667
|
+
const prevIds = Object.keys(prev.screens).sort().join("\n");
|
|
47668
|
+
const nextIds = Object.keys(next.screens).sort().join("\n");
|
|
47669
|
+
return {
|
|
47670
|
+
screens,
|
|
47671
|
+
bundles,
|
|
47672
|
+
tokens: prev.tokensHash !== next.tokensHash,
|
|
47673
|
+
config: prev.appConfigHash !== next.appConfigHash || prevIds !== nextIds
|
|
47674
|
+
};
|
|
47675
|
+
}
|
|
47676
|
+
function reloadEvents(d) {
|
|
47677
|
+
const out = [];
|
|
47678
|
+
if (d.bundles.length) out.push(["bundle.invalidated", { bundles: d.bundles }]);
|
|
47679
|
+
if (d.screens.length) out.push(["screen.invalidated", { screenIds: d.screens }]);
|
|
47680
|
+
if (d.tokens) out.push(["tokens.changed", {}]);
|
|
47681
|
+
if (d.config) out.push(["config.invalidated", {}]);
|
|
47682
|
+
return out;
|
|
47683
|
+
}
|
|
47684
|
+
function ignoredChange(relPath, isDirectory = () => false) {
|
|
47685
|
+
const parts = relPath.split(/[\\/]/).filter(Boolean);
|
|
47686
|
+
if (!parts.length) return true;
|
|
47687
|
+
const [top] = parts;
|
|
47688
|
+
if ([".himi", "dist", "node_modules", ".git", ".build"].includes(top)) return true;
|
|
47689
|
+
if ((top === "shots" || top === "evidence") && (parts.length > 1 || isDirectory(top))) return true;
|
|
47690
|
+
const name = parts[parts.length - 1];
|
|
47691
|
+
return /(^\.#|~$|\.sw[a-p]$|^\.DS_Store$|\.tmp$)/.test(name);
|
|
47692
|
+
}
|
|
47693
|
+
function watchContent(dir, onChange, opts = {}) {
|
|
47694
|
+
const debounceMs = opts.debounceMs ?? 200;
|
|
47695
|
+
const watch2 = opts.watch ?? ((p, o, l) => fsWatch(p, o, (event, file) => l(event, file === null ? null : String(file))));
|
|
47696
|
+
let timer = null;
|
|
47697
|
+
const pending = /* @__PURE__ */ new Set();
|
|
47698
|
+
const watcher = watch2(dir, { recursive: true }, (_event, file) => {
|
|
47699
|
+
if (!file || ignoredChange(file, (rel) => isDir(join50(dir, rel)))) return;
|
|
47700
|
+
pending.add(file);
|
|
47701
|
+
if (timer) clearTimeout(timer);
|
|
47702
|
+
timer = setTimeout(() => {
|
|
47703
|
+
timer = null;
|
|
47704
|
+
const paths = [...pending];
|
|
47705
|
+
pending.clear();
|
|
47706
|
+
onChange(paths);
|
|
47707
|
+
}, debounceMs);
|
|
47708
|
+
});
|
|
47709
|
+
return {
|
|
47710
|
+
close() {
|
|
47711
|
+
if (timer) clearTimeout(timer);
|
|
47712
|
+
watcher.close();
|
|
47713
|
+
}
|
|
47714
|
+
};
|
|
47715
|
+
}
|
|
47716
|
+
function watchedContentDir(source) {
|
|
47717
|
+
if (!source || /^https?:\/\//i.test(source)) return null;
|
|
47718
|
+
const dir = resolve42(source);
|
|
47719
|
+
try {
|
|
47720
|
+
return statSync14(dir).isDirectory() && existsSync53(join50(dir, "himalaya.content.json")) ? dir : null;
|
|
47721
|
+
} catch {
|
|
47722
|
+
return null;
|
|
47723
|
+
}
|
|
47724
|
+
}
|
|
47725
|
+
function watchFlagConflict(opts) {
|
|
47726
|
+
if (opts.source) {
|
|
47727
|
+
return { error: "watch_needs_source", message: "--watch rebuilds a content package on every save, so it cannot watch a packaged release or a URL. Pass the app's directory (the one with himalaya.content.json), --content <dir>, or run it from there with no argument." };
|
|
47728
|
+
}
|
|
47729
|
+
if (opts.browser) {
|
|
47730
|
+
return { error: "watch_with_browser", message: "--watch rebuilds and serves from this process; --browser runs the whole plane inside the tab. Pick one." };
|
|
47731
|
+
}
|
|
47732
|
+
if (opts.spa) {
|
|
47733
|
+
return { error: "watch_with_spa", message: "--watch pushes each rebuild to the open tab over this server's own origin, and a hosted SPA (--spa) listens on its origin instead, so it would never repaint. Drop --spa to watch with the bundled web host, or drop --watch." };
|
|
47734
|
+
}
|
|
47735
|
+
return null;
|
|
47736
|
+
}
|
|
47737
|
+
function rebuildBlocker(outcome, servedMissing) {
|
|
47738
|
+
const failed2 = outcome.failedToBuild[0];
|
|
47739
|
+
if (failed2) return `${failed2.screenId}: ${failed2.error.split("\n")[0]}`;
|
|
47740
|
+
const had = new Set(servedMissing.map((m) => `${m.screen}\0${m.bundle}`));
|
|
47741
|
+
const lost = outcome.missingBundles.find((m) => !had.has(`${m.screen}\0${m.bundle}`));
|
|
47742
|
+
if (lost) return `${lost.screen}: its worker bundle "${lost.bundle}" is referenced but was not built`;
|
|
47743
|
+
return null;
|
|
47744
|
+
}
|
|
47745
|
+
function serialize(task) {
|
|
47746
|
+
let running = null;
|
|
47747
|
+
let again = false;
|
|
47748
|
+
let stopped = false;
|
|
47749
|
+
const go = () => {
|
|
47750
|
+
if (stopped) return;
|
|
47751
|
+
if (running) {
|
|
47752
|
+
again = true;
|
|
47753
|
+
return;
|
|
47754
|
+
}
|
|
47755
|
+
running = (async () => {
|
|
47756
|
+
try {
|
|
47757
|
+
await task();
|
|
47758
|
+
} finally {
|
|
47759
|
+
running = null;
|
|
47760
|
+
if (again && !stopped) {
|
|
47761
|
+
again = false;
|
|
47762
|
+
go();
|
|
47763
|
+
}
|
|
47764
|
+
}
|
|
47765
|
+
})();
|
|
47766
|
+
};
|
|
47767
|
+
return Object.assign(() => go(), {
|
|
47768
|
+
async stop() {
|
|
47769
|
+
stopped = true;
|
|
47770
|
+
again = false;
|
|
47771
|
+
await running?.catch(() => {
|
|
47772
|
+
});
|
|
47773
|
+
}
|
|
47774
|
+
});
|
|
47775
|
+
}
|
|
47776
|
+
function himiDir(dir) {
|
|
47777
|
+
const root = join50(dir, ".himi");
|
|
47778
|
+
try {
|
|
47779
|
+
return lstatSync7(root).isDirectory() ? root : null;
|
|
47780
|
+
} catch (e) {
|
|
47781
|
+
if (e.code !== "ENOENT") return null;
|
|
47782
|
+
mkdirSync26(root, { recursive: true });
|
|
47783
|
+
return lstatSync7(root).isDirectory() ? root : null;
|
|
47784
|
+
}
|
|
47785
|
+
}
|
|
47786
|
+
function writeRunRecord(dir, record2) {
|
|
47787
|
+
const root = himiDir(dir);
|
|
47788
|
+
if (!root) return false;
|
|
47789
|
+
const tmp = join50(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
|
|
47790
|
+
try {
|
|
47791
|
+
writeFileSync22(tmp, `${JSON.stringify(record2, null, 2)}
|
|
47792
|
+
`, { flag: "wx" });
|
|
47793
|
+
renameSync5(tmp, join50(root, "run.json"));
|
|
47794
|
+
} catch (e) {
|
|
47795
|
+
rmSync12(tmp, { force: true });
|
|
47796
|
+
throw e;
|
|
47797
|
+
}
|
|
47798
|
+
return true;
|
|
47799
|
+
}
|
|
47800
|
+
function removeRunRecord(dir) {
|
|
47801
|
+
const root = join50(dir, ".himi");
|
|
47802
|
+
try {
|
|
47803
|
+
if (!lstatSync7(root).isDirectory()) return;
|
|
47804
|
+
} catch {
|
|
47805
|
+
return;
|
|
47806
|
+
}
|
|
47807
|
+
rmSync12(join50(root, "run.json"), { force: true });
|
|
47808
|
+
}
|
|
47809
|
+
function boardFile(dir, pathname) {
|
|
47810
|
+
let rel = null;
|
|
47811
|
+
if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join50("studio", "index.html");
|
|
47812
|
+
else if (pathname === "/__himi/studio/state.js") rel = join50("studio", "state.js");
|
|
47813
|
+
else {
|
|
47814
|
+
const m = /^\/__himi\/history\/([0-9a-f]{64}\.(png|jpg|gif|webp))$/.exec(pathname);
|
|
47815
|
+
if (m) rel = join50("history", m[1]);
|
|
47816
|
+
}
|
|
47817
|
+
if (!rel) return null;
|
|
47818
|
+
const bytes2 = readConfined(resolve42(dir, ".himi"), rel);
|
|
47819
|
+
if (!bytes2) return new Response("not found", { status: 404 });
|
|
47820
|
+
return new Response(bytes2, {
|
|
47821
|
+
status: 200,
|
|
47822
|
+
headers: { "content-type": BOARD_TYPES[extname4(rel)] ?? "application/octet-stream", "cache-control": rel.startsWith("history") ? "public, max-age=31536000, immutable" : "no-store" }
|
|
47823
|
+
});
|
|
47824
|
+
}
|
|
47825
|
+
function readConfined(root, rel) {
|
|
47826
|
+
try {
|
|
47827
|
+
if (!lstatSync7(root).isDirectory()) return null;
|
|
47828
|
+
const parts = rel.split(sep13);
|
|
47829
|
+
let at = root;
|
|
47830
|
+
for (let i = 0; i < parts.length; i++) {
|
|
47831
|
+
at = join50(at, parts[i]);
|
|
47832
|
+
const st = lstatSync7(at);
|
|
47833
|
+
if (st.isSymbolicLink() || !(i === parts.length - 1 ? st.isFile() : st.isDirectory())) return null;
|
|
47834
|
+
}
|
|
47835
|
+
const canonicalRoot = realpathSync6(root);
|
|
47836
|
+
if (!realpathSync6(at).startsWith(canonicalRoot + sep13)) return null;
|
|
47837
|
+
const fd = openSync2(at, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
47838
|
+
try {
|
|
47839
|
+
if (!fstatSync(fd).isFile()) return null;
|
|
47840
|
+
return readFileSync58(fd);
|
|
47841
|
+
} finally {
|
|
47842
|
+
closeSync2(fd);
|
|
47843
|
+
}
|
|
47844
|
+
} catch {
|
|
47845
|
+
return null;
|
|
47846
|
+
}
|
|
47847
|
+
}
|
|
47848
|
+
var isEmptyDiff, ReloadBus, isDir, BOARD_TYPES;
|
|
47849
|
+
var init_run_watch = __esm({
|
|
47850
|
+
"src/run-watch.ts"() {
|
|
47851
|
+
isEmptyDiff = (d) => !d.screens.length && !d.bundles.length && !d.tokens && !d.config;
|
|
47852
|
+
ReloadBus = class {
|
|
47853
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
47854
|
+
subscribe(send2) {
|
|
47855
|
+
this.subscribers.add(send2);
|
|
47856
|
+
return () => this.subscribers.delete(send2);
|
|
47857
|
+
}
|
|
47858
|
+
publish(event, data) {
|
|
47859
|
+
for (const send2 of [...this.subscribers]) send2(event, data);
|
|
47860
|
+
}
|
|
47861
|
+
get listeners() {
|
|
47862
|
+
return this.subscribers.size;
|
|
47863
|
+
}
|
|
47864
|
+
};
|
|
47865
|
+
isDir = (path2) => {
|
|
47866
|
+
try {
|
|
47867
|
+
return statSync14(path2).isDirectory();
|
|
47868
|
+
} catch {
|
|
47869
|
+
return false;
|
|
47870
|
+
}
|
|
47871
|
+
};
|
|
47872
|
+
BOARD_TYPES = {
|
|
47873
|
+
".html": "text/html; charset=utf-8",
|
|
47874
|
+
".js": "text/javascript; charset=utf-8",
|
|
47875
|
+
".png": "image/png",
|
|
47876
|
+
".jpg": "image/jpeg",
|
|
47877
|
+
".gif": "image/gif",
|
|
47878
|
+
".webp": "image/webp"
|
|
47879
|
+
};
|
|
47880
|
+
}
|
|
47881
|
+
});
|
|
47882
|
+
|
|
47523
47883
|
// src/run-browser.ts
|
|
47524
47884
|
var run_browser_exports = {};
|
|
47525
47885
|
__export(run_browser_exports, {
|
|
@@ -47528,19 +47888,19 @@ __export(run_browser_exports, {
|
|
|
47528
47888
|
runInBrowser: () => runInBrowser
|
|
47529
47889
|
});
|
|
47530
47890
|
import { createServer as createServer5 } from "node:http";
|
|
47531
|
-
import { existsSync as
|
|
47891
|
+
import { existsSync as existsSync54, readFileSync as readFileSync59 } from "node:fs";
|
|
47532
47892
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
47533
|
-
import { dirname as dirname28, resolve as
|
|
47893
|
+
import { dirname as dirname28, resolve as resolve43 } from "node:path";
|
|
47534
47894
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
47535
47895
|
function stagedDir() {
|
|
47536
|
-
return process.env.HIMI_BROWSER_PLANE_OUT ?
|
|
47896
|
+
return process.env.HIMI_BROWSER_PLANE_OUT ? resolve43(process.env.HIMI_BROWSER_PLANE_OUT) : resolve43(REPO, "packages", "serve", "dist", "browser-plane");
|
|
47537
47897
|
}
|
|
47538
47898
|
function missingStaged() {
|
|
47539
|
-
return [...SERVED].filter((f) => !
|
|
47899
|
+
return [...SERVED].filter((f) => !existsSync54(resolve43(stagedDir(), f))).sort();
|
|
47540
47900
|
}
|
|
47541
47901
|
function ensureBrowserPlaneStaged() {
|
|
47542
47902
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
47543
|
-
const r = spawnSync3(process.execPath, [
|
|
47903
|
+
const r = spawnSync3(process.execPath, [resolve43(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
47544
47904
|
cwd: REPO,
|
|
47545
47905
|
encoding: "utf8"
|
|
47546
47906
|
});
|
|
@@ -47626,7 +47986,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
47626
47986
|
}
|
|
47627
47987
|
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
47628
47988
|
if (SERVED.has(name)) {
|
|
47629
|
-
if (!
|
|
47989
|
+
if (!existsSync54(resolve43(stagedDir(), name))) {
|
|
47630
47990
|
const restaged = ensureBrowserPlaneStaged();
|
|
47631
47991
|
if (!restaged.ok) {
|
|
47632
47992
|
res.writeHead(503, { "content-type": "application/json" });
|
|
@@ -47636,7 +47996,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
47636
47996
|
}
|
|
47637
47997
|
let bytes2;
|
|
47638
47998
|
try {
|
|
47639
|
-
bytes2 =
|
|
47999
|
+
bytes2 = readFileSync59(resolve43(stagedDir(), name));
|
|
47640
48000
|
} catch (e) {
|
|
47641
48001
|
res.writeHead(503, { "content-type": "application/json" });
|
|
47642
48002
|
res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
|
|
@@ -47677,7 +48037,7 @@ var init_run_browser = __esm({
|
|
|
47677
48037
|
init_open_url();
|
|
47678
48038
|
init_file_store();
|
|
47679
48039
|
HERE = dirname28(fileURLToPath23(import.meta.url));
|
|
47680
|
-
REPO =
|
|
48040
|
+
REPO = resolve43(HERE, "..", "..", "..");
|
|
47681
48041
|
SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
|
|
47682
48042
|
}
|
|
47683
48043
|
});
|
|
@@ -48096,10 +48456,10 @@ __export(preflight_exports, {
|
|
|
48096
48456
|
parseStoreConfig: () => parseStoreConfig,
|
|
48097
48457
|
requireEnv: () => requireEnv
|
|
48098
48458
|
});
|
|
48099
|
-
import { existsSync as
|
|
48100
|
-
import { isAbsolute as isAbsolute3, relative as relative9, resolve as
|
|
48459
|
+
import { existsSync as existsSync55, readFileSync as readFileSync60 } from "node:fs";
|
|
48460
|
+
import { isAbsolute as isAbsolute3, relative as relative9, resolve as resolve44 } from "node:path";
|
|
48101
48461
|
function isInsideRepo(p) {
|
|
48102
|
-
const rel = relative9(REPO_ROOT3,
|
|
48462
|
+
const rel = relative9(REPO_ROOT3, resolve44(p));
|
|
48103
48463
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
|
|
48104
48464
|
}
|
|
48105
48465
|
function assertCredentialOutsideRepo(label2, p) {
|
|
@@ -48153,10 +48513,10 @@ function parseStoreConfig(text5) {
|
|
|
48153
48513
|
}
|
|
48154
48514
|
function loadStoreConfig(app) {
|
|
48155
48515
|
const p = storeConfigPath(app);
|
|
48156
|
-
if (!
|
|
48516
|
+
if (!existsSync55(p)) {
|
|
48157
48517
|
throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
48158
48518
|
}
|
|
48159
|
-
return parseStoreConfig(
|
|
48519
|
+
return parseStoreConfig(readFileSync60(p, "utf8"));
|
|
48160
48520
|
}
|
|
48161
48521
|
var init_preflight = __esm({
|
|
48162
48522
|
"../store-release/preflight.ts"() {
|
|
@@ -48175,19 +48535,19 @@ __export(credential_profile_exports, {
|
|
|
48175
48535
|
profilePath: () => profilePath,
|
|
48176
48536
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
48177
48537
|
});
|
|
48178
|
-
import { existsSync as
|
|
48538
|
+
import { existsSync as existsSync56, readFileSync as readFileSync61 } from "node:fs";
|
|
48179
48539
|
import { homedir as homedir5 } from "node:os";
|
|
48180
|
-
import { join as
|
|
48540
|
+
import { join as join51 } from "node:path";
|
|
48181
48541
|
function credentialsDir(home = homedir5()) {
|
|
48182
|
-
return
|
|
48542
|
+
return join51(home, ".himalaya", "store-credentials");
|
|
48183
48543
|
}
|
|
48184
48544
|
function profilePath(name, home = homedir5()) {
|
|
48185
48545
|
if (!PROFILE_NAME.test(name)) {
|
|
48186
48546
|
throw new Error(
|
|
48187
|
-
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${
|
|
48547
|
+
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join51(credentialsDir(home), "<name>.json")}; it is never a path.`
|
|
48188
48548
|
);
|
|
48189
48549
|
}
|
|
48190
|
-
return
|
|
48550
|
+
return join51(credentialsDir(home), `${name}.json`);
|
|
48191
48551
|
}
|
|
48192
48552
|
function parseProfile(text5, label2) {
|
|
48193
48553
|
let doc;
|
|
@@ -48218,8 +48578,8 @@ function resolveStoreCredentials(opts) {
|
|
|
48218
48578
|
const { app, cfg } = opts;
|
|
48219
48579
|
const env = opts.env ?? process.env;
|
|
48220
48580
|
const home = opts.home ?? homedir5();
|
|
48221
|
-
const read = opts.readProfile ?? ((p) =>
|
|
48222
|
-
const exists = opts.profileExists ??
|
|
48581
|
+
const read = opts.readProfile ?? ((p) => readFileSync61(p, "utf8"));
|
|
48582
|
+
const exists = opts.profileExists ?? existsSync56;
|
|
48223
48583
|
const ios = cfg.ios ?? {};
|
|
48224
48584
|
const flagName = opts.profileFlag?.trim();
|
|
48225
48585
|
const named = namedProfile(cfg, opts.profileFlag);
|
|
@@ -48299,9 +48659,9 @@ __export(preflight_app_exports, {
|
|
|
48299
48659
|
preflightApp: () => preflightApp,
|
|
48300
48660
|
profileAccount: () => profileAccount
|
|
48301
48661
|
});
|
|
48302
|
-
import { readFileSync as
|
|
48662
|
+
import { readFileSync as readFileSync62, existsSync as existsSync57, readdirSync as readdirSync26, statSync as statSync15 } from "node:fs";
|
|
48303
48663
|
import { createHash as createHash25 } from "node:crypto";
|
|
48304
|
-
import { join as
|
|
48664
|
+
import { join as join52 } from "node:path";
|
|
48305
48665
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
48306
48666
|
const f = [];
|
|
48307
48667
|
const has = (re, s) => re.test(s);
|
|
@@ -48365,13 +48725,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
48365
48725
|
}
|
|
48366
48726
|
}
|
|
48367
48727
|
async function preflightApp(app, opts = {}) {
|
|
48368
|
-
const projectYml =
|
|
48369
|
-
const storeConfig =
|
|
48728
|
+
const projectYml = existsSync57(iosProjectYml(app)) ? readFileSync62(iosProjectYml(app), "utf8") : "";
|
|
48729
|
+
const storeConfig = existsSync57(storeConfigPath(app)) ? readFileSync62(storeConfigPath(app), "utf8") : "";
|
|
48370
48730
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
48371
48731
|
const findings = analyze(
|
|
48372
48732
|
projectYml,
|
|
48373
48733
|
storeConfig,
|
|
48374
|
-
await appIconState(
|
|
48734
|
+
await appIconState(join52(appDir(app), "ios")),
|
|
48375
48735
|
profileAccount(app, storeConfig, opts)
|
|
48376
48736
|
);
|
|
48377
48737
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -48400,17 +48760,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
48400
48760
|
return f;
|
|
48401
48761
|
}
|
|
48402
48762
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
48403
|
-
const root =
|
|
48763
|
+
const root = join52(storeDir(app), "metadata");
|
|
48404
48764
|
const out = /* @__PURE__ */ new Set();
|
|
48405
|
-
if (
|
|
48765
|
+
if (existsSync57(root)) {
|
|
48406
48766
|
for (const n of readdirSync26(root)) if (n.endsWith(".txt")) out.add(n);
|
|
48407
48767
|
}
|
|
48408
|
-
if (
|
|
48768
|
+
if (existsSync57(join52(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
48409
48769
|
return out;
|
|
48410
48770
|
}
|
|
48411
48771
|
function reviewInfoFiles(app) {
|
|
48412
|
-
const dir =
|
|
48413
|
-
if (!
|
|
48772
|
+
const dir = join52(storeDir(app), "review_information");
|
|
48773
|
+
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48414
48774
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48415
48775
|
}
|
|
48416
48776
|
function isValidAppStoreSize(w, h) {
|
|
@@ -48520,12 +48880,12 @@ function analyzePlayListing(assets) {
|
|
|
48520
48880
|
return f;
|
|
48521
48881
|
}
|
|
48522
48882
|
function playListingAssets(app, locale = "en-US") {
|
|
48523
|
-
const dir =
|
|
48883
|
+
const dir = join52(storeDir(app), "play", locale, "images");
|
|
48524
48884
|
const read = (names) => {
|
|
48525
48885
|
for (const name of names) {
|
|
48526
|
-
const p =
|
|
48886
|
+
const p = join52(dir, name);
|
|
48527
48887
|
try {
|
|
48528
|
-
if (
|
|
48888
|
+
if (statSync15(p).isFile()) return { name, bytes: readFileSync62(p) };
|
|
48529
48889
|
} catch {
|
|
48530
48890
|
}
|
|
48531
48891
|
}
|
|
@@ -48556,26 +48916,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
48556
48916
|
return f;
|
|
48557
48917
|
}
|
|
48558
48918
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
48559
|
-
const dir =
|
|
48560
|
-
if (!
|
|
48919
|
+
const dir = join52(storeDir(app), "metadata", locale);
|
|
48920
|
+
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48561
48921
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48562
48922
|
}
|
|
48563
48923
|
function listScreenshots(app, locale = "en-US") {
|
|
48564
48924
|
const out = [];
|
|
48565
|
-
const flat =
|
|
48566
|
-
if (
|
|
48925
|
+
const flat = join52(storeDir(app), "screenshots", locale);
|
|
48926
|
+
if (existsSync57(flat)) {
|
|
48567
48927
|
for (const png of readdirSync26(flat).filter((n) => n.endsWith(".png"))) {
|
|
48568
|
-
const sz = pngSize(
|
|
48928
|
+
const sz = pngSize(readFileSync62(join52(flat, png)));
|
|
48569
48929
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
48570
48930
|
}
|
|
48571
48931
|
}
|
|
48572
|
-
const legacy =
|
|
48573
|
-
if (
|
|
48932
|
+
const legacy = join52(storeDir(app), "metadata", locale, "screenshots");
|
|
48933
|
+
if (existsSync57(legacy)) {
|
|
48574
48934
|
for (const deviceDir of readdirSync26(legacy)) {
|
|
48575
|
-
const d =
|
|
48576
|
-
if (!
|
|
48935
|
+
const d = join52(legacy, deviceDir);
|
|
48936
|
+
if (!statSync15(d).isDirectory()) continue;
|
|
48577
48937
|
for (const png of readdirSync26(d).filter((n) => n.endsWith(".png"))) {
|
|
48578
|
-
const sz = pngSize(
|
|
48938
|
+
const sz = pngSize(readFileSync62(join52(d, png)));
|
|
48579
48939
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
48580
48940
|
}
|
|
48581
48941
|
}
|
|
@@ -48583,13 +48943,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
48583
48943
|
return out;
|
|
48584
48944
|
}
|
|
48585
48945
|
function placeholderHashes2() {
|
|
48586
|
-
const templateIos =
|
|
48587
|
-
if (!
|
|
48946
|
+
const templateIos = join52(appDir("_template"), "ios");
|
|
48947
|
+
if (!existsSync57(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
48588
48948
|
for (const target of readdirSync26(templateIos)) {
|
|
48589
|
-
const p =
|
|
48949
|
+
const p = join52(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48590
48950
|
try {
|
|
48591
|
-
if (!
|
|
48592
|
-
return [LEGACY_PLACEHOLDER_SHA2562, createHash25("sha256").update(
|
|
48951
|
+
if (!statSync15(p).isFile()) continue;
|
|
48952
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash25("sha256").update(readFileSync62(p)).digest("hex")];
|
|
48593
48953
|
} catch {
|
|
48594
48954
|
}
|
|
48595
48955
|
}
|
|
@@ -48620,12 +48980,12 @@ async function pixelIssues(bytes2) {
|
|
|
48620
48980
|
}
|
|
48621
48981
|
}
|
|
48622
48982
|
async function appIconState(iosDir) {
|
|
48623
|
-
if (!
|
|
48983
|
+
if (!existsSync57(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
48624
48984
|
for (const target of readdirSync26(iosDir)) {
|
|
48625
|
-
const p =
|
|
48985
|
+
const p = join52(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48626
48986
|
try {
|
|
48627
|
-
if (!
|
|
48628
|
-
const bytes2 =
|
|
48987
|
+
if (!statSync15(p).isFile()) continue;
|
|
48988
|
+
const bytes2 = readFileSync62(p);
|
|
48629
48989
|
const hash = createHash25("sha256").update(bytes2).digest("hex");
|
|
48630
48990
|
const pixels = await pixelIssues(bytes2);
|
|
48631
48991
|
return {
|
|
@@ -48697,7 +49057,7 @@ __export(version_exports, {
|
|
|
48697
49057
|
setAndroidVersion: () => setAndroidVersion,
|
|
48698
49058
|
setIosVersion: () => setIosVersion
|
|
48699
49059
|
});
|
|
48700
|
-
import { readFileSync as
|
|
49060
|
+
import { readFileSync as readFileSync63, writeFileSync as writeFileSync23 } from "node:fs";
|
|
48701
49061
|
function readIosVersion(projectYml) {
|
|
48702
49062
|
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
48703
49063
|
const build2 = matchScalar(projectYml, "CFBundleVersion");
|
|
@@ -48755,8 +49115,8 @@ function setAndroidVersion(gradle, v) {
|
|
|
48755
49115
|
function bumpVersion(app, opts) {
|
|
48756
49116
|
const iosPath = iosProjectYml(app);
|
|
48757
49117
|
const gradlePath = androidGradle(app);
|
|
48758
|
-
const iosYml =
|
|
48759
|
-
const gradle =
|
|
49118
|
+
const iosYml = readFileSync63(iosPath, "utf8");
|
|
49119
|
+
const gradle = readFileSync63(gradlePath, "utf8");
|
|
48760
49120
|
const current = readIosVersion(iosYml);
|
|
48761
49121
|
const next = {
|
|
48762
49122
|
marketing: opts.marketing ?? current.marketing,
|
|
@@ -48773,7 +49133,7 @@ var init_version = __esm({
|
|
|
48773
49133
|
});
|
|
48774
49134
|
|
|
48775
49135
|
// ../store-release/register-bundle.ts
|
|
48776
|
-
import { readFileSync as
|
|
49136
|
+
import { readFileSync as readFileSync64 } from "node:fs";
|
|
48777
49137
|
import { createPrivateKey as createPrivateKey2, sign } from "node:crypto";
|
|
48778
49138
|
function b64url2(b) {
|
|
48779
49139
|
return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -48791,7 +49151,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
|
|
|
48791
49151
|
async function registerBundleId(opts) {
|
|
48792
49152
|
const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48793
49153
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48794
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
49154
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync64(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
48795
49155
|
const res = await fetch(`${ASC_API}/v1/bundleIds`, {
|
|
48796
49156
|
method: "POST",
|
|
48797
49157
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
@@ -48845,7 +49205,7 @@ __export(asc_status_exports, {
|
|
|
48845
49205
|
ascStatus: () => ascStatus,
|
|
48846
49206
|
buildVerdict: () => buildVerdict
|
|
48847
49207
|
});
|
|
48848
|
-
import { readFileSync as
|
|
49208
|
+
import { readFileSync as readFileSync65 } from "node:fs";
|
|
48849
49209
|
function buildVerdict(builds) {
|
|
48850
49210
|
if (!builds.length) {
|
|
48851
49211
|
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).";
|
|
@@ -48859,7 +49219,7 @@ function buildVerdict(builds) {
|
|
|
48859
49219
|
function client(creds) {
|
|
48860
49220
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48861
49221
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48862
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
49222
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync65(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
48863
49223
|
return async (path2) => {
|
|
48864
49224
|
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
48865
49225
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
@@ -49019,7 +49379,7 @@ __export(secrets_exports, {
|
|
|
49019
49379
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
49020
49380
|
runSecretsCommand: () => runSecretsCommand
|
|
49021
49381
|
});
|
|
49022
|
-
import { readFileSync as
|
|
49382
|
+
import { readFileSync as readFileSync66 } from "node:fs";
|
|
49023
49383
|
function environment(value) {
|
|
49024
49384
|
if (value === "preview" || value === "production") return value;
|
|
49025
49385
|
throw new Error("--environment must be preview or production");
|
|
@@ -49050,7 +49410,7 @@ async function runSecretsCommand(operation, flags, io, options = {}) {
|
|
|
49050
49410
|
io.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
49051
49411
|
return 0;
|
|
49052
49412
|
}
|
|
49053
|
-
const value = options.readValue ? options.readValue() :
|
|
49413
|
+
const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
|
|
49054
49414
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
49055
49415
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
49056
49416
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -49079,7 +49439,7 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
49079
49439
|
}
|
|
49080
49440
|
let body;
|
|
49081
49441
|
if (operation !== "list") {
|
|
49082
|
-
const value = options.readValue ? options.readValue() :
|
|
49442
|
+
const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
|
|
49083
49443
|
body = JSON.stringify({ value });
|
|
49084
49444
|
}
|
|
49085
49445
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -49115,15 +49475,15 @@ __export(notify_exports, {
|
|
|
49115
49475
|
runNotify: () => runNotify,
|
|
49116
49476
|
saveAdminSession: () => saveAdminSession
|
|
49117
49477
|
});
|
|
49118
|
-
import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as
|
|
49478
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as readFileSync67, writeFileSync as writeFileSync24 } from "node:fs";
|
|
49119
49479
|
import { homedir as homedir6 } from "node:os";
|
|
49120
|
-
import { dirname as dirname30, join as
|
|
49480
|
+
import { dirname as dirname30, join as join53 } from "node:path";
|
|
49121
49481
|
function defaultSessionsPath() {
|
|
49122
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
49482
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join53(homedir6(), ".himalaya", "admin-sessions.json");
|
|
49123
49483
|
}
|
|
49124
49484
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
49125
49485
|
try {
|
|
49126
|
-
return JSON.parse(
|
|
49486
|
+
return JSON.parse(readFileSync67(path2, "utf8"));
|
|
49127
49487
|
} catch {
|
|
49128
49488
|
return {};
|
|
49129
49489
|
}
|
|
@@ -51780,10 +52140,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
51780
52140
|
if (refusal) throw new Error(refusal);
|
|
51781
52141
|
}
|
|
51782
52142
|
function resolveAll(hostname2) {
|
|
51783
|
-
return new Promise((
|
|
52143
|
+
return new Promise((resolve48, reject) => {
|
|
51784
52144
|
dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
|
|
51785
52145
|
if (err) reject(err);
|
|
51786
|
-
else
|
|
52146
|
+
else resolve48(addresses);
|
|
51787
52147
|
});
|
|
51788
52148
|
});
|
|
51789
52149
|
}
|
|
@@ -51791,13 +52151,13 @@ function withAbort(start, signal, what) {
|
|
|
51791
52151
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
51792
52152
|
const work = start();
|
|
51793
52153
|
if (!signal) return work;
|
|
51794
|
-
return new Promise((
|
|
52154
|
+
return new Promise((resolve48, reject) => {
|
|
51795
52155
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
51796
52156
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
51797
|
-
work.then(
|
|
52157
|
+
work.then(resolve48, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
51798
52158
|
});
|
|
51799
52159
|
}
|
|
51800
|
-
async function pinAddress(url,
|
|
52160
|
+
async function pinAddress(url, resolve48 = resolveAll, signal) {
|
|
51801
52161
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
51802
52162
|
if (ipv4Octets(host)) {
|
|
51803
52163
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -51807,7 +52167,7 @@ async function pinAddress(url, resolve47 = resolveAll, signal) {
|
|
|
51807
52167
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
51808
52168
|
return { address: host, family: 6 };
|
|
51809
52169
|
}
|
|
51810
|
-
const addresses = await withAbort(() =>
|
|
52170
|
+
const addresses = await withAbort(() => resolve48(host), signal, `${host} lookup`);
|
|
51811
52171
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
51812
52172
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
51813
52173
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -51847,7 +52207,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
51847
52207
|
return out;
|
|
51848
52208
|
}
|
|
51849
52209
|
function requestOnce(url, pinned, init) {
|
|
51850
|
-
return new Promise((
|
|
52210
|
+
return new Promise((resolve48, reject) => {
|
|
51851
52211
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
51852
52212
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
51853
52213
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -51877,7 +52237,7 @@ function requestOnce(url, pinned, init) {
|
|
|
51877
52237
|
reject(err);
|
|
51878
52238
|
return;
|
|
51879
52239
|
}
|
|
51880
|
-
|
|
52240
|
+
resolve48(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
|
|
51881
52241
|
}
|
|
51882
52242
|
);
|
|
51883
52243
|
req.on("error", reject);
|
|
@@ -52681,7 +53041,7 @@ var init_brand_font = __esm({
|
|
|
52681
53041
|
|
|
52682
53042
|
// src/site-analyze/write-artifacts.ts
|
|
52683
53043
|
import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync25 } from "node:fs";
|
|
52684
|
-
import { join as
|
|
53044
|
+
import { join as join54 } from "node:path";
|
|
52685
53045
|
function attachVeloSources(book, sources, put) {
|
|
52686
53046
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
52687
53047
|
for (const f of book.velo.files) {
|
|
@@ -52836,12 +53196,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
52836
53196
|
}
|
|
52837
53197
|
async function writeBusinessBook(result, opts) {
|
|
52838
53198
|
const out = opts.outDir;
|
|
52839
|
-
mkdirSync28(
|
|
52840
|
-
mkdirSync28(
|
|
53199
|
+
mkdirSync28(join54(out, "evidence/pages"), { recursive: true });
|
|
53200
|
+
mkdirSync28(join54(out, "media/catalog"), { recursive: true });
|
|
52841
53201
|
const files = [];
|
|
52842
53202
|
const put = (rel, body) => {
|
|
52843
|
-
const p =
|
|
52844
|
-
mkdirSync28(
|
|
53203
|
+
const p = join54(out, rel);
|
|
53204
|
+
mkdirSync28(join54(p, ".."), { recursive: true });
|
|
52845
53205
|
writeFileSync25(p, body);
|
|
52846
53206
|
files.push(rel);
|
|
52847
53207
|
};
|
|
@@ -52935,15 +53295,15 @@ var init_customer_build = __esm({
|
|
|
52935
53295
|
});
|
|
52936
53296
|
|
|
52937
53297
|
// src/site-analyze/apply.ts
|
|
52938
|
-
import { existsSync as
|
|
52939
|
-
import { dirname as dirname31, isAbsolute as isAbsolute4, join as
|
|
53298
|
+
import { existsSync as existsSync58, readFileSync as readFileSync68, writeFileSync as writeFileSync26, copyFileSync as copyFileSync3, mkdirSync as mkdirSync29, realpathSync as realpathSync7, statSync as statSync16 } from "node:fs";
|
|
53299
|
+
import { dirname as dirname31, isAbsolute as isAbsolute4, join as join55, resolve as resolve45, sep as sep14 } from "node:path";
|
|
52940
53300
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
52941
53301
|
function unpairedRedirectNote(overlay) {
|
|
52942
53302
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
52943
53303
|
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)`;
|
|
52944
53304
|
}
|
|
52945
53305
|
function posix2(p) {
|
|
52946
|
-
return
|
|
53306
|
+
return resolve45(p).replace(/\\/g, "/");
|
|
52947
53307
|
}
|
|
52948
53308
|
function committedShellProvisioning(path2) {
|
|
52949
53309
|
return committedShellFor(posix2(path2));
|
|
@@ -52951,7 +53311,7 @@ function committedShellProvisioning(path2) {
|
|
|
52951
53311
|
function findRepoRoot(cwd) {
|
|
52952
53312
|
let dir = cwd;
|
|
52953
53313
|
for (let i = 0; i < 8; i++) {
|
|
52954
|
-
if (SHELL_NAMES2.some((name) =>
|
|
53314
|
+
if (SHELL_NAMES2.some((name) => existsSync58(join55(dir, shellAppDir(name), "package.json")))) return dir;
|
|
52955
53315
|
const next = dirname31(dir);
|
|
52956
53316
|
if (next === dir) break;
|
|
52957
53317
|
dir = next;
|
|
@@ -52977,7 +53337,7 @@ function assertNotCommitted(path2, forbidden) {
|
|
|
52977
53337
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
52978
53338
|
);
|
|
52979
53339
|
}
|
|
52980
|
-
if (forbidden &&
|
|
53340
|
+
if (forbidden && resolve45(path2) === resolve45(forbidden)) {
|
|
52981
53341
|
const named = committedShellProvisioning(forbidden);
|
|
52982
53342
|
throw new Error(
|
|
52983
53343
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -53019,35 +53379,35 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
53019
53379
|
}
|
|
53020
53380
|
function buildMergedContract(options) {
|
|
53021
53381
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
53022
|
-
const committedPath =
|
|
53023
|
-
if (!
|
|
53382
|
+
const committedPath = join55(appDir2, "provisioning.json");
|
|
53383
|
+
if (!existsSync58(committedPath)) {
|
|
53024
53384
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
53025
53385
|
}
|
|
53026
|
-
const committed = JSON.parse(
|
|
53386
|
+
const committed = JSON.parse(readFileSync68(committedPath, "utf8"));
|
|
53027
53387
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
53028
53388
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
53029
53389
|
const branding = merged.branding ?? {};
|
|
53030
53390
|
const staged = [];
|
|
53031
53391
|
const contained = (root, rel) => {
|
|
53032
53392
|
if (isAbsolute4(rel)) return void 0;
|
|
53033
|
-
const full =
|
|
53034
|
-
return full.startsWith(
|
|
53393
|
+
const full = resolve45(root, rel);
|
|
53394
|
+
return full.startsWith(resolve45(root) + sep14) ? full : void 0;
|
|
53035
53395
|
};
|
|
53036
53396
|
const stage = (fromRel, toRel) => {
|
|
53037
53397
|
const from = contained(packageDir, fromRel);
|
|
53038
|
-
const to = contained(
|
|
53039
|
-
if (!from || !to || !
|
|
53398
|
+
const to = contained(join55(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
53399
|
+
if (!from || !to || !existsSync58(from)) return void 0;
|
|
53040
53400
|
let real;
|
|
53041
53401
|
let realRoot;
|
|
53042
53402
|
try {
|
|
53043
|
-
real =
|
|
53044
|
-
realRoot =
|
|
53403
|
+
real = realpathSync7(from);
|
|
53404
|
+
realRoot = realpathSync7(packageDir);
|
|
53045
53405
|
} catch {
|
|
53046
53406
|
return void 0;
|
|
53047
53407
|
}
|
|
53048
|
-
if (!real.startsWith(realRoot +
|
|
53408
|
+
if (!real.startsWith(realRoot + sep14)) return void 0;
|
|
53049
53409
|
try {
|
|
53050
|
-
if (!
|
|
53410
|
+
if (!statSync16(real).isFile()) return void 0;
|
|
53051
53411
|
mkdirSync29(dirname31(to), { recursive: true });
|
|
53052
53412
|
copyFileSync3(real, to);
|
|
53053
53413
|
} catch {
|
|
@@ -53058,11 +53418,11 @@ function buildMergedContract(options) {
|
|
|
53058
53418
|
};
|
|
53059
53419
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
53060
53420
|
if (icon) branding.appIconPath = icon;
|
|
53061
|
-
const facesPath =
|
|
53062
|
-
if (
|
|
53421
|
+
const facesPath = join55(packageDir, "media/fonts/faces.json");
|
|
53422
|
+
if (existsSync58(facesPath)) {
|
|
53063
53423
|
let faces = [];
|
|
53064
53424
|
try {
|
|
53065
|
-
const parsed = JSON.parse(
|
|
53425
|
+
const parsed = JSON.parse(readFileSync68(facesPath, "utf8"));
|
|
53066
53426
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
53067
53427
|
} catch {
|
|
53068
53428
|
faces = [];
|
|
@@ -53083,20 +53443,20 @@ function buildMergedContract(options) {
|
|
|
53083
53443
|
merged.branding = branding;
|
|
53084
53444
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
53085
53445
|
`;
|
|
53086
|
-
const path2 =
|
|
53446
|
+
const path2 = join55(packageDir, "provisioning.contract.json");
|
|
53087
53447
|
writeFileSync26(path2, body);
|
|
53088
|
-
const localPath =
|
|
53448
|
+
const localPath = join55(appDir2, LOCAL_CONTRACT_REL);
|
|
53089
53449
|
mkdirSync29(dirname31(localPath), { recursive: true });
|
|
53090
53450
|
writeFileSync26(localPath, body);
|
|
53091
53451
|
staged.push(localPath);
|
|
53092
53452
|
return { path: path2, staged };
|
|
53093
53453
|
}
|
|
53094
53454
|
async function applyOverlays(input) {
|
|
53095
|
-
const cwd =
|
|
53455
|
+
const cwd = resolve45(input.cwd);
|
|
53096
53456
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
53097
53457
|
assertKnownShell(shell);
|
|
53098
|
-
const overlay = JSON.parse(
|
|
53099
|
-
const tokens = JSON.parse(
|
|
53458
|
+
const overlay = JSON.parse(readFileSync68(input.overlayPath, "utf8"));
|
|
53459
|
+
const tokens = JSON.parse(readFileSync68(input.tokensPath, "utf8"));
|
|
53100
53460
|
const wrote = [];
|
|
53101
53461
|
const notes = [];
|
|
53102
53462
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -53106,8 +53466,8 @@ async function applyOverlays(input) {
|
|
|
53106
53466
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
53107
53467
|
);
|
|
53108
53468
|
}
|
|
53109
|
-
const appDir2 =
|
|
53110
|
-
const packageDir = dirname31(
|
|
53469
|
+
const appDir2 = join55(repoRoot2, shellAppDir(shell));
|
|
53470
|
+
const packageDir = dirname31(resolve45(input.overlayPath));
|
|
53111
53471
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
53112
53472
|
wrote.push(...staged);
|
|
53113
53473
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -53128,10 +53488,10 @@ async function applyOverlays(input) {
|
|
|
53128
53488
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
53129
53489
|
};
|
|
53130
53490
|
}
|
|
53131
|
-
const pkgProv =
|
|
53491
|
+
const pkgProv = join55(cwd, "provisioning.json");
|
|
53132
53492
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
53133
|
-
if (
|
|
53134
|
-
const cur = JSON.parse(
|
|
53493
|
+
if (existsSync58(pkgProv)) {
|
|
53494
|
+
const cur = JSON.parse(readFileSync68(pkgProv, "utf8"));
|
|
53135
53495
|
const merged = deepMerge4(cur, overlay);
|
|
53136
53496
|
writeFileSync26(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
53137
53497
|
wrote.push(pkgProv);
|
|
@@ -53139,9 +53499,9 @@ async function applyOverlays(input) {
|
|
|
53139
53499
|
writeFileSync26(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
53140
53500
|
wrote.push(pkgProv);
|
|
53141
53501
|
}
|
|
53142
|
-
const pkgTokens =
|
|
53143
|
-
if (
|
|
53144
|
-
const cur = JSON.parse(
|
|
53502
|
+
const pkgTokens = join55(cwd, "tokens.json");
|
|
53503
|
+
if (existsSync58(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
53504
|
+
const cur = JSON.parse(readFileSync68(pkgTokens, "utf8"));
|
|
53145
53505
|
const merged = deepMerge4(cur, tokens);
|
|
53146
53506
|
const mergedColors = merged.colors;
|
|
53147
53507
|
if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
|
|
@@ -53160,9 +53520,9 @@ async function applyOverlays(input) {
|
|
|
53160
53520
|
wrote.push(pkgTokens);
|
|
53161
53521
|
}
|
|
53162
53522
|
const homeAction = homeRefreshActionId(shell);
|
|
53163
|
-
const homeSrc =
|
|
53164
|
-
if (homeAction &&
|
|
53165
|
-
const prev =
|
|
53523
|
+
const homeSrc = join55(cwd, "dev/index.ts");
|
|
53524
|
+
if (homeAction && existsSync58(homeSrc)) {
|
|
53525
|
+
const prev = readFileSync68(homeSrc, "utf8");
|
|
53166
53526
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
53167
53527
|
let next = patched.src;
|
|
53168
53528
|
if (!patched.foreign && overlay.installedVerticals?.length) {
|
|
@@ -53185,13 +53545,13 @@ async function applyOverlays(input) {
|
|
|
53185
53545
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
53186
53546
|
}
|
|
53187
53547
|
}
|
|
53188
|
-
if (!input.iconPath || !
|
|
53189
|
-
const book = input.iconPath ? dirname31(dirname31(
|
|
53548
|
+
if (!input.iconPath || !existsSync58(input.iconPath)) {
|
|
53549
|
+
const book = input.iconPath ? dirname31(dirname31(resolve45(input.iconPath))) : void 0;
|
|
53190
53550
|
notes.push(
|
|
53191
53551
|
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"
|
|
53192
53552
|
);
|
|
53193
53553
|
}
|
|
53194
|
-
if (input.iconPath &&
|
|
53554
|
+
if (input.iconPath && existsSync58(input.iconPath)) {
|
|
53195
53555
|
try {
|
|
53196
53556
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
53197
53557
|
wrote.push(...installed.wrote);
|
|
@@ -54129,10 +54489,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
54129
54489
|
}
|
|
54130
54490
|
function createPromiseCallback(cb) {
|
|
54131
54491
|
let callback;
|
|
54132
|
-
let
|
|
54492
|
+
let resolve48;
|
|
54133
54493
|
let reject;
|
|
54134
54494
|
const promise = new Promise((_resolve, _reject) => {
|
|
54135
|
-
|
|
54495
|
+
resolve48 = _resolve;
|
|
54136
54496
|
reject = _reject;
|
|
54137
54497
|
});
|
|
54138
54498
|
if (typeof cb === "function") {
|
|
@@ -54148,7 +54508,7 @@ function createPromiseCallback(cb) {
|
|
|
54148
54508
|
callback = (err, result) => {
|
|
54149
54509
|
try {
|
|
54150
54510
|
if (err) reject(err);
|
|
54151
|
-
else
|
|
54511
|
+
else resolve48(result);
|
|
54152
54512
|
} catch (e) {
|
|
54153
54513
|
reject(e instanceof Error ? e : new Error());
|
|
54154
54514
|
}
|
|
@@ -56720,7 +57080,7 @@ var init_crawl_look = __esm({
|
|
|
56720
57080
|
});
|
|
56721
57081
|
|
|
56722
57082
|
// src/site-analyze/site-function.ts
|
|
56723
|
-
import { randomUUID as
|
|
57083
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
56724
57084
|
function createRevisionUrl(msid, esi) {
|
|
56725
57085
|
const q = new URLSearchParams({ editorSessionId: esi, esi, metaSiteId: msid });
|
|
56726
57086
|
return `https://editor.wix.com/html/v1/create_revision?${q}`;
|
|
@@ -57165,7 +57525,7 @@ function codeAppIdFromRevision(json5) {
|
|
|
57165
57525
|
async function snapshotAndPublish(fetchImpl, token, msid, opts = {}) {
|
|
57166
57526
|
const production = opts.production !== false;
|
|
57167
57527
|
const initiator = opts.initiator ?? "himi";
|
|
57168
|
-
const esi =
|
|
57528
|
+
const esi = randomUUID4();
|
|
57169
57529
|
const rev = await veloCall(fetchImpl, "POST", createRevisionUrl(msid, esi), {
|
|
57170
57530
|
token,
|
|
57171
57531
|
msid,
|
|
@@ -57346,8 +57706,8 @@ __export(cli_exports, {
|
|
|
57346
57706
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
57347
57707
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
57348
57708
|
});
|
|
57349
|
-
import { readFileSync as
|
|
57350
|
-
import { resolve as
|
|
57709
|
+
import { readFileSync as readFileSync69 } from "node:fs";
|
|
57710
|
+
import { resolve as resolve46 } from "node:path";
|
|
57351
57711
|
function assetFetchFor(_opts) {
|
|
57352
57712
|
return pinnedFetch2;
|
|
57353
57713
|
}
|
|
@@ -57356,7 +57716,7 @@ async function runSiteAnalyze(opts) {
|
|
|
57356
57716
|
const assetFetch = assetFetchFor(opts);
|
|
57357
57717
|
const siteFetch = guardedSiteFetch;
|
|
57358
57718
|
const cwd = opts.cwd ?? process.cwd();
|
|
57359
|
-
const outDir =
|
|
57719
|
+
const outDir = resolve46(cwd, opts.outDir ?? ".himi/business-book");
|
|
57360
57720
|
let ownerAuth;
|
|
57361
57721
|
let msid;
|
|
57362
57722
|
try {
|
|
@@ -57394,9 +57754,9 @@ async function runSiteAnalyze(opts) {
|
|
|
57394
57754
|
if (opts.apply) {
|
|
57395
57755
|
applied = await applyOverlays({
|
|
57396
57756
|
cwd,
|
|
57397
|
-
overlayPath:
|
|
57398
|
-
tokensPath:
|
|
57399
|
-
iconPath:
|
|
57757
|
+
overlayPath: resolve46(outDir, "provisioning.overlay.json"),
|
|
57758
|
+
tokensPath: resolve46(outDir, "tokens.overlay.json"),
|
|
57759
|
+
iconPath: resolve46(outDir, "media/icon.png"),
|
|
57400
57760
|
shell: opts.shell
|
|
57401
57761
|
});
|
|
57402
57762
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -57432,8 +57792,8 @@ async function runSiteFunctionCli(opts) {
|
|
|
57432
57792
|
const token = opts.token ?? await siteToken(msid);
|
|
57433
57793
|
let source;
|
|
57434
57794
|
if (opts.sourcePath) {
|
|
57435
|
-
const p =
|
|
57436
|
-
source =
|
|
57795
|
+
const p = resolve46(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
57796
|
+
source = readFileSync69(p, "utf8");
|
|
57437
57797
|
}
|
|
57438
57798
|
let body;
|
|
57439
57799
|
if (opts.bodyRaw != null) {
|
|
@@ -57484,7 +57844,7 @@ async function accountToken2(spawnImpl = spawn5) {
|
|
|
57484
57844
|
cached2 = fromEnv;
|
|
57485
57845
|
return fromEnv;
|
|
57486
57846
|
}
|
|
57487
|
-
const token = await new Promise((
|
|
57847
|
+
const token = await new Promise((resolve48, reject) => {
|
|
57488
57848
|
let child;
|
|
57489
57849
|
try {
|
|
57490
57850
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -57513,7 +57873,7 @@ async function accountToken2(spawnImpl = spawn5) {
|
|
|
57513
57873
|
const scan = (d) => {
|
|
57514
57874
|
out += String(d);
|
|
57515
57875
|
const m = out.match(TOKEN_RE2);
|
|
57516
|
-
if (m) done(() =>
|
|
57876
|
+
if (m) done(() => resolve48(m[0]));
|
|
57517
57877
|
};
|
|
57518
57878
|
child.stdout?.on("data", scan);
|
|
57519
57879
|
child.stderr?.on("data", scan);
|
|
@@ -57690,7 +58050,7 @@ __export(site_create_exports, {
|
|
|
57690
58050
|
runSiteList: () => runSiteList,
|
|
57691
58051
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
57692
58052
|
});
|
|
57693
|
-
import { existsSync as
|
|
58053
|
+
import { existsSync as existsSync59, readFileSync as readFileSync70, writeFileSync as writeFileSync27 } from "node:fs";
|
|
57694
58054
|
import { resolve as resolvePath2 } from "node:path";
|
|
57695
58055
|
function oauthClientName(projectName) {
|
|
57696
58056
|
return `${projectName} client`;
|
|
@@ -57839,7 +58199,7 @@ async function runSiteCreate(opts) {
|
|
|
57839
58199
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
57840
58200
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
57841
58201
|
}
|
|
57842
|
-
function writeProvisioningBinding(target, binding2, fs = { existsSync:
|
|
58202
|
+
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync: readFileSync70, writeFileSync: writeFileSync27 }) {
|
|
57843
58203
|
const msid = binding2.siteId;
|
|
57844
58204
|
const path2 = resolvePath2(target);
|
|
57845
58205
|
const committed = committedShellProvisioning(path2);
|
|
@@ -58512,11 +58872,11 @@ var init_context = __esm({
|
|
|
58512
58872
|
});
|
|
58513
58873
|
|
|
58514
58874
|
// src/cli.ts
|
|
58515
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as
|
|
58875
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync71, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as rmSync13, readdirSync as readdirSync27, statSync as statSync17, lstatSync as lstatSync8, accessSync, constants as constants2, renameSync as renameSync6, cpSync as cpSync3 } from "node:fs";
|
|
58516
58876
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
|
|
58517
|
-
import { createHash as createHash26, randomUUID as
|
|
58877
|
+
import { createHash as createHash26, randomUUID as randomUUID5 } from "node:crypto";
|
|
58518
58878
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
58519
|
-
import { join as
|
|
58879
|
+
import { join as join56, resolve as resolve47, relative as relative10, basename as basename13, dirname as dirname32 } from "node:path";
|
|
58520
58880
|
import { fileURLToPath as fileURLToPath24 } from "node:url";
|
|
58521
58881
|
|
|
58522
58882
|
// ../serve-cli/src/client.ts
|
|
@@ -60225,7 +60585,7 @@ async function browserLogin(opts) {
|
|
|
60225
60585
|
const log = opts.log ?? (() => {
|
|
60226
60586
|
});
|
|
60227
60587
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
60228
|
-
return await new Promise((
|
|
60588
|
+
return await new Promise((resolve48, reject) => {
|
|
60229
60589
|
let settled = false;
|
|
60230
60590
|
let loginUrl = "";
|
|
60231
60591
|
const server = createServer();
|
|
@@ -60289,7 +60649,7 @@ async function browserLogin(opts) {
|
|
|
60289
60649
|
return;
|
|
60290
60650
|
}
|
|
60291
60651
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
60292
|
-
finish2(() =>
|
|
60652
|
+
finish2(() => resolve48({ token, loginUrl }));
|
|
60293
60653
|
});
|
|
60294
60654
|
});
|
|
60295
60655
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -61792,8 +62152,8 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
61792
62152
|
var num2 = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
61793
62153
|
function embeddedTemplateCatalog() {
|
|
61794
62154
|
return availableTemplates().map((name) => {
|
|
61795
|
-
const path2 =
|
|
61796
|
-
const meta = JSON.parse(
|
|
62155
|
+
const path2 = join56(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
62156
|
+
const meta = JSON.parse(readFileSync71(path2, "utf8"));
|
|
61797
62157
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
61798
62158
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
61799
62159
|
}
|
|
@@ -62075,11 +62435,12 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
62075
62435
|
file is not the plane's per-release archive.
|
|
62076
62436
|
himi share --file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>
|
|
62077
62437
|
publish a content-addressed package link for a released app
|
|
62078
|
-
himi run [<package.himi|dir|url>] [--browser] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open]
|
|
62438
|
+
himi run [<package.himi|dir|url>] [--browser] [--watch] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open]
|
|
62079
62439
|
serve a package on localhost + open it in a browser. No serve
|
|
62080
62440
|
plane, no dev-server. With no argument it packs the current
|
|
62081
62441
|
content package first \u2014 edit, run, look at it.
|
|
62082
|
-
|
|
62442
|
+
--watch rebuilds on every save and repaints the open tab
|
|
62443
|
+
(a failed build keeps the last good preview). Blocks until Ctrl-C.
|
|
62083
62444
|
himi flags list|set|ramp|rm [<key>] [--app <a>]
|
|
62084
62445
|
read/change operational flags (RFC 0013); writes report
|
|
62085
62446
|
servedNow from the device door, never just ok
|
|
@@ -62422,7 +62783,7 @@ var COMMANDS = [
|
|
|
62422
62783
|
{ name: "import", summary: "turn a `himi pack --dev` package back into an EDITABLE content package \u2014 the file counterpart of `himi pull`, needing no serve plane, no account and no network. Refuses an invalid package before trusting its source (the content hash is recomputed over every entry on open, so the archive is provably the one that was packed), and refuses a RELEASE package by naming the absence \u2014 it carries built output and no source \u2014 rather than reporting a missing file. `--name` re-substitutes the app identity through the same machinery `himi init --template` and `himi pull --name` use, so the restored tree is a NEW app rather than a second copy of the same one, and a name that also appears inside a screen id (`feed` in `feed_home`) is left alone. A non-empty destination needs `--force` and a merge NAMES what it kept (`left: [...]`), the same contract `himi pull --force` has; a shape clash is refused whole before anything is written. There is no `--replace`: a file you were handed is not the plane's per-release archive.", required: "<package.himi> [--out <dir>] [--name <new>] [--force]" },
|
|
62423
62784
|
{ name: "pull", summary: "restore an app's SOURCE from the serve plane into an editable content package \u2014 the other half of `himi push`, which archives the content package on every publish. Owner or editor only: a viewer may download the RUNNING app (`/v1/owner/package`), not the codebase it was built from. A PAST release is restorable, not only the live one \u2014 the archive is content-addressed per release, so it has none of the live-single-slot problem that makes `himi pack` current-release-only. Two limits: pruning keeps the current release plus the newest ~20 ledger entries, and a release id identifies OTA content rather than source, so a source-only change republishes under the same id and replaces that id's archive. A release published before source archiving shipped, or pushed with `--no-source`, answers `app_source_not_found` and says to push again. `--name` re-substitutes the app identity through the same machinery `himi init --template` uses, so the restored tree is a NEW app rather than a second copy of the same one, and a name that also appears inside a screen id (`feed` in `feed_home`) is left alone. A NON-EMPTY destination is refused unless you say which you mean: `--force` merges and reports \u2014 it writes the archive over what is there, keeps files the release does not carry, and NAMES every one of them as `left: [...]` so a tree that matches no release is never silent (#2437); `--replace` restores exactly what was archived, removing those files first (`removed: [...]`) and implying `--force`. `--replace` refuses a directory holding no `himalaya.content.json`, so a mistyped `--out` cannot clear an unrelated tree, and the only paths it can remove are the ones a push would have archived \u2014 `.git/`, `node_modules/`, `dist/`, `.env*` and key material are out of its reach by construction.", required: "<app> [--release <id>] [--out <dir>] [--name <new>] [--force|--replace] [--target <t>]" },
|
|
62424
62785
|
{ name: "share", summary: "publish or revoke a content-addressed `.himi` share link. The package must be a validated archive for an already-published release; the resulting https URL is safe to QR, copy, or open in Himi Player.", required: "--file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>" },
|
|
62425
|
-
{ name: "run", summary: "serve a .himi package on localhost and open it in a browser \u2014 no serve plane, no dev-server, no setup. Given no argument it builds the current content package first, so `himi run` is the inner loop: edit, run, look at it. The SPA and /v1 are served from ONE origin because Tier-5 bundle fetches on web are same-origin-only. --chrome preview frames the app in a device chassis; --chrome app serves it as a plain web app. Blocks until Ctrl-C, like any dev server. --browser runs the whole plane INSIDE the tab (service worker + in-memory store) so no app code executes in this process or on any pod.", required: "[<package.himi|dir|url>] [--browser] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
62786
|
+
{ name: "run", summary: "serve a .himi package on localhost and open it in a browser \u2014 no serve plane, no dev-server, no setup. Given no argument it builds the current content package first, so `himi run` is the inner loop: edit, run, look at it. The SPA and /v1 are served from ONE origin because Tier-5 bundle fetches on web are same-origin-only. --chrome preview frames the app in a device chassis; --chrome app serves it as a plain web app. Blocks until Ctrl-C, like any dev server. --browser runs the whole plane INSIDE the tab (service worker + in-memory store) so no app code executes in this process or on any pod. --watch keeps the preview LIVE: every save in the content package rebuilds it and repaints the open tab with only what changed (the dev-server's hot-reload events); a build that fails keeps the last good preview on screen and says why. It also frames itself on the build board (`himi studio`) and serves the board at /__himi/studio/ on the same origin.", required: "[<package.himi|dir|url>] [--browser] [--watch] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
62426
62787
|
{ name: "preview", summary: "print the shareable web URL + himi:// deep link + agent /v1/preview JSON URLs for an app+release; --surface frames the web preview as any catalog surface (?surface=)", required: "--app --release [--screen] [--surface]" },
|
|
62427
62788
|
{ name: "surfaces", summary: "the surface catalog vs this app's envelope (platforms.json): targeted surfaces, the opt-in key for the rest, per-surface preview links with --app --release, and which widget families the package produces with --measure-widgets (which runs its built bundles)", required: "[--content <dir>] [--app --release] [--measure-widgets]" },
|
|
62428
62789
|
{ name: "context", summary: "fetch the agent preview envelope (GET /v1/preview/a/<app>) \u2014 ok/issues/screens/links; exit 1 if ok:false", required: "--app --release [--screen] [--include telemetry]" },
|
|
@@ -62454,7 +62815,7 @@ var COMMANDS = [
|
|
|
62454
62815
|
];
|
|
62455
62816
|
function cliVersion() {
|
|
62456
62817
|
try {
|
|
62457
|
-
return JSON.parse(
|
|
62818
|
+
return JSON.parse(readFileSync71(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
62458
62819
|
} catch {
|
|
62459
62820
|
return "unknown";
|
|
62460
62821
|
}
|
|
@@ -62505,16 +62866,16 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
62505
62866
|
}
|
|
62506
62867
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
62507
62868
|
function execNpmConfig(file, args, options) {
|
|
62508
|
-
return new Promise((
|
|
62509
|
-
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) :
|
|
62869
|
+
return new Promise((resolve48, reject) => {
|
|
62870
|
+
execFile(file, args, { ...options, windowsHide: true }, (error, stdout) => error ? reject(error) : resolve48(String(stdout)));
|
|
62510
62871
|
});
|
|
62511
62872
|
}
|
|
62512
62873
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
62513
62874
|
async function scopedRegistryBefore(lookup2, deadline) {
|
|
62514
62875
|
let cancel = () => {
|
|
62515
62876
|
};
|
|
62516
|
-
const expired = new Promise((
|
|
62517
|
-
const timer = setTimeout(() =>
|
|
62877
|
+
const expired = new Promise((resolve48) => {
|
|
62878
|
+
const timer = setTimeout(() => resolve48(void 0), Math.max(0, deadline - Date.now()));
|
|
62518
62879
|
cancel = () => clearTimeout(timer);
|
|
62519
62880
|
});
|
|
62520
62881
|
try {
|
|
@@ -62572,16 +62933,16 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
62572
62933
|
}
|
|
62573
62934
|
function packageVersion(path2) {
|
|
62574
62935
|
try {
|
|
62575
|
-
const version2 = JSON.parse(
|
|
62936
|
+
const version2 = JSON.parse(readFileSync71(path2, "utf8")).version;
|
|
62576
62937
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
62577
62938
|
} catch {
|
|
62578
62939
|
return void 0;
|
|
62579
62940
|
}
|
|
62580
62941
|
}
|
|
62581
62942
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
62582
|
-
let dir =
|
|
62943
|
+
let dir = resolve47(fromDir);
|
|
62583
62944
|
for (; ; ) {
|
|
62584
|
-
const version2 = packageVersion(
|
|
62945
|
+
const version2 = packageVersion(join56(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
62585
62946
|
if (version2) return { version: version2, source: "local" };
|
|
62586
62947
|
const parent = dirname32(dir);
|
|
62587
62948
|
if (parent === dir) break;
|
|
@@ -62591,7 +62952,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
62591
62952
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
62592
62953
|
try {
|
|
62593
62954
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
62594
|
-
const version2 = root ? packageVersion(
|
|
62955
|
+
const version2 = root ? packageVersion(join56(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
62595
62956
|
return version2 ? { version: version2, source: "global" } : {};
|
|
62596
62957
|
} catch {
|
|
62597
62958
|
return {};
|
|
@@ -62638,11 +62999,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
62638
62999
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
62639
63000
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
62640
63001
|
function updateCachePath(env = process.env) {
|
|
62641
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
63002
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join56(homedir7(), ".himalaya", "update-check.json");
|
|
62642
63003
|
}
|
|
62643
63004
|
function readUpdateCache(path2) {
|
|
62644
63005
|
try {
|
|
62645
|
-
const parsed = JSON.parse(
|
|
63006
|
+
const parsed = JSON.parse(readFileSync71(path2, "utf8"));
|
|
62646
63007
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
62647
63008
|
} catch {
|
|
62648
63009
|
return {};
|
|
@@ -62681,7 +63042,7 @@ function globalPrefixWritable() {
|
|
|
62681
63042
|
const root = globalNodeModulesRoot();
|
|
62682
63043
|
if (!root) return false;
|
|
62683
63044
|
try {
|
|
62684
|
-
accessSync(root,
|
|
63045
|
+
accessSync(root, constants2.W_OK);
|
|
62685
63046
|
return true;
|
|
62686
63047
|
} catch {
|
|
62687
63048
|
return false;
|
|
@@ -62710,12 +63071,12 @@ function createUpdateRunner(spawn7 = spawnSync5) {
|
|
|
62710
63071
|
},
|
|
62711
63072
|
installedVersion: () => {
|
|
62712
63073
|
const root = globalNodeModulesRoot();
|
|
62713
|
-
return root ? packageVersion(
|
|
63074
|
+
return root ? packageVersion(join56(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
62714
63075
|
},
|
|
62715
63076
|
reexec: (argv) => {
|
|
62716
63077
|
const root = globalNodeModulesRoot();
|
|
62717
|
-
const entry = root ?
|
|
62718
|
-
if (!entry || !
|
|
63078
|
+
const entry = root ? join56(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
63079
|
+
if (!entry || !existsSync60(entry)) return void 0;
|
|
62719
63080
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
62720
63081
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
62721
63082
|
stdio: "inherit",
|
|
@@ -62743,7 +63104,7 @@ function thisHost() {
|
|
|
62743
63104
|
return hostname().replace(/\s+/g, "_");
|
|
62744
63105
|
}
|
|
62745
63106
|
function lockStamp(now) {
|
|
62746
|
-
return `${now} ${process.pid} ${thisHost()} ${
|
|
63107
|
+
return `${now} ${process.pid} ${thisHost()} ${randomUUID5()}`;
|
|
62747
63108
|
}
|
|
62748
63109
|
function processAlive(pid) {
|
|
62749
63110
|
try {
|
|
@@ -62762,7 +63123,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62762
63123
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
62763
63124
|
let content;
|
|
62764
63125
|
try {
|
|
62765
|
-
content =
|
|
63126
|
+
content = readFileSync71(path2, "utf8");
|
|
62766
63127
|
} catch {
|
|
62767
63128
|
continue;
|
|
62768
63129
|
}
|
|
@@ -62770,7 +63131,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62770
63131
|
let since = stamped;
|
|
62771
63132
|
if (!Number.isFinite(since)) {
|
|
62772
63133
|
try {
|
|
62773
|
-
since =
|
|
63134
|
+
since = statSync17(path2).mtimeMs;
|
|
62774
63135
|
} catch {
|
|
62775
63136
|
continue;
|
|
62776
63137
|
}
|
|
@@ -62785,7 +63146,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62785
63146
|
const mine = lockStamp(now);
|
|
62786
63147
|
const readLock = (path2) => {
|
|
62787
63148
|
try {
|
|
62788
|
-
return
|
|
63149
|
+
return readFileSync71(path2, "utf8");
|
|
62789
63150
|
} catch {
|
|
62790
63151
|
return void 0;
|
|
62791
63152
|
}
|
|
@@ -62800,7 +63161,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62800
63161
|
};
|
|
62801
63162
|
const removeIfMine = (path2) => {
|
|
62802
63163
|
try {
|
|
62803
|
-
if (readLock(path2) === mine)
|
|
63164
|
+
if (readLock(path2) === mine) rmSync13(path2, { force: true });
|
|
62804
63165
|
} catch {
|
|
62805
63166
|
}
|
|
62806
63167
|
};
|
|
@@ -62823,7 +63184,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62823
63184
|
hooks.underBreakLock?.();
|
|
62824
63185
|
if (current === void 0) return tryCreate(lockPath) ? release : void 0;
|
|
62825
63186
|
if (!isAbandoned(current)) return void 0;
|
|
62826
|
-
|
|
63187
|
+
rmSync13(lockPath, { force: true });
|
|
62827
63188
|
return tryCreate(lockPath) ? release : void 0;
|
|
62828
63189
|
} finally {
|
|
62829
63190
|
removeIfMine(breakPath);
|
|
@@ -63323,10 +63684,10 @@ function executableOnPath(name, env = process.env) {
|
|
|
63323
63684
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
63324
63685
|
for (const dir of entries) {
|
|
63325
63686
|
for (const suffix of suffixes) {
|
|
63326
|
-
const candidate =
|
|
63687
|
+
const candidate = join56(dir, `${name}${suffix}`);
|
|
63327
63688
|
try {
|
|
63328
|
-
if (!
|
|
63329
|
-
if (process.platform !== "win32") accessSync(candidate,
|
|
63689
|
+
if (!statSync17(candidate).isFile()) continue;
|
|
63690
|
+
if (process.platform !== "win32") accessSync(candidate, constants2.X_OK);
|
|
63330
63691
|
return true;
|
|
63331
63692
|
} catch {
|
|
63332
63693
|
}
|
|
@@ -63432,7 +63793,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63432
63793
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
63433
63794
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
63434
63795
|
const iosYmlPath = iosProjectYml2(app);
|
|
63435
|
-
const iosYml =
|
|
63796
|
+
const iosYml = existsSync60(iosYmlPath) ? readFileSync71(iosYmlPath, "utf8") : "";
|
|
63436
63797
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
63437
63798
|
if (!optedIn) {
|
|
63438
63799
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -63446,7 +63807,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63446
63807
|
}
|
|
63447
63808
|
function readConfigSource(dir) {
|
|
63448
63809
|
try {
|
|
63449
|
-
return
|
|
63810
|
+
return readFileSync71(join56(dir, "config.ts"), "utf8");
|
|
63450
63811
|
} catch {
|
|
63451
63812
|
return null;
|
|
63452
63813
|
}
|
|
@@ -63457,8 +63818,8 @@ function writePngFile(path2, base64) {
|
|
|
63457
63818
|
return path2;
|
|
63458
63819
|
}
|
|
63459
63820
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
63460
|
-
const dir =
|
|
63461
|
-
if (
|
|
63821
|
+
const dir = resolve47(parentDir, name);
|
|
63822
|
+
if (existsSync60(join56(dir, "himalaya.content.json"))) {
|
|
63462
63823
|
throw new Error(`content package already exists at ${dir}`);
|
|
63463
63824
|
}
|
|
63464
63825
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -63470,7 +63831,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
63470
63831
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
63471
63832
|
}
|
|
63472
63833
|
function contentDir(flags) {
|
|
63473
|
-
return
|
|
63834
|
+
return resolve47(str5(flags.content) ?? process.cwd());
|
|
63474
63835
|
}
|
|
63475
63836
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
63476
63837
|
const text5 = {};
|
|
@@ -63488,7 +63849,7 @@ function renameRestoredSource(restored, declaredApp, renamed) {
|
|
|
63488
63849
|
function symlinkDestinationIssue(dest) {
|
|
63489
63850
|
let kind;
|
|
63490
63851
|
try {
|
|
63491
|
-
kind =
|
|
63852
|
+
kind = lstatSync8(dest);
|
|
63492
63853
|
} catch {
|
|
63493
63854
|
return null;
|
|
63494
63855
|
}
|
|
@@ -63501,8 +63862,8 @@ function symlinkDestinationIssue(dest) {
|
|
|
63501
63862
|
function restoreDestinationIssue(dest, force) {
|
|
63502
63863
|
const link = symlinkDestinationIssue(dest);
|
|
63503
63864
|
if (link) return link;
|
|
63504
|
-
if (!
|
|
63505
|
-
if (!
|
|
63865
|
+
if (!existsSync60(dest)) return null;
|
|
63866
|
+
if (!statSync17(dest).isDirectory()) {
|
|
63506
63867
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
63507
63868
|
}
|
|
63508
63869
|
if (readdirSync27(dest).length > 0 && !force) {
|
|
@@ -63514,9 +63875,9 @@ function restoreDestinationIssue(dest, force) {
|
|
|
63514
63875
|
return null;
|
|
63515
63876
|
}
|
|
63516
63877
|
function isHimalayaMonorepoCheckout(start) {
|
|
63517
|
-
let dir =
|
|
63878
|
+
let dir = resolve47(start);
|
|
63518
63879
|
for (; ; ) {
|
|
63519
|
-
if (
|
|
63880
|
+
if (existsSync60(join56(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync60(join56(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
63520
63881
|
const parent = dirname32(dir);
|
|
63521
63882
|
if (parent === dir) return false;
|
|
63522
63883
|
dir = parent;
|
|
@@ -63558,8 +63919,8 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63558
63919
|
const forBuild = Object.fromEntries(
|
|
63559
63920
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
63560
63921
|
);
|
|
63561
|
-
const repoRoot2 =
|
|
63562
|
-
const root =
|
|
63922
|
+
const repoRoot2 = resolve47(fileURLToPath24(new URL("../../..", import.meta.url)));
|
|
63923
|
+
const root = join56(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
63563
63924
|
const stillRunning = (pid) => {
|
|
63564
63925
|
try {
|
|
63565
63926
|
process.kill(pid, 0);
|
|
@@ -63573,21 +63934,21 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63573
63934
|
if (!entry.isDirectory()) continue;
|
|
63574
63935
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
63575
63936
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
63576
|
-
|
|
63937
|
+
rmSync13(join56(root, entry.name), { recursive: true, force: true });
|
|
63577
63938
|
}
|
|
63578
63939
|
}
|
|
63579
63940
|
} catch {
|
|
63580
63941
|
}
|
|
63581
|
-
const dest =
|
|
63582
|
-
|
|
63942
|
+
const dest = join56(root, `${slug}-${process.pid}`);
|
|
63943
|
+
rmSync13(dest, { recursive: true, force: true });
|
|
63583
63944
|
mkdirSync30(dest, { recursive: true });
|
|
63584
63945
|
materializeSource(forBuild, displayName, dest, slug);
|
|
63585
63946
|
return dest;
|
|
63586
63947
|
}
|
|
63587
63948
|
async function appId(dir) {
|
|
63588
63949
|
try {
|
|
63589
|
-
const { readFileSync:
|
|
63590
|
-
const m = JSON.parse(
|
|
63950
|
+
const { readFileSync: readFileSync72 } = await import("node:fs");
|
|
63951
|
+
const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
|
|
63591
63952
|
if (m.name) return m.name;
|
|
63592
63953
|
} catch {
|
|
63593
63954
|
}
|
|
@@ -63595,8 +63956,8 @@ async function appId(dir) {
|
|
|
63595
63956
|
}
|
|
63596
63957
|
async function contentVisibility(dir) {
|
|
63597
63958
|
try {
|
|
63598
|
-
const { readFileSync:
|
|
63599
|
-
const m = JSON.parse(
|
|
63959
|
+
const { readFileSync: readFileSync72 } = await import("node:fs");
|
|
63960
|
+
const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
|
|
63600
63961
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
63601
63962
|
} catch {
|
|
63602
63963
|
}
|
|
@@ -63798,7 +64159,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
63798
64159
|
return 0;
|
|
63799
64160
|
}
|
|
63800
64161
|
case "agent-init": {
|
|
63801
|
-
const dir =
|
|
64162
|
+
const dir = resolve47(str5(flags.dir) ?? process.cwd());
|
|
63802
64163
|
const res = writeAgentContext(dir);
|
|
63803
64164
|
print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
|
|
63804
64165
|
return 0;
|
|
@@ -63820,7 +64181,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
63820
64181
|
try {
|
|
63821
64182
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63822
64183
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
63823
|
-
out = mkdtempSync4(
|
|
64184
|
+
out = mkdtempSync4(join56(tmpdir5(), "himi-ux-record-"));
|
|
63824
64185
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63825
64186
|
const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
63826
64187
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -63833,7 +64194,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
63833
64194
|
return null;
|
|
63834
64195
|
} finally {
|
|
63835
64196
|
if (out !== void 0) try {
|
|
63836
|
-
|
|
64197
|
+
rmSync13(out, { recursive: true, force: true });
|
|
63837
64198
|
} catch {
|
|
63838
64199
|
}
|
|
63839
64200
|
}
|
|
@@ -63998,7 +64359,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
63998
64359
|
let js;
|
|
63999
64360
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
64000
64361
|
try {
|
|
64001
|
-
js =
|
|
64362
|
+
js = readFileSync71(join56(outDir, candidate), "utf8");
|
|
64002
64363
|
break;
|
|
64003
64364
|
} catch {
|
|
64004
64365
|
}
|
|
@@ -64029,7 +64390,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
64029
64390
|
}
|
|
64030
64391
|
return { families, source: "dist/bundles" };
|
|
64031
64392
|
}
|
|
64032
|
-
var boardOpen = (dir) =>
|
|
64393
|
+
var boardOpen = (dir) => existsSync60(join56(dir, ".himi", "studio", "index.html"));
|
|
64033
64394
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
64034
64395
|
async function leaveForBoard(dir, record2, value) {
|
|
64035
64396
|
if (!boardOpen(dir)) return;
|
|
@@ -64296,7 +64657,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64296
64657
|
return 2;
|
|
64297
64658
|
}
|
|
64298
64659
|
const template = str5(flags.template);
|
|
64299
|
-
const parentDir =
|
|
64660
|
+
const parentDir = resolve47(str5(flags.dir) ?? process.cwd());
|
|
64300
64661
|
if (template && flags.remote === true) {
|
|
64301
64662
|
try {
|
|
64302
64663
|
const res2 = await initFromRemoteTemplate(name, parentDir, template, client2());
|
|
@@ -64413,11 +64774,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64413
64774
|
return outcome.code;
|
|
64414
64775
|
}
|
|
64415
64776
|
if (sub === "publish") {
|
|
64416
|
-
const appDir2 =
|
|
64417
|
-
const sourceDir =
|
|
64777
|
+
const appDir2 = resolve47(str5(flags.dir) ?? process.cwd());
|
|
64778
|
+
const sourceDir = resolve47(str5(flags["source-dir"]) ?? appDir2);
|
|
64418
64779
|
let meta;
|
|
64419
64780
|
try {
|
|
64420
|
-
meta = JSON.parse(
|
|
64781
|
+
meta = JSON.parse(readFileSync71(join56(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
64421
64782
|
} catch {
|
|
64422
64783
|
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>)` }));
|
|
64423
64784
|
return 2;
|
|
@@ -64427,7 +64788,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64427
64788
|
return 2;
|
|
64428
64789
|
}
|
|
64429
64790
|
try {
|
|
64430
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
64791
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync71(join56(sourceDir, "tokens.json"), "utf8")));
|
|
64431
64792
|
meta = { ...appearance, ...meta };
|
|
64432
64793
|
} catch {
|
|
64433
64794
|
}
|
|
@@ -64439,13 +64800,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64439
64800
|
const force = flags.force === true;
|
|
64440
64801
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64441
64802
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
64442
|
-
const out = mkdtempSync4(
|
|
64803
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-template-"));
|
|
64443
64804
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64444
64805
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
64445
64806
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
64446
64807
|
collect: { lint: true, strict }
|
|
64447
64808
|
});
|
|
64448
|
-
const scaffoldSourceFindings =
|
|
64809
|
+
const scaffoldSourceFindings = resolve47(sourceDir) === resolve47(appDir2) ? [] : [
|
|
64449
64810
|
...tokenColorIssues(sourceDir),
|
|
64450
64811
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
64451
64812
|
...await fontIssues(sourceDir, strict),
|
|
@@ -64488,11 +64849,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64488
64849
|
}));
|
|
64489
64850
|
return 1;
|
|
64490
64851
|
}
|
|
64491
|
-
const iconPath = str5(flags.icon) ?
|
|
64852
|
+
const iconPath = str5(flags.icon) ? resolve47(str5(flags.icon)) : templateIconPath(name);
|
|
64492
64853
|
let iconHash;
|
|
64493
64854
|
if (iconPath) {
|
|
64494
64855
|
try {
|
|
64495
|
-
const bytes2 =
|
|
64856
|
+
const bytes2 = readFileSync71(iconPath);
|
|
64496
64857
|
payload.icon = bytes2.toString("base64");
|
|
64497
64858
|
iconHash = createHash26("sha256").update(bytes2).digest("hex");
|
|
64498
64859
|
} catch {
|
|
@@ -64725,7 +65086,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64725
65086
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
64726
65087
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64727
65088
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
64728
|
-
const out = mkdtempSync4(
|
|
65089
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-validate-"));
|
|
64729
65090
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64730
65091
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
64731
65092
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64768,7 +65129,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64768
65129
|
const path2 = dpxSessionTokenPath();
|
|
64769
65130
|
let raw;
|
|
64770
65131
|
try {
|
|
64771
|
-
raw =
|
|
65132
|
+
raw = readFileSync71(path2, "utf8");
|
|
64772
65133
|
} catch {
|
|
64773
65134
|
throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
|
|
64774
65135
|
}
|
|
@@ -64888,7 +65249,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64888
65249
|
case "studio": {
|
|
64889
65250
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
64890
65251
|
const dir = contentDir(flags);
|
|
64891
|
-
if (!
|
|
65252
|
+
if (!existsSync60(join56(dir, "himalaya.content.json"))) {
|
|
64892
65253
|
io.error(JSON.stringify({ ok: false, error: "not_a_content_package", dir, hint: "run from the app directory (or pass --content <dir>) \u2014 the board reads that package's .himi/" }));
|
|
64893
65254
|
return 2;
|
|
64894
65255
|
}
|
|
@@ -64913,7 +65274,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64913
65274
|
const { appendProgress: appendProgress2, readProgress: readProgress2, summarizeProgress: summarizeProgress2, parseStep: parseStep2, notifyDesktop: notifyDesktop2, appLabel: appLabel2, journalPath: journalPath2, ProgressError: ProgressError2, JOURNEY_STEPS: JOURNEY_STEPS2 } = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
64914
65275
|
const dir = contentDir(flags);
|
|
64915
65276
|
const journal = journalPath2(dir);
|
|
64916
|
-
const hint =
|
|
65277
|
+
const hint = existsSync60(join56(dir, "himalaya.content.json")) ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
|
|
64917
65278
|
const message = pos.slice(1).join(" ").trim();
|
|
64918
65279
|
if (!message) {
|
|
64919
65280
|
if (flags.step !== void 0 || flags.image !== void 0 || flags.notify === true) {
|
|
@@ -65005,7 +65366,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65005
65366
|
case "test": {
|
|
65006
65367
|
const dir = contentDir(flags);
|
|
65007
65368
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
65008
|
-
if (
|
|
65369
|
+
if (existsSync60(join56(dir, "functions"))) {
|
|
65009
65370
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
65010
65371
|
const loaded = await loadFunctionsApp2(dir);
|
|
65011
65372
|
const results = [];
|
|
@@ -65092,7 +65453,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65092
65453
|
}
|
|
65093
65454
|
}
|
|
65094
65455
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65095
|
-
const out = mkdtempSync4(
|
|
65456
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-test-"));
|
|
65096
65457
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65097
65458
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65098
65459
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65137,7 +65498,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65137
65498
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
65138
65499
|
return 2;
|
|
65139
65500
|
}
|
|
65140
|
-
const sources = collectWorkerSources2(
|
|
65501
|
+
const sources = collectWorkerSources2(join56(dir, "tier5-src"), screen.bundleName);
|
|
65141
65502
|
if (!sources) {
|
|
65142
65503
|
io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
65143
65504
|
return 2;
|
|
@@ -65298,7 +65659,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65298
65659
|
const sp = await runShotsPass2({
|
|
65299
65660
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
65300
65661
|
tokens: outcome.tokens,
|
|
65301
|
-
outDir:
|
|
65662
|
+
outDir: join56(dir, ".himi", "shots"),
|
|
65302
65663
|
width: 390,
|
|
65303
65664
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
65304
65665
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -65308,7 +65669,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65308
65669
|
renderDescriptorWeb: renderDescriptorWeb2,
|
|
65309
65670
|
renderPngBatch: renderPngBatch2,
|
|
65310
65671
|
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
65311
|
-
clearDir: (d) =>
|
|
65672
|
+
clearDir: (d) => rmSync13(d, { recursive: true, force: true })
|
|
65312
65673
|
}
|
|
65313
65674
|
});
|
|
65314
65675
|
writtenShots = sp.written;
|
|
@@ -65336,7 +65697,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65336
65697
|
releaseId: result.releaseId,
|
|
65337
65698
|
releasePayload: release,
|
|
65338
65699
|
descriptors: attestedDescriptors,
|
|
65339
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
65700
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join56(dir, ".himi", "shots", name)])),
|
|
65340
65701
|
coverage: {
|
|
65341
65702
|
screens: crawledScreens.size,
|
|
65342
65703
|
actionsDispatched: result.actions.exercised,
|
|
@@ -65426,7 +65787,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65426
65787
|
return 2;
|
|
65427
65788
|
}
|
|
65428
65789
|
try {
|
|
65429
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
65790
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync71(stateArg.replace(/^@/, ""), "utf8");
|
|
65430
65791
|
injectedState = JSON.parse(raw);
|
|
65431
65792
|
} catch (e) {
|
|
65432
65793
|
io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
|
|
@@ -65441,7 +65802,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65441
65802
|
return 2;
|
|
65442
65803
|
}
|
|
65443
65804
|
try {
|
|
65444
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
65805
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync71(inputArg.replace(/^@/, ""), "utf8");
|
|
65445
65806
|
const parsed = JSON.parse(raw);
|
|
65446
65807
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
65447
65808
|
injectedInput = parsed;
|
|
@@ -65490,7 +65851,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65490
65851
|
}
|
|
65491
65852
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65492
65853
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65493
|
-
const out = mkdtempSync4(
|
|
65854
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-render-"));
|
|
65494
65855
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65495
65856
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65496
65857
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65504,11 +65865,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65504
65865
|
const diagnostics = (outcome.lint ?? []).find((s) => s.screenId === screenId)?.issues ?? [];
|
|
65505
65866
|
let pngFile;
|
|
65506
65867
|
let attestationPngFile;
|
|
65507
|
-
const shotPath =
|
|
65868
|
+
const shotPath = join56(dir, ".himi", "shots", `${screenId}.png`);
|
|
65508
65869
|
const pngTarget = typeof flags.png === "string" ? str5(flags.png) : flags.png === true ? shotPath : void 0;
|
|
65509
65870
|
if (pngTarget && r.pngBase64) {
|
|
65510
65871
|
pngFile = writePngFile(pngTarget, r.pngBase64);
|
|
65511
|
-
attestationPngFile =
|
|
65872
|
+
attestationPngFile = resolve47(pngTarget) === resolve47(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
|
|
65512
65873
|
}
|
|
65513
65874
|
if (renderWidth !== void 0 && r.renderable) {
|
|
65514
65875
|
recordRenderWidth(dir, {
|
|
@@ -65832,7 +66193,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65832
66193
|
return 2;
|
|
65833
66194
|
}
|
|
65834
66195
|
const renamed = str5(flags.name);
|
|
65835
|
-
const dest =
|
|
66196
|
+
const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
65836
66197
|
const replace = flags.replace === true;
|
|
65837
66198
|
const force = replace || flags.force === true;
|
|
65838
66199
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -65840,8 +66201,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65840
66201
|
io.error(JSON.stringify(linked));
|
|
65841
66202
|
return 1;
|
|
65842
66203
|
}
|
|
65843
|
-
if (
|
|
65844
|
-
if (!
|
|
66204
|
+
if (existsSync60(dest)) {
|
|
66205
|
+
if (!statSync17(dest).isDirectory()) {
|
|
65845
66206
|
io.error(JSON.stringify({
|
|
65846
66207
|
error: `${dest} exists and is not a directory`,
|
|
65847
66208
|
hint: "pass --out/--name to land somewhere else, or remove the file"
|
|
@@ -65853,7 +66214,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65853
66214
|
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" }));
|
|
65854
66215
|
return 1;
|
|
65855
66216
|
}
|
|
65856
|
-
if (replace && occupied && !
|
|
66217
|
+
if (replace && occupied && !existsSync60(join56(dest, "himalaya.content.json"))) {
|
|
65857
66218
|
io.error(JSON.stringify({
|
|
65858
66219
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
65859
66220
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -65992,7 +66353,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65992
66353
|
const force = flags.force === true;
|
|
65993
66354
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65994
66355
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
65995
|
-
const out = mkdtempSync4(
|
|
66356
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-push-"));
|
|
65996
66357
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65997
66358
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65998
66359
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66464,7 +66825,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66464
66825
|
return 2;
|
|
66465
66826
|
}
|
|
66466
66827
|
try {
|
|
66467
|
-
const res = writePack(
|
|
66828
|
+
const res = writePack(resolve47(releaseDir), only, resolve47(str5(flags.out) ?? process.cwd()));
|
|
66468
66829
|
print({
|
|
66469
66830
|
ok: true,
|
|
66470
66831
|
app: res.app,
|
|
@@ -66513,7 +66874,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66513
66874
|
}
|
|
66514
66875
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66515
66876
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
66516
|
-
const built = mkdtempSync4(
|
|
66877
|
+
const built = mkdtempSync4(join56(tmpdir5(), "himi-pack-"));
|
|
66517
66878
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66518
66879
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
66519
66880
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66530,12 +66891,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66530
66891
|
...await navIssues2(dir, strict)
|
|
66531
66892
|
]);
|
|
66532
66893
|
if (hasErrors && !force) {
|
|
66533
|
-
|
|
66894
|
+
rmSync13(built, { recursive: true, force: true });
|
|
66534
66895
|
print({ ...report2, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
66535
66896
|
return 1;
|
|
66536
66897
|
}
|
|
66537
66898
|
try {
|
|
66538
|
-
const res = writePack(built, app,
|
|
66899
|
+
const res = writePack(built, app, resolve47(str5(flags.out) ?? dir), sourceArchive);
|
|
66539
66900
|
print({
|
|
66540
66901
|
ok: true,
|
|
66541
66902
|
app: res.app,
|
|
@@ -66566,7 +66927,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66566
66927
|
io.error(JSON.stringify({ error: e.message }));
|
|
66567
66928
|
return 1;
|
|
66568
66929
|
} finally {
|
|
66569
|
-
|
|
66930
|
+
rmSync13(built, { recursive: true, force: true });
|
|
66570
66931
|
}
|
|
66571
66932
|
}
|
|
66572
66933
|
// ---- himi import — turn a dev .himi back into an editable content package ----
|
|
@@ -66580,7 +66941,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66580
66941
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
66581
66942
|
let opened;
|
|
66582
66943
|
try {
|
|
66583
|
-
opened = openPackageFile2(
|
|
66944
|
+
opened = openPackageFile2(resolve47(file));
|
|
66584
66945
|
} catch (e) {
|
|
66585
66946
|
io.error(JSON.stringify({ error: e.message }));
|
|
66586
66947
|
return 1;
|
|
@@ -66593,7 +66954,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66593
66954
|
io.error(JSON.stringify({
|
|
66594
66955
|
ok: false,
|
|
66595
66956
|
error: "app_source_not_in_package",
|
|
66596
|
-
detail: `${
|
|
66957
|
+
detail: `${resolve47(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
66597
66958
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
66598
66959
|
}));
|
|
66599
66960
|
return 1;
|
|
@@ -66616,7 +66977,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66616
66977
|
return 1;
|
|
66617
66978
|
}
|
|
66618
66979
|
}
|
|
66619
|
-
const dest =
|
|
66980
|
+
const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
66620
66981
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
66621
66982
|
if (issue2) {
|
|
66622
66983
|
io.error(JSON.stringify(issue2));
|
|
@@ -66701,7 +67062,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66701
67062
|
}
|
|
66702
67063
|
try {
|
|
66703
67064
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
66704
|
-
const opened = openPackageFile2(
|
|
67065
|
+
const opened = openPackageFile2(resolve47(file));
|
|
66705
67066
|
if (!opened.validation.ok || !opened.header) {
|
|
66706
67067
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
66707
67068
|
return 1;
|
|
@@ -66711,12 +67072,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66711
67072
|
io.error(JSON.stringify({
|
|
66712
67073
|
ok: false,
|
|
66713
67074
|
error: "refusing to share a package that carries the app's source",
|
|
66714
|
-
detail: `${
|
|
67075
|
+
detail: `${resolve47(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
|
|
66715
67076
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
66716
67077
|
}));
|
|
66717
67078
|
return 1;
|
|
66718
67079
|
}
|
|
66719
|
-
const archive =
|
|
67080
|
+
const archive = readFileSync71(resolve47(file));
|
|
66720
67081
|
const result = await client2().createPackageShare({
|
|
66721
67082
|
app: opened.header.app,
|
|
66722
67083
|
releaseId: opened.header.releaseId,
|
|
@@ -66747,16 +67108,33 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66747
67108
|
const { runPackage: runPackage2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
66748
67109
|
let source = pos[1];
|
|
66749
67110
|
let temp = null;
|
|
67111
|
+
const watch2 = flags.watch === true;
|
|
67112
|
+
if (watch2) {
|
|
67113
|
+
const { watchFlagConflict: watchFlagConflict2, watchedContentDir: watchedContentDir2 } = await Promise.resolve().then(() => (init_run_watch(), run_watch_exports));
|
|
67114
|
+
const watchedDir = watchedContentDir2(source);
|
|
67115
|
+
if (watchedDir) {
|
|
67116
|
+
flags.content = watchedDir;
|
|
67117
|
+
source = void 0;
|
|
67118
|
+
}
|
|
67119
|
+
const conflict = watchFlagConflict2({ source, browser: flags.browser === true, spa: str5(flags.spa) });
|
|
67120
|
+
if (conflict) {
|
|
67121
|
+
io.error(JSON.stringify({ ok: false, ...conflict }));
|
|
67122
|
+
return 2;
|
|
67123
|
+
}
|
|
67124
|
+
}
|
|
67125
|
+
let served = null;
|
|
67126
|
+
let servedMissing = [];
|
|
66750
67127
|
try {
|
|
66751
67128
|
if (!source) {
|
|
66752
|
-
const
|
|
66753
|
-
const app = await appId(
|
|
67129
|
+
const dir2 = contentDir(flags);
|
|
67130
|
+
const app = await appId(dir2);
|
|
66754
67131
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66755
|
-
const bres = await buildContentBundles2(
|
|
66756
|
-
temp = mkdtempSync4(
|
|
67132
|
+
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
67133
|
+
temp = mkdtempSync4(join56(tmpdir5(), "himi-run-build-"));
|
|
66757
67134
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66758
|
-
await buildReleaseFromContent2(
|
|
66759
|
-
|
|
67135
|
+
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
67136
|
+
servedMissing = initial.missingBundles;
|
|
67137
|
+
source = join56(temp, app);
|
|
66760
67138
|
}
|
|
66761
67139
|
const chromeArg = str5(flags.chrome) ?? "preview";
|
|
66762
67140
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -66781,45 +67159,142 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66781
67159
|
open: flags["no-open"] !== true
|
|
66782
67160
|
});
|
|
66783
67161
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
66784
|
-
await new Promise((
|
|
67162
|
+
await new Promise((resolve48) => {
|
|
66785
67163
|
const stop = () => {
|
|
66786
|
-
void run2.close().finally(() =>
|
|
67164
|
+
void run2.close().finally(() => resolve48());
|
|
66787
67165
|
};
|
|
66788
67166
|
process.once("SIGINT", stop);
|
|
66789
67167
|
process.once("SIGTERM", stop);
|
|
66790
67168
|
});
|
|
66791
67169
|
return 0;
|
|
66792
67170
|
}
|
|
67171
|
+
const dir = contentDir(flags);
|
|
67172
|
+
const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
67173
|
+
const bus = watchKit ? new watchKit.ReloadBus() : void 0;
|
|
67174
|
+
if (watch2) served = mkdtempSync4(join56(tmpdir5(), "himi-run-served-"));
|
|
66793
67175
|
const running = await runPackage2(source, {
|
|
66794
67176
|
port,
|
|
66795
67177
|
chrome: chromeArg,
|
|
66796
67178
|
screen: str5(flags.screen),
|
|
66797
67179
|
surface: str5(flags.surface),
|
|
66798
67180
|
spa: str5(flags.spa),
|
|
66799
|
-
open: flags["no-open"] !== true
|
|
67181
|
+
open: flags["no-open"] !== true,
|
|
67182
|
+
...watchKit && served && bus ? { workDir: served, screenEvents: bus, extraRoutes: (request) => watchKit.boardFile(dir, new URL(request.url).pathname) } : {}
|
|
66800
67183
|
});
|
|
67184
|
+
let watcher;
|
|
67185
|
+
let rebuild;
|
|
67186
|
+
let recorded = false;
|
|
67187
|
+
let stopping = false;
|
|
67188
|
+
const refreshBoard = async () => {
|
|
67189
|
+
if (!boardOpen(dir)) return;
|
|
67190
|
+
const { refreshStudio: refreshStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
67191
|
+
refreshStudio2(dir);
|
|
67192
|
+
};
|
|
67193
|
+
if (watchKit && bus) {
|
|
67194
|
+
try {
|
|
67195
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67196
|
+
const record2 = (build2) => {
|
|
67197
|
+
if (watchKit.writeRunRecord(dir, { url: running.url, port: running.port, pid: process.pid, startedAt, build: build2 })) recorded = true;
|
|
67198
|
+
};
|
|
67199
|
+
record2({ ok: true, at: startedAt });
|
|
67200
|
+
if (!recorded) io.error(JSON.stringify({ watch: "run_record_skipped", message: `${join56(dir, ".himi")} is not a real directory, so the build board will not frame this preview.` }));
|
|
67201
|
+
await refreshBoard();
|
|
67202
|
+
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
67203
|
+
const live2 = join56(running.releaseRoot, running.app);
|
|
67204
|
+
const manifestOf = (tree) => JSON.parse(readFileSync71(join56(tree, "release-manifest.json"), "utf8"));
|
|
67205
|
+
let current = manifestOf(live2);
|
|
67206
|
+
const failed2 = async (message) => {
|
|
67207
|
+
if (stopping) return;
|
|
67208
|
+
bus.publish("build.failed", { message });
|
|
67209
|
+
record2({ ok: false, at: (/* @__PURE__ */ new Date()).toISOString(), error: message });
|
|
67210
|
+
await refreshBoard();
|
|
67211
|
+
io.error(JSON.stringify({ watch: "build_failed", keptLastGood: true, message }));
|
|
67212
|
+
};
|
|
67213
|
+
rebuild = watchKit.serialize(async () => {
|
|
67214
|
+
const t0 = Date.now();
|
|
67215
|
+
const next = mkdtempSync4(join56(tmpdir5(), "himi-run-build-"));
|
|
67216
|
+
try {
|
|
67217
|
+
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
67218
|
+
if (bres.compileErrors.length) {
|
|
67219
|
+
const first = bres.compileErrors[0];
|
|
67220
|
+
const diag = first.errors[0];
|
|
67221
|
+
await failed2(`${first.bundle}: ${diag ? `${diag.file ? `${diag.file}${diag.line ? `:${diag.line}` : ""} ` : ""}${diag.text}` : "did not compile"}`);
|
|
67222
|
+
return;
|
|
67223
|
+
}
|
|
67224
|
+
const hasWorkers = bres.built.length > 0;
|
|
67225
|
+
const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
|
|
67226
|
+
const blocker = watchKit.rebuildBlocker(outcome, servedMissing);
|
|
67227
|
+
if (blocker) {
|
|
67228
|
+
await failed2(blocker);
|
|
67229
|
+
return;
|
|
67230
|
+
}
|
|
67231
|
+
if (stopping) return;
|
|
67232
|
+
const fresh = manifestOf(join56(next, running.app));
|
|
67233
|
+
const diff = watchKit.diffReleases(current, fresh);
|
|
67234
|
+
const retired = `${live2}.retired-${Date.now()}`;
|
|
67235
|
+
renameSync6(live2, retired);
|
|
67236
|
+
try {
|
|
67237
|
+
renameSync6(join56(next, running.app), live2);
|
|
67238
|
+
} catch {
|
|
67239
|
+
cpSync3(join56(next, running.app), live2, { recursive: true });
|
|
67240
|
+
}
|
|
67241
|
+
rmSync13(retired, { recursive: true, force: true });
|
|
67242
|
+
current = fresh;
|
|
67243
|
+
servedMissing = outcome.missingBundles;
|
|
67244
|
+
for (const [event, data] of watchKit.reloadEvents(diff)) bus.publish(event, data);
|
|
67245
|
+
record2({ ok: true, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
67246
|
+
await refreshBoard();
|
|
67247
|
+
io.error(JSON.stringify({ watch: "rebuilt", ms: Date.now() - t0, screens: diff.screens, tokens: diff.tokens, config: diff.config, tabs: bus.listeners }));
|
|
67248
|
+
} catch (e) {
|
|
67249
|
+
await failed2(e.message.split("\n")[0]);
|
|
67250
|
+
} finally {
|
|
67251
|
+
rmSync13(next, { recursive: true, force: true });
|
|
67252
|
+
}
|
|
67253
|
+
});
|
|
67254
|
+
watcher = watchKit.watchContent(dir, () => rebuild?.());
|
|
67255
|
+
} catch (e) {
|
|
67256
|
+
if (recorded) watchKit.removeRunRecord(dir);
|
|
67257
|
+
await running.close();
|
|
67258
|
+
throw e;
|
|
67259
|
+
}
|
|
67260
|
+
}
|
|
66801
67261
|
print({
|
|
66802
67262
|
ok: true,
|
|
66803
67263
|
app: running.app,
|
|
66804
67264
|
releaseId: running.releaseId,
|
|
66805
67265
|
url: running.url,
|
|
66806
67266
|
port: running.port,
|
|
67267
|
+
...watch2 ? { watching: dir, ...boardOpen(dir) ? { board: `${running.origin}/__himi/studio/` } : {} } : {},
|
|
66807
67268
|
...running.warnings.length ? { warnings: running.warnings } : {},
|
|
66808
67269
|
stop: "Ctrl-C"
|
|
66809
67270
|
});
|
|
66810
67271
|
await new Promise((done) => {
|
|
66811
|
-
const stop = () => {
|
|
66812
|
-
|
|
67272
|
+
const stop = async () => {
|
|
67273
|
+
stopping = true;
|
|
67274
|
+
watcher?.close();
|
|
67275
|
+
try {
|
|
67276
|
+
await rebuild?.stop();
|
|
67277
|
+
if (recorded) {
|
|
67278
|
+
watchKit?.removeRunRecord(dir);
|
|
67279
|
+
await refreshBoard();
|
|
67280
|
+
}
|
|
67281
|
+
} catch (e) {
|
|
67282
|
+
io.error(JSON.stringify({ watch: "stop_cleanup_failed", message: e.message }));
|
|
67283
|
+
} finally {
|
|
67284
|
+
await running.close();
|
|
67285
|
+
done();
|
|
67286
|
+
}
|
|
66813
67287
|
};
|
|
66814
|
-
process.once("SIGINT", stop);
|
|
66815
|
-
process.once("SIGTERM", stop);
|
|
67288
|
+
process.once("SIGINT", () => void stop());
|
|
67289
|
+
process.once("SIGTERM", () => void stop());
|
|
66816
67290
|
});
|
|
66817
67291
|
return 0;
|
|
66818
67292
|
} catch (e) {
|
|
66819
67293
|
io.error(JSON.stringify({ error: e.message }));
|
|
66820
67294
|
return 1;
|
|
66821
67295
|
} finally {
|
|
66822
|
-
if (temp)
|
|
67296
|
+
if (temp) rmSync13(temp, { recursive: true, force: true });
|
|
67297
|
+
if (served) rmSync13(served, { recursive: true, force: true });
|
|
66823
67298
|
}
|
|
66824
67299
|
}
|
|
66825
67300
|
case "preview": {
|
|
@@ -67360,7 +67835,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67360
67835
|
io.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
67361
67836
|
return 2;
|
|
67362
67837
|
}
|
|
67363
|
-
if (!
|
|
67838
|
+
if (!existsSync60(file)) {
|
|
67364
67839
|
io.error(JSON.stringify({ error: `no such file: ${file}` }));
|
|
67365
67840
|
return 2;
|
|
67366
67841
|
}
|
|
@@ -67416,7 +67891,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67416
67891
|
lintNote: "`himi patch` sends a raw file. Nothing here built or linted your app \u2014 `himi push --only <selector>` is the same edit with the full lint gate in front of it."
|
|
67417
67892
|
};
|
|
67418
67893
|
if (kind === "tokens" || kind === "app-config") {
|
|
67419
|
-
const body =
|
|
67894
|
+
const body = readFileSync71(file, "utf8");
|
|
67420
67895
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
67421
67896
|
return runReleasePatch({
|
|
67422
67897
|
...common,
|
|
@@ -67431,7 +67906,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67431
67906
|
io.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
67432
67907
|
return 2;
|
|
67433
67908
|
}
|
|
67434
|
-
const descriptor =
|
|
67909
|
+
const descriptor = readFileSync71(file, "utf8");
|
|
67435
67910
|
try {
|
|
67436
67911
|
JSON.parse(descriptor);
|
|
67437
67912
|
} catch (e) {
|
|
@@ -67471,7 +67946,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67471
67946
|
extra: { kind, screen: id, file: { path: file, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
67472
67947
|
});
|
|
67473
67948
|
}
|
|
67474
|
-
const bytes2 =
|
|
67949
|
+
const bytes2 = readFileSync71(file);
|
|
67475
67950
|
const sha = createHash26("sha256").update(bytes2).digest("hex");
|
|
67476
67951
|
const forScreens = (str5(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
67477
67952
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
@@ -67615,7 +68090,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67615
68090
|
}
|
|
67616
68091
|
let def;
|
|
67617
68092
|
try {
|
|
67618
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
68093
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync71(arg.slice(1), "utf8") : arg);
|
|
67619
68094
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
67620
68095
|
io.error(JSON.stringify({ error: "invalid_definition", problems: [`--definition must be a JSON object, got ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`] }));
|
|
67621
68096
|
return 2;
|
|
@@ -68079,7 +68554,7 @@ ${label2}`);
|
|
|
68079
68554
|
const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
68080
68555
|
{
|
|
68081
68556
|
const distDir = contentDir(flags);
|
|
68082
|
-
if (
|
|
68557
|
+
if (existsSync60(join56(distDir, "himalaya.content.json"))) {
|
|
68083
68558
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
68084
68559
|
const errors = issues.filter((i) => i.severity === "error");
|
|
68085
68560
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|
|
@@ -68348,7 +68823,7 @@ ${label2}`);
|
|
|
68348
68823
|
const dpxPath = dpxSessionTokenPath();
|
|
68349
68824
|
let dpx;
|
|
68350
68825
|
try {
|
|
68351
|
-
dpx =
|
|
68826
|
+
dpx = readFileSync71(dpxPath, "utf8").trim();
|
|
68352
68827
|
} catch {
|
|
68353
68828
|
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` }));
|
|
68354
68829
|
return 1;
|
|
@@ -68750,7 +69225,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
68750
69225
|
const path2 = dpxSessionTokenPath();
|
|
68751
69226
|
let raw;
|
|
68752
69227
|
try {
|
|
68753
|
-
raw =
|
|
69228
|
+
raw = readFileSync71(path2, "utf8");
|
|
68754
69229
|
} catch {
|
|
68755
69230
|
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
68756
69231
|
return 1;
|