@wix/himalaya-cli 0.1013.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 +977 -486
- 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
|
}
|
|
@@ -45887,6 +45924,29 @@ var init_assets = __esm({
|
|
|
45887
45924
|
}
|
|
45888
45925
|
});
|
|
45889
45926
|
|
|
45927
|
+
// ../../core/serve-runtime/src/pinned-read.ts
|
|
45928
|
+
async function checkPinnedRead(input) {
|
|
45929
|
+
const { secret, token, app, releaseId, screenId, authorizePreview } = input;
|
|
45930
|
+
if (!secret) return authorizePreview ? { status: 503, body: { error: "preview_token_unavailable" } } : null;
|
|
45931
|
+
if (!token) return await input.isLive() ? null : { status: 401, body: { error: "preview_token_required", app, releaseId } };
|
|
45932
|
+
const verified = await verifyPreviewToken({ token, secret, app, releaseId, screenId });
|
|
45933
|
+
if (verified.ok) {
|
|
45934
|
+
if (authorizePreview ? !await authorizePreview(verified.claims) : !!verified.claims.siteLease) {
|
|
45935
|
+
return { status: 403, body: { error: "site_preview_forbidden" } };
|
|
45936
|
+
}
|
|
45937
|
+
return null;
|
|
45938
|
+
}
|
|
45939
|
+
return {
|
|
45940
|
+
status: verified.error === "scope_mismatch" ? 403 : 401,
|
|
45941
|
+
body: { error: `preview_token_${verified.error}`, app, releaseId, ...screenId ? { screenId } : {} }
|
|
45942
|
+
};
|
|
45943
|
+
}
|
|
45944
|
+
var init_pinned_read = __esm({
|
|
45945
|
+
"../../core/serve-runtime/src/pinned-read.ts"() {
|
|
45946
|
+
init_preview_token();
|
|
45947
|
+
}
|
|
45948
|
+
});
|
|
45949
|
+
|
|
45890
45950
|
// ../../core/serve-runtime/package-share.ts
|
|
45891
45951
|
function parseStored(bytes2, id) {
|
|
45892
45952
|
if (!bytes2) return null;
|
|
@@ -46093,6 +46153,15 @@ function json3(status, body, headers2 = {}) {
|
|
|
46093
46153
|
function isCookieAuthorizedPath(path2) {
|
|
46094
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;
|
|
46095
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
|
+
}
|
|
46096
46165
|
function makeServeHandler(opts) {
|
|
46097
46166
|
let storePromise = null;
|
|
46098
46167
|
const getStore = () => storePromise ??= (async () => {
|
|
@@ -46222,23 +46291,16 @@ ${releaseId}`;
|
|
|
46222
46291
|
return new Response(body, { status: 200, headers: { "content-type": JSON_CT, etag, "cache-control": cache, ...vary } });
|
|
46223
46292
|
}
|
|
46224
46293
|
async function authorizePinnedRead(request, url, app, releaseId, screenId) {
|
|
46225
|
-
const
|
|
46226
|
-
|
|
46227
|
-
|
|
46228
|
-
const live2 = await manifest(app);
|
|
46229
|
-
const isLive = live2?.releaseId === releaseId;
|
|
46230
|
-
if (!token) return isLive ? null : json3(401, { error: "preview_token_required", app, releaseId });
|
|
46231
|
-
const verified = await verifyPreviewToken({ token, secret, app, releaseId, screenId });
|
|
46232
|
-
if (verified.ok) {
|
|
46233
|
-
if (opts.authorizePreview ? !await opts.authorizePreview(verified.claims) : !!verified.claims.siteLease) return json3(403, { error: "site_preview_forbidden" });
|
|
46234
|
-
return null;
|
|
46235
|
-
}
|
|
46236
|
-
return json3(verified.error === "scope_mismatch" ? 403 : 401, {
|
|
46237
|
-
error: `preview_token_${verified.error}`,
|
|
46294
|
+
const denied = await checkPinnedRead({
|
|
46295
|
+
secret: opts.previewTokenSecret,
|
|
46296
|
+
token: resolvePreviewToken(request, url),
|
|
46238
46297
|
app,
|
|
46239
46298
|
releaseId,
|
|
46240
|
-
|
|
46299
|
+
screenId,
|
|
46300
|
+
isLive: async () => (await manifest(app))?.releaseId === releaseId,
|
|
46301
|
+
authorizePreview: opts.authorizePreview
|
|
46241
46302
|
});
|
|
46303
|
+
return denied && json3(denied.status, denied.body);
|
|
46242
46304
|
}
|
|
46243
46305
|
const corsHeaders = (request) => {
|
|
46244
46306
|
const origin = request.headers.get("origin");
|
|
@@ -46406,83 +46468,109 @@ ${releaseId}`;
|
|
|
46406
46468
|
return json3(200, { authenticated: false, userId: null, email: null, webwixDirect }, { "cache-control": "no-store" });
|
|
46407
46469
|
}
|
|
46408
46470
|
if (request.method === "POST" && path2 === "/v1/__webwix/call") {
|
|
46409
|
-
|
|
46410
|
-
|
|
46411
|
-
}
|
|
46412
|
-
const app2 = resolveApp(request, url);
|
|
46413
|
-
if (!app2) return json3(400, { error: "app_required" });
|
|
46414
|
-
const resolvedCfg = await appConfigFor(request, url, app2);
|
|
46415
|
-
if (!resolvedCfg.ok) return resolvedCfg.response;
|
|
46416
|
-
const cfgBytes = resolvedCfg.bytes;
|
|
46417
|
-
let call;
|
|
46471
|
+
const served = { rung: "none" };
|
|
46472
|
+
let status = 500;
|
|
46418
46473
|
try {
|
|
46419
|
-
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
}
|
|
46423
|
-
if (call.checkOwnerSession !== void 0 && (typeof call.checkOwnerSession !== "boolean" || call.checkOwnerSession && call.ownerMsid === void 0)) {
|
|
46424
|
-
return json3(400, { error: "invalid_owner_session_check" });
|
|
46425
|
-
}
|
|
46426
|
-
const method = String(call.method ?? "GET").toUpperCase();
|
|
46427
|
-
const reqPath = String(call.path ?? "/");
|
|
46428
|
-
const body = call.body === void 0 ? void 0 : typeof call.body === "string" ? call.body : JSON.stringify(call.body);
|
|
46429
|
-
const forwardedHeaders = normalizeWixForwardedHeaders(call.headers);
|
|
46430
|
-
const callerCookie = request.headers.get("cookie") ?? "";
|
|
46431
|
-
if (!call.checkOwnerSession && webwixOwnerRungOn() && method === "POST" && isOwnerSitesPath(reqPath) && /wixSession2=/.test(callerCookie)) {
|
|
46432
|
-
try {
|
|
46433
|
-
const envelope = await wixOwnerSitesCall(reqPath, callerCookie, body, webwixFetch);
|
|
46434
|
-
if (envelope.status >= 200 && envelope.status < 300) return json3(200, envelope);
|
|
46435
|
-
return json3(200, {
|
|
46436
|
-
status: 501,
|
|
46437
|
-
body: JSON.stringify({ error: "webwix_owner_sites_failed", upstream: envelope.status })
|
|
46438
|
-
});
|
|
46439
|
-
} catch (e) {
|
|
46440
|
-
return json3(200, {
|
|
46441
|
-
status: 501,
|
|
46442
|
-
body: JSON.stringify({ error: "webwix_owner_sites_failed", detail: String(e?.message ?? e).slice(0, 200) })
|
|
46443
|
-
});
|
|
46444
|
-
}
|
|
46445
|
-
}
|
|
46446
|
-
if (call.ownerMsid !== void 0) {
|
|
46447
|
-
if (!webwixOwnerRungOn()) {
|
|
46448
|
-
return json3(503, { error: "webwix_owner_disabled" });
|
|
46449
|
-
}
|
|
46450
|
-
const msid = String(call.ownerMsid);
|
|
46451
|
-
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
46452
|
-
const cookie = request.headers.get("cookie") ?? "";
|
|
46453
|
-
if (!/wixSession2=/.test(cookie)) return json3(501, { error: "webwix_owner_no_session", app: app2 });
|
|
46454
|
-
try {
|
|
46455
|
-
const instance = await webwixOwnerInstances.instance(msid, cookie);
|
|
46456
|
-
if (call.checkOwnerSession === true) return json3(200, { status: 200, body: JSON.stringify({ ready: true }) }, { "cache-control": "no-store" });
|
|
46457
|
-
const first = await wixVisitorCall(method, reqPath, body, instance, webwixFetch, forwardedHeaders);
|
|
46458
|
-
if (first.status !== 401) return json3(200, first);
|
|
46459
|
-
webwixOwnerInstances.invalidate(msid, cookie);
|
|
46460
|
-
const fresh = await webwixOwnerInstances.instance(msid, cookie);
|
|
46461
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46462
|
-
} catch (e) {
|
|
46463
|
-
const msg = String(e?.message ?? e);
|
|
46464
|
-
if (msg.includes("absolute URLs")) {
|
|
46465
|
-
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" });
|
|
46466
46477
|
}
|
|
46467
|
-
|
|
46468
|
-
|
|
46469
|
-
|
|
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" });
|
|
46489
|
+
}
|
|
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
|
+
}
|
|
46470
46566
|
}
|
|
46471
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46472
|
-
}
|
|
46473
|
-
}
|
|
46474
|
-
const resolved2 = wixClientIdOf(utf8Decode(cfgBytes));
|
|
46475
|
-
if ("error" in resolved2) {
|
|
46476
|
-
return json3(501, { error: `webwix_bridge_${resolved2.error}`, app: app2 });
|
|
46477
|
-
}
|
|
46478
|
-
const memberStore = memberSessions();
|
|
46479
|
-
const memberBoundApp = memberApp(request);
|
|
46480
|
-
if (memberAuthOn() && memberStore && memberBoundApp !== null && memberBoundApp === app2) {
|
|
46481
|
-
const nowAuth = wixMemberAuthOf(utf8Decode(cfgBytes), callbackUrlFor(url));
|
|
46482
|
-
const memberToken = nowAuth.ok ? await memberTokenFor(memberStore, readSessionCookie(request.headers.get("cookie")), memberBoundApp, nowAuth.config.clientId) : null;
|
|
46483
|
-
if (memberToken) {
|
|
46484
46567
|
try {
|
|
46485
|
-
|
|
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));
|
|
46486
46574
|
} catch (e) {
|
|
46487
46575
|
const msg = String(e?.message ?? e);
|
|
46488
46576
|
if (msg.includes("absolute URLs")) {
|
|
@@ -46490,22 +46578,15 @@ ${releaseId}`;
|
|
|
46490
46578
|
}
|
|
46491
46579
|
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46492
46580
|
}
|
|
46581
|
+
})();
|
|
46582
|
+
status = res.status;
|
|
46583
|
+
return res;
|
|
46584
|
+
} finally {
|
|
46585
|
+
try {
|
|
46586
|
+
opts.onWebwixCall?.(webwixCallLog(served, status));
|
|
46587
|
+
} catch {
|
|
46493
46588
|
}
|
|
46494
46589
|
}
|
|
46495
|
-
try {
|
|
46496
|
-
const token = await webwixTokens.token(resolved2.clientId);
|
|
46497
|
-
const first = await wixVisitorCall(method, reqPath, body, token, webwixFetch, forwardedHeaders);
|
|
46498
|
-
if (first.status !== 401) return json3(200, first);
|
|
46499
|
-
webwixTokens.invalidate(resolved2.clientId);
|
|
46500
|
-
const fresh = await webwixTokens.token(resolved2.clientId);
|
|
46501
|
-
return json3(200, await wixVisitorCall(method, reqPath, body, fresh, webwixFetch, forwardedHeaders));
|
|
46502
|
-
} catch (e) {
|
|
46503
|
-
const msg = String(e?.message ?? e);
|
|
46504
|
-
if (msg.includes("absolute URLs")) {
|
|
46505
|
-
return absoluteUrlRejection(reqPath) === "owner-only" ? json3(501, { error: "webwix_owner_only", app: app2 }) : json3(400, { error: "absolute_urls_not_allowed" });
|
|
46506
|
-
}
|
|
46507
|
-
return json3(502, { error: "webwix_bridge_upstream_failed", detail: msg.slice(0, 200) });
|
|
46508
|
-
}
|
|
46509
46590
|
}
|
|
46510
46591
|
if (request.method !== "GET") return json3(405, { error: "method_not_allowed" });
|
|
46511
46592
|
if (path2 === "/__health") return json3(200, { ok: true });
|
|
@@ -46540,6 +46621,11 @@ ${releaseId}`;
|
|
|
46540
46621
|
}
|
|
46541
46622
|
if (path2 === "/v1/owner/instance") {
|
|
46542
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
|
+
}
|
|
46543
46629
|
if (!webwixOwnerRungOn()) return json3(503, { error: "webwix_owner_disabled" });
|
|
46544
46630
|
const msid = url.searchParams.get("msid") ?? "";
|
|
46545
46631
|
if (!isSafeMsid(msid)) return json3(400, { error: "webwix_owner_bad_msid" });
|
|
@@ -46669,6 +46755,10 @@ ${releaseId}`;
|
|
|
46669
46755
|
const cfgMatch = /^\/v1\/app-config\/([^/]+)$/.exec(path2);
|
|
46670
46756
|
const app = cfgMatch?.[1] ?? resolveApp(request, url);
|
|
46671
46757
|
const pin = resolvePin(request, url);
|
|
46758
|
+
if (app && pin) {
|
|
46759
|
+
const denied = await authorizePinnedRead(request, url, app, pin);
|
|
46760
|
+
if (denied) return denied;
|
|
46761
|
+
}
|
|
46672
46762
|
if (path2 === "/v1/template-source") {
|
|
46673
46763
|
if (!app) return json3(400, { error: "missing_app" });
|
|
46674
46764
|
if (!store.getSource) return json3(501, { error: "templates_unsupported" });
|
|
@@ -46685,10 +46775,6 @@ ${releaseId}`;
|
|
|
46685
46775
|
headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
|
|
46686
46776
|
});
|
|
46687
46777
|
}
|
|
46688
|
-
if (app && pin) {
|
|
46689
|
-
const denied = await authorizePinnedRead(request, url, app, pin);
|
|
46690
|
-
if (denied) return denied;
|
|
46691
|
-
}
|
|
46692
46778
|
if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
|
|
46693
46779
|
if (!app) return json3(400, { error: "missing_app" });
|
|
46694
46780
|
const m = pin ? await pinnedManifest(app, pin) : await manifest(app);
|
|
@@ -47008,7 +47094,7 @@ var init_server = __esm({
|
|
|
47008
47094
|
init_store();
|
|
47009
47095
|
init_base64();
|
|
47010
47096
|
init_contract();
|
|
47011
|
-
|
|
47097
|
+
init_pinned_read();
|
|
47012
47098
|
init_package_share();
|
|
47013
47099
|
init_wix_bridge();
|
|
47014
47100
|
init_wix_member_auth();
|
|
@@ -47198,8 +47284,29 @@ function makeRunHandler(opts) {
|
|
|
47198
47284
|
return new Response(null, { status: 204 });
|
|
47199
47285
|
}
|
|
47200
47286
|
if (path2 === "/v1/screen-events") {
|
|
47201
|
-
|
|
47202
|
-
|
|
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, {
|
|
47203
47310
|
status: 200,
|
|
47204
47311
|
headers: { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" }
|
|
47205
47312
|
});
|
|
@@ -47262,6 +47369,24 @@ async function toRequest(req) {
|
|
|
47262
47369
|
async function writeResponse(res, response) {
|
|
47263
47370
|
res.statusCode = response.status;
|
|
47264
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
|
+
}
|
|
47265
47390
|
const ab = await response.arrayBuffer();
|
|
47266
47391
|
res.end(ab.byteLength ? Buffer.from(ab) : void 0);
|
|
47267
47392
|
}
|
|
@@ -47324,19 +47449,19 @@ var init_preview_assets_generated = __esm({
|
|
|
47324
47449
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
47325
47450
|
init_preview_assets_format();
|
|
47326
47451
|
PREVIEW_ASSET_MANIFEST = [
|
|
47327
|
-
{ key: "assets/index-
|
|
47328
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
47329
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47330
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
47331
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
47332
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47333
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
47334
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47335
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
47336
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
47337
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47338
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
47339
|
-
{ 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" }
|
|
47340
47465
|
];
|
|
47341
47466
|
}
|
|
47342
47467
|
});
|
|
@@ -47352,7 +47477,7 @@ __export(run_exports, {
|
|
|
47352
47477
|
runPackage: () => runPackage,
|
|
47353
47478
|
withoutProdServe: () => withoutProdServe
|
|
47354
47479
|
});
|
|
47355
|
-
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";
|
|
47356
47481
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
47357
47482
|
import { dirname as dirname27, join as join49 } from "node:path";
|
|
47358
47483
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
@@ -47362,7 +47487,8 @@ function makePackageRunHandler(opts) {
|
|
|
47362
47487
|
app: opts.app,
|
|
47363
47488
|
assets: opts.assets,
|
|
47364
47489
|
...opts.chrome ? { chrome: opts.chrome } : {},
|
|
47365
|
-
header: opts.header ?? null
|
|
47490
|
+
header: opts.header ?? null,
|
|
47491
|
+
...opts.screenEvents ? { screenEvents: opts.screenEvents } : {}
|
|
47366
47492
|
});
|
|
47367
47493
|
}
|
|
47368
47494
|
async function fetchBytes(url) {
|
|
@@ -47386,8 +47512,8 @@ async function resolvePackage(source, workDir) {
|
|
|
47386
47512
|
const root2 = workDir ?? mkdtempSync3(join49(tmpdir4(), "himi-run-"));
|
|
47387
47513
|
const target = join49(root2, app2);
|
|
47388
47514
|
if (join49(source) !== target) {
|
|
47389
|
-
|
|
47390
|
-
|
|
47515
|
+
mkdirSync25(root2, { recursive: true });
|
|
47516
|
+
rmSync11(target, { recursive: true, force: true });
|
|
47391
47517
|
cpSync2(source, target, { recursive: true });
|
|
47392
47518
|
}
|
|
47393
47519
|
return {
|
|
@@ -47407,7 +47533,7 @@ async function resolvePackage(source, workDir) {
|
|
|
47407
47533
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
47408
47534
|
const opened = openPackageDir(appDir2);
|
|
47409
47535
|
if (!opened.validation.ok) {
|
|
47410
|
-
|
|
47536
|
+
rmSync11(workDir ? appDir2 : root, { recursive: true, force: true });
|
|
47411
47537
|
throw new Error(`package is not valid:
|
|
47412
47538
|
${opened.validation.errors.join("\n ")}`);
|
|
47413
47539
|
}
|
|
@@ -47454,16 +47580,19 @@ async function runPackage(source, opts = {}) {
|
|
|
47454
47580
|
const resolved2 = await resolvePackage(source, opts.workDir);
|
|
47455
47581
|
const assets = opts.assets ?? (opts.spa ? /* @__PURE__ */ new Map() : await loadPreviewAssets());
|
|
47456
47582
|
if (!opts.spa && assets.size === 0) {
|
|
47457
|
-
if (resolved2.temp)
|
|
47583
|
+
if (resolved2.temp) rmSync11(resolved2.temp, { recursive: true, force: true });
|
|
47458
47584
|
throw new Error(NO_SPA_MESSAGE);
|
|
47459
47585
|
}
|
|
47460
|
-
const
|
|
47586
|
+
const plane = makePackageRunHandler({
|
|
47461
47587
|
releaseRoot: resolved2.releaseRoot,
|
|
47462
47588
|
app: resolved2.app,
|
|
47463
47589
|
assets,
|
|
47464
47590
|
chrome: opts.chrome,
|
|
47465
|
-
header: resolved2.header
|
|
47591
|
+
header: resolved2.header,
|
|
47592
|
+
...opts.screenEvents ? { screenEvents: opts.screenEvents } : {}
|
|
47466
47593
|
});
|
|
47594
|
+
const extra = opts.extraRoutes;
|
|
47595
|
+
const handler = extra ? (request) => extra(request) ?? plane(request) : plane;
|
|
47467
47596
|
const server = nodeAdapter(handler);
|
|
47468
47597
|
const host = opts.host ?? "127.0.0.1";
|
|
47469
47598
|
const port = await new Promise((resolvePort, reject) => {
|
|
@@ -47481,10 +47610,13 @@ async function runPackage(source, opts = {}) {
|
|
|
47481
47610
|
releaseId: resolved2.releaseId,
|
|
47482
47611
|
port,
|
|
47483
47612
|
url,
|
|
47613
|
+
releaseRoot: resolved2.releaseRoot,
|
|
47614
|
+
origin,
|
|
47484
47615
|
warnings: resolved2.warnings,
|
|
47485
47616
|
close: () => new Promise((done) => {
|
|
47617
|
+
server.closeAllConnections?.();
|
|
47486
47618
|
server.close(() => {
|
|
47487
|
-
if (resolved2.temp)
|
|
47619
|
+
if (resolved2.temp) rmSync11(resolved2.temp, { recursive: true, force: true });
|
|
47488
47620
|
done();
|
|
47489
47621
|
});
|
|
47490
47622
|
})
|
|
@@ -47504,6 +47636,250 @@ var init_run = __esm({
|
|
|
47504
47636
|
}
|
|
47505
47637
|
});
|
|
47506
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
|
+
|
|
47507
47883
|
// src/run-browser.ts
|
|
47508
47884
|
var run_browser_exports = {};
|
|
47509
47885
|
__export(run_browser_exports, {
|
|
@@ -47512,19 +47888,19 @@ __export(run_browser_exports, {
|
|
|
47512
47888
|
runInBrowser: () => runInBrowser
|
|
47513
47889
|
});
|
|
47514
47890
|
import { createServer as createServer5 } from "node:http";
|
|
47515
|
-
import { existsSync as
|
|
47891
|
+
import { existsSync as existsSync54, readFileSync as readFileSync59 } from "node:fs";
|
|
47516
47892
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
47517
|
-
import { dirname as dirname28, resolve as
|
|
47893
|
+
import { dirname as dirname28, resolve as resolve43 } from "node:path";
|
|
47518
47894
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
47519
47895
|
function stagedDir() {
|
|
47520
|
-
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");
|
|
47521
47897
|
}
|
|
47522
47898
|
function missingStaged() {
|
|
47523
|
-
return [...SERVED].filter((f) => !
|
|
47899
|
+
return [...SERVED].filter((f) => !existsSync54(resolve43(stagedDir(), f))).sort();
|
|
47524
47900
|
}
|
|
47525
47901
|
function ensureBrowserPlaneStaged() {
|
|
47526
47902
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
47527
|
-
const r = spawnSync3(process.execPath, [
|
|
47903
|
+
const r = spawnSync3(process.execPath, [resolve43(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
|
|
47528
47904
|
cwd: REPO,
|
|
47529
47905
|
encoding: "utf8"
|
|
47530
47906
|
});
|
|
@@ -47610,7 +47986,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
47610
47986
|
}
|
|
47611
47987
|
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
47612
47988
|
if (SERVED.has(name)) {
|
|
47613
|
-
if (!
|
|
47989
|
+
if (!existsSync54(resolve43(stagedDir(), name))) {
|
|
47614
47990
|
const restaged = ensureBrowserPlaneStaged();
|
|
47615
47991
|
if (!restaged.ok) {
|
|
47616
47992
|
res.writeHead(503, { "content-type": "application/json" });
|
|
@@ -47620,7 +47996,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
47620
47996
|
}
|
|
47621
47997
|
let bytes2;
|
|
47622
47998
|
try {
|
|
47623
|
-
bytes2 =
|
|
47999
|
+
bytes2 = readFileSync59(resolve43(stagedDir(), name));
|
|
47624
48000
|
} catch (e) {
|
|
47625
48001
|
res.writeHead(503, { "content-type": "application/json" });
|
|
47626
48002
|
res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
|
|
@@ -47661,7 +48037,7 @@ var init_run_browser = __esm({
|
|
|
47661
48037
|
init_open_url();
|
|
47662
48038
|
init_file_store();
|
|
47663
48039
|
HERE = dirname28(fileURLToPath23(import.meta.url));
|
|
47664
|
-
REPO =
|
|
48040
|
+
REPO = resolve43(HERE, "..", "..", "..");
|
|
47665
48041
|
SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
|
|
47666
48042
|
}
|
|
47667
48043
|
});
|
|
@@ -48080,10 +48456,10 @@ __export(preflight_exports, {
|
|
|
48080
48456
|
parseStoreConfig: () => parseStoreConfig,
|
|
48081
48457
|
requireEnv: () => requireEnv
|
|
48082
48458
|
});
|
|
48083
|
-
import { existsSync as
|
|
48084
|
-
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";
|
|
48085
48461
|
function isInsideRepo(p) {
|
|
48086
|
-
const rel = relative9(REPO_ROOT3,
|
|
48462
|
+
const rel = relative9(REPO_ROOT3, resolve44(p));
|
|
48087
48463
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
|
|
48088
48464
|
}
|
|
48089
48465
|
function assertCredentialOutsideRepo(label2, p) {
|
|
@@ -48137,10 +48513,10 @@ function parseStoreConfig(text5) {
|
|
|
48137
48513
|
}
|
|
48138
48514
|
function loadStoreConfig(app) {
|
|
48139
48515
|
const p = storeConfigPath(app);
|
|
48140
|
-
if (!
|
|
48516
|
+
if (!existsSync55(p)) {
|
|
48141
48517
|
throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
48142
48518
|
}
|
|
48143
|
-
return parseStoreConfig(
|
|
48519
|
+
return parseStoreConfig(readFileSync60(p, "utf8"));
|
|
48144
48520
|
}
|
|
48145
48521
|
var init_preflight = __esm({
|
|
48146
48522
|
"../store-release/preflight.ts"() {
|
|
@@ -48159,19 +48535,19 @@ __export(credential_profile_exports, {
|
|
|
48159
48535
|
profilePath: () => profilePath,
|
|
48160
48536
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
48161
48537
|
});
|
|
48162
|
-
import { existsSync as
|
|
48538
|
+
import { existsSync as existsSync56, readFileSync as readFileSync61 } from "node:fs";
|
|
48163
48539
|
import { homedir as homedir5 } from "node:os";
|
|
48164
|
-
import { join as
|
|
48540
|
+
import { join as join51 } from "node:path";
|
|
48165
48541
|
function credentialsDir(home = homedir5()) {
|
|
48166
|
-
return
|
|
48542
|
+
return join51(home, ".himalaya", "store-credentials");
|
|
48167
48543
|
}
|
|
48168
48544
|
function profilePath(name, home = homedir5()) {
|
|
48169
48545
|
if (!PROFILE_NAME.test(name)) {
|
|
48170
48546
|
throw new Error(
|
|
48171
|
-
`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.`
|
|
48172
48548
|
);
|
|
48173
48549
|
}
|
|
48174
|
-
return
|
|
48550
|
+
return join51(credentialsDir(home), `${name}.json`);
|
|
48175
48551
|
}
|
|
48176
48552
|
function parseProfile(text5, label2) {
|
|
48177
48553
|
let doc;
|
|
@@ -48202,8 +48578,8 @@ function resolveStoreCredentials(opts) {
|
|
|
48202
48578
|
const { app, cfg } = opts;
|
|
48203
48579
|
const env = opts.env ?? process.env;
|
|
48204
48580
|
const home = opts.home ?? homedir5();
|
|
48205
|
-
const read = opts.readProfile ?? ((p) =>
|
|
48206
|
-
const exists = opts.profileExists ??
|
|
48581
|
+
const read = opts.readProfile ?? ((p) => readFileSync61(p, "utf8"));
|
|
48582
|
+
const exists = opts.profileExists ?? existsSync56;
|
|
48207
48583
|
const ios = cfg.ios ?? {};
|
|
48208
48584
|
const flagName = opts.profileFlag?.trim();
|
|
48209
48585
|
const named = namedProfile(cfg, opts.profileFlag);
|
|
@@ -48283,9 +48659,9 @@ __export(preflight_app_exports, {
|
|
|
48283
48659
|
preflightApp: () => preflightApp,
|
|
48284
48660
|
profileAccount: () => profileAccount
|
|
48285
48661
|
});
|
|
48286
|
-
import { readFileSync as
|
|
48662
|
+
import { readFileSync as readFileSync62, existsSync as existsSync57, readdirSync as readdirSync26, statSync as statSync15 } from "node:fs";
|
|
48287
48663
|
import { createHash as createHash25 } from "node:crypto";
|
|
48288
|
-
import { join as
|
|
48664
|
+
import { join as join52 } from "node:path";
|
|
48289
48665
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
48290
48666
|
const f = [];
|
|
48291
48667
|
const has = (re, s) => re.test(s);
|
|
@@ -48349,13 +48725,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
48349
48725
|
}
|
|
48350
48726
|
}
|
|
48351
48727
|
async function preflightApp(app, opts = {}) {
|
|
48352
|
-
const projectYml =
|
|
48353
|
-
const storeConfig =
|
|
48728
|
+
const projectYml = existsSync57(iosProjectYml(app)) ? readFileSync62(iosProjectYml(app), "utf8") : "";
|
|
48729
|
+
const storeConfig = existsSync57(storeConfigPath(app)) ? readFileSync62(storeConfigPath(app), "utf8") : "";
|
|
48354
48730
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
48355
48731
|
const findings = analyze(
|
|
48356
48732
|
projectYml,
|
|
48357
48733
|
storeConfig,
|
|
48358
|
-
await appIconState(
|
|
48734
|
+
await appIconState(join52(appDir(app), "ios")),
|
|
48359
48735
|
profileAccount(app, storeConfig, opts)
|
|
48360
48736
|
);
|
|
48361
48737
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -48384,17 +48760,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
48384
48760
|
return f;
|
|
48385
48761
|
}
|
|
48386
48762
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
48387
|
-
const root =
|
|
48763
|
+
const root = join52(storeDir(app), "metadata");
|
|
48388
48764
|
const out = /* @__PURE__ */ new Set();
|
|
48389
|
-
if (
|
|
48765
|
+
if (existsSync57(root)) {
|
|
48390
48766
|
for (const n of readdirSync26(root)) if (n.endsWith(".txt")) out.add(n);
|
|
48391
48767
|
}
|
|
48392
|
-
if (
|
|
48768
|
+
if (existsSync57(join52(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
48393
48769
|
return out;
|
|
48394
48770
|
}
|
|
48395
48771
|
function reviewInfoFiles(app) {
|
|
48396
|
-
const dir =
|
|
48397
|
-
if (!
|
|
48772
|
+
const dir = join52(storeDir(app), "review_information");
|
|
48773
|
+
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48398
48774
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48399
48775
|
}
|
|
48400
48776
|
function isValidAppStoreSize(w, h) {
|
|
@@ -48504,12 +48880,12 @@ function analyzePlayListing(assets) {
|
|
|
48504
48880
|
return f;
|
|
48505
48881
|
}
|
|
48506
48882
|
function playListingAssets(app, locale = "en-US") {
|
|
48507
|
-
const dir =
|
|
48883
|
+
const dir = join52(storeDir(app), "play", locale, "images");
|
|
48508
48884
|
const read = (names) => {
|
|
48509
48885
|
for (const name of names) {
|
|
48510
|
-
const p =
|
|
48886
|
+
const p = join52(dir, name);
|
|
48511
48887
|
try {
|
|
48512
|
-
if (
|
|
48888
|
+
if (statSync15(p).isFile()) return { name, bytes: readFileSync62(p) };
|
|
48513
48889
|
} catch {
|
|
48514
48890
|
}
|
|
48515
48891
|
}
|
|
@@ -48540,26 +48916,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
48540
48916
|
return f;
|
|
48541
48917
|
}
|
|
48542
48918
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
48543
|
-
const dir =
|
|
48544
|
-
if (!
|
|
48919
|
+
const dir = join52(storeDir(app), "metadata", locale);
|
|
48920
|
+
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48545
48921
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48546
48922
|
}
|
|
48547
48923
|
function listScreenshots(app, locale = "en-US") {
|
|
48548
48924
|
const out = [];
|
|
48549
|
-
const flat =
|
|
48550
|
-
if (
|
|
48925
|
+
const flat = join52(storeDir(app), "screenshots", locale);
|
|
48926
|
+
if (existsSync57(flat)) {
|
|
48551
48927
|
for (const png of readdirSync26(flat).filter((n) => n.endsWith(".png"))) {
|
|
48552
|
-
const sz = pngSize(
|
|
48928
|
+
const sz = pngSize(readFileSync62(join52(flat, png)));
|
|
48553
48929
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
48554
48930
|
}
|
|
48555
48931
|
}
|
|
48556
|
-
const legacy =
|
|
48557
|
-
if (
|
|
48932
|
+
const legacy = join52(storeDir(app), "metadata", locale, "screenshots");
|
|
48933
|
+
if (existsSync57(legacy)) {
|
|
48558
48934
|
for (const deviceDir of readdirSync26(legacy)) {
|
|
48559
|
-
const d =
|
|
48560
|
-
if (!
|
|
48935
|
+
const d = join52(legacy, deviceDir);
|
|
48936
|
+
if (!statSync15(d).isDirectory()) continue;
|
|
48561
48937
|
for (const png of readdirSync26(d).filter((n) => n.endsWith(".png"))) {
|
|
48562
|
-
const sz = pngSize(
|
|
48938
|
+
const sz = pngSize(readFileSync62(join52(d, png)));
|
|
48563
48939
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
48564
48940
|
}
|
|
48565
48941
|
}
|
|
@@ -48567,13 +48943,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
48567
48943
|
return out;
|
|
48568
48944
|
}
|
|
48569
48945
|
function placeholderHashes2() {
|
|
48570
|
-
const templateIos =
|
|
48571
|
-
if (!
|
|
48946
|
+
const templateIos = join52(appDir("_template"), "ios");
|
|
48947
|
+
if (!existsSync57(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
48572
48948
|
for (const target of readdirSync26(templateIos)) {
|
|
48573
|
-
const p =
|
|
48949
|
+
const p = join52(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48574
48950
|
try {
|
|
48575
|
-
if (!
|
|
48576
|
-
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")];
|
|
48577
48953
|
} catch {
|
|
48578
48954
|
}
|
|
48579
48955
|
}
|
|
@@ -48604,12 +48980,12 @@ async function pixelIssues(bytes2) {
|
|
|
48604
48980
|
}
|
|
48605
48981
|
}
|
|
48606
48982
|
async function appIconState(iosDir) {
|
|
48607
|
-
if (!
|
|
48983
|
+
if (!existsSync57(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
48608
48984
|
for (const target of readdirSync26(iosDir)) {
|
|
48609
|
-
const p =
|
|
48985
|
+
const p = join52(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48610
48986
|
try {
|
|
48611
|
-
if (!
|
|
48612
|
-
const bytes2 =
|
|
48987
|
+
if (!statSync15(p).isFile()) continue;
|
|
48988
|
+
const bytes2 = readFileSync62(p);
|
|
48613
48989
|
const hash = createHash25("sha256").update(bytes2).digest("hex");
|
|
48614
48990
|
const pixels = await pixelIssues(bytes2);
|
|
48615
48991
|
return {
|
|
@@ -48681,7 +49057,7 @@ __export(version_exports, {
|
|
|
48681
49057
|
setAndroidVersion: () => setAndroidVersion,
|
|
48682
49058
|
setIosVersion: () => setIosVersion
|
|
48683
49059
|
});
|
|
48684
|
-
import { readFileSync as
|
|
49060
|
+
import { readFileSync as readFileSync63, writeFileSync as writeFileSync23 } from "node:fs";
|
|
48685
49061
|
function readIosVersion(projectYml) {
|
|
48686
49062
|
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
48687
49063
|
const build2 = matchScalar(projectYml, "CFBundleVersion");
|
|
@@ -48739,8 +49115,8 @@ function setAndroidVersion(gradle, v) {
|
|
|
48739
49115
|
function bumpVersion(app, opts) {
|
|
48740
49116
|
const iosPath = iosProjectYml(app);
|
|
48741
49117
|
const gradlePath = androidGradle(app);
|
|
48742
|
-
const iosYml =
|
|
48743
|
-
const gradle =
|
|
49118
|
+
const iosYml = readFileSync63(iosPath, "utf8");
|
|
49119
|
+
const gradle = readFileSync63(gradlePath, "utf8");
|
|
48744
49120
|
const current = readIosVersion(iosYml);
|
|
48745
49121
|
const next = {
|
|
48746
49122
|
marketing: opts.marketing ?? current.marketing,
|
|
@@ -48757,7 +49133,7 @@ var init_version = __esm({
|
|
|
48757
49133
|
});
|
|
48758
49134
|
|
|
48759
49135
|
// ../store-release/register-bundle.ts
|
|
48760
|
-
import { readFileSync as
|
|
49136
|
+
import { readFileSync as readFileSync64 } from "node:fs";
|
|
48761
49137
|
import { createPrivateKey as createPrivateKey2, sign } from "node:crypto";
|
|
48762
49138
|
function b64url2(b) {
|
|
48763
49139
|
return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -48775,7 +49151,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
|
|
|
48775
49151
|
async function registerBundleId(opts) {
|
|
48776
49152
|
const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48777
49153
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48778
|
-
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));
|
|
48779
49155
|
const res = await fetch(`${ASC_API}/v1/bundleIds`, {
|
|
48780
49156
|
method: "POST",
|
|
48781
49157
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
@@ -48829,7 +49205,7 @@ __export(asc_status_exports, {
|
|
|
48829
49205
|
ascStatus: () => ascStatus,
|
|
48830
49206
|
buildVerdict: () => buildVerdict
|
|
48831
49207
|
});
|
|
48832
|
-
import { readFileSync as
|
|
49208
|
+
import { readFileSync as readFileSync65 } from "node:fs";
|
|
48833
49209
|
function buildVerdict(builds) {
|
|
48834
49210
|
if (!builds.length) {
|
|
48835
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).";
|
|
@@ -48843,7 +49219,7 @@ function buildVerdict(builds) {
|
|
|
48843
49219
|
function client(creds) {
|
|
48844
49220
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
48845
49221
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
48846
|
-
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));
|
|
48847
49223
|
return async (path2) => {
|
|
48848
49224
|
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
48849
49225
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
@@ -49003,7 +49379,7 @@ __export(secrets_exports, {
|
|
|
49003
49379
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
49004
49380
|
runSecretsCommand: () => runSecretsCommand
|
|
49005
49381
|
});
|
|
49006
|
-
import { readFileSync as
|
|
49382
|
+
import { readFileSync as readFileSync66 } from "node:fs";
|
|
49007
49383
|
function environment(value) {
|
|
49008
49384
|
if (value === "preview" || value === "production") return value;
|
|
49009
49385
|
throw new Error("--environment must be preview or production");
|
|
@@ -49034,7 +49410,7 @@ async function runSecretsCommand(operation, flags, io, options = {}) {
|
|
|
49034
49410
|
io.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
49035
49411
|
return 0;
|
|
49036
49412
|
}
|
|
49037
|
-
const value = options.readValue ? options.readValue() :
|
|
49413
|
+
const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
|
|
49038
49414
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
49039
49415
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
49040
49416
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -49063,7 +49439,7 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
49063
49439
|
}
|
|
49064
49440
|
let body;
|
|
49065
49441
|
if (operation !== "list") {
|
|
49066
|
-
const value = options.readValue ? options.readValue() :
|
|
49442
|
+
const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
|
|
49067
49443
|
body = JSON.stringify({ value });
|
|
49068
49444
|
}
|
|
49069
49445
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -49099,15 +49475,15 @@ __export(notify_exports, {
|
|
|
49099
49475
|
runNotify: () => runNotify,
|
|
49100
49476
|
saveAdminSession: () => saveAdminSession
|
|
49101
49477
|
});
|
|
49102
|
-
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";
|
|
49103
49479
|
import { homedir as homedir6 } from "node:os";
|
|
49104
|
-
import { dirname as dirname30, join as
|
|
49480
|
+
import { dirname as dirname30, join as join53 } from "node:path";
|
|
49105
49481
|
function defaultSessionsPath() {
|
|
49106
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
49482
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join53(homedir6(), ".himalaya", "admin-sessions.json");
|
|
49107
49483
|
}
|
|
49108
49484
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
49109
49485
|
try {
|
|
49110
|
-
return JSON.parse(
|
|
49486
|
+
return JSON.parse(readFileSync67(path2, "utf8"));
|
|
49111
49487
|
} catch {
|
|
49112
49488
|
return {};
|
|
49113
49489
|
}
|
|
@@ -51764,10 +52140,10 @@ function assertPublicSiteUrl(raw) {
|
|
|
51764
52140
|
if (refusal) throw new Error(refusal);
|
|
51765
52141
|
}
|
|
51766
52142
|
function resolveAll(hostname2) {
|
|
51767
|
-
return new Promise((
|
|
52143
|
+
return new Promise((resolve48, reject) => {
|
|
51768
52144
|
dnsLookup(hostname2, { all: true, verbatim: true }, (err, addresses) => {
|
|
51769
52145
|
if (err) reject(err);
|
|
51770
|
-
else
|
|
52146
|
+
else resolve48(addresses);
|
|
51771
52147
|
});
|
|
51772
52148
|
});
|
|
51773
52149
|
}
|
|
@@ -51775,13 +52151,13 @@ function withAbort(start, signal, what) {
|
|
|
51775
52151
|
if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
|
|
51776
52152
|
const work = start();
|
|
51777
52153
|
if (!signal) return work;
|
|
51778
|
-
return new Promise((
|
|
52154
|
+
return new Promise((resolve48, reject) => {
|
|
51779
52155
|
const onAbort = () => reject(new Error(`${what} aborted`));
|
|
51780
52156
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
51781
|
-
work.then(
|
|
52157
|
+
work.then(resolve48, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
51782
52158
|
});
|
|
51783
52159
|
}
|
|
51784
|
-
async function pinAddress(url,
|
|
52160
|
+
async function pinAddress(url, resolve48 = resolveAll, signal) {
|
|
51785
52161
|
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
51786
52162
|
if (ipv4Octets(host)) {
|
|
51787
52163
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
@@ -51791,7 +52167,7 @@ async function pinAddress(url, resolve47 = resolveAll, signal) {
|
|
|
51791
52167
|
if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
|
|
51792
52168
|
return { address: host, family: 6 };
|
|
51793
52169
|
}
|
|
51794
|
-
const addresses = await withAbort(() =>
|
|
52170
|
+
const addresses = await withAbort(() => resolve48(host), signal, `${host} lookup`);
|
|
51795
52171
|
if (!addresses.length) throw new Error(`${host} resolved to no address`);
|
|
51796
52172
|
const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
|
|
51797
52173
|
if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
|
|
@@ -51831,7 +52207,7 @@ function copyIncomingHeaders(headers2) {
|
|
|
51831
52207
|
return out;
|
|
51832
52208
|
}
|
|
51833
52209
|
function requestOnce(url, pinned, init) {
|
|
51834
|
-
return new Promise((
|
|
52210
|
+
return new Promise((resolve48, reject) => {
|
|
51835
52211
|
const headers2 = { host: url.host, "accept-encoding": "identity" };
|
|
51836
52212
|
new Headers(init.headers ?? {}).forEach((value, key2) => {
|
|
51837
52213
|
if (key2.toLowerCase() !== "host") headers2[key2] = value;
|
|
@@ -51861,7 +52237,7 @@ function requestOnce(url, pinned, init) {
|
|
|
51861
52237
|
reject(err);
|
|
51862
52238
|
return;
|
|
51863
52239
|
}
|
|
51864
|
-
|
|
52240
|
+
resolve48(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
|
|
51865
52241
|
}
|
|
51866
52242
|
);
|
|
51867
52243
|
req.on("error", reject);
|
|
@@ -52665,7 +53041,7 @@ var init_brand_font = __esm({
|
|
|
52665
53041
|
|
|
52666
53042
|
// src/site-analyze/write-artifacts.ts
|
|
52667
53043
|
import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync25 } from "node:fs";
|
|
52668
|
-
import { join as
|
|
53044
|
+
import { join as join54 } from "node:path";
|
|
52669
53045
|
function attachVeloSources(book, sources, put) {
|
|
52670
53046
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
52671
53047
|
for (const f of book.velo.files) {
|
|
@@ -52820,12 +53196,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
52820
53196
|
}
|
|
52821
53197
|
async function writeBusinessBook(result, opts) {
|
|
52822
53198
|
const out = opts.outDir;
|
|
52823
|
-
mkdirSync28(
|
|
52824
|
-
mkdirSync28(
|
|
53199
|
+
mkdirSync28(join54(out, "evidence/pages"), { recursive: true });
|
|
53200
|
+
mkdirSync28(join54(out, "media/catalog"), { recursive: true });
|
|
52825
53201
|
const files = [];
|
|
52826
53202
|
const put = (rel, body) => {
|
|
52827
|
-
const p =
|
|
52828
|
-
mkdirSync28(
|
|
53203
|
+
const p = join54(out, rel);
|
|
53204
|
+
mkdirSync28(join54(p, ".."), { recursive: true });
|
|
52829
53205
|
writeFileSync25(p, body);
|
|
52830
53206
|
files.push(rel);
|
|
52831
53207
|
};
|
|
@@ -52919,15 +53295,15 @@ var init_customer_build = __esm({
|
|
|
52919
53295
|
});
|
|
52920
53296
|
|
|
52921
53297
|
// src/site-analyze/apply.ts
|
|
52922
|
-
import { existsSync as
|
|
52923
|
-
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";
|
|
52924
53300
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
52925
53301
|
function unpairedRedirectNote(overlay) {
|
|
52926
53302
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
52927
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)`;
|
|
52928
53304
|
}
|
|
52929
53305
|
function posix2(p) {
|
|
52930
|
-
return
|
|
53306
|
+
return resolve45(p).replace(/\\/g, "/");
|
|
52931
53307
|
}
|
|
52932
53308
|
function committedShellProvisioning(path2) {
|
|
52933
53309
|
return committedShellFor(posix2(path2));
|
|
@@ -52935,7 +53311,7 @@ function committedShellProvisioning(path2) {
|
|
|
52935
53311
|
function findRepoRoot(cwd) {
|
|
52936
53312
|
let dir = cwd;
|
|
52937
53313
|
for (let i = 0; i < 8; i++) {
|
|
52938
|
-
if (SHELL_NAMES2.some((name) =>
|
|
53314
|
+
if (SHELL_NAMES2.some((name) => existsSync58(join55(dir, shellAppDir(name), "package.json")))) return dir;
|
|
52939
53315
|
const next = dirname31(dir);
|
|
52940
53316
|
if (next === dir) break;
|
|
52941
53317
|
dir = next;
|
|
@@ -52961,7 +53337,7 @@ function assertNotCommitted(path2, forbidden) {
|
|
|
52961
53337
|
`refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
|
|
52962
53338
|
);
|
|
52963
53339
|
}
|
|
52964
|
-
if (forbidden &&
|
|
53340
|
+
if (forbidden && resolve45(path2) === resolve45(forbidden)) {
|
|
52965
53341
|
const named = committedShellProvisioning(forbidden);
|
|
52966
53342
|
throw new Error(
|
|
52967
53343
|
`refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
|
|
@@ -53003,35 +53379,35 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
53003
53379
|
}
|
|
53004
53380
|
function buildMergedContract(options) {
|
|
53005
53381
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
53006
|
-
const committedPath =
|
|
53007
|
-
if (!
|
|
53382
|
+
const committedPath = join55(appDir2, "provisioning.json");
|
|
53383
|
+
if (!existsSync58(committedPath)) {
|
|
53008
53384
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
53009
53385
|
}
|
|
53010
|
-
const committed = JSON.parse(
|
|
53386
|
+
const committed = JSON.parse(readFileSync68(committedPath, "utf8"));
|
|
53011
53387
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
53012
53388
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
53013
53389
|
const branding = merged.branding ?? {};
|
|
53014
53390
|
const staged = [];
|
|
53015
53391
|
const contained = (root, rel) => {
|
|
53016
53392
|
if (isAbsolute4(rel)) return void 0;
|
|
53017
|
-
const full =
|
|
53018
|
-
return full.startsWith(
|
|
53393
|
+
const full = resolve45(root, rel);
|
|
53394
|
+
return full.startsWith(resolve45(root) + sep14) ? full : void 0;
|
|
53019
53395
|
};
|
|
53020
53396
|
const stage = (fromRel, toRel) => {
|
|
53021
53397
|
const from = contained(packageDir, fromRel);
|
|
53022
|
-
const to = contained(
|
|
53023
|
-
if (!from || !to || !
|
|
53398
|
+
const to = contained(join55(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
53399
|
+
if (!from || !to || !existsSync58(from)) return void 0;
|
|
53024
53400
|
let real;
|
|
53025
53401
|
let realRoot;
|
|
53026
53402
|
try {
|
|
53027
|
-
real =
|
|
53028
|
-
realRoot =
|
|
53403
|
+
real = realpathSync7(from);
|
|
53404
|
+
realRoot = realpathSync7(packageDir);
|
|
53029
53405
|
} catch {
|
|
53030
53406
|
return void 0;
|
|
53031
53407
|
}
|
|
53032
|
-
if (!real.startsWith(realRoot +
|
|
53408
|
+
if (!real.startsWith(realRoot + sep14)) return void 0;
|
|
53033
53409
|
try {
|
|
53034
|
-
if (!
|
|
53410
|
+
if (!statSync16(real).isFile()) return void 0;
|
|
53035
53411
|
mkdirSync29(dirname31(to), { recursive: true });
|
|
53036
53412
|
copyFileSync3(real, to);
|
|
53037
53413
|
} catch {
|
|
@@ -53042,11 +53418,11 @@ function buildMergedContract(options) {
|
|
|
53042
53418
|
};
|
|
53043
53419
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
53044
53420
|
if (icon) branding.appIconPath = icon;
|
|
53045
|
-
const facesPath =
|
|
53046
|
-
if (
|
|
53421
|
+
const facesPath = join55(packageDir, "media/fonts/faces.json");
|
|
53422
|
+
if (existsSync58(facesPath)) {
|
|
53047
53423
|
let faces = [];
|
|
53048
53424
|
try {
|
|
53049
|
-
const parsed = JSON.parse(
|
|
53425
|
+
const parsed = JSON.parse(readFileSync68(facesPath, "utf8"));
|
|
53050
53426
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
53051
53427
|
} catch {
|
|
53052
53428
|
faces = [];
|
|
@@ -53067,20 +53443,20 @@ function buildMergedContract(options) {
|
|
|
53067
53443
|
merged.branding = branding;
|
|
53068
53444
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
53069
53445
|
`;
|
|
53070
|
-
const path2 =
|
|
53446
|
+
const path2 = join55(packageDir, "provisioning.contract.json");
|
|
53071
53447
|
writeFileSync26(path2, body);
|
|
53072
|
-
const localPath =
|
|
53448
|
+
const localPath = join55(appDir2, LOCAL_CONTRACT_REL);
|
|
53073
53449
|
mkdirSync29(dirname31(localPath), { recursive: true });
|
|
53074
53450
|
writeFileSync26(localPath, body);
|
|
53075
53451
|
staged.push(localPath);
|
|
53076
53452
|
return { path: path2, staged };
|
|
53077
53453
|
}
|
|
53078
53454
|
async function applyOverlays(input) {
|
|
53079
|
-
const cwd =
|
|
53455
|
+
const cwd = resolve45(input.cwd);
|
|
53080
53456
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
53081
53457
|
assertKnownShell(shell);
|
|
53082
|
-
const overlay = JSON.parse(
|
|
53083
|
-
const tokens = JSON.parse(
|
|
53458
|
+
const overlay = JSON.parse(readFileSync68(input.overlayPath, "utf8"));
|
|
53459
|
+
const tokens = JSON.parse(readFileSync68(input.tokensPath, "utf8"));
|
|
53084
53460
|
const wrote = [];
|
|
53085
53461
|
const notes = [];
|
|
53086
53462
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -53090,8 +53466,8 @@ async function applyOverlays(input) {
|
|
|
53090
53466
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
53091
53467
|
);
|
|
53092
53468
|
}
|
|
53093
|
-
const appDir2 =
|
|
53094
|
-
const packageDir = dirname31(
|
|
53469
|
+
const appDir2 = join55(repoRoot2, shellAppDir(shell));
|
|
53470
|
+
const packageDir = dirname31(resolve45(input.overlayPath));
|
|
53095
53471
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
53096
53472
|
wrote.push(...staged);
|
|
53097
53473
|
const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
|
|
@@ -53112,10 +53488,10 @@ async function applyOverlays(input) {
|
|
|
53112
53488
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
53113
53489
|
};
|
|
53114
53490
|
}
|
|
53115
|
-
const pkgProv =
|
|
53491
|
+
const pkgProv = join55(cwd, "provisioning.json");
|
|
53116
53492
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
53117
|
-
if (
|
|
53118
|
-
const cur = JSON.parse(
|
|
53493
|
+
if (existsSync58(pkgProv)) {
|
|
53494
|
+
const cur = JSON.parse(readFileSync68(pkgProv, "utf8"));
|
|
53119
53495
|
const merged = deepMerge4(cur, overlay);
|
|
53120
53496
|
writeFileSync26(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
53121
53497
|
wrote.push(pkgProv);
|
|
@@ -53123,9 +53499,9 @@ async function applyOverlays(input) {
|
|
|
53123
53499
|
writeFileSync26(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
53124
53500
|
wrote.push(pkgProv);
|
|
53125
53501
|
}
|
|
53126
|
-
const pkgTokens =
|
|
53127
|
-
if (
|
|
53128
|
-
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"));
|
|
53129
53505
|
const merged = deepMerge4(cur, tokens);
|
|
53130
53506
|
const mergedColors = merged.colors;
|
|
53131
53507
|
if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
|
|
@@ -53144,9 +53520,9 @@ async function applyOverlays(input) {
|
|
|
53144
53520
|
wrote.push(pkgTokens);
|
|
53145
53521
|
}
|
|
53146
53522
|
const homeAction = homeRefreshActionId(shell);
|
|
53147
|
-
const homeSrc =
|
|
53148
|
-
if (homeAction &&
|
|
53149
|
-
const prev =
|
|
53523
|
+
const homeSrc = join55(cwd, "dev/index.ts");
|
|
53524
|
+
if (homeAction && existsSync58(homeSrc)) {
|
|
53525
|
+
const prev = readFileSync68(homeSrc, "utf8");
|
|
53150
53526
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
53151
53527
|
let next = patched.src;
|
|
53152
53528
|
if (!patched.foreign && overlay.installedVerticals?.length) {
|
|
@@ -53169,13 +53545,13 @@ async function applyOverlays(input) {
|
|
|
53169
53545
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
53170
53546
|
}
|
|
53171
53547
|
}
|
|
53172
|
-
if (!input.iconPath || !
|
|
53173
|
-
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;
|
|
53174
53550
|
notes.push(
|
|
53175
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"
|
|
53176
53552
|
);
|
|
53177
53553
|
}
|
|
53178
|
-
if (input.iconPath &&
|
|
53554
|
+
if (input.iconPath && existsSync58(input.iconPath)) {
|
|
53179
53555
|
try {
|
|
53180
53556
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
53181
53557
|
wrote.push(...installed.wrote);
|
|
@@ -54113,10 +54489,10 @@ function permuteDomain(domain, allowSpecialUseDomain) {
|
|
|
54113
54489
|
}
|
|
54114
54490
|
function createPromiseCallback(cb) {
|
|
54115
54491
|
let callback;
|
|
54116
|
-
let
|
|
54492
|
+
let resolve48;
|
|
54117
54493
|
let reject;
|
|
54118
54494
|
const promise = new Promise((_resolve, _reject) => {
|
|
54119
|
-
|
|
54495
|
+
resolve48 = _resolve;
|
|
54120
54496
|
reject = _reject;
|
|
54121
54497
|
});
|
|
54122
54498
|
if (typeof cb === "function") {
|
|
@@ -54132,7 +54508,7 @@ function createPromiseCallback(cb) {
|
|
|
54132
54508
|
callback = (err, result) => {
|
|
54133
54509
|
try {
|
|
54134
54510
|
if (err) reject(err);
|
|
54135
|
-
else
|
|
54511
|
+
else resolve48(result);
|
|
54136
54512
|
} catch (e) {
|
|
54137
54513
|
reject(e instanceof Error ? e : new Error());
|
|
54138
54514
|
}
|
|
@@ -56704,7 +57080,7 @@ var init_crawl_look = __esm({
|
|
|
56704
57080
|
});
|
|
56705
57081
|
|
|
56706
57082
|
// src/site-analyze/site-function.ts
|
|
56707
|
-
import { randomUUID as
|
|
57083
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
56708
57084
|
function createRevisionUrl(msid, esi) {
|
|
56709
57085
|
const q = new URLSearchParams({ editorSessionId: esi, esi, metaSiteId: msid });
|
|
56710
57086
|
return `https://editor.wix.com/html/v1/create_revision?${q}`;
|
|
@@ -57149,7 +57525,7 @@ function codeAppIdFromRevision(json5) {
|
|
|
57149
57525
|
async function snapshotAndPublish(fetchImpl, token, msid, opts = {}) {
|
|
57150
57526
|
const production = opts.production !== false;
|
|
57151
57527
|
const initiator = opts.initiator ?? "himi";
|
|
57152
|
-
const esi =
|
|
57528
|
+
const esi = randomUUID4();
|
|
57153
57529
|
const rev = await veloCall(fetchImpl, "POST", createRevisionUrl(msid, esi), {
|
|
57154
57530
|
token,
|
|
57155
57531
|
msid,
|
|
@@ -57330,8 +57706,8 @@ __export(cli_exports, {
|
|
|
57330
57706
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
57331
57707
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
57332
57708
|
});
|
|
57333
|
-
import { readFileSync as
|
|
57334
|
-
import { resolve as
|
|
57709
|
+
import { readFileSync as readFileSync69 } from "node:fs";
|
|
57710
|
+
import { resolve as resolve46 } from "node:path";
|
|
57335
57711
|
function assetFetchFor(_opts) {
|
|
57336
57712
|
return pinnedFetch2;
|
|
57337
57713
|
}
|
|
@@ -57340,7 +57716,7 @@ async function runSiteAnalyze(opts) {
|
|
|
57340
57716
|
const assetFetch = assetFetchFor(opts);
|
|
57341
57717
|
const siteFetch = guardedSiteFetch;
|
|
57342
57718
|
const cwd = opts.cwd ?? process.cwd();
|
|
57343
|
-
const outDir =
|
|
57719
|
+
const outDir = resolve46(cwd, opts.outDir ?? ".himi/business-book");
|
|
57344
57720
|
let ownerAuth;
|
|
57345
57721
|
let msid;
|
|
57346
57722
|
try {
|
|
@@ -57378,9 +57754,9 @@ async function runSiteAnalyze(opts) {
|
|
|
57378
57754
|
if (opts.apply) {
|
|
57379
57755
|
applied = await applyOverlays({
|
|
57380
57756
|
cwd,
|
|
57381
|
-
overlayPath:
|
|
57382
|
-
tokensPath:
|
|
57383
|
-
iconPath:
|
|
57757
|
+
overlayPath: resolve46(outDir, "provisioning.overlay.json"),
|
|
57758
|
+
tokensPath: resolve46(outDir, "tokens.overlay.json"),
|
|
57759
|
+
iconPath: resolve46(outDir, "media/icon.png"),
|
|
57384
57760
|
shell: opts.shell
|
|
57385
57761
|
});
|
|
57386
57762
|
const note = noteWithWarnings(applied.note, warnings);
|
|
@@ -57416,8 +57792,8 @@ async function runSiteFunctionCli(opts) {
|
|
|
57416
57792
|
const token = opts.token ?? await siteToken(msid);
|
|
57417
57793
|
let source;
|
|
57418
57794
|
if (opts.sourcePath) {
|
|
57419
|
-
const p =
|
|
57420
|
-
source =
|
|
57795
|
+
const p = resolve46(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
57796
|
+
source = readFileSync69(p, "utf8");
|
|
57421
57797
|
}
|
|
57422
57798
|
let body;
|
|
57423
57799
|
if (opts.bodyRaw != null) {
|
|
@@ -57468,7 +57844,7 @@ async function accountToken2(spawnImpl = spawn5) {
|
|
|
57468
57844
|
cached2 = fromEnv;
|
|
57469
57845
|
return fromEnv;
|
|
57470
57846
|
}
|
|
57471
|
-
const token = await new Promise((
|
|
57847
|
+
const token = await new Promise((resolve48, reject) => {
|
|
57472
57848
|
let child;
|
|
57473
57849
|
try {
|
|
57474
57850
|
child = spawnImpl("wix", ["token"]);
|
|
@@ -57497,7 +57873,7 @@ async function accountToken2(spawnImpl = spawn5) {
|
|
|
57497
57873
|
const scan = (d) => {
|
|
57498
57874
|
out += String(d);
|
|
57499
57875
|
const m = out.match(TOKEN_RE2);
|
|
57500
|
-
if (m) done(() =>
|
|
57876
|
+
if (m) done(() => resolve48(m[0]));
|
|
57501
57877
|
};
|
|
57502
57878
|
child.stdout?.on("data", scan);
|
|
57503
57879
|
child.stderr?.on("data", scan);
|
|
@@ -57674,7 +58050,7 @@ __export(site_create_exports, {
|
|
|
57674
58050
|
runSiteList: () => runSiteList,
|
|
57675
58051
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
57676
58052
|
});
|
|
57677
|
-
import { existsSync as
|
|
58053
|
+
import { existsSync as existsSync59, readFileSync as readFileSync70, writeFileSync as writeFileSync27 } from "node:fs";
|
|
57678
58054
|
import { resolve as resolvePath2 } from "node:path";
|
|
57679
58055
|
function oauthClientName(projectName) {
|
|
57680
58056
|
return `${projectName} client`;
|
|
@@ -57823,7 +58199,7 @@ async function runSiteCreate(opts) {
|
|
|
57823
58199
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
57824
58200
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
57825
58201
|
}
|
|
57826
|
-
function writeProvisioningBinding(target, binding2, fs = { existsSync:
|
|
58202
|
+
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync: readFileSync70, writeFileSync: writeFileSync27 }) {
|
|
57827
58203
|
const msid = binding2.siteId;
|
|
57828
58204
|
const path2 = resolvePath2(target);
|
|
57829
58205
|
const committed = committedShellProvisioning(path2);
|
|
@@ -58496,11 +58872,11 @@ var init_context = __esm({
|
|
|
58496
58872
|
});
|
|
58497
58873
|
|
|
58498
58874
|
// src/cli.ts
|
|
58499
|
-
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";
|
|
58500
58876
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
|
|
58501
|
-
import { createHash as createHash26, randomUUID as
|
|
58877
|
+
import { createHash as createHash26, randomUUID as randomUUID5 } from "node:crypto";
|
|
58502
58878
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
58503
|
-
import { join as
|
|
58879
|
+
import { join as join56, resolve as resolve47, relative as relative10, basename as basename13, dirname as dirname32 } from "node:path";
|
|
58504
58880
|
import { fileURLToPath as fileURLToPath24 } from "node:url";
|
|
58505
58881
|
|
|
58506
58882
|
// ../serve-cli/src/client.ts
|
|
@@ -60209,7 +60585,7 @@ async function browserLogin(opts) {
|
|
|
60209
60585
|
const log = opts.log ?? (() => {
|
|
60210
60586
|
});
|
|
60211
60587
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
60212
|
-
return await new Promise((
|
|
60588
|
+
return await new Promise((resolve48, reject) => {
|
|
60213
60589
|
let settled = false;
|
|
60214
60590
|
let loginUrl = "";
|
|
60215
60591
|
const server = createServer();
|
|
@@ -60273,7 +60649,7 @@ async function browserLogin(opts) {
|
|
|
60273
60649
|
return;
|
|
60274
60650
|
}
|
|
60275
60651
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
|
|
60276
|
-
finish2(() =>
|
|
60652
|
+
finish2(() => resolve48({ token, loginUrl }));
|
|
60277
60653
|
});
|
|
60278
60654
|
});
|
|
60279
60655
|
server.on("error", (err) => finish2(() => reject(err)));
|
|
@@ -61776,8 +62152,8 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
61776
62152
|
var num2 = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
61777
62153
|
function embeddedTemplateCatalog() {
|
|
61778
62154
|
return availableTemplates().map((name) => {
|
|
61779
|
-
const path2 =
|
|
61780
|
-
const meta = JSON.parse(
|
|
62155
|
+
const path2 = join56(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
62156
|
+
const meta = JSON.parse(readFileSync71(path2, "utf8"));
|
|
61781
62157
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
61782
62158
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
61783
62159
|
}
|
|
@@ -62059,11 +62435,12 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
62059
62435
|
file is not the plane's per-release archive.
|
|
62060
62436
|
himi share --file <package.himi> [--expires-at <ISO>] | revoke --app <app> <shareId>
|
|
62061
62437
|
publish a content-addressed package link for a released app
|
|
62062
|
-
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]
|
|
62063
62439
|
serve a package on localhost + open it in a browser. No serve
|
|
62064
62440
|
plane, no dev-server. With no argument it packs the current
|
|
62065
62441
|
content package first \u2014 edit, run, look at it.
|
|
62066
|
-
|
|
62442
|
+
--watch rebuilds on every save and repaints the open tab
|
|
62443
|
+
(a failed build keeps the last good preview). Blocks until Ctrl-C.
|
|
62067
62444
|
himi flags list|set|ramp|rm [<key>] [--app <a>]
|
|
62068
62445
|
read/change operational flags (RFC 0013); writes report
|
|
62069
62446
|
servedNow from the device door, never just ok
|
|
@@ -62406,7 +62783,7 @@ var COMMANDS = [
|
|
|
62406
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]" },
|
|
62407
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>]" },
|
|
62408
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>" },
|
|
62409
|
-
{ 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>]" },
|
|
62410
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]" },
|
|
62411
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]" },
|
|
62412
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]" },
|
|
@@ -62438,7 +62815,7 @@ var COMMANDS = [
|
|
|
62438
62815
|
];
|
|
62439
62816
|
function cliVersion() {
|
|
62440
62817
|
try {
|
|
62441
|
-
return JSON.parse(
|
|
62818
|
+
return JSON.parse(readFileSync71(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
62442
62819
|
} catch {
|
|
62443
62820
|
return "unknown";
|
|
62444
62821
|
}
|
|
@@ -62489,16 +62866,16 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
|
|
|
62489
62866
|
}
|
|
62490
62867
|
var SCOPED_REGISTRY_TIMEOUT_MS = 5e3;
|
|
62491
62868
|
function execNpmConfig(file, args, options) {
|
|
62492
|
-
return new Promise((
|
|
62493
|
-
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)));
|
|
62494
62871
|
});
|
|
62495
62872
|
}
|
|
62496
62873
|
var npmScopedWixRegistry = createScopedRegistryResolver();
|
|
62497
62874
|
async function scopedRegistryBefore(lookup2, deadline) {
|
|
62498
62875
|
let cancel = () => {
|
|
62499
62876
|
};
|
|
62500
|
-
const expired = new Promise((
|
|
62501
|
-
const timer = setTimeout(() =>
|
|
62877
|
+
const expired = new Promise((resolve48) => {
|
|
62878
|
+
const timer = setTimeout(() => resolve48(void 0), Math.max(0, deadline - Date.now()));
|
|
62502
62879
|
cancel = () => clearTimeout(timer);
|
|
62503
62880
|
});
|
|
62504
62881
|
try {
|
|
@@ -62556,16 +62933,16 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
62556
62933
|
}
|
|
62557
62934
|
function packageVersion(path2) {
|
|
62558
62935
|
try {
|
|
62559
|
-
const version2 = JSON.parse(
|
|
62936
|
+
const version2 = JSON.parse(readFileSync71(path2, "utf8")).version;
|
|
62560
62937
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
62561
62938
|
} catch {
|
|
62562
62939
|
return void 0;
|
|
62563
62940
|
}
|
|
62564
62941
|
}
|
|
62565
62942
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
62566
|
-
let dir =
|
|
62943
|
+
let dir = resolve47(fromDir);
|
|
62567
62944
|
for (; ; ) {
|
|
62568
|
-
const version2 = packageVersion(
|
|
62945
|
+
const version2 = packageVersion(join56(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
62569
62946
|
if (version2) return { version: version2, source: "local" };
|
|
62570
62947
|
const parent = dirname32(dir);
|
|
62571
62948
|
if (parent === dir) break;
|
|
@@ -62575,7 +62952,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
62575
62952
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
62576
62953
|
try {
|
|
62577
62954
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
62578
|
-
const version2 = root ? packageVersion(
|
|
62955
|
+
const version2 = root ? packageVersion(join56(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
62579
62956
|
return version2 ? { version: version2, source: "global" } : {};
|
|
62580
62957
|
} catch {
|
|
62581
62958
|
return {};
|
|
@@ -62622,11 +62999,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
62622
62999
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
62623
63000
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
62624
63001
|
function updateCachePath(env = process.env) {
|
|
62625
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
63002
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join56(homedir7(), ".himalaya", "update-check.json");
|
|
62626
63003
|
}
|
|
62627
63004
|
function readUpdateCache(path2) {
|
|
62628
63005
|
try {
|
|
62629
|
-
const parsed = JSON.parse(
|
|
63006
|
+
const parsed = JSON.parse(readFileSync71(path2, "utf8"));
|
|
62630
63007
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
62631
63008
|
} catch {
|
|
62632
63009
|
return {};
|
|
@@ -62665,7 +63042,7 @@ function globalPrefixWritable() {
|
|
|
62665
63042
|
const root = globalNodeModulesRoot();
|
|
62666
63043
|
if (!root) return false;
|
|
62667
63044
|
try {
|
|
62668
|
-
accessSync(root,
|
|
63045
|
+
accessSync(root, constants2.W_OK);
|
|
62669
63046
|
return true;
|
|
62670
63047
|
} catch {
|
|
62671
63048
|
return false;
|
|
@@ -62694,12 +63071,12 @@ function createUpdateRunner(spawn7 = spawnSync5) {
|
|
|
62694
63071
|
},
|
|
62695
63072
|
installedVersion: () => {
|
|
62696
63073
|
const root = globalNodeModulesRoot();
|
|
62697
|
-
return root ? packageVersion(
|
|
63074
|
+
return root ? packageVersion(join56(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
62698
63075
|
},
|
|
62699
63076
|
reexec: (argv) => {
|
|
62700
63077
|
const root = globalNodeModulesRoot();
|
|
62701
|
-
const entry = root ?
|
|
62702
|
-
if (!entry || !
|
|
63078
|
+
const entry = root ? join56(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
63079
|
+
if (!entry || !existsSync60(entry)) return void 0;
|
|
62703
63080
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
62704
63081
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
62705
63082
|
stdio: "inherit",
|
|
@@ -62727,7 +63104,7 @@ function thisHost() {
|
|
|
62727
63104
|
return hostname().replace(/\s+/g, "_");
|
|
62728
63105
|
}
|
|
62729
63106
|
function lockStamp(now) {
|
|
62730
|
-
return `${now} ${process.pid} ${thisHost()} ${
|
|
63107
|
+
return `${now} ${process.pid} ${thisHost()} ${randomUUID5()}`;
|
|
62731
63108
|
}
|
|
62732
63109
|
function processAlive(pid) {
|
|
62733
63110
|
try {
|
|
@@ -62746,7 +63123,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62746
63123
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
62747
63124
|
let content;
|
|
62748
63125
|
try {
|
|
62749
|
-
content =
|
|
63126
|
+
content = readFileSync71(path2, "utf8");
|
|
62750
63127
|
} catch {
|
|
62751
63128
|
continue;
|
|
62752
63129
|
}
|
|
@@ -62754,7 +63131,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
62754
63131
|
let since = stamped;
|
|
62755
63132
|
if (!Number.isFinite(since)) {
|
|
62756
63133
|
try {
|
|
62757
|
-
since =
|
|
63134
|
+
since = statSync17(path2).mtimeMs;
|
|
62758
63135
|
} catch {
|
|
62759
63136
|
continue;
|
|
62760
63137
|
}
|
|
@@ -62769,7 +63146,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62769
63146
|
const mine = lockStamp(now);
|
|
62770
63147
|
const readLock = (path2) => {
|
|
62771
63148
|
try {
|
|
62772
|
-
return
|
|
63149
|
+
return readFileSync71(path2, "utf8");
|
|
62773
63150
|
} catch {
|
|
62774
63151
|
return void 0;
|
|
62775
63152
|
}
|
|
@@ -62784,7 +63161,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62784
63161
|
};
|
|
62785
63162
|
const removeIfMine = (path2) => {
|
|
62786
63163
|
try {
|
|
62787
|
-
if (readLock(path2) === mine)
|
|
63164
|
+
if (readLock(path2) === mine) rmSync13(path2, { force: true });
|
|
62788
63165
|
} catch {
|
|
62789
63166
|
}
|
|
62790
63167
|
};
|
|
@@ -62807,7 +63184,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
62807
63184
|
hooks.underBreakLock?.();
|
|
62808
63185
|
if (current === void 0) return tryCreate(lockPath) ? release : void 0;
|
|
62809
63186
|
if (!isAbandoned(current)) return void 0;
|
|
62810
|
-
|
|
63187
|
+
rmSync13(lockPath, { force: true });
|
|
62811
63188
|
return tryCreate(lockPath) ? release : void 0;
|
|
62812
63189
|
} finally {
|
|
62813
63190
|
removeIfMine(breakPath);
|
|
@@ -63307,10 +63684,10 @@ function executableOnPath(name, env = process.env) {
|
|
|
63307
63684
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
63308
63685
|
for (const dir of entries) {
|
|
63309
63686
|
for (const suffix of suffixes) {
|
|
63310
|
-
const candidate =
|
|
63687
|
+
const candidate = join56(dir, `${name}${suffix}`);
|
|
63311
63688
|
try {
|
|
63312
|
-
if (!
|
|
63313
|
-
if (process.platform !== "win32") accessSync(candidate,
|
|
63689
|
+
if (!statSync17(candidate).isFile()) continue;
|
|
63690
|
+
if (process.platform !== "win32") accessSync(candidate, constants2.X_OK);
|
|
63314
63691
|
return true;
|
|
63315
63692
|
} catch {
|
|
63316
63693
|
}
|
|
@@ -63416,7 +63793,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63416
63793
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
63417
63794
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
63418
63795
|
const iosYmlPath = iosProjectYml2(app);
|
|
63419
|
-
const iosYml =
|
|
63796
|
+
const iosYml = existsSync60(iosYmlPath) ? readFileSync71(iosYmlPath, "utf8") : "";
|
|
63420
63797
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
63421
63798
|
if (!optedIn) {
|
|
63422
63799
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -63430,7 +63807,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63430
63807
|
}
|
|
63431
63808
|
function readConfigSource(dir) {
|
|
63432
63809
|
try {
|
|
63433
|
-
return
|
|
63810
|
+
return readFileSync71(join56(dir, "config.ts"), "utf8");
|
|
63434
63811
|
} catch {
|
|
63435
63812
|
return null;
|
|
63436
63813
|
}
|
|
@@ -63441,8 +63818,8 @@ function writePngFile(path2, base64) {
|
|
|
63441
63818
|
return path2;
|
|
63442
63819
|
}
|
|
63443
63820
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
63444
|
-
const dir =
|
|
63445
|
-
if (
|
|
63821
|
+
const dir = resolve47(parentDir, name);
|
|
63822
|
+
if (existsSync60(join56(dir, "himalaya.content.json"))) {
|
|
63446
63823
|
throw new Error(`content package already exists at ${dir}`);
|
|
63447
63824
|
}
|
|
63448
63825
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -63454,7 +63831,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
63454
63831
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
63455
63832
|
}
|
|
63456
63833
|
function contentDir(flags) {
|
|
63457
|
-
return
|
|
63834
|
+
return resolve47(str5(flags.content) ?? process.cwd());
|
|
63458
63835
|
}
|
|
63459
63836
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
63460
63837
|
const text5 = {};
|
|
@@ -63472,7 +63849,7 @@ function renameRestoredSource(restored, declaredApp, renamed) {
|
|
|
63472
63849
|
function symlinkDestinationIssue(dest) {
|
|
63473
63850
|
let kind;
|
|
63474
63851
|
try {
|
|
63475
|
-
kind =
|
|
63852
|
+
kind = lstatSync8(dest);
|
|
63476
63853
|
} catch {
|
|
63477
63854
|
return null;
|
|
63478
63855
|
}
|
|
@@ -63485,8 +63862,8 @@ function symlinkDestinationIssue(dest) {
|
|
|
63485
63862
|
function restoreDestinationIssue(dest, force) {
|
|
63486
63863
|
const link = symlinkDestinationIssue(dest);
|
|
63487
63864
|
if (link) return link;
|
|
63488
|
-
if (!
|
|
63489
|
-
if (!
|
|
63865
|
+
if (!existsSync60(dest)) return null;
|
|
63866
|
+
if (!statSync17(dest).isDirectory()) {
|
|
63490
63867
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
63491
63868
|
}
|
|
63492
63869
|
if (readdirSync27(dest).length > 0 && !force) {
|
|
@@ -63498,9 +63875,9 @@ function restoreDestinationIssue(dest, force) {
|
|
|
63498
63875
|
return null;
|
|
63499
63876
|
}
|
|
63500
63877
|
function isHimalayaMonorepoCheckout(start) {
|
|
63501
|
-
let dir =
|
|
63878
|
+
let dir = resolve47(start);
|
|
63502
63879
|
for (; ; ) {
|
|
63503
|
-
if (
|
|
63880
|
+
if (existsSync60(join56(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync60(join56(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
63504
63881
|
const parent = dirname32(dir);
|
|
63505
63882
|
if (parent === dir) return false;
|
|
63506
63883
|
dir = parent;
|
|
@@ -63542,8 +63919,8 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63542
63919
|
const forBuild = Object.fromEntries(
|
|
63543
63920
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
63544
63921
|
);
|
|
63545
|
-
const repoRoot2 =
|
|
63546
|
-
const root =
|
|
63922
|
+
const repoRoot2 = resolve47(fileURLToPath24(new URL("../../..", import.meta.url)));
|
|
63923
|
+
const root = join56(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
63547
63924
|
const stillRunning = (pid) => {
|
|
63548
63925
|
try {
|
|
63549
63926
|
process.kill(pid, 0);
|
|
@@ -63557,21 +63934,21 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63557
63934
|
if (!entry.isDirectory()) continue;
|
|
63558
63935
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
63559
63936
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
63560
|
-
|
|
63937
|
+
rmSync13(join56(root, entry.name), { recursive: true, force: true });
|
|
63561
63938
|
}
|
|
63562
63939
|
}
|
|
63563
63940
|
} catch {
|
|
63564
63941
|
}
|
|
63565
|
-
const dest =
|
|
63566
|
-
|
|
63942
|
+
const dest = join56(root, `${slug}-${process.pid}`);
|
|
63943
|
+
rmSync13(dest, { recursive: true, force: true });
|
|
63567
63944
|
mkdirSync30(dest, { recursive: true });
|
|
63568
63945
|
materializeSource(forBuild, displayName, dest, slug);
|
|
63569
63946
|
return dest;
|
|
63570
63947
|
}
|
|
63571
63948
|
async function appId(dir) {
|
|
63572
63949
|
try {
|
|
63573
|
-
const { readFileSync:
|
|
63574
|
-
const m = JSON.parse(
|
|
63950
|
+
const { readFileSync: readFileSync72 } = await import("node:fs");
|
|
63951
|
+
const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
|
|
63575
63952
|
if (m.name) return m.name;
|
|
63576
63953
|
} catch {
|
|
63577
63954
|
}
|
|
@@ -63579,8 +63956,8 @@ async function appId(dir) {
|
|
|
63579
63956
|
}
|
|
63580
63957
|
async function contentVisibility(dir) {
|
|
63581
63958
|
try {
|
|
63582
|
-
const { readFileSync:
|
|
63583
|
-
const m = JSON.parse(
|
|
63959
|
+
const { readFileSync: readFileSync72 } = await import("node:fs");
|
|
63960
|
+
const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
|
|
63584
63961
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
63585
63962
|
} catch {
|
|
63586
63963
|
}
|
|
@@ -63782,7 +64159,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
63782
64159
|
return 0;
|
|
63783
64160
|
}
|
|
63784
64161
|
case "agent-init": {
|
|
63785
|
-
const dir =
|
|
64162
|
+
const dir = resolve47(str5(flags.dir) ?? process.cwd());
|
|
63786
64163
|
const res = writeAgentContext(dir);
|
|
63787
64164
|
print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
|
|
63788
64165
|
return 0;
|
|
@@ -63804,7 +64181,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
63804
64181
|
try {
|
|
63805
64182
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
63806
64183
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
63807
|
-
out = mkdtempSync4(
|
|
64184
|
+
out = mkdtempSync4(join56(tmpdir5(), "himi-ux-record-"));
|
|
63808
64185
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
63809
64186
|
const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
63810
64187
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -63817,7 +64194,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
63817
64194
|
return null;
|
|
63818
64195
|
} finally {
|
|
63819
64196
|
if (out !== void 0) try {
|
|
63820
|
-
|
|
64197
|
+
rmSync13(out, { recursive: true, force: true });
|
|
63821
64198
|
} catch {
|
|
63822
64199
|
}
|
|
63823
64200
|
}
|
|
@@ -63982,7 +64359,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
63982
64359
|
let js;
|
|
63983
64360
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
63984
64361
|
try {
|
|
63985
|
-
js =
|
|
64362
|
+
js = readFileSync71(join56(outDir, candidate), "utf8");
|
|
63986
64363
|
break;
|
|
63987
64364
|
} catch {
|
|
63988
64365
|
}
|
|
@@ -64013,7 +64390,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
64013
64390
|
}
|
|
64014
64391
|
return { families, source: "dist/bundles" };
|
|
64015
64392
|
}
|
|
64016
|
-
var boardOpen = (dir) =>
|
|
64393
|
+
var boardOpen = (dir) => existsSync60(join56(dir, ".himi", "studio", "index.html"));
|
|
64017
64394
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
64018
64395
|
async function leaveForBoard(dir, record2, value) {
|
|
64019
64396
|
if (!boardOpen(dir)) return;
|
|
@@ -64280,7 +64657,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64280
64657
|
return 2;
|
|
64281
64658
|
}
|
|
64282
64659
|
const template = str5(flags.template);
|
|
64283
|
-
const parentDir =
|
|
64660
|
+
const parentDir = resolve47(str5(flags.dir) ?? process.cwd());
|
|
64284
64661
|
if (template && flags.remote === true) {
|
|
64285
64662
|
try {
|
|
64286
64663
|
const res2 = await initFromRemoteTemplate(name, parentDir, template, client2());
|
|
@@ -64397,11 +64774,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64397
64774
|
return outcome.code;
|
|
64398
64775
|
}
|
|
64399
64776
|
if (sub === "publish") {
|
|
64400
|
-
const appDir2 =
|
|
64401
|
-
const sourceDir =
|
|
64777
|
+
const appDir2 = resolve47(str5(flags.dir) ?? process.cwd());
|
|
64778
|
+
const sourceDir = resolve47(str5(flags["source-dir"]) ?? appDir2);
|
|
64402
64779
|
let meta;
|
|
64403
64780
|
try {
|
|
64404
|
-
meta = JSON.parse(
|
|
64781
|
+
meta = JSON.parse(readFileSync71(join56(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
64405
64782
|
} catch {
|
|
64406
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>)` }));
|
|
64407
64784
|
return 2;
|
|
@@ -64411,7 +64788,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64411
64788
|
return 2;
|
|
64412
64789
|
}
|
|
64413
64790
|
try {
|
|
64414
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
64791
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync71(join56(sourceDir, "tokens.json"), "utf8")));
|
|
64415
64792
|
meta = { ...appearance, ...meta };
|
|
64416
64793
|
} catch {
|
|
64417
64794
|
}
|
|
@@ -64423,13 +64800,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64423
64800
|
const force = flags.force === true;
|
|
64424
64801
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64425
64802
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
64426
|
-
const out = mkdtempSync4(
|
|
64803
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-template-"));
|
|
64427
64804
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64428
64805
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
64429
64806
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
64430
64807
|
collect: { lint: true, strict }
|
|
64431
64808
|
});
|
|
64432
|
-
const scaffoldSourceFindings =
|
|
64809
|
+
const scaffoldSourceFindings = resolve47(sourceDir) === resolve47(appDir2) ? [] : [
|
|
64433
64810
|
...tokenColorIssues(sourceDir),
|
|
64434
64811
|
...surfaceIssues(sourceDir, void 0, strict),
|
|
64435
64812
|
...await fontIssues(sourceDir, strict),
|
|
@@ -64472,11 +64849,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64472
64849
|
}));
|
|
64473
64850
|
return 1;
|
|
64474
64851
|
}
|
|
64475
|
-
const iconPath = str5(flags.icon) ?
|
|
64852
|
+
const iconPath = str5(flags.icon) ? resolve47(str5(flags.icon)) : templateIconPath(name);
|
|
64476
64853
|
let iconHash;
|
|
64477
64854
|
if (iconPath) {
|
|
64478
64855
|
try {
|
|
64479
|
-
const bytes2 =
|
|
64856
|
+
const bytes2 = readFileSync71(iconPath);
|
|
64480
64857
|
payload.icon = bytes2.toString("base64");
|
|
64481
64858
|
iconHash = createHash26("sha256").update(bytes2).digest("hex");
|
|
64482
64859
|
} catch {
|
|
@@ -64709,7 +65086,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64709
65086
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
64710
65087
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64711
65088
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
64712
|
-
const out = mkdtempSync4(
|
|
65089
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-validate-"));
|
|
64713
65090
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64714
65091
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
64715
65092
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -64752,7 +65129,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64752
65129
|
const path2 = dpxSessionTokenPath();
|
|
64753
65130
|
let raw;
|
|
64754
65131
|
try {
|
|
64755
|
-
raw =
|
|
65132
|
+
raw = readFileSync71(path2, "utf8");
|
|
64756
65133
|
} catch {
|
|
64757
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`);
|
|
64758
65135
|
}
|
|
@@ -64872,7 +65249,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64872
65249
|
case "studio": {
|
|
64873
65250
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
64874
65251
|
const dir = contentDir(flags);
|
|
64875
|
-
if (!
|
|
65252
|
+
if (!existsSync60(join56(dir, "himalaya.content.json"))) {
|
|
64876
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/" }));
|
|
64877
65254
|
return 2;
|
|
64878
65255
|
}
|
|
@@ -64897,7 +65274,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64897
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));
|
|
64898
65275
|
const dir = contentDir(flags);
|
|
64899
65276
|
const journal = journalPath2(dir);
|
|
64900
|
-
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" };
|
|
64901
65278
|
const message = pos.slice(1).join(" ").trim();
|
|
64902
65279
|
if (!message) {
|
|
64903
65280
|
if (flags.step !== void 0 || flags.image !== void 0 || flags.notify === true) {
|
|
@@ -64989,7 +65366,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64989
65366
|
case "test": {
|
|
64990
65367
|
const dir = contentDir(flags);
|
|
64991
65368
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
64992
|
-
if (
|
|
65369
|
+
if (existsSync60(join56(dir, "functions"))) {
|
|
64993
65370
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
64994
65371
|
const loaded = await loadFunctionsApp2(dir);
|
|
64995
65372
|
const results = [];
|
|
@@ -65076,7 +65453,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65076
65453
|
}
|
|
65077
65454
|
}
|
|
65078
65455
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65079
|
-
const out = mkdtempSync4(
|
|
65456
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-test-"));
|
|
65080
65457
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65081
65458
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65082
65459
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65121,7 +65498,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65121
65498
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
65122
65499
|
return 2;
|
|
65123
65500
|
}
|
|
65124
|
-
const sources = collectWorkerSources2(
|
|
65501
|
+
const sources = collectWorkerSources2(join56(dir, "tier5-src"), screen.bundleName);
|
|
65125
65502
|
if (!sources) {
|
|
65126
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` }));
|
|
65127
65504
|
return 2;
|
|
@@ -65282,7 +65659,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65282
65659
|
const sp = await runShotsPass2({
|
|
65283
65660
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
65284
65661
|
tokens: outcome.tokens,
|
|
65285
|
-
outDir:
|
|
65662
|
+
outDir: join56(dir, ".himi", "shots"),
|
|
65286
65663
|
width: 390,
|
|
65287
65664
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
65288
65665
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -65292,7 +65669,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65292
65669
|
renderDescriptorWeb: renderDescriptorWeb2,
|
|
65293
65670
|
renderPngBatch: renderPngBatch2,
|
|
65294
65671
|
writePng: (path2, base64) => writePngFile(path2, base64),
|
|
65295
|
-
clearDir: (d) =>
|
|
65672
|
+
clearDir: (d) => rmSync13(d, { recursive: true, force: true })
|
|
65296
65673
|
}
|
|
65297
65674
|
});
|
|
65298
65675
|
writtenShots = sp.written;
|
|
@@ -65320,7 +65697,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65320
65697
|
releaseId: result.releaseId,
|
|
65321
65698
|
releasePayload: release,
|
|
65322
65699
|
descriptors: attestedDescriptors,
|
|
65323
|
-
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)])),
|
|
65324
65701
|
coverage: {
|
|
65325
65702
|
screens: crawledScreens.size,
|
|
65326
65703
|
actionsDispatched: result.actions.exercised,
|
|
@@ -65410,7 +65787,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65410
65787
|
return 2;
|
|
65411
65788
|
}
|
|
65412
65789
|
try {
|
|
65413
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
65790
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync71(stateArg.replace(/^@/, ""), "utf8");
|
|
65414
65791
|
injectedState = JSON.parse(raw);
|
|
65415
65792
|
} catch (e) {
|
|
65416
65793
|
io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
|
|
@@ -65425,7 +65802,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65425
65802
|
return 2;
|
|
65426
65803
|
}
|
|
65427
65804
|
try {
|
|
65428
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
65805
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync71(inputArg.replace(/^@/, ""), "utf8");
|
|
65429
65806
|
const parsed = JSON.parse(raw);
|
|
65430
65807
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
65431
65808
|
injectedInput = parsed;
|
|
@@ -65474,7 +65851,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65474
65851
|
}
|
|
65475
65852
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65476
65853
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65477
|
-
const out = mkdtempSync4(
|
|
65854
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-render-"));
|
|
65478
65855
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65479
65856
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65480
65857
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65488,11 +65865,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65488
65865
|
const diagnostics = (outcome.lint ?? []).find((s) => s.screenId === screenId)?.issues ?? [];
|
|
65489
65866
|
let pngFile;
|
|
65490
65867
|
let attestationPngFile;
|
|
65491
|
-
const shotPath =
|
|
65868
|
+
const shotPath = join56(dir, ".himi", "shots", `${screenId}.png`);
|
|
65492
65869
|
const pngTarget = typeof flags.png === "string" ? str5(flags.png) : flags.png === true ? shotPath : void 0;
|
|
65493
65870
|
if (pngTarget && r.pngBase64) {
|
|
65494
65871
|
pngFile = writePngFile(pngTarget, r.pngBase64);
|
|
65495
|
-
attestationPngFile =
|
|
65872
|
+
attestationPngFile = resolve47(pngTarget) === resolve47(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
|
|
65496
65873
|
}
|
|
65497
65874
|
if (renderWidth !== void 0 && r.renderable) {
|
|
65498
65875
|
recordRenderWidth(dir, {
|
|
@@ -65816,7 +66193,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65816
66193
|
return 2;
|
|
65817
66194
|
}
|
|
65818
66195
|
const renamed = str5(flags.name);
|
|
65819
|
-
const dest =
|
|
66196
|
+
const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
65820
66197
|
const replace = flags.replace === true;
|
|
65821
66198
|
const force = replace || flags.force === true;
|
|
65822
66199
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -65824,8 +66201,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65824
66201
|
io.error(JSON.stringify(linked));
|
|
65825
66202
|
return 1;
|
|
65826
66203
|
}
|
|
65827
|
-
if (
|
|
65828
|
-
if (!
|
|
66204
|
+
if (existsSync60(dest)) {
|
|
66205
|
+
if (!statSync17(dest).isDirectory()) {
|
|
65829
66206
|
io.error(JSON.stringify({
|
|
65830
66207
|
error: `${dest} exists and is not a directory`,
|
|
65831
66208
|
hint: "pass --out/--name to land somewhere else, or remove the file"
|
|
@@ -65837,7 +66214,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65837
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" }));
|
|
65838
66215
|
return 1;
|
|
65839
66216
|
}
|
|
65840
|
-
if (replace && occupied && !
|
|
66217
|
+
if (replace && occupied && !existsSync60(join56(dest, "himalaya.content.json"))) {
|
|
65841
66218
|
io.error(JSON.stringify({
|
|
65842
66219
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
65843
66220
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -65976,7 +66353,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
65976
66353
|
const force = flags.force === true;
|
|
65977
66354
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65978
66355
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
65979
|
-
const out = mkdtempSync4(
|
|
66356
|
+
const out = mkdtempSync4(join56(tmpdir5(), "himi-push-"));
|
|
65980
66357
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65981
66358
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65982
66359
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66448,7 +66825,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66448
66825
|
return 2;
|
|
66449
66826
|
}
|
|
66450
66827
|
try {
|
|
66451
|
-
const res = writePack(
|
|
66828
|
+
const res = writePack(resolve47(releaseDir), only, resolve47(str5(flags.out) ?? process.cwd()));
|
|
66452
66829
|
print({
|
|
66453
66830
|
ok: true,
|
|
66454
66831
|
app: res.app,
|
|
@@ -66497,7 +66874,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66497
66874
|
}
|
|
66498
66875
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66499
66876
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
66500
|
-
const built = mkdtempSync4(
|
|
66877
|
+
const built = mkdtempSync4(join56(tmpdir5(), "himi-pack-"));
|
|
66501
66878
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66502
66879
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
66503
66880
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66514,12 +66891,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66514
66891
|
...await navIssues2(dir, strict)
|
|
66515
66892
|
]);
|
|
66516
66893
|
if (hasErrors && !force) {
|
|
66517
|
-
|
|
66894
|
+
rmSync13(built, { recursive: true, force: true });
|
|
66518
66895
|
print({ ...report2, packed: false, hint: "lint found errors \u2014 fix them, or re-run `himi pack --force` to pack anyway" });
|
|
66519
66896
|
return 1;
|
|
66520
66897
|
}
|
|
66521
66898
|
try {
|
|
66522
|
-
const res = writePack(built, app,
|
|
66899
|
+
const res = writePack(built, app, resolve47(str5(flags.out) ?? dir), sourceArchive);
|
|
66523
66900
|
print({
|
|
66524
66901
|
ok: true,
|
|
66525
66902
|
app: res.app,
|
|
@@ -66550,7 +66927,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66550
66927
|
io.error(JSON.stringify({ error: e.message }));
|
|
66551
66928
|
return 1;
|
|
66552
66929
|
} finally {
|
|
66553
|
-
|
|
66930
|
+
rmSync13(built, { recursive: true, force: true });
|
|
66554
66931
|
}
|
|
66555
66932
|
}
|
|
66556
66933
|
// ---- himi import — turn a dev .himi back into an editable content package ----
|
|
@@ -66564,7 +66941,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66564
66941
|
const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
|
|
66565
66942
|
let opened;
|
|
66566
66943
|
try {
|
|
66567
|
-
opened = openPackageFile2(
|
|
66944
|
+
opened = openPackageFile2(resolve47(file));
|
|
66568
66945
|
} catch (e) {
|
|
66569
66946
|
io.error(JSON.stringify({ error: e.message }));
|
|
66570
66947
|
return 1;
|
|
@@ -66577,7 +66954,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66577
66954
|
io.error(JSON.stringify({
|
|
66578
66955
|
ok: false,
|
|
66579
66956
|
error: "app_source_not_in_package",
|
|
66580
|
-
detail: `${
|
|
66957
|
+
detail: `${resolve47(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
|
|
66581
66958
|
hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
|
|
66582
66959
|
}));
|
|
66583
66960
|
return 1;
|
|
@@ -66600,7 +66977,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66600
66977
|
return 1;
|
|
66601
66978
|
}
|
|
66602
66979
|
}
|
|
66603
|
-
const dest =
|
|
66980
|
+
const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
66604
66981
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
66605
66982
|
if (issue2) {
|
|
66606
66983
|
io.error(JSON.stringify(issue2));
|
|
@@ -66685,7 +67062,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66685
67062
|
}
|
|
66686
67063
|
try {
|
|
66687
67064
|
const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
66688
|
-
const opened = openPackageFile2(
|
|
67065
|
+
const opened = openPackageFile2(resolve47(file));
|
|
66689
67066
|
if (!opened.validation.ok || !opened.header) {
|
|
66690
67067
|
io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
|
|
66691
67068
|
return 1;
|
|
@@ -66695,12 +67072,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66695
67072
|
io.error(JSON.stringify({
|
|
66696
67073
|
ok: false,
|
|
66697
67074
|
error: "refusing to share a package that carries the app's source",
|
|
66698
|
-
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`,
|
|
66699
67076
|
hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
|
|
66700
67077
|
}));
|
|
66701
67078
|
return 1;
|
|
66702
67079
|
}
|
|
66703
|
-
const archive =
|
|
67080
|
+
const archive = readFileSync71(resolve47(file));
|
|
66704
67081
|
const result = await client2().createPackageShare({
|
|
66705
67082
|
app: opened.header.app,
|
|
66706
67083
|
releaseId: opened.header.releaseId,
|
|
@@ -66731,16 +67108,33 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66731
67108
|
const { runPackage: runPackage2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
66732
67109
|
let source = pos[1];
|
|
66733
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 = [];
|
|
66734
67127
|
try {
|
|
66735
67128
|
if (!source) {
|
|
66736
|
-
const
|
|
66737
|
-
const app = await appId(
|
|
67129
|
+
const dir2 = contentDir(flags);
|
|
67130
|
+
const app = await appId(dir2);
|
|
66738
67131
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66739
|
-
const bres = await buildContentBundles2(
|
|
66740
|
-
temp = mkdtempSync4(
|
|
67132
|
+
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
67133
|
+
temp = mkdtempSync4(join56(tmpdir5(), "himi-run-build-"));
|
|
66741
67134
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66742
|
-
await buildReleaseFromContent2(
|
|
66743
|
-
|
|
67135
|
+
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
67136
|
+
servedMissing = initial.missingBundles;
|
|
67137
|
+
source = join56(temp, app);
|
|
66744
67138
|
}
|
|
66745
67139
|
const chromeArg = str5(flags.chrome) ?? "preview";
|
|
66746
67140
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -66765,45 +67159,142 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66765
67159
|
open: flags["no-open"] !== true
|
|
66766
67160
|
});
|
|
66767
67161
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
66768
|
-
await new Promise((
|
|
67162
|
+
await new Promise((resolve48) => {
|
|
66769
67163
|
const stop = () => {
|
|
66770
|
-
void run2.close().finally(() =>
|
|
67164
|
+
void run2.close().finally(() => resolve48());
|
|
66771
67165
|
};
|
|
66772
67166
|
process.once("SIGINT", stop);
|
|
66773
67167
|
process.once("SIGTERM", stop);
|
|
66774
67168
|
});
|
|
66775
67169
|
return 0;
|
|
66776
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-"));
|
|
66777
67175
|
const running = await runPackage2(source, {
|
|
66778
67176
|
port,
|
|
66779
67177
|
chrome: chromeArg,
|
|
66780
67178
|
screen: str5(flags.screen),
|
|
66781
67179
|
surface: str5(flags.surface),
|
|
66782
67180
|
spa: str5(flags.spa),
|
|
66783
|
-
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) } : {}
|
|
66784
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
|
+
}
|
|
66785
67261
|
print({
|
|
66786
67262
|
ok: true,
|
|
66787
67263
|
app: running.app,
|
|
66788
67264
|
releaseId: running.releaseId,
|
|
66789
67265
|
url: running.url,
|
|
66790
67266
|
port: running.port,
|
|
67267
|
+
...watch2 ? { watching: dir, ...boardOpen(dir) ? { board: `${running.origin}/__himi/studio/` } : {} } : {},
|
|
66791
67268
|
...running.warnings.length ? { warnings: running.warnings } : {},
|
|
66792
67269
|
stop: "Ctrl-C"
|
|
66793
67270
|
});
|
|
66794
67271
|
await new Promise((done) => {
|
|
66795
|
-
const stop = () => {
|
|
66796
|
-
|
|
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
|
+
}
|
|
66797
67287
|
};
|
|
66798
|
-
process.once("SIGINT", stop);
|
|
66799
|
-
process.once("SIGTERM", stop);
|
|
67288
|
+
process.once("SIGINT", () => void stop());
|
|
67289
|
+
process.once("SIGTERM", () => void stop());
|
|
66800
67290
|
});
|
|
66801
67291
|
return 0;
|
|
66802
67292
|
} catch (e) {
|
|
66803
67293
|
io.error(JSON.stringify({ error: e.message }));
|
|
66804
67294
|
return 1;
|
|
66805
67295
|
} finally {
|
|
66806
|
-
if (temp)
|
|
67296
|
+
if (temp) rmSync13(temp, { recursive: true, force: true });
|
|
67297
|
+
if (served) rmSync13(served, { recursive: true, force: true });
|
|
66807
67298
|
}
|
|
66808
67299
|
}
|
|
66809
67300
|
case "preview": {
|
|
@@ -67344,7 +67835,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67344
67835
|
io.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
67345
67836
|
return 2;
|
|
67346
67837
|
}
|
|
67347
|
-
if (!
|
|
67838
|
+
if (!existsSync60(file)) {
|
|
67348
67839
|
io.error(JSON.stringify({ error: `no such file: ${file}` }));
|
|
67349
67840
|
return 2;
|
|
67350
67841
|
}
|
|
@@ -67400,7 +67891,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67400
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."
|
|
67401
67892
|
};
|
|
67402
67893
|
if (kind === "tokens" || kind === "app-config") {
|
|
67403
|
-
const body =
|
|
67894
|
+
const body = readFileSync71(file, "utf8");
|
|
67404
67895
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
67405
67896
|
return runReleasePatch({
|
|
67406
67897
|
...common,
|
|
@@ -67415,7 +67906,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67415
67906
|
io.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
67416
67907
|
return 2;
|
|
67417
67908
|
}
|
|
67418
|
-
const descriptor =
|
|
67909
|
+
const descriptor = readFileSync71(file, "utf8");
|
|
67419
67910
|
try {
|
|
67420
67911
|
JSON.parse(descriptor);
|
|
67421
67912
|
} catch (e) {
|
|
@@ -67455,7 +67946,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67455
67946
|
extra: { kind, screen: id, file: { path: file, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
67456
67947
|
});
|
|
67457
67948
|
}
|
|
67458
|
-
const bytes2 =
|
|
67949
|
+
const bytes2 = readFileSync71(file);
|
|
67459
67950
|
const sha = createHash26("sha256").update(bytes2).digest("hex");
|
|
67460
67951
|
const forScreens = (str5(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
67461
67952
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
@@ -67599,7 +68090,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67599
68090
|
}
|
|
67600
68091
|
let def;
|
|
67601
68092
|
try {
|
|
67602
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
68093
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync71(arg.slice(1), "utf8") : arg);
|
|
67603
68094
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
67604
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}`] }));
|
|
67605
68096
|
return 2;
|
|
@@ -68063,7 +68554,7 @@ ${label2}`);
|
|
|
68063
68554
|
const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
68064
68555
|
{
|
|
68065
68556
|
const distDir = contentDir(flags);
|
|
68066
|
-
if (
|
|
68557
|
+
if (existsSync60(join56(distDir, "himalaya.content.json"))) {
|
|
68067
68558
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
68068
68559
|
const errors = issues.filter((i) => i.severity === "error");
|
|
68069
68560
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|
|
@@ -68332,7 +68823,7 @@ ${label2}`);
|
|
|
68332
68823
|
const dpxPath = dpxSessionTokenPath();
|
|
68333
68824
|
let dpx;
|
|
68334
68825
|
try {
|
|
68335
|
-
dpx =
|
|
68826
|
+
dpx = readFileSync71(dpxPath, "utf8").trim();
|
|
68336
68827
|
} catch {
|
|
68337
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` }));
|
|
68338
68829
|
return 1;
|
|
@@ -68734,7 +69225,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
68734
69225
|
const path2 = dpxSessionTokenPath();
|
|
68735
69226
|
let raw;
|
|
68736
69227
|
try {
|
|
68737
|
-
raw =
|
|
69228
|
+
raw = readFileSync71(path2, "utf8");
|
|
68738
69229
|
} catch {
|
|
68739
69230
|
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
68740
69231
|
return 1;
|