@wix/himalaya-cli 0.807.0 → 0.809.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +963 -325
- package/guides/himi-test.md +46 -1
- package/guides/release-notes.md +68 -0
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -1014,7 +1014,7 @@ function sentinelizeIdentity(body, identity) {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
if (identity.name) {
|
|
1016
1016
|
const re = new RegExp(`\\b(${NAME_FIELDS.join("|")})(["']?\\s*[:=]\\s*)(["'])${escapeRe(identity.name)}\\3`, "g");
|
|
1017
|
-
out = out.replace(re, (_m, key2,
|
|
1017
|
+
out = out.replace(re, (_m, key2, sep11, q) => `${key2}${sep11}${q}__HIMI_APP_NAME__${q}`);
|
|
1018
1018
|
}
|
|
1019
1019
|
return out;
|
|
1020
1020
|
}
|
|
@@ -2496,8 +2496,8 @@ var init_splash = __esm({
|
|
|
2496
2496
|
|
|
2497
2497
|
// ../../core/dev-server/tier5-bundles-src/build-lib.mjs
|
|
2498
2498
|
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
2499
|
-
import { dirname as dirname8, resolve as resolve8 } from "node:path";
|
|
2500
|
-
import { readdirSync as readdirSync6, existsSync as existsSync8, readFileSync as readFileSync10 } from "node:fs";
|
|
2499
|
+
import { dirname as dirname8, join as join12, resolve as resolve8, sep as sep2 } from "node:path";
|
|
2500
|
+
import { readdirSync as readdirSync6, existsSync as existsSync8, readFileSync as readFileSync10, realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
2501
2501
|
async function loadCompiler() {
|
|
2502
2502
|
try {
|
|
2503
2503
|
const nativeCompiler = ["es", "build"].join("");
|
|
@@ -2530,6 +2530,259 @@ function isOffRepo() {
|
|
|
2530
2530
|
if (process.env.HIMI_OFF_REPO === "1") return true;
|
|
2531
2531
|
return !existsSync8(alias["@himalaya/state"]);
|
|
2532
2532
|
}
|
|
2533
|
+
function buildConfinementRequired() {
|
|
2534
|
+
return _confinementRequired;
|
|
2535
|
+
}
|
|
2536
|
+
function realpathOrSelf(p) {
|
|
2537
|
+
try {
|
|
2538
|
+
return realpathSync2(resolve8(p));
|
|
2539
|
+
} catch {
|
|
2540
|
+
return resolve8(p);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
function isUnder(p, root) {
|
|
2544
|
+
return p === root || p.startsWith(root + sep2);
|
|
2545
|
+
}
|
|
2546
|
+
function confinementRoots(contentRoot) {
|
|
2547
|
+
const roots = /* @__PURE__ */ new Set();
|
|
2548
|
+
const add = (p) => {
|
|
2549
|
+
if (!p) return;
|
|
2550
|
+
roots.add(realpathOrSelf(p));
|
|
2551
|
+
roots.add(resolve8(p));
|
|
2552
|
+
};
|
|
2553
|
+
const real = realpathOrSelf(contentRoot);
|
|
2554
|
+
add(real);
|
|
2555
|
+
for (let d = real, up; ; d = up) {
|
|
2556
|
+
add(join12(d, "node_modules"));
|
|
2557
|
+
up = dirname8(d);
|
|
2558
|
+
if (up === d) break;
|
|
2559
|
+
}
|
|
2560
|
+
add(process.env.HIMI_AUTHORING_RUNTIME_DIR);
|
|
2561
|
+
add(process.env.HIMI_CLI_RUNTIME_DIR);
|
|
2562
|
+
if (!isOffRepo()) add(REPO_ROOT4);
|
|
2563
|
+
return [...roots];
|
|
2564
|
+
}
|
|
2565
|
+
function confinementMatcher(contentRoot, extraRoots = []) {
|
|
2566
|
+
const roots = [...confinementRoots(contentRoot), ...extraRoots.filter(Boolean).flatMap((r) => [realpathOrSelf(r), resolve8(r)])];
|
|
2567
|
+
let linked;
|
|
2568
|
+
const linkedRoots = () => {
|
|
2569
|
+
if (linked) return linked;
|
|
2570
|
+
linked = [];
|
|
2571
|
+
const scanned = /* @__PURE__ */ new Set();
|
|
2572
|
+
const queue = [...roots];
|
|
2573
|
+
const CAP3 = 4096;
|
|
2574
|
+
const take = (abs) => {
|
|
2575
|
+
const target = realpathOrSelf(abs);
|
|
2576
|
+
if (scanned.has(target) || linked.length >= CAP3) return;
|
|
2577
|
+
linked.push(target);
|
|
2578
|
+
queue.push(target);
|
|
2579
|
+
};
|
|
2580
|
+
while (queue.length && linked.length < CAP3) {
|
|
2581
|
+
const r = queue.shift();
|
|
2582
|
+
for (const nm of [r, join12(r, "node_modules")]) {
|
|
2583
|
+
if (scanned.has(nm)) continue;
|
|
2584
|
+
scanned.add(nm);
|
|
2585
|
+
let entries;
|
|
2586
|
+
try {
|
|
2587
|
+
entries = readdirSync6(nm, { withFileTypes: true });
|
|
2588
|
+
} catch {
|
|
2589
|
+
continue;
|
|
2590
|
+
}
|
|
2591
|
+
for (const e of entries) {
|
|
2592
|
+
const abs = join12(nm, e.name);
|
|
2593
|
+
if (e.isSymbolicLink()) take(abs);
|
|
2594
|
+
else if (e.isDirectory() && e.name.startsWith("@")) {
|
|
2595
|
+
let scoped;
|
|
2596
|
+
try {
|
|
2597
|
+
scoped = readdirSync6(abs, { withFileTypes: true });
|
|
2598
|
+
} catch {
|
|
2599
|
+
continue;
|
|
2600
|
+
}
|
|
2601
|
+
for (const sc of scoped) if (sc.isSymbolicLink()) take(join12(abs, sc.name));
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
return linked;
|
|
2607
|
+
};
|
|
2608
|
+
return (p) => {
|
|
2609
|
+
const direct = resolve8(p);
|
|
2610
|
+
if (roots.some((r) => isUnder(direct, r))) return true;
|
|
2611
|
+
const real = realpathOrSelf(direct);
|
|
2612
|
+
if (real !== direct && roots.some((r) => isUnder(real, r))) return true;
|
|
2613
|
+
return linkedRoots().some((r) => isUnder(real, r) || isUnder(direct, r));
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2616
|
+
function confinementPlugin(contentRoot) {
|
|
2617
|
+
const allows = confinementMatcher(contentRoot);
|
|
2618
|
+
return {
|
|
2619
|
+
name: "himalaya-confine-import-graph",
|
|
2620
|
+
setup(b) {
|
|
2621
|
+
b.onResolve({ filter: /^[./]/ }, (args) => {
|
|
2622
|
+
const base = args.path.startsWith("/") ? args.path : args.resolveDir ? resolve8(args.resolveDir, args.path) : void 0;
|
|
2623
|
+
if (!base || allows(base)) return void 0;
|
|
2624
|
+
return {
|
|
2625
|
+
errors: [{
|
|
2626
|
+
text: `refused to resolve ${args.path}: it is outside this content package. A worker or app config may import files from its own package, the Himalaya SDK, and its installed dependencies \u2014 nothing else.`
|
|
2627
|
+
}]
|
|
2628
|
+
};
|
|
2629
|
+
});
|
|
2630
|
+
b.onLoad({ filter: /.*/ }, (args) => {
|
|
2631
|
+
if (args.namespace && args.namespace !== "file") return void 0;
|
|
2632
|
+
if (allows(args.path)) return void 0;
|
|
2633
|
+
return {
|
|
2634
|
+
errors: [{
|
|
2635
|
+
text: `refused to read ${args.path}: it is outside this content package. A worker or app config may import files from its own package, the Himalaya SDK, and its installed dependencies \u2014 nothing else.`
|
|
2636
|
+
}]
|
|
2637
|
+
};
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
function assertConfinedTsconfig(entry, contentRoot, allows) {
|
|
2643
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2644
|
+
const refuse = (p, why) => {
|
|
2645
|
+
throw new Error(
|
|
2646
|
+
`refused to read ${p}: ${why}. A tsconfig may extend a file from its own package or an installed dependency \u2014 nothing else.`
|
|
2647
|
+
);
|
|
2648
|
+
};
|
|
2649
|
+
const stripJsonc = (text2) => {
|
|
2650
|
+
if (text2.charCodeAt(0) === 65279) text2 = text2.slice(1);
|
|
2651
|
+
let out = "";
|
|
2652
|
+
let inStr = false;
|
|
2653
|
+
let esc = false;
|
|
2654
|
+
for (let i = 0; i < text2.length; i++) {
|
|
2655
|
+
const c = text2[i];
|
|
2656
|
+
if (inStr) {
|
|
2657
|
+
out += c;
|
|
2658
|
+
if (esc) esc = false;
|
|
2659
|
+
else if (c === "\\") esc = true;
|
|
2660
|
+
else if (c === '"') inStr = false;
|
|
2661
|
+
continue;
|
|
2662
|
+
}
|
|
2663
|
+
if (c === '"') {
|
|
2664
|
+
inStr = true;
|
|
2665
|
+
out += c;
|
|
2666
|
+
continue;
|
|
2667
|
+
}
|
|
2668
|
+
if (c === "/" && text2[i + 1] === "/") {
|
|
2669
|
+
while (i < text2.length && text2[i] !== "\n") i++;
|
|
2670
|
+
continue;
|
|
2671
|
+
}
|
|
2672
|
+
if (c === "/" && text2[i + 1] === "*") {
|
|
2673
|
+
i += 2;
|
|
2674
|
+
while (i < text2.length && !(text2[i] === "*" && text2[i + 1] === "/")) i++;
|
|
2675
|
+
i++;
|
|
2676
|
+
continue;
|
|
2677
|
+
}
|
|
2678
|
+
if (c === "}" || c === "]") {
|
|
2679
|
+
const trimmed = out.replace(/\s+$/, "");
|
|
2680
|
+
if (trimmed.endsWith(",")) out = trimmed.slice(0, -1);
|
|
2681
|
+
}
|
|
2682
|
+
out += c;
|
|
2683
|
+
}
|
|
2684
|
+
return out;
|
|
2685
|
+
};
|
|
2686
|
+
const isFile = (p) => {
|
|
2687
|
+
try {
|
|
2688
|
+
return statSync2(p).isFile();
|
|
2689
|
+
} catch {
|
|
2690
|
+
return false;
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
const asConfigFile = (t) => {
|
|
2694
|
+
if (isFile(t)) return t;
|
|
2695
|
+
const inDir = join12(t, "tsconfig.json");
|
|
2696
|
+
if (isFile(inDir)) return inDir;
|
|
2697
|
+
if (isFile(`${t}.json`)) return `${t}.json`;
|
|
2698
|
+
return t;
|
|
2699
|
+
};
|
|
2700
|
+
const resolveBare = (spec, fromDir) => {
|
|
2701
|
+
for (let d = fromDir, up; ; d = up) {
|
|
2702
|
+
const base = join12(d, "node_modules", spec);
|
|
2703
|
+
for (const cand of [base, `${base}.json`]) if (isFile(cand)) return cand;
|
|
2704
|
+
const pj = join12(base, "package.json");
|
|
2705
|
+
if (isFile(pj)) {
|
|
2706
|
+
let manifest;
|
|
2707
|
+
try {
|
|
2708
|
+
manifest = JSON.parse(stripJsonc(readFileSync10(pj, "utf8")));
|
|
2709
|
+
} catch {
|
|
2710
|
+
refuse(pj, "its package.json could not be parsed, so its `tsconfig` field cannot be checked");
|
|
2711
|
+
}
|
|
2712
|
+
const field = manifest?.tsconfig;
|
|
2713
|
+
if (typeof field === "string" && field) {
|
|
2714
|
+
return asConfigFile(field.startsWith("/") ? field : resolve8(base, field));
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
if (isFile(join12(base, "tsconfig.json"))) return join12(base, "tsconfig.json");
|
|
2718
|
+
up = dirname8(d);
|
|
2719
|
+
if (up === d) return void 0;
|
|
2720
|
+
}
|
|
2721
|
+
};
|
|
2722
|
+
const follow = (file) => {
|
|
2723
|
+
const real = realpathOrSelf(file);
|
|
2724
|
+
if (seen.has(real)) return;
|
|
2725
|
+
seen.add(real);
|
|
2726
|
+
if (!allows(real)) refuse(file, "it is outside this content package");
|
|
2727
|
+
let raw;
|
|
2728
|
+
try {
|
|
2729
|
+
raw = readFileSync10(real, "utf8");
|
|
2730
|
+
} catch {
|
|
2731
|
+
return;
|
|
2732
|
+
}
|
|
2733
|
+
let parsed;
|
|
2734
|
+
try {
|
|
2735
|
+
parsed = JSON.parse(stripJsonc(raw));
|
|
2736
|
+
} catch {
|
|
2737
|
+
refuse(file, "its tsconfig could not be parsed, so its `extends` cannot be checked");
|
|
2738
|
+
}
|
|
2739
|
+
const ext = parsed?.extends;
|
|
2740
|
+
for (const one of Array.isArray(ext) ? ext : ext ? [ext] : []) {
|
|
2741
|
+
if (typeof one !== "string" || !one) continue;
|
|
2742
|
+
if (one.startsWith(".") || one.startsWith("/")) {
|
|
2743
|
+
const target = asConfigFile(one.startsWith("/") ? one : resolve8(dirname8(real), one));
|
|
2744
|
+
if (target) follow(target);
|
|
2745
|
+
} else {
|
|
2746
|
+
const target = resolveBare(one, dirname8(real));
|
|
2747
|
+
if (target) follow(target);
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
};
|
|
2751
|
+
const scan = (dir) => {
|
|
2752
|
+
let entries;
|
|
2753
|
+
try {
|
|
2754
|
+
entries = readdirSync6(dir, { withFileTypes: true });
|
|
2755
|
+
} catch {
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2758
|
+
for (const e of entries) {
|
|
2759
|
+
const abs = join12(dir, e.name);
|
|
2760
|
+
if (e.isDirectory()) scan(abs);
|
|
2761
|
+
else if (e.name === "tsconfig.json" && e.isFile()) follow(abs);
|
|
2762
|
+
}
|
|
2763
|
+
};
|
|
2764
|
+
scan(realpathOrSelf(contentRoot));
|
|
2765
|
+
for (let d = dirname8(realpathOrSelf(entry)), up; ; d = up) {
|
|
2766
|
+
const cfg = join12(d, "tsconfig.json");
|
|
2767
|
+
if (existsSync8(cfg)) {
|
|
2768
|
+
follow(cfg);
|
|
2769
|
+
return;
|
|
2770
|
+
}
|
|
2771
|
+
up = dirname8(d);
|
|
2772
|
+
if (up === d) return;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
function confinementFor(contentRoot, where, entry) {
|
|
2776
|
+
if (!_confinementRequired) return void 0;
|
|
2777
|
+
if (!contentRoot) {
|
|
2778
|
+
throw new Error(
|
|
2779
|
+
`${where}: this process compiles untrusted uploads (requireBuildConfinement) but no content root was given, so the import graph would be unconfined. Pass \`confineTo: <content dir>\`.`
|
|
2780
|
+
);
|
|
2781
|
+
}
|
|
2782
|
+
const allows = confinementMatcher(contentRoot);
|
|
2783
|
+
if (entry) assertConfinedTsconfig(entry, contentRoot, allows);
|
|
2784
|
+
return confinementPlugin(contentRoot);
|
|
2785
|
+
}
|
|
2533
2786
|
function umbrellaRewritePlugin({ external = false } = {}) {
|
|
2534
2787
|
return {
|
|
2535
2788
|
name: "himalaya-umbrella-rewrite",
|
|
@@ -2597,7 +2850,8 @@ function importMetaUrlPlugin() {
|
|
|
2597
2850
|
};
|
|
2598
2851
|
}
|
|
2599
2852
|
async function buildBundleFromEntry(entry, outfile, opts = {}) {
|
|
2600
|
-
const { resolution = "source", name = "bundle", absWorkingDir = REPO_ROOT4 } = opts;
|
|
2853
|
+
const { resolution = "source", name = "bundle", absWorkingDir = REPO_ROOT4, confineTo } = opts;
|
|
2854
|
+
const confine = confinementFor(confineTo, "buildBundleFromEntry", entry);
|
|
2601
2855
|
if (!existsSync8(entry)) throw new Error(`no bundle entry: ${entry}`);
|
|
2602
2856
|
const buildOpts = {
|
|
2603
2857
|
entryPoints: [entry],
|
|
@@ -2620,11 +2874,13 @@ async function buildBundleFromEntry(entry, outfile, opts = {}) {
|
|
|
2620
2874
|
else if (isOffRepo()) {
|
|
2621
2875
|
buildOpts.plugins = process.env.HIMI_CLI_RUNTIME_DIR ? [cliRuntimeUmbrellaPlugin()] : [umbrellaRewritePlugin({ external: false })];
|
|
2622
2876
|
}
|
|
2877
|
+
if (confine) buildOpts.plugins = [confine, ...buildOpts.plugins ?? []];
|
|
2623
2878
|
await build(buildOpts);
|
|
2624
2879
|
return outfile;
|
|
2625
2880
|
}
|
|
2626
2881
|
async function buildAppEntry(entry, outfile, opts = {}) {
|
|
2627
|
-
const { umbrella = false, resolveTsExtensions = false, absWorkingDir = REPO_ROOT4 } = opts;
|
|
2882
|
+
const { umbrella = false, resolveTsExtensions = false, absWorkingDir = REPO_ROOT4, confineTo } = opts;
|
|
2883
|
+
const confine = confinementFor(confineTo, "buildAppEntry", entry);
|
|
2628
2884
|
if (!existsSync8(entry)) throw new Error(`unknown app entry: ${entry}`);
|
|
2629
2885
|
await build({
|
|
2630
2886
|
entryPoints: [entry],
|
|
@@ -2648,6 +2904,9 @@ async function buildAppEntry(entry, outfile, opts = {}) {
|
|
|
2648
2904
|
// -- a single global `define` here pinned the whole graph to the entry and broke
|
|
2649
2905
|
// every app whose config.ts reads a file relative to itself.
|
|
2650
2906
|
plugins: [
|
|
2907
|
+
// FIRST, and here it is load-bearing: `importMetaUrlPlugin` registers an onLoad and CLAIMS
|
|
2908
|
+
// every file containing `import.meta.url`, so a confinement behind it would never see them.
|
|
2909
|
+
...confine ? [confine] : [],
|
|
2651
2910
|
importMetaUrlPlugin(),
|
|
2652
2911
|
...resolveTsExtensions ? [tsExtResolvePlugin()] : [],
|
|
2653
2912
|
...process.env.HIMI_CLI_RUNTIME_DIR ? [cliRuntimeUmbrellaPlugin()] : [],
|
|
@@ -2656,7 +2915,7 @@ async function buildAppEntry(entry, outfile, opts = {}) {
|
|
|
2656
2915
|
});
|
|
2657
2916
|
return outfile;
|
|
2658
2917
|
}
|
|
2659
|
-
var _compilerP, __dirname, REPO_ROOT4, SDK, alias, sourceAliases, OUT_DIR, HERMES_SAFE_SUPPORTED, HERMES_UNSAFE_BUNDLES, APP_ENTRY_TARGET;
|
|
2918
|
+
var _compilerP, __dirname, REPO_ROOT4, SDK, alias, sourceAliases, OUT_DIR, HERMES_SAFE_SUPPORTED, HERMES_UNSAFE_BUNDLES, _confinementRequired, APP_ENTRY_TARGET;
|
|
2660
2919
|
var init_build_lib = __esm({
|
|
2661
2920
|
"../../core/dev-server/tier5-bundles-src/build-lib.mjs"() {
|
|
2662
2921
|
"use strict";
|
|
@@ -2805,6 +3064,7 @@ var init_build_lib = __esm({
|
|
|
2805
3064
|
// worker-safe wix-auth showcase pulls ~11 classes from stdlib/auth-providers.
|
|
2806
3065
|
"demo-app-wix-platform"
|
|
2807
3066
|
]);
|
|
3067
|
+
_confinementRequired = false;
|
|
2808
3068
|
APP_ENTRY_TARGET = ["node18"];
|
|
2809
3069
|
}
|
|
2810
3070
|
});
|
|
@@ -2829,7 +3089,7 @@ var init_tier5_dir = __esm({
|
|
|
2829
3089
|
|
|
2830
3090
|
// src/tier5-typecheck.ts
|
|
2831
3091
|
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "node:fs";
|
|
2832
|
-
import { relative as relative2, resolve as resolve10, sep as
|
|
3092
|
+
import { relative as relative2, resolve as resolve10, sep as sep3 } from "node:path";
|
|
2833
3093
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
2834
3094
|
async function loadTypeScript() {
|
|
2835
3095
|
const runtime = process.env.HIMI_AUTHORING_RUNTIME_DIR;
|
|
@@ -2868,7 +3128,7 @@ function pathsFor(options) {
|
|
|
2868
3128
|
return declarationPaths(options.umbrellaDir);
|
|
2869
3129
|
}
|
|
2870
3130
|
function relativeFile(contentDir2, fileName) {
|
|
2871
|
-
return relative2(contentDir2, fileName).split(
|
|
3131
|
+
return relative2(contentDir2, fileName).split(sep3).join("/");
|
|
2872
3132
|
}
|
|
2873
3133
|
function belongsToContentWorkers(contentDir2, diagnostic) {
|
|
2874
3134
|
if (!diagnostic.file) return true;
|
|
@@ -2890,6 +3150,19 @@ function toIssue(ts, contentDir2, diagnostic) {
|
|
|
2890
3150
|
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
2891
3151
|
};
|
|
2892
3152
|
}
|
|
3153
|
+
function confinedHost(ts, contentDir2, options) {
|
|
3154
|
+
if (!buildConfinementRequired()) return void 0;
|
|
3155
|
+
const host = ts.createCompilerHost(options);
|
|
3156
|
+
const libDir = resolve10(ts.getDefaultLibFilePath(options), "..");
|
|
3157
|
+
const allows = confinementMatcher(contentDir2, [libDir]);
|
|
3158
|
+
const getSourceFile = host.getSourceFile.bind(host);
|
|
3159
|
+
const readFile3 = host.readFile.bind(host);
|
|
3160
|
+
const fileExists = host.fileExists.bind(host);
|
|
3161
|
+
host.getSourceFile = (fileName, ...rest) => allows(fileName) ? getSourceFile(fileName, ...rest) : void 0;
|
|
3162
|
+
host.readFile = (fileName) => allows(fileName) ? readFile3(fileName) : void 0;
|
|
3163
|
+
host.fileExists = (fileName) => allows(fileName) && fileExists(fileName);
|
|
3164
|
+
return host;
|
|
3165
|
+
}
|
|
2893
3166
|
async function typecheckContentWorkers(contentDir2, options) {
|
|
2894
3167
|
if (!existsSync9(resolve10(contentDir2, "tier5-src"))) return [];
|
|
2895
3168
|
const ts = await compiler2();
|
|
@@ -2907,7 +3180,11 @@ async function typecheckContentWorkers(contentDir2, options) {
|
|
|
2907
3180
|
};
|
|
2908
3181
|
const parsed = ts.parseJsonConfigFileContent(config, ts.sys, contentDir2);
|
|
2909
3182
|
if (parsed.fileNames.length === 0) return [];
|
|
2910
|
-
const program = ts.createProgram({
|
|
3183
|
+
const program = ts.createProgram({
|
|
3184
|
+
rootNames: parsed.fileNames,
|
|
3185
|
+
options: parsed.options,
|
|
3186
|
+
host: confinedHost(ts, contentDir2, parsed.options)
|
|
3187
|
+
});
|
|
2911
3188
|
return [...parsed.errors, ...ts.getPreEmitDiagnostics(program)].filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error && belongsToContentWorkers(contentDir2, diagnostic)).map((diagnostic) => toIssue(ts, contentDir2, diagnostic));
|
|
2912
3189
|
}
|
|
2913
3190
|
var compilerPromise;
|
|
@@ -2936,31 +3213,31 @@ __export(build_exports, {
|
|
|
2936
3213
|
umbrellaVersion: () => umbrellaVersion,
|
|
2937
3214
|
umbrellaVersionIssue: () => umbrellaVersionIssue
|
|
2938
3215
|
});
|
|
2939
|
-
import { existsSync as existsSync10, readdirSync as readdirSync8, mkdirSync as mkdirSync6, statSync as
|
|
2940
|
-
import { resolve as resolve11, join as
|
|
3216
|
+
import { existsSync as existsSync10, readdirSync as readdirSync8, mkdirSync as mkdirSync6, statSync as statSync3, symlinkSync, readFileSync as readFileSync12 } from "node:fs";
|
|
3217
|
+
import { resolve as resolve11, join as join13, dirname as dirname9 } from "node:path";
|
|
2941
3218
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
2942
3219
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
2943
3220
|
function bundledRuntimeDir() {
|
|
2944
3221
|
const configured = process.env.HIMI_CLI_RUNTIME_DIR;
|
|
2945
|
-
if (configured && existsSync10(
|
|
3222
|
+
if (configured && existsSync10(join13(configured, "node_modules", "@wix", "himalaya", "package.json"))) {
|
|
2946
3223
|
return configured;
|
|
2947
3224
|
}
|
|
2948
3225
|
const candidate = resolve11(dirname9(fileURLToPath6(import.meta.url)), "authoring-runtime");
|
|
2949
|
-
if (!existsSync10(
|
|
3226
|
+
if (!existsSync10(join13(candidate, "node_modules", "@wix", "himalaya", "package.json"))) return null;
|
|
2950
3227
|
process.env.HIMI_CLI_RUNTIME_DIR = candidate;
|
|
2951
3228
|
return candidate;
|
|
2952
3229
|
}
|
|
2953
3230
|
function bundledUmbrella() {
|
|
2954
3231
|
const runtime = bundledRuntimeDir();
|
|
2955
|
-
return runtime ?
|
|
3232
|
+
return runtime ? join13(runtime, "node_modules", "@wix", "himalaya") : null;
|
|
2956
3233
|
}
|
|
2957
3234
|
function umbrellaDir(fromDir) {
|
|
2958
3235
|
const bundled = bundledUmbrella();
|
|
2959
3236
|
if (bundled) return bundled;
|
|
2960
3237
|
let d = resolve11(fromDir);
|
|
2961
3238
|
for (; ; ) {
|
|
2962
|
-
const pkg =
|
|
2963
|
-
if (existsSync10(
|
|
3239
|
+
const pkg = join13(d, "node_modules", "@wix", "himalaya");
|
|
3240
|
+
if (existsSync10(join13(pkg, "package.json"))) return pkg;
|
|
2964
3241
|
const parent = dirname9(d);
|
|
2965
3242
|
if (parent === d) return null;
|
|
2966
3243
|
d = parent;
|
|
@@ -2973,8 +3250,8 @@ function globalUmbrella() {
|
|
|
2973
3250
|
try {
|
|
2974
3251
|
const root = execFileSync3("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
2975
3252
|
if (!root) return null;
|
|
2976
|
-
const pkg =
|
|
2977
|
-
return existsSync10(
|
|
3253
|
+
const pkg = join13(root, "@wix", "himalaya");
|
|
3254
|
+
return existsSync10(join13(pkg, "package.json")) ? pkg : null;
|
|
2978
3255
|
} catch {
|
|
2979
3256
|
return null;
|
|
2980
3257
|
}
|
|
@@ -2983,11 +3260,11 @@ function ensureUmbrella(contentDir2, globalPath = globalUmbrella()) {
|
|
|
2983
3260
|
if (umbrellaInstalled(contentDir2)) return true;
|
|
2984
3261
|
if (!globalPath) return false;
|
|
2985
3262
|
try {
|
|
2986
|
-
const scope =
|
|
3263
|
+
const scope = join13(contentDir2, "node_modules", "@wix");
|
|
2987
3264
|
mkdirSync6(scope, { recursive: true });
|
|
2988
|
-
const link =
|
|
3265
|
+
const link = join13(scope, "himalaya");
|
|
2989
3266
|
if (!existsSync10(link)) symlinkSync(globalPath, link, "dir");
|
|
2990
|
-
return existsSync10(
|
|
3267
|
+
return existsSync10(join13(link, "package.json"));
|
|
2991
3268
|
} catch {
|
|
2992
3269
|
return false;
|
|
2993
3270
|
}
|
|
@@ -3005,7 +3282,7 @@ function umbrellaVersion(fromDir) {
|
|
|
3005
3282
|
const dir = umbrellaDir(fromDir);
|
|
3006
3283
|
if (!dir) return null;
|
|
3007
3284
|
try {
|
|
3008
|
-
const v = JSON.parse(readFileSync12(
|
|
3285
|
+
const v = JSON.parse(readFileSync12(join13(dir, "package.json"), "utf8")).version;
|
|
3009
3286
|
return typeof v === "string" && v ? v : null;
|
|
3010
3287
|
} catch {
|
|
3011
3288
|
return null;
|
|
@@ -3026,7 +3303,7 @@ function umbrellaDistIssue(contentDir2) {
|
|
|
3026
3303
|
if (!dir) return null;
|
|
3027
3304
|
let exportsMap;
|
|
3028
3305
|
try {
|
|
3029
|
-
exportsMap = JSON.parse(readFileSync12(
|
|
3306
|
+
exportsMap = JSON.parse(readFileSync12(join13(dir, "package.json"), "utf8")).exports;
|
|
3030
3307
|
} catch {
|
|
3031
3308
|
return null;
|
|
3032
3309
|
}
|
|
@@ -3080,14 +3357,19 @@ async function buildContentBundles(contentDir2, opts = {}) {
|
|
|
3080
3357
|
if (!existsSync10(srcDir)) return { built, outDir, compileErrors, ...sdkVersionIssue ? { sdkVersionIssue } : {} };
|
|
3081
3358
|
mkdirSync6(outDir, { recursive: true });
|
|
3082
3359
|
for (const name of readdirSync8(srcDir).sort()) {
|
|
3083
|
-
const entry =
|
|
3084
|
-
if (!
|
|
3360
|
+
const entry = join13(srcDir, name, "index.ts");
|
|
3361
|
+
if (!statSync3(join13(srcDir, name)).isDirectory() || !existsSync10(entry)) continue;
|
|
3085
3362
|
try {
|
|
3086
|
-
await buildBundleFromEntry(entry,
|
|
3363
|
+
await buildBundleFromEntry(entry, join13(outDir, `${name}.bundle.js`), {
|
|
3087
3364
|
resolution,
|
|
3088
3365
|
name,
|
|
3089
3366
|
// Off-repo, resolve the umbrella from the content package's own node_modules.
|
|
3090
|
-
...offRepo ? { absWorkingDir: contentDir2 } : {}
|
|
3367
|
+
...offRepo ? { absWorkingDir: contentDir2 } : {},
|
|
3368
|
+
// Bounds the import graph in a process that compiles untrusted uploads
|
|
3369
|
+
// (core/serve-authoring); inert everywhere else. Always passed, so the authoring guest
|
|
3370
|
+
// cannot reach this build without a root — build-lib throws rather than compile
|
|
3371
|
+
// unconfined.
|
|
3372
|
+
confineTo: contentDir2
|
|
3091
3373
|
});
|
|
3092
3374
|
built.push(name);
|
|
3093
3375
|
} catch (err) {
|
|
@@ -3125,11 +3407,11 @@ __export(app_config_loader_exports, {
|
|
|
3125
3407
|
loadAppConfigModule: () => loadAppConfigModule
|
|
3126
3408
|
});
|
|
3127
3409
|
import { existsSync as existsSync11, mkdirSync as mkdirSync7 } from "node:fs";
|
|
3128
|
-
import { dirname as dirname10, join as
|
|
3410
|
+
import { dirname as dirname10, join as join14, resolve as resolve12 } from "node:path";
|
|
3129
3411
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
3130
3412
|
function configEntry(dir) {
|
|
3131
3413
|
for (const f of ["config.ts", "config.js", "config.mjs"]) {
|
|
3132
|
-
const p =
|
|
3414
|
+
const p = join14(dir, f);
|
|
3133
3415
|
if (existsSync11(p)) return p;
|
|
3134
3416
|
}
|
|
3135
3417
|
return null;
|
|
@@ -3141,7 +3423,7 @@ async function buildConfigModuleUrl(entry, dir) {
|
|
|
3141
3423
|
bundledRuntimeDir2();
|
|
3142
3424
|
const out = resolve12(dir, "dist/.himi/config.mjs");
|
|
3143
3425
|
mkdirSync7(dirname10(out), { recursive: true });
|
|
3144
|
-
await buildAppEntry(entry, out, { umbrella: true, resolveTsExtensions: true, absWorkingDir: dir });
|
|
3426
|
+
await buildAppEntry(entry, out, { umbrella: true, resolveTsExtensions: true, absWorkingDir: dir, confineTo: dir });
|
|
3145
3427
|
return pathToFileURL4(out).href;
|
|
3146
3428
|
}
|
|
3147
3429
|
function rememberBuild(key2, pending) {
|
|
@@ -3889,10 +4171,10 @@ var init_app_icon_rules = __esm({
|
|
|
3889
4171
|
|
|
3890
4172
|
// ../../core/dev-server/src/app-icon.ts
|
|
3891
4173
|
import { existsSync as existsSync14, readFileSync as readFileSync17, readdirSync as readdirSync9 } from "node:fs";
|
|
3892
|
-
import { dirname as dirname13, join as
|
|
4174
|
+
import { dirname as dirname13, join as join18, resolve as resolve13 } from "node:path";
|
|
3893
4175
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
3894
4176
|
function findAppIconPath(appDir2) {
|
|
3895
|
-
const iosDir =
|
|
4177
|
+
const iosDir = join18(appDir2, "ios");
|
|
3896
4178
|
let children;
|
|
3897
4179
|
try {
|
|
3898
4180
|
children = readdirSync9(iosDir);
|
|
@@ -3900,7 +4182,7 @@ function findAppIconPath(appDir2) {
|
|
|
3900
4182
|
return null;
|
|
3901
4183
|
}
|
|
3902
4184
|
for (const child of children) {
|
|
3903
|
-
const p =
|
|
4185
|
+
const p = join18(iosDir, child, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
3904
4186
|
if (existsSync14(p)) return p;
|
|
3905
4187
|
}
|
|
3906
4188
|
return null;
|
|
@@ -3908,7 +4190,7 @@ function findAppIconPath(appDir2) {
|
|
|
3908
4190
|
function findContentIconPath(appDir2) {
|
|
3909
4191
|
let rel;
|
|
3910
4192
|
try {
|
|
3911
|
-
rel = JSON.parse(readFileSync17(
|
|
4193
|
+
rel = JSON.parse(readFileSync17(join18(appDir2, "himalaya.content.json"), "utf8")).icon;
|
|
3912
4194
|
} catch {
|
|
3913
4195
|
return null;
|
|
3914
4196
|
}
|
|
@@ -3933,7 +4215,7 @@ function readIconFromDir(appDir2) {
|
|
|
3933
4215
|
function resolveAppDir(appId2) {
|
|
3934
4216
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(appId2)) return null;
|
|
3935
4217
|
for (const base of APP_ROOTS) {
|
|
3936
|
-
const dir =
|
|
4218
|
+
const dir = join18(ROOT, base, appId2);
|
|
3937
4219
|
if (existsSync14(dir)) return dir;
|
|
3938
4220
|
}
|
|
3939
4221
|
return null;
|
|
@@ -4226,11 +4508,11 @@ __export(icon_exports, {
|
|
|
4226
4508
|
summarize: () => summarize
|
|
4227
4509
|
});
|
|
4228
4510
|
import { createHash as createHash5 } from "node:crypto";
|
|
4229
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync18, statSync as
|
|
4230
|
-
import { basename as basename4, dirname as dirname14, join as
|
|
4511
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync18, statSync as statSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
4512
|
+
import { basename as basename4, dirname as dirname14, join as join19, resolve as resolve14, sep as sep4 } from "node:path";
|
|
4231
4513
|
function readManifest(dir) {
|
|
4232
4514
|
try {
|
|
4233
|
-
return JSON.parse(readFileSync18(
|
|
4515
|
+
return JSON.parse(readFileSync18(join19(dir, MANIFEST), "utf8"));
|
|
4234
4516
|
} catch {
|
|
4235
4517
|
return null;
|
|
4236
4518
|
}
|
|
@@ -4244,7 +4526,7 @@ function declaredIconName(dir) {
|
|
|
4244
4526
|
function iconDest(dir, name) {
|
|
4245
4527
|
const base = resolve14(dir);
|
|
4246
4528
|
const abs = resolve14(base, name);
|
|
4247
|
-
if (!abs.startsWith(base +
|
|
4529
|
+
if (!abs.startsWith(base + sep4)) {
|
|
4248
4530
|
throw new Error(
|
|
4249
4531
|
`himi icon: himalaya.content.json declares "icon": "${name}", which resolves outside the package (${abs}). Declare a path inside it, e.g. "${DEFAULT_CONTENT_ICON}".`
|
|
4250
4532
|
);
|
|
@@ -4254,9 +4536,9 @@ function iconDest(dir, name) {
|
|
|
4254
4536
|
}
|
|
4255
4537
|
function templateIconMatch(png) {
|
|
4256
4538
|
for (const template of availableTemplates()) {
|
|
4257
|
-
const candidate =
|
|
4539
|
+
const candidate = join19(templateSourceDir(template), DEFAULT_CONTENT_ICON);
|
|
4258
4540
|
try {
|
|
4259
|
-
if (
|
|
4541
|
+
if (statSync4(candidate).size !== png.length) continue;
|
|
4260
4542
|
if (readFileSync18(candidate).equals(png)) return template;
|
|
4261
4543
|
} catch {
|
|
4262
4544
|
}
|
|
@@ -4264,10 +4546,10 @@ function templateIconMatch(png) {
|
|
|
4264
4546
|
return null;
|
|
4265
4547
|
}
|
|
4266
4548
|
function playState(dir) {
|
|
4267
|
-
const p =
|
|
4549
|
+
const p = join19(resolve14(dir), PLAY_LISTING_ICON);
|
|
4268
4550
|
if (!existsSync15(p)) return null;
|
|
4269
4551
|
try {
|
|
4270
|
-
if (!
|
|
4552
|
+
if (!statSync4(p).isFile()) return { path: p, issues: ["is a directory, not a PNG file"] };
|
|
4271
4553
|
return { path: p, issues: playListingIconIssues(readFileSync18(p)) };
|
|
4272
4554
|
} catch (err) {
|
|
4273
4555
|
return { path: p, issues: [`could not be read (${err.message.split("\n")[0]})`] };
|
|
@@ -4294,7 +4576,7 @@ async function iconStatus(dir) {
|
|
|
4294
4576
|
if (!path || !existsSync15(path)) return base;
|
|
4295
4577
|
let png;
|
|
4296
4578
|
try {
|
|
4297
|
-
if (!
|
|
4579
|
+
if (!statSync4(path).isFile()) {
|
|
4298
4580
|
return {
|
|
4299
4581
|
...base,
|
|
4300
4582
|
byteIssues: [`at ${path} is a directory, not a PNG file`],
|
|
@@ -4371,7 +4653,7 @@ function summarize(status) {
|
|
|
4371
4653
|
}
|
|
4372
4654
|
function backdropFromTokens(dir, fallback = "#1F2933") {
|
|
4373
4655
|
try {
|
|
4374
|
-
const tokens = JSON.parse(readFileSync18(
|
|
4656
|
+
const tokens = JSON.parse(readFileSync18(join19(dir, "tokens.json"), "utf8"));
|
|
4375
4657
|
const accent = tokens.colors?.accentPrimary;
|
|
4376
4658
|
const hex2 = typeof accent === "string" ? accent : accent?.light;
|
|
4377
4659
|
return typeof hex2 === "string" && HEX_COLOR2.test(hex2) ? hex2 : fallback;
|
|
@@ -4430,15 +4712,15 @@ function declareIcon(dir, name) {
|
|
|
4430
4712
|
if (k === "name") next.icon = name;
|
|
4431
4713
|
}
|
|
4432
4714
|
next.icon = name;
|
|
4433
|
-
writeFileSync8(
|
|
4434
|
-
return [
|
|
4715
|
+
writeFileSync8(join19(dir, MANIFEST), JSON.stringify(next, null, 2) + "\n");
|
|
4716
|
+
return [join19(dir, MANIFEST)];
|
|
4435
4717
|
}
|
|
4436
4718
|
function siteBookIcon(bookDir) {
|
|
4437
|
-
const p =
|
|
4719
|
+
const p = join19(resolve14(bookDir), SITE_BOOK_ICON_REL);
|
|
4438
4720
|
return existsSync15(p) ? p : null;
|
|
4439
4721
|
}
|
|
4440
4722
|
function siteLogoAbsence(bookDir) {
|
|
4441
|
-
const bookJson =
|
|
4723
|
+
const bookJson = join19(resolve14(bookDir), "book.json");
|
|
4442
4724
|
if (!existsSync15(bookJson)) {
|
|
4443
4725
|
return { reason: "no-book", hint: `no business book at ${bookDir} \u2014 run \`himi site analyze --out <dir>\` first, or pass --book <dir>` };
|
|
4444
4726
|
}
|
|
@@ -4520,7 +4802,7 @@ var init_icon = __esm({
|
|
|
4520
4802
|
// ../fonts/catalog.ts
|
|
4521
4803
|
import { existsSync as existsSync17, readFileSync as readFileSync19 } from "node:fs";
|
|
4522
4804
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
4523
|
-
import { join as
|
|
4805
|
+
import { join as join21 } from "node:path";
|
|
4524
4806
|
function loadCatalog() {
|
|
4525
4807
|
if (cached) return cached;
|
|
4526
4808
|
const path = CATALOG_CANDIDATES.find((p) => existsSync17(p));
|
|
@@ -4589,9 +4871,9 @@ var init_catalog = __esm({
|
|
|
4589
4871
|
"../fonts/catalog.ts"() {
|
|
4590
4872
|
CATALOG_CANDIDATES = [
|
|
4591
4873
|
// in-repo: tools/fonts/catalog.ts → <repo>/stdlib/fonts/catalog.json
|
|
4592
|
-
|
|
4874
|
+
join21(fileURLToPath8(new URL("../..", import.meta.url)), "stdlib", "fonts", "catalog.json"),
|
|
4593
4875
|
// published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/fonts/catalog.json
|
|
4594
|
-
|
|
4876
|
+
join21(fileURLToPath8(new URL("..", import.meta.url)), "stdlib", "fonts", "catalog.json")
|
|
4595
4877
|
];
|
|
4596
4878
|
cached = null;
|
|
4597
4879
|
normalizeFamily = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
@@ -4696,17 +4978,17 @@ var init_plan_fonts = __esm({
|
|
|
4696
4978
|
import { createHash as createHash6 } from "node:crypto";
|
|
4697
4979
|
import { existsSync as existsSync18, readFileSync as readFileSync20 } from "node:fs";
|
|
4698
4980
|
import { homedir as homedir4 } from "node:os";
|
|
4699
|
-
import { basename as basename5, join as
|
|
4981
|
+
import { basename as basename5, join as join22 } from "node:path";
|
|
4700
4982
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
4701
4983
|
function hasVendoredFloor() {
|
|
4702
4984
|
return existsSync18(VENDORED_DIR);
|
|
4703
4985
|
}
|
|
4704
4986
|
function faceSource(file, sha2565) {
|
|
4705
|
-
const vendored =
|
|
4987
|
+
const vendored = join22(VENDORED_DIR, basename5(file));
|
|
4706
4988
|
if (existsSync18(vendored) && createHash6("sha256").update(readFileSync20(vendored)).digest("hex") === sha2565) {
|
|
4707
4989
|
return vendored;
|
|
4708
4990
|
}
|
|
4709
|
-
const cached3 =
|
|
4991
|
+
const cached3 = join22(CACHE_DIR, sha2565);
|
|
4710
4992
|
if (existsSync18(cached3)) return cached3;
|
|
4711
4993
|
return null;
|
|
4712
4994
|
}
|
|
@@ -4714,8 +4996,8 @@ var REPO_ROOT5, VENDORED_DIR, CACHE_DIR;
|
|
|
4714
4996
|
var init_face_source = __esm({
|
|
4715
4997
|
"../font-bake/face-source.ts"() {
|
|
4716
4998
|
REPO_ROOT5 = fileURLToPath9(new URL("../..", import.meta.url));
|
|
4717
|
-
VENDORED_DIR = process.env.HIMI_FONTS_VENDORED_DIR ||
|
|
4718
|
-
CACHE_DIR =
|
|
4999
|
+
VENDORED_DIR = process.env.HIMI_FONTS_VENDORED_DIR || join22(REPO_ROOT5, "stdlib", "fonts", "vendored", "wix-madefor");
|
|
5000
|
+
CACHE_DIR = join22(process.env.XDG_CACHE_HOME || join22(homedir4(), ".cache"), "himi", "fonts");
|
|
4719
5001
|
}
|
|
4720
5002
|
});
|
|
4721
5003
|
|
|
@@ -4729,7 +5011,7 @@ __export(fonts_exports, {
|
|
|
4729
5011
|
resolveFamilyName: () => resolveFamilyName
|
|
4730
5012
|
});
|
|
4731
5013
|
import { existsSync as existsSync19, readFileSync as readFileSync21 } from "node:fs";
|
|
4732
|
-
import { join as
|
|
5014
|
+
import { join as join23 } from "node:path";
|
|
4733
5015
|
function readJson(path, fallback) {
|
|
4734
5016
|
try {
|
|
4735
5017
|
return JSON.parse(readFileSync21(path, "utf8"));
|
|
@@ -4761,11 +5043,11 @@ function listReport(opts = {}) {
|
|
|
4761
5043
|
return { ok: true, count: families.length, totalBytes, families };
|
|
4762
5044
|
}
|
|
4763
5045
|
function fontFindings(appDir2) {
|
|
4764
|
-
const tokensPath =
|
|
5046
|
+
const tokensPath = join23(appDir2, "tokens.json");
|
|
4765
5047
|
if (!existsSync19(tokensPath)) return null;
|
|
4766
5048
|
const catalog = loadCatalog();
|
|
4767
5049
|
const tokens = readJson(tokensPath, {});
|
|
4768
|
-
const policy = readJson(
|
|
5050
|
+
const policy = readJson(join23(appDir2, "fonts.json"), {});
|
|
4769
5051
|
const plan = planFonts(tokens, policy, catalog);
|
|
4770
5052
|
const findings = [];
|
|
4771
5053
|
for (const family of plan.unresolved) {
|
|
@@ -4851,7 +5133,7 @@ function addReport(appDir2, family) {
|
|
|
4851
5133
|
totalBytes: bytes2,
|
|
4852
5134
|
problems: [],
|
|
4853
5135
|
families: [{ family: resolved, license: fam?.license.id ?? "system", copyright: fam?.license.copyright, kb: Math.round(bytes2 / 1024) }],
|
|
4854
|
-
hint: `add "${resolved}" to ${
|
|
5136
|
+
hint: `add "${resolved}" to ${join23(appDir2, "fonts.json")} under "families" (or name it in tokens.json typography), then run gen.sh. Licence: ${fam?.license.id ?? "system"}${fam?.license.copyright ? ` \u2014 ${fam.license.copyright}` : ""}`
|
|
4855
5137
|
};
|
|
4856
5138
|
}
|
|
4857
5139
|
var DEFAULT_ASSET_BUDGET_BYTES;
|
|
@@ -5773,7 +6055,7 @@ var init_src = __esm({
|
|
|
5773
6055
|
// ../app-icons/plan.ts
|
|
5774
6056
|
import { existsSync as existsSync23, readFileSync as readFileSync25, readdirSync as readdirSync12 } from "node:fs";
|
|
5775
6057
|
import { createHash as createHash7 } from "node:crypto";
|
|
5776
|
-
import { dirname as dirname16, join as
|
|
6058
|
+
import { dirname as dirname16, join as join27, resolve as resolve17 } from "node:path";
|
|
5777
6059
|
function stripComments(src) {
|
|
5778
6060
|
let out = "";
|
|
5779
6061
|
let i = 0;
|
|
@@ -5903,10 +6185,10 @@ function rotateHue(hex2, deg) {
|
|
|
5903
6185
|
function resolveTokensPath(app, configTs) {
|
|
5904
6186
|
const literal = /^ {2}designTokensPath\s*:\s*["']([^"']+)["']/m.exec(stripComments(configTs))?.[1];
|
|
5905
6187
|
if (literal) return { path: resolve17(appDir(app), literal), source: "declared" };
|
|
5906
|
-
return { path:
|
|
6188
|
+
return { path: join27(appDir(app), "tokens.json"), source: "assumed" };
|
|
5907
6189
|
}
|
|
5908
6190
|
function resolveToken(app, token, tokensPathOverride) {
|
|
5909
|
-
const tokensPath = tokensPathOverride ??
|
|
6191
|
+
const tokensPath = tokensPathOverride ?? join27(appDir(app), "tokens.json");
|
|
5910
6192
|
if (!existsSync23(tokensPath)) {
|
|
5911
6193
|
throw new Error(`app-icons: ${app} has no tokens.json at ${tokensPath} (needed to resolve "${token}").`);
|
|
5912
6194
|
}
|
|
@@ -5989,17 +6271,17 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
|
|
|
5989
6271
|
};
|
|
5990
6272
|
}
|
|
5991
6273
|
function iosAssetCatalog2(app) {
|
|
5992
|
-
return assetCatalogIn(
|
|
6274
|
+
return assetCatalogIn(join27(appDir(app), "ios"));
|
|
5993
6275
|
}
|
|
5994
6276
|
function assetCatalogIn(platformDir) {
|
|
5995
6277
|
if (!existsSync23(platformDir)) return void 0;
|
|
5996
6278
|
const children = readdirSync12(platformDir).filter((c) => !c.startsWith("build")).sort();
|
|
5997
|
-
const catalogs = children.map((c) =>
|
|
6279
|
+
const catalogs = children.map((c) => join27(platformDir, c, "Assets.xcassets")).filter(existsSync23);
|
|
5998
6280
|
if (catalogs.length === 1) return catalogs[0];
|
|
5999
6281
|
if (catalogs.length > 1) return void 0;
|
|
6000
6282
|
const targets = [];
|
|
6001
6283
|
for (const child of children) {
|
|
6002
|
-
const dir =
|
|
6284
|
+
const dir = join27(platformDir, child);
|
|
6003
6285
|
let entries;
|
|
6004
6286
|
try {
|
|
6005
6287
|
entries = readdirSync12(dir);
|
|
@@ -6007,20 +6289,20 @@ function assetCatalogIn(platformDir) {
|
|
|
6007
6289
|
continue;
|
|
6008
6290
|
}
|
|
6009
6291
|
if (entries.includes("Info.plist") || entries.some((e) => e.endsWith(".swift"))) {
|
|
6010
|
-
targets.push(
|
|
6292
|
+
targets.push(join27(dir, "Assets.xcassets"));
|
|
6011
6293
|
}
|
|
6012
6294
|
}
|
|
6013
6295
|
return targets.length === 1 ? targets[0] : void 0;
|
|
6014
6296
|
}
|
|
6015
6297
|
function androidResDir2(manifestPath) {
|
|
6016
|
-
return
|
|
6298
|
+
return join27(dirname16(manifestPath), "res");
|
|
6017
6299
|
}
|
|
6018
6300
|
function androidManifestPath(app) {
|
|
6019
|
-
const androidDir =
|
|
6301
|
+
const androidDir = join27(appDir(app), "android");
|
|
6020
6302
|
if (!existsSync23(androidDir)) return void 0;
|
|
6021
|
-
const preferred =
|
|
6303
|
+
const preferred = join27(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
6022
6304
|
if (existsSync23(preferred)) return preferred;
|
|
6023
|
-
const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) =>
|
|
6305
|
+
const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join27(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync23);
|
|
6024
6306
|
return candidates.length === 1 ? candidates[0] : void 0;
|
|
6025
6307
|
}
|
|
6026
6308
|
function androidOptedIn2(manifestPath) {
|
|
@@ -6029,7 +6311,7 @@ function androidOptedIn2(manifestPath) {
|
|
|
6029
6311
|
}
|
|
6030
6312
|
function templateIconSha256() {
|
|
6031
6313
|
const cat = iosAssetCatalog2("_template");
|
|
6032
|
-
return cat ? fileSha256(
|
|
6314
|
+
return cat ? fileSha256(join27(cat, "AppIcon.appiconset", "icon_1024.png")) : null;
|
|
6033
6315
|
}
|
|
6034
6316
|
function placeholderHashes() {
|
|
6035
6317
|
const current = templateIconSha256();
|
|
@@ -6048,7 +6330,7 @@ function generationAllowed(app, configTs, opts = {}) {
|
|
|
6048
6330
|
return { allowed: true, reason: "declares an icon block" };
|
|
6049
6331
|
}
|
|
6050
6332
|
const iosCat = iosAssetCatalog2(app);
|
|
6051
|
-
const iosIcon = iosCat ?
|
|
6333
|
+
const iosIcon = iosCat ? join27(iosCat, "AppIcon.appiconset", "icon_1024.png") : void 0;
|
|
6052
6334
|
if (!iosIcon || !existsSync23(iosIcon)) return { allowed: true, reason: "no icon yet" };
|
|
6053
6335
|
const hash = fileSha256(iosIcon);
|
|
6054
6336
|
const placeholders = opts.placeholderHashes ?? placeholderHashes();
|
|
@@ -6074,7 +6356,7 @@ var init_plan2 = __esm({
|
|
|
6074
6356
|
|
|
6075
6357
|
// ../native-config/icon.ts
|
|
6076
6358
|
import { existsSync as existsSync24, readFileSync as readFileSync26 } from "node:fs";
|
|
6077
|
-
import { join as
|
|
6359
|
+
import { join as join28 } from "node:path";
|
|
6078
6360
|
function androidAdaptiveIconXml() {
|
|
6079
6361
|
return [
|
|
6080
6362
|
'<?xml version="1.0" encoding="utf-8"?>',
|
|
@@ -6101,7 +6383,7 @@ function androidIconArtifacts(app, configTs) {
|
|
|
6101
6383
|
if (!androidOptedIn2(manifest)) return [];
|
|
6102
6384
|
if (!generationAllowed(app, configTs).allowed) return [];
|
|
6103
6385
|
const res = androidResDir2(manifest);
|
|
6104
|
-
const foreground =
|
|
6386
|
+
const foreground = join28(res, "mipmap-mdpi", "ic_launcher_foreground.png");
|
|
6105
6387
|
if (!existsSync24(foreground)) {
|
|
6106
6388
|
throw new Error(
|
|
6107
6389
|
`native-config icon: ${app} opts into @mipmap/ic_launcher but has no mipmap-*/ic_launcher_foreground.png. Run \`npm run app-icons -- ${app}\` first \u2014 the XML emitted here points at those rasters.`
|
|
@@ -6111,11 +6393,11 @@ function androidIconArtifacts(app, configTs) {
|
|
|
6111
6393
|
const spec = iconSpec(app, configTs, id, resolveTokensPath(app, configTs).path);
|
|
6112
6394
|
return [
|
|
6113
6395
|
...ANDROID_ADAPTIVE_FILES.map((name) => ({
|
|
6114
|
-
path:
|
|
6396
|
+
path: join28(res, "mipmap-anydpi-v26", name),
|
|
6115
6397
|
content: androidAdaptiveIconXml()
|
|
6116
6398
|
})),
|
|
6117
6399
|
{
|
|
6118
|
-
path:
|
|
6400
|
+
path: join28(res, "values", ANDROID_ICON_BACKGROUND_FILE),
|
|
6119
6401
|
content: androidIconBackgroundXml(spec.background)
|
|
6120
6402
|
}
|
|
6121
6403
|
];
|
|
@@ -6350,7 +6632,7 @@ __export(gen_native_config_exports, {
|
|
|
6350
6632
|
watchInfoPlan: () => watchInfoPlan
|
|
6351
6633
|
});
|
|
6352
6634
|
import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync27, readdirSync as readdirSync13, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
6353
|
-
import { dirname as dirname17, join as
|
|
6635
|
+
import { dirname as dirname17, join as join29 } from "node:path";
|
|
6354
6636
|
function parseStringArray(configTs, field) {
|
|
6355
6637
|
const m = new RegExp(`${field}:\\s*\\[([^\\]]*)\\]`).exec(configTs);
|
|
6356
6638
|
if (!m) return [];
|
|
@@ -6422,7 +6704,7 @@ function buildSet(capabilities, envelope = []) {
|
|
|
6422
6704
|
return [...new Set([...capabilities, ...envelope].map(catalogKey))].sort();
|
|
6423
6705
|
}
|
|
6424
6706
|
function loadOverrides(app) {
|
|
6425
|
-
const p =
|
|
6707
|
+
const p = join29(appDir(app), "native-config.overrides.json");
|
|
6426
6708
|
if (!existsSync25(p)) return {};
|
|
6427
6709
|
return JSON.parse(readFileSync27(p, "utf8"));
|
|
6428
6710
|
}
|
|
@@ -6479,14 +6761,14 @@ function endText(kind, label2, indent) {
|
|
|
6479
6761
|
return kind === "yaml" ? `${indent}# <<< ${label2} <<<` : `${indent}<!-- <<< ${label2} <<< -->`;
|
|
6480
6762
|
}
|
|
6481
6763
|
function hostAppliesDeferredWidgetActions(app) {
|
|
6482
|
-
const root =
|
|
6764
|
+
const root = join29(appDir(app), "ios");
|
|
6483
6765
|
if (!existsSync25(root)) return false;
|
|
6484
6766
|
const stack = [root];
|
|
6485
6767
|
while (stack.length) {
|
|
6486
6768
|
const dir = stack.pop();
|
|
6487
6769
|
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
6488
6770
|
if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
|
|
6489
|
-
const path =
|
|
6771
|
+
const path = join29(dir, entry.name);
|
|
6490
6772
|
if (entry.isDirectory()) {
|
|
6491
6773
|
if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
|
|
6492
6774
|
stack.push(path);
|
|
@@ -6513,14 +6795,14 @@ function injectBlock(text2, kind, label2, render) {
|
|
|
6513
6795
|
return [...lines.slice(0, beginIdx), ...block, ...lines.slice(endIdx + 1)].join("\n");
|
|
6514
6796
|
}
|
|
6515
6797
|
function androidManifestPath2(app) {
|
|
6516
|
-
const androidDir =
|
|
6517
|
-
const preferred =
|
|
6798
|
+
const androidDir = join29(appDir(app), "android");
|
|
6799
|
+
const preferred = join29(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
6518
6800
|
if (existsSync25(preferred)) return preferred;
|
|
6519
|
-
const candidates = existsSync25(androidDir) ? readdirSync13(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) =>
|
|
6801
|
+
const candidates = existsSync25(androidDir) ? readdirSync13(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join29(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync25) : [];
|
|
6520
6802
|
return candidates.length === 1 ? candidates[0] : preferred;
|
|
6521
6803
|
}
|
|
6522
6804
|
function automotiveAppDescPath(app) {
|
|
6523
|
-
return
|
|
6805
|
+
return join29(dirname17(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
|
|
6524
6806
|
}
|
|
6525
6807
|
function applyToFile(path, kind, label2, render, check) {
|
|
6526
6808
|
if (!existsSync25(path)) return { path, outcome: "skipped" };
|
|
@@ -6619,9 +6901,9 @@ function genNativeConfig(app, opts = {}) {
|
|
|
6619
6901
|
const plan = live2;
|
|
6620
6902
|
files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_TARGET, (i) => plan.target.map((line) => i + line), check));
|
|
6621
6903
|
files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_EMBED, (i) => plan.embed.map((line) => i + line), check));
|
|
6622
|
-
const source =
|
|
6904
|
+
const source = join29(dirname17(iosYml), LIVE_SOURCE_PATH);
|
|
6623
6905
|
files.push(plan.source ? applyWholeFile(source, plan.source, check) : removeWholeFile(source, check));
|
|
6624
|
-
const entitlements =
|
|
6906
|
+
const entitlements = join29(dirname17(iosYml), LIVE_ENTITLEMENTS_PATH);
|
|
6625
6907
|
files.push(plan.entitlements ? applyWholeFile(entitlements, plan.entitlements, check) : removeWholeFile(entitlements, check));
|
|
6626
6908
|
}
|
|
6627
6909
|
const iosSplashManaged = existsSync25(iosYml) && hasMarkers(readFileSync27(iosYml, "utf8"), "yaml", LABEL_IOS_SPLASH);
|
|
@@ -6759,7 +7041,8 @@ async function devModuleUrl(entry, dir) {
|
|
|
6759
7041
|
// intentionally point at `.ts` sources, which are only loadable under tsx.
|
|
6760
7042
|
umbrella: true,
|
|
6761
7043
|
resolveTsExtensions: true,
|
|
6762
|
-
absWorkingDir: dir
|
|
7044
|
+
absWorkingDir: dir,
|
|
7045
|
+
confineTo: dir
|
|
6763
7046
|
});
|
|
6764
7047
|
return pathToFileURL5(out).href;
|
|
6765
7048
|
}
|
|
@@ -6881,8 +7164,8 @@ var init_build_sha = __esm({
|
|
|
6881
7164
|
|
|
6882
7165
|
// ../../core/dev-server/src/app-assets.ts
|
|
6883
7166
|
import { createHash as createHash8 } from "node:crypto";
|
|
6884
|
-
import { existsSync as existsSync27, lstatSync as lstatSync3, readFileSync as readFileSync29, readdirSync as readdirSync15, realpathSync as
|
|
6885
|
-
import { join as
|
|
7167
|
+
import { existsSync as existsSync27, lstatSync as lstatSync3, readFileSync as readFileSync29, readdirSync as readdirSync15, realpathSync as realpathSync3, statSync as statSync6 } from "node:fs";
|
|
7168
|
+
import { join as join30, resolve as resolve19, sep as sep5 } from "node:path";
|
|
6886
7169
|
function contentTypeFor(name) {
|
|
6887
7170
|
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
6888
7171
|
return CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
@@ -6896,19 +7179,19 @@ function assetSha256(bytes2) {
|
|
|
6896
7179
|
function findAssetsDir(appDir2) {
|
|
6897
7180
|
let declared;
|
|
6898
7181
|
try {
|
|
6899
|
-
declared = JSON.parse(readFileSync29(
|
|
7182
|
+
declared = JSON.parse(readFileSync29(join30(appDir2, "himalaya.content.json"), "utf8")).assets;
|
|
6900
7183
|
} catch {
|
|
6901
7184
|
declared = void 0;
|
|
6902
7185
|
}
|
|
6903
7186
|
const rel = typeof declared === "string" && declared ? declared : "assets";
|
|
6904
7187
|
const abs = resolve19(appDir2, rel);
|
|
6905
7188
|
const base = resolve19(appDir2);
|
|
6906
|
-
if (abs !== base && !abs.startsWith(base +
|
|
6907
|
-
return existsSync27(abs) &&
|
|
7189
|
+
if (abs !== base && !abs.startsWith(base + sep5)) return null;
|
|
7190
|
+
return existsSync27(abs) && statSync6(abs).isDirectory() ? abs : null;
|
|
6908
7191
|
}
|
|
6909
7192
|
function readOtaOnlyPatterns(appDir2) {
|
|
6910
7193
|
try {
|
|
6911
|
-
const raw = JSON.parse(readFileSync29(
|
|
7194
|
+
const raw = JSON.parse(readFileSync29(join30(appDir2, "assets.json"), "utf8"));
|
|
6912
7195
|
return Array.isArray(raw.otaOnly) ? raw.otaOnly.filter((p) => typeof p === "string") : [];
|
|
6913
7196
|
} catch {
|
|
6914
7197
|
return [];
|
|
@@ -6926,7 +7209,7 @@ function collectAssets(appDir2) {
|
|
|
6926
7209
|
const walk2 = (abs, prefix) => {
|
|
6927
7210
|
for (const entry of readdirSync15(abs, { withFileTypes: true })) {
|
|
6928
7211
|
if (entry.name.startsWith(".")) continue;
|
|
6929
|
-
const child =
|
|
7212
|
+
const child = join30(abs, entry.name);
|
|
6930
7213
|
const name = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
6931
7214
|
if (entry.isDirectory()) {
|
|
6932
7215
|
walk2(child, name);
|
|
@@ -6935,7 +7218,7 @@ function collectAssets(appDir2) {
|
|
|
6935
7218
|
if (!entry.isFile()) continue;
|
|
6936
7219
|
const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
6937
7220
|
const baked = !OTA_ONLY_BY_DEFAULT.has(ext) && !otaOnly.some((p) => matchesPattern(name, p));
|
|
6938
|
-
out.push({ name, path: child, bytes:
|
|
7221
|
+
out.push({ name, path: child, bytes: statSync6(child).size, contentType: contentTypeFor(name), baked });
|
|
6939
7222
|
}
|
|
6940
7223
|
};
|
|
6941
7224
|
walk2(dir, "");
|
|
@@ -6944,7 +7227,7 @@ function collectAssets(appDir2) {
|
|
|
6944
7227
|
function collectBrandFonts(appDir2) {
|
|
6945
7228
|
let faces;
|
|
6946
7229
|
try {
|
|
6947
|
-
faces = JSON.parse(readFileSync29(
|
|
7230
|
+
faces = JSON.parse(readFileSync29(join30(appDir2, "media/fonts/faces.json"), "utf8"));
|
|
6948
7231
|
} catch {
|
|
6949
7232
|
return [];
|
|
6950
7233
|
}
|
|
@@ -6957,11 +7240,11 @@ function collectBrandFonts(appDir2) {
|
|
|
6957
7240
|
const rel = typeof raw?.file === "string" ? raw.file : "";
|
|
6958
7241
|
if (!family || !postscriptName || !rel) continue;
|
|
6959
7242
|
if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
|
|
6960
|
-
const path =
|
|
7243
|
+
const path = join30(appDir2, rel);
|
|
6961
7244
|
try {
|
|
6962
7245
|
if (!lstatSync3(path).isFile()) continue;
|
|
6963
|
-
const root =
|
|
6964
|
-
if (!
|
|
7246
|
+
const root = realpathSync3(appDir2);
|
|
7247
|
+
if (!realpathSync3(path).startsWith(root + sep5)) continue;
|
|
6965
7248
|
} catch {
|
|
6966
7249
|
continue;
|
|
6967
7250
|
}
|
|
@@ -8782,7 +9065,7 @@ var init_stable_ids = __esm({
|
|
|
8782
9065
|
// ../../core/dev-server/src/preview.ts
|
|
8783
9066
|
import { spawn as spawn2 } from "node:child_process";
|
|
8784
9067
|
import { createHash as createHash11 } from "node:crypto";
|
|
8785
|
-
import { existsSync as existsSync30, createReadStream, statSync as
|
|
9068
|
+
import { existsSync as existsSync30, createReadStream, statSync as statSync7, readFileSync as readFileSync33, renameSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
8786
9069
|
import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
|
|
8787
9070
|
import { resolve as resolvePath, dirname as dirname20 } from "node:path";
|
|
8788
9071
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
@@ -9480,7 +9763,7 @@ function finalizeRecording(key2, rec) {
|
|
|
9480
9763
|
} catch {
|
|
9481
9764
|
}
|
|
9482
9765
|
}
|
|
9483
|
-
const sizeBytes = existsSync30(rec.localPath) ?
|
|
9766
|
+
const sizeBytes = existsSync30(rec.localPath) ? statSync7(rec.localPath).size : 0;
|
|
9484
9767
|
clips.set(rec.id, { path: rec.localPath, mime: rec.mime });
|
|
9485
9768
|
recordings.delete(key2);
|
|
9486
9769
|
return { sizeBytes };
|
|
@@ -9557,7 +9840,7 @@ async function handlePreviewClip(res, url) {
|
|
|
9557
9840
|
res.setHeader("content-type", "application/json");
|
|
9558
9841
|
return void res.end(JSON.stringify({ error: "clip_not_found", id }));
|
|
9559
9842
|
}
|
|
9560
|
-
const size =
|
|
9843
|
+
const size = statSync7(clip.path).size;
|
|
9561
9844
|
res.statusCode = 200;
|
|
9562
9845
|
res.setHeader("content-type", clip.mime);
|
|
9563
9846
|
res.setHeader("content-length", String(size));
|
|
@@ -11170,6 +11453,7 @@ function shouldRevealError(args) {
|
|
|
11170
11453
|
var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
|
|
11171
11454
|
var init_validation = __esm({
|
|
11172
11455
|
"../../core/ts/src/validation.ts"() {
|
|
11456
|
+
"use strict";
|
|
11173
11457
|
EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
|
|
11174
11458
|
URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
|
|
11175
11459
|
INTEGER_RE = /^[+-]?[0-9]+$/;
|
|
@@ -14515,6 +14799,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
|
|
|
14515
14799
|
var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
|
|
14516
14800
|
var init_worker_subtree = __esm({
|
|
14517
14801
|
"../../core/ts/src/worker-subtree.ts"() {
|
|
14802
|
+
"use strict";
|
|
14518
14803
|
init_worker_subtree_safe_types_generated();
|
|
14519
14804
|
WORKER_SUBTREE_CEILINGS = Object.freeze({
|
|
14520
14805
|
maxEncodedBytes: 65536,
|
|
@@ -14734,8 +15019,8 @@ function ensureCountUpRuntime() {
|
|
|
14734
15019
|
const neg = fixed.startsWith("-");
|
|
14735
15020
|
const body = neg ? fixed.slice(1) : fixed;
|
|
14736
15021
|
const [int, frac] = body.split(".");
|
|
14737
|
-
const
|
|
14738
|
-
return (neg ? "-" : "") +
|
|
15022
|
+
const sep11 = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
15023
|
+
return (neg ? "-" : "") + sep11 + (frac ? "." + frac : "");
|
|
14739
15024
|
};
|
|
14740
15025
|
const animateEl = (el) => {
|
|
14741
15026
|
const node = el;
|
|
@@ -21912,18 +22197,18 @@ var init_motion_flags = __esm({
|
|
|
21912
22197
|
|
|
21913
22198
|
// ../../core/dev-server/src/kits.ts
|
|
21914
22199
|
import { readdirSync as readdirSync16, readFileSync as readFileSync36 } from "node:fs";
|
|
21915
|
-
import { resolve as resolve25, join as
|
|
22200
|
+
import { resolve as resolve25, join as join31 } from "node:path";
|
|
21916
22201
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
21917
22202
|
function listKits() {
|
|
21918
22203
|
return readdirSync16(CATALOG).filter((f) => f.endsWith(".json")).map((f) => {
|
|
21919
|
-
const { tokens, ...meta } = JSON.parse(readFileSync36(
|
|
22204
|
+
const { tokens, ...meta } = JSON.parse(readFileSync36(join31(CATALOG, f), "utf8"));
|
|
21920
22205
|
return meta;
|
|
21921
22206
|
});
|
|
21922
22207
|
}
|
|
21923
22208
|
function readKit(id) {
|
|
21924
22209
|
if (!/^[a-z0-9-]+$/.test(id)) return null;
|
|
21925
22210
|
try {
|
|
21926
|
-
return JSON.parse(readFileSync36(
|
|
22211
|
+
return JSON.parse(readFileSync36(join31(CATALOG, `${id}.json`), "utf8"));
|
|
21927
22212
|
} catch {
|
|
21928
22213
|
return null;
|
|
21929
22214
|
}
|
|
@@ -21932,7 +22217,7 @@ var ROOT5, CATALOG;
|
|
|
21932
22217
|
var init_kits = __esm({
|
|
21933
22218
|
"../../core/dev-server/src/kits.ts"() {
|
|
21934
22219
|
ROOT5 = resolve25(fileURLToPath15(new URL("../../..", import.meta.url)));
|
|
21935
|
-
CATALOG =
|
|
22220
|
+
CATALOG = join31(ROOT5, "stdlib/design-kits");
|
|
21936
22221
|
}
|
|
21937
22222
|
});
|
|
21938
22223
|
|
|
@@ -24135,7 +24420,7 @@ __export(config_exports, {
|
|
|
24135
24420
|
validateOverlayPatch: () => validateOverlayPatch
|
|
24136
24421
|
});
|
|
24137
24422
|
import { mkdirSync as mkdirSync15, readFileSync as readFileSync38, writeFileSync as writeFileSync12 } from "node:fs";
|
|
24138
|
-
import { dirname as dirname21, join as
|
|
24423
|
+
import { dirname as dirname21, join as join32, resolve as resolve27 } from "node:path";
|
|
24139
24424
|
import { fileURLToPath as fileURLToPath16 } from "node:url";
|
|
24140
24425
|
function strip(line) {
|
|
24141
24426
|
const h = line.indexOf("#");
|
|
@@ -24200,14 +24485,14 @@ function parseRevocationsYaml(text2) {
|
|
|
24200
24485
|
function appConfigPath(app, file, root = REPO_ROOT6) {
|
|
24201
24486
|
assertAppId(app, "appConfigPath");
|
|
24202
24487
|
for (const base of ["apps", "test-apps"]) {
|
|
24203
|
-
const p =
|
|
24488
|
+
const p = join32(root, base, app, file);
|
|
24204
24489
|
try {
|
|
24205
24490
|
readFileSync38(p);
|
|
24206
24491
|
return p;
|
|
24207
24492
|
} catch {
|
|
24208
24493
|
}
|
|
24209
24494
|
}
|
|
24210
|
-
return
|
|
24495
|
+
return join32(root, "apps", app, file);
|
|
24211
24496
|
}
|
|
24212
24497
|
function serializeRolloutYaml(cfg) {
|
|
24213
24498
|
const lines = [`app: ${cfg.app}`, "rings:"];
|
|
@@ -24351,7 +24636,7 @@ var init_config2 = __esm({
|
|
|
24351
24636
|
import { createServer as createServer2 } from "node:http";
|
|
24352
24637
|
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
24353
24638
|
import { readFileSync as readFileSync39, existsSync as existsSync33, watch, mkdirSync as mkdirSync16, rmSync as rmSync4 } from "node:fs";
|
|
24354
|
-
import { extname, resolve as resolve28, normalize as normalize3, sep as
|
|
24639
|
+
import { extname, resolve as resolve28, normalize as normalize3, sep as sep6, join as join33 } from "node:path";
|
|
24355
24640
|
import { createHash as createHash15, randomUUID } from "node:crypto";
|
|
24356
24641
|
import { fileURLToPath as fileURLToPath17, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
24357
24642
|
function deepMerge2(base, patch) {
|
|
@@ -24526,7 +24811,7 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
|
|
|
24526
24811
|
}
|
|
24527
24812
|
function servedFontFaces(appDir2, tokens) {
|
|
24528
24813
|
try {
|
|
24529
|
-
const policyPath =
|
|
24814
|
+
const policyPath = join33(appDir2, "fonts.json");
|
|
24530
24815
|
const policy = existsSync33(policyPath) ? JSON.parse(readFileSync39(policyPath, "utf8")) : {};
|
|
24531
24816
|
const plan = planFonts(tokens, policy);
|
|
24532
24817
|
if (plan.families.length === 0) return void 0;
|
|
@@ -25169,7 +25454,7 @@ function startBundleSourceWatcher(state) {
|
|
|
25169
25454
|
try {
|
|
25170
25455
|
const watcher = watch(TIER5_SRC_ROOT, { persistent: false, recursive: true }, (_event, filename) => {
|
|
25171
25456
|
if (!filename || !/\.(ts|tsx)$/.test(filename)) return;
|
|
25172
|
-
const name = filename.split(
|
|
25457
|
+
const name = filename.split(sep6)[0];
|
|
25173
25458
|
if (!name || name.startsWith(".")) return;
|
|
25174
25459
|
pending.add(name);
|
|
25175
25460
|
if (timer) clearTimeout(timer);
|
|
@@ -25199,7 +25484,7 @@ async function reloadAppModule(state, opts) {
|
|
|
25199
25484
|
const outfile = resolve28(HMR_TMP_DIR, `${current.name}-${++appReloadSeq}.mjs`);
|
|
25200
25485
|
try {
|
|
25201
25486
|
const lib = await import(pathToFileURL6(resolve28(TIER5_SRC_ROOT, "build-lib.mjs")).href);
|
|
25202
|
-
await lib.buildAppEntry(entry, outfile);
|
|
25487
|
+
await lib.buildAppEntry(entry, outfile, { confineTo: current.dir });
|
|
25203
25488
|
const mod = await import(pathToFileURL6(outfile).href);
|
|
25204
25489
|
const next = mod.default;
|
|
25205
25490
|
if (!next || !next.config || typeof next.homeScreenId !== "string" || !next.screens || typeof next.screens.exact !== "object" || Object.keys(next.screens.exact).length === 0 || !Array.isArray(next.actions) || !next.seed) {
|
|
@@ -25284,7 +25569,7 @@ function startAppSourceWatcher(state) {
|
|
|
25284
25569
|
try {
|
|
25285
25570
|
const watcher = watch(appDir2, { persistent: false, recursive: true }, (_event, filename) => {
|
|
25286
25571
|
if (!filename) return;
|
|
25287
|
-
const rel = String(filename).split(
|
|
25572
|
+
const rel = String(filename).split(sep6).join("/");
|
|
25288
25573
|
if (!classifyAppPath(rel)) return;
|
|
25289
25574
|
pending.add(rel);
|
|
25290
25575
|
if (timer) clearTimeout(timer);
|
|
@@ -27446,7 +27731,7 @@ __export(build_exports2, {
|
|
|
27446
27731
|
});
|
|
27447
27732
|
import { createHash as createHash18 } from "node:crypto";
|
|
27448
27733
|
import { readFileSync as readFileSync40, readdirSync as readdirSync18, existsSync as existsSync34 } from "node:fs";
|
|
27449
|
-
import { dirname as dirname22, join as
|
|
27734
|
+
import { dirname as dirname22, join as join34, resolve as resolve29 } from "node:path";
|
|
27450
27735
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
27451
27736
|
import { createRequire as createRequire2 } from "node:module";
|
|
27452
27737
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -27484,7 +27769,7 @@ function l10nLintOptions(locale, appDir2) {
|
|
|
27484
27769
|
const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
|
|
27485
27770
|
const catalog = /* @__PURE__ */ new Set();
|
|
27486
27771
|
for (const tag of tags) {
|
|
27487
|
-
const path =
|
|
27772
|
+
const path = join34(appDir2, "l10n", `${tag}.json`);
|
|
27488
27773
|
if (!existsSync34(path)) continue;
|
|
27489
27774
|
try {
|
|
27490
27775
|
const parsed = JSON.parse(readFileSync40(path, "utf8"));
|
|
@@ -27581,7 +27866,7 @@ function shellSha(root = REPO_ROOT7) {
|
|
|
27581
27866
|
function isMonorepoCheckout(dir) {
|
|
27582
27867
|
try {
|
|
27583
27868
|
const top = execFileSync4("git", ["rev-parse", "--show-toplevel"], { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
27584
|
-
return top.length > 0 && existsSync34(
|
|
27869
|
+
return top.length > 0 && existsSync34(join34(top, "core", "schema", "core.proto"));
|
|
27585
27870
|
} catch {
|
|
27586
27871
|
return false;
|
|
27587
27872
|
}
|
|
@@ -27811,7 +28096,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
27811
28096
|
if (addrCache.has(name)) return addrCache.get(name);
|
|
27812
28097
|
let bytes2;
|
|
27813
28098
|
try {
|
|
27814
|
-
bytes2 = readFileSync40(
|
|
28099
|
+
bytes2 = readFileSync40(join34(tier5Dir, `${name}.bundle.js`));
|
|
27815
28100
|
} catch {
|
|
27816
28101
|
return null;
|
|
27817
28102
|
}
|
|
@@ -27832,7 +28117,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
27832
28117
|
const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
|
|
27833
28118
|
if (store.putDoc) {
|
|
27834
28119
|
for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
|
|
27835
|
-
const path =
|
|
28120
|
+
const path = join34(preloaded.dir, file);
|
|
27836
28121
|
if (!existsSync34(path)) continue;
|
|
27837
28122
|
const bytes2 = readFileSync40(path);
|
|
27838
28123
|
if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
|
|
@@ -27892,7 +28177,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
27892
28177
|
const canEmitFonts = hasVendoredFloor();
|
|
27893
28178
|
try {
|
|
27894
28179
|
const appTokens = readTokensForLint(preloaded) ?? {};
|
|
27895
|
-
const policy = existsSync34(
|
|
28180
|
+
const policy = existsSync34(join34(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync40(join34(preloaded.dir, "fonts.json"), "utf8")) : {};
|
|
27896
28181
|
fontPlan = planFonts(appTokens, policy);
|
|
27897
28182
|
} catch (err) {
|
|
27898
28183
|
throw new Error(
|
|
@@ -28357,7 +28642,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
|
|
|
28357
28642
|
await store.reset(app);
|
|
28358
28643
|
const sources = {};
|
|
28359
28644
|
for (const definition of config.functions.functions) {
|
|
28360
|
-
const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) =>
|
|
28645
|
+
const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join34(preloaded.dir, "functions", `${definition.name}${extension}`));
|
|
28361
28646
|
const source = candidates.find((candidate) => existsSync34(candidate));
|
|
28362
28647
|
if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
|
|
28363
28648
|
sources[definition.name] = readFileSync40(source, "utf8");
|
|
@@ -28388,7 +28673,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
|
|
|
28388
28673
|
return { manifest, failedToBuild: [], missingBundles: [], auth: {} };
|
|
28389
28674
|
}
|
|
28390
28675
|
function listBuildableApps() {
|
|
28391
|
-
const appsDir =
|
|
28676
|
+
const appsDir = join34(REPO_ROOT7, "apps");
|
|
28392
28677
|
return readdirSync18(appsDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_")).map((d) => d.name);
|
|
28393
28678
|
}
|
|
28394
28679
|
var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
|
|
@@ -28419,9 +28704,9 @@ var init_build3 = __esm({
|
|
|
28419
28704
|
KNOWN_ICON_NAMES = [...ICON_NAMES].sort();
|
|
28420
28705
|
KNOWN_ICONS = new Set(KNOWN_ICON_NAMES);
|
|
28421
28706
|
REPO_ROOT7 = resolve29(dirname22(fileURLToPath18(import.meta.url)), "../..");
|
|
28422
|
-
TIER5_DIR =
|
|
28707
|
+
TIER5_DIR = join34(REPO_ROOT7, "core/dev-server/tier5-bundles");
|
|
28423
28708
|
requireFromHere = createRequire2(import.meta.url);
|
|
28424
|
-
SOURCEMAP_ON_DEMAND_PATH =
|
|
28709
|
+
SOURCEMAP_ON_DEMAND_PATH = join34(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
|
|
28425
28710
|
BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
|
|
28426
28711
|
}
|
|
28427
28712
|
});
|
|
@@ -28468,6 +28753,133 @@ var init_net_scenario = __esm({
|
|
|
28468
28753
|
}
|
|
28469
28754
|
});
|
|
28470
28755
|
|
|
28756
|
+
// ../../core/dev-server/src/crawl-relations.ts
|
|
28757
|
+
function inversePartner(action, declared) {
|
|
28758
|
+
if (/^toggle/i.test(action)) return null;
|
|
28759
|
+
const candidates = [];
|
|
28760
|
+
if (/^un[A-Z_a-z]/.test(action)) {
|
|
28761
|
+
candidates.push(lowerFirst(action.slice(2)), action.slice(2));
|
|
28762
|
+
} else {
|
|
28763
|
+
candidates.push("un" + action, "un" + upperFirst(action));
|
|
28764
|
+
}
|
|
28765
|
+
for (const c of candidates) if (c !== action && declared.includes(c)) return c;
|
|
28766
|
+
for (const [a, b] of PREFIX_PAIRS) {
|
|
28767
|
+
for (const [from, to] of [
|
|
28768
|
+
[a, b],
|
|
28769
|
+
[b, a]
|
|
28770
|
+
]) {
|
|
28771
|
+
if (!action.toLowerCase().startsWith(from)) continue;
|
|
28772
|
+
const rest = action.slice(from.length);
|
|
28773
|
+
for (const c of [to + rest, to + upperFirst(rest), to]) {
|
|
28774
|
+
if (c !== action && declared.includes(c)) return c;
|
|
28775
|
+
}
|
|
28776
|
+
}
|
|
28777
|
+
}
|
|
28778
|
+
return null;
|
|
28779
|
+
}
|
|
28780
|
+
function isUndoAction(action) {
|
|
28781
|
+
if (/^toggle/i.test(action)) return false;
|
|
28782
|
+
if (/^un[A-Z]/.test(action) || /^un[a-z]/.test(action)) return true;
|
|
28783
|
+
return PREFIX_PAIRS.some(([, undo]) => action.toLowerCase().startsWith(undo));
|
|
28784
|
+
}
|
|
28785
|
+
function isOptionSelection(params) {
|
|
28786
|
+
return Object.keys(params).some((k) => /^(selected|tab|segment|mode|scope)/i.test(k) || /Id$/.test(k) || k === "id");
|
|
28787
|
+
}
|
|
28788
|
+
function stripVolatile(value, depth = 0) {
|
|
28789
|
+
if (depth > 8 || value === null || typeof value !== "object") return value;
|
|
28790
|
+
if (Array.isArray(value)) return value.map((v) => stripVolatile(v, depth + 1));
|
|
28791
|
+
const out = {};
|
|
28792
|
+
for (const k of Object.keys(value).sort()) {
|
|
28793
|
+
if (VOLATILE_KEY.test(k)) continue;
|
|
28794
|
+
out[k] = stripVolatile(value[k], depth + 1);
|
|
28795
|
+
}
|
|
28796
|
+
return out;
|
|
28797
|
+
}
|
|
28798
|
+
function relationalSignature(state) {
|
|
28799
|
+
return JSON.stringify(stripVolatile(state));
|
|
28800
|
+
}
|
|
28801
|
+
function listLengths(state, depth = 4) {
|
|
28802
|
+
const out = {};
|
|
28803
|
+
const walk2 = (node, path, left) => {
|
|
28804
|
+
if (left < 0 || node === null || typeof node !== "object") return;
|
|
28805
|
+
if (Array.isArray(node)) {
|
|
28806
|
+
out[path] = node.length;
|
|
28807
|
+
return;
|
|
28808
|
+
}
|
|
28809
|
+
for (const [k, v] of Object.entries(node)) {
|
|
28810
|
+
walk2(v, path ? `${path}.${k}` : k, left - 1);
|
|
28811
|
+
}
|
|
28812
|
+
};
|
|
28813
|
+
walk2(state, "", depth);
|
|
28814
|
+
return out;
|
|
28815
|
+
}
|
|
28816
|
+
function summarizeDiff(aSig, bSig, limit = 3) {
|
|
28817
|
+
let a;
|
|
28818
|
+
let b;
|
|
28819
|
+
try {
|
|
28820
|
+
a = JSON.parse(aSig);
|
|
28821
|
+
b = JSON.parse(bSig);
|
|
28822
|
+
} catch {
|
|
28823
|
+
return aSig === bSig ? "" : "states differ (unparseable signature)";
|
|
28824
|
+
}
|
|
28825
|
+
const diffs = [];
|
|
28826
|
+
const brief = (v) => {
|
|
28827
|
+
const t = JSON.stringify(v);
|
|
28828
|
+
if (t === void 0) return "undefined";
|
|
28829
|
+
return t.length > 80 ? `${t.slice(0, 77)}\u2026` : t;
|
|
28830
|
+
};
|
|
28831
|
+
const walk2 = (x, y, path) => {
|
|
28832
|
+
if (diffs.length >= limit) return;
|
|
28833
|
+
const bothObjects = x !== null && y !== null && typeof x === "object" && typeof y === "object" && !Array.isArray(x) && !Array.isArray(y);
|
|
28834
|
+
if (bothObjects) {
|
|
28835
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(x), ...Object.keys(y)])) {
|
|
28836
|
+
walk2(x[k], y[k], path ? `${path}.${k}` : k);
|
|
28837
|
+
}
|
|
28838
|
+
return;
|
|
28839
|
+
}
|
|
28840
|
+
if (Array.isArray(x) && Array.isArray(y)) {
|
|
28841
|
+
if (x.length !== y.length) {
|
|
28842
|
+
diffs.push(`${path || "state"}: ${x.length} \u2192 ${y.length} items`);
|
|
28843
|
+
return;
|
|
28844
|
+
}
|
|
28845
|
+
for (let i = 0; i < x.length && diffs.length < limit; i++) walk2(x[i], y[i], `${path}[${i}]`);
|
|
28846
|
+
return;
|
|
28847
|
+
}
|
|
28848
|
+
const xs = brief(x);
|
|
28849
|
+
const ys = brief(y);
|
|
28850
|
+
if (xs !== ys) diffs.push(`${path || "state"}: ${xs} \u2192 ${ys}`);
|
|
28851
|
+
};
|
|
28852
|
+
walk2(a, b, "");
|
|
28853
|
+
return diffs.slice(0, limit).join("; ");
|
|
28854
|
+
}
|
|
28855
|
+
var PREFIX_PAIRS, upperFirst, lowerFirst, REFRESH_ACTION, LOAD_MORE_ACTION, FILTER_ACTION, VOLATILE_KEY;
|
|
28856
|
+
var init_crawl_relations = __esm({
|
|
28857
|
+
"../../core/dev-server/src/crawl-relations.ts"() {
|
|
28858
|
+
PREFIX_PAIRS = [
|
|
28859
|
+
["add", "remove"],
|
|
28860
|
+
["add", "delete"],
|
|
28861
|
+
// NOT ["start", "stop"]. Measured 2026-09-16: it produced 2 warnings on unmutated, correct code
|
|
28862
|
+
// (voice-journal, `start → stop` and `startBackground → stop`, both leaving
|
|
28863
|
+
// `statusLabel: "Ready" → "Ready — recording stopped"`). start/stop is a LIFECYCLE pair, not an
|
|
28864
|
+
// algebraic inverse: stopping does not unmake the recording that was started, and an app is right
|
|
28865
|
+
// to say so. Only pairs where the undo genuinely restores the prior value belong here.
|
|
28866
|
+
["open", "close"],
|
|
28867
|
+
["show", "hide"],
|
|
28868
|
+
["expand", "collapse"],
|
|
28869
|
+
["select", "deselect"],
|
|
28870
|
+
["increment", "decrement"],
|
|
28871
|
+
["follow", "unfollow"],
|
|
28872
|
+
["save", "unsave"]
|
|
28873
|
+
];
|
|
28874
|
+
upperFirst = (s) => s ? s[0].toUpperCase() + s.slice(1) : s;
|
|
28875
|
+
lowerFirst = (s) => s ? s[0].toLowerCase() + s.slice(1) : s;
|
|
28876
|
+
REFRESH_ACTION = /^(refresh|reload|retry|sync|pullToRefresh)/i;
|
|
28877
|
+
LOAD_MORE_ACTION = /^(loadMore|nextPage|fetchMore)|^more$|More$|NextPage$/;
|
|
28878
|
+
FILTER_ACTION = /^(filter|search|query|sort)|(Filter|Search|Query|Sort)/;
|
|
28879
|
+
VOLATILE_KEY = /^_|^(id|uuid|guid|nonce|seed|token|timestamp|now|revision|etag)$|(Id|ID|Uuid|Guid|Nonce|Seed|Token|At|Timestamp|Ms|Revision|ETag)$/;
|
|
28880
|
+
}
|
|
28881
|
+
});
|
|
28882
|
+
|
|
28471
28883
|
// ../../core/dev-server/src/screen-crawl.ts
|
|
28472
28884
|
var screen_crawl_exports = {};
|
|
28473
28885
|
__export(screen_crawl_exports, {
|
|
@@ -28480,6 +28892,7 @@ __export(screen_crawl_exports, {
|
|
|
28480
28892
|
crawlScreenDeep: () => crawlScreenDeep,
|
|
28481
28893
|
crawlScreenHostile: () => crawlScreenHostile,
|
|
28482
28894
|
crawlScreenJourney: () => crawlScreenJourney,
|
|
28895
|
+
crawlScreenRelations: () => crawlScreenRelations,
|
|
28483
28896
|
crawlSignature: () => crawlSignature,
|
|
28484
28897
|
deepStateSignature: () => deepStateSignature,
|
|
28485
28898
|
emptiedArrays: () => emptiedArrays,
|
|
@@ -28490,6 +28903,7 @@ __export(screen_crawl_exports, {
|
|
|
28490
28903
|
parseWorkerAction: () => parseWorkerAction,
|
|
28491
28904
|
recordScreenTraffic: () => recordScreenTraffic,
|
|
28492
28905
|
rootOnAppear: () => rootOnAppear,
|
|
28906
|
+
snapshot: () => snapshot,
|
|
28493
28907
|
structuralSignature: () => structuralSignature,
|
|
28494
28908
|
unverifiableNodes: () => unverifiableNodes,
|
|
28495
28909
|
workerArgs: () => workerArgs
|
|
@@ -29725,7 +30139,209 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
29725
30139
|
return { findings: dedupe(findings), nodesVisited: visited.size, dispatches, capped };
|
|
29726
30140
|
});
|
|
29727
30141
|
}
|
|
29728
|
-
|
|
30142
|
+
function effectiveSiteForRow(site, row) {
|
|
30143
|
+
const merged = { ...site.params ?? {}, ...site.args ?? {} };
|
|
30144
|
+
const substituted = {};
|
|
30145
|
+
for (const [k, v] of Object.entries(merged)) {
|
|
30146
|
+
substituted[k] = typeof v === "string" && v.startsWith("$item.") ? pathValue(row, v.slice("$item.".length)) : v === "$item" ? row : v;
|
|
30147
|
+
}
|
|
30148
|
+
return { ...site, params: substituted, args: void 0 };
|
|
30149
|
+
}
|
|
30150
|
+
function isRowBound(site) {
|
|
30151
|
+
const payload = { ...site.params ?? {}, ...site.args ?? {} };
|
|
30152
|
+
return Object.values(payload).some((v) => typeof v === "string" && (v === "$item" || v.startsWith("$item.")));
|
|
30153
|
+
}
|
|
30154
|
+
function collectItemsPaths(node, out = /* @__PURE__ */ new Set()) {
|
|
30155
|
+
if (!node || typeof node !== "object") return out;
|
|
30156
|
+
if (Array.isArray(node)) {
|
|
30157
|
+
for (const n of node) collectItemsPaths(n, out);
|
|
30158
|
+
return out;
|
|
30159
|
+
}
|
|
30160
|
+
const rec = node;
|
|
30161
|
+
const body = rec.body;
|
|
30162
|
+
if (body && typeof body === "object" && typeof body.type === "string" && body.props && typeof body.props === "object") {
|
|
30163
|
+
const itemsPath = body.props.itemsPath;
|
|
30164
|
+
if (typeof itemsPath === "string") out.add(itemsPath);
|
|
30165
|
+
}
|
|
30166
|
+
for (const v of Object.values(rec)) collectItemsPaths(v, out);
|
|
30167
|
+
return out;
|
|
30168
|
+
}
|
|
30169
|
+
function newlyAddedRow(before, after, itemsPath) {
|
|
30170
|
+
if (!itemsPath || itemsPath === UNTRACKED_ITEMS) return null;
|
|
30171
|
+
const rowsOf = (s) => {
|
|
30172
|
+
const provider = new FakeServiceProvider(s);
|
|
30173
|
+
const v = resolveSiteRows(itemsPath, (p) => provider.value(p));
|
|
30174
|
+
return Array.isArray(v) ? v.filter((r) => r && typeof r === "object") : [];
|
|
30175
|
+
};
|
|
30176
|
+
const seen = new Set(rowsOf(before).map((r) => relationalSignature(r)));
|
|
30177
|
+
const fresh = rowsOf(after).filter((r) => !seen.has(relationalSignature(r)));
|
|
30178
|
+
return fresh.length === 1 ? fresh[0] : null;
|
|
30179
|
+
}
|
|
30180
|
+
async function crawlScreenRelations(opts) {
|
|
30181
|
+
return withSwallowedRejections(async () => {
|
|
30182
|
+
const { screenId, descriptor, bundleJs } = opts;
|
|
30183
|
+
const findings = [];
|
|
30184
|
+
const byKind = { inverse: 0, refresh: 0, loadMore: 0, filter: 0 };
|
|
30185
|
+
let checked = 0;
|
|
30186
|
+
if (!bundleJs) return { findings, checked, byKind };
|
|
30187
|
+
const layered = layeredTransport({ rules: opts.rules, cmsSeed: opts.cmsSeed, canned: opts.canned });
|
|
30188
|
+
const wixCall = opts.transportWrap ? opts.transportWrap(layered.call) : layered.call;
|
|
30189
|
+
const sites = actionSitesForDescriptor(descriptor).filter(
|
|
30190
|
+
(s) => parseWorkerAction(s.actionId) && !opts.skipAction?.(s.actionId, s.componentId)
|
|
30191
|
+
);
|
|
30192
|
+
const nameOf = (s) => parseWorkerAction(s.actionId).action;
|
|
30193
|
+
const serviceOf = (s) => parseWorkerAction(s.actionId).service;
|
|
30194
|
+
const boot = () => bootScreenWorker({
|
|
30195
|
+
bundleJs,
|
|
30196
|
+
descriptor,
|
|
30197
|
+
wixCall,
|
|
30198
|
+
screenId,
|
|
30199
|
+
inputOverride: opts.inputOverride,
|
|
30200
|
+
budgetMs: opts.budgetMs,
|
|
30201
|
+
clock: opts.clock,
|
|
30202
|
+
seed: opts.seed,
|
|
30203
|
+
localDbSchema: opts.localDbSchema,
|
|
30204
|
+
...opts.evaluator ? { evaluator: opts.evaluator } : {}
|
|
30205
|
+
});
|
|
30206
|
+
const replay = async (path, rowFor = () => null) => {
|
|
30207
|
+
const w = await boot();
|
|
30208
|
+
try {
|
|
30209
|
+
if (w.errors.length) return null;
|
|
30210
|
+
let prev = snapshot(w).state;
|
|
30211
|
+
const bootState = prev;
|
|
30212
|
+
for (const [i, site] of path.entries()) {
|
|
30213
|
+
const parsed = parseWorkerAction(site.actionId);
|
|
30214
|
+
const h = w.handles[parsed.service];
|
|
30215
|
+
if (!h || !h.actionNames().includes(parsed.action)) return null;
|
|
30216
|
+
const pinned = rowFor(i, bootState, prev);
|
|
30217
|
+
if (pinned === UNBINDABLE_ROW) return null;
|
|
30218
|
+
const eff = pinned ? effectiveSiteForRow(site, pinned) : effectiveSiteFor(site, prev);
|
|
30219
|
+
if (!eff) return null;
|
|
30220
|
+
try {
|
|
30221
|
+
await h.dispatch(parsed.action, ...workerArgs(eff));
|
|
30222
|
+
} catch {
|
|
30223
|
+
return null;
|
|
30224
|
+
}
|
|
30225
|
+
for (let k = 0; k < 20; k++) await yieldMacrotask();
|
|
30226
|
+
if (w.errors.length) return null;
|
|
30227
|
+
prev = snapshot(w).state;
|
|
30228
|
+
}
|
|
30229
|
+
return prev;
|
|
30230
|
+
} finally {
|
|
30231
|
+
w.dispose();
|
|
30232
|
+
}
|
|
30233
|
+
};
|
|
30234
|
+
const base = await replay([]);
|
|
30235
|
+
if (!base || Object.values(base).some(hasOwnError)) return { findings, checked, byKind };
|
|
30236
|
+
const baseSig = relationalSignature(base);
|
|
30237
|
+
const baseLens = listLengths(base);
|
|
30238
|
+
const listPathOf = (itemsPath) => {
|
|
30239
|
+
if (!itemsPath || itemsPath === UNTRACKED_ITEMS || itemsPath.includes("[]")) return null;
|
|
30240
|
+
const m = /^\$service:(.+)$/.exec(itemsPath);
|
|
30241
|
+
return m && baseLens[m[1]] !== void 0 ? m[1] : null;
|
|
30242
|
+
};
|
|
30243
|
+
const screenListPaths = [
|
|
30244
|
+
...new Set(
|
|
30245
|
+
[...collectItemsPaths(descriptor)].map(listPathOf).filter((x) => x !== null)
|
|
30246
|
+
)
|
|
30247
|
+
];
|
|
30248
|
+
const trig = (s) => ({ tap: s.componentId, key: s.key, action: s.actionId });
|
|
30249
|
+
for (const s of sites.filter((s2) => REFRESH_ACTION.test(nameOf(s2)) || s2.key === "onPullToRefresh")) {
|
|
30250
|
+
const after = await replay([s]);
|
|
30251
|
+
if (!after) continue;
|
|
30252
|
+
checked++;
|
|
30253
|
+
byKind.refresh++;
|
|
30254
|
+
const sig = relationalSignature(after);
|
|
30255
|
+
if (sig !== baseSig) {
|
|
30256
|
+
findings.push({
|
|
30257
|
+
screen: screenId,
|
|
30258
|
+
trigger: trig(s),
|
|
30259
|
+
invariant: "refresh-not-idempotent",
|
|
30260
|
+
severity: "warning",
|
|
30261
|
+
axis: "relation",
|
|
30262
|
+
message: `${nameOf(s)} from a fresh boot settles on a different state than the boot itself, under identical data: ${summarizeDiff(baseSig, sig)}`,
|
|
30263
|
+
hint: "a refresh that appends instead of replacing, or clears a flag the loader set \u2014 REPLACE collections on refresh; ids, *At and _counters are already ignored by this comparison"
|
|
30264
|
+
});
|
|
30265
|
+
}
|
|
30266
|
+
}
|
|
30267
|
+
for (const s of sites.filter((s2) => LOAD_MORE_ACTION.test(nameOf(s2)) || s2.key === "onLoadMore")) {
|
|
30268
|
+
const target = listPathOf(s.itemsPath);
|
|
30269
|
+
const after = target ? await replay([s]) : null;
|
|
30270
|
+
if (!after) continue;
|
|
30271
|
+
checked++;
|
|
30272
|
+
byKind.loadMore++;
|
|
30273
|
+
for (const [p, n] of Object.entries(listLengths(after))) {
|
|
30274
|
+
if (p === target && baseLens[p] !== void 0 && n < baseLens[p]) {
|
|
30275
|
+
findings.push({
|
|
30276
|
+
screen: screenId,
|
|
30277
|
+
trigger: trig(s),
|
|
30278
|
+
invariant: "list-shrank-on-load-more",
|
|
30279
|
+
severity: "warning",
|
|
30280
|
+
axis: "relation",
|
|
30281
|
+
at: p,
|
|
30282
|
+
actual: `${baseLens[p]} \u2192 ${n}`,
|
|
30283
|
+
message: `${nameOf(s)} shrank ${p} from ${baseLens[p]} to ${n} rows \u2014 a "load more" that replaces the page instead of appending it`,
|
|
30284
|
+
hint: "append the new page to the existing rows (and de-duplicate by id); the user scrolled to see MORE"
|
|
30285
|
+
});
|
|
30286
|
+
}
|
|
30287
|
+
}
|
|
30288
|
+
}
|
|
30289
|
+
for (const s of sites.filter((s2) => FILTER_ACTION.test(nameOf(s2)) && !isOptionSelection({ ...s2.params, ...s2.args }))) {
|
|
30290
|
+
if (screenListPaths.length !== 1) continue;
|
|
30291
|
+
const after = await replay([s]);
|
|
30292
|
+
if (!after) continue;
|
|
30293
|
+
checked++;
|
|
30294
|
+
byKind.filter++;
|
|
30295
|
+
for (const [p, n] of Object.entries(listLengths(after))) {
|
|
30296
|
+
if (screenListPaths.includes(p) && baseLens[p] !== void 0 && n > baseLens[p]) {
|
|
30297
|
+
findings.push({
|
|
30298
|
+
screen: screenId,
|
|
30299
|
+
trigger: trig(s),
|
|
30300
|
+
invariant: "list-grew-on-filter",
|
|
30301
|
+
severity: "warning",
|
|
30302
|
+
axis: "relation",
|
|
30303
|
+
at: p,
|
|
30304
|
+
actual: `${baseLens[p]} \u2192 ${n}`,
|
|
30305
|
+
message: `${nameOf(s)} grew ${p} from ${baseLens[p]} to ${n} rows \u2014 a filter/search/sort can narrow or reorder a list, never enlarge it`,
|
|
30306
|
+
hint: "filter from the FULL set you keep aside, and assign the narrowed result \u2014 not a concatenation"
|
|
30307
|
+
});
|
|
30308
|
+
}
|
|
30309
|
+
}
|
|
30310
|
+
}
|
|
30311
|
+
const declaredNames = sites.map(nameOf);
|
|
30312
|
+
for (const a of sites) {
|
|
30313
|
+
const partner = inversePartner(nameOf(a), declaredNames);
|
|
30314
|
+
if (!partner) continue;
|
|
30315
|
+
if (isUndoAction(nameOf(a))) continue;
|
|
30316
|
+
const b = sites.find((s) => nameOf(s) === partner && serviceOf(s) === serviceOf(a) && s !== a);
|
|
30317
|
+
if (!b) continue;
|
|
30318
|
+
const undoIsRowBound = isRowBound(b);
|
|
30319
|
+
const after = await replay([a, b], (i, bootState, prev) => {
|
|
30320
|
+
if (i !== 1) return null;
|
|
30321
|
+
const row = newlyAddedRow(bootState, prev, b.itemsPath);
|
|
30322
|
+
if (row) return row;
|
|
30323
|
+
return undoIsRowBound ? UNBINDABLE_ROW : null;
|
|
30324
|
+
});
|
|
30325
|
+
if (!after) continue;
|
|
30326
|
+
checked++;
|
|
30327
|
+
byKind.inverse++;
|
|
30328
|
+
const sig = relationalSignature(after);
|
|
30329
|
+
if (sig !== baseSig) {
|
|
30330
|
+
findings.push({
|
|
30331
|
+
screen: screenId,
|
|
30332
|
+
trigger: trig(b),
|
|
30333
|
+
invariant: "inverse-pair-diverges",
|
|
30334
|
+
severity: "warning",
|
|
30335
|
+
axis: "relation",
|
|
30336
|
+
message: `${nameOf(a)} \u2192 ${nameOf(b)} does not return to the boot state: ${summarizeDiff(baseSig, sig)}`,
|
|
30337
|
+
hint: `${nameOf(b)} should undo exactly what ${nameOf(a)} did \u2014 check which row it removes (by the id it was given) and every field ${nameOf(a)} touched; ids, *At and _counters are already ignored`
|
|
30338
|
+
});
|
|
30339
|
+
}
|
|
30340
|
+
}
|
|
30341
|
+
return { findings: dedupe(findings), checked, byKind };
|
|
30342
|
+
});
|
|
30343
|
+
}
|
|
30344
|
+
var ACTION_KEYS, UNTRACKED_ITEMS, NESTED_ITEMS_SEP, REJECT_ALL_MESSAGE, VLQ, WIX_DATA_QUERY, WIX_DATA_ANY, CAPABILITY_ACTION, BLANK_WHEN_BOUND, UNBINDABLE_ROW;
|
|
29729
30345
|
var init_screen_crawl = __esm({
|
|
29730
30346
|
"../../core/dev-server/src/screen-crawl.ts"() {
|
|
29731
30347
|
init_validate_descriptor_core();
|
|
@@ -29735,6 +30351,7 @@ var init_screen_crawl = __esm({
|
|
|
29735
30351
|
init_FakeServiceProvider();
|
|
29736
30352
|
init_actionParams();
|
|
29737
30353
|
init_implications();
|
|
30354
|
+
init_crawl_relations();
|
|
29738
30355
|
ACTION_KEYS = [
|
|
29739
30356
|
"action",
|
|
29740
30357
|
"onTap",
|
|
@@ -29758,6 +30375,7 @@ var init_screen_crawl = __esm({
|
|
|
29758
30375
|
Marquee: ["items", "itemsPath", "text"],
|
|
29759
30376
|
MediaPlayer: ["items", "itemsPath"]
|
|
29760
30377
|
};
|
|
30378
|
+
UNBINDABLE_ROW = Symbol("unbindable-row");
|
|
29761
30379
|
}
|
|
29762
30380
|
});
|
|
29763
30381
|
|
|
@@ -30313,8 +30931,8 @@ __export(pack_exports, {
|
|
|
30313
30931
|
});
|
|
30314
30932
|
import { createHash as createHash19 } from "node:crypto";
|
|
30315
30933
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
30316
|
-
import { existsSync as existsSync35, mkdirSync as mkdirSync17, readFileSync as readFileSync42, readdirSync as readdirSync19, rmSync as rmSync5, statSync as
|
|
30317
|
-
import { dirname as dirname23, join as
|
|
30934
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync17, readFileSync as readFileSync42, readdirSync as readdirSync19, rmSync as rmSync5, statSync as statSync8, writeFileSync as writeFileSync13 } from "node:fs";
|
|
30935
|
+
import { dirname as dirname23, join as join35, resolve as resolve31 } from "node:path";
|
|
30318
30936
|
function writeZip(entries) {
|
|
30319
30937
|
const sorted = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
30320
30938
|
const total = sorted.reduce((n, e) => n + e.bytes.length, 0);
|
|
@@ -30408,13 +31026,13 @@ function inflateEntry(buf, entry) {
|
|
|
30408
31026
|
return bytes2;
|
|
30409
31027
|
}
|
|
30410
31028
|
function readIf(path) {
|
|
30411
|
-
return existsSync35(path) &&
|
|
31029
|
+
return existsSync35(path) && statSync8(path).isFile() ? readFileSync42(path) : null;
|
|
30412
31030
|
}
|
|
30413
31031
|
function listDir(dir) {
|
|
30414
|
-
return existsSync35(dir) ? readdirSync19(dir).filter((f) =>
|
|
31032
|
+
return existsSync35(dir) ? readdirSync19(dir).filter((f) => statSync8(join35(dir, f)).isFile()) : [];
|
|
30415
31033
|
}
|
|
30416
31034
|
function gatherReleaseEntries(appDir2) {
|
|
30417
|
-
const manifestPath =
|
|
31035
|
+
const manifestPath = join35(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
|
|
30418
31036
|
const manifestBytes = readIf(manifestPath);
|
|
30419
31037
|
if (!manifestBytes) throw new Error(`no ${HIMI_PACKAGE_MANIFEST_PATH} in ${appDir2} \u2014 build a release there first`);
|
|
30420
31038
|
const manifest = JSON.parse(manifestBytes.toString("utf8"));
|
|
@@ -30438,7 +31056,7 @@ function gatherReleaseEntries(appDir2) {
|
|
|
30438
31056
|
}
|
|
30439
31057
|
const missing = [];
|
|
30440
31058
|
for (const rel of wanted) {
|
|
30441
|
-
const bytes2 = readIf(
|
|
31059
|
+
const bytes2 = readIf(join35(appDir2, rel));
|
|
30442
31060
|
if (bytes2) entries.push({ path: rel, bytes: bytes2 });
|
|
30443
31061
|
else missing.push(rel);
|
|
30444
31062
|
}
|
|
@@ -30449,12 +31067,12 @@ function gatherReleaseEntries(appDir2) {
|
|
|
30449
31067
|
);
|
|
30450
31068
|
}
|
|
30451
31069
|
for (const name of SINGLETONS) {
|
|
30452
|
-
const bytes2 = readIf(
|
|
31070
|
+
const bytes2 = readIf(join35(appDir2, name));
|
|
30453
31071
|
if (bytes2) entries.push({ path: name, bytes: bytes2 });
|
|
30454
31072
|
}
|
|
30455
31073
|
const skipped = [];
|
|
30456
31074
|
for (const sub of ["screens", "bundles", "assets", "widgets"]) {
|
|
30457
|
-
for (const f of listDir(
|
|
31075
|
+
for (const f of listDir(join35(appDir2, sub))) {
|
|
30458
31076
|
if (!wanted.has(`${sub}/${f}`)) skipped.push(`${sub}/${f}`);
|
|
30459
31077
|
}
|
|
30460
31078
|
}
|
|
@@ -30485,18 +31103,18 @@ function buildEntries(appDir2, app, opts) {
|
|
|
30485
31103
|
return { all, header, manifest, skipped };
|
|
30486
31104
|
}
|
|
30487
31105
|
function packRelease(releaseRoot, app, out, opts = {}) {
|
|
30488
|
-
const appDir2 =
|
|
31106
|
+
const appDir2 = join35(resolve31(releaseRoot), app);
|
|
30489
31107
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
30490
31108
|
const buf = writeZip(all);
|
|
30491
|
-
const isDir = existsSync35(out) &&
|
|
30492
|
-
const outFile = isDir ?
|
|
31109
|
+
const isDir = existsSync35(out) && statSync8(out).isDirectory();
|
|
31110
|
+
const outFile = isDir ? join35(resolve31(out), packageFileName(app, header.releaseId)) : resolve31(out);
|
|
30493
31111
|
mkdirSync17(dirname23(outFile), { recursive: true });
|
|
30494
31112
|
writeFileSync13(outFile, buf);
|
|
30495
31113
|
return { app, releaseId: header.releaseId, header, out: outFile, bytes: buf.length, entryCount: all.length, skipped };
|
|
30496
31114
|
}
|
|
30497
31115
|
function resolvePackageDirDest(outDir, app, releaseId) {
|
|
30498
31116
|
const packagedApp = (dir) => {
|
|
30499
|
-
const bytes2 = readIf(
|
|
31117
|
+
const bytes2 = readIf(join35(dir, HIMI_PACKAGE_HEADER_PATH));
|
|
30500
31118
|
if (!bytes2) return void 0;
|
|
30501
31119
|
try {
|
|
30502
31120
|
return JSON.parse(bytes2.toString("utf8")).app;
|
|
@@ -30506,14 +31124,14 @@ function resolvePackageDirDest(outDir, app, releaseId) {
|
|
|
30506
31124
|
};
|
|
30507
31125
|
const replaceable = (dir) => {
|
|
30508
31126
|
if (!existsSync35(dir)) return true;
|
|
30509
|
-
if (!
|
|
31127
|
+
if (!statSync8(dir).isDirectory()) return false;
|
|
30510
31128
|
return readdirSync19(dir).length === 0 || packagedApp(dir) === app;
|
|
30511
31129
|
};
|
|
30512
|
-
if (existsSync35(outDir) && !
|
|
31130
|
+
if (existsSync35(outDir) && !statSync8(outDir).isDirectory()) {
|
|
30513
31131
|
throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
|
|
30514
31132
|
}
|
|
30515
31133
|
if (replaceable(outDir)) return outDir;
|
|
30516
|
-
const child =
|
|
31134
|
+
const child = join35(outDir, packageDirName(app, releaseId));
|
|
30517
31135
|
if (!replaceable(child)) {
|
|
30518
31136
|
throw new Error(
|
|
30519
31137
|
`refusing to replace ${child}: it is not empty and is not a ${app} package (no ${HIMI_PACKAGE_HEADER_PATH}). Pass --out to a new or empty directory.`
|
|
@@ -30522,13 +31140,13 @@ function resolvePackageDirDest(outDir, app, releaseId) {
|
|
|
30522
31140
|
return child;
|
|
30523
31141
|
}
|
|
30524
31142
|
function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
|
|
30525
|
-
const appDir2 =
|
|
31143
|
+
const appDir2 = join35(resolve31(releaseRoot), app);
|
|
30526
31144
|
const { all, header, skipped } = buildEntries(appDir2, app, opts);
|
|
30527
31145
|
const dest = resolvePackageDirDest(resolve31(outDir), app, header.releaseId);
|
|
30528
31146
|
rmSync5(dest, { recursive: true, force: true });
|
|
30529
31147
|
let bytes2 = 0;
|
|
30530
31148
|
for (const entry of all) {
|
|
30531
|
-
const target =
|
|
31149
|
+
const target = join35(dest, entry.path);
|
|
30532
31150
|
mkdirSync17(dirname23(target), { recursive: true });
|
|
30533
31151
|
writeFileSync13(target, entry.bytes);
|
|
30534
31152
|
bytes2 += entry.bytes.length;
|
|
@@ -30557,11 +31175,11 @@ function openPackageDir(dir) {
|
|
|
30557
31175
|
const root = resolve31(dir);
|
|
30558
31176
|
const entries = /* @__PURE__ */ new Map();
|
|
30559
31177
|
const walk2 = (rel) => {
|
|
30560
|
-
const abs = rel ?
|
|
31178
|
+
const abs = rel ? join35(root, rel) : root;
|
|
30561
31179
|
for (const name of readdirSync19(abs)) {
|
|
30562
31180
|
const childRel = rel ? `${rel}/${name}` : name;
|
|
30563
|
-
const childAbs =
|
|
30564
|
-
if (
|
|
31181
|
+
const childAbs = join35(abs, name);
|
|
31182
|
+
if (statSync8(childAbs).isDirectory()) walk2(childRel);
|
|
30565
31183
|
else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync42(childAbs));
|
|
30566
31184
|
}
|
|
30567
31185
|
};
|
|
@@ -30599,10 +31217,10 @@ function unpackTo(buf, dest, appFallback) {
|
|
|
30599
31217
|
if (!app) throw new Error("package declares no app id (no himi-package.json and no manifest.app)");
|
|
30600
31218
|
if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
|
|
30601
31219
|
const root = resolve31(dest);
|
|
30602
|
-
const appDir2 =
|
|
31220
|
+
const appDir2 = join35(root, app);
|
|
30603
31221
|
rmSync5(appDir2, { recursive: true, force: true });
|
|
30604
31222
|
for (const [rel, bytes2] of entries) {
|
|
30605
|
-
const target =
|
|
31223
|
+
const target = join35(appDir2, rel);
|
|
30606
31224
|
mkdirSync17(dirname23(target), { recursive: true });
|
|
30607
31225
|
writeFileSync13(target, bytes2);
|
|
30608
31226
|
}
|
|
@@ -30634,14 +31252,14 @@ __export(app_source_exports, {
|
|
|
30634
31252
|
zipAppSource: () => zipAppSource
|
|
30635
31253
|
});
|
|
30636
31254
|
import { readdirSync as readdirSync20, lstatSync as lstatSync4, readFileSync as readFileSync43, mkdirSync as mkdirSync18, writeFileSync as writeFileSync14 } from "node:fs";
|
|
30637
|
-
import { join as
|
|
31255
|
+
import { join as join36, dirname as dirname24, sep as sep7 } from "node:path";
|
|
30638
31256
|
function collectAppSource(dir) {
|
|
30639
31257
|
const entries = [];
|
|
30640
31258
|
const skipped = [];
|
|
30641
31259
|
const walk2 = (relDir) => {
|
|
30642
|
-
for (const name of readdirSync20(
|
|
30643
|
-
const rel = relDir ?
|
|
30644
|
-
const st = lstatSync4(
|
|
31260
|
+
for (const name of readdirSync20(join36(dir, relDir))) {
|
|
31261
|
+
const rel = relDir ? join36(relDir, name) : name;
|
|
31262
|
+
const st = lstatSync4(join36(dir, rel));
|
|
30645
31263
|
if (st.isSymbolicLink()) {
|
|
30646
31264
|
skipped.push(rel);
|
|
30647
31265
|
continue;
|
|
@@ -30655,7 +31273,7 @@ function collectAppSource(dir) {
|
|
|
30655
31273
|
skipped.push(rel);
|
|
30656
31274
|
continue;
|
|
30657
31275
|
}
|
|
30658
|
-
entries.push({ path: rel.split(
|
|
31276
|
+
entries.push({ path: rel.split(sep7).join("/"), bytes: readFileSync43(join36(dir, rel)) });
|
|
30659
31277
|
}
|
|
30660
31278
|
};
|
|
30661
31279
|
walk2("");
|
|
@@ -30681,7 +31299,7 @@ function readAppSource(zip) {
|
|
|
30681
31299
|
function writeAppSource(entries, destDir) {
|
|
30682
31300
|
const written = [];
|
|
30683
31301
|
for (const entry of entries) {
|
|
30684
|
-
const target =
|
|
31302
|
+
const target = join36(destDir, ...entry.path.split("/"));
|
|
30685
31303
|
mkdirSync18(dirname24(target), { recursive: true });
|
|
30686
31304
|
writeFileSync14(target, entry.bytes);
|
|
30687
31305
|
written.push(entry.path);
|
|
@@ -30712,7 +31330,7 @@ __export(eject_exports, {
|
|
|
30712
31330
|
ejectModule: () => ejectModule
|
|
30713
31331
|
});
|
|
30714
31332
|
import { existsSync as existsSync36, mkdirSync as mkdirSync19, readFileSync as readFileSync44, writeFileSync as writeFileSync15 } from "node:fs";
|
|
30715
|
-
import { dirname as dirname25, join as
|
|
31333
|
+
import { dirname as dirname25, join as join37, relative as relative4, resolve as resolve32, sep as sep8 } from "node:path";
|
|
30716
31334
|
function locate(repoRootOrCwd, mod) {
|
|
30717
31335
|
const inRepo = resolve32(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
30718
31336
|
if (existsSync36(inRepo)) return { path: inRepo, form: "source" };
|
|
@@ -30741,7 +31359,7 @@ function ejectModule(opts) {
|
|
|
30741
31359
|
};
|
|
30742
31360
|
}
|
|
30743
31361
|
const ext = found.form === "source" ? "ts" : "mjs";
|
|
30744
|
-
const target =
|
|
31362
|
+
const target = join37(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
|
|
30745
31363
|
mkdirSync19(dirname25(target), { recursive: true });
|
|
30746
31364
|
const banner = `// EJECTED from @wix/himalaya/${mod}. This app owns this file now.
|
|
30747
31365
|
//
|
|
@@ -30765,7 +31383,7 @@ function ejectModule(opts) {
|
|
|
30765
31383
|
if (!existsSync36(f)) continue;
|
|
30766
31384
|
const before = readFileSync44(f, "utf8");
|
|
30767
31385
|
let after = before;
|
|
30768
|
-
let rel = relative4(dirname25(f), target).split(
|
|
31386
|
+
let rel = relative4(dirname25(f), target).split(sep8).join("/").replace(/\.tsx?$/, ".js");
|
|
30769
31387
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
30770
31388
|
for (const spec of specifiersFor(mod)) {
|
|
30771
31389
|
const q = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -30812,7 +31430,7 @@ __export(test_exports, {
|
|
|
30812
31430
|
writeRecordedMocks: () => writeRecordedMocks
|
|
30813
31431
|
});
|
|
30814
31432
|
import { existsSync as existsSync37, mkdirSync as mkdirSync20, readFileSync as readFileSync45, writeFileSync as writeFileSync16 } from "node:fs";
|
|
30815
|
-
import { join as
|
|
31433
|
+
import { join as join38, resolve as resolve33 } from "node:path";
|
|
30816
31434
|
function readTestConfig(dir) {
|
|
30817
31435
|
const p = resolve33(dir, TEST_CONFIG_FILE);
|
|
30818
31436
|
if (!existsSync37(p)) return {};
|
|
@@ -30831,8 +31449,8 @@ function readTestConfig(dir) {
|
|
|
30831
31449
|
if (typeof s.reason !== "string" || !s.reason.trim()) {
|
|
30832
31450
|
throw new Error(`${TEST_CONFIG_FILE}: skip[${i}] needs a non-empty "reason" \u2014 suppressions have to stay auditable`);
|
|
30833
31451
|
}
|
|
30834
|
-
if (!s.screen && !s.action && !s.component) {
|
|
30835
|
-
throw new Error(`${TEST_CONFIG_FILE}: skip[${i}] matches everything \u2014 give it a "screen", "action", or "
|
|
31452
|
+
if (!s.screen && !s.action && !s.component && !s.invariant) {
|
|
31453
|
+
throw new Error(`${TEST_CONFIG_FILE}: skip[${i}] matches everything \u2014 give it a "screen", "action", "component", or "invariant"`);
|
|
30836
31454
|
}
|
|
30837
31455
|
});
|
|
30838
31456
|
}
|
|
@@ -30990,8 +31608,8 @@ function writeRecordedMocks(opts) {
|
|
|
30990
31608
|
mkdir: (p) => mkdirSync20(p, { recursive: true }),
|
|
30991
31609
|
write: (p, s) => writeFileSync16(p, s)
|
|
30992
31610
|
};
|
|
30993
|
-
fs.mkdir(
|
|
30994
|
-
fs.write(
|
|
31611
|
+
fs.mkdir(join38(opts.dir, "dev"));
|
|
31612
|
+
fs.write(join38(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
|
|
30995
31613
|
return { ok: true, rules, to: "dev/net-mocks.json" };
|
|
30996
31614
|
}
|
|
30997
31615
|
function scopeDescriptors(descriptors, requestedIds, invalidScreens) {
|
|
@@ -31057,12 +31675,15 @@ async function runCrawl(opts) {
|
|
|
31057
31675
|
const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve33(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
|
|
31058
31676
|
const suppressions = opts.config?.skip ?? [];
|
|
31059
31677
|
const suppressed = [];
|
|
31060
|
-
const matchSuppression = (screen, actionId, componentId) => suppressions.find((s) => (s.screen === void 0 || s.screen === screen) && (s.action === void 0 || s.action === actionId) && (s.component === void 0 || s.component === componentId));
|
|
31678
|
+
const matchSuppression = (screen, actionId, componentId, invariant) => suppressions.find((s) => (s.screen === void 0 || s.screen === screen) && (s.action === void 0 || s.action === actionId) && (s.component === void 0 || s.component === componentId) && (s.invariant === void 0 || s.invariant === invariant));
|
|
31061
31679
|
const results = [];
|
|
31062
31680
|
const uncoveredByScreen = /* @__PURE__ */ new Map();
|
|
31063
31681
|
const coverageFns = /* @__PURE__ */ new Map();
|
|
31064
31682
|
const bundleOf = new Map(descriptors.map((d) => [d.screenId, d]));
|
|
31065
31683
|
const hostileFindings = [];
|
|
31684
|
+
const relationFindings = [];
|
|
31685
|
+
let relationsChecked = 0;
|
|
31686
|
+
const relationsByKind = { inverse: 0, refresh: 0, loadMore: 0, filter: 0 };
|
|
31066
31687
|
const deepFindings = [];
|
|
31067
31688
|
const journeyFindings = [];
|
|
31068
31689
|
const journeyResults = [];
|
|
@@ -31132,14 +31753,22 @@ async function runCrawl(opts) {
|
|
|
31132
31753
|
hostileFindings.push(...hs.filter((f) => !already.has(keyOf(f))));
|
|
31133
31754
|
}
|
|
31134
31755
|
}
|
|
31756
|
+
if (deps.crawlScreenRelations && baked.bundleJs) {
|
|
31757
|
+
const rr = await deps.crawlScreenRelations(args);
|
|
31758
|
+
relationsChecked += rr.checked;
|
|
31759
|
+
for (const [k, n] of Object.entries(rr.byKind ?? {})) relationsByKind[k] = (relationsByKind[k] ?? 0) + n;
|
|
31760
|
+
const keyOf = deps.findingKey ?? ((f) => `${f.invariant}|${f.at ?? ""}|${f.screen}|${f.message}`);
|
|
31761
|
+
const already = new Set(r.findings.map(keyOf));
|
|
31762
|
+
for (const f of rr.findings) if (!already.has(keyOf(f))) relationFindings.push(f);
|
|
31763
|
+
}
|
|
31135
31764
|
await finishScreenCoverage();
|
|
31136
31765
|
}
|
|
31137
31766
|
const keep = (f) => {
|
|
31138
31767
|
const actionId = typeof f.trigger === "object" ? f.trigger.action : "boot";
|
|
31139
31768
|
const componentId = typeof f.trigger === "object" ? f.trigger.tap : null;
|
|
31140
|
-
const s = matchSuppression(f.screen, actionId, componentId);
|
|
31141
|
-
if (s && !suppressed.some((x) => x.screen === f.screen && x.action === actionId && x.component === (componentId ?? void 0))) {
|
|
31142
|
-
suppressed.push({ screen: f.screen, action: actionId, ...componentId ? { component: componentId } : {}, reason: s.reason });
|
|
31769
|
+
const s = matchSuppression(f.screen, actionId, componentId, f.invariant);
|
|
31770
|
+
if (s && !suppressed.some((x) => x.screen === f.screen && x.action === actionId && x.component === (componentId ?? void 0) && x.invariant === s.invariant)) {
|
|
31771
|
+
suppressed.push({ screen: f.screen, action: actionId, ...componentId ? { component: componentId } : {}, ...s.invariant ? { invariant: s.invariant } : {}, reason: s.reason });
|
|
31143
31772
|
}
|
|
31144
31773
|
return !s;
|
|
31145
31774
|
};
|
|
@@ -31220,7 +31849,7 @@ async function runCrawl(opts) {
|
|
|
31220
31849
|
if (uncovered.length) uncoveredByScreen.set(screen, uncovered);
|
|
31221
31850
|
}
|
|
31222
31851
|
}
|
|
31223
|
-
const all = [...results.flatMap((r) => r.findings), ...hostileFindings, ...deepFindings, ...journeyFindings, ...edgeFindings].filter((f) => {
|
|
31852
|
+
const all = [...results.flatMap((r) => r.findings), ...hostileFindings, ...deepFindings, ...journeyFindings, ...edgeFindings, ...relationFindings].filter((f) => {
|
|
31224
31853
|
if (f.invariant === "no-request-issued" && !f.axis && fetchProven.has(f.screen)) {
|
|
31225
31854
|
const by = fetchProven.get(f.screen);
|
|
31226
31855
|
if (!retired.some((x) => x.screen === f.screen)) retired.push({ screen: f.screen, from: by.from, params: by.params });
|
|
@@ -31240,7 +31869,15 @@ async function runCrawl(opts) {
|
|
|
31240
31869
|
...blockedReasons.length ? { blockedReasons } : {},
|
|
31241
31870
|
app: opts.app,
|
|
31242
31871
|
releaseId: opts.releaseId,
|
|
31243
|
-
|
|
31872
|
+
// Whether the axis RAN, not whether it was injected. The engine is gated on `baked.bundleJs`,
|
|
31873
|
+
// so a run over static or bundle-less screens injects the dependency and replays nothing —
|
|
31874
|
+
// and the label then advertised "+ relations" beside `relations.checked: 0`. This is the
|
|
31875
|
+
// second time this line has overstated itself: it first claimed the axis unconditionally.
|
|
31876
|
+
transport: describeTransport(net, opts, {
|
|
31877
|
+
relations: relationsChecked > 0,
|
|
31878
|
+
hostile: opts.hostile !== false && Boolean(deps.crawlScreenHostile),
|
|
31879
|
+
deep: Boolean(opts.deep && opts.deep >= 2 && deps.crawlScreenDeep)
|
|
31880
|
+
}),
|
|
31244
31881
|
screens: { total: targets.length, clean: targets.length - failedScreens.size, failed: failedScreens.size },
|
|
31245
31882
|
actions: { exercised: results.reduce((n, r) => n + r.actionsExercised, 0) },
|
|
31246
31883
|
counts: { errors: failures.length, warnings: warnings.length },
|
|
@@ -31263,22 +31900,22 @@ async function runCrawl(opts) {
|
|
|
31263
31900
|
...edgesCapped.length ? { edgesCapped } : {},
|
|
31264
31901
|
...retired.length ? { retired } : {},
|
|
31265
31902
|
...opts.deep && opts.deep >= 2 ? { deep: { depth: opts.deep, ...deepTotals } } : {},
|
|
31903
|
+
...deps.crawlScreenRelations ? { relations: { checked: relationsChecked, byKind: relationsByKind } } : {},
|
|
31266
31904
|
...journeyResults.length ? { journeys: journeyResults } : {},
|
|
31267
31905
|
...results.some((r) => r.observations) ? { observations: Object.fromEntries(results.filter((r) => r.observations).map((r) => [r.screen, r.observations])) } : {}
|
|
31268
31906
|
};
|
|
31269
31907
|
}
|
|
31270
|
-
function describeTransport(net, opts) {
|
|
31908
|
+
function describeTransport(net, opts, ran) {
|
|
31271
31909
|
const layers = [];
|
|
31272
31910
|
if (net) layers.push(`mocked (${net.from})`);
|
|
31273
31911
|
const cmsCount = Object.keys(opts.cmsSeed ?? {}).length;
|
|
31274
31912
|
if (cmsCount) layers.push(`cms (${cmsCount} seeded collection${cmsCount === 1 ? "" : "s"})`);
|
|
31275
31913
|
if (opts.canned?.count) layers.push(`canned (${opts.canned.count} frozen endpoints, ${opts.canned.from} \u2014 exercises code paths, not API-contract truth)`);
|
|
31276
|
-
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
const
|
|
31280
|
-
|
|
31281
|
-
return layers.join(" + ") + hostile + deep;
|
|
31914
|
+
const base = layers.length ? layers.join(" + ") : "offline (no net fixture \u2014 screens are crawled against a rejecting transport, which exercises their failure UI)";
|
|
31915
|
+
const hostile = ran.hostile ? " + hostile boot passes (empty-lists, all-500)" : "";
|
|
31916
|
+
const relations = ran.relations ? " + relations" : "";
|
|
31917
|
+
const deep = ran.deep ? ` + deep chains (depth ${opts.deep})` : "";
|
|
31918
|
+
return base + hostile + relations + deep;
|
|
31282
31919
|
}
|
|
31283
31920
|
function formatReport(r) {
|
|
31284
31921
|
const out = [];
|
|
@@ -31413,9 +32050,9 @@ __export(mobile_ux_lint_exports, {
|
|
|
31413
32050
|
mobileUxIssues: () => mobileUxIssues
|
|
31414
32051
|
});
|
|
31415
32052
|
import { existsSync as existsSync38, readFileSync as readFileSync46 } from "node:fs";
|
|
31416
|
-
import { join as
|
|
32053
|
+
import { join as join39 } from "node:path";
|
|
31417
32054
|
function mobileUxIssues(dir, strict) {
|
|
31418
|
-
const file =
|
|
32055
|
+
const file = join39(dir, "MOBILE-UX.md");
|
|
31419
32056
|
if (!existsSync38(file)) return [];
|
|
31420
32057
|
let text2;
|
|
31421
32058
|
try {
|
|
@@ -33079,7 +33716,7 @@ __export(functions_exports, {
|
|
|
33079
33716
|
runRemoteFunctionOperation: () => runRemoteFunctionOperation
|
|
33080
33717
|
});
|
|
33081
33718
|
import { readFileSync as readFileSync47, existsSync as existsSync39 } from "node:fs";
|
|
33082
|
-
import { join as
|
|
33719
|
+
import { join as join40, resolve as resolve34 } from "node:path";
|
|
33083
33720
|
function resolveFunctionsTarget(input) {
|
|
33084
33721
|
const explicitUrl = input.functionsUrl?.trim();
|
|
33085
33722
|
if (explicitUrl) return { mode: "remote", baseUrl: explicitUrl };
|
|
@@ -33098,7 +33735,7 @@ async function loadFunctionsApp(dir) {
|
|
|
33098
33735
|
}
|
|
33099
33736
|
const sources = {};
|
|
33100
33737
|
for (const definition of config.functions.functions) {
|
|
33101
|
-
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) =>
|
|
33738
|
+
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join40(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync39);
|
|
33102
33739
|
if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
|
|
33103
33740
|
sources[definition.name] = readFileSync47(source, "utf8");
|
|
33104
33741
|
}
|
|
@@ -33256,7 +33893,7 @@ __export(native_decode_exports, {
|
|
|
33256
33893
|
import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
|
|
33257
33894
|
import { existsSync as existsSync40, mkdtempSync as mkdtempSync2, readFileSync as readFileSync48, rmSync as rmSync6, writeFileSync as writeFileSync17 } from "node:fs";
|
|
33258
33895
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
33259
|
-
import { join as
|
|
33896
|
+
import { join as join41 } from "node:path";
|
|
33260
33897
|
import { fileURLToPath as fileURLToPath19 } from "node:url";
|
|
33261
33898
|
function nativeDecodePackageDir() {
|
|
33262
33899
|
return fileURLToPath19(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
|
|
@@ -33272,7 +33909,7 @@ function detectNativeDecode(options = {}) {
|
|
|
33272
33909
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
33273
33910
|
}
|
|
33274
33911
|
if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
|
|
33275
|
-
const packageAvailable = options.packageAvailable ?? existsSync40(
|
|
33912
|
+
const packageAvailable = options.packageAvailable ?? existsSync40(join41(packageDir, "Package.swift"));
|
|
33276
33913
|
if (!packageAvailable) {
|
|
33277
33914
|
return {
|
|
33278
33915
|
platform: "ios",
|
|
@@ -33284,7 +33921,7 @@ function detectNativeDecode(options = {}) {
|
|
|
33284
33921
|
}
|
|
33285
33922
|
function localPropertiesSdk(harnessDir) {
|
|
33286
33923
|
try {
|
|
33287
|
-
const match = readFileSync48(
|
|
33924
|
+
const match = readFileSync48(join41(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
|
|
33288
33925
|
return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
|
|
33289
33926
|
} catch {
|
|
33290
33927
|
return null;
|
|
@@ -33292,7 +33929,7 @@ function localPropertiesSdk(harnessDir) {
|
|
|
33292
33929
|
}
|
|
33293
33930
|
function detectAndroidNativeDecode(options = {}) {
|
|
33294
33931
|
const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
|
|
33295
|
-
const gradlew =
|
|
33932
|
+
const gradlew = join41(harnessDir, "gradlew");
|
|
33296
33933
|
const gradlewAvailable = options.gradlewAvailable ?? existsSync40(gradlew);
|
|
33297
33934
|
if (!gradlewAvailable) {
|
|
33298
33935
|
return {
|
|
@@ -33375,14 +34012,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
|
|
|
33375
34012
|
return verdicts;
|
|
33376
34013
|
}
|
|
33377
34014
|
function runNativeDecode(options) {
|
|
33378
|
-
const descriptorDir = mkdtempSync2(
|
|
34015
|
+
const descriptorDir = mkdtempSync2(join41(tmpdir3(), "himi-native-decode-"));
|
|
33379
34016
|
const startedAt = Date.now();
|
|
33380
34017
|
try {
|
|
33381
34018
|
for (const descriptor of options.descriptors) {
|
|
33382
34019
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
33383
34020
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
33384
34021
|
}
|
|
33385
|
-
writeFileSync17(
|
|
34022
|
+
writeFileSync17(join41(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
33386
34023
|
}
|
|
33387
34024
|
options.progress?.("building cached Swift oracle");
|
|
33388
34025
|
execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
|
|
@@ -33394,7 +34031,7 @@ function runNativeDecode(options) {
|
|
|
33394
34031
|
encoding: "utf8"
|
|
33395
34032
|
}).trim();
|
|
33396
34033
|
options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
33397
|
-
const stdout = execFileSync5(
|
|
34034
|
+
const stdout = execFileSync5(join41(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
|
|
33398
34035
|
stdio: ["ignore", "pipe", "pipe"],
|
|
33399
34036
|
encoding: "utf8"
|
|
33400
34037
|
});
|
|
@@ -33412,15 +34049,15 @@ function runNativeDecode(options) {
|
|
|
33412
34049
|
}
|
|
33413
34050
|
}
|
|
33414
34051
|
function runAndroidNativeDecode(options) {
|
|
33415
|
-
const descriptorDir = mkdtempSync2(
|
|
33416
|
-
const outputPath =
|
|
34052
|
+
const descriptorDir = mkdtempSync2(join41(tmpdir3(), "himi-native-decode-android-"));
|
|
34053
|
+
const outputPath = join41(descriptorDir, "verdicts.ndjson");
|
|
33417
34054
|
const startedAt = Date.now();
|
|
33418
34055
|
try {
|
|
33419
34056
|
for (const descriptor of options.descriptors) {
|
|
33420
34057
|
if (typeof descriptor.descriptorJson !== "string") {
|
|
33421
34058
|
throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
|
|
33422
34059
|
}
|
|
33423
|
-
writeFileSync17(
|
|
34060
|
+
writeFileSync17(join41(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
|
|
33424
34061
|
}
|
|
33425
34062
|
options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
|
|
33426
34063
|
execFileSync5(options.gradlew, [
|
|
@@ -33506,23 +34143,23 @@ __export(browser_authoring_exports, {
|
|
|
33506
34143
|
import { createServer as createServer3 } from "node:http";
|
|
33507
34144
|
import { createHash as createHash22, randomBytes as randomBytes5 } from "node:crypto";
|
|
33508
34145
|
import { execFile as execFile2 } from "node:child_process";
|
|
33509
|
-
import { existsSync as existsSync41, readdirSync as readdirSync21, readFileSync as readFileSync49, realpathSync as
|
|
33510
|
-
import { join as
|
|
34146
|
+
import { existsSync as existsSync41, readdirSync as readdirSync21, readFileSync as readFileSync49, realpathSync as realpathSync4, statSync as statSync9 } from "node:fs";
|
|
34147
|
+
import { join as join42, posix, relative as relative5, sep as sep9 } from "node:path";
|
|
33511
34148
|
function humanMs(ms) {
|
|
33512
34149
|
return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
|
|
33513
34150
|
}
|
|
33514
34151
|
function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
33515
|
-
const root =
|
|
34152
|
+
const root = join42(tier5SrcDir, bundleName);
|
|
33516
34153
|
const files = {};
|
|
33517
34154
|
const visitedDirs = /* @__PURE__ */ new Set();
|
|
33518
34155
|
const walk2 = (abs, rel) => {
|
|
33519
|
-
const real =
|
|
34156
|
+
const real = realpathSync4(abs);
|
|
33520
34157
|
if (visitedDirs.has(real)) return;
|
|
33521
34158
|
visitedDirs.add(real);
|
|
33522
34159
|
for (const name of readdirSync21(abs).sort()) {
|
|
33523
|
-
const childAbs =
|
|
34160
|
+
const childAbs = join42(abs, name);
|
|
33524
34161
|
const childRel = posix.join(rel, name);
|
|
33525
|
-
if (
|
|
34162
|
+
if (statSync9(childAbs).isDirectory()) {
|
|
33526
34163
|
walk2(childAbs, childRel);
|
|
33527
34164
|
} else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
|
|
33528
34165
|
files[childRel] = readFileSync49(childAbs, "utf8");
|
|
@@ -33546,18 +34183,18 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
33546
34183
|
const spec = m[1];
|
|
33547
34184
|
const virtual = posix.normalize(posix.join(dir, spec));
|
|
33548
34185
|
if (!virtual.startsWith("/tier5-src/")) continue;
|
|
33549
|
-
const onDisk =
|
|
34186
|
+
const onDisk = join42(tier5SrcDir, virtual.slice("/tier5-src/".length));
|
|
33550
34187
|
const candidates = [
|
|
33551
34188
|
onDisk,
|
|
33552
34189
|
`${onDisk}.ts`,
|
|
33553
34190
|
`${onDisk}.js`,
|
|
33554
34191
|
onDisk.replace(/\.js$/, ".ts"),
|
|
33555
|
-
|
|
33556
|
-
|
|
34192
|
+
join42(onDisk, "index.ts"),
|
|
34193
|
+
join42(onDisk, "index.js")
|
|
33557
34194
|
];
|
|
33558
34195
|
for (const abs of candidates) {
|
|
33559
|
-
if (!existsSync41(abs) ||
|
|
33560
|
-
const key2 = `/tier5-src/${relative5(tier5SrcDir, abs).split(
|
|
34196
|
+
if (!existsSync41(abs) || statSync9(abs).isDirectory()) continue;
|
|
34197
|
+
const key2 = `/tier5-src/${relative5(tier5SrcDir, abs).split(sep9).join(posix.sep)}`;
|
|
33561
34198
|
if (key2 in files) break;
|
|
33562
34199
|
files[key2] = readFileSync49(abs, "utf8");
|
|
33563
34200
|
queue.push(key2);
|
|
@@ -33768,7 +34405,7 @@ __export(coverage_exports, {
|
|
|
33768
34405
|
trendAndStore: () => trendAndStore
|
|
33769
34406
|
});
|
|
33770
34407
|
import { existsSync as existsSync42, mkdirSync as mkdirSync21, readFileSync as readFileSync50, writeFileSync as writeFileSync18 } from "node:fs";
|
|
33771
|
-
import { dirname as dirname26, join as
|
|
34408
|
+
import { dirname as dirname26, join as join43 } from "node:path";
|
|
33772
34409
|
function assembleLedger(r) {
|
|
33773
34410
|
const out = [];
|
|
33774
34411
|
for (const c of r.crawled ?? []) {
|
|
@@ -33934,7 +34571,7 @@ function assembleLedger(r) {
|
|
|
33934
34571
|
return out;
|
|
33935
34572
|
}
|
|
33936
34573
|
function trendAndStore(dir, entries) {
|
|
33937
|
-
const p =
|
|
34574
|
+
const p = join43(dir, LEDGER_FILE);
|
|
33938
34575
|
let previous = null;
|
|
33939
34576
|
try {
|
|
33940
34577
|
if (existsSync42(p)) {
|
|
@@ -33975,7 +34612,7 @@ function formatLedger(entries, trend) {
|
|
|
33975
34612
|
return out.join("\n");
|
|
33976
34613
|
}
|
|
33977
34614
|
function diffAndStoreObservations(dir, current) {
|
|
33978
|
-
const p =
|
|
34615
|
+
const p = join43(dir, OBS_FILE);
|
|
33979
34616
|
let previous = null;
|
|
33980
34617
|
try {
|
|
33981
34618
|
if (existsSync42(p)) {
|
|
@@ -34027,8 +34664,8 @@ function formatDelta(delta) {
|
|
|
34027
34664
|
var LEDGER_FILE, OBS_FILE;
|
|
34028
34665
|
var init_coverage = __esm({
|
|
34029
34666
|
"src/coverage.ts"() {
|
|
34030
|
-
LEDGER_FILE =
|
|
34031
|
-
OBS_FILE =
|
|
34667
|
+
LEDGER_FILE = join43(".himi", "test-ledger.json");
|
|
34668
|
+
OBS_FILE = join43(".himi", "test-observations.json");
|
|
34032
34669
|
}
|
|
34033
34670
|
});
|
|
34034
34671
|
|
|
@@ -35232,9 +35869,9 @@ __export(run_exports, {
|
|
|
35232
35869
|
runPackage: () => runPackage,
|
|
35233
35870
|
withoutProdServe: () => withoutProdServe
|
|
35234
35871
|
});
|
|
35235
|
-
import { cpSync, existsSync as existsSync43, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync3, readFileSync as readFileSync52, rmSync as rmSync7, statSync as
|
|
35872
|
+
import { cpSync, existsSync as existsSync43, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync3, readFileSync as readFileSync52, rmSync as rmSync7, statSync as statSync10 } from "node:fs";
|
|
35236
35873
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
35237
|
-
import { join as
|
|
35874
|
+
import { join as join44 } from "node:path";
|
|
35238
35875
|
import { spawn as spawn3 } from "node:child_process";
|
|
35239
35876
|
function makePackageRunHandler(opts) {
|
|
35240
35877
|
return makeRunHandler({
|
|
@@ -35252,8 +35889,8 @@ async function fetchBytes(url) {
|
|
|
35252
35889
|
}
|
|
35253
35890
|
async function resolvePackage(source, workDir) {
|
|
35254
35891
|
const isUrl2 = /^https?:\/\//i.test(source);
|
|
35255
|
-
if (!isUrl2 && existsSync43(source) &&
|
|
35256
|
-
const appDirManifest =
|
|
35892
|
+
if (!isUrl2 && existsSync43(source) && statSync10(source).isDirectory()) {
|
|
35893
|
+
const appDirManifest = join44(source, "release-manifest.json");
|
|
35257
35894
|
if (existsSync43(appDirManifest)) {
|
|
35258
35895
|
const opened2 = openPackageDir(source);
|
|
35259
35896
|
if (!opened2.validation.ok) {
|
|
@@ -35263,9 +35900,9 @@ async function resolvePackage(source, workDir) {
|
|
|
35263
35900
|
const app2 = opened2.header?.app ?? opened2.manifest?.app;
|
|
35264
35901
|
if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
|
|
35265
35902
|
if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
|
|
35266
|
-
const root2 = workDir ?? mkdtempSync3(
|
|
35267
|
-
const target =
|
|
35268
|
-
if (
|
|
35903
|
+
const root2 = workDir ?? mkdtempSync3(join44(tmpdir4(), "himi-run-"));
|
|
35904
|
+
const target = join44(root2, app2);
|
|
35905
|
+
if (join44(source) !== target) {
|
|
35269
35906
|
mkdirSync22(root2, { recursive: true });
|
|
35270
35907
|
rmSync7(target, { recursive: true, force: true });
|
|
35271
35908
|
cpSync(source, target, { recursive: true });
|
|
@@ -35283,7 +35920,7 @@ async function resolvePackage(source, workDir) {
|
|
|
35283
35920
|
throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
|
|
35284
35921
|
}
|
|
35285
35922
|
const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync52(source);
|
|
35286
|
-
const root = workDir ?? mkdtempSync3(
|
|
35923
|
+
const root = workDir ?? mkdtempSync3(join44(tmpdir4(), "himi-run-"));
|
|
35287
35924
|
const { app, appDir: appDir2 } = unpackTo(bytes2, root);
|
|
35288
35925
|
const opened = openPackageDir(appDir2);
|
|
35289
35926
|
if (!opened.validation.ok) {
|
|
@@ -35992,9 +36629,9 @@ __export(preflight_app_exports, {
|
|
|
35992
36629
|
pngSize: () => pngSize,
|
|
35993
36630
|
preflightApp: () => preflightApp
|
|
35994
36631
|
});
|
|
35995
|
-
import { readFileSync as readFileSync55, existsSync as existsSync46, readdirSync as readdirSync22, statSync as
|
|
36632
|
+
import { readFileSync as readFileSync55, existsSync as existsSync46, readdirSync as readdirSync22, statSync as statSync11 } from "node:fs";
|
|
35996
36633
|
import { createHash as createHash23 } from "node:crypto";
|
|
35997
|
-
import { join as
|
|
36634
|
+
import { join as join45 } from "node:path";
|
|
35998
36635
|
function analyze(projectYml, storeConfig, icon) {
|
|
35999
36636
|
const f = [];
|
|
36000
36637
|
const has = (re, s) => re.test(s);
|
|
@@ -36045,7 +36682,7 @@ async function preflightApp(app) {
|
|
|
36045
36682
|
const projectYml = existsSync46(iosProjectYml(app)) ? readFileSync55(iosProjectYml(app), "utf8") : "";
|
|
36046
36683
|
const storeConfig = existsSync46(storeConfigPath(app)) ? readFileSync55(storeConfigPath(app), "utf8") : "";
|
|
36047
36684
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
|
|
36048
|
-
const findings = analyze(projectYml, storeConfig, await appIconState(
|
|
36685
|
+
const findings = analyze(projectYml, storeConfig, await appIconState(join45(appDir(app), "ios")));
|
|
36049
36686
|
findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
|
|
36050
36687
|
findings.push(
|
|
36051
36688
|
...analyzePlayListing(playListingAssets(app)).map((finding) => ({ ...finding, level: "warn" }))
|
|
@@ -36072,16 +36709,16 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
36072
36709
|
return f;
|
|
36073
36710
|
}
|
|
36074
36711
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
36075
|
-
const root =
|
|
36712
|
+
const root = join45(storeDir(app), "metadata");
|
|
36076
36713
|
const out = /* @__PURE__ */ new Set();
|
|
36077
36714
|
if (existsSync46(root)) {
|
|
36078
36715
|
for (const n of readdirSync22(root)) if (n.endsWith(".txt")) out.add(n);
|
|
36079
36716
|
}
|
|
36080
|
-
if (existsSync46(
|
|
36717
|
+
if (existsSync46(join45(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
|
|
36081
36718
|
return out;
|
|
36082
36719
|
}
|
|
36083
36720
|
function reviewInfoFiles(app) {
|
|
36084
|
-
const dir =
|
|
36721
|
+
const dir = join45(storeDir(app), "review_information");
|
|
36085
36722
|
if (!existsSync46(dir)) return /* @__PURE__ */ new Set();
|
|
36086
36723
|
return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
|
|
36087
36724
|
}
|
|
@@ -36192,12 +36829,12 @@ function analyzePlayListing(assets) {
|
|
|
36192
36829
|
return f;
|
|
36193
36830
|
}
|
|
36194
36831
|
function playListingAssets(app, locale = "en-US") {
|
|
36195
|
-
const dir =
|
|
36832
|
+
const dir = join45(storeDir(app), "play", locale, "images");
|
|
36196
36833
|
const read = (names) => {
|
|
36197
36834
|
for (const name of names) {
|
|
36198
|
-
const p =
|
|
36835
|
+
const p = join45(dir, name);
|
|
36199
36836
|
try {
|
|
36200
|
-
if (
|
|
36837
|
+
if (statSync11(p).isFile()) return { name, bytes: readFileSync55(p) };
|
|
36201
36838
|
} catch {
|
|
36202
36839
|
}
|
|
36203
36840
|
}
|
|
@@ -36228,26 +36865,26 @@ function analyzeListing(metaFiles, shots) {
|
|
|
36228
36865
|
return f;
|
|
36229
36866
|
}
|
|
36230
36867
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
36231
|
-
const dir =
|
|
36868
|
+
const dir = join45(storeDir(app), "metadata", locale);
|
|
36232
36869
|
if (!existsSync46(dir)) return /* @__PURE__ */ new Set();
|
|
36233
36870
|
return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
|
|
36234
36871
|
}
|
|
36235
36872
|
function listScreenshots(app, locale = "en-US") {
|
|
36236
36873
|
const out = [];
|
|
36237
|
-
const flat =
|
|
36874
|
+
const flat = join45(storeDir(app), "screenshots", locale);
|
|
36238
36875
|
if (existsSync46(flat)) {
|
|
36239
36876
|
for (const png of readdirSync22(flat).filter((n) => n.endsWith(".png"))) {
|
|
36240
|
-
const sz = pngSize(readFileSync55(
|
|
36877
|
+
const sz = pngSize(readFileSync55(join45(flat, png)));
|
|
36241
36878
|
if (sz) out.push({ name: png, w: sz.w, h: sz.h });
|
|
36242
36879
|
}
|
|
36243
36880
|
}
|
|
36244
|
-
const legacy =
|
|
36881
|
+
const legacy = join45(storeDir(app), "metadata", locale, "screenshots");
|
|
36245
36882
|
if (existsSync46(legacy)) {
|
|
36246
36883
|
for (const deviceDir of readdirSync22(legacy)) {
|
|
36247
|
-
const d =
|
|
36248
|
-
if (!
|
|
36884
|
+
const d = join45(legacy, deviceDir);
|
|
36885
|
+
if (!statSync11(d).isDirectory()) continue;
|
|
36249
36886
|
for (const png of readdirSync22(d).filter((n) => n.endsWith(".png"))) {
|
|
36250
|
-
const sz = pngSize(readFileSync55(
|
|
36887
|
+
const sz = pngSize(readFileSync55(join45(d, png)));
|
|
36251
36888
|
if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
|
|
36252
36889
|
}
|
|
36253
36890
|
}
|
|
@@ -36255,12 +36892,12 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
36255
36892
|
return out;
|
|
36256
36893
|
}
|
|
36257
36894
|
function placeholderHashes2() {
|
|
36258
|
-
const templateIos =
|
|
36895
|
+
const templateIos = join45(appDir("_template"), "ios");
|
|
36259
36896
|
if (!existsSync46(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
36260
36897
|
for (const target of readdirSync22(templateIos)) {
|
|
36261
|
-
const p =
|
|
36898
|
+
const p = join45(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
36262
36899
|
try {
|
|
36263
|
-
if (!
|
|
36900
|
+
if (!statSync11(p).isFile()) continue;
|
|
36264
36901
|
return [LEGACY_PLACEHOLDER_SHA2562, createHash23("sha256").update(readFileSync55(p)).digest("hex")];
|
|
36265
36902
|
} catch {
|
|
36266
36903
|
}
|
|
@@ -36294,9 +36931,9 @@ async function pixelIssues(bytes2) {
|
|
|
36294
36931
|
async function appIconState(iosDir) {
|
|
36295
36932
|
if (!existsSync46(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
36296
36933
|
for (const target of readdirSync22(iosDir)) {
|
|
36297
|
-
const p =
|
|
36934
|
+
const p = join45(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
36298
36935
|
try {
|
|
36299
|
-
if (!
|
|
36936
|
+
if (!statSync11(p).isFile()) continue;
|
|
36300
36937
|
const bytes2 = readFileSync55(p);
|
|
36301
36938
|
const hash = createHash23("sha256").update(bytes2).digest("hex");
|
|
36302
36939
|
const pixels = await pixelIssues(bytes2);
|
|
@@ -36369,12 +37006,12 @@ __export(credential_profile_exports, {
|
|
|
36369
37006
|
});
|
|
36370
37007
|
import { existsSync as existsSync47, readFileSync as readFileSync56 } from "node:fs";
|
|
36371
37008
|
import { homedir as homedir6 } from "node:os";
|
|
36372
|
-
import { join as
|
|
37009
|
+
import { join as join46 } from "node:path";
|
|
36373
37010
|
function credentialsDir(home = homedir6()) {
|
|
36374
|
-
return
|
|
37011
|
+
return join46(home, ".himalaya", "store-credentials");
|
|
36375
37012
|
}
|
|
36376
37013
|
function profilePath(name, home = homedir6()) {
|
|
36377
|
-
return
|
|
37014
|
+
return join46(credentialsDir(home), `${name}.json`);
|
|
36378
37015
|
}
|
|
36379
37016
|
function parseProfile(text2, label2) {
|
|
36380
37017
|
let doc;
|
|
@@ -39887,7 +40524,7 @@ var init_brand_font = __esm({
|
|
|
39887
40524
|
|
|
39888
40525
|
// src/site-analyze/write-artifacts.ts
|
|
39889
40526
|
import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync20 } from "node:fs";
|
|
39890
|
-
import { join as
|
|
40527
|
+
import { join as join47 } from "node:path";
|
|
39891
40528
|
function attachVeloSources(book, sources, put) {
|
|
39892
40529
|
const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
|
|
39893
40530
|
for (const f of book.velo.files) {
|
|
@@ -40042,12 +40679,12 @@ async function downloadMedia(book, fetchImpl, put) {
|
|
|
40042
40679
|
}
|
|
40043
40680
|
async function writeBusinessBook(result, opts) {
|
|
40044
40681
|
const out = opts.outDir;
|
|
40045
|
-
mkdirSync23(
|
|
40046
|
-
mkdirSync23(
|
|
40682
|
+
mkdirSync23(join47(out, "evidence/pages"), { recursive: true });
|
|
40683
|
+
mkdirSync23(join47(out, "media/catalog"), { recursive: true });
|
|
40047
40684
|
const files = [];
|
|
40048
40685
|
const put = (rel, body) => {
|
|
40049
|
-
const p =
|
|
40050
|
-
mkdirSync23(
|
|
40686
|
+
const p = join47(out, rel);
|
|
40687
|
+
mkdirSync23(join47(p, ".."), { recursive: true });
|
|
40051
40688
|
writeFileSync20(p, body);
|
|
40052
40689
|
files.push(rel);
|
|
40053
40690
|
};
|
|
@@ -40378,8 +41015,8 @@ var init_home_descriptor = __esm({
|
|
|
40378
41015
|
});
|
|
40379
41016
|
|
|
40380
41017
|
// src/site-analyze/apply.ts
|
|
40381
|
-
import { existsSync as existsSync48, readFileSync as readFileSync60, writeFileSync as writeFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync24, realpathSync as
|
|
40382
|
-
import { dirname as dirname28, isAbsolute as isAbsolute3, join as
|
|
41018
|
+
import { existsSync as existsSync48, readFileSync as readFileSync60, writeFileSync as writeFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync24, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
|
|
41019
|
+
import { dirname as dirname28, isAbsolute as isAbsolute3, join as join48, resolve as resolve37, sep as sep10 } from "node:path";
|
|
40383
41020
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
40384
41021
|
function unpairedRedirectNote(overlay) {
|
|
40385
41022
|
if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
|
|
@@ -40394,7 +41031,7 @@ function committedShellProvisioning(path) {
|
|
|
40394
41031
|
function findRepoRoot(cwd) {
|
|
40395
41032
|
let dir = cwd;
|
|
40396
41033
|
for (let i = 0; i < 8; i++) {
|
|
40397
|
-
if (SHELL_NAMES2.some((name) => existsSync48(
|
|
41034
|
+
if (SHELL_NAMES2.some((name) => existsSync48(join48(dir, shellAppDir(name), "package.json")))) return dir;
|
|
40398
41035
|
const next = dirname28(dir);
|
|
40399
41036
|
if (next === dir) break;
|
|
40400
41037
|
dir = next;
|
|
@@ -40462,7 +41099,7 @@ function mergeCustomerOwned(committed, overlay) {
|
|
|
40462
41099
|
}
|
|
40463
41100
|
function buildMergedContract(options) {
|
|
40464
41101
|
const { appDir: appDir2, packageDir, overlay } = options;
|
|
40465
|
-
const committedPath =
|
|
41102
|
+
const committedPath = join48(appDir2, "provisioning.json");
|
|
40466
41103
|
if (!existsSync48(committedPath)) {
|
|
40467
41104
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
40468
41105
|
}
|
|
@@ -40474,23 +41111,23 @@ function buildMergedContract(options) {
|
|
|
40474
41111
|
const contained = (root, rel) => {
|
|
40475
41112
|
if (isAbsolute3(rel)) return void 0;
|
|
40476
41113
|
const full = resolve37(root, rel);
|
|
40477
|
-
return full.startsWith(resolve37(root) +
|
|
41114
|
+
return full.startsWith(resolve37(root) + sep10) ? full : void 0;
|
|
40478
41115
|
};
|
|
40479
41116
|
const stage = (fromRel, toRel) => {
|
|
40480
41117
|
const from = contained(packageDir, fromRel);
|
|
40481
|
-
const to = contained(
|
|
41118
|
+
const to = contained(join48(appDir2, STAGED), toRel.slice(STAGED.length + 1));
|
|
40482
41119
|
if (!from || !to || !existsSync48(from)) return void 0;
|
|
40483
41120
|
let real;
|
|
40484
41121
|
let realRoot;
|
|
40485
41122
|
try {
|
|
40486
|
-
real =
|
|
40487
|
-
realRoot =
|
|
41123
|
+
real = realpathSync5(from);
|
|
41124
|
+
realRoot = realpathSync5(packageDir);
|
|
40488
41125
|
} catch {
|
|
40489
41126
|
return void 0;
|
|
40490
41127
|
}
|
|
40491
|
-
if (!real.startsWith(realRoot +
|
|
41128
|
+
if (!real.startsWith(realRoot + sep10)) return void 0;
|
|
40492
41129
|
try {
|
|
40493
|
-
if (!
|
|
41130
|
+
if (!statSync12(real).isFile()) return void 0;
|
|
40494
41131
|
mkdirSync24(dirname28(to), { recursive: true });
|
|
40495
41132
|
copyFileSync3(real, to);
|
|
40496
41133
|
} catch {
|
|
@@ -40501,7 +41138,7 @@ function buildMergedContract(options) {
|
|
|
40501
41138
|
};
|
|
40502
41139
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
40503
41140
|
if (icon) branding.appIconPath = icon;
|
|
40504
|
-
const facesPath =
|
|
41141
|
+
const facesPath = join48(packageDir, "media/fonts/faces.json");
|
|
40505
41142
|
if (existsSync48(facesPath)) {
|
|
40506
41143
|
let faces = [];
|
|
40507
41144
|
try {
|
|
@@ -40526,9 +41163,9 @@ function buildMergedContract(options) {
|
|
|
40526
41163
|
merged.branding = branding;
|
|
40527
41164
|
const body = `${JSON.stringify(merged, null, 2)}
|
|
40528
41165
|
`;
|
|
40529
|
-
const path =
|
|
41166
|
+
const path = join48(packageDir, "provisioning.contract.json");
|
|
40530
41167
|
writeFileSync21(path, body);
|
|
40531
|
-
const localPath =
|
|
41168
|
+
const localPath = join48(appDir2, LOCAL_CONTRACT_REL);
|
|
40532
41169
|
mkdirSync24(dirname28(localPath), { recursive: true });
|
|
40533
41170
|
writeFileSync21(localPath, body);
|
|
40534
41171
|
staged.push(localPath);
|
|
@@ -40549,7 +41186,7 @@ async function applyOverlays(input) {
|
|
|
40549
41186
|
`shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
|
|
40550
41187
|
);
|
|
40551
41188
|
}
|
|
40552
|
-
const appDir2 =
|
|
41189
|
+
const appDir2 = join48(repoRoot2, shellAppDir(shell));
|
|
40553
41190
|
const packageDir = dirname28(resolve37(input.overlayPath));
|
|
40554
41191
|
const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
|
|
40555
41192
|
wrote.push(...staged);
|
|
@@ -40571,7 +41208,7 @@ async function applyOverlays(input) {
|
|
|
40571
41208
|
note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
|
|
40572
41209
|
};
|
|
40573
41210
|
}
|
|
40574
|
-
const pkgProv =
|
|
41211
|
+
const pkgProv = join48(cwd, "provisioning.json");
|
|
40575
41212
|
assertNotCommitted(pkgProv, input.forbiddenProvisioning);
|
|
40576
41213
|
if (existsSync48(pkgProv)) {
|
|
40577
41214
|
const cur = JSON.parse(readFileSync60(pkgProv, "utf8"));
|
|
@@ -40582,7 +41219,7 @@ async function applyOverlays(input) {
|
|
|
40582
41219
|
writeFileSync21(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
|
|
40583
41220
|
wrote.push(pkgProv);
|
|
40584
41221
|
}
|
|
40585
|
-
const pkgTokens =
|
|
41222
|
+
const pkgTokens = join48(cwd, "tokens.json");
|
|
40586
41223
|
if (existsSync48(pkgTokens) && (tokens.colors || tokens.typography)) {
|
|
40587
41224
|
const cur = JSON.parse(readFileSync60(pkgTokens, "utf8"));
|
|
40588
41225
|
const merged = deepMerge3(cur, tokens);
|
|
@@ -40590,7 +41227,7 @@ async function applyOverlays(input) {
|
|
|
40590
41227
|
wrote.push(pkgTokens);
|
|
40591
41228
|
}
|
|
40592
41229
|
const homeAction = homeRefreshActionId(shell);
|
|
40593
|
-
const homeSrc =
|
|
41230
|
+
const homeSrc = join48(cwd, "dev/index.ts");
|
|
40594
41231
|
if (homeAction && existsSync48(homeSrc)) {
|
|
40595
41232
|
const prev = readFileSync60(homeSrc, "utf8");
|
|
40596
41233
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
@@ -42574,11 +43211,11 @@ var init_site_oauth_client = __esm({
|
|
|
42574
43211
|
});
|
|
42575
43212
|
|
|
42576
43213
|
// src/cli.ts
|
|
42577
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync63, mkdirSync as mkdirSync25, writeFileSync as writeFileSync23, existsSync as existsSync50, rmSync as rmSync8, readdirSync as readdirSync23, statSync as
|
|
43214
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync63, mkdirSync as mkdirSync25, writeFileSync as writeFileSync23, existsSync as existsSync50, rmSync as rmSync8, readdirSync as readdirSync23, statSync as statSync13 } from "node:fs";
|
|
42578
43215
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
42579
43216
|
import { createHash as createHash24 } from "node:crypto";
|
|
42580
43217
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
42581
|
-
import { join as
|
|
43218
|
+
import { join as join49, resolve as resolve39, basename as basename8, dirname as dirname29 } from "node:path";
|
|
42582
43219
|
import { fileURLToPath as fileURLToPath21 } from "node:url";
|
|
42583
43220
|
|
|
42584
43221
|
// ../serve-cli/src/client.ts
|
|
@@ -45086,10 +45723,10 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
|
|
|
45086
45723
|
// src/notify.ts
|
|
45087
45724
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "node:fs";
|
|
45088
45725
|
import { homedir as homedir3 } from "node:os";
|
|
45089
|
-
import { dirname as dirname12, join as
|
|
45726
|
+
import { dirname as dirname12, join as join15 } from "node:path";
|
|
45090
45727
|
var DEFAULT_ADMIN_URL = "http://127.0.0.1:8888";
|
|
45091
45728
|
function defaultSessionsPath() {
|
|
45092
|
-
return process.env.HIMI_ADMIN_SESSIONS_FILE ??
|
|
45729
|
+
return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join15(homedir3(), ".himalaya", "admin-sessions.json");
|
|
45093
45730
|
}
|
|
45094
45731
|
function loadSessionsFile(path = defaultSessionsPath()) {
|
|
45095
45732
|
try {
|
|
@@ -45328,7 +45965,7 @@ NOTE: ${simulated} of those went to the booted iOS Simulator, NOT to the device
|
|
|
45328
45965
|
init_car();
|
|
45329
45966
|
init_preview_surfaces();
|
|
45330
45967
|
import { existsSync as existsSync12, readFileSync as readFileSync15 } from "node:fs";
|
|
45331
|
-
import { join as
|
|
45968
|
+
import { join as join16 } from "node:path";
|
|
45332
45969
|
var VALID_PLATFORM_KEYS = /* @__PURE__ */ new Set([
|
|
45333
45970
|
...PREVIEW_SURFACES.map((s) => s.platformKey).filter((k) => k !== null),
|
|
45334
45971
|
...PREVIEW_EXEMPT_PLATFORM_KEYS
|
|
@@ -45339,7 +45976,7 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
45339
45976
|
const error = (message) => issues.push({ screen: null, pass: "surfaces", severity: "error", message });
|
|
45340
45977
|
let platforms = {};
|
|
45341
45978
|
let envelopeUnreadable = false;
|
|
45342
|
-
const p =
|
|
45979
|
+
const p = join16(dir, "platforms.json");
|
|
45343
45980
|
if (existsSync12(p)) {
|
|
45344
45981
|
let raw;
|
|
45345
45982
|
try {
|
|
@@ -45372,7 +46009,7 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
45372
46009
|
});
|
|
45373
46010
|
}
|
|
45374
46011
|
if (envelopeUnreadable) return issues;
|
|
45375
|
-
const configTs =
|
|
46012
|
+
const configTs = join16(dir, "config.ts");
|
|
45376
46013
|
if (existsSync12(configTs)) {
|
|
45377
46014
|
const declared = parseCarConfig(readFileSync15(configTs, "utf8")).category;
|
|
45378
46015
|
const inEnvelope = platforms.androidauto === true;
|
|
@@ -45398,7 +46035,7 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
45398
46035
|
}
|
|
45399
46036
|
function readLocalPlatforms(dir) {
|
|
45400
46037
|
try {
|
|
45401
|
-
const raw = JSON.parse(readFileSync15(
|
|
46038
|
+
const raw = JSON.parse(readFileSync15(join16(dir, "platforms.json"), "utf8"));
|
|
45402
46039
|
return Object.fromEntries(
|
|
45403
46040
|
Object.entries(raw).filter(([k, v]) => VALID_PLATFORM_KEYS.has(k) && typeof v === "boolean")
|
|
45404
46041
|
);
|
|
@@ -45410,10 +46047,10 @@ function readLocalPlatforms(dir) {
|
|
|
45410
46047
|
// src/token-lint.ts
|
|
45411
46048
|
init_token_colors();
|
|
45412
46049
|
import { existsSync as existsSync13, readFileSync as readFileSync16 } from "node:fs";
|
|
45413
|
-
import { join as
|
|
46050
|
+
import { join as join17 } from "node:path";
|
|
45414
46051
|
function configuredTokensPath(dir) {
|
|
45415
46052
|
for (const name of ["config.ts", "config.js", "himi.config.ts"]) {
|
|
45416
|
-
const f =
|
|
46053
|
+
const f = join17(dir, name);
|
|
45417
46054
|
if (!existsSync13(f)) continue;
|
|
45418
46055
|
const src = readFileSync16(f, "utf8");
|
|
45419
46056
|
const m = /designTokensPath\s*:\s*["'`]([^"'`]+)["'`]/.exec(src);
|
|
@@ -45433,7 +46070,7 @@ function tokenColorIssues(dir, tokensPathOverride) {
|
|
|
45433
46070
|
);
|
|
45434
46071
|
}
|
|
45435
46072
|
const tokensPath = configured.path ?? "tokens.json";
|
|
45436
|
-
const p =
|
|
46073
|
+
const p = join17(dir, tokensPath);
|
|
45437
46074
|
if (!existsSync13(p)) {
|
|
45438
46075
|
if (tokensPath !== "tokens.json") {
|
|
45439
46076
|
warn(`config designTokensPath points at ${tokensPath}, which does not exist -- colour tokens were not checked`);
|
|
@@ -45481,9 +46118,9 @@ function tokenColorIssues(dir, tokensPathOverride) {
|
|
|
45481
46118
|
// src/icon-lint.ts
|
|
45482
46119
|
init_icon();
|
|
45483
46120
|
import { existsSync as existsSync16 } from "node:fs";
|
|
45484
|
-
import { join as
|
|
46121
|
+
import { join as join20 } from "node:path";
|
|
45485
46122
|
async function iconIssues(dir, strict, opts = {}) {
|
|
45486
|
-
if (!existsSync16(
|
|
46123
|
+
if (!existsSync16(join20(dir, "himalaya.content.json"))) return [];
|
|
45487
46124
|
const status = await iconStatus(dir);
|
|
45488
46125
|
const issue2 = (severity, message) => ({
|
|
45489
46126
|
screen: null,
|
|
@@ -45551,13 +46188,13 @@ function fontIssues(dir, strict) {
|
|
|
45551
46188
|
|
|
45552
46189
|
// src/stores-api-lint.ts
|
|
45553
46190
|
import { existsSync as existsSync20, readdirSync as readdirSync10, readFileSync as readFileSync22 } from "node:fs";
|
|
45554
|
-
import { join as
|
|
46191
|
+
import { join as join24 } from "node:path";
|
|
45555
46192
|
function storesV1Issues(contentDir2, strict) {
|
|
45556
|
-
const roots = [
|
|
46193
|
+
const roots = [join24(contentDir2, "tier5-src"), join24(contentDir2, "dev")].filter(existsSync20);
|
|
45557
46194
|
const files = [];
|
|
45558
46195
|
const visit = (dir) => {
|
|
45559
46196
|
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
45560
|
-
const path =
|
|
46197
|
+
const path = join24(dir, entry.name);
|
|
45561
46198
|
if (entry.isDirectory()) visit(path);
|
|
45562
46199
|
else if (/\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) files.push(path);
|
|
45563
46200
|
}
|
|
@@ -45578,7 +46215,7 @@ init_crawl_layers();
|
|
|
45578
46215
|
init_wix_gateway_rules();
|
|
45579
46216
|
init_mobile_ux_contract();
|
|
45580
46217
|
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync23, readdirSync as readdirSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
45581
|
-
import { join as
|
|
46218
|
+
import { join as join25, relative as relative3, resolve as resolve15 } from "node:path";
|
|
45582
46219
|
var EVIDENCE_RELATIVE_PATH = ".himi/ux-audit.json";
|
|
45583
46220
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
|
|
45584
46221
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
|
|
@@ -45596,12 +46233,12 @@ function walkSource(dir, root = dir) {
|
|
|
45596
46233
|
const found = [];
|
|
45597
46234
|
for (const entry of readdirSync11(dir, { withFileTypes: true })) {
|
|
45598
46235
|
if (entry.isDirectory()) {
|
|
45599
|
-
if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(
|
|
46236
|
+
if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(join25(dir, entry.name), root));
|
|
45600
46237
|
continue;
|
|
45601
46238
|
}
|
|
45602
46239
|
const ext = entry.name.slice(entry.name.lastIndexOf("."));
|
|
45603
46240
|
if (!SOURCE_EXTENSIONS.has(ext)) continue;
|
|
45604
|
-
const absolute =
|
|
46241
|
+
const absolute = join25(dir, entry.name);
|
|
45605
46242
|
const text2 = readText(absolute);
|
|
45606
46243
|
if (text2 !== null) found.push({ path: relative3(root, absolute), text: text2 });
|
|
45607
46244
|
}
|
|
@@ -45631,9 +46268,9 @@ function usesAppNetwork(source) {
|
|
|
45631
46268
|
function auditUx(content, strict = false) {
|
|
45632
46269
|
const dir = resolve15(content);
|
|
45633
46270
|
const issues = [];
|
|
45634
|
-
const evidencePath =
|
|
45635
|
-
const spec = readText(
|
|
45636
|
-
const mobile = readText(
|
|
46271
|
+
const evidencePath = join25(dir, EVIDENCE_RELATIVE_PATH);
|
|
46272
|
+
const spec = readText(join25(dir, "SPEC.md"));
|
|
46273
|
+
const mobile = readText(join25(dir, "MOBILE-UX.md"));
|
|
45637
46274
|
if (!spec) issue(issues, strict, "missing-spec", "SPEC.md is missing; define the customer task before calling this UX-ready.", "SPEC.md");
|
|
45638
46275
|
if (!mobile) {
|
|
45639
46276
|
issue(issues, strict, "missing-mobile-ux", "MOBILE-UX.md is missing; add the mobile state and platform contract.", "MOBILE-UX.md");
|
|
@@ -45672,7 +46309,7 @@ function auditUx(content, strict = false) {
|
|
|
45672
46309
|
const preview = matches(previewControl);
|
|
45673
46310
|
if (preview) issue(issues, strict, "possible-preview-control", "Possible customer-visible test/demo state control found. Keep scenario controls out of shipping UI, or document a capability-limited fallback.", preview.path);
|
|
45674
46311
|
if (usesAppNetwork(source)) {
|
|
45675
|
-
const mocksPath =
|
|
46312
|
+
const mocksPath = join25(dir, "dev", "net-mocks.json");
|
|
45676
46313
|
if (!existsSync21(mocksPath)) {
|
|
45677
46314
|
issue(issues, strict, "missing-app-mocks", "This package uses a Wix/network client but has no app-specific dev/net-mocks.json. Add fixtures for dynamic, entitlement, or recovery flows.", "dev/net-mocks.json");
|
|
45678
46315
|
} else {
|
|
@@ -45694,12 +46331,12 @@ function recordNativeAudit(content, platform, status, checks, reason) {
|
|
|
45694
46331
|
if (!normalizedChecks.length) throw new Error("--checks needs at least one comma-separated check (for example: back,keyboard,voiceover)");
|
|
45695
46332
|
if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
|
|
45696
46333
|
const dir = resolve15(content);
|
|
45697
|
-
const path =
|
|
46334
|
+
const path = join25(dir, EVIDENCE_RELATIVE_PATH);
|
|
45698
46335
|
const parsed = parseEvidence(path);
|
|
45699
46336
|
if (parsed.error) throw new Error(`${EVIDENCE_RELATIVE_PATH} ${parsed.error}`);
|
|
45700
46337
|
const evidence = parsed.evidence ?? { version: 1, platforms: {} };
|
|
45701
46338
|
evidence.platforms[platform] = { status, checks: normalizedChecks, ...reason?.trim() ? { reason: reason.trim() } : {}, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
45702
|
-
mkdirSync10(
|
|
46339
|
+
mkdirSync10(join25(dir, ".himi"), { recursive: true });
|
|
45703
46340
|
writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
|
|
45704
46341
|
return evidence;
|
|
45705
46342
|
}
|
|
@@ -45708,26 +46345,26 @@ function recordNativeAudit(content, platform, status, checks, reason) {
|
|
|
45708
46345
|
init_mobile_ux_contract();
|
|
45709
46346
|
import { readFileSync as readFileSync24, existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, copyFileSync as copyFileSync2 } from "node:fs";
|
|
45710
46347
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
45711
|
-
import { dirname as dirname15, join as
|
|
46348
|
+
import { dirname as dirname15, join as join26, resolve as resolve16 } from "node:path";
|
|
45712
46349
|
var GUIDES_DIR = resolve16(dirname15(fileURLToPath10(import.meta.url)), "../guides");
|
|
45713
46350
|
function guidesAvailable() {
|
|
45714
|
-
return existsSync22(
|
|
46351
|
+
return existsSync22(join26(GUIDES_DIR, "index.json"));
|
|
45715
46352
|
}
|
|
45716
46353
|
function loadIndex() {
|
|
45717
|
-
return JSON.parse(readFileSync24(
|
|
46354
|
+
return JSON.parse(readFileSync24(join26(GUIDES_DIR, "index.json"), "utf8"));
|
|
45718
46355
|
}
|
|
45719
46356
|
function readGuide(id) {
|
|
45720
46357
|
const meta = loadIndex().guides.find((g) => g.id === id);
|
|
45721
46358
|
if (!meta) return null;
|
|
45722
|
-
return readFileSync24(
|
|
46359
|
+
return readFileSync24(join26(GUIDES_DIR, meta.file), "utf8");
|
|
45723
46360
|
}
|
|
45724
46361
|
function loadComponentReference() {
|
|
45725
46362
|
const idx = loadIndex();
|
|
45726
|
-
return JSON.parse(readFileSync24(
|
|
46363
|
+
return JSON.parse(readFileSync24(join26(GUIDES_DIR, idx.componentReferenceFile), "utf8"));
|
|
45727
46364
|
}
|
|
45728
46365
|
function loadSdkReference() {
|
|
45729
46366
|
const idx = loadIndex();
|
|
45730
|
-
return JSON.parse(readFileSync24(
|
|
46367
|
+
return JSON.parse(readFileSync24(join26(GUIDES_DIR, idx.sdkReferenceFile), "utf8"));
|
|
45731
46368
|
}
|
|
45732
46369
|
function buildAgentPrimer() {
|
|
45733
46370
|
const idx = loadIndex();
|
|
@@ -45835,19 +46472,19 @@ function writeAgentContext(targetDir) {
|
|
|
45835
46472
|
const idx = loadIndex();
|
|
45836
46473
|
const files = [];
|
|
45837
46474
|
const write2 = (rel, body) => {
|
|
45838
|
-
const p =
|
|
46475
|
+
const p = join26(targetDir, rel);
|
|
45839
46476
|
mkdirSync11(dirname15(p), { recursive: true });
|
|
45840
46477
|
writeFileSync10(p, body);
|
|
45841
46478
|
files.push(rel);
|
|
45842
46479
|
};
|
|
45843
46480
|
const copy = (srcRel, destRel) => {
|
|
45844
|
-
const p =
|
|
46481
|
+
const p = join26(targetDir, destRel);
|
|
45845
46482
|
mkdirSync11(dirname15(p), { recursive: true });
|
|
45846
|
-
copyFileSync2(
|
|
46483
|
+
copyFileSync2(join26(GUIDES_DIR, srcRel), p);
|
|
45847
46484
|
files.push(destRel);
|
|
45848
46485
|
};
|
|
45849
46486
|
const writeIfMissing = (rel, body) => {
|
|
45850
|
-
if (existsSync22(
|
|
46487
|
+
if (existsSync22(join26(targetDir, rel))) return;
|
|
45851
46488
|
write2(rel, body);
|
|
45852
46489
|
};
|
|
45853
46490
|
write2("HIMALAYA.md", buildAgentPrimer());
|
|
@@ -45908,7 +46545,7 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
|
|
|
45908
46545
|
var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
|
|
45909
46546
|
function embeddedTemplateCatalog() {
|
|
45910
46547
|
return availableTemplates().map((name) => {
|
|
45911
|
-
const path =
|
|
46548
|
+
const path = join49(templateSourceDir(name), TEMPLATE_META_FILE);
|
|
45912
46549
|
const meta = JSON.parse(readFileSync63(path, "utf8"));
|
|
45913
46550
|
if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
|
|
45914
46551
|
throw new Error(`${path} must be { title: string, description: string, tags: string[], category?: string }`);
|
|
@@ -46375,7 +47012,7 @@ function packageVersion(path) {
|
|
|
46375
47012
|
function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
|
|
46376
47013
|
let dir = resolve39(fromDir);
|
|
46377
47014
|
for (; ; ) {
|
|
46378
|
-
const version = packageVersion(
|
|
47015
|
+
const version = packageVersion(join49(dir, "node_modules", "@wix", "himalaya", "package.json"));
|
|
46379
47016
|
if (version) return { version, source: "local" };
|
|
46380
47017
|
const parent = dirname29(dir);
|
|
46381
47018
|
if (parent === dir) break;
|
|
@@ -46385,7 +47022,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
|
|
|
46385
47022
|
if (bundled) return { version: bundled, source: "bundled" };
|
|
46386
47023
|
try {
|
|
46387
47024
|
const root = execFileSync6("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
46388
|
-
const version = root ? packageVersion(
|
|
47025
|
+
const version = root ? packageVersion(join49(root, "@wix", "himalaya", "package.json")) : void 0;
|
|
46389
47026
|
return version ? { version, source: "global" } : {};
|
|
46390
47027
|
} catch {
|
|
46391
47028
|
return {};
|
|
@@ -46760,7 +47397,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
46760
47397
|
}
|
|
46761
47398
|
function readConfigSource(dir) {
|
|
46762
47399
|
try {
|
|
46763
|
-
return readFileSync63(
|
|
47400
|
+
return readFileSync63(join49(dir, "config.ts"), "utf8");
|
|
46764
47401
|
} catch {
|
|
46765
47402
|
return null;
|
|
46766
47403
|
}
|
|
@@ -46772,7 +47409,7 @@ function writePngFile(path, base64) {
|
|
|
46772
47409
|
}
|
|
46773
47410
|
async function initFromRemoteTemplate(name, parentDir, template, c) {
|
|
46774
47411
|
const dir = resolve39(parentDir, name);
|
|
46775
|
-
if (existsSync50(
|
|
47412
|
+
if (existsSync50(join49(dir, "himalaya.content.json"))) {
|
|
46776
47413
|
throw new Error(`content package already exists at ${dir}`);
|
|
46777
47414
|
}
|
|
46778
47415
|
const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -46789,7 +47426,7 @@ function contentDir(flags) {
|
|
|
46789
47426
|
function isHimalayaMonorepoCheckout(start) {
|
|
46790
47427
|
let dir = resolve39(start);
|
|
46791
47428
|
for (; ; ) {
|
|
46792
|
-
if (existsSync50(
|
|
47429
|
+
if (existsSync50(join49(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync50(join49(dir, "core", "serve", "src", "server.ts"))) return true;
|
|
46793
47430
|
const parent = dirname29(dir);
|
|
46794
47431
|
if (parent === dir) return false;
|
|
46795
47432
|
dir = parent;
|
|
@@ -46820,7 +47457,7 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
46820
47457
|
Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
|
|
46821
47458
|
);
|
|
46822
47459
|
const repoRoot2 = resolve39(fileURLToPath21(new URL("../../..", import.meta.url)));
|
|
46823
|
-
const dest =
|
|
47460
|
+
const dest = join49(repoRoot2, "node_modules", ".cache", "himi-template-preview", slug);
|
|
46824
47461
|
rmSync8(dest, { recursive: true, force: true });
|
|
46825
47462
|
mkdirSync25(dest, { recursive: true });
|
|
46826
47463
|
materializeSource(forBuild, displayName, dest, slug);
|
|
@@ -46829,7 +47466,7 @@ function materializeForPreview(appDir2, slug, displayName) {
|
|
|
46829
47466
|
async function appId(dir) {
|
|
46830
47467
|
try {
|
|
46831
47468
|
const { readFileSync: readFileSync64 } = await import("node:fs");
|
|
46832
|
-
const m = JSON.parse(readFileSync64(
|
|
47469
|
+
const m = JSON.parse(readFileSync64(join49(dir, "himalaya.content.json"), "utf8"));
|
|
46833
47470
|
if (m.name) return m.name;
|
|
46834
47471
|
} catch {
|
|
46835
47472
|
}
|
|
@@ -46838,7 +47475,7 @@ async function appId(dir) {
|
|
|
46838
47475
|
async function contentVisibility(dir) {
|
|
46839
47476
|
try {
|
|
46840
47477
|
const { readFileSync: readFileSync64 } = await import("node:fs");
|
|
46841
|
-
const m = JSON.parse(readFileSync64(
|
|
47478
|
+
const m = JSON.parse(readFileSync64(join49(dir, "himalaya.content.json"), "utf8"));
|
|
46842
47479
|
if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
|
|
46843
47480
|
} catch {
|
|
46844
47481
|
}
|
|
@@ -47077,6 +47714,7 @@ async function loadAuthoring() {
|
|
|
47077
47714
|
crawlScreen: crawl.crawlScreen,
|
|
47078
47715
|
crawlScreenJourney: crawl.crawlScreenJourney,
|
|
47079
47716
|
crawlScreenHostile: crawl.crawlScreenHostile,
|
|
47717
|
+
crawlScreenRelations: crawl.crawlScreenRelations,
|
|
47080
47718
|
findingKey: crawl.findingKey,
|
|
47081
47719
|
startWorkerCoverage: cov.startWorkerCoverage,
|
|
47082
47720
|
uncoveredFunctions: cov.uncoveredFunctions,
|
|
@@ -47239,7 +47877,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47239
47877
|
const sourceDir = resolve39(str5(flags["source-dir"]) ?? appDir2);
|
|
47240
47878
|
let meta;
|
|
47241
47879
|
try {
|
|
47242
|
-
meta = JSON.parse(readFileSync63(
|
|
47880
|
+
meta = JSON.parse(readFileSync63(join49(sourceDir, TEMPLATE_META_FILE), "utf8"));
|
|
47243
47881
|
} catch {
|
|
47244
47882
|
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>)` }));
|
|
47245
47883
|
return 2;
|
|
@@ -47249,7 +47887,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47249
47887
|
return 2;
|
|
47250
47888
|
}
|
|
47251
47889
|
try {
|
|
47252
|
-
const appearance = extractTemplateAppearance(JSON.parse(readFileSync63(
|
|
47890
|
+
const appearance = extractTemplateAppearance(JSON.parse(readFileSync63(join49(sourceDir, "tokens.json"), "utf8")));
|
|
47253
47891
|
meta = { ...appearance, ...meta };
|
|
47254
47892
|
} catch {
|
|
47255
47893
|
}
|
|
@@ -47261,7 +47899,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47261
47899
|
const force = flags.force === true;
|
|
47262
47900
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
47263
47901
|
const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
|
|
47264
|
-
const out = mkdtempSync4(
|
|
47902
|
+
const out = mkdtempSync4(join49(tmpdir5(), "himi-template-"));
|
|
47265
47903
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
47266
47904
|
const outcome = await buildReleaseFromContent2(buildDir, out, {
|
|
47267
47905
|
...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
|
|
@@ -47420,7 +48058,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47420
48058
|
const { mobileUxIssues: mobileUxIssues2 } = await Promise.resolve().then(() => (init_mobile_ux_lint(), mobile_ux_lint_exports));
|
|
47421
48059
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
47422
48060
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
47423
|
-
const out = mkdtempSync4(
|
|
48061
|
+
const out = mkdtempSync4(join49(tmpdir5(), "himi-validate-"));
|
|
47424
48062
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
47425
48063
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
47426
48064
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -47608,7 +48246,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47608
48246
|
case "test": {
|
|
47609
48247
|
const dir = contentDir(flags);
|
|
47610
48248
|
const structuredOutput = flags.json === true || io.isTTY !== true;
|
|
47611
|
-
if (existsSync50(
|
|
48249
|
+
if (existsSync50(join49(dir, "functions"))) {
|
|
47612
48250
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
47613
48251
|
const loaded = await loadFunctionsApp2(dir);
|
|
47614
48252
|
const results = [];
|
|
@@ -47622,7 +48260,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47622
48260
|
return results.every((result2) => result2.ok) ? 0 : 1;
|
|
47623
48261
|
}
|
|
47624
48262
|
const app = await appId(dir);
|
|
47625
|
-
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2, crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2, recordScreenTraffic: recordScreenTraffic2, mintVisitor: mintVisitor2, webWixCall: webWixCall2, freezeTrafficToMocks: freezeTrafficToMocks2, bootAndSnapshotState: bootAndSnapshotState2, renderDescriptorWeb: renderDescriptorWeb2, renderPngBatch: renderPngBatch2, pngAvailable: pngAvailable2, crawlBlockingPasses } = await loadAuthoring();
|
|
48263
|
+
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2, crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, crawlScreenRelations: crawlScreenRelations2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2, recordScreenTraffic: recordScreenTraffic2, mintVisitor: mintVisitor2, webWixCall: webWixCall2, freezeTrafficToMocks: freezeTrafficToMocks2, bootAndSnapshotState: bootAndSnapshotState2, renderDescriptorWeb: renderDescriptorWeb2, renderPngBatch: renderPngBatch2, pngAvailable: pngAvailable2, crawlBlockingPasses } = await loadAuthoring();
|
|
47626
48264
|
const { readTestConfig: readTestConfig2, runCrawl: runCrawl2, formatReport: formatReport2, readCannedResponses: readCannedResponses2, makeRecordingWixCall: makeRecordingWixCall2, runRecordPass: runRecordPass2, runShotsPass: runShotsPass2, defaultNetRules: defaultNetRules2, readNetRules: readNetRules2, scopeDescriptors: scopeDescriptors2, writeRecordedMocks: writeRecordedMocks2 } = await Promise.resolve().then(() => (init_test(), test_exports));
|
|
47627
48265
|
let config;
|
|
47628
48266
|
try {
|
|
@@ -47695,7 +48333,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47695
48333
|
}
|
|
47696
48334
|
}
|
|
47697
48335
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
47698
|
-
const out = mkdtempSync4(
|
|
48336
|
+
const out = mkdtempSync4(join49(tmpdir5(), "himi-test-"));
|
|
47699
48337
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
47700
48338
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
47701
48339
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -47740,7 +48378,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47740
48378
|
io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
|
|
47741
48379
|
return 2;
|
|
47742
48380
|
}
|
|
47743
|
-
const sources = collectWorkerSources2(
|
|
48381
|
+
const sources = collectWorkerSources2(join49(dir, "tier5-src"), screen.bundleName);
|
|
47744
48382
|
if (!sources) {
|
|
47745
48383
|
io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
|
|
47746
48384
|
return 2;
|
|
@@ -47860,7 +48498,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47860
48498
|
...deep ? { deep } : {},
|
|
47861
48499
|
...offline ? { offline: true } : {},
|
|
47862
48500
|
...offline || flags["no-hostile"] === true ? { hostile: false } : {},
|
|
47863
|
-
deps: { crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2 }
|
|
48501
|
+
deps: { crawlScreen: crawlScreen2, crawlScreenJourney: crawlScreenJourney2, crawlScreenHostile: crawlScreenHostile2, crawlScreenRelations: crawlScreenRelations2, findingKey: findingKey2, startWorkerCoverage: startWorkerCoverage2, uncoveredFunctions: uncoveredFunctions2, crawlScreenDeep: crawlScreenDeep2, crawlSignature: crawlSignature2 }
|
|
47864
48502
|
});
|
|
47865
48503
|
} catch (e) {
|
|
47866
48504
|
io.error(JSON.stringify({ error: e.message }));
|
|
@@ -47897,7 +48535,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47897
48535
|
const sp = await runShotsPass2({
|
|
47898
48536
|
descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
|
|
47899
48537
|
tokens: outcome.tokens,
|
|
47900
|
-
outDir:
|
|
48538
|
+
outDir: join49(dir, ".himi", "shots"),
|
|
47901
48539
|
width: 390,
|
|
47902
48540
|
layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
|
|
47903
48541
|
...budgetMs ? { budgetMs } : {},
|
|
@@ -47933,7 +48571,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
47933
48571
|
releaseId: result.releaseId,
|
|
47934
48572
|
releasePayload: release,
|
|
47935
48573
|
descriptors: attestedDescriptors,
|
|
47936
|
-
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""),
|
|
48574
|
+
screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join49(dir, ".himi", "shots", name)])),
|
|
47937
48575
|
coverage: {
|
|
47938
48576
|
screens: crawledScreens.size,
|
|
47939
48577
|
actionsDispatched: result.actions.exercised,
|
|
@@ -48075,7 +48713,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
48075
48713
|
}
|
|
48076
48714
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
48077
48715
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
48078
|
-
const out = mkdtempSync4(
|
|
48716
|
+
const out = mkdtempSync4(join49(tmpdir5(), "himi-render-"));
|
|
48079
48717
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
48080
48718
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
48081
48719
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -48091,7 +48729,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
|
|
|
48091
48729
|
let attestationPngFile;
|
|
48092
48730
|
if (typeof flags.png === "string" && r.pngBase64) {
|
|
48093
48731
|
pngFile = writePngFile(str5(flags.png), r.pngBase64);
|
|
48094
|
-
attestationPngFile = writePngFile(
|
|
48732
|
+
attestationPngFile = writePngFile(join49(dir, ".himi", "shots", `${screenId}.png`), r.pngBase64);
|
|
48095
48733
|
}
|
|
48096
48734
|
const legacyRender = {
|
|
48097
48735
|
ok: r.renderable,
|
|
@@ -48398,7 +49036,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
48398
49036
|
const renamed = str5(flags.name);
|
|
48399
49037
|
const dest = resolve39(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
|
|
48400
49038
|
if (existsSync50(dest)) {
|
|
48401
|
-
if (!
|
|
49039
|
+
if (!statSync13(dest).isDirectory()) {
|
|
48402
49040
|
io.error(JSON.stringify({
|
|
48403
49041
|
error: `${dest} exists and is not a directory`,
|
|
48404
49042
|
hint: "pass --out/--name to land somewhere else, or remove the file"
|
|
@@ -48471,7 +49109,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
48471
49109
|
const force = flags.force === true;
|
|
48472
49110
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
48473
49111
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
48474
|
-
const out = mkdtempSync4(
|
|
49112
|
+
const out = mkdtempSync4(join49(tmpdir5(), "himi-push-"));
|
|
48475
49113
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
48476
49114
|
const outcome = await buildReleaseFromContent2(dir, out, {
|
|
48477
49115
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -48763,7 +49401,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
48763
49401
|
const force = flags.force === true;
|
|
48764
49402
|
const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
48765
49403
|
const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
|
|
48766
|
-
const built = mkdtempSync4(
|
|
49404
|
+
const built = mkdtempSync4(join49(tmpdir5(), "himi-pack-"));
|
|
48767
49405
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
48768
49406
|
const outcome = await buildReleaseFromContent2(dir, built, {
|
|
48769
49407
|
...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
|
|
@@ -48876,10 +49514,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
|
|
|
48876
49514
|
const app = await appId(dir);
|
|
48877
49515
|
const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
|
|
48878
49516
|
const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
|
|
48879
|
-
temp = mkdtempSync4(
|
|
49517
|
+
temp = mkdtempSync4(join49(tmpdir5(), "himi-run-build-"));
|
|
48880
49518
|
const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
|
|
48881
49519
|
await buildReleaseFromContent2(dir, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
|
|
48882
|
-
source =
|
|
49520
|
+
source = join49(temp, app);
|
|
48883
49521
|
}
|
|
48884
49522
|
const chromeArg = str5(flags.chrome) ?? "preview";
|
|
48885
49523
|
if (chromeArg !== "preview" && chromeArg !== "app") {
|
|
@@ -49677,7 +50315,7 @@ ${label2}`);
|
|
|
49677
50315
|
const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
|
|
49678
50316
|
{
|
|
49679
50317
|
const distDir = contentDir(flags);
|
|
49680
|
-
if (existsSync50(
|
|
50318
|
+
if (existsSync50(join49(distDir, "himalaya.content.json"))) {
|
|
49681
50319
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
49682
50320
|
const errors = issues.filter((i) => i.severity === "error");
|
|
49683
50321
|
for (const i of issues.filter((i2) => i2.severity === "warning")) {
|