@wix/himalaya-cli 0.1015.0 → 0.1017.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +67 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/state/src/index.d.ts +45 -3
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +18 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +7 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/genie-chat/src/index.d.ts +51 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +21 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +79 -6
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-genie-chat.mjs +23 -0
- package/dist/cli.mjs +1293 -679
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +1 -1
- package/guides/component-reference.md +25 -9
- package/guides/designing-himi-screens.md +6 -4
- package/guides/headless-loop.md +1 -0
- package/guides/sdk-reference.json +47 -5
- package/guides/tier-5-add-a-screen.md +40 -13
- package/guides/wix-api-usage.md +9 -0
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +252 -7
- package/templates/beauty-salon/tier5-src/himi-booking-bookings/index.ts +5 -2
- package/templates/beauty-salon-owner/config.ts +1 -1
- package/templates/beauty-salon-owner/dev/index.ts +419 -2
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/branded-lite/dev/index.ts +487 -14
- package/templates/branded-lite/tier5-src/himi-booking-bookings/index.ts +5 -2
- package/templates/community-club/dev/index.ts +196 -13
- package/templates/community-club-owner/config.ts +1 -1
- package/templates/community-club-owner/dev/index.ts +402 -2
- package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/community-club-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/events-meetups/dev/index.ts +196 -13
- package/templates/events-meetups-owner/config.ts +1 -1
- package/templates/events-meetups-owner/dev/index.ts +348 -2
- package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/events-meetups-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/gym-fitness/dev/index.ts +324 -12
- package/templates/gym-fitness/tier5-src/himi-booking-bookings/index.ts +5 -2
- package/templates/gym-fitness-owner/config.ts +1 -1
- package/templates/gym-fitness-owner/dev/index.ts +440 -2
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/himi-chat/dev/index.ts +2 -2
- package/templates/nonprofit-cause/dev/index.ts +212 -13
- package/templates/nonprofit-cause-owner/config.ts +1 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +386 -2
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/owner-lite/config.ts +1 -1
- package/templates/owner-lite/dev/index.ts +446 -2
- package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/owner-lite/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/podcast-creator/dev/index.ts +206 -13
- package/templates/podcast-creator-owner/config.ts +1 -1
- package/templates/podcast-creator-owner/dev/index.ts +402 -2
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/portfolio-creative/dev/index.ts +249 -11
- package/templates/portfolio-creative-owner/config.ts +1 -1
- package/templates/portfolio-creative-owner/dev/index.ts +419 -2
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/restaurant/dev/index.ts +219 -11
- package/templates/restaurant-owner/config.ts +1 -1
- package/templates/restaurant-owner/dev/index.ts +440 -2
- package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/restaurant-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/retail-store/dev/index.ts +159 -6
- package/templates/retail-store-owner/config.ts +1 -1
- package/templates/retail-store-owner/dev/index.ts +381 -2
- package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/retail-store-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
- package/templates/yoga-studio/dev/index.ts +284 -12
- package/templates/yoga-studio/tier5-src/himi-booking-bookings/index.ts +5 -2
- package/templates/yoga-studio-owner/config.ts +1 -1
- package/templates/yoga-studio-owner/dev/index.ts +386 -2
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +226 -9
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
package/dist/cli.mjs
CHANGED
|
@@ -5345,6 +5345,7 @@ 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";
|
|
5348
5349
|
SYSTEM_FONT_FAMILY = "$system";
|
|
5349
5350
|
}
|
|
5350
5351
|
});
|
|
@@ -6516,6 +6517,260 @@ var init_l10n_strings = __esm({
|
|
|
6516
6517
|
}
|
|
6517
6518
|
});
|
|
6518
6519
|
|
|
6520
|
+
// ../../core/dev-server/src/a11y-contract.ts
|
|
6521
|
+
function isDynamicValue(v) {
|
|
6522
|
+
return typeof v === "string" && (v.startsWith("$service:") || v.startsWith("$item") || v.startsWith("$flag") || v.startsWith("$state") || v.startsWith("$t:"));
|
|
6523
|
+
}
|
|
6524
|
+
function isActionEnvelope(v) {
|
|
6525
|
+
return !!v && typeof v === "object" && !Array.isArray(v) && typeof v.actionId === "string";
|
|
6526
|
+
}
|
|
6527
|
+
function own(bag, key2) {
|
|
6528
|
+
return Object.prototype.hasOwnProperty.call(bag, key2) ? bag[key2] : void 0;
|
|
6529
|
+
}
|
|
6530
|
+
function atExposureOf(node) {
|
|
6531
|
+
const mods = node.modifiers;
|
|
6532
|
+
if (!mods || typeof mods !== "object" || Array.isArray(mods)) return "exposed";
|
|
6533
|
+
const m = mods;
|
|
6534
|
+
if (m.accessibilityHidden === true) return "hidden";
|
|
6535
|
+
if (m.accessibilityRole === "decorative" && !isInteractive(node)) return "decorative";
|
|
6536
|
+
return "exposed";
|
|
6537
|
+
}
|
|
6538
|
+
function isInteractive(node) {
|
|
6539
|
+
const raw = node.modifiers;
|
|
6540
|
+
const mods = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
6541
|
+
return TAP_MODIFIER_KEYS.some(
|
|
6542
|
+
(k) => !!mods[k] && typeof mods[k] === "object" || !!node[k] && typeof node[k] === "object"
|
|
6543
|
+
);
|
|
6544
|
+
}
|
|
6545
|
+
function ownName(n) {
|
|
6546
|
+
for (const k of ACCESSIBLE_NAME_KEYS) {
|
|
6547
|
+
const v = own(n, k);
|
|
6548
|
+
if (typeof v === "string" && v.trim() !== "" || isDynamicValue(v)) return true;
|
|
6549
|
+
}
|
|
6550
|
+
for (const k of CONTENT_ARM_KEYS) {
|
|
6551
|
+
const v = own(n, k);
|
|
6552
|
+
if (v !== void 0 && v !== null) return true;
|
|
6553
|
+
}
|
|
6554
|
+
return false;
|
|
6555
|
+
}
|
|
6556
|
+
function isWireWrapper(n) {
|
|
6557
|
+
return componentTypeOf(n) !== null && typeof n.body?.type === "string";
|
|
6558
|
+
}
|
|
6559
|
+
function nameIn(node, at) {
|
|
6560
|
+
if (!node || typeof node !== "object") return false;
|
|
6561
|
+
if (Array.isArray(node)) return node.some((v) => nameIn(v, at));
|
|
6562
|
+
if (isActionEnvelope(node)) return false;
|
|
6563
|
+
const n = node;
|
|
6564
|
+
let readOwnKeys = true;
|
|
6565
|
+
if (at === "descendant") {
|
|
6566
|
+
const exposure = atExposureOf(n);
|
|
6567
|
+
if (exposure === "hidden") return false;
|
|
6568
|
+
if (exposure === "decorative") readOwnKeys = false;
|
|
6569
|
+
} else if (at === "decorativeOwn") {
|
|
6570
|
+
if (componentTypeOf(n) !== null) return nameIn(n, "descendant");
|
|
6571
|
+
readOwnKeys = false;
|
|
6572
|
+
}
|
|
6573
|
+
if (readOwnKeys) {
|
|
6574
|
+
if (ownName(n)) return true;
|
|
6575
|
+
return Object.values(n).some((v) => nameIn(v, "descendant"));
|
|
6576
|
+
}
|
|
6577
|
+
const wrapper = isWireWrapper(n);
|
|
6578
|
+
return Object.entries(n).some(([k, v]) => {
|
|
6579
|
+
if (k === "body" && wrapper && v && typeof v === "object" && !Array.isArray(v)) {
|
|
6580
|
+
return Object.values(v).some((w) => nameIn(w, "decorativeOwn"));
|
|
6581
|
+
}
|
|
6582
|
+
return nameIn(v, "decorativeOwn");
|
|
6583
|
+
});
|
|
6584
|
+
}
|
|
6585
|
+
function hasAccessibleName(node) {
|
|
6586
|
+
return nameIn(node, "self");
|
|
6587
|
+
}
|
|
6588
|
+
function componentTypeOf(node) {
|
|
6589
|
+
const body = node.body;
|
|
6590
|
+
if (body && typeof body === "object" && !Array.isArray(body) && typeof body.type === "string" && typeof body.package === "string") {
|
|
6591
|
+
return body.type;
|
|
6592
|
+
}
|
|
6593
|
+
if (typeof node.type === "string" && typeof node.package === "string") return node.type;
|
|
6594
|
+
return null;
|
|
6595
|
+
}
|
|
6596
|
+
function accessibleNameGaps(descriptor, options = {}) {
|
|
6597
|
+
const out = [];
|
|
6598
|
+
const interactiveOnly = options.interactiveOnly === true;
|
|
6599
|
+
const walk2 = (node, path2, key2, suppressed = false) => {
|
|
6600
|
+
if (!node || typeof node !== "object") return;
|
|
6601
|
+
if (Array.isArray(node)) {
|
|
6602
|
+
node.forEach((v, i) => walk2(v, `${path2}[${i}]`, key2, suppressed));
|
|
6603
|
+
return;
|
|
6604
|
+
}
|
|
6605
|
+
const n = node;
|
|
6606
|
+
if (key2 === "args" || key2 === "input" && path2 === "input") return;
|
|
6607
|
+
const rawMods = n.modifiers;
|
|
6608
|
+
const hasMods = !!rawMods && typeof rawMods === "object" && !Array.isArray(rawMods);
|
|
6609
|
+
const exposure = atExposureOf(n);
|
|
6610
|
+
if (exposure === "hidden") return;
|
|
6611
|
+
const viaBody = componentTypeOf(n) !== null && typeof n.body?.type === "string";
|
|
6612
|
+
const bodyMods = viaBody ? n.body.modifiers : void 0;
|
|
6613
|
+
const deferToBody = viaBody && !hasMods && !!bodyMods && typeof bodyMods === "object" && !Array.isArray(bodyMods);
|
|
6614
|
+
if (key2 !== "modifiers" && !suppressed && !deferToBody) {
|
|
6615
|
+
if (exposure !== "decorative") {
|
|
6616
|
+
const tappable = isInteractive(n);
|
|
6617
|
+
const type = componentTypeOf(n);
|
|
6618
|
+
const row = type ? own(A11Y_CONTRACT, type) : void 0;
|
|
6619
|
+
const contractual = !interactiveOnly && row?.name === "required";
|
|
6620
|
+
if ((tappable || contractual) && !hasAccessibleName(n)) {
|
|
6621
|
+
out.push({
|
|
6622
|
+
at: path2 || "root",
|
|
6623
|
+
type: type ?? (n.icon ? "icon" : "node"),
|
|
6624
|
+
reason: tappable ? "interactive" : "contract",
|
|
6625
|
+
// §3.4: interactivity promotes the container to a BUTTON whatever its row says.
|
|
6626
|
+
role: tappable ? "button" : row?.role ?? "unspecified"
|
|
6627
|
+
});
|
|
6628
|
+
}
|
|
6629
|
+
}
|
|
6630
|
+
}
|
|
6631
|
+
for (const [k, v] of Object.entries(n)) {
|
|
6632
|
+
walk2(v, path2 ? `${path2}.${k}` : k, k, k === "body" && viaBody && !deferToBody);
|
|
6633
|
+
}
|
|
6634
|
+
};
|
|
6635
|
+
walk2(descriptor, "", "");
|
|
6636
|
+
return out;
|
|
6637
|
+
}
|
|
6638
|
+
var A11Y_CONTRACT, ACCESSIBLE_NAME_KEYS, CONTENT_ARM_KEYS, TAP_MODIFIER_KEYS;
|
|
6639
|
+
var init_a11y_contract = __esm({
|
|
6640
|
+
"../../core/dev-server/src/a11y-contract.ts"() {
|
|
6641
|
+
A11Y_CONTRACT = {
|
|
6642
|
+
// ---- Layout / structural containers -------------------------------------------------
|
|
6643
|
+
// Transparent by default: not AT stops, they expose their children directly. They become a
|
|
6644
|
+
// named GROUP only when they carry `accessibilityLabel` — or when an `onTap` promotes them
|
|
6645
|
+
// (§3.4), which is what the `conditional` arm catches.
|
|
6646
|
+
VStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
|
|
6647
|
+
HStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
|
|
6648
|
+
ZStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
|
|
6649
|
+
Grid: { role: "unspecified", name: "conditional", state: [], decorative: false },
|
|
6650
|
+
LazyList: { role: "list", name: "conditional", state: ["item position", "item count"], decorative: false },
|
|
6651
|
+
Card: { role: "group", name: "conditional", state: [], decorative: false },
|
|
6652
|
+
Divider: { role: "decorative", name: "none", state: [], decorative: true },
|
|
6653
|
+
Spacer: { role: "decorative", name: "none", state: [], decorative: true },
|
|
6654
|
+
SplitView: { role: "unspecified", name: "conditional", state: [], decorative: false },
|
|
6655
|
+
Section: { role: "group", name: "conditional", state: [], decorative: false },
|
|
6656
|
+
LabeledContent: { role: "group", name: "required", state: ["value = the content"], decorative: false },
|
|
6657
|
+
// ---- Text and inline content --------------------------------------------------------
|
|
6658
|
+
// Named by themselves: the copy IS the name, so `required` here reads "this node must carry
|
|
6659
|
+
// some copy", which is also what makes an empty Text a finding rather than a silent stop.
|
|
6660
|
+
Text: { role: "text", name: "required", state: [], decorative: false },
|
|
6661
|
+
RichText: { role: "text", name: "required", state: [], decorative: false },
|
|
6662
|
+
Label: { role: "text", name: "required", state: [], decorative: false },
|
|
6663
|
+
Marquee: { role: "text", name: "required", state: [], decorative: false },
|
|
6664
|
+
Badge: { role: "status", name: "required", state: ["count/value"], decorative: false },
|
|
6665
|
+
Tag: { role: "text", name: "required", state: ["selected (if in a group)"], decorative: false },
|
|
6666
|
+
// ---- Images and media ---------------------------------------------------------------
|
|
6667
|
+
Image: { role: "image", name: "conditional", state: [], decorative: false },
|
|
6668
|
+
// `contentDescription` present ⇒ IMAGE; absent ⇒ DECORATIVE. That is exactly why this pass
|
|
6669
|
+
// can exist: before #2893 there was no way for an author to SAY "decorative", so a validator
|
|
6670
|
+
// could not tell a chevron from an unlabelled icon button and any rule would have been noise.
|
|
6671
|
+
Icon: { role: "decorative", name: "conditional", state: [], decorative: true },
|
|
6672
|
+
Avatar: { role: "image", name: "required", state: [], decorative: false },
|
|
6673
|
+
AvatarStrip: { role: "group", name: "required", state: ["count"], decorative: false },
|
|
6674
|
+
Video: { role: "group", name: "required", state: ["playing/paused", "position"], decorative: false },
|
|
6675
|
+
MediaPlayer: { role: "group", name: "required", state: ["playing/paused", "position"], decorative: false },
|
|
6676
|
+
Lottie: { role: "decorative", name: "conditional", state: [], decorative: true },
|
|
6677
|
+
Rive: { role: "decorative", name: "conditional", state: [], decorative: true },
|
|
6678
|
+
PdfView: { role: "group", name: "required", state: ["page N of M"], decorative: false },
|
|
6679
|
+
VoiceNote: { role: "group", name: "required", state: ["playing", "duration/position"], decorative: false },
|
|
6680
|
+
Map: { role: "image", name: "required", state: [], decorative: false },
|
|
6681
|
+
WebView: { role: "group", name: "required", state: [], decorative: false },
|
|
6682
|
+
// ---- Interactive controls -----------------------------------------------------------
|
|
6683
|
+
Button: { role: "button", name: "required", state: ["disabled"], decorative: false },
|
|
6684
|
+
Fab: { role: "button", name: "required", state: ["disabled"], decorative: false },
|
|
6685
|
+
TextField: { role: "textfield", name: "required", state: ["value", "error", "required"], decorative: false },
|
|
6686
|
+
SearchField: { role: "search", name: "required", state: ["value"], decorative: false },
|
|
6687
|
+
Toggle: { role: "toggle", name: "required", state: ["on/off"], decorative: false },
|
|
6688
|
+
Stepper: { role: "adjustable", name: "required", state: ["value", "increment/decrement"], decorative: false },
|
|
6689
|
+
Slider: { role: "adjustable", name: "required", state: ["value (+ min/max/pct)"], decorative: false },
|
|
6690
|
+
SelectionControl: { role: "checkbox", name: "required", state: ["checked", "group membership"], decorative: false },
|
|
6691
|
+
Picker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
|
|
6692
|
+
DatePicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
|
|
6693
|
+
WheelPicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
|
|
6694
|
+
ColorPicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
|
|
6695
|
+
OtpInput: { role: "textfield", name: "required", state: ["value", "per-cell position"], decorative: false },
|
|
6696
|
+
ChipsInput: { role: "textfield", name: "required", state: ["value", "each chip removable"], decorative: false },
|
|
6697
|
+
Chip: { role: "button", name: "required", state: ["selected", "disabled"], decorative: false },
|
|
6698
|
+
FilterChips: { role: "group", name: "required", state: ["each chip selected"], decorative: false },
|
|
6699
|
+
SegmentedControl: { role: "tablist", name: "required", state: ["each segment selected"], decorative: false },
|
|
6700
|
+
Tabs: { role: "tablist", name: "required", state: ["selected tab", "index/count"], decorative: false },
|
|
6701
|
+
Menu: { role: "menu", name: "required", state: ["each item enabled/checked"], decorative: false },
|
|
6702
|
+
Rating: { role: "adjustable", name: "required", state: ['value "N of M"'], decorative: false },
|
|
6703
|
+
ListItem: { role: "listitem", name: "required", state: ["selected", "disabled", "position"], decorative: false },
|
|
6704
|
+
// ---- Navigation and progress structures ---------------------------------------------
|
|
6705
|
+
DisclosureGroup: { role: "button", name: "required", state: ["expanded/collapsed"], decorative: false },
|
|
6706
|
+
CollapsingHeader: { role: "heading", name: "required", state: ["expanded/collapsed"], decorative: false },
|
|
6707
|
+
Carousel: { role: "list", name: "required", state: ["item N of M"], decorative: false },
|
|
6708
|
+
Pager: { role: "list", name: "required", state: ["item N of M"], decorative: false },
|
|
6709
|
+
PageControl: { role: "adjustable", name: "required", state: ["page N of M"], decorative: false },
|
|
6710
|
+
StepIndicator: { role: "group", name: "required", state: ["step N of M", "current"], decorative: false },
|
|
6711
|
+
// ---- Status, feedback, and overlays -------------------------------------------------
|
|
6712
|
+
ProgressBar: { role: "progressbar", name: "conditional", state: ["value/pct or indeterminate"], decorative: false },
|
|
6713
|
+
ActivityIndicator: { role: "status", name: "conditional", state: ["busy"], decorative: false },
|
|
6714
|
+
Gauge: { role: "progressbar", name: "required", state: ["value + unit"], decorative: false },
|
|
6715
|
+
Skeleton: { role: "decorative", name: "none", state: [], decorative: true },
|
|
6716
|
+
Banner: { role: "status", name: "required", state: ["dismissible"], decorative: false },
|
|
6717
|
+
Snackbar: { role: "status", name: "required", state: [], decorative: false },
|
|
6718
|
+
AlertDialog: { role: "alert", name: "required", state: ["modal"], decorative: false },
|
|
6719
|
+
Tooltip: { role: "unspecified", name: "required", state: [], decorative: false },
|
|
6720
|
+
EmptyState: { role: "group", name: "required", state: [], decorative: false },
|
|
6721
|
+
StatefulSection: { role: "group", name: "conditional", state: ["loading/empty/error/loaded"], decorative: false },
|
|
6722
|
+
FieldError: { role: "alert", name: "required", state: ["associated field"], decorative: false },
|
|
6723
|
+
BottomSheet: { role: "dialog", name: "required", state: ["modal", "expanded"], decorative: false },
|
|
6724
|
+
Popover: { role: "dialog", name: "required", state: ["modal", "expanded"], decorative: false },
|
|
6725
|
+
Form: { role: "group", name: "conditional", state: ["field grouping", "errors"], decorative: false },
|
|
6726
|
+
FormField: { role: "group", name: "conditional", state: ["field grouping", "errors"], decorative: false },
|
|
6727
|
+
// ---- Data, visualization, and temporal ----------------------------------------------
|
|
6728
|
+
Chart: { role: "image", name: "required", state: ["a spoken data summary"], decorative: false },
|
|
6729
|
+
DonutChart: { role: "image", name: "required", state: ["a spoken data summary"], decorative: false },
|
|
6730
|
+
Legend: { role: "list", name: "required", state: ["each series name + value"], decorative: false },
|
|
6731
|
+
DataTable: { role: "group", name: "required", state: ["row/col headers", "cell position"], decorative: false },
|
|
6732
|
+
Table: { role: "group", name: "required", state: ["row/col headers", "cell position"], decorative: false },
|
|
6733
|
+
MonthCalendar: { role: "grid", name: "required", state: ["selected date", "today", "range"], decorative: false },
|
|
6734
|
+
TimeGrid: { role: "grid", name: "required", state: ["slot time", "availability", "selected"], decorative: false },
|
|
6735
|
+
Agenda: { role: "list", name: "required", state: ["each entry time + title"], decorative: false },
|
|
6736
|
+
Timeline: { role: "list", name: "required", state: ["each event position + label"], decorative: false },
|
|
6737
|
+
// ---- Fragment / worker composition --------------------------------------------------
|
|
6738
|
+
// Pass-through: the subtree they render is subject to the same contract, so scoring the
|
|
6739
|
+
// carrier as well would double-report its children.
|
|
6740
|
+
FragmentSlot: { role: "unspecified", name: "none", state: ["announcement on case change"], decorative: false },
|
|
6741
|
+
WorkerSubtree: { role: "unspecified", name: "none", state: [], decorative: false }
|
|
6742
|
+
};
|
|
6743
|
+
ACCESSIBLE_NAME_KEYS = [
|
|
6744
|
+
"accessibilityLabel",
|
|
6745
|
+
"contentDescription",
|
|
6746
|
+
"text",
|
|
6747
|
+
"title",
|
|
6748
|
+
"label",
|
|
6749
|
+
"placeholder",
|
|
6750
|
+
"message",
|
|
6751
|
+
"subtitle",
|
|
6752
|
+
"overline",
|
|
6753
|
+
"caption",
|
|
6754
|
+
"initials",
|
|
6755
|
+
"emptyText",
|
|
6756
|
+
"actionLabel",
|
|
6757
|
+
"confirmLabel",
|
|
6758
|
+
"cancelLabel",
|
|
6759
|
+
"helpText",
|
|
6760
|
+
"errorMessage",
|
|
6761
|
+
"centerTitle",
|
|
6762
|
+
"centerSubtitle",
|
|
6763
|
+
// The one `…Path` TWIN of a name prop in the whole vocabulary. Binding copy to worker state
|
|
6764
|
+
// is authoring it, not omitting it — `textPath: "$service:cart.title"` speaks on device.
|
|
6765
|
+
// (Checked: `textPath` is the only `<nameKey>Path` prop `KNOWN_PROPS` declares. The other
|
|
6766
|
+
// ~40 `…Path` props bind items, colours, dates and values, none of which is a name.)
|
|
6767
|
+
"textPath"
|
|
6768
|
+
];
|
|
6769
|
+
CONTENT_ARM_KEYS = ["template", "timeRef"];
|
|
6770
|
+
TAP_MODIFIER_KEYS = ["onTap", "onLongPress", "onDoubleTap"];
|
|
6771
|
+
}
|
|
6772
|
+
});
|
|
6773
|
+
|
|
6519
6774
|
// ../../stdlib/wix-sdk/media/src/index.ts
|
|
6520
6775
|
function wixMediaId(reference) {
|
|
6521
6776
|
return WIX_IMAGE.exec(reference)?.[1] ?? (reference.includes("/") || reference.includes(":") ? "" : reference);
|
|
@@ -7428,7 +7683,7 @@ function serviceFieldDeclared(state, path2) {
|
|
|
7428
7683
|
function ellipsis(value, max) {
|
|
7429
7684
|
return value.length <= max ? value : `${value.slice(0, max)}\u2026`;
|
|
7430
7685
|
}
|
|
7431
|
-
function
|
|
7686
|
+
function own2(table, key2) {
|
|
7432
7687
|
return Object.prototype.hasOwnProperty.call(table, key2) ? table[key2] : void 0;
|
|
7433
7688
|
}
|
|
7434
7689
|
function isOpaqueAuthorJson(key2, value, atRoot) {
|
|
@@ -7473,7 +7728,7 @@ function nativeRequiredFindings(descriptor) {
|
|
|
7473
7728
|
value.forEach((v, i) => checkNested(v, of, `${path2}[${i}]`, from));
|
|
7474
7729
|
return;
|
|
7475
7730
|
}
|
|
7476
|
-
const rule =
|
|
7731
|
+
const rule = own2(NATIVE_NESTED_CLASSES, cls);
|
|
7477
7732
|
if (!rule) return;
|
|
7478
7733
|
if (Array.isArray(value) || !value || typeof value !== "object") {
|
|
7479
7734
|
reportKind(cls, value, path2, from);
|
|
@@ -7481,17 +7736,17 @@ function nativeRequiredFindings(descriptor) {
|
|
|
7481
7736
|
}
|
|
7482
7737
|
const bag = value;
|
|
7483
7738
|
for (const name of rule.required) {
|
|
7484
|
-
if (
|
|
7739
|
+
if (own2(bag, name) !== void 0 && bag[name] !== null) continue;
|
|
7485
7740
|
out.push({
|
|
7486
7741
|
path: `${path2}.${name}`,
|
|
7487
7742
|
message: `${cls}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${cls}', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
|
|
7488
7743
|
});
|
|
7489
7744
|
}
|
|
7490
7745
|
for (const [name, sub] of Object.entries(rule.nested)) {
|
|
7491
|
-
const inner =
|
|
7746
|
+
const inner = own2(bag, name);
|
|
7492
7747
|
if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path2}.${name}`, from);
|
|
7493
7748
|
}
|
|
7494
|
-
if (cls === "Action") checkActionParams(
|
|
7749
|
+
if (cls === "Action") checkActionParams(own2(bag, "params"), `${path2}.params`, from);
|
|
7495
7750
|
};
|
|
7496
7751
|
const checkActionParams = (params, path2, from) => {
|
|
7497
7752
|
if (params === void 0 || params === null) return;
|
|
@@ -7524,22 +7779,22 @@ function nativeRequiredFindings(descriptor) {
|
|
|
7524
7779
|
const props = body.props;
|
|
7525
7780
|
const bag = props && typeof props === "object" && !Array.isArray(props) ? props : {};
|
|
7526
7781
|
const base = at ? `${at}.body.props` : "body.props";
|
|
7527
|
-
for (const name of
|
|
7528
|
-
if (
|
|
7782
|
+
for (const name of own2(NATIVE_REQUIRED_PROPS, type) ?? []) {
|
|
7783
|
+
if (own2(bag, name) !== void 0 && bag[name] !== null) continue;
|
|
7529
7784
|
const hint = type === "Button" && name === "title" && bag.iconOnly === true ? " \u2014 `iconOnly` HIDES the label, it does not make it optional; keep a title (it is also the accessibility label)" : "";
|
|
7530
7785
|
out.push({
|
|
7531
7786
|
path: `${base}.${name}`,
|
|
7532
7787
|
message: `${type}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${type}Props', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine${hint}`
|
|
7533
7788
|
});
|
|
7534
7789
|
}
|
|
7535
|
-
for (const [prop, cls] of Object.entries(
|
|
7536
|
-
const value =
|
|
7790
|
+
for (const [prop, cls] of Object.entries(own2(NATIVE_NESTED_PROPS, type) ?? {})) {
|
|
7791
|
+
const value = own2(bag, prop);
|
|
7537
7792
|
if (value === void 0 || value === null) continue;
|
|
7538
7793
|
checkNested(value, cls, `${base}.${prop}`, `${type}.${prop}`);
|
|
7539
7794
|
}
|
|
7540
7795
|
}
|
|
7541
7796
|
if (body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string") {
|
|
7542
|
-
const modifiers =
|
|
7797
|
+
const modifiers = own2(record2, "modifiers");
|
|
7543
7798
|
if (modifiers !== void 0 && modifiers !== null) {
|
|
7544
7799
|
checkNested(modifiers, NATIVE_MODIFIERS_CLASS, at ? `${at}.modifiers` : "modifiers", "modifiers");
|
|
7545
7800
|
}
|
|
@@ -7553,7 +7808,7 @@ function nativeRequiredFindings(descriptor) {
|
|
|
7553
7808
|
if (descriptor && typeof descriptor === "object" && !Array.isArray(descriptor)) {
|
|
7554
7809
|
const root = descriptor;
|
|
7555
7810
|
for (const [field, cls] of Object.entries(NATIVE_DESCRIPTOR_NESTED)) {
|
|
7556
|
-
const value =
|
|
7811
|
+
const value = own2(root, field);
|
|
7557
7812
|
if (value === void 0 || value === null) continue;
|
|
7558
7813
|
checkNested(value, cls, field, `${NATIVE_DESCRIPTOR_CLASS}.${field}`);
|
|
7559
7814
|
}
|
|
@@ -7583,14 +7838,14 @@ function componentPropFindings(descriptor) {
|
|
|
7583
7838
|
const body = record2.body;
|
|
7584
7839
|
if (typeof body?.package === "string" && CORE_PACKAGES.has(body.package) && typeof body.type === "string") {
|
|
7585
7840
|
const type = body.type;
|
|
7586
|
-
const declared =
|
|
7841
|
+
const declared = own2(KNOWN_PROPS, type);
|
|
7587
7842
|
const props = body.props;
|
|
7588
7843
|
if (declared && props && typeof props === "object" && !Array.isArray(props)) {
|
|
7589
7844
|
const bag = props;
|
|
7590
7845
|
const base = at ? `${at}.body.props` : "body.props";
|
|
7591
7846
|
for (const name of Object.keys(bag)) {
|
|
7592
7847
|
const path2 = `${base}.${name}`;
|
|
7593
|
-
const kind =
|
|
7848
|
+
const kind = own2(declared, name);
|
|
7594
7849
|
if (kind === void 0) {
|
|
7595
7850
|
if (LEGACY_UNSCORED_KEYS.has(`${type}.${name}`)) continue;
|
|
7596
7851
|
const hint = MODIFIER_KEYS.has(name) ? ` \u2014 \`${name}\` is a MODIFIER, not a prop: move it out of \`props\` and into the node's \`modifiers\` bag (\`{ id, body, modifiers: { ${name}: \u2026 } }\`)` : "";
|
|
@@ -7606,7 +7861,7 @@ function componentPropFindings(descriptor) {
|
|
|
7606
7861
|
if (kind === "any") continue;
|
|
7607
7862
|
if (typeof value === "string" && BINDING_SIGIL_RE.test(value)) {
|
|
7608
7863
|
if (kind === "string") continue;
|
|
7609
|
-
const twin =
|
|
7864
|
+
const twin = own2(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
|
|
7610
7865
|
const inArray = IN_ARRAY_BINDING_PROPS.has(`${type}.${name}`) && value.startsWith(SERVICE_SIGIL);
|
|
7611
7866
|
out.push({
|
|
7612
7867
|
path: path2,
|
|
@@ -7629,10 +7884,10 @@ function componentPropFindings(descriptor) {
|
|
|
7629
7884
|
});
|
|
7630
7885
|
continue;
|
|
7631
7886
|
}
|
|
7632
|
-
if (
|
|
7887
|
+
if (own2(NATIVE_PROP_ENUMS, name) !== void 0) continue;
|
|
7633
7888
|
const actual = wireKind(value);
|
|
7634
7889
|
if (actual === kind) {
|
|
7635
|
-
if (kind === "number" && typeof value === "number" && !Number.isInteger(value) &&
|
|
7890
|
+
if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own2(INTEGER_PROPS, type)?.includes(name)) {
|
|
7636
7891
|
out.push({
|
|
7637
7892
|
path: path2,
|
|
7638
7893
|
kind: "decode",
|
|
@@ -7650,13 +7905,13 @@ function componentPropFindings(descriptor) {
|
|
|
7650
7905
|
}
|
|
7651
7906
|
}
|
|
7652
7907
|
if (body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string") {
|
|
7653
|
-
const modifiers =
|
|
7908
|
+
const modifiers = own2(record2, "modifiers");
|
|
7654
7909
|
if (modifiers && typeof modifiers === "object" && !Array.isArray(modifiers)) {
|
|
7655
7910
|
const schemaOwnsUnknownKeys = SCHEMA_SCORED_NODES.has(at);
|
|
7656
7911
|
const bag = modifiers;
|
|
7657
7912
|
for (const key2 of Object.keys(bag)) {
|
|
7658
7913
|
if (MODIFIER_KEYS.has(key2)) {
|
|
7659
|
-
const spec =
|
|
7914
|
+
const spec = own2(MODIFIER_KINDS, key2);
|
|
7660
7915
|
const value = bag[key2];
|
|
7661
7916
|
if (!spec || value === void 0 || value === null) continue;
|
|
7662
7917
|
const where = at ? `${at}.modifiers.${key2}` : `modifiers.${key2}`;
|
|
@@ -8252,7 +8507,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
8252
8507
|
if (isOpaqueAuthorJson(k, val, at === "")) continue;
|
|
8253
8508
|
if (k === "params" && typeof node.actionId === "string") continue;
|
|
8254
8509
|
const here = at ? `${at}.${k}` : k;
|
|
8255
|
-
const allowed2 =
|
|
8510
|
+
const allowed2 = own2(NATIVE_PROP_ENUMS, k);
|
|
8256
8511
|
if (typeof val === "string" && enums.has(k) && DYNAMIC_PLACEHOLDER.test(val)) {
|
|
8257
8512
|
issues.push({
|
|
8258
8513
|
severity: "error",
|
|
@@ -8493,6 +8748,30 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
|
|
|
8493
8748
|
});
|
|
8494
8749
|
}
|
|
8495
8750
|
}
|
|
8751
|
+
const a11yMode = opts.a11y?.enforce ?? "error";
|
|
8752
|
+
if (a11yMode !== "off") {
|
|
8753
|
+
const severity = a11yMode === "warn" && !strict ? "warning" : "error";
|
|
8754
|
+
const gaps = accessibleNameGaps(descriptor);
|
|
8755
|
+
const CAP4 = 20;
|
|
8756
|
+
for (const gap of gaps.slice(0, CAP4)) {
|
|
8757
|
+
const row = Object.prototype.hasOwnProperty.call(A11Y_CONTRACT, gap.type) ? A11Y_CONTRACT[gap.type] : void 0;
|
|
8758
|
+
const why = gap.reason === "interactive" ? `it carries an \`onTap\`/\`onLongPress\`/\`onDoubleTap\`, which promotes ANY node to a control that owes a name (RFC 0058 \xA73.4)` : `RFC 0058 \xA73.3 requires a name for \`${gap.type}\` (announced as \`${gap.role}\`)`;
|
|
8759
|
+
const fix = gap.reason === "contract" ? `Give it \`modifiers.accessibilityLabel\`, or copy on a descendant \u2014 or, if it really is presentational, say so with \`modifiers.accessibilityRole: "decorative"\` (node-local) or \`modifiers.accessibilityHidden: true\` (whole subtree).` : `Give it \`modifiers.accessibilityLabel\`, or put readable copy on a descendant. An icon-only control names itself with \`Icon.contentDescription\`. \`decorative\` does not silence a control${row?.decorative ? ` \u2014 a tappable \`${gap.type}\` is one` : ""}.`;
|
|
8760
|
+
issues.push({
|
|
8761
|
+
severity,
|
|
8762
|
+
pass: "a11y",
|
|
8763
|
+
path: gap.at,
|
|
8764
|
+
message: `${gap.type} renders no accessible name anywhere in its subtree, and ${why}. A screen reader announces this node as an unnamed \`${gap.role}\`. ${fix}`
|
|
8765
|
+
});
|
|
8766
|
+
}
|
|
8767
|
+
if (gaps.length > CAP4) {
|
|
8768
|
+
issues.push({
|
|
8769
|
+
severity,
|
|
8770
|
+
pass: "a11y",
|
|
8771
|
+
message: `+${gaps.length - CAP4} more node(s) on this screen render no accessible name (${gaps.length} in total). Fix the ${CAP4} above and re-run to see the rest.`
|
|
8772
|
+
});
|
|
8773
|
+
}
|
|
8774
|
+
}
|
|
8496
8775
|
return {
|
|
8497
8776
|
screenId,
|
|
8498
8777
|
ok: !issues.some((i) => i.severity === "error"),
|
|
@@ -8507,6 +8786,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
8507
8786
|
init_validator();
|
|
8508
8787
|
init_validator();
|
|
8509
8788
|
init_l10n_strings();
|
|
8789
|
+
init_a11y_contract();
|
|
8510
8790
|
init_bindings();
|
|
8511
8791
|
init_media_value();
|
|
8512
8792
|
init_frame_limits();
|
|
@@ -8957,6 +9237,7 @@ var init_validate_descriptor_core = __esm({
|
|
|
8957
9237
|
interactive: "boolean",
|
|
8958
9238
|
max: "number",
|
|
8959
9239
|
onChange: "any",
|
|
9240
|
+
size: "string",
|
|
8960
9241
|
value: "number",
|
|
8961
9242
|
valuePath: "string"
|
|
8962
9243
|
},
|
|
@@ -12729,8 +13010,8 @@ var init_tokens2 = __esm({
|
|
|
12729
13010
|
// ../font-bake/web-fallback.ts
|
|
12730
13011
|
function webRenderedFallback(family) {
|
|
12731
13012
|
const stack = fontStack(family);
|
|
12732
|
-
const
|
|
12733
|
-
const tail = stack.startsWith(
|
|
13013
|
+
const own3 = `"${family}", `;
|
|
13014
|
+
const tail = stack.startsWith(own3) ? stack.slice(own3.length) : stack;
|
|
12734
13015
|
return tail.split(",")[0].trim().replace(/^"(.*)"$/, "$1");
|
|
12735
13016
|
}
|
|
12736
13017
|
var init_web_fallback = __esm({
|
|
@@ -14076,7 +14357,7 @@ function parseIconConfig(configTs) {
|
|
|
14076
14357
|
const block = /^ {2}icon\s*[:=]\s*\{([^}]*)\}/m.exec(src);
|
|
14077
14358
|
if (!block) return {};
|
|
14078
14359
|
const body = block[1];
|
|
14079
|
-
const
|
|
14360
|
+
const str7 = (k) => new RegExp(`\\b${k}\\s*:\\s*["']([^"']+)["']`).exec(body)?.[1];
|
|
14080
14361
|
const num3 = (k) => {
|
|
14081
14362
|
const m = new RegExp(`\\b${k}\\s*:\\s*(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)\\s*(?=[,}\\n]|$)`).exec(body);
|
|
14082
14363
|
if (!m) return void 0;
|
|
@@ -14087,10 +14368,10 @@ function parseIconConfig(configTs) {
|
|
|
14087
14368
|
return n;
|
|
14088
14369
|
};
|
|
14089
14370
|
const out = {};
|
|
14090
|
-
const source =
|
|
14091
|
-
const glyph =
|
|
14092
|
-
const accentColor =
|
|
14093
|
-
const backgroundColor =
|
|
14371
|
+
const source = str7("source");
|
|
14372
|
+
const glyph = str7("glyph");
|
|
14373
|
+
const accentColor = str7("accentColor");
|
|
14374
|
+
const backgroundColor = str7("backgroundColor");
|
|
14094
14375
|
const glyphScale = num3("glyphScale");
|
|
14095
14376
|
for (const [key2, parsed] of [
|
|
14096
14377
|
["source", source],
|
|
@@ -18732,13 +19013,13 @@ function parsePaddingShorthand(v) {
|
|
|
18732
19013
|
}
|
|
18733
19014
|
function addIntrinsicPadding(style, modPad) {
|
|
18734
19015
|
if (!style) return void 0;
|
|
18735
|
-
const
|
|
18736
|
-
if (!
|
|
19016
|
+
const own3 = parsePaddingShorthand(style.padding);
|
|
19017
|
+
if (!own3) return void 0;
|
|
18737
19018
|
const sides = [
|
|
18738
|
-
["paddingTop",
|
|
18739
|
-
["paddingBottom",
|
|
18740
|
-
["paddingLeft",
|
|
18741
|
-
["paddingRight",
|
|
19019
|
+
["paddingTop", own3.top],
|
|
19020
|
+
["paddingBottom", own3.bottom],
|
|
19021
|
+
["paddingLeft", own3.left],
|
|
19022
|
+
["paddingRight", own3.right]
|
|
18742
19023
|
];
|
|
18743
19024
|
let out;
|
|
18744
19025
|
for (const [key2, ownPx] of sides) {
|
|
@@ -24025,10 +24306,10 @@ function calSnap(minuteOfDay, step) {
|
|
|
24025
24306
|
return Math.min(Math.max(Math.round(minuteOfDay / s) * s, 0), 24 * 60);
|
|
24026
24307
|
}
|
|
24027
24308
|
function calMoveEvent(startMinute, endMinute, deltaMinutes, step) {
|
|
24028
|
-
const
|
|
24029
|
-
const maxStart = Math.max(0, 24 * 60 -
|
|
24309
|
+
const duration2 = Math.max(1, endMinute - startMinute);
|
|
24310
|
+
const maxStart = Math.max(0, 24 * 60 - duration2);
|
|
24030
24311
|
const start = Math.min(Math.max(calSnap(startMinute + deltaMinutes, step), 0), maxStart);
|
|
24031
|
-
return { startMinute: start, endMinute: start +
|
|
24312
|
+
return { startMinute: start, endMinute: start + duration2 };
|
|
24032
24313
|
}
|
|
24033
24314
|
function calResizeEvent(startMinute, endMinute, deltaMinutes, step) {
|
|
24034
24315
|
const s = Math.max(1, step);
|
|
@@ -24178,7 +24459,7 @@ function calKeyActivate(enabled, activate) {
|
|
|
24178
24459
|
function applyA11ySemantics(node, ctx, extra) {
|
|
24179
24460
|
const m = node?.modifiers;
|
|
24180
24461
|
if (!m) return void 0;
|
|
24181
|
-
const
|
|
24462
|
+
const str7 = (v) => {
|
|
24182
24463
|
if (v == null) return void 0;
|
|
24183
24464
|
const r = resolveScalarStatic(v, ctx);
|
|
24184
24465
|
const s = r == null ? "" : String(r).trim();
|
|
@@ -24189,7 +24470,7 @@ function applyA11ySemantics(node, ctx, extra) {
|
|
|
24189
24470
|
extra.inert = "";
|
|
24190
24471
|
return void 0;
|
|
24191
24472
|
}
|
|
24192
|
-
const role =
|
|
24473
|
+
const role = str7(m.accessibilityRole ?? m.accessibility_role);
|
|
24193
24474
|
const headingLevel = m.headingLevel ?? m.heading_level;
|
|
24194
24475
|
const tappable = Boolean((m.onTap ?? m.on_tap ?? m.onDoubleTap ?? m.on_double_tap) && ctx.onAction);
|
|
24195
24476
|
if (role === "decorative" && !tappable) {
|
|
@@ -24204,8 +24485,8 @@ function applyA11ySemantics(node, ctx, extra) {
|
|
|
24204
24485
|
if (typeof headingLevel === "number" && headingLevel >= 1 && headingLevel <= 6) {
|
|
24205
24486
|
extra["aria-level"] = String(headingLevel);
|
|
24206
24487
|
}
|
|
24207
|
-
const hint =
|
|
24208
|
-
const value =
|
|
24488
|
+
const hint = str7(m.accessibilityHint ?? m.accessibility_hint);
|
|
24489
|
+
const value = str7(m.accessibilityValue ?? m.accessibility_value);
|
|
24209
24490
|
if (value) extra["aria-valuetext"] = value;
|
|
24210
24491
|
const traits = m.accessibilityTraits ?? m.accessibility_traits;
|
|
24211
24492
|
if (Array.isArray(traits)) {
|
|
@@ -25079,7 +25360,7 @@ function renderInner(node, ctx) {
|
|
|
25079
25360
|
}
|
|
25080
25361
|
}
|
|
25081
25362
|
}
|
|
25082
|
-
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
|
|
25363
|
+
var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
|
|
25083
25364
|
var init_renderNode = __esm({
|
|
25084
25365
|
"../../core/web-renderer/src/renderNode.tsx"() {
|
|
25085
25366
|
"use strict";
|
|
@@ -25808,7 +26089,7 @@ var init_renderNode = __esm({
|
|
|
25808
26089
|
}, [resolvedItems.length, startIndex, queueReady, seatKey]);
|
|
25809
26090
|
const [status, setStatus] = React5.useState("idle");
|
|
25810
26091
|
const [position, setPosition] = React5.useState(initialStartPosition);
|
|
25811
|
-
const [
|
|
26092
|
+
const [duration2, setDuration] = React5.useState(0);
|
|
25812
26093
|
const [buffered, setBuffered] = React5.useState(0);
|
|
25813
26094
|
const [rate, setRateState] = React5.useState(1);
|
|
25814
26095
|
const [fullscreen, setFullscreen] = React5.useState(false);
|
|
@@ -25851,9 +26132,9 @@ var init_renderNode = __esm({
|
|
|
25851
26132
|
artist: String(item?.artist ?? ""),
|
|
25852
26133
|
artworkUrl: String(item?.artworkUrl ?? props.posterUrl ?? ""),
|
|
25853
26134
|
positionSeconds: position,
|
|
25854
|
-
durationSeconds:
|
|
26135
|
+
durationSeconds: duration2 || Number(item?.durationSeconds ?? 0),
|
|
25855
26136
|
bufferedSeconds: buffered,
|
|
25856
|
-
progress:
|
|
26137
|
+
progress: duration2 > 0 ? Math.max(0, Math.min(1, position / duration2)) : 0,
|
|
25857
26138
|
muted: mediaRef.current?.muted ?? props.muted === true,
|
|
25858
26139
|
rate,
|
|
25859
26140
|
fullscreen,
|
|
@@ -25881,7 +26162,7 @@ var init_renderNode = __esm({
|
|
|
25881
26162
|
status,
|
|
25882
26163
|
index,
|
|
25883
26164
|
positionSeconds: position,
|
|
25884
|
-
durationSeconds:
|
|
26165
|
+
durationSeconds: duration2 || Number(item?.durationSeconds ?? 0),
|
|
25885
26166
|
bufferedSeconds: buffered,
|
|
25886
26167
|
rate,
|
|
25887
26168
|
muted: mediaRef.current?.muted ?? props.muted === true,
|
|
@@ -25891,7 +26172,7 @@ var init_renderNode = __esm({
|
|
|
25891
26172
|
error
|
|
25892
26173
|
};
|
|
25893
26174
|
ctx.onAction({ ...action, args: { ...action.args ?? {}, ...snapshot2, ...extra }, params: { ...action.params ?? {}, sessionId, index: String(index), ...Object.fromEntries(Object.entries(extra).map(([k, v]) => [k, String(v)])) } });
|
|
25894
|
-
}, [ctx.onAction, sessionId, status, index, position,
|
|
26175
|
+
}, [ctx.onAction, sessionId, status, index, position, duration2, item, buffered, rate, props.muted, fullscreen, error]);
|
|
25895
26176
|
React5.useEffect(() => {
|
|
25896
26177
|
if (!isUnsupportedProvider || status === "error") return;
|
|
25897
26178
|
setStatus("error");
|
|
@@ -26115,8 +26396,8 @@ var init_renderNode = __esm({
|
|
|
26115
26396
|
/* @__PURE__ */ jsx6("button", { "aria-label": status === "playing" ? "Pause" : "Play", onClick: () => status === "playing" ? pause() : void play(), style: { width: 38, height: 38, borderRadius: "50%", color: background, background: foreground, border: 0, fontSize: 18 }, children: status === "playing" ? "\u275A\u275A" : "\u25B6" }),
|
|
26116
26397
|
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [
|
|
26117
26398
|
/* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(position) }),
|
|
26118
|
-
/* @__PURE__ */ jsx6("input", { "aria-label": "Media position", type: "range", min: 0, max: Math.max(
|
|
26119
|
-
/* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(
|
|
26399
|
+
/* @__PURE__ */ jsx6("input", { "aria-label": "Media position", type: "range", min: 0, max: Math.max(duration2, 1), step: 0.1, value: Math.min(position, Math.max(duration2, 1)), onChange: (event) => seek(Number(event.currentTarget.value)), style: { width: "100%", accentColor: accent } }),
|
|
26400
|
+
/* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(duration2) })
|
|
26120
26401
|
] }),
|
|
26121
26402
|
items.length > 1 && /* @__PURE__ */ jsx6("button", { "aria-label": "Next", onClick: () => select(index + 1), style: { color: "inherit", background: "transparent", border: 0, fontSize: 18 }, children: "\u25B6\u25B6" }),
|
|
26122
26403
|
props.fullscreen !== "disabled" && /* @__PURE__ */ jsx6("button", { "aria-label": "Fullscreen", onClick: () => void toggleFullscreen(), style: { color: "inherit", background: "transparent", border: 0, fontSize: 18 }, children: "\u26F6" })
|
|
@@ -27003,20 +27284,26 @@ var init_renderNode = __esm({
|
|
|
27003
27284
|
/* @__PURE__ */ jsx6("div", { style: { position: "absolute", inset: 0, display: "grid", placeItems: "center", fontFamily: fontStack(capF.family), fontSize: capF.remSize, fontWeight: capF.weight, color: C("textPrimary", "#13171e") }, children: txt(props.label, ctx) || `${Math.round(pct * 100)}%` })
|
|
27004
27285
|
] }) });
|
|
27005
27286
|
});
|
|
27287
|
+
RATING_METRICS = {
|
|
27288
|
+
sm: { cell: 16, glyph: 14, gap: 2 },
|
|
27289
|
+
md: { cell: 22, glyph: 20, gap: 3 }
|
|
27290
|
+
};
|
|
27291
|
+
ratingMetrics = (size) => size === "sm" ? RATING_METRICS.sm : RATING_METRICS.md;
|
|
27006
27292
|
RatingNode = withExtras("RatingNode", ({ props, ctx, wrap }) => {
|
|
27007
27293
|
const C = ctx.color;
|
|
27008
27294
|
const bound = useResolvedScalar(props.valuePath, ctx);
|
|
27009
27295
|
const raw = props.valuePath != null ? bound : props.value;
|
|
27010
27296
|
const val = typeof raw === "number" ? raw : 0;
|
|
27011
27297
|
const max = props.max ?? 5;
|
|
27298
|
+
const m = ratingMetrics(props.size);
|
|
27012
27299
|
const col = C(props.color ?? "warning", "#E89F00");
|
|
27013
27300
|
const invalidIcon = props.icon != null && typeof props.icon !== "string";
|
|
27014
27301
|
const base = invalidIcon ? ICON_FALLBACK : (typeof props.icon === "string" && props.icon ? props.icon : "star").replace(/_fill$/, "");
|
|
27015
27302
|
const filledCount = Math.round(val);
|
|
27016
27303
|
const onClickStar = (i) => ctx.onAction && props.interactive && props.onChange ? () => ctx.onAction({ ...props.onChange, params: { ...props.onChange?.params ?? {}, value: String(i + 1) } }) : void 0;
|
|
27017
|
-
return /* @__PURE__ */ jsx6("span", { style: { display: "inline-flex", alignItems: "center", gap:
|
|
27304
|
+
return /* @__PURE__ */ jsx6("span", { style: { display: "inline-flex", alignItems: "center", gap: m.gap, ...wrap }, children: Array.from({ length: max }).map((_, i) => {
|
|
27018
27305
|
const filled = i < filledCount;
|
|
27019
|
-
return /* @__PURE__ */ jsx6("span", { onClick: onClickStar(i), style: { display: "inline-grid", placeItems: "center", width:
|
|
27306
|
+
return /* @__PURE__ */ jsx6("span", { onClick: onClickStar(i), style: { display: "inline-grid", placeItems: "center", width: m.cell, height: m.cell, cursor: props.interactive ? "pointer" : "default", opacity: filled ? 1 : 0.28 }, children: iconSvg(filled ? `${base}_fill` : base, { size: m.glyph, color: col }) }, i);
|
|
27020
27307
|
}) });
|
|
27021
27308
|
});
|
|
27022
27309
|
AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
|
|
@@ -28449,10 +28736,10 @@ var init_renderNode = __esm({
|
|
|
28449
28736
|
};
|
|
28450
28737
|
A11yHintDescription = ({ hint, idBase, children, ...forwarded }) => {
|
|
28451
28738
|
const descId = `${idBase ?? "hm"}__hint${React5.useId()}`;
|
|
28452
|
-
const
|
|
28739
|
+
const own3 = children.props;
|
|
28453
28740
|
const next = { ...forwarded };
|
|
28454
|
-
if (forwarded.style) next.style = { ...
|
|
28455
|
-
next["aria-describedby"] = [
|
|
28741
|
+
if (forwarded.style) next.style = { ...own3.style ?? {}, ...forwarded.style };
|
|
28742
|
+
next["aria-describedby"] = [own3["aria-describedby"], descId].filter(Boolean).join(" ");
|
|
28456
28743
|
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
28457
28744
|
React5.cloneElement(children, next),
|
|
28458
28745
|
/* @__PURE__ */ jsx6("span", { id: descId, hidden: true, "data-hm-a11y-hint": "", children: hint })
|
|
@@ -31480,7 +31767,9 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
31480
31767
|
nativeActions,
|
|
31481
31768
|
appWorkerActions,
|
|
31482
31769
|
strict: false,
|
|
31483
|
-
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? [])
|
|
31770
|
+
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
|
|
31771
|
+
// Same a11y rung the build lint applies (RFC 0058 §5) — diagnostics must not disagree.
|
|
31772
|
+
a11y: state.app?.module.config.a11y
|
|
31484
31773
|
});
|
|
31485
31774
|
const telemetry = state.telemetryEvents.filter((e) => e.screenId === screenId && (/^worker_/.test(e.type) || e.type === "bundle_load_revoked")).slice(-20);
|
|
31486
31775
|
const lastError = [...telemetry].reverse().find((e) => /crash|revoked|error|fail/i.test(e.type)) ?? null;
|
|
@@ -32136,8 +32425,8 @@ function startBundleSourceWatcher(state) {
|
|
|
32136
32425
|
}
|
|
32137
32426
|
function applyTopBarDefault(descriptor, config) {
|
|
32138
32427
|
const fallback = config?.navigation?.topBarDefault;
|
|
32139
|
-
const
|
|
32140
|
-
if (!fallback ||
|
|
32428
|
+
const own3 = descriptor?.topBar;
|
|
32429
|
+
if (!fallback || own3) return descriptor;
|
|
32141
32430
|
return { ...descriptor, topBar: fallback };
|
|
32142
32431
|
}
|
|
32143
32432
|
function syncNetMocksWithApp(state) {
|
|
@@ -32405,7 +32694,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32405
32694
|
const session = webWixSession(req, res, state);
|
|
32406
32695
|
const auth = resolveWebWixAuth(state.app);
|
|
32407
32696
|
const path2 = new URL(req.url ?? "", "http://localhost").pathname;
|
|
32408
|
-
const
|
|
32697
|
+
const readJson5 = async () => {
|
|
32409
32698
|
const chunks = [];
|
|
32410
32699
|
for await (const c of req) chunks.push(c);
|
|
32411
32700
|
const t = Buffer.concat(chunks).toString("utf8");
|
|
@@ -32422,7 +32711,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32422
32711
|
res.end(JSON.stringify(obj3));
|
|
32423
32712
|
};
|
|
32424
32713
|
if (path2 === "/v1/__webwix/login" && req.method === "POST") {
|
|
32425
|
-
const b = await
|
|
32714
|
+
const b = await readJson5();
|
|
32426
32715
|
try {
|
|
32427
32716
|
const { memberToken, visitorToken } = await memberDirectLogin(
|
|
32428
32717
|
auth.clientId,
|
|
@@ -32439,7 +32728,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32439
32728
|
}
|
|
32440
32729
|
}
|
|
32441
32730
|
if (path2 === "/v1/__webwix/call" && req.method === "POST") {
|
|
32442
|
-
const b = await
|
|
32731
|
+
const b = await readJson5();
|
|
32443
32732
|
if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
|
|
32444
32733
|
const msid = String(b.ownerMsid ?? "");
|
|
32445
32734
|
if (!isSafeMsid(msid)) return reply(400, { error: "webwix_owner_bad_msid" });
|
|
@@ -32555,7 +32844,7 @@ async function handleWebWix(req, res, state) {
|
|
|
32555
32844
|
});
|
|
32556
32845
|
}
|
|
32557
32846
|
if (path2 === "/v1/__webwix/register" && req.method === "POST") {
|
|
32558
|
-
const b = await
|
|
32847
|
+
const b = await readJson5();
|
|
32559
32848
|
try {
|
|
32560
32849
|
const { memberToken, visitorToken } = await memberDirectRegister(
|
|
32561
32850
|
auth.clientId,
|
|
@@ -33105,7 +33394,8 @@ async function handleAdminPlayground(req, res, state) {
|
|
|
33105
33394
|
nativeActions,
|
|
33106
33395
|
appWorkerActions,
|
|
33107
33396
|
strict,
|
|
33108
|
-
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? [])
|
|
33397
|
+
workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
|
|
33398
|
+
a11y: state.app?.module.config.a11y
|
|
33109
33399
|
});
|
|
33110
33400
|
return sendJson(res, report2.ok ? 200 : 422, report2);
|
|
33111
33401
|
}
|
|
@@ -37532,7 +37822,10 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37532
37822
|
appWorkerActions,
|
|
37533
37823
|
strict: collect2.strict,
|
|
37534
37824
|
workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? []),
|
|
37535
|
-
l10n: l10nLintOptions(preloaded.module.config.locale, preloaded.dir)
|
|
37825
|
+
l10n: l10nLintOptions(preloaded.module.config.locale, preloaded.dir),
|
|
37826
|
+
// RFC 0058 §5 — the app's own rung of the a11y ladder. Omitted ⇒ the validator's
|
|
37827
|
+
// default, "error"; an in-repo app with ratcheted debt declares "warn".
|
|
37828
|
+
a11y: preloaded.module.config.a11y
|
|
37536
37829
|
});
|
|
37537
37830
|
lint.push({ screenId, ok: report2.ok, issues: report2.issues });
|
|
37538
37831
|
}
|
|
@@ -37560,7 +37853,8 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
37560
37853
|
nativeActions,
|
|
37561
37854
|
appWorkerActions,
|
|
37562
37855
|
strict: collect2.strict,
|
|
37563
|
-
workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? [])
|
|
37856
|
+
workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? []),
|
|
37857
|
+
a11y: preloaded.module.config.a11y
|
|
37564
37858
|
});
|
|
37565
37859
|
lint.push({ screenId: wantedRender, ok: report2.ok, issues: report2.issues });
|
|
37566
37860
|
}
|
|
@@ -38095,6 +38389,7 @@ __export(progress_exports, {
|
|
|
38095
38389
|
appleScriptString: () => appleScriptString,
|
|
38096
38390
|
archiveBytes: () => archiveBytes,
|
|
38097
38391
|
archiveImage: () => archiveImage,
|
|
38392
|
+
imageExtension: () => imageExtension,
|
|
38098
38393
|
journalPath: () => journalPath,
|
|
38099
38394
|
notifyDesktop: () => notifyDesktop,
|
|
38100
38395
|
parseStep: () => parseStep,
|
|
@@ -38335,6 +38630,7 @@ __export(studio_exports, {
|
|
|
38335
38630
|
STUDIO_PAGE: () => STUDIO_PAGE,
|
|
38336
38631
|
VALIDATE_RECORD: () => VALIDATE_RECORD,
|
|
38337
38632
|
buildView: () => buildView,
|
|
38633
|
+
escapeHtml: () => escapeHtml,
|
|
38338
38634
|
observeShots: () => observeShots,
|
|
38339
38635
|
openStudio: () => openStudio,
|
|
38340
38636
|
refreshStudio: () => refreshStudio,
|
|
@@ -38473,7 +38769,12 @@ function liveRun(dir) {
|
|
|
38473
38769
|
const build2 = obj(rec?.build);
|
|
38474
38770
|
try {
|
|
38475
38771
|
process.kill(pid, 0);
|
|
38476
|
-
return {
|
|
38772
|
+
return {
|
|
38773
|
+
url,
|
|
38774
|
+
buildError: build2?.ok === false ? text(build2.error) ?? "the last rebuild failed" : null,
|
|
38775
|
+
// Only `--watch` wrote this record before plain runs did, so a record without the key is one.
|
|
38776
|
+
watching: rec?.watching !== false
|
|
38777
|
+
};
|
|
38477
38778
|
} catch {
|
|
38478
38779
|
return null;
|
|
38479
38780
|
}
|
|
@@ -38661,7 +38962,7 @@ function render(s){
|
|
|
38661
38962
|
$("nowmsg").textContent=last?last.message:"Waiting for the first postcard.";
|
|
38662
38963
|
$("nowmeta").textContent=last?("Now \xB7 "+(last.step?("step "+last.stepNumber+" of 8, "+last.step+" \xB7 "):"")+ago(last.ts)):"Now";
|
|
38663
38964
|
var focus=$("focus");clear(focus);var film=$("film");clear(film);
|
|
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))}
|
|
38965
|
+
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",(s.live.watching?"Repaints as the app is edited \xB7 ":"The build this run started with; himi run --watch repaints on every edit \xB7 ")+s.live.url))}
|
|
38665
38966
|
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"))}
|
|
38666
38967
|
else{$("focuslbl").textContent="Latest";focus.appendChild(el("div","empty","The first render appears here."))}
|
|
38667
38968
|
if(s.focus&&s.focus.frames.length>1)s.focus.frames.forEach(function(fm){film.appendChild(img(fm.img))});
|
|
@@ -40659,8 +40960,8 @@ function rewriteNav(nav, removed, homeId) {
|
|
|
40659
40960
|
return p;
|
|
40660
40961
|
};
|
|
40661
40962
|
const tabFor = (screenId) => {
|
|
40662
|
-
const
|
|
40663
|
-
return typeof
|
|
40963
|
+
const own3 = remainingRoots.find((t) => t.screenId === screenId);
|
|
40964
|
+
return typeof own3?.id === "string" ? own3.id : void 0;
|
|
40664
40965
|
};
|
|
40665
40966
|
const homeTab = tabFor(homeId) ?? (typeof remainingRoots[0]?.id === "string" ? remainingRoots[0].id : "");
|
|
40666
40967
|
const finalTab = /* @__PURE__ */ new Map();
|
|
@@ -40795,8 +41096,8 @@ function planTrim(src, keepIds, links) {
|
|
|
40795
41096
|
if (!linksOf(r).some((l) => removedTarget(l.to))) continue;
|
|
40796
41097
|
const block = structuredClone(r.block);
|
|
40797
41098
|
const isDead = (entry) => {
|
|
40798
|
-
const
|
|
40799
|
-
const to =
|
|
41099
|
+
const own3 = tapTarget(entry);
|
|
41100
|
+
const to = own3 && removedTarget(own3) ? own3 : rowTemplateTarget(entry, removedTarget);
|
|
40800
41101
|
if (!to) return false;
|
|
40801
41102
|
dropped.push({ screen: r.label, node: entryLabel(entry), to });
|
|
40802
41103
|
return true;
|
|
@@ -44922,6 +45223,254 @@ var init_functions = __esm({
|
|
|
44922
45223
|
}
|
|
44923
45224
|
});
|
|
44924
45225
|
|
|
45226
|
+
// src/studio-reel.ts
|
|
45227
|
+
var studio_reel_exports = {};
|
|
45228
|
+
__export(studio_reel_exports, {
|
|
45229
|
+
REEL_BUDGET_BYTES: () => REEL_BUDGET_BYTES,
|
|
45230
|
+
buildReel: () => buildReel,
|
|
45231
|
+
inlineImages: () => inlineImages,
|
|
45232
|
+
planReel: () => planReel,
|
|
45233
|
+
renderReel: () => renderReel,
|
|
45234
|
+
thin: () => thin,
|
|
45235
|
+
utcDay: () => utcDay
|
|
45236
|
+
});
|
|
45237
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
45238
|
+
import { lstatSync as lstatSync7, readFileSync as readFileSync52 } from "node:fs";
|
|
45239
|
+
import { basename as basename11, join as join45 } from "node:path";
|
|
45240
|
+
function loadMemory2(dir) {
|
|
45241
|
+
const m = readJson4(join45(dir, ".himi", "studio", "memory.json"));
|
|
45242
|
+
if (!isObj(m) || m.version !== 1 || !isObj(m.shots) || !Array.isArray(m.timeline)) return null;
|
|
45243
|
+
const shots = [];
|
|
45244
|
+
for (const [id, s] of Object.entries(m.shots)) {
|
|
45245
|
+
if (!isObj(s)) continue;
|
|
45246
|
+
const file = historyName(s.sha, s.ext);
|
|
45247
|
+
const firstSeen = str(s.firstSeen);
|
|
45248
|
+
if (!file || !firstSeen) continue;
|
|
45249
|
+
const versions = typeof s.versions === "number" && Number.isSafeInteger(s.versions) && s.versions > 0 ? s.versions : 1;
|
|
45250
|
+
shots.push({ id, file, firstSeen, versions, present: s.present === true });
|
|
45251
|
+
}
|
|
45252
|
+
const timeline = [];
|
|
45253
|
+
for (const t of m.timeline) {
|
|
45254
|
+
if (!isObj(t)) continue;
|
|
45255
|
+
const file = historyName(t.sha, t.ext);
|
|
45256
|
+
const ts2 = str(t.ts);
|
|
45257
|
+
const id = str(t.id);
|
|
45258
|
+
if (file && ts2 && id) timeline.push({ ts: ts2, id, file });
|
|
45259
|
+
}
|
|
45260
|
+
return { createdAt: str(m.createdAt), shots, timeline };
|
|
45261
|
+
}
|
|
45262
|
+
function captionAt(entries, ts2) {
|
|
45263
|
+
let best = null;
|
|
45264
|
+
for (const e of entries) if (e.ts <= ts2) best = e;
|
|
45265
|
+
return best ? best.message : null;
|
|
45266
|
+
}
|
|
45267
|
+
function thin(items, max) {
|
|
45268
|
+
if (items.length <= max) return items;
|
|
45269
|
+
if (max < 2) return items.slice(-1);
|
|
45270
|
+
const out = [];
|
|
45271
|
+
for (let i = 0; i < max; i++) out.push(items[Math.round(i * (items.length - 1) / (max - 1))]);
|
|
45272
|
+
return out;
|
|
45273
|
+
}
|
|
45274
|
+
function planReel(dir) {
|
|
45275
|
+
const memory = loadMemory2(dir);
|
|
45276
|
+
const { entries } = readProgress(dir);
|
|
45277
|
+
const summary = summarizeProgress(entries);
|
|
45278
|
+
const manifest = readJson4(join45(dir, "himalaya.content.json"));
|
|
45279
|
+
const tokens = readJson4(join45(dir, "tokens.json"));
|
|
45280
|
+
const accentToken = tokens?.colors?.accentPrimary;
|
|
45281
|
+
const accentRaw = typeof accentToken === "string" ? accentToken : accentToken?.light;
|
|
45282
|
+
const accent = typeof accentRaw === "string" && ACCENT.test(accentRaw) ? accentRaw : DEFAULT_ACCENT;
|
|
45283
|
+
const shots = memory?.shots ?? [];
|
|
45284
|
+
const present = shots.filter((s) => s.present).sort((a, b) => a.firstSeen.localeCompare(b.firstSeen) || a.id.localeCompare(b.id));
|
|
45285
|
+
const home = present.find((s) => /(^|_)home($|_)/i.test(s.id)) ?? present.find((s) => /home/i.test(s.id));
|
|
45286
|
+
const focusId = home?.id ?? present[0]?.id ?? null;
|
|
45287
|
+
const timeline = memory && focusId ? memory.timeline.filter((t) => t.id === focusId) : [];
|
|
45288
|
+
const frames = thin(timeline, MAX_FLIP_FRAMES).map((t) => ({ ts: t.ts, file: t.file, caption: captionAt(entries, t.ts) }));
|
|
45289
|
+
const finals = present.map((s) => ({ id: s.id, file: s.file }));
|
|
45290
|
+
const postcards = entries.map((e) => ({
|
|
45291
|
+
ts: e.ts,
|
|
45292
|
+
message: e.message,
|
|
45293
|
+
step: str(e.step),
|
|
45294
|
+
files: (Array.isArray(e.images) ? e.images : []).map((i) => isObj(i) && typeof i.file === "string" ? basename11(i.file) : "").filter((f) => HISTORY_NAME.test(f))
|
|
45295
|
+
}));
|
|
45296
|
+
const times = [summary.startedAt, ...timeline.map((t) => t.ts), memory?.createdAt].filter((x) => !!x).sort();
|
|
45297
|
+
const startedAt = times[0] ?? null;
|
|
45298
|
+
const endedAt = [summary.lastAt, ...timeline.map((t) => t.ts)].filter((x) => !!x).sort().pop() ?? null;
|
|
45299
|
+
return {
|
|
45300
|
+
app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename11(dir),
|
|
45301
|
+
accent,
|
|
45302
|
+
startedAt,
|
|
45303
|
+
endedAt,
|
|
45304
|
+
focusId,
|
|
45305
|
+
frames,
|
|
45306
|
+
finals,
|
|
45307
|
+
postcards,
|
|
45308
|
+
stats: {
|
|
45309
|
+
screens: finals.length,
|
|
45310
|
+
versions: shots.reduce((n, s) => n + s.versions, 0),
|
|
45311
|
+
postcards: entries.length,
|
|
45312
|
+
elapsedMs: startedAt && endedAt ? Date.parse(endedAt) - Date.parse(startedAt) : null
|
|
45313
|
+
},
|
|
45314
|
+
dropped: 0
|
|
45315
|
+
};
|
|
45316
|
+
}
|
|
45317
|
+
function inlineImages(dir, plan, budget = REEL_BUDGET_BYTES) {
|
|
45318
|
+
const verified = (f) => {
|
|
45319
|
+
if (!HISTORY_NAME.test(f)) return null;
|
|
45320
|
+
try {
|
|
45321
|
+
const path2 = join45(dir, HISTORY_DIR, f);
|
|
45322
|
+
const st = lstatSync7(path2);
|
|
45323
|
+
if (!st.isFile() || st.nlink !== 1) return null;
|
|
45324
|
+
const bytes2 = readFileSync52(path2);
|
|
45325
|
+
return createHash24("sha256").update(bytes2).digest("hex") === f.slice(0, 64) && imageExtension(bytes2) === f.slice(65) ? bytes2 : null;
|
|
45326
|
+
} catch {
|
|
45327
|
+
return null;
|
|
45328
|
+
}
|
|
45329
|
+
};
|
|
45330
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
45331
|
+
const sizeOf = (f) => {
|
|
45332
|
+
if (!sizes.has(f)) sizes.set(f, verified(f)?.length ?? null);
|
|
45333
|
+
return sizes.get(f);
|
|
45334
|
+
};
|
|
45335
|
+
const total = (p) => {
|
|
45336
|
+
const blank = /* @__PURE__ */ new Map();
|
|
45337
|
+
let bytes2 = 0;
|
|
45338
|
+
for (const f of cited(p)) {
|
|
45339
|
+
const n = sizeOf(f);
|
|
45340
|
+
if (n === null) continue;
|
|
45341
|
+
blank.set(f, "");
|
|
45342
|
+
bytes2 += `data:${mimeOf(f)};base64,`.length + 4 * Math.ceil(n / 3);
|
|
45343
|
+
}
|
|
45344
|
+
return bytes2 + Buffer.byteLength(renderReel(p, blank));
|
|
45345
|
+
};
|
|
45346
|
+
let current = { ...plan };
|
|
45347
|
+
let dropped = 0;
|
|
45348
|
+
const over = () => total(current) > budget;
|
|
45349
|
+
while (over() && current.frames.length > 2) {
|
|
45350
|
+
const next = thin(current.frames, Math.max(2, Math.floor(current.frames.length * 0.7)));
|
|
45351
|
+
dropped += current.frames.length - next.length;
|
|
45352
|
+
current = { ...current, frames: next };
|
|
45353
|
+
}
|
|
45354
|
+
for (let i = 0; i < current.postcards.length && over(); i++) {
|
|
45355
|
+
if (!current.postcards[i].files.length) continue;
|
|
45356
|
+
dropped += current.postcards[i].files.length;
|
|
45357
|
+
current = { ...current, postcards: current.postcards.map((c, j) => j === i ? { ...c, files: [] } : c) };
|
|
45358
|
+
}
|
|
45359
|
+
const order = current.finals.map((f, j) => ({ f, j })).filter(({ f }) => f.file).sort((a, b) => Number(a.f.id === current.focusId) - Number(b.f.id === current.focusId) || b.j - a.j);
|
|
45360
|
+
for (const { j } of order) {
|
|
45361
|
+
if (!over()) break;
|
|
45362
|
+
dropped++;
|
|
45363
|
+
current = { ...current, finals: current.finals.map((f, k) => k === j ? { ...f, file: null } : f) };
|
|
45364
|
+
}
|
|
45365
|
+
if (over() && current.frames.length > 1) {
|
|
45366
|
+
dropped += current.frames.length - 1;
|
|
45367
|
+
current = { ...current, frames: current.frames.slice(-1) };
|
|
45368
|
+
}
|
|
45369
|
+
const images = /* @__PURE__ */ new Map();
|
|
45370
|
+
for (const f of new Set(cited(current))) {
|
|
45371
|
+
if (sizeOf(f) === null) continue;
|
|
45372
|
+
const bytes2 = verified(f);
|
|
45373
|
+
if (!bytes2 || bytes2.length !== sizeOf(f)) continue;
|
|
45374
|
+
images.set(f, `data:${mimeOf(f)};base64,${bytes2.toString("base64")}`);
|
|
45375
|
+
}
|
|
45376
|
+
return { plan: { ...current, dropped }, images };
|
|
45377
|
+
}
|
|
45378
|
+
function duration(ms) {
|
|
45379
|
+
if (ms === null || !Number.isFinite(ms) || ms < 0) return "\u2014";
|
|
45380
|
+
const m = Math.round(ms / 6e4);
|
|
45381
|
+
return m < 60 ? `${m} min` : `${Math.floor(m / 60)} h ${m % 60} min`;
|
|
45382
|
+
}
|
|
45383
|
+
function utcDay(ts2) {
|
|
45384
|
+
const d = new Date(ts2);
|
|
45385
|
+
return Number.isNaN(d.getTime()) ? "" : `${d.toUTCString().slice(0, 16)} (UTC)`;
|
|
45386
|
+
}
|
|
45387
|
+
function sinceStart(start, ts2) {
|
|
45388
|
+
if (!start) return "";
|
|
45389
|
+
const s = Math.max(0, Math.round((Date.parse(ts2) - Date.parse(start)) / 1e3));
|
|
45390
|
+
const h = Math.floor(s / 3600);
|
|
45391
|
+
const m = Math.floor(s % 3600 / 60);
|
|
45392
|
+
const sec = String(s % 60).padStart(2, "0");
|
|
45393
|
+
return h ? `${h}:${String(m).padStart(2, "0")}:${sec}` : `${m}:${sec}`;
|
|
45394
|
+
}
|
|
45395
|
+
function renderReel(plan, images) {
|
|
45396
|
+
const img = (f, alt, cls = "") => f && images.has(f) ? `<img class="${cls}" src="${images.get(f)}" alt="${escapeHtml(alt)}">` : "";
|
|
45397
|
+
const count = (n) => escapeHtml(String(Number.isSafeInteger(n) && n >= 0 ? n : 0));
|
|
45398
|
+
const accent = ACCENT.test(plan.accent) ? plan.accent : DEFAULT_ACCENT;
|
|
45399
|
+
const clock = (ts2) => sinceStart(plan.startedAt, ts2);
|
|
45400
|
+
const frames = plan.frames.filter((f) => images.has(f.file));
|
|
45401
|
+
const flip = frames.length ? `<section class="flip"><div class="phone">${frames.map((f, i) => `<img class="fr${i === 0 ? " on" : ""}" src="${images.get(f.file)}" alt="${escapeHtml(plan.focusId ?? "")} at ${clock(f.ts)}">`).join("")}</div>
|
|
45402
|
+
<div class="flipcap"><div class="t" id="ft">${frames[0] ? clock(frames[0].ts) : ""}</div><div id="fc">${escapeHtml(frames[0]?.caption ?? "")}</div><div class="bar"><div id="fb"></div></div></div></section>` : `<p class="muted">No screen versions were recorded \u2014 open the build board with <code>himi studio</code> before building to capture them.</p>`;
|
|
45403
|
+
const data = JSON.stringify(frames.map((f) => ({ t: clock(f.ts), c: f.caption ?? "" }))).replace(/</g, "\\u003c");
|
|
45404
|
+
return `<!doctype html>
|
|
45405
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
45406
|
+
<title>${escapeHtml(plan.app)} \xB7 the making of</title>
|
|
45407
|
+
<style>
|
|
45408
|
+
:root{--bg:#f6f5f2;--card:#fff;--ink:#1c1c1a;--muted:#6b6a64;--line:#e6e3dc;--accent:${accent}}
|
|
45409
|
+
@media (prefers-color-scheme:dark){:root{--bg:#121211;--card:#1c1c1a;--ink:#ecebe6;--muted:#a3a19a;--line:#2c2b28}}
|
|
45410
|
+
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
|
|
45411
|
+
.wrap{max-width:980px;margin:0 auto;padding:32px 20px 64px}h1{font-size:30px;margin:0 0 4px}h2{font-size:14px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:40px 0 14px}
|
|
45412
|
+
.muted{color:var(--muted)}.stats{display:flex;gap:28px;flex-wrap:wrap;margin:18px 0 8px}.stats b{display:block;font-size:24px}
|
|
45413
|
+
.flip{display:flex;gap:28px;align-items:center;flex-wrap:wrap}.phone{position:relative;width:280px;aspect-ratio:390/844;border:10px solid #111;border-radius:38px;overflow:hidden;background:#fff;flex:none}
|
|
45414
|
+
.phone img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top;opacity:0;transition:opacity .35s}.phone img.on{opacity:1}
|
|
45415
|
+
.flipcap{flex:1;min-width:220px}.flipcap .t{font-size:40px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent)}.bar{height:4px;background:var(--line);border-radius:2px;margin-top:16px}.bar div{height:4px;background:var(--accent);border-radius:2px;width:0}
|
|
45416
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:18px}.grid figure{margin:0;text-align:center}.grid img{width:100%;aspect-ratio:390/844;object-fit:cover;object-position:top;border:6px solid #111;border-radius:22px;background:#fff}
|
|
45417
|
+
figcaption{font-size:12px;color:var(--muted);margin-top:6px;word-break:break-all}
|
|
45418
|
+
.log{list-style:none;padding:0;margin:0}.log li{display:flex;gap:14px;padding:12px 0;border-top:1px solid var(--line)}.log .t{min-width:52px;color:var(--muted);font-variant-numeric:tabular-nums}.log .s{font-size:12px;color:var(--muted);text-transform:capitalize}
|
|
45419
|
+
.log .imgs{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}.log .imgs img{height:120px;border-radius:10px;border:1px solid var(--line)}
|
|
45420
|
+
footer{margin-top:48px;font-size:12px;color:var(--muted)}
|
|
45421
|
+
</style></head><body><div class="wrap">
|
|
45422
|
+
<h1>${escapeHtml(plan.app)}</h1><div class="muted">The making of \u2014 every version of the app as it was built${plan.startedAt ? `, ${escapeHtml(utcDay(plan.startedAt))}` : ""}</div>
|
|
45423
|
+
<div class="stats"><div><b>${duration(plan.stats.elapsedMs)}</b><span class="muted">from first picture to last</span></div><div><b>${count(plan.stats.screens)}</b><span class="muted">screens</span></div><div><b>${count(plan.stats.versions)}</b><span class="muted">versions rendered</span></div><div><b>${count(plan.stats.postcards)}</b><span class="muted">postcards</span></div></div>
|
|
45424
|
+
<h2>${escapeHtml(plan.focusId ?? "The app")}, version by version</h2>
|
|
45425
|
+
${flip}
|
|
45426
|
+
<h2>Where it ended up</h2>
|
|
45427
|
+
<div class="grid">${plan.finals.map((f) => `<figure>${img(f.file, f.id)}<figcaption>${escapeHtml(f.id)}</figcaption></figure>`).join("")}</div>
|
|
45428
|
+
<h2>Postcards</h2>
|
|
45429
|
+
<ul class="log">${plan.postcards.map((c) => `<li><div class="t">${clock(c.ts)}</div><div><div>${escapeHtml(c.message)}</div>${c.step ? `<div class="s">step ${JOURNEY_STEPS.indexOf(c.step) + 1} \xB7 ${escapeHtml(c.step)}</div>` : ""}${c.files.length ? `<div class="imgs">${c.files.map((f) => img(f, c.message)).join("")}</div>` : ""}</div></li>`).join("") || `<li class="muted">No postcards were journaled.</li>`}</ul>
|
|
45430
|
+
<footer>Built with himi.${plan.dropped ? ` ${count(plan.dropped)} pictures were left out to keep this file small.` : ""}</footer>
|
|
45431
|
+
</div>
|
|
45432
|
+
<script>
|
|
45433
|
+
(function(){var F=${data};var imgs=document.querySelectorAll(".phone img");if(imgs.length<2)return;var i=0;
|
|
45434
|
+
function show(n){imgs[i].classList.remove("on");i=n;imgs[i].classList.add("on");document.getElementById("ft").textContent=F[i].t;document.getElementById("fc").textContent=F[i].c;document.getElementById("fb").style.width=(100*i/(imgs.length-1))+"%"}
|
|
45435
|
+
function tick(){show(i+1<imgs.length?i+1:0);setTimeout(tick,i+1<imgs.length?900:2500)}setTimeout(tick,1200);})();
|
|
45436
|
+
</script>
|
|
45437
|
+
</body></html>
|
|
45438
|
+
`;
|
|
45439
|
+
}
|
|
45440
|
+
function buildReel(dir, budget = REEL_BUDGET_BYTES) {
|
|
45441
|
+
const { plan, images } = inlineImages(dir, planReel(dir), budget);
|
|
45442
|
+
return { html: renderReel(plan, images), plan };
|
|
45443
|
+
}
|
|
45444
|
+
var REEL_BUDGET_BYTES, MAX_FLIP_FRAMES, DEFAULT_ACCENT, ACCENT, HISTORY_NAME, MIME2, mimeOf, readJson4, isObj, str, historyName, cited;
|
|
45445
|
+
var init_studio_reel = __esm({
|
|
45446
|
+
"src/studio-reel.ts"() {
|
|
45447
|
+
init_progress();
|
|
45448
|
+
init_studio();
|
|
45449
|
+
REEL_BUDGET_BYTES = 12 * 1024 * 1024;
|
|
45450
|
+
MAX_FLIP_FRAMES = 40;
|
|
45451
|
+
DEFAULT_ACCENT = "#3b6fd8";
|
|
45452
|
+
ACCENT = /^#[0-9a-f]{3,8}$/i;
|
|
45453
|
+
HISTORY_NAME = /^[0-9a-f]{64}\.(png|jpg|gif|webp)$/;
|
|
45454
|
+
MIME2 = { png: "image/png", jpg: "image/jpeg", gif: "image/gif", webp: "image/webp" };
|
|
45455
|
+
mimeOf = (file) => MIME2[file.slice(65)] ?? "image/png";
|
|
45456
|
+
readJson4 = (file) => {
|
|
45457
|
+
try {
|
|
45458
|
+
return JSON.parse(readFileSync52(file, "utf8"));
|
|
45459
|
+
} catch {
|
|
45460
|
+
return null;
|
|
45461
|
+
}
|
|
45462
|
+
};
|
|
45463
|
+
isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
45464
|
+
str = (v) => typeof v === "string" && v ? v : null;
|
|
45465
|
+
historyName = (sha, ext) => typeof sha === "string" && typeof ext === "string" && HISTORY_NAME.test(`${sha}.${ext}`) ? `${sha}.${ext}` : null;
|
|
45466
|
+
cited = (p) => [
|
|
45467
|
+
...p.frames.map((f) => f.file),
|
|
45468
|
+
...p.finals.flatMap((f) => f.file ? [f.file] : []),
|
|
45469
|
+
...p.postcards.flatMap((c) => c.files)
|
|
45470
|
+
];
|
|
45471
|
+
}
|
|
45472
|
+
});
|
|
45473
|
+
|
|
44925
45474
|
// src/native-decode.ts
|
|
44926
45475
|
var native_decode_exports = {};
|
|
44927
45476
|
__export(native_decode_exports, {
|
|
@@ -44937,9 +45486,9 @@ __export(native_decode_exports, {
|
|
|
44937
45486
|
runNativeDecode: () => runNativeDecode
|
|
44938
45487
|
});
|
|
44939
45488
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
44940
|
-
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as
|
|
45489
|
+
import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync53, rmSync as rmSync10, writeFileSync as writeFileSync20 } from "node:fs";
|
|
44941
45490
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
44942
|
-
import { join as
|
|
45491
|
+
import { join as join46 } from "node:path";
|
|
44943
45492
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
44944
45493
|
function nativeDecodePackageDir() {
|
|
44945
45494
|
return fileURLToPath20(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
|
|
@@ -44949,8 +45498,8 @@ function nativeDecodeAndroidHarnessDir() {
|
|
|
44949
45498
|
}
|
|
44950
45499
|
function nativeOracleShipped() {
|
|
44951
45500
|
return {
|
|
44952
|
-
ios: existsSync48(
|
|
44953
|
-
android: existsSync48(
|
|
45501
|
+
ios: existsSync48(join46(nativeDecodePackageDir(), "Package.swift")),
|
|
45502
|
+
android: existsSync48(join46(nativeDecodeAndroidHarnessDir(), "gradlew"))
|
|
44954
45503
|
};
|
|
44955
45504
|
}
|
|
44956
45505
|
function detectNativeDecode(options = {}) {
|
|
@@ -44961,7 +45510,7 @@ function detectNativeDecode(options = {}) {
|
|
|
44961
45510
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
44962
45511
|
}
|
|
44963
45512
|
if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
|
|
44964
|
-
const packageAvailable = options.packageAvailable ?? existsSync48(
|
|
45513
|
+
const packageAvailable = options.packageAvailable ?? existsSync48(join46(packageDir, "Package.swift"));
|
|
44965
45514
|
if (!packageAvailable) {
|
|
44966
45515
|
return {
|
|
44967
45516
|
platform: "ios",
|
|
@@ -44973,7 +45522,7 @@ function detectNativeDecode(options = {}) {
|
|
|
44973
45522
|
}
|
|
44974
45523
|
function localPropertiesSdk(harnessDir) {
|
|
44975
45524
|
try {
|
|
44976
|
-
const match =
|
|
45525
|
+
const match = readFileSync53(join46(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
|
|
44977
45526
|
return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
|
|
44978
45527
|
} catch {
|
|
44979
45528
|
return null;
|
|
@@ -44981,7 +45530,7 @@ function localPropertiesSdk(harnessDir) {
|
|
|
44981
45530
|
}
|
|
44982
45531
|
function detectAndroidNativeDecode(options = {}) {
|
|
44983
45532
|
const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
|
|
44984
|
-
const gradlew =
|
|
45533
|
+
const gradlew = join46(harnessDir, "gradlew");
|
|
44985
45534
|
const gradlewAvailable = options.gradlewAvailable ?? existsSync48(gradlew);
|
|
44986
45535
|
if (!gradlewAvailable) {
|
|
44987
45536
|
return {
|
|
@@ -45064,14 +45613,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
|
|
|
45064
45613
|
return verdicts;
|
|
45065
45614
|
}
|
|
45066
45615
|
function runNativeDecode(options) {
|
|
45067
|
-
const descriptorDir = mkdtempSync2(
|
|
45616
|
+
const descriptorDir = mkdtempSync2(join46(tmpdir3(), "himi-native-decode-"));
|
|
45068
45617
|
const startedAt = Date.now();
|
|
45069
45618
|
try {
|
|
45070
45619
|
for (const descriptor of options.descriptors) {
|
|
45071
45620
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
45072
45621
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
45073
45622
|
}
|
|
45074
|
-
writeFileSync20(
|
|
45623
|
+
writeFileSync20(join46(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
45075
45624
|
}
|
|
45076
45625
|
options.progress?.("building cached Swift oracle");
|
|
45077
45626
|
execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
|
|
@@ -45083,7 +45632,7 @@ function runNativeDecode(options) {
|
|
|
45083
45632
|
encoding: "utf8"
|
|
45084
45633
|
}).trim();
|
|
45085
45634
|
options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
45086
|
-
const stdout = execFileSync5(
|
|
45635
|
+
const stdout = execFileSync5(join46(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
|
|
45087
45636
|
stdio: ["ignore", "pipe", "pipe"],
|
|
45088
45637
|
encoding: "utf8"
|
|
45089
45638
|
});
|
|
@@ -45101,15 +45650,15 @@ function runNativeDecode(options) {
|
|
|
45101
45650
|
}
|
|
45102
45651
|
}
|
|
45103
45652
|
function runAndroidNativeDecode(options) {
|
|
45104
|
-
const descriptorDir = mkdtempSync2(
|
|
45105
|
-
const outputPath =
|
|
45653
|
+
const descriptorDir = mkdtempSync2(join46(tmpdir3(), "himi-native-decode-android-"));
|
|
45654
|
+
const outputPath = join46(descriptorDir, "verdicts.ndjson");
|
|
45106
45655
|
const startedAt = Date.now();
|
|
45107
45656
|
try {
|
|
45108
45657
|
for (const descriptor of options.descriptors) {
|
|
45109
45658
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
45110
45659
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
45111
45660
|
}
|
|
45112
|
-
writeFileSync20(
|
|
45661
|
+
writeFileSync20(join46(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
45113
45662
|
}
|
|
45114
45663
|
options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
45115
45664
|
execFileSync5(options.gradlew, [
|
|
@@ -45124,7 +45673,7 @@ function runAndroidNativeDecode(options) {
|
|
|
45124
45673
|
stdio: ["ignore", "ignore", "pipe"],
|
|
45125
45674
|
encoding: "utf8"
|
|
45126
45675
|
});
|
|
45127
|
-
const stdout =
|
|
45676
|
+
const stdout = readFileSync53(outputPath, "utf8");
|
|
45128
45677
|
return {
|
|
45129
45678
|
platform: "android",
|
|
45130
45679
|
verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
|
|
@@ -45193,14 +45742,14 @@ __export(browser_authoring_exports, {
|
|
|
45193
45742
|
sdkSubpathReader: () => sdkSubpathReader
|
|
45194
45743
|
});
|
|
45195
45744
|
import { createServer as createServer3 } from "node:http";
|
|
45196
|
-
import { createHash as
|
|
45197
|
-
import { existsSync as existsSync49, readdirSync as readdirSync24, readFileSync as
|
|
45198
|
-
import { join as
|
|
45745
|
+
import { createHash as createHash25, randomBytes as randomBytes4 } from "node:crypto";
|
|
45746
|
+
import { existsSync as existsSync49, readdirSync as readdirSync24, readFileSync as readFileSync54, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
|
|
45747
|
+
import { join as join47, posix, relative as relative8, sep as sep12 } from "node:path";
|
|
45199
45748
|
function humanMs(ms) {
|
|
45200
45749
|
return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
|
|
45201
45750
|
}
|
|
45202
45751
|
function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
45203
|
-
const root =
|
|
45752
|
+
const root = join47(tier5SrcDir, bundleName);
|
|
45204
45753
|
const files = {};
|
|
45205
45754
|
const visitedDirs = /* @__PURE__ */ new Set();
|
|
45206
45755
|
const walk2 = (abs, rel) => {
|
|
@@ -45208,12 +45757,12 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
|
45208
45757
|
if (visitedDirs.has(real)) return;
|
|
45209
45758
|
visitedDirs.add(real);
|
|
45210
45759
|
for (const name of readdirSync24(abs).sort()) {
|
|
45211
|
-
const childAbs =
|
|
45760
|
+
const childAbs = join47(abs, name);
|
|
45212
45761
|
const childRel = posix.join(rel, name);
|
|
45213
45762
|
if (statSync12(childAbs).isDirectory()) {
|
|
45214
45763
|
walk2(childAbs, childRel);
|
|
45215
45764
|
} else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
|
|
45216
|
-
files[childRel] =
|
|
45765
|
+
files[childRel] = readFileSync54(childAbs, "utf8");
|
|
45217
45766
|
}
|
|
45218
45767
|
}
|
|
45219
45768
|
};
|
|
@@ -45234,20 +45783,20 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
45234
45783
|
const spec = m[1];
|
|
45235
45784
|
const virtual = posix.normalize(posix.join(dir, spec));
|
|
45236
45785
|
if (!virtual.startsWith("/tier5-src/")) continue;
|
|
45237
|
-
const onDisk =
|
|
45786
|
+
const onDisk = join47(tier5SrcDir, virtual.slice("/tier5-src/".length));
|
|
45238
45787
|
const candidates = [
|
|
45239
45788
|
onDisk,
|
|
45240
45789
|
`${onDisk}.ts`,
|
|
45241
45790
|
`${onDisk}.js`,
|
|
45242
45791
|
onDisk.replace(/\.js$/, ".ts"),
|
|
45243
|
-
|
|
45244
|
-
|
|
45792
|
+
join47(onDisk, "index.ts"),
|
|
45793
|
+
join47(onDisk, "index.js")
|
|
45245
45794
|
];
|
|
45246
45795
|
for (const abs of candidates) {
|
|
45247
45796
|
if (!existsSync49(abs) || statSync12(abs).isDirectory()) continue;
|
|
45248
45797
|
const key2 = `/tier5-src/${relative8(tier5SrcDir, abs).split(sep12).join(posix.sep)}`;
|
|
45249
45798
|
if (key2 in files) break;
|
|
45250
|
-
files[key2] =
|
|
45799
|
+
files[key2] = readFileSync54(abs, "utf8");
|
|
45251
45800
|
queue.push(key2);
|
|
45252
45801
|
break;
|
|
45253
45802
|
}
|
|
@@ -45282,7 +45831,7 @@ function collectSdkModules(files, resolveSubpath) {
|
|
|
45282
45831
|
function sdkSubpathReader(resolve48) {
|
|
45283
45832
|
return (sub) => {
|
|
45284
45833
|
try {
|
|
45285
|
-
return
|
|
45834
|
+
return readFileSync54(resolve48(`@wix/himalaya/${sub}`), "utf8");
|
|
45286
45835
|
} catch {
|
|
45287
45836
|
return null;
|
|
45288
45837
|
}
|
|
@@ -45292,7 +45841,7 @@ function encodeJob(job) {
|
|
|
45292
45841
|
return Buffer.from(JSON.stringify(job), "utf8").toString("base64");
|
|
45293
45842
|
}
|
|
45294
45843
|
function mintToken2(payload, nonce = randomBytes4(16).toString("hex")) {
|
|
45295
|
-
const digest2 =
|
|
45844
|
+
const digest2 = createHash25("sha256").update(payload, "utf8").digest("base64url");
|
|
45296
45845
|
return `${nonce}.${digest2}`;
|
|
45297
45846
|
}
|
|
45298
45847
|
function defaultOpenBrowser2(url) {
|
|
@@ -45454,8 +46003,8 @@ __export(coverage_exports, {
|
|
|
45454
46003
|
suppressedNativeKeys: () => suppressedNativeKeys,
|
|
45455
46004
|
trendAndStore: () => trendAndStore
|
|
45456
46005
|
});
|
|
45457
|
-
import { existsSync as existsSync50, mkdirSync as mkdirSync24, readFileSync as
|
|
45458
|
-
import { dirname as dirname26, join as
|
|
46006
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync24, readFileSync as readFileSync55, writeFileSync as writeFileSync21 } from "node:fs";
|
|
46007
|
+
import { dirname as dirname26, join as join48 } from "node:path";
|
|
45459
46008
|
function suppressedNativeKeys(oracle) {
|
|
45460
46009
|
return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
|
|
45461
46010
|
}
|
|
@@ -45516,15 +46065,15 @@ function assembleLedger(r, options = {}) {
|
|
|
45516
46065
|
remedy: SOURCEMAP_REMEDY[c.sourcemap]
|
|
45517
46066
|
});
|
|
45518
46067
|
}
|
|
45519
|
-
const
|
|
45520
|
-
if (!
|
|
45521
|
-
const named =
|
|
45522
|
-
const more =
|
|
46068
|
+
const own3 = (c.uncoveredFunctions ?? []).filter((f) => f.source?.startsWith("tier5-src/") || f.source?.startsWith("core/dev-server/tier5-bundles-src/"));
|
|
46069
|
+
if (!own3.length) continue;
|
|
46070
|
+
const named = own3.slice(0, 6).map((f) => `${f.name} (${f.source})`).join(", ");
|
|
46071
|
+
const more = own3.length > 6 ? ` +${own3.length - 6} more` : "";
|
|
45523
46072
|
out.push({
|
|
45524
46073
|
key: `code-uncovered|${c.screen}`,
|
|
45525
46074
|
kind: "code-uncovered",
|
|
45526
46075
|
screen: c.screen,
|
|
45527
|
-
gap: `${
|
|
46076
|
+
gap: `${own3.length} worker function${own3.length === 1 ? "" : "s"} never executed on any axis: ${named}${more}`,
|
|
45528
46077
|
remedy: "usually an error/edge branch \u2014 give the crawl data that reaches it (a net-mocks rule, cms seed rows, or a nav edge with the right input), or verify the path on a preview"
|
|
45529
46078
|
});
|
|
45530
46079
|
}
|
|
@@ -45625,11 +46174,11 @@ function assembleLedger(r, options = {}) {
|
|
|
45625
46174
|
return out;
|
|
45626
46175
|
}
|
|
45627
46176
|
function trendAndStore(dir, entries, suppressed) {
|
|
45628
|
-
const p =
|
|
46177
|
+
const p = join48(dir, LEDGER_FILE);
|
|
45629
46178
|
let previous = null;
|
|
45630
46179
|
try {
|
|
45631
46180
|
if (existsSync50(p)) {
|
|
45632
|
-
const parsed = JSON.parse(
|
|
46181
|
+
const parsed = JSON.parse(readFileSync55(p, "utf8"));
|
|
45633
46182
|
if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k) => typeof k === "string");
|
|
45634
46183
|
}
|
|
45635
46184
|
} catch {
|
|
@@ -45668,11 +46217,11 @@ function formatLedger(entries, trend) {
|
|
|
45668
46217
|
return out.join("\n");
|
|
45669
46218
|
}
|
|
45670
46219
|
function diffAndStoreObservations(dir, current) {
|
|
45671
|
-
const p =
|
|
46220
|
+
const p = join48(dir, OBS_FILE);
|
|
45672
46221
|
let previous = null;
|
|
45673
46222
|
try {
|
|
45674
46223
|
if (existsSync50(p)) {
|
|
45675
|
-
const parsed = JSON.parse(
|
|
46224
|
+
const parsed = JSON.parse(readFileSync55(p, "utf8"));
|
|
45676
46225
|
if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
|
|
45677
46226
|
(v) => Array.isArray(v) && v.every((l) => typeof l === "string")
|
|
45678
46227
|
)) {
|
|
@@ -45721,8 +46270,8 @@ var LEDGER_FILE, OBS_FILE;
|
|
|
45721
46270
|
var init_coverage = __esm({
|
|
45722
46271
|
"src/coverage.ts"() {
|
|
45723
46272
|
init_native_decode();
|
|
45724
|
-
LEDGER_FILE =
|
|
45725
|
-
OBS_FILE =
|
|
46273
|
+
LEDGER_FILE = join48(".himi", "test-ledger.json");
|
|
46274
|
+
OBS_FILE = join48(".himi", "test-observations.json");
|
|
45726
46275
|
}
|
|
45727
46276
|
});
|
|
45728
46277
|
|
|
@@ -45733,8 +46282,8 @@ __export(design_kits_exports, {
|
|
|
45733
46282
|
kitsDir: () => kitsDir,
|
|
45734
46283
|
listKits: () => listKits2
|
|
45735
46284
|
});
|
|
45736
|
-
import { existsSync as existsSync51, readFileSync as
|
|
45737
|
-
import { join as
|
|
46285
|
+
import { existsSync as existsSync51, readFileSync as readFileSync56, readdirSync as readdirSync25 } from "node:fs";
|
|
46286
|
+
import { join as join49, basename as basename12 } from "node:path";
|
|
45738
46287
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
45739
46288
|
function kitsDir() {
|
|
45740
46289
|
return KIT_DIR_CANDIDATES.find((p) => existsSync51(p));
|
|
@@ -45742,7 +46291,7 @@ function kitsDir() {
|
|
|
45742
46291
|
function listKits2() {
|
|
45743
46292
|
const dir = kitsDir();
|
|
45744
46293
|
if (!dir) return [];
|
|
45745
|
-
return readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) =>
|
|
46294
|
+
return readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) => basename12(f, ".json")).sort();
|
|
45746
46295
|
}
|
|
45747
46296
|
function kitReport(name) {
|
|
45748
46297
|
const dir = kitsDir();
|
|
@@ -45761,7 +46310,7 @@ In a published @wix/himalaya-cli this is a packaging bug \u2014 the kits should
|
|
|
45761
46310
|
if (!kits.includes(name)) {
|
|
45762
46311
|
return { ok: false, kit: name, kits, problems: [`no design kit named "${name}". Available: ${kits.join(", ")}`] };
|
|
45763
46312
|
}
|
|
45764
|
-
const raw =
|
|
46313
|
+
const raw = readFileSync56(join49(dir, `${name}.json`), "utf8");
|
|
45765
46314
|
let parsed;
|
|
45766
46315
|
try {
|
|
45767
46316
|
parsed = JSON.parse(raw);
|
|
@@ -45785,9 +46334,9 @@ var init_design_kits = __esm({
|
|
|
45785
46334
|
"src/design-kits.ts"() {
|
|
45786
46335
|
KIT_DIR_CANDIDATES = [
|
|
45787
46336
|
// in-repo: tools/himi-cli/src/design-kits.ts → <repo>/stdlib/design-kits/
|
|
45788
|
-
|
|
46337
|
+
join49(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
|
|
45789
46338
|
// published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/design-kits/
|
|
45790
|
-
|
|
46339
|
+
join49(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
|
|
45791
46340
|
];
|
|
45792
46341
|
}
|
|
45793
46342
|
});
|
|
@@ -45801,11 +46350,11 @@ __export(assets_exports, {
|
|
|
45801
46350
|
removeAssetPayload: () => removeAssetPayload,
|
|
45802
46351
|
verifyReport: () => verifyReport
|
|
45803
46352
|
});
|
|
45804
|
-
import { readFileSync as
|
|
45805
|
-
import { basename as
|
|
46353
|
+
import { readFileSync as readFileSync57 } from "node:fs";
|
|
46354
|
+
import { basename as basename13 } from "node:path";
|
|
45806
46355
|
function declaredAssets(dir) {
|
|
45807
46356
|
return collectAssets(dir).map((a) => {
|
|
45808
|
-
const bytes2 =
|
|
46357
|
+
const bytes2 = readFileSync57(a.path);
|
|
45809
46358
|
return {
|
|
45810
46359
|
name: a.name,
|
|
45811
46360
|
sha256: assetSha256(bytes2),
|
|
@@ -45882,8 +46431,8 @@ function verifyReport(dir, app, manifest) {
|
|
|
45882
46431
|
};
|
|
45883
46432
|
}
|
|
45884
46433
|
function addAssetPayload(manifest, filePath, opts) {
|
|
45885
|
-
const bytes2 =
|
|
45886
|
-
const name = opts.name ??
|
|
46434
|
+
const bytes2 = readFileSync57(filePath);
|
|
46435
|
+
const name = opts.name ?? basename13(filePath);
|
|
45887
46436
|
const sha2565 = assetSha256(bytes2);
|
|
45888
46437
|
const record2 = {
|
|
45889
46438
|
sha256: sha2565,
|
|
@@ -46767,12 +47316,13 @@ ${releaseId}`;
|
|
|
46767
47316
|
const bytes2 = await store.getSource(app, m.sourceHash);
|
|
46768
47317
|
if (!bytes2) return json3(404, { error: "template_source_not_found", app });
|
|
46769
47318
|
const etag = `"${m.sourceHash}"`;
|
|
47319
|
+
const cache = { "cache-control": pin ? PINNED_CACHE_CONTROL : DOC_CACHE_CONTROL, ...pin ? { vary: "x-himalaya-release" } : {} };
|
|
46770
47320
|
if (request.headers.get("if-none-match") === etag) {
|
|
46771
|
-
return new Response(null, { status: 304, headers: { etag,
|
|
47321
|
+
return new Response(null, { status: 304, headers: { etag, ...cache } });
|
|
46772
47322
|
}
|
|
46773
47323
|
return new Response(bytes2, {
|
|
46774
47324
|
status: 200,
|
|
46775
|
-
headers: { "content-type": JSON_CT, etag,
|
|
47325
|
+
headers: { "content-type": JSON_CT, etag, ...cache, "x-himalaya-app": app }
|
|
46776
47326
|
});
|
|
46777
47327
|
}
|
|
46778
47328
|
if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
|
|
@@ -47449,19 +47999,19 @@ var init_preview_assets_generated = __esm({
|
|
|
47449
47999
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
47450
48000
|
init_preview_assets_format();
|
|
47451
48001
|
PREVIEW_ASSET_MANIFEST = [
|
|
47452
|
-
{ key: "assets/index-
|
|
47453
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
47454
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47455
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
47456
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
47457
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47458
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
47459
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
47460
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
47461
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
47462
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
47463
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
47464
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
48002
|
+
{ key: "assets/index-DRerTUYc.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1016478, sha256: "42a5b901a0a58a495e5261f68782d28d12aa95cf64df33d9d8d14236e8ea6ead" },
|
|
48003
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1016486, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
48004
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1107410, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
48005
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1198394, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
48006
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1289374, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
48007
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1380246, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
48008
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1471226, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
48009
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1579862, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
48010
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1688946, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
48011
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1797994, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
48012
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1905694, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
48013
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 1993802, length: 4448, sha256: "98239860f1289aebffdb28d2b9f5ce15fbb95a657bb63d262c650ca21513dde3" },
|
|
48014
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1998250, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
|
|
47465
48015
|
];
|
|
47466
48016
|
}
|
|
47467
48017
|
});
|
|
@@ -47477,9 +48027,9 @@ __export(run_exports, {
|
|
|
47477
48027
|
runPackage: () => runPackage,
|
|
47478
48028
|
withoutProdServe: () => withoutProdServe
|
|
47479
48029
|
});
|
|
47480
|
-
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as
|
|
48030
|
+
import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync58, rmSync as rmSync11, statSync as statSync13 } from "node:fs";
|
|
47481
48031
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
47482
|
-
import { dirname as dirname27, join as
|
|
48032
|
+
import { dirname as dirname27, join as join50 } from "node:path";
|
|
47483
48033
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
47484
48034
|
function makePackageRunHandler(opts) {
|
|
47485
48035
|
return makeRunHandler({
|
|
@@ -47499,7 +48049,7 @@ async function fetchBytes(url) {
|
|
|
47499
48049
|
async function resolvePackage(source, workDir) {
|
|
47500
48050
|
const isUrl2 = /^https?:\/\//i.test(source);
|
|
47501
48051
|
if (!isUrl2 && existsSync52(source) && statSync13(source).isDirectory()) {
|
|
47502
|
-
const appDirManifest =
|
|
48052
|
+
const appDirManifest = join50(source, "release-manifest.json");
|
|
47503
48053
|
if (existsSync52(appDirManifest)) {
|
|
47504
48054
|
const opened2 = openPackageDir(source);
|
|
47505
48055
|
if (!opened2.validation.ok) {
|
|
@@ -47509,9 +48059,9 @@ async function resolvePackage(source, workDir) {
|
|
|
47509
48059
|
const app2 = opened2.header?.app ?? opened2.manifest?.app;
|
|
47510
48060
|
if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
|
|
47511
48061
|
if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
|
|
47512
|
-
const root2 = workDir ?? mkdtempSync3(
|
|
47513
|
-
const target =
|
|
47514
|
-
if (
|
|
48062
|
+
const root2 = workDir ?? mkdtempSync3(join50(tmpdir4(), "himi-run-"));
|
|
48063
|
+
const target = join50(root2, app2);
|
|
48064
|
+
if (join50(source) !== target) {
|
|
47515
48065
|
mkdirSync25(root2, { recursive: true });
|
|
47516
48066
|
rmSync11(target, { recursive: true, force: true });
|
|
47517
48067
|
cpSync2(source, target, { recursive: true });
|
|
@@ -47528,8 +48078,8 @@ async function resolvePackage(source, workDir) {
|
|
|
47528
48078
|
}
|
|
47529
48079
|
throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
|
|
47530
48080
|
}
|
|
47531
|
-
const bytes2 = isUrl2 ? await fetchBytes(source) :
|
|
47532
|
-
const root = workDir ?? mkdtempSync3(
|
|
48081
|
+
const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync58(source);
|
|
48082
|
+
const root = workDir ?? mkdtempSync3(join50(tmpdir4(), "himi-run-"));
|
|
47533
48083
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
47534
48084
|
const opened = openPackageDir(appDir2);
|
|
47535
48085
|
if (!opened.validation.ok) {
|
|
@@ -47552,14 +48102,14 @@ async function loadPreviewAssets() {
|
|
|
47552
48102
|
const mod = await Promise.resolve().then(() => (init_preview_assets_generated(), preview_assets_generated_exports));
|
|
47553
48103
|
const here = dirname27(fileURLToPath22(import.meta.url));
|
|
47554
48104
|
const candidates = [
|
|
47555
|
-
|
|
48105
|
+
join50(here, "preview-assets.generated.bin"),
|
|
47556
48106
|
// published: copied next to the bundled CLI
|
|
47557
|
-
|
|
48107
|
+
join50(here, "../../../packages/serve/src/preview-assets.generated.bin")
|
|
47558
48108
|
// in-repo checkout
|
|
47559
48109
|
];
|
|
47560
48110
|
for (const path2 of candidates) {
|
|
47561
48111
|
if (!existsSync52(path2)) continue;
|
|
47562
|
-
const blob =
|
|
48112
|
+
const blob = readFileSync58(path2);
|
|
47563
48113
|
return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
47564
48114
|
}
|
|
47565
48115
|
return /* @__PURE__ */ new Map();
|
|
@@ -47654,9 +48204,9 @@ __export(run_watch_exports, {
|
|
|
47654
48204
|
watchedContentDir: () => watchedContentDir,
|
|
47655
48205
|
writeRunRecord: () => writeRunRecord
|
|
47656
48206
|
});
|
|
47657
|
-
import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as
|
|
48207
|
+
import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync8, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync59, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as rmSync12, writeFileSync as writeFileSync22, watch as fsWatch } from "node:fs";
|
|
47658
48208
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
47659
|
-
import { extname as extname4, join as
|
|
48209
|
+
import { extname as extname4, join as join51, resolve as resolve42, sep as sep13 } from "node:path";
|
|
47660
48210
|
function diffReleases(prev, next) {
|
|
47661
48211
|
const bundles = Object.keys(next.bundles).filter((b) => prev.bundles[b]?.sha256 !== next.bundles[b].sha256).sort();
|
|
47662
48212
|
const changedBundles = new Set(bundles);
|
|
@@ -47696,7 +48246,7 @@ function watchContent(dir, onChange, opts = {}) {
|
|
|
47696
48246
|
let timer = null;
|
|
47697
48247
|
const pending = /* @__PURE__ */ new Set();
|
|
47698
48248
|
const watcher = watch2(dir, { recursive: true }, (_event, file) => {
|
|
47699
|
-
if (!file || ignoredChange(file, (rel) => isDir(
|
|
48249
|
+
if (!file || ignoredChange(file, (rel) => isDir(join51(dir, rel)))) return;
|
|
47700
48250
|
pending.add(file);
|
|
47701
48251
|
if (timer) clearTimeout(timer);
|
|
47702
48252
|
timer = setTimeout(() => {
|
|
@@ -47717,7 +48267,7 @@ function watchedContentDir(source) {
|
|
|
47717
48267
|
if (!source || /^https?:\/\//i.test(source)) return null;
|
|
47718
48268
|
const dir = resolve42(source);
|
|
47719
48269
|
try {
|
|
47720
|
-
return statSync14(dir).isDirectory() && existsSync53(
|
|
48270
|
+
return statSync14(dir).isDirectory() && existsSync53(join51(dir, "himalaya.content.json")) ? dir : null;
|
|
47721
48271
|
} catch {
|
|
47722
48272
|
return null;
|
|
47723
48273
|
}
|
|
@@ -47774,45 +48324,54 @@ function serialize(task) {
|
|
|
47774
48324
|
});
|
|
47775
48325
|
}
|
|
47776
48326
|
function himiDir(dir) {
|
|
47777
|
-
const root =
|
|
48327
|
+
const root = join51(dir, ".himi");
|
|
47778
48328
|
try {
|
|
47779
|
-
return
|
|
48329
|
+
return lstatSync8(root).isDirectory() ? root : null;
|
|
47780
48330
|
} catch (e) {
|
|
47781
48331
|
if (e.code !== "ENOENT") return null;
|
|
47782
48332
|
mkdirSync26(root, { recursive: true });
|
|
47783
|
-
return
|
|
48333
|
+
return lstatSync8(root).isDirectory() ? root : null;
|
|
47784
48334
|
}
|
|
47785
48335
|
}
|
|
47786
48336
|
function writeRunRecord(dir, record2) {
|
|
47787
48337
|
const root = himiDir(dir);
|
|
47788
48338
|
if (!root) return false;
|
|
47789
|
-
const tmp =
|
|
48339
|
+
const tmp = join51(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
|
|
47790
48340
|
try {
|
|
47791
48341
|
writeFileSync22(tmp, `${JSON.stringify(record2, null, 2)}
|
|
47792
48342
|
`, { flag: "wx" });
|
|
47793
|
-
renameSync5(tmp,
|
|
48343
|
+
renameSync5(tmp, join51(root, "run.json"));
|
|
47794
48344
|
} catch (e) {
|
|
47795
48345
|
rmSync12(tmp, { force: true });
|
|
47796
48346
|
throw e;
|
|
47797
48347
|
}
|
|
47798
48348
|
return true;
|
|
47799
48349
|
}
|
|
47800
|
-
function removeRunRecord(dir) {
|
|
47801
|
-
const root =
|
|
48350
|
+
function removeRunRecord(dir, owner) {
|
|
48351
|
+
const root = join51(dir, ".himi");
|
|
47802
48352
|
try {
|
|
47803
|
-
if (!
|
|
48353
|
+
if (!lstatSync8(root).isDirectory()) return;
|
|
47804
48354
|
} catch {
|
|
47805
48355
|
return;
|
|
47806
48356
|
}
|
|
47807
|
-
|
|
48357
|
+
if (owner !== void 0) {
|
|
48358
|
+
const bytes2 = readConfined(root, "run.json");
|
|
48359
|
+
let pid;
|
|
48360
|
+
try {
|
|
48361
|
+
pid = bytes2 ? JSON.parse(bytes2.toString("utf8")).pid : void 0;
|
|
48362
|
+
} catch {
|
|
48363
|
+
}
|
|
48364
|
+
if (typeof pid === "number" && pid !== owner) return;
|
|
48365
|
+
}
|
|
48366
|
+
rmSync12(join51(root, "run.json"), { force: true });
|
|
47808
48367
|
}
|
|
47809
48368
|
function boardFile(dir, pathname) {
|
|
47810
48369
|
let rel = null;
|
|
47811
|
-
if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel =
|
|
47812
|
-
else if (pathname === "/__himi/studio/state.js") rel =
|
|
48370
|
+
if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join51("studio", "index.html");
|
|
48371
|
+
else if (pathname === "/__himi/studio/state.js") rel = join51("studio", "state.js");
|
|
47813
48372
|
else {
|
|
47814
48373
|
const m = /^\/__himi\/history\/([0-9a-f]{64}\.(png|jpg|gif|webp))$/.exec(pathname);
|
|
47815
|
-
if (m) rel =
|
|
48374
|
+
if (m) rel = join51("history", m[1]);
|
|
47816
48375
|
}
|
|
47817
48376
|
if (!rel) return null;
|
|
47818
48377
|
const bytes2 = readConfined(resolve42(dir, ".himi"), rel);
|
|
@@ -47824,12 +48383,12 @@ function boardFile(dir, pathname) {
|
|
|
47824
48383
|
}
|
|
47825
48384
|
function readConfined(root, rel) {
|
|
47826
48385
|
try {
|
|
47827
|
-
if (!
|
|
48386
|
+
if (!lstatSync8(root).isDirectory()) return null;
|
|
47828
48387
|
const parts = rel.split(sep13);
|
|
47829
48388
|
let at = root;
|
|
47830
48389
|
for (let i = 0; i < parts.length; i++) {
|
|
47831
|
-
at =
|
|
47832
|
-
const st =
|
|
48390
|
+
at = join51(at, parts[i]);
|
|
48391
|
+
const st = lstatSync8(at);
|
|
47833
48392
|
if (st.isSymbolicLink() || !(i === parts.length - 1 ? st.isFile() : st.isDirectory())) return null;
|
|
47834
48393
|
}
|
|
47835
48394
|
const canonicalRoot = realpathSync6(root);
|
|
@@ -47837,7 +48396,7 @@ function readConfined(root, rel) {
|
|
|
47837
48396
|
const fd = openSync2(at, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
47838
48397
|
try {
|
|
47839
48398
|
if (!fstatSync(fd).isFile()) return null;
|
|
47840
|
-
return
|
|
48399
|
+
return readFileSync59(fd);
|
|
47841
48400
|
} finally {
|
|
47842
48401
|
closeSync2(fd);
|
|
47843
48402
|
}
|
|
@@ -47888,7 +48447,7 @@ __export(run_browser_exports, {
|
|
|
47888
48447
|
runInBrowser: () => runInBrowser
|
|
47889
48448
|
});
|
|
47890
48449
|
import { createServer as createServer5 } from "node:http";
|
|
47891
|
-
import { existsSync as existsSync54, readFileSync as
|
|
48450
|
+
import { existsSync as existsSync54, readFileSync as readFileSync60 } from "node:fs";
|
|
47892
48451
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
47893
48452
|
import { dirname as dirname28, resolve as resolve43 } from "node:path";
|
|
47894
48453
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
@@ -47930,7 +48489,7 @@ async function releasePayloadFromDir(root, app, header) {
|
|
|
47930
48489
|
await addDoc(meta.descriptorHash);
|
|
47931
48490
|
}
|
|
47932
48491
|
for (const hash of Object.values(manifest.catalogs ?? {})) await addDoc(hash);
|
|
47933
|
-
for (const d of manifest.authoringDocs ??
|
|
48492
|
+
for (const d of Object.values(manifest.authoringDocs ?? {})) await addDoc(d?.sha256);
|
|
47934
48493
|
await addDoc(manifest.tokensHash);
|
|
47935
48494
|
await addDoc(manifest.appConfigHash);
|
|
47936
48495
|
await addDoc(manifest.sourceHash);
|
|
@@ -47996,7 +48555,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
47996
48555
|
}
|
|
47997
48556
|
let bytes2;
|
|
47998
48557
|
try {
|
|
47999
|
-
bytes2 =
|
|
48558
|
+
bytes2 = readFileSync60(resolve43(stagedDir(), name));
|
|
48000
48559
|
} catch (e) {
|
|
48001
48560
|
res.writeHead(503, { "content-type": "application/json" });
|
|
48002
48561
|
res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
|
|
@@ -48109,13 +48668,13 @@ async function runWixMobileRelease(pos, flags, io, deps) {
|
|
|
48109
48668
|
};
|
|
48110
48669
|
if (invokedAs !== "testflight" && !(invokedAs === "store" && pos[1] === "upload")) return fail2("Wix Mobile Release only supports `himi testflight <app>` or `himi store upload <app>`");
|
|
48111
48670
|
if (app !== "himi-player") return fail2("Wix Mobile Release is reserved for the Wix-owned Himi Player binary", { app });
|
|
48112
|
-
if (
|
|
48671
|
+
if (str2(flags.artifact)) return fail2("--artifact is not accepted for Himi Player; pass --release so deployed serve can validate the Job Service IPA and call MRE with its service identity");
|
|
48113
48672
|
if (on(flags["no-wait"])) return fail2("--no-wait is not supported for Himi Player TestFlight releases; wait for MRE processing to complete");
|
|
48114
|
-
const release =
|
|
48115
|
-
const version2 =
|
|
48673
|
+
const release = str2(flags.release);
|
|
48674
|
+
const version2 = str2(flags.version);
|
|
48116
48675
|
if (!release) return fail2("--release is required for a Himi Player TestFlight release");
|
|
48117
48676
|
if (!version2 || !/^\d+(?:\.\d+){0,2}$/.test(version2)) return fail2("--version needs the Player marketing version (for example 1.0.0)");
|
|
48118
|
-
if (
|
|
48677
|
+
if (str2(flags.track) && str2(flags.track) !== "testflight" && str2(flags.track) !== "internal") return fail2("Wix Mobile Release only supports TestFlight upload; public App Store release remains a separate human step");
|
|
48119
48678
|
const plan = {
|
|
48120
48679
|
ok: true,
|
|
48121
48680
|
dryRun: on(flags["dry-run"]),
|
|
@@ -48148,10 +48707,10 @@ async function runWixMobileRelease(pos, flags, io, deps) {
|
|
|
48148
48707
|
return fail2(`could not complete the Himi Player TestFlight Job Service release: ${error.message}`);
|
|
48149
48708
|
}
|
|
48150
48709
|
}
|
|
48151
|
-
var
|
|
48710
|
+
var str2, on;
|
|
48152
48711
|
var init_wix_mobile_release = __esm({
|
|
48153
48712
|
"src/wix-mobile-release.ts"() {
|
|
48154
|
-
|
|
48713
|
+
str2 = (value) => typeof value === "string" ? value : void 0;
|
|
48155
48714
|
on = (value) => value === true || value === "true";
|
|
48156
48715
|
}
|
|
48157
48716
|
});
|
|
@@ -48231,7 +48790,7 @@ async function runStore(pos, flags, io, deps) {
|
|
|
48231
48790
|
if (sub === "status") {
|
|
48232
48791
|
let creds2;
|
|
48233
48792
|
try {
|
|
48234
|
-
creds2 = deps.resolveCredentials({ app, cfg, profileFlag:
|
|
48793
|
+
creds2 = deps.resolveCredentials({ app, cfg, profileFlag: str3(flags.profile) });
|
|
48235
48794
|
} catch (e) {
|
|
48236
48795
|
return fail2(e.message);
|
|
48237
48796
|
}
|
|
@@ -48251,7 +48810,7 @@ async function runStore(pos, flags, io, deps) {
|
|
|
48251
48810
|
}
|
|
48252
48811
|
let findings;
|
|
48253
48812
|
try {
|
|
48254
|
-
findings = await deps.preflightApp(app, { profileFlag:
|
|
48813
|
+
findings = await deps.preflightApp(app, { profileFlag: str3(flags.profile) });
|
|
48255
48814
|
} catch (e) {
|
|
48256
48815
|
return fail2(e.message);
|
|
48257
48816
|
}
|
|
@@ -48266,7 +48825,7 @@ async function runStore(pos, flags, io, deps) {
|
|
|
48266
48825
|
}
|
|
48267
48826
|
return errors.length === 0 ? 0 : 1;
|
|
48268
48827
|
}
|
|
48269
|
-
const explicitTrack =
|
|
48828
|
+
const explicitTrack = str3(flags.track);
|
|
48270
48829
|
const configTrack = cfg.review?.defaultTrackIos;
|
|
48271
48830
|
const track = explicitTrack ?? (invokedAs === "testflight" ? "testflight" : configTrack ?? "testflight");
|
|
48272
48831
|
if (track === "appstore") {
|
|
@@ -48281,7 +48840,7 @@ async function runStore(pos, flags, io, deps) {
|
|
|
48281
48840
|
let creds;
|
|
48282
48841
|
let version2;
|
|
48283
48842
|
try {
|
|
48284
|
-
creds = deps.resolveCredentials({ app, cfg, profileFlag:
|
|
48843
|
+
creds = deps.resolveCredentials({ app, cfg, profileFlag: str3(flags.profile) });
|
|
48285
48844
|
version2 = deps.readVersion(app);
|
|
48286
48845
|
} catch (e) {
|
|
48287
48846
|
return fail2(e.message);
|
|
@@ -48434,10 +48993,10 @@ function credsToEnv(c) {
|
|
|
48434
48993
|
HIMALAYA_APPLE_TEAM_ID: c.team
|
|
48435
48994
|
};
|
|
48436
48995
|
}
|
|
48437
|
-
var
|
|
48996
|
+
var str3, on2, UPLOAD_STEPS, BUILD_STEPS, TRACKS, PROCESSING_POLL_MS, PROCESSING_TIMEOUT_MS;
|
|
48438
48997
|
var init_store3 = __esm({
|
|
48439
48998
|
"src/store.ts"() {
|
|
48440
|
-
|
|
48999
|
+
str3 = (v) => typeof v === "string" ? v : void 0;
|
|
48441
49000
|
on2 = (v) => v === true || v === "true";
|
|
48442
49001
|
UPLOAD_STEPS = ["signing", "build", "validate", "upload"];
|
|
48443
49002
|
BUILD_STEPS = /* @__PURE__ */ new Set(["signing", "build"]);
|
|
@@ -48456,7 +49015,7 @@ __export(preflight_exports, {
|
|
|
48456
49015
|
parseStoreConfig: () => parseStoreConfig,
|
|
48457
49016
|
requireEnv: () => requireEnv
|
|
48458
49017
|
});
|
|
48459
|
-
import { existsSync as existsSync55, readFileSync as
|
|
49018
|
+
import { existsSync as existsSync55, readFileSync as readFileSync61 } from "node:fs";
|
|
48460
49019
|
import { isAbsolute as isAbsolute3, relative as relative9, resolve as resolve44 } from "node:path";
|
|
48461
49020
|
function isInsideRepo(p) {
|
|
48462
49021
|
const rel = relative9(REPO_ROOT3, resolve44(p));
|
|
@@ -48516,7 +49075,7 @@ function loadStoreConfig(app) {
|
|
|
48516
49075
|
if (!existsSync55(p)) {
|
|
48517
49076
|
throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
48518
49077
|
}
|
|
48519
|
-
return parseStoreConfig(
|
|
49078
|
+
return parseStoreConfig(readFileSync61(p, "utf8"));
|
|
48520
49079
|
}
|
|
48521
49080
|
var init_preflight = __esm({
|
|
48522
49081
|
"../store-release/preflight.ts"() {
|
|
@@ -48535,19 +49094,19 @@ __export(credential_profile_exports, {
|
|
|
48535
49094
|
profilePath: () => profilePath,
|
|
48536
49095
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
48537
49096
|
});
|
|
48538
|
-
import { existsSync as existsSync56, readFileSync as
|
|
49097
|
+
import { existsSync as existsSync56, readFileSync as readFileSync62 } from "node:fs";
|
|
48539
49098
|
import { homedir as homedir5 } from "node:os";
|
|
48540
|
-
import { join as
|
|
49099
|
+
import { join as join52 } from "node:path";
|
|
48541
49100
|
function credentialsDir(home = homedir5()) {
|
|
48542
|
-
return
|
|
49101
|
+
return join52(home, ".himalaya", "store-credentials");
|
|
48543
49102
|
}
|
|
48544
49103
|
function profilePath(name, home = homedir5()) {
|
|
48545
49104
|
if (!PROFILE_NAME.test(name)) {
|
|
48546
49105
|
throw new Error(
|
|
48547
|
-
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${
|
|
49106
|
+
`credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join52(credentialsDir(home), "<name>.json")}; it is never a path.`
|
|
48548
49107
|
);
|
|
48549
49108
|
}
|
|
48550
|
-
return
|
|
49109
|
+
return join52(credentialsDir(home), `${name}.json`);
|
|
48551
49110
|
}
|
|
48552
49111
|
function parseProfile(text5, label2) {
|
|
48553
49112
|
let doc;
|
|
@@ -48578,7 +49137,7 @@ function resolveStoreCredentials(opts) {
|
|
|
48578
49137
|
const { app, cfg } = opts;
|
|
48579
49138
|
const env = opts.env ?? process.env;
|
|
48580
49139
|
const home = opts.home ?? homedir5();
|
|
48581
|
-
const read = opts.readProfile ?? ((p) =>
|
|
49140
|
+
const read = opts.readProfile ?? ((p) => readFileSync62(p, "utf8"));
|
|
48582
49141
|
const exists = opts.profileExists ?? existsSync56;
|
|
48583
49142
|
const ios = cfg.ios ?? {};
|
|
48584
49143
|
const flagName = opts.profileFlag?.trim();
|
|
@@ -48659,9 +49218,9 @@ __export(preflight_app_exports, {
|
|
|
48659
49218
|
preflightApp: () => preflightApp,
|
|
48660
49219
|
profileAccount: () => profileAccount
|
|
48661
49220
|
});
|
|
48662
|
-
import { readFileSync as
|
|
48663
|
-
import { createHash as
|
|
48664
|
-
import { join as
|
|
49221
|
+
import { readFileSync as readFileSync63, existsSync as existsSync57, readdirSync as readdirSync26, statSync as statSync15 } from "node:fs";
|
|
49222
|
+
import { createHash as createHash26 } from "node:crypto";
|
|
49223
|
+
import { join as join53 } from "node:path";
|
|
48665
49224
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
48666
49225
|
const f = [];
|
|
48667
49226
|
const has = (re, s) => re.test(s);
|
|
@@ -48725,13 +49284,13 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
48725
49284
|
}
|
|
48726
49285
|
}
|
|
48727
49286
|
async function preflightApp(app, opts = {}) {
|
|
48728
|
-
const projectYml = existsSync57(iosProjectYml(app)) ?
|
|
48729
|
-
const storeConfig = existsSync57(storeConfigPath(app)) ?
|
|
49287
|
+
const projectYml = existsSync57(iosProjectYml(app)) ? readFileSync63(iosProjectYml(app), "utf8") : "";
|
|
49288
|
+
const storeConfig = existsSync57(storeConfigPath(app)) ? readFileSync63(storeConfigPath(app), "utf8") : "";
|
|
48730
49289
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
48731
49290
|
const findings = analyze(
|
|
48732
49291
|
projectYml,
|
|
48733
49292
|
storeConfig,
|
|
48734
|
-
await appIconState(
|
|
49293
|
+
await appIconState(join53(appDir(app), "ios")),
|
|
48735
49294
|
profileAccount(app, storeConfig, opts)
|
|
48736
49295
|
);
|
|
48737
49296
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
@@ -48760,16 +49319,16 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
48760
49319
|
return f;
|
|
48761
49320
|
}
|
|
48762
49321
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
48763
|
-
const root =
|
|
49322
|
+
const root = join53(storeDir(app), "metadata");
|
|
48764
49323
|
const out = /* @__PURE__ */ new Set();
|
|
48765
49324
|
if (existsSync57(root)) {
|
|
48766
49325
|
for (const n of readdirSync26(root)) if (n.endsWith(".txt")) out.add(n);
|
|
48767
49326
|
}
|
|
48768
|
-
if (existsSync57(
|
|
49327
|
+
if (existsSync57(join53(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
48769
49328
|
return out;
|
|
48770
49329
|
}
|
|
48771
49330
|
function reviewInfoFiles(app) {
|
|
48772
|
-
const dir =
|
|
49331
|
+
const dir = join53(storeDir(app), "review_information");
|
|
48773
49332
|
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48774
49333
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48775
49334
|
}
|
|
@@ -48880,12 +49439,12 @@ function analyzePlayListing(assets) {
|
|
|
48880
49439
|
return f;
|
|
48881
49440
|
}
|
|
48882
49441
|
function playListingAssets(app, locale = "en-US") {
|
|
48883
|
-
const dir =
|
|
49442
|
+
const dir = join53(storeDir(app), "play", locale, "images");
|
|
48884
49443
|
const read = (names) => {
|
|
48885
49444
|
for (const name of names) {
|
|
48886
|
-
const p =
|
|
49445
|
+
const p = join53(dir, name);
|
|
48887
49446
|
try {
|
|
48888
|
-
if (statSync15(p).isFile()) return { name, bytes:
|
|
49447
|
+
if (statSync15(p).isFile()) return { name, bytes: readFileSync63(p) };
|
|
48889
49448
|
} catch {
|
|
48890
49449
|
}
|
|
48891
49450
|
}
|
|
@@ -48916,26 +49475,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
48916
49475
|
return f;
|
|
48917
49476
|
}
|
|
48918
49477
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
48919
|
-
const dir =
|
|
49478
|
+
const dir = join53(storeDir(app), "metadata", locale);
|
|
48920
49479
|
if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
|
|
48921
49480
|
return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
|
|
48922
49481
|
}
|
|
48923
49482
|
function listScreenshots(app, locale = "en-US") {
|
|
48924
49483
|
const out = [];
|
|
48925
|
-
const flat =
|
|
49484
|
+
const flat = join53(storeDir(app), "screenshots", locale);
|
|
48926
49485
|
if (existsSync57(flat)) {
|
|
48927
49486
|
for (const png of readdirSync26(flat).filter((n) => n.endsWith(".png"))) {
|
|
48928
|
-
const sz = pngSize(
|
|
49487
|
+
const sz = pngSize(readFileSync63(join53(flat, png)));
|
|
48929
49488
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
48930
49489
|
}
|
|
48931
49490
|
}
|
|
48932
|
-
const legacy =
|
|
49491
|
+
const legacy = join53(storeDir(app), "metadata", locale, "screenshots");
|
|
48933
49492
|
if (existsSync57(legacy)) {
|
|
48934
49493
|
for (const deviceDir of readdirSync26(legacy)) {
|
|
48935
|
-
const d =
|
|
49494
|
+
const d = join53(legacy, deviceDir);
|
|
48936
49495
|
if (!statSync15(d).isDirectory()) continue;
|
|
48937
49496
|
for (const png of readdirSync26(d).filter((n) => n.endsWith(".png"))) {
|
|
48938
|
-
const sz = pngSize(
|
|
49497
|
+
const sz = pngSize(readFileSync63(join53(d, png)));
|
|
48939
49498
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
48940
49499
|
}
|
|
48941
49500
|
}
|
|
@@ -48943,13 +49502,13 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
48943
49502
|
return out;
|
|
48944
49503
|
}
|
|
48945
49504
|
function placeholderHashes2() {
|
|
48946
|
-
const templateIos =
|
|
49505
|
+
const templateIos = join53(appDir("_template"), "ios");
|
|
48947
49506
|
if (!existsSync57(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
48948
49507
|
for (const target of readdirSync26(templateIos)) {
|
|
48949
|
-
const p =
|
|
49508
|
+
const p = join53(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48950
49509
|
try {
|
|
48951
49510
|
if (!statSync15(p).isFile()) continue;
|
|
48952
|
-
return [LEGACY_PLACEHOLDER_SHA2562,
|
|
49511
|
+
return [LEGACY_PLACEHOLDER_SHA2562, createHash26("sha256").update(readFileSync63(p)).digest("hex")];
|
|
48953
49512
|
} catch {
|
|
48954
49513
|
}
|
|
48955
49514
|
}
|
|
@@ -48982,11 +49541,11 @@ async function pixelIssues(bytes2) {
|
|
|
48982
49541
|
async function appIconState(iosDir) {
|
|
48983
49542
|
if (!existsSync57(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
48984
49543
|
for (const target of readdirSync26(iosDir)) {
|
|
48985
|
-
const p =
|
|
49544
|
+
const p = join53(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
48986
49545
|
try {
|
|
48987
49546
|
if (!statSync15(p).isFile()) continue;
|
|
48988
|
-
const bytes2 =
|
|
48989
|
-
const hash =
|
|
49547
|
+
const bytes2 = readFileSync63(p);
|
|
49548
|
+
const hash = createHash26("sha256").update(bytes2).digest("hex");
|
|
48990
49549
|
const pixels = await pixelIssues(bytes2);
|
|
48991
49550
|
return {
|
|
48992
49551
|
exists: true,
|
|
@@ -49057,7 +49616,7 @@ __export(version_exports, {
|
|
|
49057
49616
|
setAndroidVersion: () => setAndroidVersion,
|
|
49058
49617
|
setIosVersion: () => setIosVersion
|
|
49059
49618
|
});
|
|
49060
|
-
import { readFileSync as
|
|
49619
|
+
import { readFileSync as readFileSync64, writeFileSync as writeFileSync23 } from "node:fs";
|
|
49061
49620
|
function readIosVersion(projectYml) {
|
|
49062
49621
|
const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
|
|
49063
49622
|
const build2 = matchScalar(projectYml, "CFBundleVersion");
|
|
@@ -49115,8 +49674,8 @@ function setAndroidVersion(gradle, v) {
|
|
|
49115
49674
|
function bumpVersion(app, opts) {
|
|
49116
49675
|
const iosPath = iosProjectYml(app);
|
|
49117
49676
|
const gradlePath = androidGradle(app);
|
|
49118
|
-
const iosYml =
|
|
49119
|
-
const gradle =
|
|
49677
|
+
const iosYml = readFileSync64(iosPath, "utf8");
|
|
49678
|
+
const gradle = readFileSync64(gradlePath, "utf8");
|
|
49120
49679
|
const current = readIosVersion(iosYml);
|
|
49121
49680
|
const next = {
|
|
49122
49681
|
marketing: opts.marketing ?? current.marketing,
|
|
@@ -49133,7 +49692,7 @@ var init_version = __esm({
|
|
|
49133
49692
|
});
|
|
49134
49693
|
|
|
49135
49694
|
// ../store-release/register-bundle.ts
|
|
49136
|
-
import { readFileSync as
|
|
49695
|
+
import { readFileSync as readFileSync65 } from "node:fs";
|
|
49137
49696
|
import { createPrivateKey as createPrivateKey2, sign } from "node:crypto";
|
|
49138
49697
|
function b64url2(b) {
|
|
49139
49698
|
return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -49151,7 +49710,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
|
|
|
49151
49710
|
async function registerBundleId(opts) {
|
|
49152
49711
|
const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
49153
49712
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
49154
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
49713
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync65(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
49155
49714
|
const res = await fetch(`${ASC_API}/v1/bundleIds`, {
|
|
49156
49715
|
method: "POST",
|
|
49157
49716
|
headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
|
|
@@ -49205,7 +49764,7 @@ __export(asc_status_exports, {
|
|
|
49205
49764
|
ascStatus: () => ascStatus,
|
|
49206
49765
|
buildVerdict: () => buildVerdict
|
|
49207
49766
|
});
|
|
49208
|
-
import { readFileSync as
|
|
49767
|
+
import { readFileSync as readFileSync66 } from "node:fs";
|
|
49209
49768
|
function buildVerdict(builds) {
|
|
49210
49769
|
if (!builds.length) {
|
|
49211
49770
|
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).";
|
|
@@ -49219,7 +49778,7 @@ function buildVerdict(builds) {
|
|
|
49219
49778
|
function client(creds) {
|
|
49220
49779
|
const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
|
|
49221
49780
|
assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
|
|
49222
|
-
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID,
|
|
49781
|
+
const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync66(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
|
|
49223
49782
|
return async (path2) => {
|
|
49224
49783
|
const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
|
|
49225
49784
|
return { status: r.status, json: await r.json().catch(() => ({})) };
|
|
@@ -49379,7 +49938,7 @@ __export(secrets_exports, {
|
|
|
49379
49938
|
runRemoteSecretsCommand: () => runRemoteSecretsCommand,
|
|
49380
49939
|
runSecretsCommand: () => runSecretsCommand
|
|
49381
49940
|
});
|
|
49382
|
-
import { readFileSync as
|
|
49941
|
+
import { readFileSync as readFileSync67 } from "node:fs";
|
|
49383
49942
|
function environment(value) {
|
|
49384
49943
|
if (value === "preview" || value === "production") return value;
|
|
49385
49944
|
throw new Error("--environment must be preview or production");
|
|
@@ -49410,7 +49969,7 @@ async function runSecretsCommand(operation, flags, io, options = {}) {
|
|
|
49410
49969
|
io.log(JSON.stringify(await vault.list({ app, environment: env })));
|
|
49411
49970
|
return 0;
|
|
49412
49971
|
}
|
|
49413
|
-
const value = options.readValue ? options.readValue() :
|
|
49972
|
+
const value = options.readValue ? options.readValue() : readFileSync67(0, "utf8").replace(/\r?\n$/, "");
|
|
49414
49973
|
if (operation === "set") await vault.set({ app, environment: env, name, value });
|
|
49415
49974
|
else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
|
|
49416
49975
|
else throw new Error(`unknown secrets operation ${operation}`);
|
|
@@ -49439,7 +49998,7 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
49439
49998
|
}
|
|
49440
49999
|
let body;
|
|
49441
50000
|
if (operation !== "list") {
|
|
49442
|
-
const value = options.readValue ? options.readValue() :
|
|
50001
|
+
const value = options.readValue ? options.readValue() : readFileSync67(0, "utf8").replace(/\r?\n$/, "");
|
|
49443
50002
|
body = JSON.stringify({ value });
|
|
49444
50003
|
}
|
|
49445
50004
|
const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
|
|
@@ -49475,15 +50034,15 @@ __export(notify_exports, {
|
|
|
49475
50034
|
runNotify: () => runNotify,
|
|
49476
50035
|
saveAdminSession: () => saveAdminSession
|
|
49477
50036
|
});
|
|
49478
|
-
import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as
|
|
50037
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as readFileSync68, writeFileSync as writeFileSync24 } from "node:fs";
|
|
49479
50038
|
import { homedir as homedir6 } from "node:os";
|
|
49480
|
-
import { dirname as dirname30, join as
|
|
50039
|
+
import { dirname as dirname30, join as join54 } from "node:path";
|
|
49481
50040
|
function defaultSessionsPath() {
|
|
49482
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
50041
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join54(homedir6(), ".himalaya", "admin-sessions.json");
|
|
49483
50042
|
}
|
|
49484
50043
|
function loadSessionsFile(path2 = defaultSessionsPath()) {
|
|
49485
50044
|
try {
|
|
49486
|
-
return JSON.parse(
|
|
50045
|
+
return JSON.parse(readFileSync68(path2, "utf8"));
|
|
49487
50046
|
} catch {
|
|
49488
50047
|
return {};
|
|
49489
50048
|
}
|
|
@@ -49532,7 +50091,7 @@ function parseDataFlag(raw) {
|
|
|
49532
50091
|
}
|
|
49533
50092
|
async function runNotify(pos, flags, io, deps = {}) {
|
|
49534
50093
|
const doFetch = deps.fetchImpl ?? fetch;
|
|
49535
|
-
const
|
|
50094
|
+
const str7 = (v) => typeof v === "string" ? v : void 0;
|
|
49536
50095
|
const json5 = flags.json === true;
|
|
49537
50096
|
const print = (v) => io.log(JSON.stringify(v, null, 2));
|
|
49538
50097
|
const sub = pos[1];
|
|
@@ -49547,8 +50106,8 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
49547
50106
|
return 2;
|
|
49548
50107
|
}
|
|
49549
50108
|
const { adminUrl, session } = resolveAuth({
|
|
49550
|
-
adminUrl:
|
|
49551
|
-
adminSession:
|
|
50109
|
+
adminUrl: str7(flags["admin-url"]),
|
|
50110
|
+
adminSession: str7(flags["admin-session"]),
|
|
49552
50111
|
...deps.env ? { env: deps.env } : {},
|
|
49553
50112
|
...deps.file ? { file: deps.file } : {}
|
|
49554
50113
|
});
|
|
@@ -49599,14 +50158,14 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
49599
50158
|
}
|
|
49600
50159
|
return report2.ok ? 0 : 1;
|
|
49601
50160
|
}
|
|
49602
|
-
const app =
|
|
50161
|
+
const app = str7(flags.app);
|
|
49603
50162
|
if (!app) {
|
|
49604
50163
|
io.error(JSON.stringify({ error: "--app is required", usage: USAGE2 }));
|
|
49605
50164
|
return 2;
|
|
49606
50165
|
}
|
|
49607
50166
|
if (sub === "tokens") {
|
|
49608
50167
|
const query = new URLSearchParams();
|
|
49609
|
-
const platform =
|
|
50168
|
+
const platform = str7(flags.platform);
|
|
49610
50169
|
if (platform) query.set("platform", platform);
|
|
49611
50170
|
if (flags["include-disabled"] === true) query.set("includeDisabled", "1");
|
|
49612
50171
|
const url = `${adminUrl}/v1/admin/push-tokens/${encodeURIComponent(app)}${query.size ? `?${query}` : ""}`;
|
|
@@ -49650,8 +50209,8 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
49650
50209
|
}
|
|
49651
50210
|
return 0;
|
|
49652
50211
|
}
|
|
49653
|
-
const token =
|
|
49654
|
-
const device =
|
|
50212
|
+
const token = str7(flags.token);
|
|
50213
|
+
const device = str7(flags.device);
|
|
49655
50214
|
const all = flags.all === true;
|
|
49656
50215
|
const targets = [token && "--token", device && "--device", all && "--all"].filter(Boolean);
|
|
49657
50216
|
if (targets.length === 0) {
|
|
@@ -49668,20 +50227,20 @@ async function runNotify(pos, flags, io, deps = {}) {
|
|
|
49668
50227
|
return 2;
|
|
49669
50228
|
}
|
|
49670
50229
|
const silent = flags.silent === true;
|
|
49671
|
-
const title =
|
|
50230
|
+
const title = str7(flags.title);
|
|
49672
50231
|
if (!silent && !title) {
|
|
49673
50232
|
io.error(JSON.stringify({ error: "--title is required for a visible notification (use --silent for a background push)", usage: USAGE2 }));
|
|
49674
50233
|
return 2;
|
|
49675
50234
|
}
|
|
49676
|
-
const badgeRaw =
|
|
50235
|
+
const badgeRaw = str7(flags.badge);
|
|
49677
50236
|
const payload = {
|
|
49678
50237
|
...title ? { title } : {},
|
|
49679
|
-
...
|
|
49680
|
-
...
|
|
49681
|
-
...
|
|
49682
|
-
...
|
|
49683
|
-
...
|
|
49684
|
-
...
|
|
50238
|
+
...str7(flags.body) ? { body: str7(flags.body) } : {},
|
|
50239
|
+
...str7(flags.link) ? { link: str7(flags.link) } : {},
|
|
50240
|
+
...str7(flags.category) ? { category: str7(flags.category) } : {},
|
|
50241
|
+
...str7(flags.channel) ? { channelId: str7(flags.channel) } : {},
|
|
50242
|
+
...str7(flags.platform) ? { platform: str7(flags.platform) } : {},
|
|
50243
|
+
...str7(flags["bundle-id"]) ? { bundleId: str7(flags["bundle-id"]) } : {},
|
|
49685
50244
|
...badgeRaw !== void 0 && Number.isFinite(Number(badgeRaw)) ? { badge: Number(badgeRaw) } : {},
|
|
49686
50245
|
...silent ? { pushType: "background" } : {},
|
|
49687
50246
|
...flags["dry-run"] === true ? { dryRun: true } : {},
|
|
@@ -49946,7 +50505,7 @@ var init_copy_clean = __esm({
|
|
|
49946
50505
|
function genericDescription(it) {
|
|
49947
50506
|
for (const field of DESCRIPTION_FIELDS) {
|
|
49948
50507
|
const raw = it[field];
|
|
49949
|
-
const text5 = typeof raw === "string" ? raw :
|
|
50508
|
+
const text5 = typeof raw === "string" ? raw : str4(raw?.text);
|
|
49950
50509
|
if (!text5) continue;
|
|
49951
50510
|
const plain2 = text5.replace(/<[^>]*>/g, " ").replace(/ /g, " ");
|
|
49952
50511
|
if (plain2.trim()) return plain2;
|
|
@@ -49994,18 +50553,18 @@ function planPrice(p) {
|
|
|
49994
50553
|
const price = pricing?.price ?? p.price;
|
|
49995
50554
|
if (typeof price === "string" && price.trim()) return price.trim();
|
|
49996
50555
|
if (price && typeof price === "object") {
|
|
49997
|
-
return
|
|
50556
|
+
return str4(price.formatted) || str4(price.value) || void 0;
|
|
49998
50557
|
}
|
|
49999
|
-
return
|
|
50558
|
+
return str4(p.formattedPrice) || str4(pricing?.formattedPrice) || void 0;
|
|
50000
50559
|
}
|
|
50001
50560
|
function planDetail(p) {
|
|
50002
50561
|
const pricing = p.pricing && typeof p.pricing === "object" ? p.pricing : void 0;
|
|
50003
50562
|
const sub = pricing?.subscription && typeof pricing.subscription === "object" ? pricing.subscription : void 0;
|
|
50004
50563
|
const cycleDur = sub?.cycleDuration && typeof sub.cycleDuration === "object" ? sub.cycleDuration : void 0;
|
|
50005
50564
|
const count = cycleDur?.count;
|
|
50006
|
-
const unit =
|
|
50007
|
-
const cycle = typeof count === "number" && unit ? `${count} ${unit}` :
|
|
50008
|
-
const perks = asArr(p.perks ?? p.benefits).map((x) =>
|
|
50565
|
+
const unit = str4(cycleDur?.unit ?? cycleDur?.period).toLowerCase();
|
|
50566
|
+
const cycle = typeof count === "number" && unit ? `${count} ${unit}` : str4(sub?.cycle ?? pricing?.cycle ?? p.period ?? p.billingPeriod);
|
|
50567
|
+
const perks = asArr(p.perks ?? p.benefits).map((x) => str4(x) || str4(x.name)).filter(Boolean);
|
|
50009
50568
|
const bits = [cycle, perks.slice(0, 4).join("; ")].filter(Boolean);
|
|
50010
50569
|
return bits.length ? bits.join(" \xB7 ") : void 0;
|
|
50011
50570
|
}
|
|
@@ -50017,7 +50576,7 @@ function formLabels(x, depth = 0, out = []) {
|
|
|
50017
50576
|
}
|
|
50018
50577
|
if (typeof x !== "object") return out;
|
|
50019
50578
|
const o = x;
|
|
50020
|
-
const label2 =
|
|
50579
|
+
const label2 = str4(o.label ?? o.displayName ?? o.fieldTitle ?? o.title);
|
|
50021
50580
|
if (label2 && !UUID_RE.test(label2) && label2.length < 80 && !out.includes(label2)) out.push(label2);
|
|
50022
50581
|
for (const k of ["fields", "formFields", "form", "schema", "properties"]) {
|
|
50023
50582
|
if (o[k] != null) formLabels(o[k], depth + 1, out);
|
|
@@ -50060,10 +50619,10 @@ function side(call, def) {
|
|
|
50060
50619
|
}
|
|
50061
50620
|
function toItems(def, raw) {
|
|
50062
50621
|
return raw.slice(0, 12).map((it, i) => ({
|
|
50063
|
-
id:
|
|
50622
|
+
id: str4((def.idOf ? def.idOf(it) : it.id) ?? `row-${i}`),
|
|
50064
50623
|
title: def.titleOf(it) || "(untitled)",
|
|
50065
50624
|
imageUrl: def.imageOf?.(it),
|
|
50066
|
-
price: def.priceOf?.(it) ||
|
|
50625
|
+
price: def.priceOf?.(it) || str4(it.price?.formatted) || str4(it.formattedPrice) || void 0,
|
|
50067
50626
|
detail: def.detailOf?.(it),
|
|
50068
50627
|
description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
|
|
50069
50628
|
}));
|
|
@@ -50088,7 +50647,7 @@ async function readBookingsCategories(call) {
|
|
|
50088
50647
|
const { data } = await probeCall(call, "POST", "/bookings/v2/categories/query", {
|
|
50089
50648
|
query: { paging: { limit: 100 } }
|
|
50090
50649
|
});
|
|
50091
|
-
return asArr(data?.categories).map((c) => ({ id:
|
|
50650
|
+
return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.name ?? c.title) }));
|
|
50092
50651
|
}
|
|
50093
50652
|
async function readRedirects(call) {
|
|
50094
50653
|
if (!call) return 0;
|
|
@@ -50101,27 +50660,27 @@ async function readStoreCategories(call) {
|
|
|
50101
50660
|
query: { cursorPaging: { limit: 100 } },
|
|
50102
50661
|
treeReference: { appNamespace: "@wix/stores" }
|
|
50103
50662
|
});
|
|
50104
|
-
return asArr(data?.categories).map((c) => ({ id:
|
|
50663
|
+
return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.name), count: typeof c.numberOfProducts === "number" ? c.numberOfProducts : void 0 }));
|
|
50105
50664
|
}
|
|
50106
50665
|
async function readBlogCategories(call) {
|
|
50107
50666
|
if (!call) return [];
|
|
50108
50667
|
const { data } = await probeCall(call, "POST", "/blog/v3/categories/query", {
|
|
50109
50668
|
query: { paging: { limit: 100 } }
|
|
50110
50669
|
});
|
|
50111
|
-
return asArr(data?.categories).map((c) => ({ id:
|
|
50670
|
+
return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.label ?? c.name) }));
|
|
50112
50671
|
}
|
|
50113
50672
|
async function readMediaLibrary(call) {
|
|
50114
50673
|
if (!call) return [];
|
|
50115
50674
|
const { data } = await probeCall(call, "GET", "/site-media/v1/files?paging.limit=50");
|
|
50116
50675
|
return asArr(data?.files).slice(0, 50).map((f) => ({
|
|
50117
|
-
id:
|
|
50118
|
-
url:
|
|
50119
|
-
filename:
|
|
50676
|
+
id: str4(f.id ?? f.fileId),
|
|
50677
|
+
url: str4(f.url) || (str4(f.id) ? `https://static.wixstatic.com/media/${str4(f.id)}` : ""),
|
|
50678
|
+
filename: str4(f.displayName ?? f.fileName ?? f.name) || void 0
|
|
50120
50679
|
})).filter((f) => f.id && f.url);
|
|
50121
50680
|
}
|
|
50122
50681
|
function sampleTitle(data) {
|
|
50123
50682
|
for (const k of ["title", "name", "headline", "slug", "label", "displayName"]) {
|
|
50124
|
-
const v =
|
|
50683
|
+
const v = str4(data[k]).trim();
|
|
50125
50684
|
if (v && !v.includes("@") && v.length < 120) return v;
|
|
50126
50685
|
}
|
|
50127
50686
|
for (const [k, v] of Object.entries(data)) {
|
|
@@ -50145,13 +50704,13 @@ async function readCms(call, opts = {}) {
|
|
|
50145
50704
|
const unread = Math.max(0, (total ?? all.length) - cols.length);
|
|
50146
50705
|
const out = [];
|
|
50147
50706
|
for (const c of cols) {
|
|
50148
|
-
const id =
|
|
50707
|
+
const id = str4(c.id);
|
|
50149
50708
|
if (!id) continue;
|
|
50150
50709
|
const fieldsRaw = asArr(c.fields ?? c.displayFields);
|
|
50151
50710
|
const fields = fieldsRaw.map((f) => ({
|
|
50152
|
-
key:
|
|
50153
|
-
displayName:
|
|
50154
|
-
type:
|
|
50711
|
+
key: str4(f.key ?? f.id),
|
|
50712
|
+
displayName: str4(f.displayName) || void 0,
|
|
50713
|
+
type: str4(f.type) || void 0,
|
|
50155
50714
|
...f.systemField === true ? { systemField: true } : {},
|
|
50156
50715
|
...f.encrypted === true ? { encrypted: true } : {}
|
|
50157
50716
|
})).filter((f) => f.key);
|
|
@@ -50164,17 +50723,17 @@ async function readCms(call, opts = {}) {
|
|
|
50164
50723
|
const samples = items.slice(0, 5).map((row, i) => {
|
|
50165
50724
|
const dataObj = row.data && typeof row.data === "object" ? row.data : row;
|
|
50166
50725
|
const title = sampleTitle(dataObj);
|
|
50167
|
-
return { id:
|
|
50726
|
+
return { id: str4(row.id ?? dataObj._id) || `row-${i}`, ...title ? { title } : {} };
|
|
50168
50727
|
});
|
|
50169
50728
|
out.push({
|
|
50170
50729
|
id,
|
|
50171
|
-
displayName:
|
|
50730
|
+
displayName: str4(c.displayName ?? c.name) || void 0,
|
|
50172
50731
|
// A Wix APP's collection (Stores, Bookings, …) — the generic CMS screen must not
|
|
50173
50732
|
// advertise it, because its vertical already does, properly.
|
|
50174
|
-
...
|
|
50175
|
-
...
|
|
50176
|
-
readRole:
|
|
50177
|
-
writeRole:
|
|
50733
|
+
...str4(c.ownerAppId) ? { ownerAppId: str4(c.ownerAppId) } : {},
|
|
50734
|
+
...str4(c.displayField) ? { displayField: str4(c.displayField) } : {},
|
|
50735
|
+
readRole: str4(perms?.read) || str4(c.permissions) || void 0,
|
|
50736
|
+
writeRole: str4(perms?.insert ?? perms?.update) || void 0,
|
|
50178
50737
|
fields,
|
|
50179
50738
|
sampleCount: items.length,
|
|
50180
50739
|
...samples.length ? { samples } : {}
|
|
@@ -50198,8 +50757,8 @@ async function readInstalledApps(call) {
|
|
|
50198
50757
|
if (!data) continue;
|
|
50199
50758
|
const raw = asArr(data.apps ?? data.siteApps ?? data.items);
|
|
50200
50759
|
const apps = raw.map((a) => ({
|
|
50201
|
-
id:
|
|
50202
|
-
name:
|
|
50760
|
+
id: str4(a.id ?? a.appId ?? a.appDefId),
|
|
50761
|
+
name: str4(a.name ?? a.appName ?? a.title) || void 0
|
|
50203
50762
|
})).filter((a) => a.id);
|
|
50204
50763
|
if (apps.length) return apps.slice(0, 40);
|
|
50205
50764
|
}
|
|
@@ -50218,7 +50777,7 @@ async function readMemberRoles(call) {
|
|
|
50218
50777
|
}
|
|
50219
50778
|
if (!data) continue;
|
|
50220
50779
|
const raw = asArr(data.roles ?? data.items);
|
|
50221
|
-
const names = raw.map((r) =>
|
|
50780
|
+
const names = raw.map((r) => str4(r.title ?? r.name ?? r.id)).filter((n) => n && !n.includes("@"));
|
|
50222
50781
|
if (names.length) return { names: names.slice(0, 24), status: "ok" };
|
|
50223
50782
|
sawEmptyPayload = true;
|
|
50224
50783
|
}
|
|
@@ -50226,13 +50785,13 @@ async function readMemberRoles(call) {
|
|
|
50226
50785
|
if (sawAuthError) return { names: [], status: "error" };
|
|
50227
50786
|
return { names: [], status: "empty" };
|
|
50228
50787
|
}
|
|
50229
|
-
var asArr,
|
|
50788
|
+
var asArr, str4, DESCRIPTION_FIELDS, UUID_RE, CORE_PROBES, OPTIONAL_PROBES, ALL, CMS_LIST_LIMIT;
|
|
50230
50789
|
var init_probes = __esm({
|
|
50231
50790
|
"src/site-analyze/probes.ts"() {
|
|
50232
50791
|
init_rest();
|
|
50233
50792
|
init_copy_clean();
|
|
50234
50793
|
asArr = (x) => Array.isArray(x) ? x : [];
|
|
50235
|
-
|
|
50794
|
+
str4 = (x) => typeof x === "string" ? x : "";
|
|
50236
50795
|
DESCRIPTION_FIELDS = ["plainDescription", "description", "shortDescription", "excerpt", "tagLine", "subtitle"];
|
|
50237
50796
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
50238
50797
|
CORE_PROBES = [
|
|
@@ -50242,9 +50801,9 @@ var init_probes = __esm({
|
|
|
50242
50801
|
path: "/stores/v3/products/query",
|
|
50243
50802
|
body: { query: { cursorPaging: { limit: 50 } } },
|
|
50244
50803
|
itemsOf: (d) => asArr(d.products),
|
|
50245
|
-
titleOf: (p) =>
|
|
50804
|
+
titleOf: (p) => str4(p.name),
|
|
50246
50805
|
imageOf: productImage,
|
|
50247
|
-
priceOf: (p) =>
|
|
50806
|
+
priceOf: (p) => str4(p.price?.formatted) || str4(p.priceData?.formatted?.price) || str4(p.formattedPrice) || (typeof p.price === "number" ? String(p.price) : void 0),
|
|
50248
50807
|
fallbacks: [
|
|
50249
50808
|
{
|
|
50250
50809
|
method: "POST",
|
|
@@ -50266,7 +50825,7 @@ var init_probes = __esm({
|
|
|
50266
50825
|
path: "/bookings/v2/services/query",
|
|
50267
50826
|
body: { query: { paging: { limit: 50 } } },
|
|
50268
50827
|
itemsOf: (d) => asArr(d.services),
|
|
50269
|
-
titleOf: (s) =>
|
|
50828
|
+
titleOf: (s) => str4(s.name),
|
|
50270
50829
|
imageOf: serviceImage
|
|
50271
50830
|
},
|
|
50272
50831
|
{
|
|
@@ -50275,8 +50834,8 @@ var init_probes = __esm({
|
|
|
50275
50834
|
path: "/events/v3/events/query",
|
|
50276
50835
|
body: { query: { paging: { limit: 50 } } },
|
|
50277
50836
|
itemsOf: (d) => asArr(d.events),
|
|
50278
|
-
titleOf: (e) =>
|
|
50279
|
-
imageOf: (e) =>
|
|
50837
|
+
titleOf: (e) => str4(e.title ?? e.name),
|
|
50838
|
+
imageOf: (e) => str4(e.mainImage) || str4(e.mainImage?.url) || void 0
|
|
50280
50839
|
},
|
|
50281
50840
|
{
|
|
50282
50841
|
vertical: "blog",
|
|
@@ -50284,7 +50843,7 @@ var init_probes = __esm({
|
|
|
50284
50843
|
path: "/blog/v3/posts/query",
|
|
50285
50844
|
body: { query: { paging: { limit: 50 } } },
|
|
50286
50845
|
itemsOf: (d) => asArr(d.posts),
|
|
50287
|
-
titleOf: (p) =>
|
|
50846
|
+
titleOf: (p) => str4(p.title),
|
|
50288
50847
|
imageOf: blogCover
|
|
50289
50848
|
},
|
|
50290
50849
|
{
|
|
@@ -50293,7 +50852,7 @@ var init_probes = __esm({
|
|
|
50293
50852
|
path: "/social-groups-proxy/groups/v2/groups/query",
|
|
50294
50853
|
body: { query: { paging: { limit: 50 } } },
|
|
50295
50854
|
itemsOf: (d) => asArr(d.groups),
|
|
50296
|
-
titleOf: (g) =>
|
|
50855
|
+
titleOf: (g) => str4(g.title ?? g.name),
|
|
50297
50856
|
imageOf: (g) => deepImageUrl(g.coverImage) || deepImageUrl(g.image)
|
|
50298
50857
|
},
|
|
50299
50858
|
{
|
|
@@ -50302,7 +50861,7 @@ var init_probes = __esm({
|
|
|
50302
50861
|
path: "/online-programs/v3/programs/query",
|
|
50303
50862
|
body: { query: { cursorPaging: { limit: 50 } } },
|
|
50304
50863
|
itemsOf: (d) => asArr(d.programs),
|
|
50305
|
-
titleOf: (p) =>
|
|
50864
|
+
titleOf: (p) => str4(p.title ?? p.name),
|
|
50306
50865
|
imageOf: (p) => deepImageUrl(p.image) || deepImageUrl(p.coverImage) || deepImageUrl(p.media)
|
|
50307
50866
|
},
|
|
50308
50867
|
{
|
|
@@ -50310,21 +50869,21 @@ var init_probes = __esm({
|
|
|
50310
50869
|
method: "GET",
|
|
50311
50870
|
path: "/restaurants/menus/v1/menus",
|
|
50312
50871
|
itemsOf: (d) => asArr(d.menus),
|
|
50313
|
-
titleOf: (m) =>
|
|
50872
|
+
titleOf: (m) => str4(m.name)
|
|
50314
50873
|
}
|
|
50315
50874
|
];
|
|
50316
50875
|
OPTIONAL_PROBES = [
|
|
50317
|
-
{ vertical: "plans", method: "GET", path: "/pricing-plans/v2/plans", itemsOf: (d) => asArr(d.plans), titleOf: (p) =>
|
|
50318
|
-
{ vertical: "reviews", method: "POST", path: "/reviews/v1/reviews/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.reviews), titleOf: (r) =>
|
|
50319
|
-
{ vertical: "loyalty", method: "GET", path: "/loyalty-programs/v1/program", itemsOf: (d) => d.loyaltyProgram ? [d.loyaltyProgram] : [], titleOf: (p) =>
|
|
50320
|
-
{ vertical: "forum", method: "POST", path: "/forum/v1/posts/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.posts), titleOf: (p) =>
|
|
50321
|
-
{ vertical: "donations", method: "POST", path: "/donation-campaigns/v2/donation-campaigns/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.donationCampaigns), titleOf: (c) =>
|
|
50322
|
-
{ vertical: "giftCards", method: "POST", path: "/gift-cards/v1/gift-cards/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.giftCards), titleOf: (g) =>
|
|
50323
|
-
{ vertical: "reservations", method: "GET", path: "/table-reservations/reservation-locations/v1/reservation-locations", itemsOf: (d) => asArr(d.reservationLocations ?? d.reservations), titleOf: (l) =>
|
|
50324
|
-
{ vertical: "badges", method: "POST", path: "/badges/v4/badges/query", body: { query: { cursorPaging: { limit: 50 } } }, itemsOf: (d) => asArr(d.badges), titleOf: (b) =>
|
|
50325
|
-
{ vertical: "coupons", method: "POST", path: "/stores/v2/coupons/query", body: { query: { paging: { limit: 30 } } }, itemsOf: (d) => asArr(d.coupons), titleOf: (c) =>
|
|
50326
|
-
{ vertical: "forms", method: "POST", path: "/form-schema-service/v4/forms/query", body: { query: { paging: { limit: 30 } }, namespace: "wix.form_app.form" }, itemsOf: (d) => asArr(d.forms), titleOf: (f) =>
|
|
50327
|
-
{ vertical: "portfolio", method: "GET", path: "/portfolio/v1/projects", itemsOf: (d) => asArr(d.projects), titleOf: (p) =>
|
|
50876
|
+
{ vertical: "plans", method: "GET", path: "/pricing-plans/v2/plans", itemsOf: (d) => asArr(d.plans), titleOf: (p) => str4(p.name), imageOf: (p) => deepImageUrl(p.image) || deepImageUrl(p.media), priceOf: planPrice, detailOf: planDetail },
|
|
50877
|
+
{ vertical: "reviews", method: "POST", path: "/reviews/v1/reviews/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.reviews), titleOf: (r) => str4(r.content ?? r.title) },
|
|
50878
|
+
{ vertical: "loyalty", method: "GET", path: "/loyalty-programs/v1/program", itemsOf: (d) => d.loyaltyProgram ? [d.loyaltyProgram] : [], titleOf: (p) => str4(p.name) || "Loyalty" },
|
|
50879
|
+
{ vertical: "forum", method: "POST", path: "/forum/v1/posts/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.posts), titleOf: (p) => str4(p.title) },
|
|
50880
|
+
{ vertical: "donations", method: "POST", path: "/donation-campaigns/v2/donation-campaigns/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.donationCampaigns), titleOf: (c) => str4(c.name) },
|
|
50881
|
+
{ vertical: "giftCards", method: "POST", path: "/gift-cards/v1/gift-cards/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.giftCards), titleOf: (g) => str4(g.name) },
|
|
50882
|
+
{ vertical: "reservations", method: "GET", path: "/table-reservations/reservation-locations/v1/reservation-locations", itemsOf: (d) => asArr(d.reservationLocations ?? d.reservations), titleOf: (l) => str4(l.name) },
|
|
50883
|
+
{ vertical: "badges", method: "POST", path: "/badges/v4/badges/query", body: { query: { cursorPaging: { limit: 50 } } }, itemsOf: (d) => asArr(d.badges), titleOf: (b) => str4(b.title ?? b.name) },
|
|
50884
|
+
{ vertical: "coupons", method: "POST", path: "/stores/v2/coupons/query", body: { query: { paging: { limit: 30 } } }, itemsOf: (d) => asArr(d.coupons), titleOf: (c) => str4(c.name) },
|
|
50885
|
+
{ vertical: "forms", method: "POST", path: "/form-schema-service/v4/forms/query", body: { query: { paging: { limit: 30 } }, namespace: "wix.form_app.form" }, itemsOf: (d) => asArr(d.forms), titleOf: (f) => str4(f.name), detailOf: formDetail },
|
|
50886
|
+
{ vertical: "portfolio", method: "GET", path: "/portfolio/v1/projects", itemsOf: (d) => asArr(d.projects), titleOf: (p) => str4(p.title ?? p.name), imageOf: (p) => deepImageUrl(p.coverImage) || deepImageUrl(p.image) },
|
|
50328
50887
|
{
|
|
50329
50888
|
vertical: "members",
|
|
50330
50889
|
method: "POST",
|
|
@@ -51428,7 +51987,7 @@ function veloArtifactRelPath(veloPath) {
|
|
|
51428
51987
|
if (!parts.length || parts.some((s) => s === "..")) return void 0;
|
|
51429
51988
|
return `${VELO_DIR}/${parts.join("/")}`;
|
|
51430
51989
|
}
|
|
51431
|
-
function
|
|
51990
|
+
function str5(x) {
|
|
51432
51991
|
return typeof x === "string" ? x : "";
|
|
51433
51992
|
}
|
|
51434
51993
|
function asArr2(x) {
|
|
@@ -51446,9 +52005,9 @@ function filesFromOwnerPayload(data, redact = redactSecrets) {
|
|
|
51446
52005
|
for (const item of raw) {
|
|
51447
52006
|
if (!item || typeof item !== "object") continue;
|
|
51448
52007
|
const f = item;
|
|
51449
|
-
const path2 =
|
|
52008
|
+
const path2 = str5(f.path || f.relativePath || f.fileName || f.name);
|
|
51450
52009
|
if (!path2 || isSecretVeloPath(path2)) continue;
|
|
51451
|
-
const content =
|
|
52010
|
+
const content = str5(f.content ?? f.source ?? f.code ?? f.body);
|
|
51452
52011
|
const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
|
|
51453
52012
|
const redacted = content ? redact(content) : "";
|
|
51454
52013
|
const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
|
|
@@ -53041,7 +53600,7 @@ var init_brand_font = __esm({
|
|
|
53041
53600
|
|
|
53042
53601
|
// src/site-analyze/write-artifacts.ts
|
|
53043
53602
|
import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync25 } from "node:fs";
|
|
53044
|
-
import { join as
|
|
53603
|
+
import { join as join55 } from "node:path";
|
|
53045
53604
|
function attachVeloSources(book, sources, put) {
|
|
53046
53605
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
53047
53606
|
for (const f of book.velo.files) {
|
|
@@ -53196,12 +53755,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
53196
53755
|
}
|
|
53197
53756
|
async function writeBusinessBook(result, opts) {
|
|
53198
53757
|
const out = opts.outDir;
|
|
53199
|
-
mkdirSync28(
|
|
53200
|
-
mkdirSync28(
|
|
53758
|
+
mkdirSync28(join55(out, "evidence/pages"), { recursive: true });
|
|
53759
|
+
mkdirSync28(join55(out, "media/catalog"), { recursive: true });
|
|
53201
53760
|
const files = [];
|
|
53202
53761
|
const put = (rel, body) => {
|
|
53203
|
-
const p =
|
|
53204
|
-
mkdirSync28(
|
|
53762
|
+
const p = join55(out, rel);
|
|
53763
|
+
mkdirSync28(join55(p, ".."), { recursive: true });
|
|
53205
53764
|
writeFileSync25(p, body);
|
|
53206
53765
|
files.push(rel);
|
|
53207
53766
|
};
|
|
@@ -53295,8 +53854,8 @@ var init_customer_build = __esm({
|
|
|
53295
53854
|
});
|
|
53296
53855
|
|
|
53297
53856
|
// src/site-analyze/apply.ts
|
|
53298
|
-
import { existsSync as existsSync58, readFileSync as
|
|
53299
|
-
import { dirname as dirname31, isAbsolute as isAbsolute4, join as
|
|
53857
|
+
import { existsSync as existsSync58, readFileSync as readFileSync69, writeFileSync as writeFileSync26, copyFileSync as copyFileSync3, mkdirSync as mkdirSync29, realpathSync as realpathSync7, statSync as statSync16 } from "node:fs";
|
|
53858
|
+
import { dirname as dirname31, isAbsolute as isAbsolute4, join as join56, resolve as resolve45, sep as sep14 } from "node:path";
|
|
53300
53859
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
53301
53860
|
function unpairedRedirectNote(overlay) {
|
|
53302
53861
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
@@ -53311,7 +53870,7 @@ function committedShellProvisioning(path2) {
|
|
|
53311
53870
|
function findRepoRoot(cwd) {
|
|
53312
53871
|
let dir = cwd;
|
|
53313
53872
|
for (let i = 0; i < 8; i++) {
|
|
53314
|
-
if (SHELL_NAMES2.some((name) => existsSync58(
|
|
53873
|
+
if (SHELL_NAMES2.some((name) => existsSync58(join56(dir, shellAppDir(name), "package.json")))) return dir;
|
|
53315
53874
|
const next = dirname31(dir);
|
|
53316
53875
|
if (next === dir) break;
|
|
53317
53876
|
dir = next;
|
|
@@ -53379,11 +53938,11 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
53379
53938
|
}
|
|
53380
53939
|
function buildMergedContract(options) {
|
|
53381
53940
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
53382
|
-
const committedPath =
|
|
53941
|
+
const committedPath = join56(appDir2, "provisioning.json");
|
|
53383
53942
|
if (!existsSync58(committedPath)) {
|
|
53384
53943
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
53385
53944
|
}
|
|
53386
|
-
const committed = JSON.parse(
|
|
53945
|
+
const committed = JSON.parse(readFileSync69(committedPath, "utf8"));
|
|
53387
53946
|
const merged = mergeCustomerOwned(committed, overlay);
|
|
53388
53947
|
const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
|
|
53389
53948
|
const branding = merged.branding ?? {};
|
|
@@ -53395,7 +53954,7 @@ function buildMergedContract(options) {
|
|
|
53395
53954
|
};
|
|
53396
53955
|
const stage = (fromRel, toRel) => {
|
|
53397
53956
|
const from = contained(packageDir, fromRel);
|
|
53398
|
-
const to = contained(
|
|
53957
|
+
const to = contained(join56(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
53399
53958
|
if (!from || !to || !existsSync58(from)) return void 0;
|
|
53400
53959
|
let real;
|
|
53401
53960
|
let realRoot;
|
|
@@ -53418,11 +53977,11 @@ function buildMergedContract(options) {
|
|
|
53418
53977
|
};
|
|
53419
53978
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
53420
53979
|
if (icon) branding.appIconPath = icon;
|
|
53421
|
-
const facesPath =
|
|
53980
|
+
const facesPath = join56(packageDir, "media/fonts/faces.json");
|
|
53422
53981
|
if (existsSync58(facesPath)) {
|
|
53423
53982
|
let faces = [];
|
|
53424
53983
|
try {
|
|
53425
|
-
const parsed = JSON.parse(
|
|
53984
|
+
const parsed = JSON.parse(readFileSync69(facesPath, "utf8"));
|
|
53426
53985
|
faces = Array.isArray(parsed) ? parsed : [];
|
|
53427
53986
|
} catch {
|
|
53428
53987
|
faces = [];
|
|
@@ -53443,9 +54002,9 @@ function buildMergedContract(options) {
|
|
|
53443
54002
|
merged.branding = branding;
|
|
53444
54003
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
53445
54004
|
`;
|
|
53446
|
-
const path2 =
|
|
54005
|
+
const path2 = join56(packageDir, "provisioning.contract.json");
|
|
53447
54006
|
writeFileSync26(path2, body);
|
|
53448
|
-
const localPath =
|
|
54007
|
+
const localPath = join56(appDir2, LOCAL_CONTRACT_REL);
|
|
53449
54008
|
mkdirSync29(dirname31(localPath), { recursive: true });
|
|
53450
54009
|
writeFileSync26(localPath, body);
|
|
53451
54010
|
staged.push(localPath);
|
|
@@ -53455,8 +54014,8 @@ async function applyOverlays(input) {
|
|
|
53455
54014
|
const cwd = resolve45(input.cwd);
|
|
53456
54015
|
const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
|
|
53457
54016
|
assertKnownShell(shell);
|
|
53458
|
-
const overlay = JSON.parse(
|
|
53459
|
-
const tokens = JSON.parse(
|
|
54017
|
+
const overlay = JSON.parse(readFileSync69(input.overlayPath, "utf8"));
|
|
54018
|
+
const tokens = JSON.parse(readFileSync69(input.tokensPath, "utf8"));
|
|
53460
54019
|
const wrote = [];
|
|
53461
54020
|
const notes = [];
|
|
53462
54021
|
const repoRoot2 = findRepoRoot(cwd);
|
|
@@ -53466,7 +54025,7 @@ async function applyOverlays(input) {
|
|
|
53466
54025
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
53467
54026
|
);
|
|
53468
54027
|
}
|
|
53469
|
-
const appDir2 =
|
|
54028
|
+
const appDir2 = join56(repoRoot2, shellAppDir(shell));
|
|
53470
54029
|
const packageDir = dirname31(resolve45(input.overlayPath));
|
|
53471
54030
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
53472
54031
|
wrote.push(...staged);
|
|
@@ -53488,10 +54047,10 @@ async function applyOverlays(input) {
|
|
|
53488
54047
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
53489
54048
|
};
|
|
53490
54049
|
}
|
|
53491
|
-
const pkgProv =
|
|
54050
|
+
const pkgProv = join56(cwd, "provisioning.json");
|
|
53492
54051
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
53493
54052
|
if (existsSync58(pkgProv)) {
|
|
53494
|
-
const cur = JSON.parse(
|
|
54053
|
+
const cur = JSON.parse(readFileSync69(pkgProv, "utf8"));
|
|
53495
54054
|
const merged = deepMerge4(cur, overlay);
|
|
53496
54055
|
writeFileSync26(pkgProv, JSON.stringify(merged, null, 2) + "\n");
|
|
53497
54056
|
wrote.push(pkgProv);
|
|
@@ -53499,9 +54058,9 @@ async function applyOverlays(input) {
|
|
|
53499
54058
|
writeFileSync26(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
53500
54059
|
wrote.push(pkgProv);
|
|
53501
54060
|
}
|
|
53502
|
-
const pkgTokens =
|
|
54061
|
+
const pkgTokens = join56(cwd, "tokens.json");
|
|
53503
54062
|
if (existsSync58(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
53504
|
-
const cur = JSON.parse(
|
|
54063
|
+
const cur = JSON.parse(readFileSync69(pkgTokens, "utf8"));
|
|
53505
54064
|
const merged = deepMerge4(cur, tokens);
|
|
53506
54065
|
const mergedColors = merged.colors;
|
|
53507
54066
|
if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
|
|
@@ -53520,9 +54079,9 @@ async function applyOverlays(input) {
|
|
|
53520
54079
|
wrote.push(pkgTokens);
|
|
53521
54080
|
}
|
|
53522
54081
|
const homeAction = homeRefreshActionId(shell);
|
|
53523
|
-
const homeSrc =
|
|
54082
|
+
const homeSrc = join56(cwd, "dev/index.ts");
|
|
53524
54083
|
if (homeAction && existsSync58(homeSrc)) {
|
|
53525
|
-
const prev =
|
|
54084
|
+
const prev = readFileSync69(homeSrc, "utf8");
|
|
53526
54085
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
53527
54086
|
let next = patched.src;
|
|
53528
54087
|
if (!patched.foreign && overlay.installedVerticals?.length) {
|
|
@@ -54558,20 +55117,20 @@ function canonicalDomain(domainName) {
|
|
|
54558
55117
|
if (domainName == null) {
|
|
54559
55118
|
return void 0;
|
|
54560
55119
|
}
|
|
54561
|
-
let
|
|
54562
|
-
if (IP_V6_REGEX_OBJECT.test(
|
|
54563
|
-
if (!
|
|
54564
|
-
|
|
55120
|
+
let str7 = domainName.trim().replace(/^\./, "");
|
|
55121
|
+
if (IP_V6_REGEX_OBJECT.test(str7)) {
|
|
55122
|
+
if (!str7.startsWith("[")) {
|
|
55123
|
+
str7 = "[" + str7;
|
|
54565
55124
|
}
|
|
54566
|
-
if (!
|
|
54567
|
-
|
|
55125
|
+
if (!str7.endsWith("]")) {
|
|
55126
|
+
str7 = str7 + "]";
|
|
54568
55127
|
}
|
|
54569
|
-
return domainToASCII(
|
|
55128
|
+
return domainToASCII(str7).slice(1, -1);
|
|
54570
55129
|
}
|
|
54571
|
-
if (/[^\u0001-\u007f]/.test(
|
|
54572
|
-
return domainToASCII(
|
|
55130
|
+
if (/[^\u0001-\u007f]/.test(str7)) {
|
|
55131
|
+
return domainToASCII(str7);
|
|
54573
55132
|
}
|
|
54574
|
-
return
|
|
55133
|
+
return str7.toLowerCase();
|
|
54575
55134
|
}
|
|
54576
55135
|
function formatDate(date) {
|
|
54577
55136
|
return date.toUTCString();
|
|
@@ -54665,16 +55224,16 @@ function parseDate(cookieDate) {
|
|
|
54665
55224
|
}
|
|
54666
55225
|
return date;
|
|
54667
55226
|
}
|
|
54668
|
-
function trimTerminator(
|
|
54669
|
-
if (isEmptyString(
|
|
55227
|
+
function trimTerminator(str7) {
|
|
55228
|
+
if (isEmptyString(str7)) return str7;
|
|
54670
55229
|
for (let t = 0; t < TERMINATORS.length; t++) {
|
|
54671
55230
|
const terminator = TERMINATORS[t];
|
|
54672
|
-
const terminatorIdx = terminator ?
|
|
55231
|
+
const terminatorIdx = terminator ? str7.indexOf(terminator) : -1;
|
|
54673
55232
|
if (terminatorIdx !== -1) {
|
|
54674
|
-
|
|
55233
|
+
str7 = str7.slice(0, terminatorIdx);
|
|
54675
55234
|
}
|
|
54676
55235
|
}
|
|
54677
|
-
return
|
|
55236
|
+
return str7;
|
|
54678
55237
|
}
|
|
54679
55238
|
function parseCookiePair(cookiePair, looseMode) {
|
|
54680
55239
|
cookiePair = trimTerminator(cookiePair);
|
|
@@ -54705,13 +55264,13 @@ function parseCookiePair(cookiePair, looseMode) {
|
|
|
54705
55264
|
c.value = cookieValue;
|
|
54706
55265
|
return c;
|
|
54707
55266
|
}
|
|
54708
|
-
function parse(
|
|
54709
|
-
if (isEmptyString(
|
|
55267
|
+
function parse(str7, options) {
|
|
55268
|
+
if (isEmptyString(str7) || !isString(str7)) {
|
|
54710
55269
|
return void 0;
|
|
54711
55270
|
}
|
|
54712
|
-
|
|
54713
|
-
const firstSemi =
|
|
54714
|
-
const cookiePair = firstSemi === -1 ?
|
|
55271
|
+
str7 = str7.trim();
|
|
55272
|
+
const firstSemi = str7.indexOf(";");
|
|
55273
|
+
const cookiePair = firstSemi === -1 ? str7 : str7.slice(0, firstSemi);
|
|
54715
55274
|
const c = parseCookiePair(cookiePair, options?.loose ?? false);
|
|
54716
55275
|
if (!c) {
|
|
54717
55276
|
return void 0;
|
|
@@ -54719,7 +55278,7 @@ function parse(str6, options) {
|
|
|
54719
55278
|
if (firstSemi === -1) {
|
|
54720
55279
|
return c;
|
|
54721
55280
|
}
|
|
54722
|
-
const unparsed =
|
|
55281
|
+
const unparsed = str7.slice(firstSemi + 1).trim();
|
|
54723
55282
|
if (unparsed.length === 0) {
|
|
54724
55283
|
return c;
|
|
54725
55284
|
}
|
|
@@ -54800,19 +55359,19 @@ function parse(str6, options) {
|
|
|
54800
55359
|
}
|
|
54801
55360
|
return c;
|
|
54802
55361
|
}
|
|
54803
|
-
function fromJSON(
|
|
54804
|
-
if (!
|
|
55362
|
+
function fromJSON(str7) {
|
|
55363
|
+
if (!str7 || isEmptyString(str7)) {
|
|
54805
55364
|
return void 0;
|
|
54806
55365
|
}
|
|
54807
55366
|
let obj3;
|
|
54808
|
-
if (typeof
|
|
55367
|
+
if (typeof str7 === "string") {
|
|
54809
55368
|
try {
|
|
54810
|
-
obj3 = JSON.parse(
|
|
55369
|
+
obj3 = JSON.parse(str7);
|
|
54811
55370
|
} catch {
|
|
54812
55371
|
return void 0;
|
|
54813
55372
|
}
|
|
54814
55373
|
} else {
|
|
54815
|
-
obj3 =
|
|
55374
|
+
obj3 = str7;
|
|
54816
55375
|
}
|
|
54817
55376
|
const c = new Cookie();
|
|
54818
55377
|
Cookie.serializableProperties.forEach((prop) => {
|
|
@@ -55530,42 +56089,42 @@ var init_dist = __esm({
|
|
|
55530
56089
|
* @public
|
|
55531
56090
|
*/
|
|
55532
56091
|
toString() {
|
|
55533
|
-
let
|
|
56092
|
+
let str7 = this.cookieString();
|
|
55534
56093
|
if (this.expires != "Infinity") {
|
|
55535
56094
|
if (this.expires instanceof Date) {
|
|
55536
|
-
|
|
56095
|
+
str7 += `; Expires=${formatDate(this.expires)}`;
|
|
55537
56096
|
}
|
|
55538
56097
|
}
|
|
55539
56098
|
if (this.maxAge != null && this.maxAge != Infinity) {
|
|
55540
|
-
|
|
56099
|
+
str7 += `; Max-Age=${String(this.maxAge)}`;
|
|
55541
56100
|
}
|
|
55542
56101
|
if (this.domain && !this.hostOnly) {
|
|
55543
|
-
|
|
56102
|
+
str7 += `; Domain=${this.domain}`;
|
|
55544
56103
|
}
|
|
55545
56104
|
if (this.path) {
|
|
55546
|
-
|
|
56105
|
+
str7 += `; Path=${this.path}`;
|
|
55547
56106
|
}
|
|
55548
56107
|
if (this.secure) {
|
|
55549
|
-
|
|
56108
|
+
str7 += "; Secure";
|
|
55550
56109
|
}
|
|
55551
56110
|
if (this.httpOnly) {
|
|
55552
|
-
|
|
56111
|
+
str7 += "; HttpOnly";
|
|
55553
56112
|
}
|
|
55554
56113
|
if (this.sameSite && this.sameSite !== "none") {
|
|
55555
56114
|
if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.lax.toLowerCase()) {
|
|
55556
|
-
|
|
56115
|
+
str7 += `; SameSite=${_Cookie2.sameSiteCanonical.lax}`;
|
|
55557
56116
|
} else if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.strict.toLowerCase()) {
|
|
55558
|
-
|
|
56117
|
+
str7 += `; SameSite=${_Cookie2.sameSiteCanonical.strict}`;
|
|
55559
56118
|
} else {
|
|
55560
|
-
|
|
56119
|
+
str7 += `; SameSite=${this.sameSite}`;
|
|
55561
56120
|
}
|
|
55562
56121
|
}
|
|
55563
56122
|
if (this.extensions) {
|
|
55564
56123
|
this.extensions.forEach((ext) => {
|
|
55565
|
-
|
|
56124
|
+
str7 += `; ${ext}`;
|
|
55566
56125
|
});
|
|
55567
56126
|
}
|
|
55568
|
-
return
|
|
56127
|
+
return str7;
|
|
55569
56128
|
}
|
|
55570
56129
|
/**
|
|
55571
56130
|
* Computes the TTL relative to now (milliseconds).
|
|
@@ -55688,8 +56247,8 @@ var init_dist = __esm({
|
|
|
55688
56247
|
* @param str - The `Set-Cookie` header or a Cookie string to parse.
|
|
55689
56248
|
* @param options - Configures `strict` or `loose` mode for cookie parsing
|
|
55690
56249
|
*/
|
|
55691
|
-
static parse(
|
|
55692
|
-
return parse(
|
|
56250
|
+
static parse(str7, options) {
|
|
56251
|
+
return parse(str7, options);
|
|
55693
56252
|
}
|
|
55694
56253
|
/**
|
|
55695
56254
|
* Does the reverse of {@link Cookie.toJSON}.
|
|
@@ -55716,8 +56275,8 @@ var init_dist = __esm({
|
|
|
55716
56275
|
*
|
|
55717
56276
|
* @param str - An unparsed JSON string or a value that has already been parsed as JSON
|
|
55718
56277
|
*/
|
|
55719
|
-
static fromJSON(
|
|
55720
|
-
return fromJSON(
|
|
56278
|
+
static fromJSON(str7) {
|
|
56279
|
+
return fromJSON(str7);
|
|
55721
56280
|
}
|
|
55722
56281
|
};
|
|
55723
56282
|
_Cookie.cookiesCreated = 0;
|
|
@@ -57706,7 +58265,7 @@ __export(cli_exports, {
|
|
|
57706
58265
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
57707
58266
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
57708
58267
|
});
|
|
57709
|
-
import { readFileSync as
|
|
58268
|
+
import { readFileSync as readFileSync70 } from "node:fs";
|
|
57710
58269
|
import { resolve as resolve46 } from "node:path";
|
|
57711
58270
|
function assetFetchFor(_opts) {
|
|
57712
58271
|
return pinnedFetch2;
|
|
@@ -57793,7 +58352,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
57793
58352
|
let source;
|
|
57794
58353
|
if (opts.sourcePath) {
|
|
57795
58354
|
const p = resolve46(opts.cwd ?? process.cwd(), opts.sourcePath);
|
|
57796
|
-
source =
|
|
58355
|
+
source = readFileSync70(p, "utf8");
|
|
57797
58356
|
}
|
|
57798
58357
|
let body;
|
|
57799
58358
|
if (opts.bodyRaw != null) {
|
|
@@ -58050,7 +58609,7 @@ __export(site_create_exports, {
|
|
|
58050
58609
|
runSiteList: () => runSiteList,
|
|
58051
58610
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
58052
58611
|
});
|
|
58053
|
-
import { existsSync as existsSync59, readFileSync as
|
|
58612
|
+
import { existsSync as existsSync59, readFileSync as readFileSync71, writeFileSync as writeFileSync27 } from "node:fs";
|
|
58054
58613
|
import { resolve as resolvePath2 } from "node:path";
|
|
58055
58614
|
function oauthClientName(projectName) {
|
|
58056
58615
|
return `${projectName} client`;
|
|
@@ -58199,7 +58758,7 @@ async function runSiteCreate(opts) {
|
|
|
58199
58758
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
58200
58759
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
58201
58760
|
}
|
|
58202
|
-
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync:
|
|
58761
|
+
function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync: readFileSync71, writeFileSync: writeFileSync27 }) {
|
|
58203
58762
|
const msid = binding2.siteId;
|
|
58204
58763
|
const path2 = resolvePath2(target);
|
|
58205
58764
|
const committed = committedShellProvisioning(path2);
|
|
@@ -58872,11 +59431,11 @@ var init_context = __esm({
|
|
|
58872
59431
|
});
|
|
58873
59432
|
|
|
58874
59433
|
// src/cli.ts
|
|
58875
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as
|
|
59434
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync72, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as rmSync13, readdirSync as readdirSync27, statSync as statSync17, lstatSync as lstatSync9, accessSync, constants as constants2, renameSync as renameSync6, cpSync as cpSync3 } from "node:fs";
|
|
58876
59435
|
import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
|
|
58877
|
-
import { createHash as
|
|
59436
|
+
import { createHash as createHash27, randomUUID as randomUUID5 } from "node:crypto";
|
|
58878
59437
|
import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
|
|
58879
|
-
import { join as
|
|
59438
|
+
import { join as join57, resolve as resolve47, relative as relative10, basename as basename14, dirname as dirname32 } from "node:path";
|
|
58880
59439
|
import { fileURLToPath as fileURLToPath24 } from "node:url";
|
|
58881
59440
|
|
|
58882
59441
|
// ../serve-cli/src/client.ts
|
|
@@ -62148,12 +62707,12 @@ function parseFlags(argv) {
|
|
|
62148
62707
|
return { _, flags };
|
|
62149
62708
|
}
|
|
62150
62709
|
var caveatLead = (ni) => ni.severity === "category" ? "WARNING \u2014 not implemented" : "NOTE \u2014 implemented, but these props are inert";
|
|
62151
|
-
var
|
|
62710
|
+
var str6 = (v) => typeof v === "string" ? v : void 0;
|
|
62152
62711
|
var num2 = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
62153
62712
|
function embeddedTemplateCatalog() {
|
|
62154
62713
|
return availableTemplates().map((name) => {
|
|
62155
|
-
const path2 =
|
|
62156
|
-
const meta = JSON.parse(
|
|
62714
|
+
const path2 = join57(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
62715
|
+
const meta = JSON.parse(readFileSync72(path2, "utf8"));
|
|
62157
62716
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
62158
62717
|
throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
62159
62718
|
}
|
|
@@ -62215,6 +62774,10 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
|
|
|
62215
62774
|
app is built \u2014 screens as they render, the journey step and the
|
|
62216
62775
|
latest postcard, validate/test/UX/draft checks, site vs app.
|
|
62217
62776
|
Updates itself; once open, other commands keep it current.
|
|
62777
|
+
himi studio reel [--out <file>] [--no-open]
|
|
62778
|
+
the making-of: one self-contained HTML file of the app taking
|
|
62779
|
+
shape \u2014 a flipbook of the home screen, the final screens, the
|
|
62780
|
+
postcards. Default .himi/making-of.html.
|
|
62218
62781
|
himi progress ["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]
|
|
62219
62782
|
journal a postcard for the owner (.himi/progress.jsonl): what
|
|
62220
62783
|
changed, which journey step, and the image that shows it (copied
|
|
@@ -62766,7 +63329,7 @@ var COMMANDS = [
|
|
|
62766
63329
|
{ name: "test", summary: "DERIVED behavioral crawl \u2014 no test files to write. Boots each screen's real worker, replays its onAppear, then dispatches every action site the descriptor already declares (each from a fresh boot) and checks a narrow set of unambiguous invariants: no uncaught throw, never stuck on `loading`, no `$service:` token or NaN/undefined/[object Object] reaching visible text, no binding aimed at state the worker never defines, no nav param silently dropped, no dead nav target. Catches what validate/render cannot \u2014 a WRONG REDUCER passes both with ok:true. Runs the worker in a DEVICE-PARITY sandbox (no setTimeout/setInterval, as on JSC/WebView) so a bundle that would die on device fails here. Crawls on HERMETIC DATA by default \u2014 zero network: the app's own dev/net-mocks.json first (--net <file> overrides), then the config's CMS `seed:` rows, then a canned fixture of frozen real vertical responses shipped with the CLI (exercises code paths, not API-contract truth) \u2014 so the success/mapping path runs, not just the failure UI. Two boot-only HOSTILE passes (every list empty; every request 500) then check the failure/empty day \u2014 corpus-proven, so their findings are errors. NAV EDGES are followed too: every himi.open site ($item params resolved against row 0 of its list, $service against worker state) and worker _nav directive is harvested, and each baked target is booted WITH the params the source sends \u2014 detail screens finally run their content arm; edge findings are errors tagged edge:<source>. --native runs both real native decoders over the exact baked JSON bytes; --native ios or --native android selects one. It is explicit, runs only from a Himalaya SOURCE CHECKOUT (the decoder oracles are that tree's own HimalayaCore Swift package and Gradle harness, which a published install does not ship), and needs the selected local toolchain. From a source checkout, default runs name missing native verdicts in the coverage ledger; elsewhere the ledger stays silent about them rather than offering a remedy you cannot run. --offline strips all data layers (the old reject-all axis); --no-hostile skips the hostile passes. --record (EXPLICIT, never automatic) refreshes dev/net-mocks.json from live reads first: it boots each screen (load + root onAppear ONLY \u2014 nothing the app's own launch would not fire; the tap/action crawl never sees the live transport, and only proven reads \u2014 GET, or read-shaped POST (/query, /search, /list*, \u2026) \u2014 ever reach the wire), freezes the round-trips, then crawls hermetically on the fresh fixture; record against a QA site, not production. Nodes it cannot judge headless are named, never silently passed. Exit 1 on any error. The CLI carries the authoring runtime off-repo; no per-app SDK install is required. --browser runs the whole loop (build \u2192 extract \u2192 validate \u2192 render \u2192 test) in YOUR browser instead of here, so the source never reaches a pod: it opens one screen's worker + descriptor in a tab, blocks on a loopback callback, and prints the report it posts back. One screen per tab \u2014 name it. --no-open prints the URL rather than launching a browser (SSH); --timeout <ms> bounds the wait, which matters because the page has no execution deadline of its own and an infinite loop in the worker hangs the tab.", required: "[<screenId>\u2026] [--content <dir>] [--net <file>] [--budget <ms>] [--deep [n]] [--record] [--native [ios|android]] [--no-shots] [--offline] [--no-hostile] [--all-screens] [--browser] [--no-open] [--timeout <ms>] [--json]" },
|
|
62767
63330
|
{ name: "ux", summary: "audit or record mobile UX evidence. `audit` checks the public-safe contract, seeded blank acceptance rows, placeholder source copy, app-specific mocks, and iOS/Android audit records. It warns while existing templates migrate; `--strict` promotes missing evidence. `record` stores checks performed on an installed iOS/Android build: `--checks` is required for passed|failed and empty for unavailable, which drove nothing and needs a `--reason` instead. `record` also STAMPS the release it audited (it resolves the id from a build, the same one a push would publish), because an unforced `himi push` of a release with screens refuses when no drive is recorded for THAT release, or when the one that is recorded says `failed` \u2014 the artifact stopped being advice nobody reads (#2955). `unavailable` still satisfies it; only `failed` refuses.", required: "audit [--content <dir>] [--strict] [--json] | record --content <dir> --platform ios|android --status passed|failed|unavailable [--checks back,keyboard,...] [--reason <text>]" },
|
|
62768
63331
|
{ name: "progress", summary: 'the build JOURNAL an agent keeps for the owner while it works. `himi progress "<what changed>" --step <1-8|name> --image <png>` appends one postcard to .himi/progress.jsonl \u2014 the step is one of the customer journey\'s eight (discover, classify, plan, implement, brand, validate, review, download) \u2014 and COPIES each image, content-addressed, into .himi/history/, because .himi/shots/ is overwritten by every render and cleared by every full `himi test`, so a path into it would later show a different picture than the one the owner was sent. --image repeats. --notify also raises a best-effort desktop notification for an owner who stepped away. A bare `himi progress` prints the journal with the current step and elapsed time \u2014 also how an agent recovers its place after its context was compacted. Local only: nothing is sent anywhere.', required: '["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]' },
|
|
62769
|
-
{ name: "studio", summary: "open the BUILD BOARD \u2014 one local page the owner can leave open while an agent builds their app, which fills itself in: every screen as it renders (NEW/CHANGED badges, and each earlier version kept for a filmstrip), the journey stepper and the latest postcard from `himi progress`, the validate/test/UX/draft checks as they run, the site next to the app's home screen with its palette, and the navigation the test crawl followed. Writes .himi/studio/index.html and opens it; the page re-reads its state every two seconds, so nothing needs to be served. OPT-IN BY EXISTENCE: until this command has run, no other command touches .himi/studio/ \u2014 after it, render/test/validate/push/icon/site/ux/progress each refresh the board as they finish (best-effort; never fails a command). Every image is a content-addressed copy in .himi/history/, never a live path into .himi/shots/. Local only, no secrets: it never reads a preview token, handover code or control token. --no-open prints the path instead (SSH, CI).", required: "[--content <dir>] [--no-open]" },
|
|
63332
|
+
{ name: "studio", summary: "open the BUILD BOARD \u2014 one local page the owner can leave open while an agent builds their app, which fills itself in: every screen as it renders (NEW/CHANGED badges, and each earlier version kept for a filmstrip), the journey stepper and the latest postcard from `himi progress`, the validate/test/UX/draft checks as they run, the site next to the app's home screen with its palette, and the navigation the test crawl followed. Writes .himi/studio/index.html and opens it; the page re-reads its state every two seconds, so nothing needs to be served. OPT-IN BY EXISTENCE: until this command has run, no other command touches .himi/studio/ \u2014 after it, render/test/validate/push/icon/site/ux/progress each refresh the board as they finish (best-effort; never fails a command). Every image is a content-addressed copy in .himi/history/, never a live path into .himi/shots/. Local only, no secrets: it never reads a preview token, handover code or control token. --no-open prints the path instead (SSH, CI). `himi studio reel` writes the MAKING-OF: one self-contained HTML file (every image inlined, nothing fetched) with a flipbook of the home screen version by version, captioned by the postcard in effect at the time, the final screens, and every postcard \u2014 sized to stay attachable, thinning frames first. Defaults to .himi/making-of.html (never archived by push); --out to put it elsewhere.", required: "[--content <dir>] [--no-open] | reel [--out <file>] [--no-open]" },
|
|
62770
63333
|
{ name: "render", summary: "headless-render a screen with the web renderer: render-tree + diagnostics, optional --png <file>, --scheme dark, --tree. Local by default (content dir). Pass --remote --app --release to hit GET /v1/preview/\u2026/render on the serve plane after a push. Boots the worker so $service bindings resolve; --static raw bindings; --live real Wix fetches; --state injects worker state; --input supplies pre-boot navigation params; --width/--device for PNG viewport; --rtl for dir=rtl + $env:isRTL.", required: "<screenId> [--content <dir>] [--scheme dark] [--png <file>] [--tree] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--remote --app --release]" },
|
|
62771
63334
|
{ name: "cms", summary: "inspect, provision, and seed the app's CMS (Wix Data) collections, declared as a `cms` block in config.ts. `query` is READ-ONLY \u2014 by default it fetches ONLY the physical ids `config.ts` declares (item counts + schema drift) and reports `siteScanned: false`; it never lists the site, so an UNDECLARED `himi_<app>_` collection this app owns is not reached without `--all`. `--all` SCANS the site \u2014 every collection it lists is labeled `owned`/`adopted`/`foreign`, and it describes every foreign one \u2014 id, non-system field keys + types, and the site's read role \u2014 so an app with no `cms` block at all can DISCOVER a collection to adopt (`--all` is the one case where a missing `cms` block is not 'nothing to do'). Foreign collections are described up to a cap and are never item-counted (`itemCount: null`), because a row count is one query each; `foreign.count` is how many the scan LISTED \u2014 it follows the list endpoint's pages, and `listingIncomplete: true` says when the walk stopped short of the end, with `unlistedCollections` counting what it left out when Wix gave a paging total \u2014 and `foreign.truncated` says how many of those went undescribed, each still NAMED in `foreign.others` (id + displayName), so a collection the site already has is never hidden behind the cap. The scan is OWNER-scoped \u2014 it needs --site <msid> (or WIX_SITE_ID) plus owner auth via `wix token`; a visitor token can read a public collection's ITEMS but can never enumerate collections, so there is no tokenless discovery path. `create` reconciles declared collections additively and idempotently, and REFUSES any id outside the app's `himi_<app>_` namespace, so it is safe against a production site. It reports declared-vs-site `permissionDrift` but never writes permissions unless asked with --apply-permissions, so a field reconcile can't silently revert access control changed in the dashboard. `seed` inserts the git-tracked `seed:` rows into EMPTY owned collections (--force to add to a non-empty one; --ai writes placeholder rows plus a refinement prompt for you to review). Adopted collections (declared by `wixId`) are read-only and never created, updated, or seeded. Site from --site <msid> or WIX_SITE_ID; owner auth via `wix token`.", required: "query|create|seed [--site <msid>] [--content <dir>] [--all] [--dry-run] [--force] [--allow-destructive] [--apply-permissions] [--only <id>] [--ai] [--count <n>]" },
|
|
62772
63335
|
{ name: "data", summary: "read-only plan or explicitly provision/seed declared KV and Wix Data resources. Preview and production are separate scopes. KV administration uses the operator data plane from --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN; draft push never calls it.", required: "plan|create|seed [--site <msid>] [--environment preview|production] [--content <dir>] [--data-url <url>] [--dry-run] [--force]" },
|
|
@@ -62783,7 +63346,7 @@ var COMMANDS = [
|
|
|
62783
63346
|
{ 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]" },
|
|
62784
63347
|
{ 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>]" },
|
|
62785
63348
|
{ 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>" },
|
|
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.
|
|
63349
|
+
{ 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. Any `himi run` of a content package (plain, --watch or --browser) frames its preview on the build board (`himi studio`) while it serves, and all but --browser also serve that board at /__himi/studio/ on the preview's own origin.", required: "[<package.himi|dir|url>] [--browser] [--watch] [--content <dir>] [--port <n>] [--chrome preview|app] [--screen <id>] [--surface <id>] [--no-open] [--spa <url>]" },
|
|
62787
63350
|
{ 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]" },
|
|
62788
63351
|
{ 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]" },
|
|
62789
63352
|
{ 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]" },
|
|
@@ -62815,7 +63378,7 @@ var COMMANDS = [
|
|
|
62815
63378
|
];
|
|
62816
63379
|
function cliVersion() {
|
|
62817
63380
|
try {
|
|
62818
|
-
return JSON.parse(
|
|
63381
|
+
return JSON.parse(readFileSync72(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
|
|
62819
63382
|
} catch {
|
|
62820
63383
|
return "unknown";
|
|
62821
63384
|
}
|
|
@@ -62933,7 +63496,7 @@ function ageInDays(publishedAt, now = Date.now()) {
|
|
|
62933
63496
|
}
|
|
62934
63497
|
function packageVersion(path2) {
|
|
62935
63498
|
try {
|
|
62936
|
-
const version2 = JSON.parse(
|
|
63499
|
+
const version2 = JSON.parse(readFileSync72(path2, "utf8")).version;
|
|
62937
63500
|
return typeof version2 === "string" && version2 ? version2 : void 0;
|
|
62938
63501
|
} catch {
|
|
62939
63502
|
return void 0;
|
|
@@ -62942,7 +63505,7 @@ function packageVersion(path2) {
|
|
|
62942
63505
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
62943
63506
|
let dir = resolve47(fromDir);
|
|
62944
63507
|
for (; ; ) {
|
|
62945
|
-
const version2 = packageVersion(
|
|
63508
|
+
const version2 = packageVersion(join57(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
62946
63509
|
if (version2) return { version: version2, source: "local" };
|
|
62947
63510
|
const parent = dirname32(dir);
|
|
62948
63511
|
if (parent === dir) break;
|
|
@@ -62952,7 +63515,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
62952
63515
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
62953
63516
|
try {
|
|
62954
63517
|
const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
62955
|
-
const version2 = root ? packageVersion(
|
|
63518
|
+
const version2 = root ? packageVersion(join57(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
62956
63519
|
return version2 ? { version: version2, source: "global" } : {};
|
|
62957
63520
|
} catch {
|
|
62958
63521
|
return {};
|
|
@@ -62999,11 +63562,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
|
|
|
62999
63562
|
var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
|
|
63000
63563
|
var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
|
|
63001
63564
|
function updateCachePath(env = process.env) {
|
|
63002
|
-
return env.HIMI_UPDATE_CACHE_FILE ??
|
|
63565
|
+
return env.HIMI_UPDATE_CACHE_FILE ?? join57(homedir7(), ".himalaya", "update-check.json");
|
|
63003
63566
|
}
|
|
63004
63567
|
function readUpdateCache(path2) {
|
|
63005
63568
|
try {
|
|
63006
|
-
const parsed = JSON.parse(
|
|
63569
|
+
const parsed = JSON.parse(readFileSync72(path2, "utf8"));
|
|
63007
63570
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
63008
63571
|
} catch {
|
|
63009
63572
|
return {};
|
|
@@ -63071,11 +63634,11 @@ function createUpdateRunner(spawn7 = spawnSync5) {
|
|
|
63071
63634
|
},
|
|
63072
63635
|
installedVersion: () => {
|
|
63073
63636
|
const root = globalNodeModulesRoot();
|
|
63074
|
-
return root ? packageVersion(
|
|
63637
|
+
return root ? packageVersion(join57(root, "@wix", "himalaya-cli", "package.json")) : void 0;
|
|
63075
63638
|
},
|
|
63076
63639
|
reexec: (argv) => {
|
|
63077
63640
|
const root = globalNodeModulesRoot();
|
|
63078
|
-
const entry = root ?
|
|
63641
|
+
const entry = root ? join57(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
|
|
63079
63642
|
if (!entry || !existsSync60(entry)) return void 0;
|
|
63080
63643
|
const result = spawnSync5(process.execPath, [entry, ...argv], {
|
|
63081
63644
|
// inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
|
|
@@ -63123,7 +63686,7 @@ function staleUpdateLockFile(cachePath, now) {
|
|
|
63123
63686
|
for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
|
|
63124
63687
|
let content;
|
|
63125
63688
|
try {
|
|
63126
|
-
content =
|
|
63689
|
+
content = readFileSync72(path2, "utf8");
|
|
63127
63690
|
} catch {
|
|
63128
63691
|
continue;
|
|
63129
63692
|
}
|
|
@@ -63146,7 +63709,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
|
|
|
63146
63709
|
const mine = lockStamp(now);
|
|
63147
63710
|
const readLock = (path2) => {
|
|
63148
63711
|
try {
|
|
63149
|
-
return
|
|
63712
|
+
return readFileSync72(path2, "utf8");
|
|
63150
63713
|
} catch {
|
|
63151
63714
|
return void 0;
|
|
63152
63715
|
}
|
|
@@ -63684,7 +64247,7 @@ function executableOnPath(name, env = process.env) {
|
|
|
63684
64247
|
const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
63685
64248
|
for (const dir of entries) {
|
|
63686
64249
|
for (const suffix of suffixes) {
|
|
63687
|
-
const candidate =
|
|
64250
|
+
const candidate = join57(dir, `${name}${suffix}`);
|
|
63688
64251
|
try {
|
|
63689
64252
|
if (!statSync17(candidate).isFile()) continue;
|
|
63690
64253
|
if (process.platform !== "win32") accessSync(candidate, constants2.X_OK);
|
|
@@ -63793,7 +64356,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63793
64356
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
63794
64357
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
63795
64358
|
const iosYmlPath = iosProjectYml2(app);
|
|
63796
|
-
const iosYml = existsSync60(iosYmlPath) ?
|
|
64359
|
+
const iosYml = existsSync60(iosYmlPath) ? readFileSync72(iosYmlPath, "utf8") : "";
|
|
63797
64360
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
63798
64361
|
if (!optedIn) {
|
|
63799
64362
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -63807,7 +64370,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
63807
64370
|
}
|
|
63808
64371
|
function readConfigSource(dir) {
|
|
63809
64372
|
try {
|
|
63810
|
-
return
|
|
64373
|
+
return readFileSync72(join57(dir, "config.ts"), "utf8");
|
|
63811
64374
|
} catch {
|
|
63812
64375
|
return null;
|
|
63813
64376
|
}
|
|
@@ -63819,7 +64382,7 @@ function writePngFile(path2, base64) {
|
|
|
63819
64382
|
}
|
|
63820
64383
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
63821
64384
|
const dir = resolve47(parentDir, name);
|
|
63822
|
-
if (existsSync60(
|
|
64385
|
+
if (existsSync60(join57(dir, "himalaya.content.json"))) {
|
|
63823
64386
|
throw new Error(`content package already exists at ${dir}`);
|
|
63824
64387
|
}
|
|
63825
64388
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -63831,7 +64394,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
|
63831
64394
|
return finishScaffold(materializeSource(archive.files, name, dir), template);
|
|
63832
64395
|
}
|
|
63833
64396
|
function contentDir(flags) {
|
|
63834
|
-
return resolve47(
|
|
64397
|
+
return resolve47(str6(flags.content) ?? process.cwd());
|
|
63835
64398
|
}
|
|
63836
64399
|
function renameRestoredSource(restored, declaredApp, renamed) {
|
|
63837
64400
|
const text5 = {};
|
|
@@ -63849,7 +64412,7 @@ function renameRestoredSource(restored, declaredApp, renamed) {
|
|
|
63849
64412
|
function symlinkDestinationIssue(dest) {
|
|
63850
64413
|
let kind;
|
|
63851
64414
|
try {
|
|
63852
|
-
kind =
|
|
64415
|
+
kind = lstatSync9(dest);
|
|
63853
64416
|
} catch {
|
|
63854
64417
|
return null;
|
|
63855
64418
|
}
|
|
@@ -63877,7 +64440,7 @@ function restoreDestinationIssue(dest, force) {
|
|
|
63877
64440
|
function isHimalayaMonorepoCheckout(start) {
|
|
63878
64441
|
let dir = resolve47(start);
|
|
63879
64442
|
for (; ; ) {
|
|
63880
|
-
if (existsSync60(
|
|
64443
|
+
if (existsSync60(join57(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync60(join57(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
63881
64444
|
const parent = dirname32(dir);
|
|
63882
64445
|
if (parent === dir) return false;
|
|
63883
64446
|
dir = parent;
|
|
@@ -63920,7 +64483,7 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63920
64483
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
63921
64484
|
);
|
|
63922
64485
|
const repoRoot2 = resolve47(fileURLToPath24(new URL("../../..", import.meta.url)));
|
|
63923
|
-
const root =
|
|
64486
|
+
const root = join57(repoRoot2, "node_modules", ".cache", "himi-template-preview");
|
|
63924
64487
|
const stillRunning = (pid) => {
|
|
63925
64488
|
try {
|
|
63926
64489
|
process.kill(pid, 0);
|
|
@@ -63934,12 +64497,12 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63934
64497
|
if (!entry.isDirectory()) continue;
|
|
63935
64498
|
const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
|
|
63936
64499
|
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
|
|
63937
|
-
rmSync13(
|
|
64500
|
+
rmSync13(join57(root, entry.name), { recursive: true, force: true });
|
|
63938
64501
|
}
|
|
63939
64502
|
}
|
|
63940
64503
|
} catch {
|
|
63941
64504
|
}
|
|
63942
|
-
const dest =
|
|
64505
|
+
const dest = join57(root, `${slug}-${process.pid}`);
|
|
63943
64506
|
rmSync13(dest, { recursive: true, force: true });
|
|
63944
64507
|
mkdirSync30(dest, { recursive: true });
|
|
63945
64508
|
materializeSource(forBuild, displayName, dest, slug);
|
|
@@ -63947,17 +64510,17 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
63947
64510
|
}
|
|
63948
64511
|
async function appId(dir) {
|
|
63949
64512
|
try {
|
|
63950
|
-
const { readFileSync:
|
|
63951
|
-
const m = JSON.parse(
|
|
64513
|
+
const { readFileSync: readFileSync73 } = await import("node:fs");
|
|
64514
|
+
const m = JSON.parse(readFileSync73(join57(dir, "himalaya.content.json"), "utf8"));
|
|
63952
64515
|
if (m.name) return m.name;
|
|
63953
64516
|
} catch {
|
|
63954
64517
|
}
|
|
63955
|
-
return
|
|
64518
|
+
return basename14(dir);
|
|
63956
64519
|
}
|
|
63957
64520
|
async function contentVisibility(dir) {
|
|
63958
64521
|
try {
|
|
63959
|
-
const { readFileSync:
|
|
63960
|
-
const m = JSON.parse(
|
|
64522
|
+
const { readFileSync: readFileSync73 } = await import("node:fs");
|
|
64523
|
+
const m = JSON.parse(readFileSync73(join57(dir, "himalaya.content.json"), "utf8"));
|
|
63961
64524
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
63962
64525
|
} catch {
|
|
63963
64526
|
}
|
|
@@ -63965,7 +64528,7 @@ async function contentVisibility(dir) {
|
|
|
63965
64528
|
}
|
|
63966
64529
|
function visibilityFlag(flags, io) {
|
|
63967
64530
|
if (flags.visibility === void 0) return {};
|
|
63968
|
-
const v =
|
|
64531
|
+
const v = str6(flags.visibility);
|
|
63969
64532
|
if (v !== "public" && v !== "unlisted") {
|
|
63970
64533
|
io.error(JSON.stringify({ error: `--visibility must be public or unlisted (got "${v ?? ""}")` }));
|
|
63971
64534
|
return null;
|
|
@@ -64159,7 +64722,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
64159
64722
|
return 0;
|
|
64160
64723
|
}
|
|
64161
64724
|
case "agent-init": {
|
|
64162
|
-
const dir = resolve47(
|
|
64725
|
+
const dir = resolve47(str6(flags.dir) ?? process.cwd());
|
|
64163
64726
|
const res = writeAgentContext(dir);
|
|
64164
64727
|
print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
|
|
64165
64728
|
return 0;
|
|
@@ -64181,7 +64744,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
|
|
|
64181
64744
|
try {
|
|
64182
64745
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64183
64746
|
const bres = await buildContentForValidation2(dir, { resolution });
|
|
64184
|
-
out = mkdtempSync4(
|
|
64747
|
+
out = mkdtempSync4(join57(tmpdir5(), "himi-ux-record-"));
|
|
64185
64748
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64186
64749
|
const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
|
|
64187
64750
|
const releaseId = outcome.manifest.releaseId;
|
|
@@ -64359,7 +64922,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
64359
64922
|
let js;
|
|
64360
64923
|
for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
|
|
64361
64924
|
try {
|
|
64362
|
-
js =
|
|
64925
|
+
js = readFileSync72(join57(outDir, candidate), "utf8");
|
|
64363
64926
|
break;
|
|
64364
64927
|
} catch {
|
|
64365
64928
|
}
|
|
@@ -64390,7 +64953,7 @@ async function producedWidgetFamilies(dir) {
|
|
|
64390
64953
|
}
|
|
64391
64954
|
return { families, source: "dist/bundles" };
|
|
64392
64955
|
}
|
|
64393
|
-
var boardOpen = (dir) => existsSync60(
|
|
64956
|
+
var boardOpen = (dir) => existsSync60(join57(dir, ".himi", "studio", "index.html"));
|
|
64394
64957
|
var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
|
|
64395
64958
|
async function leaveForBoard(dir, record2, value) {
|
|
64396
64959
|
if (!boardOpen(dir)) return;
|
|
@@ -64445,20 +65008,20 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64445
65008
|
if (update) updateNotice = update;
|
|
64446
65009
|
}
|
|
64447
65010
|
const contextualDefaultTarget = defaultTargetForCommand(command, contentDir(flags));
|
|
64448
|
-
const targetName = () => resolveTargetName({ target:
|
|
65011
|
+
const targetName = () => resolveTargetName({ target: str6(flags.target), defaultTarget: contextualDefaultTarget });
|
|
64449
65012
|
const client2 = () => new ServeCliClient(
|
|
64450
65013
|
resolveTarget({
|
|
64451
|
-
target:
|
|
65014
|
+
target: str6(flags.target),
|
|
64452
65015
|
defaultTarget: contextualDefaultTarget,
|
|
64453
|
-
serveUrl:
|
|
64454
|
-
telemetryUrl:
|
|
64455
|
-
controlUrl:
|
|
64456
|
-
telemetryToken:
|
|
64457
|
-
controlToken:
|
|
65016
|
+
serveUrl: str6(flags["serve-url"]),
|
|
65017
|
+
telemetryUrl: str6(flags["telemetry-url"]),
|
|
65018
|
+
controlUrl: str6(flags["control-url"]),
|
|
65019
|
+
telemetryToken: str6(flags["telemetry-token"]),
|
|
65020
|
+
controlToken: str6(flags["control-token"])
|
|
64458
65021
|
})
|
|
64459
65022
|
);
|
|
64460
|
-
const serveBase = () => resolveTarget({ target:
|
|
64461
|
-
const controlBase = () => resolveTarget({ target:
|
|
65023
|
+
const serveBase = () => resolveTarget({ target: str6(flags.target), defaultTarget: contextualDefaultTarget, serveUrl: str6(flags["serve-url"]) }).serve;
|
|
65024
|
+
const controlBase = () => resolveTarget({ target: str6(flags.target), defaultTarget: contextualDefaultTarget, controlUrl: str6(flags["control-url"]) }).control ?? "";
|
|
64462
65025
|
const foreignPlaneRefusal = async () => {
|
|
64463
65026
|
const base = serveBase();
|
|
64464
65027
|
if (!isLoopbackBase(base)) return null;
|
|
@@ -64656,8 +65219,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64656
65219
|
io.error(JSON.stringify({ ok: false, error: flagError }));
|
|
64657
65220
|
return 2;
|
|
64658
65221
|
}
|
|
64659
|
-
const template =
|
|
64660
|
-
const parentDir = resolve47(
|
|
65222
|
+
const template = str6(flags.template);
|
|
65223
|
+
const parentDir = resolve47(str6(flags.dir) ?? process.cwd());
|
|
64661
65224
|
if (template && flags.remote === true) {
|
|
64662
65225
|
try {
|
|
64663
65226
|
const res2 = await initFromRemoteTemplate(name, parentDir, template, client2());
|
|
@@ -64774,11 +65337,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64774
65337
|
return outcome.code;
|
|
64775
65338
|
}
|
|
64776
65339
|
if (sub === "publish") {
|
|
64777
|
-
const appDir2 = resolve47(
|
|
64778
|
-
const sourceDir = resolve47(
|
|
65340
|
+
const appDir2 = resolve47(str6(flags.dir) ?? process.cwd());
|
|
65341
|
+
const sourceDir = resolve47(str6(flags["source-dir"]) ?? appDir2);
|
|
64779
65342
|
let meta;
|
|
64780
65343
|
try {
|
|
64781
|
-
meta = JSON.parse(
|
|
65344
|
+
meta = JSON.parse(readFileSync72(join57(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
64782
65345
|
} catch {
|
|
64783
65346
|
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>)` }));
|
|
64784
65347
|
return 2;
|
|
@@ -64788,11 +65351,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64788
65351
|
return 2;
|
|
64789
65352
|
}
|
|
64790
65353
|
try {
|
|
64791
|
-
const appearance = extractTemplateAppearance(JSON.parse(
|
|
65354
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync72(join57(sourceDir, "tokens.json"), "utf8")));
|
|
64792
65355
|
meta = { ...appearance, ...meta };
|
|
64793
65356
|
} catch {
|
|
64794
65357
|
}
|
|
64795
|
-
const name =
|
|
65358
|
+
const name = str6(flags.name) ?? await appId(sourceDir);
|
|
64796
65359
|
const templateAppId = TEMPLATE_APP_PREFIX + name;
|
|
64797
65360
|
const buildDir = materializeForPreview(appDir2, name, meta.title);
|
|
64798
65361
|
const app = await appId(buildDir);
|
|
@@ -64800,7 +65363,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64800
65363
|
const force = flags.force === true;
|
|
64801
65364
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
64802
65365
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
64803
|
-
const out = mkdtempSync4(
|
|
65366
|
+
const out = mkdtempSync4(join57(tmpdir5(), "himi-template-"));
|
|
64804
65367
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
64805
65368
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
64806
65369
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
@@ -64849,13 +65412,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64849
65412
|
}));
|
|
64850
65413
|
return 1;
|
|
64851
65414
|
}
|
|
64852
|
-
const iconPath =
|
|
65415
|
+
const iconPath = str6(flags.icon) ? resolve47(str6(flags.icon)) : templateIconPath(name);
|
|
64853
65416
|
let iconHash;
|
|
64854
65417
|
if (iconPath) {
|
|
64855
65418
|
try {
|
|
64856
|
-
const bytes2 =
|
|
65419
|
+
const bytes2 = readFileSync72(iconPath);
|
|
64857
65420
|
payload.icon = bytes2.toString("base64");
|
|
64858
|
-
iconHash =
|
|
65421
|
+
iconHash = createHash27("sha256").update(bytes2).digest("hex");
|
|
64859
65422
|
} catch {
|
|
64860
65423
|
}
|
|
64861
65424
|
}
|
|
@@ -64904,8 +65467,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
64904
65467
|
const tplVis = visibilityFlag(flags, io);
|
|
64905
65468
|
if (!tplVis) return 2;
|
|
64906
65469
|
const publishMeta = {
|
|
64907
|
-
...
|
|
64908
|
-
...
|
|
65470
|
+
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
65471
|
+
...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
|
|
64909
65472
|
...tplVis.value ? { visibility: tplVis.value } : {}
|
|
64910
65473
|
};
|
|
64911
65474
|
let sendPayload = payload;
|
|
@@ -65005,7 +65568,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65005
65568
|
return 1;
|
|
65006
65569
|
}
|
|
65007
65570
|
const releaseId = r.json?.releaseId ?? payload.manifest.releaseId;
|
|
65008
|
-
const targetFlag =
|
|
65571
|
+
const targetFlag = str6(flags.target) ? ` --target ${str6(flags.target)}` : "";
|
|
65009
65572
|
print({
|
|
65010
65573
|
ok: true,
|
|
65011
65574
|
template: name,
|
|
@@ -65086,7 +65649,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65086
65649
|
const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
|
|
65087
65650
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65088
65651
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
65089
|
-
const out = mkdtempSync4(
|
|
65652
|
+
const out = mkdtempSync4(join57(tmpdir5(), "himi-validate-"));
|
|
65090
65653
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65091
65654
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65092
65655
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65124,12 +65687,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65124
65687
|
}
|
|
65125
65688
|
case "functions": {
|
|
65126
65689
|
const { buildLocalFunctions: buildLocalFunctions2, describeFunction: describeFunction2, invokeLocalFunction: invokeLocalFunction2, invokeRemoteFunction: invokeRemoteFunction2, listFunctions: listFunctions2, loadFunctionsApp: loadFunctionsApp2, openApiForFunctions: openApiForFunctions2, resolveFunctionsTarget: resolveFunctionsTarget2, runRemoteFunctionOperation: runRemoteFunctionOperation2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
65127
|
-
const remoteTarget =
|
|
65690
|
+
const remoteTarget = str6(flags.target);
|
|
65128
65691
|
const boCookie = () => {
|
|
65129
65692
|
const path2 = dpxSessionTokenPath();
|
|
65130
65693
|
let raw;
|
|
65131
65694
|
try {
|
|
65132
|
-
raw =
|
|
65695
|
+
raw = readFileSync72(path2, "utf8");
|
|
65133
65696
|
} catch {
|
|
65134
65697
|
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`);
|
|
65135
65698
|
}
|
|
@@ -65147,14 +65710,14 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65147
65710
|
io.error(JSON.stringify({ error: `functions ${sub} needs ${allowed2.join(" | ")}` }));
|
|
65148
65711
|
return 2;
|
|
65149
65712
|
}
|
|
65150
|
-
const app =
|
|
65713
|
+
const app = str6(flags.app);
|
|
65151
65714
|
const id = pos[3];
|
|
65152
65715
|
if (!app || !["list", "dlq"].includes(action) && !id) {
|
|
65153
65716
|
io.error(JSON.stringify({ error: `functions ${sub} ${action} needs --app${["list", "dlq"].includes(action) ? "" : " and an id/name"}` }));
|
|
65154
65717
|
return 2;
|
|
65155
65718
|
}
|
|
65156
|
-
const target2 = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl:
|
|
65157
|
-
const result = await runRemoteFunctionOperation2({ baseUrl: target2.mode === "remote" ? target2.baseUrl : "", app, environment:
|
|
65719
|
+
const target2 = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str6(flags["functions-url"]), releaseId: str6(flags.release), requireRemote: true });
|
|
65720
|
+
const result = await runRemoteFunctionOperation2({ baseUrl: target2.mode === "remote" ? target2.baseUrl : "", app, environment: str6(flags.environment) === "preview" ? "preview" : "production", resource: sub === "jobs" ? "jobs" : "schedules", action, id, releaseId: str6(flags.release), boCookie: boCookie(), previewToken: str6(flags["preview-token"]) });
|
|
65158
65721
|
print({ ...result.body, ok: result.ok, status: result.status });
|
|
65159
65722
|
return result.ok ? 0 : 1;
|
|
65160
65723
|
}
|
|
@@ -65190,7 +65753,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65190
65753
|
}
|
|
65191
65754
|
let input = { name: "Himi", value: "echo", ok: true };
|
|
65192
65755
|
if (flags.body !== void 0) {
|
|
65193
|
-
const raw =
|
|
65756
|
+
const raw = str6(flags.body);
|
|
65194
65757
|
if (!raw) {
|
|
65195
65758
|
io.error(JSON.stringify({ error: "--body must be non-empty JSON" }));
|
|
65196
65759
|
return 2;
|
|
@@ -65204,7 +65767,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65204
65767
|
}
|
|
65205
65768
|
let params = {};
|
|
65206
65769
|
if (flags.params !== void 0) {
|
|
65207
|
-
const raw =
|
|
65770
|
+
const raw = str6(flags.params);
|
|
65208
65771
|
try {
|
|
65209
65772
|
const parsed = JSON.parse(raw ?? "");
|
|
65210
65773
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.values(parsed).some((value) => typeof value !== "string")) throw new Error("must be a JSON object of string values");
|
|
@@ -65214,16 +65777,16 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65214
65777
|
return 2;
|
|
65215
65778
|
}
|
|
65216
65779
|
}
|
|
65217
|
-
const remoteRelease =
|
|
65218
|
-
const target = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl:
|
|
65780
|
+
const remoteRelease = str6(flags.release);
|
|
65781
|
+
const target = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str6(flags["functions-url"]), releaseId: remoteRelease });
|
|
65219
65782
|
if (target.mode === "remote") {
|
|
65220
65783
|
const definition = loaded.definitions.find((item) => item.name === name);
|
|
65221
65784
|
if (!definition) {
|
|
65222
65785
|
io.error(JSON.stringify({ error: `unknown function "${name}"` }));
|
|
65223
65786
|
return 1;
|
|
65224
65787
|
}
|
|
65225
|
-
const app =
|
|
65226
|
-
const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken:
|
|
65788
|
+
const app = str6(flags.app) ?? loaded.app;
|
|
65789
|
+
const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken: str6(flags["preview-token"]), boCookie: boCookie() });
|
|
65227
65790
|
const response = invoked2.response;
|
|
65228
65791
|
const text6 = await response.text();
|
|
65229
65792
|
let body2;
|
|
@@ -65249,10 +65812,41 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65249
65812
|
case "studio": {
|
|
65250
65813
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
65251
65814
|
const dir = contentDir(flags);
|
|
65252
|
-
if (!existsSync60(
|
|
65815
|
+
if (!existsSync60(join57(dir, "himalaya.content.json"))) {
|
|
65253
65816
|
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/" }));
|
|
65254
65817
|
return 2;
|
|
65255
65818
|
}
|
|
65819
|
+
if (pos[1] === "reel") {
|
|
65820
|
+
const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
|
|
65821
|
+
const out = resolve47(str6(flags.out) ?? join57(dir, ".himi", "making-of.html"));
|
|
65822
|
+
const { html, plan } = buildReel2(dir);
|
|
65823
|
+
mkdirSync30(dirname32(out), { recursive: true });
|
|
65824
|
+
writeFileSync28(out, html);
|
|
65825
|
+
const { pathToFileURL: pathToFileURL9 } = await import("node:url");
|
|
65826
|
+
const url2 = pathToFileURL9(out).href;
|
|
65827
|
+
const open2 = flags["no-open"] !== true;
|
|
65828
|
+
if (open2) {
|
|
65829
|
+
const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
|
|
65830
|
+
openUrl2(url2);
|
|
65831
|
+
}
|
|
65832
|
+
print({
|
|
65833
|
+
ok: true,
|
|
65834
|
+
file: out,
|
|
65835
|
+
url: url2,
|
|
65836
|
+
opened: open2,
|
|
65837
|
+
bytes: Buffer.byteLength(html),
|
|
65838
|
+
frames: plan.frames.length,
|
|
65839
|
+
screens: plan.stats.screens,
|
|
65840
|
+
postcards: plan.stats.postcards,
|
|
65841
|
+
...plan.dropped ? { dropped: plan.dropped, note: "pictures were left out to keep the file attachable" } : {},
|
|
65842
|
+
...plan.frames.length === 0 ? { hint: "no screen versions were recorded \u2014 run `himi studio` before building so the board keeps them" } : {}
|
|
65843
|
+
});
|
|
65844
|
+
return 0;
|
|
65845
|
+
}
|
|
65846
|
+
if (pos[1] !== void 0) {
|
|
65847
|
+
io.error(JSON.stringify({ ok: false, error: "unknown_subcommand", got: pos[1], expected: "himi studio [reel]" }));
|
|
65848
|
+
return 2;
|
|
65849
|
+
}
|
|
65256
65850
|
const { page, url, view } = openStudio2(dir);
|
|
65257
65851
|
const open = flags["no-open"] !== true;
|
|
65258
65852
|
if (open) {
|
|
@@ -65274,7 +65868,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65274
65868
|
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));
|
|
65275
65869
|
const dir = contentDir(flags);
|
|
65276
65870
|
const journal = journalPath2(dir);
|
|
65277
|
-
const hint = existsSync60(
|
|
65871
|
+
const hint = existsSync60(join57(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" };
|
|
65278
65872
|
const message = pos.slice(1).join(" ").trim();
|
|
65279
65873
|
if (!message) {
|
|
65280
65874
|
if (flags.step !== void 0 || flags.image !== void 0 || flags.notify === true) {
|
|
@@ -65325,9 +65919,9 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65325
65919
|
io.error(JSON.stringify({ error: "ux needs audit | record" }));
|
|
65326
65920
|
return 2;
|
|
65327
65921
|
}
|
|
65328
|
-
const platform =
|
|
65329
|
-
const status =
|
|
65330
|
-
const checks =
|
|
65922
|
+
const platform = str6(flags.platform);
|
|
65923
|
+
const status = str6(flags.status);
|
|
65924
|
+
const checks = str6(flags.checks)?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
|
|
65331
65925
|
if (!isNativePlatform(platform)) {
|
|
65332
65926
|
io.error(JSON.stringify({ error: `ux record needs --platform ${NATIVE_PLATFORMS.join("|")}` }));
|
|
65333
65927
|
return 2;
|
|
@@ -65341,7 +65935,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65341
65935
|
drifting = workers;
|
|
65342
65936
|
});
|
|
65343
65937
|
try {
|
|
65344
|
-
const evidence = recordNativeAudit(dir, platform, status, checks,
|
|
65938
|
+
const evidence = recordNativeAudit(dir, platform, status, checks, str6(flags.reason), uxRelease ?? void 0);
|
|
65345
65939
|
print({
|
|
65346
65940
|
ok: true,
|
|
65347
65941
|
content: dir,
|
|
@@ -65366,7 +65960,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65366
65960
|
case "test": {
|
|
65367
65961
|
const dir = contentDir(flags);
|
|
65368
65962
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
65369
|
-
if (existsSync60(
|
|
65963
|
+
if (existsSync60(join57(dir, "functions"))) {
|
|
65370
65964
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
65371
65965
|
const loaded = await loadFunctionsApp2(dir);
|
|
65372
65966
|
const results = [];
|
|
@@ -65391,21 +65985,21 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65391
65985
|
}
|
|
65392
65986
|
let budgetMs;
|
|
65393
65987
|
if (flags.budget !== void 0) {
|
|
65394
|
-
budgetMs = Number(
|
|
65988
|
+
budgetMs = Number(str6(flags.budget));
|
|
65395
65989
|
if (!Number.isFinite(budgetMs) || budgetMs <= 0) {
|
|
65396
|
-
io.error(JSON.stringify({ error: `--budget must be a positive number of ms (got "${
|
|
65990
|
+
io.error(JSON.stringify({ error: `--budget must be a positive number of ms (got "${str6(flags.budget) ?? ""}")` }));
|
|
65397
65991
|
return 2;
|
|
65398
65992
|
}
|
|
65399
65993
|
}
|
|
65400
65994
|
let deep;
|
|
65401
65995
|
if (flags.deep !== void 0) {
|
|
65402
|
-
deep = flags.deep === true ? 3 : Number(
|
|
65996
|
+
deep = flags.deep === true ? 3 : Number(str6(flags.deep));
|
|
65403
65997
|
if (!Number.isFinite(deep) || deep < 2 || deep > 6) {
|
|
65404
65998
|
io.error(JSON.stringify({ error: `--deep takes a chain depth between 2 and 6 (got "${String(flags.deep)}") \u2014 bare --deep means 3` }));
|
|
65405
65999
|
return 2;
|
|
65406
66000
|
}
|
|
65407
66001
|
}
|
|
65408
|
-
const netPath =
|
|
66002
|
+
const netPath = str6(flags.net);
|
|
65409
66003
|
if (flags.net !== void 0 && !netPath) {
|
|
65410
66004
|
io.error(JSON.stringify({ error: "--net was given but empty \u2014 pass a path to a net-mocks JSON file" }));
|
|
65411
66005
|
return 2;
|
|
@@ -65436,7 +66030,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65436
66030
|
const { detectAndroidNativeDecode: detectAndroidNativeDecode2, detectNativeDecode: detectNativeDecode2, nativeDecodePlatforms: nativeDecodePlatforms2 } = await Promise.resolve().then(() => (init_native_decode(), native_decode_exports));
|
|
65437
66031
|
let platforms;
|
|
65438
66032
|
try {
|
|
65439
|
-
platforms = nativeDecodePlatforms2(flags.native === true ? true :
|
|
66033
|
+
platforms = nativeDecodePlatforms2(flags.native === true ? true : str6(flags.native));
|
|
65440
66034
|
} catch (error) {
|
|
65441
66035
|
io.error(JSON.stringify({ error: error.message }));
|
|
65442
66036
|
return 2;
|
|
@@ -65453,7 +66047,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65453
66047
|
}
|
|
65454
66048
|
}
|
|
65455
66049
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65456
|
-
const out = mkdtempSync4(
|
|
66050
|
+
const out = mkdtempSync4(join57(tmpdir5(), "himi-test-"));
|
|
65457
66051
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65458
66052
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65459
66053
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65478,9 +66072,9 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65478
66072
|
}
|
|
65479
66073
|
let browserTimeoutMs;
|
|
65480
66074
|
if (flags.timeout !== void 0) {
|
|
65481
|
-
browserTimeoutMs = Number(
|
|
66075
|
+
browserTimeoutMs = Number(str6(flags.timeout));
|
|
65482
66076
|
if (!Number.isFinite(browserTimeoutMs) || browserTimeoutMs <= 0) {
|
|
65483
|
-
io.error(JSON.stringify({ error: `--timeout must be a positive number of ms (got "${
|
|
66077
|
+
io.error(JSON.stringify({ error: `--timeout must be a positive number of ms (got "${str6(flags.timeout) ?? ""}")` }));
|
|
65484
66078
|
return 2;
|
|
65485
66079
|
}
|
|
65486
66080
|
}
|
|
@@ -65498,7 +66092,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65498
66092
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
65499
66093
|
return 2;
|
|
65500
66094
|
}
|
|
65501
|
-
const sources = collectWorkerSources2(
|
|
66095
|
+
const sources = collectWorkerSources2(join57(dir, "tier5-src"), screen.bundleName);
|
|
65502
66096
|
if (!sources) {
|
|
65503
66097
|
io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
65504
66098
|
return 2;
|
|
@@ -65659,7 +66253,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65659
66253
|
const sp = await runShotsPass2({
|
|
65660
66254
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
65661
66255
|
tokens: outcome.tokens,
|
|
65662
|
-
outDir:
|
|
66256
|
+
outDir: join57(dir, ".himi", "shots"),
|
|
65663
66257
|
width: 390,
|
|
65664
66258
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
65665
66259
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -65697,7 +66291,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65697
66291
|
releaseId: result.releaseId,
|
|
65698
66292
|
releasePayload: release,
|
|
65699
66293
|
descriptors: attestedDescriptors,
|
|
65700
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
66294
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join57(dir, ".himi", "shots", name)])),
|
|
65701
66295
|
coverage: {
|
|
65702
66296
|
screens: crawledScreens.size,
|
|
65703
66297
|
actionsDispatched: result.actions.exercised,
|
|
@@ -65731,15 +66325,15 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65731
66325
|
io.error(JSON.stringify({ error: "render --remote cannot --dump-state: the serve plane has no worker runtime. Render locally to inspect state." }));
|
|
65732
66326
|
return 2;
|
|
65733
66327
|
}
|
|
65734
|
-
const app2 =
|
|
65735
|
-
const release2 =
|
|
66328
|
+
const app2 = str6(flags.app);
|
|
66329
|
+
const release2 = str6(flags.release);
|
|
65736
66330
|
if (!app2 || !release2) {
|
|
65737
66331
|
io.error(JSON.stringify({ error: "render --remote needs --app and --release" }));
|
|
65738
66332
|
return 2;
|
|
65739
66333
|
}
|
|
65740
|
-
const scheme2 =
|
|
66334
|
+
const scheme2 = str6(flags.scheme) === "dark" ? "dark" : "light";
|
|
65741
66335
|
const wantPng2 = flags.png === true || typeof flags.png === "string";
|
|
65742
|
-
const widthRaw =
|
|
66336
|
+
const widthRaw = str6(flags.width);
|
|
65743
66337
|
const width = widthRaw ? Number(widthRaw) : void 0;
|
|
65744
66338
|
let r2;
|
|
65745
66339
|
try {
|
|
@@ -65770,7 +66364,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65770
66364
|
}
|
|
65771
66365
|
const dir = contentDir(flags);
|
|
65772
66366
|
const app = await appId(dir);
|
|
65773
|
-
const scheme =
|
|
66367
|
+
const scheme = str6(flags.scheme) === "dark" ? "dark" : "light";
|
|
65774
66368
|
const wantPng = flags.png === true || typeof flags.png === "string";
|
|
65775
66369
|
const hydrate = flags.static !== true;
|
|
65776
66370
|
const live2 = flags.live === true;
|
|
@@ -65781,13 +66375,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65781
66375
|
}
|
|
65782
66376
|
let injectedState;
|
|
65783
66377
|
if (flags.state !== void 0) {
|
|
65784
|
-
const stateArg =
|
|
66378
|
+
const stateArg = str6(flags.state);
|
|
65785
66379
|
if (!stateArg || !stateArg.trim()) {
|
|
65786
66380
|
io.error(JSON.stringify({ error: "--state was given but empty \u2014 pass inline JSON `{\u2026}` or a path to a .json file" }));
|
|
65787
66381
|
return 2;
|
|
65788
66382
|
}
|
|
65789
66383
|
try {
|
|
65790
|
-
const raw = stateArg.trim().startsWith("{") ? stateArg :
|
|
66384
|
+
const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync72(stateArg.replace(/^@/, ""), "utf8");
|
|
65791
66385
|
injectedState = JSON.parse(raw);
|
|
65792
66386
|
} catch (e) {
|
|
65793
66387
|
io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
|
|
@@ -65796,13 +66390,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65796
66390
|
}
|
|
65797
66391
|
let injectedInput;
|
|
65798
66392
|
if (flags.input !== void 0) {
|
|
65799
|
-
const inputArg =
|
|
66393
|
+
const inputArg = str6(flags.input);
|
|
65800
66394
|
if (!inputArg || !inputArg.trim()) {
|
|
65801
66395
|
io.error(JSON.stringify({ error: "--input was given but empty \u2014 pass inline JSON `{\u2026}` or a path to a .json file" }));
|
|
65802
66396
|
return 2;
|
|
65803
66397
|
}
|
|
65804
66398
|
try {
|
|
65805
|
-
const raw = inputArg.trim().startsWith("{") ? inputArg :
|
|
66399
|
+
const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync72(inputArg.replace(/^@/, ""), "utf8");
|
|
65806
66400
|
const parsed = JSON.parse(raw);
|
|
65807
66401
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
|
|
65808
66402
|
injectedInput = parsed;
|
|
@@ -65812,7 +66406,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65812
66406
|
}
|
|
65813
66407
|
}
|
|
65814
66408
|
const DEVICE_WIDTHS = renderDeviceWidths();
|
|
65815
|
-
const deviceName =
|
|
66409
|
+
const deviceName = str6(flags.device);
|
|
65816
66410
|
let renderWidth;
|
|
65817
66411
|
if (deviceName) {
|
|
65818
66412
|
renderWidth = DEVICE_WIDTHS[deviceName.toLowerCase()];
|
|
@@ -65837,7 +66431,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65837
66431
|
} else if (typeof flags.width === "string" && flags.width) {
|
|
65838
66432
|
renderWidth = Math.round(Number(flags.width));
|
|
65839
66433
|
if (!Number.isFinite(renderWidth) || renderWidth <= 0) {
|
|
65840
|
-
io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${
|
|
66434
|
+
io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${str6(flags.width)}")` }));
|
|
65841
66435
|
return 2;
|
|
65842
66436
|
}
|
|
65843
66437
|
}
|
|
@@ -65845,13 +66439,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65845
66439
|
if (typeof flags["load-budget"] === "string" && flags["load-budget"]) {
|
|
65846
66440
|
loadBudgetMs = Number(flags["load-budget"]);
|
|
65847
66441
|
if (!Number.isFinite(loadBudgetMs) || loadBudgetMs <= 0) {
|
|
65848
|
-
io.error(JSON.stringify({ error: `--load-budget must be a positive number of ms (got "${
|
|
66442
|
+
io.error(JSON.stringify({ error: `--load-budget must be a positive number of ms (got "${str6(flags["load-budget"])}")` }));
|
|
65849
66443
|
return 2;
|
|
65850
66444
|
}
|
|
65851
66445
|
}
|
|
65852
66446
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
65853
66447
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
65854
|
-
const out = mkdtempSync4(
|
|
66448
|
+
const out = mkdtempSync4(join57(tmpdir5(), "himi-render-"));
|
|
65855
66449
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
65856
66450
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
65857
66451
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -65865,8 +66459,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
65865
66459
|
const diagnostics = (outcome.lint ?? []).find((s) => s.screenId === screenId)?.issues ?? [];
|
|
65866
66460
|
let pngFile;
|
|
65867
66461
|
let attestationPngFile;
|
|
65868
|
-
const shotPath =
|
|
65869
|
-
const pngTarget = typeof flags.png === "string" ?
|
|
66462
|
+
const shotPath = join57(dir, ".himi", "shots", `${screenId}.png`);
|
|
66463
|
+
const pngTarget = typeof flags.png === "string" ? str6(flags.png) : flags.png === true ? shotPath : void 0;
|
|
65870
66464
|
if (pngTarget && r.pngBase64) {
|
|
65871
66465
|
pngFile = writePngFile(pngTarget, r.pngBase64);
|
|
65872
66466
|
attestationPngFile = resolve47(pngTarget) === resolve47(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
|
|
@@ -66047,7 +66641,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
66047
66641
|
return report2(res.status, { wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
66048
66642
|
}
|
|
66049
66643
|
if (sub === "from-site") {
|
|
66050
|
-
const book =
|
|
66644
|
+
const book = str6(flags.book) ?? ".himi/business-book";
|
|
66051
66645
|
const logo = siteBookIcon2(book);
|
|
66052
66646
|
if (!logo) {
|
|
66053
66647
|
const absence = siteLogoAbsence2(book);
|
|
@@ -66062,7 +66656,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
66062
66656
|
return report2(res.status, { from: logo, wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
|
|
66063
66657
|
}
|
|
66064
66658
|
if (sub === "generate") {
|
|
66065
|
-
const res = await generateIcon2(dir, { glyph:
|
|
66659
|
+
const res = await generateIcon2(dir, { glyph: str6(flags.glyph), background: str6(flags.accent), derivePlay: true });
|
|
66066
66660
|
return report2(res.status, { wrote: res.wrote });
|
|
66067
66661
|
}
|
|
66068
66662
|
if (sub === "glyphs") {
|
|
@@ -66094,8 +66688,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66094
66688
|
return report2.ok ? 0 : 1;
|
|
66095
66689
|
}
|
|
66096
66690
|
if (sub === "verify") {
|
|
66097
|
-
const app =
|
|
66098
|
-
const found = await fetchReleaseManifest(client2, app,
|
|
66691
|
+
const app = str6(flags.app) ?? await appId(dir);
|
|
66692
|
+
const found = await fetchReleaseManifest(client2, app, str6(flags.release));
|
|
66099
66693
|
if ("error" in found) {
|
|
66100
66694
|
io.error(JSON.stringify(found));
|
|
66101
66695
|
return 1;
|
|
@@ -66105,9 +66699,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66105
66699
|
return report2.ok ? 0 : 1;
|
|
66106
66700
|
}
|
|
66107
66701
|
if (sub === "add" || sub === "rm") {
|
|
66108
|
-
const app =
|
|
66702
|
+
const app = str6(flags.app) ?? await appId(dir);
|
|
66109
66703
|
const { contentReleaseId: contentReleaseId2 } = await Promise.resolve().then(() => (init_build3(), build_exports2));
|
|
66110
|
-
const found = await fetchReleaseManifest(client2, app,
|
|
66704
|
+
const found = await fetchReleaseManifest(client2, app, str6(flags.release));
|
|
66111
66705
|
if ("error" in found) {
|
|
66112
66706
|
io.error(JSON.stringify(found));
|
|
66113
66707
|
return 1;
|
|
@@ -66123,7 +66717,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66123
66717
|
io.error(JSON.stringify({ error: "assets add needs a file: himi assets add <file> [--name <logical/name>]" }));
|
|
66124
66718
|
return 2;
|
|
66125
66719
|
}
|
|
66126
|
-
const { payload, record: record2, name: name2 } = addAssetPayload2(manifest, file, { name:
|
|
66720
|
+
const { payload, record: record2, name: name2 } = addAssetPayload2(manifest, file, { name: str6(flags.name), mintReleaseId: contentReleaseId2 });
|
|
66127
66721
|
const r2 = await client2().publishRelease(payload, {}, flags.live !== true);
|
|
66128
66722
|
if (!r2.ok) {
|
|
66129
66723
|
print({ ok: false, status: r2.status, body: r2.json ?? r2.text });
|
|
@@ -66192,8 +66786,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66192
66786
|
io.error(JSON.stringify({ error: "pull needs an <app>", usage: "himi pull <app> [--release <id>] [--out <dir>] [--name <new>]" }));
|
|
66193
66787
|
return 2;
|
|
66194
66788
|
}
|
|
66195
|
-
const renamed =
|
|
66196
|
-
const dest = resolve47(
|
|
66789
|
+
const renamed = str6(flags.name);
|
|
66790
|
+
const dest = resolve47(str6(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
66197
66791
|
const replace = flags.replace === true;
|
|
66198
66792
|
const force = replace || flags.force === true;
|
|
66199
66793
|
const linked = symlinkDestinationIssue(dest);
|
|
@@ -66214,7 +66808,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66214
66808
|
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" }));
|
|
66215
66809
|
return 1;
|
|
66216
66810
|
}
|
|
66217
|
-
if (replace && occupied && !existsSync60(
|
|
66811
|
+
if (replace && occupied && !existsSync60(join57(dest, "himalaya.content.json"))) {
|
|
66218
66812
|
io.error(JSON.stringify({
|
|
66219
66813
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
66220
66814
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -66222,7 +66816,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66222
66816
|
return 1;
|
|
66223
66817
|
}
|
|
66224
66818
|
}
|
|
66225
|
-
const pulled = await client2().ownerSource(wanted,
|
|
66819
|
+
const pulled = await client2().ownerSource(wanted, str6(flags.release));
|
|
66226
66820
|
if (!pulled.ok) {
|
|
66227
66821
|
io.error(JSON.stringify({ ok: false, app: wanted, status: pulled.status, ...pulled.json ?? {} }));
|
|
66228
66822
|
return 1;
|
|
@@ -66295,7 +66889,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66295
66889
|
const declared = await appId(dir);
|
|
66296
66890
|
let onlyRaw;
|
|
66297
66891
|
if (flags.only !== void 0) {
|
|
66298
|
-
onlyRaw =
|
|
66892
|
+
onlyRaw = str6(flags.only);
|
|
66299
66893
|
if (!onlyRaw) {
|
|
66300
66894
|
io.error(JSON.stringify({ error: "--only needs a selector", usage: ONLY_USAGE }));
|
|
66301
66895
|
return 2;
|
|
@@ -66317,7 +66911,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66317
66911
|
return 2;
|
|
66318
66912
|
}
|
|
66319
66913
|
}
|
|
66320
|
-
if (flags["from-release"] !== void 0 && !
|
|
66914
|
+
if (flags["from-release"] !== void 0 && !str6(flags["from-release"])) {
|
|
66321
66915
|
io.error(JSON.stringify({ ok: false, error: "from_release_needs_a_value", message: "--from-release takes a release id to branch from. Omit the flag entirely to patch the live release.", usage: ONLY_USAGE }));
|
|
66322
66916
|
return 2;
|
|
66323
66917
|
}
|
|
@@ -66327,7 +66921,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66327
66921
|
let ownerIssue;
|
|
66328
66922
|
let pushToken;
|
|
66329
66923
|
try {
|
|
66330
|
-
const t = resolveTarget({ target: pushTarget, controlToken:
|
|
66924
|
+
const t = resolveTarget({ target: pushTarget, controlToken: str6(flags["control-token"]) });
|
|
66331
66925
|
ownerIssue = t.ownerIssue;
|
|
66332
66926
|
pushToken = t.controlToken;
|
|
66333
66927
|
} catch {
|
|
@@ -66353,7 +66947,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66353
66947
|
const force = flags.force === true;
|
|
66354
66948
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66355
66949
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
66356
|
-
const out = mkdtempSync4(
|
|
66950
|
+
const out = mkdtempSync4(join57(tmpdir5(), "himi-push-"));
|
|
66357
66951
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66358
66952
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
66359
66953
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66392,7 +66986,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66392
66986
|
io.error(JSON.stringify(parsed.error, null, 2));
|
|
66393
66987
|
return 2;
|
|
66394
66988
|
}
|
|
66395
|
-
const fromRelease =
|
|
66989
|
+
const fromRelease = str6(flags["from-release"]);
|
|
66396
66990
|
const baseForPlan = await fetchReleaseManifest(client2, app, fromRelease);
|
|
66397
66991
|
if ("error" in baseForPlan) {
|
|
66398
66992
|
io.error(JSON.stringify(baseForPlan));
|
|
@@ -66441,7 +67035,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66441
67035
|
let localSourceHash;
|
|
66442
67036
|
try {
|
|
66443
67037
|
const { collectAppSource: collectAppSource2, zipAppSource: zipAppSource2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
|
|
66444
|
-
localSourceHash =
|
|
67038
|
+
localSourceHash = createHash27("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
|
|
66445
67039
|
} catch {
|
|
66446
67040
|
}
|
|
66447
67041
|
return runReleasePatch({
|
|
@@ -66460,8 +67054,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66460
67054
|
acceptPartial: flags["accept-partial"] === true,
|
|
66461
67055
|
force,
|
|
66462
67056
|
meta: {
|
|
66463
|
-
...
|
|
66464
|
-
...
|
|
67057
|
+
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
67058
|
+
...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
|
|
66465
67059
|
...hasErrors ? { forcedPastErrors: true } : {}
|
|
66466
67060
|
},
|
|
66467
67061
|
...localSourceHash ? { localSourceHash } : {},
|
|
@@ -66581,8 +67175,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66581
67175
|
if (!visArg) return 2;
|
|
66582
67176
|
const visibility = visArg.value ?? await contentVisibility(dir);
|
|
66583
67177
|
const meta = {
|
|
66584
|
-
...
|
|
66585
|
-
...
|
|
67178
|
+
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
67179
|
+
...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
|
|
66586
67180
|
...visibility ? { visibility } : {},
|
|
66587
67181
|
...attestation ? { attestation } : {},
|
|
66588
67182
|
...forcedPastErrors ? { forcedPastErrors: true } : {}
|
|
@@ -66614,7 +67208,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66614
67208
|
let adoptedSlug;
|
|
66615
67209
|
if (flags["no-claim"] !== true) {
|
|
66616
67210
|
if (ownerIssue && pushToken && !tokenCoversApp(pushToken, app)) {
|
|
66617
|
-
const claim = await autoClaimSlug({ ownerIssue, controlToken: pushToken, app, accountId:
|
|
67211
|
+
const claim = await autoClaimSlug({ ownerIssue, controlToken: pushToken, app, accountId: str6(flags["account-id"]) });
|
|
66618
67212
|
if (claim.fatal) {
|
|
66619
67213
|
io.error(JSON.stringify({
|
|
66620
67214
|
ok: false,
|
|
@@ -66791,7 +67385,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66791
67385
|
// goes. `push` hands it to a serve plane, `pack` hands it to a FILE, so an app can
|
|
66792
67386
|
// be emailed, dropped on a static host, or opened from Files with no serve at all.
|
|
66793
67387
|
case "pack": {
|
|
66794
|
-
const format =
|
|
67388
|
+
const format = str6(flags.format) ?? "zip";
|
|
66795
67389
|
if (format !== "zip" && format !== "dir") {
|
|
66796
67390
|
io.error(JSON.stringify({ error: `unknown --format ${JSON.stringify(format)}`, formats: ["zip", "dir"] }));
|
|
66797
67391
|
return 2;
|
|
@@ -66806,13 +67400,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66806
67400
|
return 2;
|
|
66807
67401
|
}
|
|
66808
67402
|
const { packRelease: packRelease2, packReleaseToDir: packReleaseToDir2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
|
|
66809
|
-
const displayName =
|
|
67403
|
+
const displayName = str6(flags.name);
|
|
66810
67404
|
const launchMode = flags.snapshot === true ? "snapshot" : "live";
|
|
66811
67405
|
const packOpts = { createdBy: `himi-cli ${cliVersion()}`, launchMode, ...displayName ? { displayName } : {} };
|
|
66812
67406
|
const writePack = (root, appName, out, source) => format === "dir" ? packReleaseToDir2(root, appName, out, packOpts) : packRelease2(root, appName, out, { ...packOpts, ...source ? { source } : {} });
|
|
66813
|
-
const releaseDir =
|
|
67407
|
+
const releaseDir = str6(flags["release-dir"]);
|
|
66814
67408
|
if (releaseDir) {
|
|
66815
|
-
const only =
|
|
67409
|
+
const only = str6(flags.app);
|
|
66816
67410
|
if (!only) {
|
|
66817
67411
|
io.error(JSON.stringify({ error: "--release-dir needs --app (a release store holds many apps)" }));
|
|
66818
67412
|
return 2;
|
|
@@ -66825,7 +67419,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66825
67419
|
return 2;
|
|
66826
67420
|
}
|
|
66827
67421
|
try {
|
|
66828
|
-
const res = writePack(resolve47(releaseDir), only, resolve47(
|
|
67422
|
+
const res = writePack(resolve47(releaseDir), only, resolve47(str6(flags.out) ?? process.cwd()));
|
|
66829
67423
|
print({
|
|
66830
67424
|
ok: true,
|
|
66831
67425
|
app: res.app,
|
|
@@ -66874,7 +67468,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66874
67468
|
}
|
|
66875
67469
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
66876
67470
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
66877
|
-
const built = mkdtempSync4(
|
|
67471
|
+
const built = mkdtempSync4(join57(tmpdir5(), "himi-pack-"));
|
|
66878
67472
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
66879
67473
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
66880
67474
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -66896,7 +67490,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66896
67490
|
return 1;
|
|
66897
67491
|
}
|
|
66898
67492
|
try {
|
|
66899
|
-
const res = writePack(built, app, resolve47(
|
|
67493
|
+
const res = writePack(built, app, resolve47(str6(flags.out) ?? dir), sourceArchive);
|
|
66900
67494
|
print({
|
|
66901
67495
|
ok: true,
|
|
66902
67496
|
app: res.app,
|
|
@@ -66964,7 +67558,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66964
67558
|
io.error(JSON.stringify({ ok: false, error: "app_source_not_in_package", detail: `${HIMI_PACKAGE_SOURCE_PATH2} is absent despite the header declaring it` }));
|
|
66965
67559
|
return 1;
|
|
66966
67560
|
}
|
|
66967
|
-
const renamed =
|
|
67561
|
+
const renamed = str6(flags.name);
|
|
66968
67562
|
const idsToCheck = renamed ? [["--name", renamed]] : [["package", opened.header.app]];
|
|
66969
67563
|
for (const [what, value] of idsToCheck) {
|
|
66970
67564
|
if (!isSafeAppId2(value)) {
|
|
@@ -66977,7 +67571,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
66977
67571
|
return 1;
|
|
66978
67572
|
}
|
|
66979
67573
|
}
|
|
66980
|
-
const dest = resolve47(
|
|
67574
|
+
const dest = resolve47(str6(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
|
|
66981
67575
|
const issue2 = restoreDestinationIssue(dest, flags.force === true);
|
|
66982
67576
|
if (issue2) {
|
|
66983
67577
|
io.error(JSON.stringify(issue2));
|
|
@@ -67041,7 +67635,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67041
67635
|
case "share": {
|
|
67042
67636
|
const sub = pos[1];
|
|
67043
67637
|
if (sub === "revoke") {
|
|
67044
|
-
const app =
|
|
67638
|
+
const app = str6(flags.app);
|
|
67045
67639
|
const shareId = pos[2];
|
|
67046
67640
|
if (!app || !shareId) {
|
|
67047
67641
|
io.error(JSON.stringify({ error: "himi share revoke needs --app <app> <shareId>" }));
|
|
@@ -67055,7 +67649,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67055
67649
|
print({ ok: true, ...result.json });
|
|
67056
67650
|
return 0;
|
|
67057
67651
|
}
|
|
67058
|
-
const file =
|
|
67652
|
+
const file = str6(flags.file);
|
|
67059
67653
|
if (!file) {
|
|
67060
67654
|
io.error(JSON.stringify({ error: "himi share needs --file <package.himi>; create it with `himi pack --out <file>`" }));
|
|
67061
67655
|
return 2;
|
|
@@ -67077,13 +67671,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67077
67671
|
}));
|
|
67078
67672
|
return 1;
|
|
67079
67673
|
}
|
|
67080
|
-
const archive =
|
|
67674
|
+
const archive = readFileSync72(resolve47(file));
|
|
67081
67675
|
const result = await client2().createPackageShare({
|
|
67082
67676
|
app: opened.header.app,
|
|
67083
67677
|
releaseId: opened.header.releaseId,
|
|
67084
67678
|
launchMode: opened.header.launchMode ?? "snapshot",
|
|
67085
67679
|
archiveBase64: archive.toString("base64"),
|
|
67086
|
-
...
|
|
67680
|
+
...str6(flags["expires-at"]) ? { expiresAt: str6(flags["expires-at"]) } : {}
|
|
67087
67681
|
});
|
|
67088
67682
|
if (!result.ok) {
|
|
67089
67683
|
print({ ok: false, status: result.status, body: result.json ?? result.text });
|
|
@@ -67116,7 +67710,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67116
67710
|
flags.content = watchedDir;
|
|
67117
67711
|
source = void 0;
|
|
67118
67712
|
}
|
|
67119
|
-
const conflict = watchFlagConflict2({ source, browser: flags.browser === true, spa:
|
|
67713
|
+
const conflict = watchFlagConflict2({ source, browser: flags.browser === true, spa: str6(flags.spa) });
|
|
67120
67714
|
if (conflict) {
|
|
67121
67715
|
io.error(JSON.stringify({ ok: false, ...conflict }));
|
|
67122
67716
|
return 2;
|
|
@@ -67124,31 +67718,62 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67124
67718
|
}
|
|
67125
67719
|
let served = null;
|
|
67126
67720
|
let servedMissing = [];
|
|
67721
|
+
const fromContent = !source;
|
|
67127
67722
|
try {
|
|
67128
67723
|
if (!source) {
|
|
67129
67724
|
const dir2 = contentDir(flags);
|
|
67130
67725
|
const app = await appId(dir2);
|
|
67131
67726
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
67132
67727
|
const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
|
|
67133
|
-
temp = mkdtempSync4(
|
|
67728
|
+
temp = mkdtempSync4(join57(tmpdir5(), "himi-run-build-"));
|
|
67134
67729
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
67135
67730
|
const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
|
|
67136
67731
|
servedMissing = initial.missingBundles;
|
|
67137
|
-
source =
|
|
67732
|
+
source = join57(temp, app);
|
|
67138
67733
|
}
|
|
67139
|
-
const chromeArg =
|
|
67734
|
+
const chromeArg = str6(flags.chrome) ?? "preview";
|
|
67140
67735
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
67141
67736
|
io.error(JSON.stringify({ error: `unknown --chrome ${JSON.stringify(chromeArg)}`, values: ["preview", "app"] }));
|
|
67142
67737
|
return 2;
|
|
67143
67738
|
}
|
|
67144
67739
|
let port;
|
|
67145
67740
|
if (flags.port !== void 0) {
|
|
67146
|
-
port = Number(
|
|
67741
|
+
port = Number(str6(flags.port));
|
|
67147
67742
|
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
67148
|
-
io.error(JSON.stringify({ error: `--port needs a number 0-65535, got ${JSON.stringify(
|
|
67743
|
+
io.error(JSON.stringify({ error: `--port needs a number 0-65535, got ${JSON.stringify(str6(flags.port) ?? "")}` }));
|
|
67149
67744
|
return 2;
|
|
67150
67745
|
}
|
|
67151
67746
|
}
|
|
67747
|
+
const dir = contentDir(flags);
|
|
67748
|
+
const refreshBoard = async () => {
|
|
67749
|
+
if (!boardOpen(dir)) return;
|
|
67750
|
+
const { refreshStudio: refreshStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
67751
|
+
refreshStudio2(dir);
|
|
67752
|
+
};
|
|
67753
|
+
const recordKit = fromContent ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
67754
|
+
let recorded = false;
|
|
67755
|
+
let startedAt = "";
|
|
67756
|
+
const record2 = (served2, build2) => {
|
|
67757
|
+
try {
|
|
67758
|
+
if (recordKit?.writeRunRecord(dir, { url: served2.url, port: served2.port, pid: process.pid, startedAt, watching: watch2, build: build2 })) recorded = true;
|
|
67759
|
+
return null;
|
|
67760
|
+
} catch (e) {
|
|
67761
|
+
return e.message;
|
|
67762
|
+
}
|
|
67763
|
+
};
|
|
67764
|
+
const announce = async (served2) => {
|
|
67765
|
+
if (!recordKit) return;
|
|
67766
|
+
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
67767
|
+
const failure = record2(served2, { ok: true, at: startedAt });
|
|
67768
|
+
if (!recorded) io.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${join57(dir, ".himi")} is not a real directory`}, so the build board will not frame this preview.` }));
|
|
67769
|
+
await refreshBoard();
|
|
67770
|
+
};
|
|
67771
|
+
const retract = async () => {
|
|
67772
|
+
if (!recorded) return;
|
|
67773
|
+
recorded = false;
|
|
67774
|
+
recordKit?.removeRunRecord(dir, process.pid);
|
|
67775
|
+
await refreshBoard();
|
|
67776
|
+
};
|
|
67152
67777
|
if (flags.browser === true) {
|
|
67153
67778
|
const { runInBrowser: runInBrowser2 } = await Promise.resolve().then(() => (init_run_browser(), run_browser_exports));
|
|
67154
67779
|
const { resolvePackage: resolvePackage2 } = await Promise.resolve().then(() => (init_run(), run_exports));
|
|
@@ -67158,61 +67783,51 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67158
67783
|
chrome: chromeArg,
|
|
67159
67784
|
open: flags["no-open"] !== true
|
|
67160
67785
|
});
|
|
67786
|
+
await announce(run2);
|
|
67161
67787
|
print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
|
|
67162
67788
|
await new Promise((resolve48) => {
|
|
67163
67789
|
const stop = () => {
|
|
67164
|
-
void run2.close().finally(() => resolve48());
|
|
67790
|
+
void retract().catch((e) => io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }))).finally(() => run2.close().finally(() => resolve48()));
|
|
67165
67791
|
};
|
|
67166
67792
|
process.once("SIGINT", stop);
|
|
67167
67793
|
process.once("SIGTERM", stop);
|
|
67168
67794
|
});
|
|
67169
67795
|
return 0;
|
|
67170
67796
|
}
|
|
67171
|
-
const dir = contentDir(flags);
|
|
67172
67797
|
const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
|
|
67173
67798
|
const bus = watchKit ? new watchKit.ReloadBus() : void 0;
|
|
67174
|
-
if (watch2) served = mkdtempSync4(
|
|
67799
|
+
if (watch2) served = mkdtempSync4(join57(tmpdir5(), "himi-run-served-"));
|
|
67175
67800
|
const running = await runPackage2(source, {
|
|
67176
67801
|
port,
|
|
67177
67802
|
chrome: chromeArg,
|
|
67178
|
-
screen:
|
|
67179
|
-
surface:
|
|
67180
|
-
spa:
|
|
67803
|
+
screen: str6(flags.screen),
|
|
67804
|
+
surface: str6(flags.surface),
|
|
67805
|
+
spa: str6(flags.spa),
|
|
67181
67806
|
open: flags["no-open"] !== true,
|
|
67182
|
-
|
|
67807
|
+
// The build board on the preview's own origin, for any run of this content package.
|
|
67808
|
+
...recordKit ? { extraRoutes: (request) => recordKit.boardFile(dir, new URL(request.url).pathname) } : {},
|
|
67809
|
+
...watchKit && served && bus ? { workDir: served, screenEvents: bus } : {}
|
|
67183
67810
|
});
|
|
67184
67811
|
let watcher;
|
|
67185
67812
|
let rebuild;
|
|
67186
|
-
let recorded = false;
|
|
67187
67813
|
let stopping = false;
|
|
67188
|
-
|
|
67189
|
-
|
|
67190
|
-
|
|
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();
|
|
67814
|
+
try {
|
|
67815
|
+
await announce(running);
|
|
67816
|
+
if (watchKit && bus) {
|
|
67202
67817
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
67203
|
-
const live2 =
|
|
67204
|
-
const manifestOf = (tree) => JSON.parse(
|
|
67818
|
+
const live2 = join57(running.releaseRoot, running.app);
|
|
67819
|
+
const manifestOf = (tree) => JSON.parse(readFileSync72(join57(tree, "release-manifest.json"), "utf8"));
|
|
67205
67820
|
let current = manifestOf(live2);
|
|
67206
67821
|
const failed2 = async (message) => {
|
|
67207
67822
|
if (stopping) return;
|
|
67208
67823
|
bus.publish("build.failed", { message });
|
|
67209
|
-
record2({ ok: false, at: (/* @__PURE__ */ new Date()).toISOString(), error: message });
|
|
67824
|
+
record2(running, { ok: false, at: (/* @__PURE__ */ new Date()).toISOString(), error: message });
|
|
67210
67825
|
await refreshBoard();
|
|
67211
67826
|
io.error(JSON.stringify({ watch: "build_failed", keptLastGood: true, message }));
|
|
67212
67827
|
};
|
|
67213
67828
|
rebuild = watchKit.serialize(async () => {
|
|
67214
67829
|
const t0 = Date.now();
|
|
67215
|
-
const next = mkdtempSync4(
|
|
67830
|
+
const next = mkdtempSync4(join57(tmpdir5(), "himi-run-build-"));
|
|
67216
67831
|
try {
|
|
67217
67832
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
67218
67833
|
if (bres.compileErrors.length) {
|
|
@@ -67229,20 +67844,20 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67229
67844
|
return;
|
|
67230
67845
|
}
|
|
67231
67846
|
if (stopping) return;
|
|
67232
|
-
const fresh = manifestOf(
|
|
67847
|
+
const fresh = manifestOf(join57(next, running.app));
|
|
67233
67848
|
const diff = watchKit.diffReleases(current, fresh);
|
|
67234
67849
|
const retired = `${live2}.retired-${Date.now()}`;
|
|
67235
67850
|
renameSync6(live2, retired);
|
|
67236
67851
|
try {
|
|
67237
|
-
renameSync6(
|
|
67852
|
+
renameSync6(join57(next, running.app), live2);
|
|
67238
67853
|
} catch {
|
|
67239
|
-
cpSync3(
|
|
67854
|
+
cpSync3(join57(next, running.app), live2, { recursive: true });
|
|
67240
67855
|
}
|
|
67241
67856
|
rmSync13(retired, { recursive: true, force: true });
|
|
67242
67857
|
current = fresh;
|
|
67243
67858
|
servedMissing = outcome.missingBundles;
|
|
67244
67859
|
for (const [event, data] of watchKit.reloadEvents(diff)) bus.publish(event, data);
|
|
67245
|
-
record2({ ok: true, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
67860
|
+
record2(running, { ok: true, at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
67246
67861
|
await refreshBoard();
|
|
67247
67862
|
io.error(JSON.stringify({ watch: "rebuilt", ms: Date.now() - t0, screens: diff.screens, tokens: diff.tokens, config: diff.config, tabs: bus.listeners }));
|
|
67248
67863
|
} catch (e) {
|
|
@@ -67252,11 +67867,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67252
67867
|
}
|
|
67253
67868
|
});
|
|
67254
67869
|
watcher = watchKit.watchContent(dir, () => rebuild?.());
|
|
67255
|
-
} catch (e) {
|
|
67256
|
-
if (recorded) watchKit.removeRunRecord(dir);
|
|
67257
|
-
await running.close();
|
|
67258
|
-
throw e;
|
|
67259
67870
|
}
|
|
67871
|
+
} catch (e) {
|
|
67872
|
+
await retract().catch(() => {
|
|
67873
|
+
});
|
|
67874
|
+
await running.close();
|
|
67875
|
+
throw e;
|
|
67260
67876
|
}
|
|
67261
67877
|
print({
|
|
67262
67878
|
ok: true,
|
|
@@ -67264,7 +67880,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67264
67880
|
releaseId: running.releaseId,
|
|
67265
67881
|
url: running.url,
|
|
67266
67882
|
port: running.port,
|
|
67267
|
-
...watch2 ? { watching: dir
|
|
67883
|
+
...watch2 ? { watching: dir } : {},
|
|
67884
|
+
...recordKit && boardOpen(dir) ? { board: `${running.origin}/__himi/studio/` } : {},
|
|
67268
67885
|
...running.warnings.length ? { warnings: running.warnings } : {},
|
|
67269
67886
|
stop: "Ctrl-C"
|
|
67270
67887
|
});
|
|
@@ -67274,12 +67891,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67274
67891
|
watcher?.close();
|
|
67275
67892
|
try {
|
|
67276
67893
|
await rebuild?.stop();
|
|
67277
|
-
|
|
67278
|
-
watchKit?.removeRunRecord(dir);
|
|
67279
|
-
await refreshBoard();
|
|
67280
|
-
}
|
|
67894
|
+
await retract();
|
|
67281
67895
|
} catch (e) {
|
|
67282
|
-
io.error(JSON.stringify({
|
|
67896
|
+
io.error(JSON.stringify({ run: "stop_cleanup_failed", message: e.message }));
|
|
67283
67897
|
} finally {
|
|
67284
67898
|
await running.close();
|
|
67285
67899
|
done();
|
|
@@ -67298,15 +67912,15 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67298
67912
|
}
|
|
67299
67913
|
}
|
|
67300
67914
|
case "preview": {
|
|
67301
|
-
const app =
|
|
67302
|
-
const release =
|
|
67915
|
+
const app = str6(flags.app);
|
|
67916
|
+
const release = str6(flags.release);
|
|
67303
67917
|
if (!app || !release) {
|
|
67304
67918
|
io.error(JSON.stringify({ error: "preview needs --app and --release" }));
|
|
67305
67919
|
return 2;
|
|
67306
67920
|
}
|
|
67307
67921
|
const base = serveBase();
|
|
67308
|
-
const screen =
|
|
67309
|
-
const surface =
|
|
67922
|
+
const screen = str6(flags.screen);
|
|
67923
|
+
const surface = str6(flags.surface);
|
|
67310
67924
|
if (surface && !surfaceById(surface)) {
|
|
67311
67925
|
io.error(JSON.stringify({
|
|
67312
67926
|
error: `unknown --surface "${surface}"`,
|
|
@@ -67314,22 +67928,22 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67314
67928
|
}));
|
|
67315
67929
|
return 2;
|
|
67316
67930
|
}
|
|
67317
|
-
let previewToken =
|
|
67931
|
+
let previewToken = str6(flags["preview-token"]);
|
|
67318
67932
|
let previewTokenExpiresAt;
|
|
67319
67933
|
let previewHandover;
|
|
67320
67934
|
let mintedHere = false;
|
|
67321
67935
|
let mintFailure;
|
|
67322
67936
|
if (!previewToken) {
|
|
67323
67937
|
const target = resolveTarget({
|
|
67324
|
-
target:
|
|
67938
|
+
target: str6(flags.target),
|
|
67325
67939
|
// Same default as `client()` (#2483.1) — without it this resolved a DIFFERENT target
|
|
67326
67940
|
// than the request that follows, so off-repo the mint was attempted against `local`.
|
|
67327
67941
|
defaultTarget: contextualDefaultTarget,
|
|
67328
|
-
serveUrl:
|
|
67329
|
-
telemetryUrl:
|
|
67330
|
-
controlUrl:
|
|
67331
|
-
telemetryToken:
|
|
67332
|
-
controlToken:
|
|
67942
|
+
serveUrl: str6(flags["serve-url"]),
|
|
67943
|
+
telemetryUrl: str6(flags["telemetry-url"]),
|
|
67944
|
+
controlUrl: str6(flags["control-url"]),
|
|
67945
|
+
telemetryToken: str6(flags["telemetry-token"]),
|
|
67946
|
+
controlToken: str6(flags["control-token"])
|
|
67333
67947
|
});
|
|
67334
67948
|
if (!target.controlToken) {
|
|
67335
67949
|
mintFailure = `this target has no stored control credential, so none was requested \u2014 run \`himi login --target ${targetName()}\`, or pass --control-token`;
|
|
@@ -67390,8 +68004,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67390
68004
|
case "surfaces": {
|
|
67391
68005
|
const dir = contentDir(flags);
|
|
67392
68006
|
const platforms = readLocalPlatforms(dir);
|
|
67393
|
-
const app =
|
|
67394
|
-
const release =
|
|
68007
|
+
const app = str6(flags.app);
|
|
68008
|
+
const release = str6(flags.release);
|
|
67395
68009
|
const base = serveBase();
|
|
67396
68010
|
const withLinks = !!(app && release && base);
|
|
67397
68011
|
const produced = flags["measure-widgets"] === true ? await producedWidgetFamilies(dir) : { families: void 0, source: "not-measured" };
|
|
@@ -67443,16 +68057,16 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67443
68057
|
return 0;
|
|
67444
68058
|
}
|
|
67445
68059
|
case "context": {
|
|
67446
|
-
const app =
|
|
67447
|
-
const release =
|
|
68060
|
+
const app = str6(flags.app);
|
|
68061
|
+
const release = str6(flags.release);
|
|
67448
68062
|
if (!app || !release) {
|
|
67449
68063
|
io.error(JSON.stringify({ error: "context needs --app and --release" }));
|
|
67450
68064
|
return 2;
|
|
67451
68065
|
}
|
|
67452
|
-
const include =
|
|
68066
|
+
const include = str6(flags.include);
|
|
67453
68067
|
let r;
|
|
67454
68068
|
try {
|
|
67455
|
-
r = await client2().previewContext(app, release, { screen:
|
|
68069
|
+
r = await client2().previewContext(app, release, { screen: str6(flags.screen), include });
|
|
67456
68070
|
} catch (e) {
|
|
67457
68071
|
io.error(JSON.stringify({
|
|
67458
68072
|
error: `cannot reach serve for context: ${e.message}. Pass --target bo.`,
|
|
@@ -67467,8 +68081,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67467
68081
|
}
|
|
67468
68082
|
case "app-docs": {
|
|
67469
68083
|
const subcommand = pos[1] ?? "list";
|
|
67470
|
-
const app =
|
|
67471
|
-
const release =
|
|
68084
|
+
const app = str6(flags.app);
|
|
68085
|
+
const release = str6(flags.release) ?? str6(flags.releaseId);
|
|
67472
68086
|
if (!app) {
|
|
67473
68087
|
io.error(JSON.stringify({ error: "app-docs needs --app" }));
|
|
67474
68088
|
return 2;
|
|
@@ -67496,15 +68110,15 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67496
68110
|
return 0;
|
|
67497
68111
|
}
|
|
67498
68112
|
case "telemetry": {
|
|
67499
|
-
const app =
|
|
67500
|
-
const release =
|
|
68113
|
+
const app = str6(flags.app);
|
|
68114
|
+
const release = str6(flags.release) ?? str6(flags.releaseId);
|
|
67501
68115
|
if (!app || !release) {
|
|
67502
68116
|
io.error(JSON.stringify({ error: "telemetry needs --app and --release" }));
|
|
67503
68117
|
return 2;
|
|
67504
68118
|
}
|
|
67505
68119
|
const c = client2();
|
|
67506
68120
|
const target = targetName();
|
|
67507
|
-
const level =
|
|
68121
|
+
const level = str6(flags.level);
|
|
67508
68122
|
const byLevel = (ls) => level ? ls.filter((l) => l.level === level) : ls;
|
|
67509
68123
|
const includeEvents = flags["no-events"] !== true;
|
|
67510
68124
|
const includeLogs = flags["no-logs"] !== true;
|
|
@@ -67519,8 +68133,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67519
68133
|
if (includeEvents) {
|
|
67520
68134
|
const r = await c.telemetryEvents(app, {
|
|
67521
68135
|
releaseId: release,
|
|
67522
|
-
screenId:
|
|
67523
|
-
event:
|
|
68136
|
+
screenId: str6(flags.screen) ?? str6(flags.screenId),
|
|
68137
|
+
event: str6(flags.type) ?? str6(flags.event),
|
|
67524
68138
|
since: eventSince,
|
|
67525
68139
|
limit: num2(flags.limit),
|
|
67526
68140
|
crashesOnly: flags["crashes-only"] === true || flags.crashesOnly === true
|
|
@@ -67533,7 +68147,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67533
68147
|
if (includeLogs) {
|
|
67534
68148
|
const r = await c.telemetryLogs(app, {
|
|
67535
68149
|
releaseId: release,
|
|
67536
|
-
screenId:
|
|
68150
|
+
screenId: str6(flags.screen) ?? str6(flags.screenId),
|
|
67537
68151
|
since: logSince,
|
|
67538
68152
|
limit: num2(flags.limit)
|
|
67539
68153
|
});
|
|
@@ -67555,7 +68169,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67555
68169
|
}
|
|
67556
68170
|
const eventCount = out.events?.length ?? 0;
|
|
67557
68171
|
const logCount = out.logs?.length ?? 0;
|
|
67558
|
-
const narrowed = !!(level ||
|
|
68172
|
+
const narrowed = !!(level || str6(flags.screen) || str6(flags.screenId) || str6(flags.type) || str6(flags.event) || flags["crashes-only"] === true || flags.crashesOnly === true || num2(flags.limit) !== void 0 || eventSince !== void 0 || logSince !== void 0);
|
|
67559
68173
|
const wholeChannels = includeEvents && includeLogs && !narrowed;
|
|
67560
68174
|
if (wholeChannels && eventCount === 0 && logCount === 0 && !includeSummary && !includeCrashes) {
|
|
67561
68175
|
out.note = "no events and no worker console output on this release \u2014 open the web preview or Himi Player link for it, then retry or use --follow";
|
|
@@ -67599,8 +68213,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67599
68213
|
}
|
|
67600
68214
|
}
|
|
67601
68215
|
case "screens": {
|
|
67602
|
-
const app =
|
|
67603
|
-
const release =
|
|
68216
|
+
const app = str6(flags.app);
|
|
68217
|
+
const release = str6(flags.release);
|
|
67604
68218
|
if (!app || !release) {
|
|
67605
68219
|
io.error(JSON.stringify({ error: "screens needs --app and --release" }));
|
|
67606
68220
|
return 2;
|
|
@@ -67621,8 +68235,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67621
68235
|
}
|
|
67622
68236
|
case "diagnose": {
|
|
67623
68237
|
const screenId = pos[1];
|
|
67624
|
-
const app =
|
|
67625
|
-
const release =
|
|
68238
|
+
const app = str6(flags.app);
|
|
68239
|
+
const release = str6(flags.release);
|
|
67626
68240
|
if (!screenId || !app || !release) {
|
|
67627
68241
|
io.error(JSON.stringify({ error: "diagnose needs <screenId> --app --release" }));
|
|
67628
68242
|
return 2;
|
|
@@ -67647,8 +68261,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67647
68261
|
return body.ok === false ? 1 : 0;
|
|
67648
68262
|
}
|
|
67649
68263
|
case "deeplinks": {
|
|
67650
|
-
const app =
|
|
67651
|
-
const release =
|
|
68264
|
+
const app = str6(flags.app);
|
|
68265
|
+
const release = str6(flags.release);
|
|
67652
68266
|
if (!app || !release) {
|
|
67653
68267
|
io.error(JSON.stringify({ error: "deeplinks needs --app and --release" }));
|
|
67654
68268
|
return 2;
|
|
@@ -67668,13 +68282,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67668
68282
|
return 0;
|
|
67669
68283
|
}
|
|
67670
68284
|
case "logs": {
|
|
67671
|
-
const app =
|
|
68285
|
+
const app = str6(flags.app);
|
|
67672
68286
|
if (!app) {
|
|
67673
68287
|
io.error(JSON.stringify({ error: "logs needs --app" }));
|
|
67674
68288
|
return 2;
|
|
67675
68289
|
}
|
|
67676
|
-
const release =
|
|
67677
|
-
const level =
|
|
68290
|
+
const release = str6(flags.release);
|
|
68291
|
+
const level = str6(flags.level);
|
|
67678
68292
|
const byLevel = (ls) => level ? ls.filter((l) => l.level === level) : ls;
|
|
67679
68293
|
const num3 = (v) => typeof v === "string" && v ? Number(v) : void 0;
|
|
67680
68294
|
const c = client2();
|
|
@@ -67683,7 +68297,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67683
68297
|
try {
|
|
67684
68298
|
r = await c.telemetryLogs(app, {
|
|
67685
68299
|
releaseId: release,
|
|
67686
|
-
screenId:
|
|
68300
|
+
screenId: str6(flags.screen) ?? str6(flags.screenId),
|
|
67687
68301
|
since: num3(flags.since),
|
|
67688
68302
|
limit: num3(flags.limit)
|
|
67689
68303
|
});
|
|
@@ -67701,7 +68315,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67701
68315
|
}
|
|
67702
68316
|
const rawLogs = r.json?.logs ?? [];
|
|
67703
68317
|
const logs = byLevel(rawLogs);
|
|
67704
|
-
const narrowed = !!(level ||
|
|
68318
|
+
const narrowed = !!(level || str6(flags.screen) || str6(flags.screenId) || num3(flags.since) !== void 0 || num3(flags.limit) !== void 0);
|
|
67705
68319
|
const scope = release ? "this release" : "this app";
|
|
67706
68320
|
const note = logs.length > 0 ? void 0 : narrowed ? `no worker \`console.*\` lines matched this query${level && rawLogs.length ? ` (${rawLogs.length} line(s) were hidden by --level ${level})` : ""}. Drop --level/--screen/--since/--limit to see the whole console channel for ${scope}; the telemetry EVENT stream is a separate channel, read with \`himi telemetry\`.` : `no worker \`console.*\` output on ${scope}. This is the console channel \u2014 distinct from the telemetry EVENT stream, which \`himi telemetry --app <app> --release <id>\` reads: ${scope} can carry many events and no console lines \u2014 commonly because the worker never logged any, though an empty channel can also mean the lines aged out or never made it through ingestion. Boot-time \`console.log\` is visible via \`himi validate\` / \`himi render\`.`;
|
|
67707
68321
|
print({ ok: true, logs, ...note ? { note } : {} });
|
|
@@ -67711,7 +68325,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67711
68325
|
const deadline = num3(flags.for) !== void 0 ? Date.now() + num3(flags.for) : Infinity;
|
|
67712
68326
|
let since = num3(flags.since) ?? 0;
|
|
67713
68327
|
for (; ; ) {
|
|
67714
|
-
const r = await c.telemetryLogs(app, { releaseId: release, screenId:
|
|
68328
|
+
const r = await c.telemetryLogs(app, { releaseId: release, screenId: str6(flags.screen) ?? str6(flags.screenId), since });
|
|
67715
68329
|
if (r.ok) {
|
|
67716
68330
|
const logs = r.json?.logs ?? [];
|
|
67717
68331
|
for (const l of byLevel(logs)) io.log(JSON.stringify(l));
|
|
@@ -67722,8 +68336,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67722
68336
|
}
|
|
67723
68337
|
}
|
|
67724
68338
|
case "promote": {
|
|
67725
|
-
const app =
|
|
67726
|
-
const release =
|
|
68339
|
+
const app = str6(flags.app);
|
|
68340
|
+
const release = str6(flags.release);
|
|
67727
68341
|
if (!app || !release) {
|
|
67728
68342
|
io.error(JSON.stringify({ error: "promote needs --app and --release" }));
|
|
67729
68343
|
return 2;
|
|
@@ -67731,7 +68345,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67731
68345
|
const target = targetName();
|
|
67732
68346
|
const force = flags.force === true;
|
|
67733
68347
|
const ringGiven = flags.ring !== void 0;
|
|
67734
|
-
const ring =
|
|
68348
|
+
const ring = str6(flags.ring);
|
|
67735
68349
|
if (ringGiven && !ring) {
|
|
67736
68350
|
io.error(JSON.stringify({ error: "--ring needs a ring name, e.g. --ring ga" }));
|
|
67737
68351
|
return 2;
|
|
@@ -67829,8 +68443,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67829
68443
|
}));
|
|
67830
68444
|
return 2;
|
|
67831
68445
|
}
|
|
67832
|
-
const app =
|
|
67833
|
-
const file =
|
|
68446
|
+
const app = str6(flags.app) ?? await appId(contentDir(flags));
|
|
68447
|
+
const file = str6(flags.file);
|
|
67834
68448
|
if (!file) {
|
|
67835
68449
|
io.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
67836
68450
|
return 2;
|
|
@@ -67841,7 +68455,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67841
68455
|
}
|
|
67842
68456
|
const draft = patchBlastRadius(PATCH_USAGE);
|
|
67843
68457
|
if (draft === null) return 2;
|
|
67844
|
-
const notes =
|
|
68458
|
+
const notes = str6(flags.notes);
|
|
67845
68459
|
if (!draft && (kind === "screen" || kind === "app-config") && !notes) {
|
|
67846
68460
|
io.error(JSON.stringify({
|
|
67847
68461
|
ok: false,
|
|
@@ -67852,11 +68466,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67852
68466
|
}));
|
|
67853
68467
|
return 2;
|
|
67854
68468
|
}
|
|
67855
|
-
if (flags["from-release"] !== void 0 && !
|
|
68469
|
+
if (flags["from-release"] !== void 0 && !str6(flags["from-release"])) {
|
|
67856
68470
|
io.error(JSON.stringify({ ok: false, error: "from_release_needs_a_value", message: "--from-release takes a release id to branch from. Omit the flag entirely to patch the live release.", usage: PATCH_USAGE }));
|
|
67857
68471
|
return 2;
|
|
67858
68472
|
}
|
|
67859
|
-
const fromRelease =
|
|
68473
|
+
const fromRelease = str6(flags["from-release"]);
|
|
67860
68474
|
const baseOrRefuse = (manifest) => {
|
|
67861
68475
|
if (manifest) return true;
|
|
67862
68476
|
io.error(JSON.stringify({
|
|
@@ -67874,7 +68488,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67874
68488
|
const patchGitSha = defaultGitOps2(contentDir(flags)).shortSha() ?? "dev";
|
|
67875
68489
|
const meta = {
|
|
67876
68490
|
gitSha: patchGitSha,
|
|
67877
|
-
...
|
|
68491
|
+
...str6(flags.label) ? { label: str6(flags.label) } : {},
|
|
67878
68492
|
...notes ? { notes } : {}
|
|
67879
68493
|
};
|
|
67880
68494
|
const common = {
|
|
@@ -67891,7 +68505,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67891
68505
|
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."
|
|
67892
68506
|
};
|
|
67893
68507
|
if (kind === "tokens" || kind === "app-config") {
|
|
67894
|
-
const body =
|
|
68508
|
+
const body = readFileSync72(file, "utf8");
|
|
67895
68509
|
const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
|
|
67896
68510
|
return runReleasePatch({
|
|
67897
68511
|
...common,
|
|
@@ -67906,7 +68520,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67906
68520
|
io.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
|
|
67907
68521
|
return 2;
|
|
67908
68522
|
}
|
|
67909
|
-
const descriptor =
|
|
68523
|
+
const descriptor = readFileSync72(file, "utf8");
|
|
67910
68524
|
try {
|
|
67911
68525
|
JSON.parse(descriptor);
|
|
67912
68526
|
} catch (e) {
|
|
@@ -67935,7 +68549,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67935
68549
|
io.error(JSON.stringify({ ok: false, error: "bundle_flag_needs_a_value", message: "--bundle takes a bundle sha256, or the literal `none` to unbind the screen.", usage: PATCH_USAGE }));
|
|
67936
68550
|
return 2;
|
|
67937
68551
|
}
|
|
67938
|
-
const bundleFlag =
|
|
68552
|
+
const bundleFlag = str6(flags.bundle);
|
|
67939
68553
|
const bundle = bundleFlag === "none" ? null : bundleFlag;
|
|
67940
68554
|
if (!baseOrRefuse(baseFound.manifest)) return 1;
|
|
67941
68555
|
return runReleasePatch({
|
|
@@ -67946,9 +68560,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
67946
68560
|
extra: { kind, screen: id, file: { path: file, bytes: Buffer.byteLength(descriptor, "utf8") } }
|
|
67947
68561
|
});
|
|
67948
68562
|
}
|
|
67949
|
-
const bytes2 =
|
|
67950
|
-
const sha =
|
|
67951
|
-
const forScreens = (
|
|
68563
|
+
const bytes2 = readFileSync72(file);
|
|
68564
|
+
const sha = createHash27("sha256").update(bytes2).digest("hex");
|
|
68565
|
+
const forScreens = (str6(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
67952
68566
|
if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
|
|
67953
68567
|
io.error(JSON.stringify({ ok: false, error: "no_rebind_takes_no_value", message: "--no-rebind is a switch and takes no value; pass it bare.", usage: PATCH_USAGE }));
|
|
67954
68568
|
return 2;
|
|
@@ -68037,7 +68651,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68037
68651
|
// READ of the device-facing door, and what that read says is what gets printed.
|
|
68038
68652
|
case "flags": {
|
|
68039
68653
|
const sub = pos[1];
|
|
68040
|
-
const app =
|
|
68654
|
+
const app = str6(flags.app) ?? await appId(contentDir(flags));
|
|
68041
68655
|
const usage = "usage: himi flags list | set <key> --definition <json|@file> | ramp <key> [--percent 0-100] [--enabled true|false] | rm <key>";
|
|
68042
68656
|
if (sub !== "list" && sub !== "set" && sub !== "ramp" && sub !== "rm") {
|
|
68043
68657
|
io.error(JSON.stringify({ error: `unknown flags subcommand: ${sub ?? "(none)"}`, hint: usage }));
|
|
@@ -68083,14 +68697,14 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68083
68697
|
return 2;
|
|
68084
68698
|
}
|
|
68085
68699
|
if (sub === "set") {
|
|
68086
|
-
const arg =
|
|
68700
|
+
const arg = str6(flags.definition);
|
|
68087
68701
|
if (!arg) {
|
|
68088
68702
|
io.error(JSON.stringify({ error: "flags set needs --definition <json|@file>", hint: usage }));
|
|
68089
68703
|
return 2;
|
|
68090
68704
|
}
|
|
68091
68705
|
let def;
|
|
68092
68706
|
try {
|
|
68093
|
-
const parsed = JSON.parse(arg.startsWith("@") ?
|
|
68707
|
+
const parsed = JSON.parse(arg.startsWith("@") ? readFileSync72(arg.slice(1), "utf8") : arg);
|
|
68094
68708
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
68095
68709
|
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}`] }));
|
|
68096
68710
|
return 2;
|
|
@@ -68135,7 +68749,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68135
68749
|
return 2;
|
|
68136
68750
|
}
|
|
68137
68751
|
const enabledGiven = flags.enabled !== void 0;
|
|
68138
|
-
const enabledRaw = flags.enabled === true ? "true" :
|
|
68752
|
+
const enabledRaw = flags.enabled === true ? "true" : str6(flags.enabled);
|
|
68139
68753
|
if (enabledGiven && enabledRaw !== "true" && enabledRaw !== "false") {
|
|
68140
68754
|
io.error(JSON.stringify({ error: `--enabled must be true or false, got ${String(flags.enabled)}` }));
|
|
68141
68755
|
return 2;
|
|
@@ -68213,7 +68827,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68213
68827
|
io.error(JSON.stringify({ error: `visibility takes public|unlisted (got "${value}")` }));
|
|
68214
68828
|
return 2;
|
|
68215
68829
|
}
|
|
68216
|
-
const app =
|
|
68830
|
+
const app = str6(flags.app) ?? await appId(contentDir(flags));
|
|
68217
68831
|
let r;
|
|
68218
68832
|
try {
|
|
68219
68833
|
r = value === void 0 ? await client2().appSettings(app) : await client2().setVisibility(app, value);
|
|
@@ -68235,8 +68849,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
68235
68849
|
// a minBinaryVersion floor bump.
|
|
68236
68850
|
case "store":
|
|
68237
68851
|
case "testflight": {
|
|
68238
|
-
if (
|
|
68239
|
-
const playerTarget = wixPlayerTestflightTarget(
|
|
68852
|
+
if (str6(flags.provider) === "wix-mobile-release") {
|
|
68853
|
+
const playerTarget = wixPlayerTestflightTarget(str6(flags.target));
|
|
68240
68854
|
if (!playerTarget) {
|
|
68241
68855
|
io.error(JSON.stringify({ error: "Wix Mobile Release requires deployed --target bo or --target prod; local/custom targets cannot hold the Himi service identity" }));
|
|
68242
68856
|
return 2;
|
|
@@ -68470,8 +69084,8 @@ ${label2}`);
|
|
|
68470
69084
|
io.error(JSON.stringify({ error: "dist watch needs a <jobId>" }));
|
|
68471
69085
|
return 2;
|
|
68472
69086
|
}
|
|
68473
|
-
const intervalMs2 = Number(
|
|
68474
|
-
const deadline2 = Date.now() + (Number(
|
|
69087
|
+
const intervalMs2 = Number(str6(flags.interval)) || 2e4;
|
|
69088
|
+
const deadline2 = Date.now() + (Number(str6(flags.timeout)) || 45 * 6e4);
|
|
68475
69089
|
let announced = false;
|
|
68476
69090
|
for (; ; ) {
|
|
68477
69091
|
let s;
|
|
@@ -68513,14 +69127,14 @@ ${label2}`);
|
|
|
68513
69127
|
}
|
|
68514
69128
|
}
|
|
68515
69129
|
if (sub === "list") {
|
|
68516
|
-
const app2 =
|
|
69130
|
+
const app2 = str6(flags.app) ?? await appId(contentDir(flags));
|
|
68517
69131
|
if (!app2) {
|
|
68518
69132
|
io.error(JSON.stringify({ error: "dist list needs --app" }));
|
|
68519
69133
|
return 2;
|
|
68520
69134
|
}
|
|
68521
69135
|
let r2;
|
|
68522
69136
|
try {
|
|
68523
|
-
r2 = await c.distList(app2, Number(
|
|
69137
|
+
r2 = await c.distList(app2, Number(str6(flags.limit)) || void 0);
|
|
68524
69138
|
} catch (e) {
|
|
68525
69139
|
return distUnreachable(e);
|
|
68526
69140
|
}
|
|
@@ -68546,15 +69160,15 @@ ${label2}`);
|
|
|
68546
69160
|
io.error(JSON.stringify({ error: `unknown dist subcommand "${sub}" \u2014 use status | watch | list | cancel, or no subcommand to start a build` }));
|
|
68547
69161
|
return 2;
|
|
68548
69162
|
}
|
|
68549
|
-
const app =
|
|
69163
|
+
const app = str6(flags.app) ?? await appId(contentDir(flags));
|
|
68550
69164
|
if (!app) {
|
|
68551
69165
|
io.error(JSON.stringify({ error: "dist needs --app (or a content dir whose himalaya.content.json names one)" }));
|
|
68552
69166
|
return 2;
|
|
68553
69167
|
}
|
|
68554
|
-
const platform =
|
|
69168
|
+
const platform = str6(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
68555
69169
|
{
|
|
68556
69170
|
const distDir = contentDir(flags);
|
|
68557
|
-
if (existsSync60(
|
|
69171
|
+
if (existsSync60(join57(distDir, "himalaya.content.json"))) {
|
|
68558
69172
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
68559
69173
|
const errors = issues.filter((i) => i.severity === "error");
|
|
68560
69174
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|
|
@@ -68572,31 +69186,31 @@ ${label2}`);
|
|
|
68572
69186
|
}
|
|
68573
69187
|
}
|
|
68574
69188
|
const { captchaContentInput: captchaContentInput2 } = await Promise.resolve().then(() => (init_captcha2(), captcha_exports));
|
|
68575
|
-
const captchaSiteId =
|
|
69189
|
+
const captchaSiteId = str6(flags.site) ?? captchaContentInput2(contentDir(flags)).siteId;
|
|
68576
69190
|
let r;
|
|
68577
69191
|
try {
|
|
68578
69192
|
r = await c.distCreate({
|
|
68579
69193
|
app,
|
|
68580
69194
|
...platform?.length ? { platform } : {},
|
|
68581
|
-
...
|
|
69195
|
+
...str6(flags.release) ? { release: str6(flags.release) } : {},
|
|
68582
69196
|
...flags["allow-draft"] === true ? { allowDraft: true } : {},
|
|
68583
69197
|
...captchaSiteId ? { captchaSiteId } : {},
|
|
68584
|
-
...
|
|
69198
|
+
...str6(flags.shell) ? { shell: str6(flags.shell) } : {},
|
|
68585
69199
|
// INTERIM, iOS only: sign under an internal enterprise id the Mac pool already holds a
|
|
68586
69200
|
// profile for, because no profile covers a himi shell's own id yet. The serve plane
|
|
68587
69201
|
// refuses anything outside its allow-list (internal `ent.*` only — never a store id).
|
|
68588
69202
|
// flags["borrow-ios-id"], NOT flags.borrowIosId — parseFlags does no kebab→camel
|
|
68589
69203
|
// conversion (see line ~58), so the camel form reads undefined and the flag would be a
|
|
68590
69204
|
// silent no-op. Every other multi-word flag here uses the bracket form for the same reason.
|
|
68591
|
-
...
|
|
68592
|
-
...
|
|
68593
|
-
...
|
|
69205
|
+
...str6(flags["borrow-ios-id"]) ? { borrowIosBundleId: str6(flags["borrow-ios-id"]) } : {},
|
|
69206
|
+
...str6(flags.destination) ? { destination: str6(flags.destination) } : {},
|
|
69207
|
+
...str6(flags.signing) ? { signing: str6(flags.signing) } : {},
|
|
68594
69208
|
// WHICH KEYSTORE signs the APK. A separate axis from --signing (that one is the Apple
|
|
68595
69209
|
// account), so a `--platform ios,android` build can say "Wix-managed on iOS, the QA
|
|
68596
69210
|
// keystore on Android" — the normal combination — with one command.
|
|
68597
69211
|
// flags["android-signing"], NOT flags.androidSigning: parseFlags does no kebab→camel
|
|
68598
69212
|
// conversion, so the camel form reads undefined and the flag is a silent no-op.
|
|
68599
|
-
...
|
|
69213
|
+
...str6(flags["android-signing"]) ? { androidSigning: str6(flags["android-signing"]) } : {}
|
|
68600
69214
|
});
|
|
68601
69215
|
} catch (e) {
|
|
68602
69216
|
return distUnreachable(e);
|
|
@@ -68611,14 +69225,14 @@ ${label2}`);
|
|
|
68611
69225
|
if (noWait) {
|
|
68612
69226
|
print({ status: r.status, ...r.json ?? {} });
|
|
68613
69227
|
if (!flags.json) {
|
|
68614
|
-
const t =
|
|
69228
|
+
const t = str6(flags.target);
|
|
68615
69229
|
const targetArg = t ? ` --target ${t}` : "";
|
|
68616
69230
|
for (const j of jobs) io.log(` ${j.platform} ${j.jobId} \u2192 himi dist status ${j.jobId}${targetArg}`);
|
|
68617
69231
|
}
|
|
68618
69232
|
return 0;
|
|
68619
69233
|
}
|
|
68620
|
-
const intervalMs = Number(
|
|
68621
|
-
const timeoutMs = Number(
|
|
69234
|
+
const intervalMs = Number(str6(flags.interval)) || 2e4;
|
|
69235
|
+
const timeoutMs = Number(str6(flags.timeout)) || 45 * 6e4;
|
|
68622
69236
|
const deadline = Date.now() + timeoutMs;
|
|
68623
69237
|
const pending = new Map(jobs.map((j) => [String(j.jobId), String(j.platform)]));
|
|
68624
69238
|
const done = [];
|
|
@@ -68660,7 +69274,7 @@ ${label2}`);
|
|
|
68660
69274
|
let issue2;
|
|
68661
69275
|
let ownerIssue;
|
|
68662
69276
|
try {
|
|
68663
|
-
const t = resolveTarget({ target, issueUrl:
|
|
69277
|
+
const t = resolveTarget({ target, issueUrl: str6(flags["issue-url"]), ownerIssueUrl: str6(flags["owner-issue-url"]) });
|
|
68664
69278
|
issue2 = t.issue;
|
|
68665
69279
|
ownerIssue = t.ownerIssue;
|
|
68666
69280
|
} catch (e) {
|
|
@@ -68823,7 +69437,7 @@ ${label2}`);
|
|
|
68823
69437
|
const dpxPath = dpxSessionTokenPath();
|
|
68824
69438
|
let dpx;
|
|
68825
69439
|
try {
|
|
68826
|
-
dpx =
|
|
69440
|
+
dpx = readFileSync72(dpxPath, "utf8").trim();
|
|
68827
69441
|
} catch {
|
|
68828
69442
|
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` }));
|
|
68829
69443
|
return 1;
|
|
@@ -68859,7 +69473,7 @@ ${label2}`);
|
|
|
68859
69473
|
const target = targetName();
|
|
68860
69474
|
let ownerIssue;
|
|
68861
69475
|
try {
|
|
68862
|
-
ownerIssue = resolveTarget({ target, ownerIssueUrl:
|
|
69476
|
+
ownerIssue = resolveTarget({ target, ownerIssueUrl: str6(flags["owner-issue-url"]) }).ownerIssue;
|
|
68863
69477
|
} catch (e) {
|
|
68864
69478
|
io.error(JSON.stringify({ error: e.message }));
|
|
68865
69479
|
return 2;
|
|
@@ -68875,10 +69489,10 @@ ${label2}`);
|
|
|
68875
69489
|
}
|
|
68876
69490
|
const base = ownerIssue.replace(/\/$/, "");
|
|
68877
69491
|
const sub = pos[1];
|
|
68878
|
-
const cookie =
|
|
69492
|
+
const cookie = str6(flags.cookie) ?? process.env.HIMI_WIX_COOKIE;
|
|
68879
69493
|
let ownerToken;
|
|
68880
69494
|
try {
|
|
68881
|
-
ownerToken = resolveTarget({ target, controlToken:
|
|
69495
|
+
ownerToken = resolveTarget({ target, controlToken: str6(flags["control-token"]) }).controlToken;
|
|
68882
69496
|
} catch {
|
|
68883
69497
|
}
|
|
68884
69498
|
if (!cookie && !ownerToken) {
|
|
@@ -68898,9 +69512,9 @@ ${label2}`);
|
|
|
68898
69512
|
return 2;
|
|
68899
69513
|
}
|
|
68900
69514
|
const body = { slug };
|
|
68901
|
-
const dn =
|
|
69515
|
+
const dn = str6(flags["display-name"]);
|
|
68902
69516
|
if (dn) body.displayName = dn;
|
|
68903
|
-
const acct =
|
|
69517
|
+
const acct = str6(flags["account-id"]);
|
|
68904
69518
|
if (acct) body.accountId = acct;
|
|
68905
69519
|
const r2 = await fetch(`${base}/v1/owner/apps/claim`, { method: "POST", redirect: "error", headers: { ...headers2, "content-type": "application/json" }, body: JSON.stringify(body) });
|
|
68906
69520
|
const j2 = await r2.json().catch(() => ({}));
|
|
@@ -69020,8 +69634,8 @@ ${label2}`);
|
|
|
69020
69634
|
try {
|
|
69021
69635
|
const t = resolveTarget({
|
|
69022
69636
|
target,
|
|
69023
|
-
controlUrl:
|
|
69024
|
-
controlToken:
|
|
69637
|
+
controlUrl: str6(flags["control-url"]),
|
|
69638
|
+
controlToken: str6(flags["control-token"])
|
|
69025
69639
|
});
|
|
69026
69640
|
if (t.controlToken && t.control) {
|
|
69027
69641
|
const revokeRefusal = credentialHostRefusal(t.control);
|
|
@@ -69099,8 +69713,8 @@ ${label2}`);
|
|
|
69099
69713
|
}
|
|
69100
69714
|
case "doctor": {
|
|
69101
69715
|
const target = targetName();
|
|
69102
|
-
const timeoutMs = Number(
|
|
69103
|
-
const dataUrl =
|
|
69716
|
+
const timeoutMs = Number(str6(flags.timeout)) > 0 ? Number(str6(flags.timeout)) : DOCTOR_TIMEOUT_MS;
|
|
69717
|
+
const dataUrl = str6(flags["data-url"]) ?? process.env.HIMI_DATA_URL ?? PUBLIC_WIX_API_BASE;
|
|
69104
69718
|
let resolved2;
|
|
69105
69719
|
let serveUrl = "";
|
|
69106
69720
|
let targetError;
|
|
@@ -69110,9 +69724,9 @@ ${label2}`);
|
|
|
69110
69724
|
// Passing `str(flags.target)` re-ran resolution without `defaultTarget`, so off-repo
|
|
69111
69725
|
// doctor labelled its report `wix` while probing the `local` URLs.
|
|
69112
69726
|
target,
|
|
69113
|
-
serveUrl:
|
|
69114
|
-
controlUrl:
|
|
69115
|
-
controlToken:
|
|
69727
|
+
serveUrl: str6(flags["serve-url"]),
|
|
69728
|
+
controlUrl: str6(flags["control-url"]),
|
|
69729
|
+
controlToken: str6(flags["control-token"])
|
|
69116
69730
|
});
|
|
69117
69731
|
serveUrl = resolved2.serve;
|
|
69118
69732
|
} catch (e) {
|
|
@@ -69216,7 +69830,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69216
69830
|
const { BO_FUNCTIONS_BASE_URL: BO_FUNCTIONS_BASE_URL2, resolveFunctionsTarget: resolveFunctionsTarget2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
69217
69831
|
let secretTarget;
|
|
69218
69832
|
try {
|
|
69219
|
-
secretTarget = resolveFunctionsTarget2({ target:
|
|
69833
|
+
secretTarget = resolveFunctionsTarget2({ target: str6(flags.target), functionsUrl: str6(flags["functions-url"]), releaseId: str6(flags.release) });
|
|
69220
69834
|
} catch (error) {
|
|
69221
69835
|
io.error(JSON.stringify({ error: error.message }));
|
|
69222
69836
|
return 1;
|
|
@@ -69225,7 +69839,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69225
69839
|
const path2 = dpxSessionTokenPath();
|
|
69226
69840
|
let raw;
|
|
69227
69841
|
try {
|
|
69228
|
-
raw =
|
|
69842
|
+
raw = readFileSync72(path2, "utf8");
|
|
69229
69843
|
} catch {
|
|
69230
69844
|
io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
|
|
69231
69845
|
return 1;
|
|
@@ -69269,20 +69883,20 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69269
69883
|
let site;
|
|
69270
69884
|
let call;
|
|
69271
69885
|
try {
|
|
69272
|
-
site = resolveSiteId(
|
|
69886
|
+
site = resolveSiteId(str6(flags.site));
|
|
69273
69887
|
call = ownerTransport(site);
|
|
69274
69888
|
} catch (error) {
|
|
69275
69889
|
io.error(JSON.stringify({ error: error.message }));
|
|
69276
69890
|
return 2;
|
|
69277
69891
|
}
|
|
69278
|
-
const environment2 =
|
|
69892
|
+
const environment2 = str6(flags.environment) ?? "preview";
|
|
69279
69893
|
if (environment2 !== "preview" && environment2 !== "production") {
|
|
69280
69894
|
io.error(JSON.stringify({ error: "--environment must be preview or production" }));
|
|
69281
69895
|
return 2;
|
|
69282
69896
|
}
|
|
69283
69897
|
let kv;
|
|
69284
69898
|
if (data.kv?.length) {
|
|
69285
|
-
const baseUrl =
|
|
69899
|
+
const baseUrl = str6(flags["data-url"]) ?? process.env.HIMI_DATA_ADMIN_URL;
|
|
69286
69900
|
const token = process.env.HIMI_DATA_ADMIN_TOKEN;
|
|
69287
69901
|
if (!baseUrl || !token) {
|
|
69288
69902
|
io.error(JSON.stringify({ error: "KV declarations require --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN for the operator data plane", app, site, environment: environment2 }));
|
|
@@ -69354,7 +69968,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69354
69968
|
return 1;
|
|
69355
69969
|
}
|
|
69356
69970
|
if (sub === "seed" && flags.ai === true) {
|
|
69357
|
-
const res = await writeSeedRows({ app, cms, dir, count: Number(
|
|
69971
|
+
const res = await writeSeedRows({ app, cms, dir, count: Number(str6(flags.count)) || 8 });
|
|
69358
69972
|
print(res);
|
|
69359
69973
|
return res.ok ? 0 : 1;
|
|
69360
69974
|
}
|
|
@@ -69371,7 +69985,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69371
69985
|
let call;
|
|
69372
69986
|
let site;
|
|
69373
69987
|
try {
|
|
69374
|
-
site = resolveSiteId(
|
|
69988
|
+
site = resolveSiteId(str6(flags.site));
|
|
69375
69989
|
call = ownerTransport(site);
|
|
69376
69990
|
} catch (e) {
|
|
69377
69991
|
io.error(JSON.stringify({ error: e.message }));
|
|
@@ -69380,7 +69994,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69380
69994
|
const common = { app, cms, call };
|
|
69381
69995
|
let report2;
|
|
69382
69996
|
try {
|
|
69383
|
-
report2 = sub === "query" ? await queryCms({ ...common, all: flags.all === true }) : sub === "create" ? await createCms({ ...common, dryRun: flags["dry-run"] === true, allowDestructive: flags["allow-destructive"] === true, applyPermissions: flags["apply-permissions"] === true }) : await seedCms({ ...common, dir, dryRun: flags["dry-run"] === true, force: flags.force === true, only:
|
|
69997
|
+
report2 = sub === "query" ? await queryCms({ ...common, all: flags.all === true }) : sub === "create" ? await createCms({ ...common, dryRun: flags["dry-run"] === true, allowDestructive: flags["allow-destructive"] === true, applyPermissions: flags["apply-permissions"] === true }) : await seedCms({ ...common, dir, dryRun: flags["dry-run"] === true, force: flags.force === true, only: str6(flags.only) });
|
|
69384
69998
|
} catch (e) {
|
|
69385
69999
|
const partial = e.partial;
|
|
69386
70000
|
io.error(JSON.stringify({
|
|
@@ -69403,17 +70017,17 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69403
70017
|
const r = await runSiteFunctionCli2({
|
|
69404
70018
|
op: pos[2],
|
|
69405
70019
|
name: pos[3],
|
|
69406
|
-
siteFlag:
|
|
69407
|
-
siteUrl:
|
|
69408
|
-
clientId:
|
|
69409
|
-
method:
|
|
69410
|
-
sourcePath:
|
|
69411
|
-
bodyRaw:
|
|
70020
|
+
siteFlag: str6(flags.site),
|
|
70021
|
+
siteUrl: str6(flags.url) ?? str6(flags["site-url"]) ?? process.env.WIX_SITE_URL,
|
|
70022
|
+
clientId: str6(flags["client-id"]) ?? process.env.WIX_CLIENT_ID,
|
|
70023
|
+
method: str6(flags.method),
|
|
70024
|
+
sourcePath: str6(flags.source),
|
|
70025
|
+
bodyRaw: str6(flags.body),
|
|
69412
70026
|
publish: flags.publish === true,
|
|
69413
70027
|
invoke: flags.invoke === true,
|
|
69414
70028
|
dryRun: flags["dry-run"] === true,
|
|
69415
70029
|
visitor: flags.visitor === true,
|
|
69416
|
-
cwd:
|
|
70030
|
+
cwd: str6(flags.content) ?? process.cwd()
|
|
69417
70031
|
});
|
|
69418
70032
|
print(r);
|
|
69419
70033
|
return r.ok ? 0 : 1;
|
|
@@ -69435,17 +70049,17 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69435
70049
|
}
|
|
69436
70050
|
try {
|
|
69437
70051
|
const r = op === "list" ? await runSiteClientList2({
|
|
69438
|
-
siteFlag:
|
|
69439
|
-
redirectUri:
|
|
70052
|
+
siteFlag: str6(flags.site),
|
|
70053
|
+
redirectUri: str6(flags["redirect-uri"])
|
|
69440
70054
|
}) : await runSiteClientEnsure2({
|
|
69441
|
-
siteFlag:
|
|
69442
|
-
name:
|
|
69443
|
-
redirectUri:
|
|
70055
|
+
siteFlag: str6(flags.site),
|
|
70056
|
+
name: str6(flags.name),
|
|
70057
|
+
redirectUri: str6(flags["redirect-uri"]),
|
|
69444
70058
|
new: flags.new === true,
|
|
69445
70059
|
yes: flags.yes === true,
|
|
69446
70060
|
// Bare `--write-provisioning` is the default path; with a value it is that path.
|
|
69447
|
-
writeProvisioning: flags["write-provisioning"] === true ? true :
|
|
69448
|
-
siteUrl:
|
|
70061
|
+
writeProvisioning: flags["write-provisioning"] === true ? true : str6(flags["write-provisioning"]),
|
|
70062
|
+
siteUrl: str6(flags["site-url"]) ?? str6(flags.url)
|
|
69449
70063
|
});
|
|
69450
70064
|
print(r);
|
|
69451
70065
|
return r.ok ? 0 : 1;
|
|
@@ -69468,15 +70082,15 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69468
70082
|
try {
|
|
69469
70083
|
const r = sub === "list" ? await runSiteList2() : await runSiteCreate2({
|
|
69470
70084
|
name: pos[2],
|
|
69471
|
-
type:
|
|
69472
|
-
templateId:
|
|
69473
|
-
verticals:
|
|
69474
|
-
folderId:
|
|
69475
|
-
redirectUri:
|
|
70085
|
+
type: str6(flags.type),
|
|
70086
|
+
templateId: str6(flags.template),
|
|
70087
|
+
verticals: str6(flags.verticals),
|
|
70088
|
+
folderId: str6(flags.folder),
|
|
70089
|
+
redirectUri: str6(flags["redirect-uri"]),
|
|
69476
70090
|
noOauthApp: flags["no-oauth-app"] === true,
|
|
69477
70091
|
// Bare `--write-provisioning` is the default path; with a value it is that path.
|
|
69478
|
-
writeProvisioning: flags["write-provisioning"] === true ? true :
|
|
69479
|
-
siteUrl:
|
|
70092
|
+
writeProvisioning: flags["write-provisioning"] === true ? true : str6(flags["write-provisioning"]),
|
|
70093
|
+
siteUrl: str6(flags["site-url"]),
|
|
69480
70094
|
yes: flags.yes === true,
|
|
69481
70095
|
// The argv as typed, so the dry run echoes back a command that actually
|
|
69482
70096
|
// recreates THIS plan. Reconstructing it from the fields above would
|
|
@@ -69495,14 +70109,14 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69495
70109
|
io.error(JSON.stringify({ error: sub ? `unknown site subcommand "${sub}"` : "site needs a subcommand", usage: `himi site create <name> [--type wix|headless|branded-app|vibe] --yes | himi site list | himi site client ensure|list --site <msid> | himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply [--shell <id>]] | himi site function list|get|put|publish|invoke \u2026` }));
|
|
69496
70110
|
return 2;
|
|
69497
70111
|
}
|
|
69498
|
-
const clientId =
|
|
69499
|
-
const siteUrl =
|
|
70112
|
+
const clientId = str6(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
|
|
70113
|
+
const siteUrl = str6(flags.url) ?? str6(flags["site-url"]);
|
|
69500
70114
|
if (flags["read-only"] === true) {
|
|
69501
70115
|
if (flags.apply || flags.out || flags.shell || flags["redirect-uri"]) {
|
|
69502
70116
|
io.error(JSON.stringify({ error: "--read-only returns API context only; it cannot be combined with --apply, --out, --shell, or --redirect-uri" }));
|
|
69503
70117
|
return 2;
|
|
69504
70118
|
}
|
|
69505
|
-
const siteId =
|
|
70119
|
+
const siteId = str6(flags.site) ?? process.env.WIX_SITE_ID;
|
|
69506
70120
|
if (!clientId && !siteId && !process.env.WIX_TEST_TOKEN?.trim()) {
|
|
69507
70121
|
io.error(JSON.stringify({ error: "--read-only needs --site, --client-id, or a site-scoped WIX_TEST_TOKEN" }));
|
|
69508
70122
|
return 2;
|
|
@@ -69544,16 +70158,16 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
|
|
|
69544
70158
|
const r = await runSiteAnalyze2({
|
|
69545
70159
|
clientId,
|
|
69546
70160
|
siteUrl,
|
|
69547
|
-
siteFlag:
|
|
69548
|
-
outDir:
|
|
70161
|
+
siteFlag: str6(flags.site),
|
|
70162
|
+
outDir: str6(flags.out),
|
|
69549
70163
|
apply: flags.apply === true,
|
|
69550
|
-
shell:
|
|
70164
|
+
shell: str6(flags.shell),
|
|
69551
70165
|
// A redirect already REGISTERED on --client-id, recorded into the applied binding.
|
|
69552
70166
|
// Analyze cannot discover it (GET-only; the registered list lives behind
|
|
69553
70167
|
// `oauth-app/v1`), and the shell refuses to reuse its own default once a customer
|
|
69554
70168
|
// client is in play — so it is passed in by whoever registered it.
|
|
69555
|
-
redirectUri:
|
|
69556
|
-
cwd:
|
|
70169
|
+
redirectUri: str6(flags["redirect-uri"]),
|
|
70170
|
+
cwd: str6(flags.content) ?? process.cwd()
|
|
69557
70171
|
});
|
|
69558
70172
|
print({ ok: true, ...r });
|
|
69559
70173
|
return 0;
|