@wix/himalaya-cli 0.1534.0 → 0.1535.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 +1161 -531
- package/guides/index.json +1 -1
- package/guides/sdk-reference.json +36 -610
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -2380,11 +2380,446 @@ var init_app_link = __esm({
|
|
|
2380
2380
|
});
|
|
2381
2381
|
|
|
2382
2382
|
// ../../core/serve-control/src/dist-jobs.ts
|
|
2383
|
-
var
|
|
2383
|
+
var dist_jobs_exports = {};
|
|
2384
|
+
__export(dist_jobs_exports, {
|
|
2385
|
+
ANDROID_FORMATS: () => ANDROID_FORMATS,
|
|
2386
|
+
ANDROID_FORMAT_NOT_BUILT: () => ANDROID_FORMAT_NOT_BUILT,
|
|
2387
|
+
ANDROID_FORMAT_NOT_REQUESTED: () => ANDROID_FORMAT_NOT_REQUESTED,
|
|
2388
|
+
ANDROID_FORMAT_WRONG_SIGNER: () => ANDROID_FORMAT_WRONG_SIGNER,
|
|
2389
|
+
ANDROID_SIGNING_ALIASES: () => ANDROID_SIGNING_ALIASES,
|
|
2390
|
+
ANDROID_SIGNING_POLICIES: () => ANDROID_SIGNING_POLICIES,
|
|
2391
|
+
CUSTOMER_UPLOAD_LEASE_MS: () => CUSTOMER_UPLOAD_LEASE_MS,
|
|
2392
|
+
DEFAULT_ANDROID_FORMAT: () => DEFAULT_ANDROID_FORMAT,
|
|
2393
|
+
DEFAULT_ANDROID_SIGNING: () => DEFAULT_ANDROID_SIGNING,
|
|
2394
|
+
DEFAULT_BORROWABLE_IOS_IDS: () => DEFAULT_BORROWABLE_IOS_IDS,
|
|
2395
|
+
DEFAULT_DIST_SHELL: () => DEFAULT_DIST_SHELL,
|
|
2396
|
+
DEFAULT_DIST_SIGNING: () => DEFAULT_DIST_SIGNING,
|
|
2397
|
+
DEFAULT_GIT_URL: () => DEFAULT_GIT_URL,
|
|
2398
|
+
DIST_PACKAGE_NAME: () => DIST_PACKAGE_NAME,
|
|
2399
|
+
DIST_PARAMS_FLAG: () => DIST_PARAMS_FLAG,
|
|
2400
|
+
DIST_SHELLS: () => DIST_SHELLS,
|
|
2401
|
+
JobServiceBroker: () => JobServiceBroker,
|
|
2402
|
+
JobServiceError: () => JobServiceError,
|
|
2403
|
+
MAX_MEASURABLE_IDENTITY_WINDOW: () => MAX_MEASURABLE_IDENTITY_WINDOW,
|
|
2404
|
+
SCOPE_CANCEL: () => SCOPE_CANCEL,
|
|
2405
|
+
SCOPE_CREATE: () => SCOPE_CREATE,
|
|
2406
|
+
SCOPE_READ: () => SCOPE_READ,
|
|
2407
|
+
WIX_MANAGED_SIGNING_ALIASES: () => WIX_MANAGED_SIGNING_ALIASES,
|
|
2408
|
+
androidFormatSkewFailed: () => androidFormatSkewFailed,
|
|
2409
|
+
borrowableIosIds: () => borrowableIosIds,
|
|
2410
|
+
credsFromConfig: () => credsFromConfig,
|
|
2411
|
+
customerUploadClaimable: () => customerUploadClaimable,
|
|
2412
|
+
distJobSpec: () => distJobSpec,
|
|
2413
|
+
encodeDistParams: () => encodeDistParams,
|
|
2414
|
+
isBorrowableIosId: () => isBorrowableIosId,
|
|
2415
|
+
isSuccess: () => isSuccess,
|
|
2416
|
+
isTerminal: () => isTerminal,
|
|
2417
|
+
isTerminalTestflightStatus: () => isTerminalTestflightStatus,
|
|
2418
|
+
isValidDistAttemptId: () => isValidDistAttemptId,
|
|
2419
|
+
nextCustomerUploadClaim: () => nextCustomerUploadClaim,
|
|
2420
|
+
nextCustomerUploadSettlement: () => nextCustomerUploadSettlement,
|
|
2421
|
+
resolveAndroidFormat: () => resolveAndroidFormat,
|
|
2422
|
+
resolveAndroidSigning: () => resolveAndroidSigning,
|
|
2423
|
+
resolveBorrowedIosId: () => resolveBorrowedIosId,
|
|
2424
|
+
resolveDistSigning: () => resolveDistSigning,
|
|
2425
|
+
testflightStatusRank: () => testflightStatusRank
|
|
2426
|
+
});
|
|
2427
|
+
function isTerminal(status) {
|
|
2428
|
+
return !!status && !IN_FLIGHT.has(status);
|
|
2429
|
+
}
|
|
2430
|
+
function isSuccess(status) {
|
|
2431
|
+
return status === "SUCCESS";
|
|
2432
|
+
}
|
|
2433
|
+
function snapshot(job) {
|
|
2434
|
+
return {
|
|
2435
|
+
id: String(job.id),
|
|
2436
|
+
status: job.status ?? "STATUS_UNKNOWN",
|
|
2437
|
+
...job.buildUrl ? { buildUrl: String(job.buildUrl) } : {},
|
|
2438
|
+
...job.output ? { output: String(job.output) } : {},
|
|
2439
|
+
...typeof job.attemptNumber === "number" ? { attemptNumber: job.attemptNumber } : {}
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2442
|
+
function truncate(s2, max = 400) {
|
|
2443
|
+
return s2.length > max ? `${s2.slice(0, max)}\u2026` : s2;
|
|
2444
|
+
}
|
|
2445
|
+
function credsFromConfig(cfg) {
|
|
2446
|
+
const appDefId = cfg("POCO_APP_DEF_ID")?.trim();
|
|
2447
|
+
const appSecret = cfg("POCO_APP_SECRET")?.trim();
|
|
2448
|
+
if (!appDefId || !appSecret) return void 0;
|
|
2449
|
+
return { appDefId, appSecret };
|
|
2450
|
+
}
|
|
2451
|
+
function isValidDistAttemptId(value2) {
|
|
2452
|
+
return typeof value2 === "string" && /^[A-Za-z0-9_-]{1,128}$/.test(value2);
|
|
2453
|
+
}
|
|
2454
|
+
function customerUploadClaimable(pending, now) {
|
|
2455
|
+
if (!pending) return false;
|
|
2456
|
+
if (pending.status === "READY_FOR_UPLOAD") return true;
|
|
2457
|
+
if (pending.status !== "UPLOADING") return false;
|
|
2458
|
+
if (!pending.claimedAt) return true;
|
|
2459
|
+
const claimedAt = Date.parse(pending.claimedAt);
|
|
2460
|
+
const at2 = Date.parse(now);
|
|
2461
|
+
return Number.isFinite(claimedAt) && Number.isFinite(at2) && at2 - claimedAt >= CUSTOMER_UPLOAD_LEASE_MS;
|
|
2462
|
+
}
|
|
2463
|
+
function nextCustomerUploadClaim(record2, now) {
|
|
2464
|
+
if (!record2 || record2.status !== "SUCCESS" || !customerUploadClaimable(record2.customerAppStore, now)) return void 0;
|
|
2465
|
+
return {
|
|
2466
|
+
...record2,
|
|
2467
|
+
customerAppStore: { ...record2.customerAppStore, status: "UPLOADING", claimedAt: now },
|
|
2468
|
+
updatedAt: now
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
function nextCustomerUploadSettlement(record2, claimedAt, update, now) {
|
|
2472
|
+
const pending = record2?.customerAppStore;
|
|
2473
|
+
if (!record2 || pending?.status !== "UPLOADING" || pending.claimedAt !== claimedAt) return void 0;
|
|
2474
|
+
return {
|
|
2475
|
+
...record2,
|
|
2476
|
+
customerAppStore: {
|
|
2477
|
+
version: pending.version,
|
|
2478
|
+
mode: pending.mode,
|
|
2479
|
+
claimedAt: pending.claimedAt,
|
|
2480
|
+
status: update.status,
|
|
2481
|
+
...update.error ? { error: update.error } : {},
|
|
2482
|
+
...update.delivery ? { delivery: update.delivery } : {}
|
|
2483
|
+
},
|
|
2484
|
+
updatedAt: now
|
|
2485
|
+
};
|
|
2486
|
+
}
|
|
2487
|
+
function isTerminalTestflightStatus(status) {
|
|
2488
|
+
return /(?:^|_)(?:COMPLETED|FAILED|NOT_FOUND)$/.test(status?.toUpperCase() ?? "");
|
|
2489
|
+
}
|
|
2490
|
+
function testflightStatusRank(status) {
|
|
2491
|
+
const normalized = status?.toUpperCase() ?? "";
|
|
2492
|
+
if (isTerminalTestflightStatus(normalized)) return 3;
|
|
2493
|
+
if (/(?:^|_)UPLOADING$/.test(normalized)) return 2;
|
|
2494
|
+
if (/(?:^|_)PENDING$/.test(normalized)) return 1;
|
|
2495
|
+
return 0;
|
|
2496
|
+
}
|
|
2497
|
+
function borrowableIosIds(raw) {
|
|
2498
|
+
const parsed = (raw ?? "").split(",").map((s2) => s2.trim().toLowerCase()).filter(Boolean);
|
|
2499
|
+
return parsed.length > 0 ? parsed : DEFAULT_BORROWABLE_IOS_IDS;
|
|
2500
|
+
}
|
|
2501
|
+
function isBorrowableIosId(id, allowed2 = DEFAULT_BORROWABLE_IOS_IDS) {
|
|
2502
|
+
const candidate = id.toLowerCase();
|
|
2503
|
+
return allowed2.some(
|
|
2504
|
+
(pattern) => pattern.endsWith("*") ? candidate.startsWith(pattern.slice(0, -1)) : candidate === pattern
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
function resolveBorrowedIosId(opts) {
|
|
2508
|
+
const { requested, platform } = opts;
|
|
2509
|
+
if (requested === void 0 || requested === null || requested === "") return {};
|
|
2510
|
+
if (opts.selfServe || opts.role === "owner") {
|
|
2511
|
+
return {
|
|
2512
|
+
error: {
|
|
2513
|
+
error: "operator_only_borrow_id",
|
|
2514
|
+
message: "borrowIosBundleId is not available to self-serve credentials",
|
|
2515
|
+
hint: "Ship the change over-the-air instead \u2014 OTA needs no rebuild and no borrowed signing identity."
|
|
2516
|
+
}
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
2519
|
+
if (typeof requested !== "string") {
|
|
2520
|
+
return { error: { error: "invalid_borrow_id", message: "borrowIosBundleId must be a string" } };
|
|
2521
|
+
}
|
|
2522
|
+
const id = requested.trim().toLowerCase();
|
|
2523
|
+
if (platform !== "ios") {
|
|
2524
|
+
return {
|
|
2525
|
+
error: {
|
|
2526
|
+
error: "borrow_id_ios_only",
|
|
2527
|
+
message: `borrowIosBundleId applies to iOS signing only (got platform "${platform}")`,
|
|
2528
|
+
hint: "Android needs no provisioning profile \u2014 drop the flag for android builds."
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
if (!BUNDLE_ID_RE.test(id)) {
|
|
2533
|
+
return {
|
|
2534
|
+
error: {
|
|
2535
|
+
error: "invalid_borrow_id",
|
|
2536
|
+
message: `"${requested}" is not a valid reverse-DNS bundle id`
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
const allowed2 = opts.allowed ?? DEFAULT_BORROWABLE_IOS_IDS;
|
|
2541
|
+
if (!isBorrowableIosId(id, allowed2)) {
|
|
2542
|
+
return {
|
|
2543
|
+
error: {
|
|
2544
|
+
error: "borrow_id_not_allowed",
|
|
2545
|
+
message: `"${id}" is not borrowable; allowed: ${allowed2.join(", ")}`,
|
|
2546
|
+
hint: "Only internal enterprise ids may be borrowed \u2014 a store id would replace the real App Store app on the device. An operator can change this with HIMI_DIST_BORROWABLE_IOS_IDS."
|
|
2547
|
+
}
|
|
2548
|
+
};
|
|
2549
|
+
}
|
|
2550
|
+
return { bundleId: id };
|
|
2551
|
+
}
|
|
2552
|
+
function resolveDistSigning(requested) {
|
|
2553
|
+
if (requested === void 0 || requested === null || requested === "") {
|
|
2554
|
+
return { policy: DEFAULT_DIST_SIGNING };
|
|
2555
|
+
}
|
|
2556
|
+
if (typeof requested !== "string") {
|
|
2557
|
+
return { error: { status: 400, body: { error: "invalid_signing", message: "signing must be a string" } } };
|
|
2558
|
+
}
|
|
2559
|
+
const want = requested.trim().toLowerCase();
|
|
2560
|
+
if (WIX_MANAGED_SIGNING_ALIASES.includes(want)) return { policy: "wix-managed" };
|
|
2561
|
+
if (want === "byo") return { policy: "byo" };
|
|
2562
|
+
return {
|
|
2563
|
+
error: {
|
|
2564
|
+
status: 501,
|
|
2565
|
+
body: {
|
|
2566
|
+
error: "dist_signing_unsupported",
|
|
2567
|
+
message: `signing "${requested}" is not implemented`,
|
|
2568
|
+
supported: [DEFAULT_DIST_SIGNING, "byo"]
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2573
|
+
function resolveAndroidSigning(requested) {
|
|
2574
|
+
if (requested === void 0 || requested === null || requested === "") {
|
|
2575
|
+
return { policy: DEFAULT_ANDROID_SIGNING };
|
|
2576
|
+
}
|
|
2577
|
+
if (typeof requested !== "string") {
|
|
2578
|
+
return { error: { status: 400, body: { error: "invalid_android_signing", message: "androidSigning must be a string" } } };
|
|
2579
|
+
}
|
|
2580
|
+
const want = requested.trim().toLowerCase();
|
|
2581
|
+
const policy = Object.hasOwn(ANDROID_SIGNING_ALIASES, want) ? ANDROID_SIGNING_ALIASES[want] : void 0;
|
|
2582
|
+
if (policy) return { policy };
|
|
2583
|
+
return {
|
|
2584
|
+
error: {
|
|
2585
|
+
status: 400,
|
|
2586
|
+
body: {
|
|
2587
|
+
error: "invalid_android_signing",
|
|
2588
|
+
message: `androidSigning "${requested}" is not a known policy`,
|
|
2589
|
+
supported: ["qa-keystore", "wix-keystore", "debug"]
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
function androidFormatSkewFailed(record2) {
|
|
2595
|
+
return record2.platform === "android" && typeof record2.error === "string" && [ANDROID_FORMAT_NOT_BUILT, ANDROID_FORMAT_WRONG_SIGNER, ANDROID_FORMAT_NOT_REQUESTED].some((code) => record2.error.includes(`${code}:`));
|
|
2596
|
+
}
|
|
2597
|
+
function resolveAndroidFormat(requested) {
|
|
2598
|
+
if (requested === void 0 || requested === null || requested === "") return { format: DEFAULT_ANDROID_FORMAT };
|
|
2599
|
+
if (typeof requested === "string" && ANDROID_FORMATS.includes(requested)) {
|
|
2600
|
+
return { format: requested };
|
|
2601
|
+
}
|
|
2602
|
+
return {
|
|
2603
|
+
error: {
|
|
2604
|
+
status: 400,
|
|
2605
|
+
body: {
|
|
2606
|
+
error: "invalid_android_format",
|
|
2607
|
+
message: `androidFormat ${typeof requested === "string" ? `"${requested.slice(0, 40)}"` : `of type ${typeof requested}`} is not a known format`,
|
|
2608
|
+
supported: [...ANDROID_FORMATS]
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
function encodeDistParams(env) {
|
|
2614
|
+
return Buffer.from(JSON.stringify(env), "utf8").toString("base64url");
|
|
2615
|
+
}
|
|
2616
|
+
function distJobSpec(req) {
|
|
2617
|
+
const envVars = {
|
|
2618
|
+
APP_DIR: req.appDir,
|
|
2619
|
+
// WHICH APP this binary is FOR, as distinct from which shell builds it. Without it the pool
|
|
2620
|
+
// can only infer an app from APP_DIR — i.e. the shell — so it baked the SHELL's content and
|
|
2621
|
+
// resolved the SHELL's OTA app id. A device-verified consequence: `himi dist --app demo-app`
|
|
2622
|
+
// produced a binary rendering himi_branded_home. The shell is the container; this is the app.
|
|
2623
|
+
HIMI_DIST_APP: req.app,
|
|
2624
|
+
// (HIMI_DIST_PROVISIONING_ENV is set at the END of this object, after `req.env` — see there.)
|
|
2625
|
+
// run-dist gates iOS on DIST_ENABLE_IOS / DIST_PROVISIONING_PROFILE / an explicit
|
|
2626
|
+
// `[dist:ios]` IN THE COMMIT MESSAGE. A serve-brokered job has no commit by design, and
|
|
2627
|
+
// `--force` only bypasses the `[dist]` tag gate — so without this an `--platform ios`
|
|
2628
|
+
// request would skip the build and finish as SUCCESS with no install link. Asking for iOS
|
|
2629
|
+
// through the API IS the explicit opt-in that `[dist:ios]` represents.
|
|
2630
|
+
...req.platform === "ios" ? { DIST_ENABLE_IOS: "1" } : {},
|
|
2631
|
+
...req.release ? { HIMI_DIST_RELEASE_PIN: req.release } : {},
|
|
2632
|
+
...req.contractUrl ? { HIMI_DIST_CONTRACT_URL: req.contractUrl } : {},
|
|
2633
|
+
// Where the pool fetches the RELEASE to bake its offline seed from. Its absence is what makes
|
|
2634
|
+
// the classic Falcon `[dist]` path fall back to building the seed from repo source.
|
|
2635
|
+
...req.seedUrl ? { HIMI_DIST_SEED_URL: req.seedUrl } : {},
|
|
2636
|
+
...req.platform === "android" && req.androidConfigUrl ? { HIMI_DIST_ANDROID_CONFIG_URL: req.androidConfigUrl } : {},
|
|
2637
|
+
// Where the pool fetches its SIGNING IDENTITY (profile + p12 + password). A URL, not the
|
|
2638
|
+
// bytes: the envelope is ~20KB of base64 and `command` is capped at MAX_COMMAND_CHARS — the
|
|
2639
|
+
// same reason the brand contract travels this way. It also keeps key material out of the
|
|
2640
|
+
// job params, which the pool echoes into its log.
|
|
2641
|
+
...req.signingUrl ? { HIMI_DIST_SIGNING_URL: req.signingUrl } : {},
|
|
2642
|
+
// WHICH KEYSTORE the Android build signs with. Android only — on an iOS job this would be a
|
|
2643
|
+
// variable nothing reads, and dispatching one implies a decision that was never made.
|
|
2644
|
+
// A bundle dispatches the QA key BY NAME, never `wix-keystore`. `--aab` always means the Wix
|
|
2645
|
+
// production key, and the new run-dist derives that from DIST_ANDROID_FORMAT itself, overriding
|
|
2646
|
+
// this. Naming `wix-keystore` here would reach a run-dist OLDER than `--aab` too (the pool builds
|
|
2647
|
+
// the release's own commit): it ignores the format, builds an installable APK, signs it with the
|
|
2648
|
+
// Wix production key and uploads and announces it — the exact artifact the self-serve 403
|
|
2649
|
+
// withholds. Naming NOTHING is not safe either: a pool machine with DIST_ANDROID_USE_WIX_KEYSTORE=1
|
|
2650
|
+
// then hands that old runner the Wix key anyway. A named QA key outranks that machine setting, so
|
|
2651
|
+
// an old runner signs an ordinary QA APK and the job fails as `android_format_not_built`.
|
|
2652
|
+
...req.platform === "android" && req.androidSigning ? { DIST_ANDROID_SIGNING: req.androidFormat === "aab" ? "qa-keystore" : req.androidSigning } : {},
|
|
2653
|
+
// A Play bundle instead of an APK. Only when asked: the APK default needs no parameter, and a
|
|
2654
|
+
// runner that predates the variable ignores it — which the result callback catches.
|
|
2655
|
+
...req.platform === "android" && req.androidFormat === "aab" ? { DIST_ANDROID_FORMAT: "aab" } : {},
|
|
2656
|
+
...req.previewRoute ? { HIMI_DIST_PREVIEW_ROUTE: req.previewRoute } : {},
|
|
2657
|
+
...req.callbackUrl ? { HIMI_DIST_CALLBACK_URL: req.callbackUrl } : {},
|
|
2658
|
+
...req.callbackToken ? { HIMI_DIST_CALLBACK_TOKEN: req.callbackToken } : {},
|
|
2659
|
+
// The per-job artifact path component. Without it two concurrent jobs for one
|
|
2660
|
+
// app+shell+platform+commit wrote the same ipa, manifest.plist and install.html, and the
|
|
2661
|
+
// loser's install page then handed a tester the other build's binary.
|
|
2662
|
+
...req.jobNonce ? { HIMI_DIST_JOB_NONCE: req.jobNonce } : {},
|
|
2663
|
+
// Who to DM the install link to. See DistJobRequest.requestedBy: the git-history guess the pool
|
|
2664
|
+
// falls back to misroutes brokered builds to an unrelated colleague.
|
|
2665
|
+
...req.requestedBy ? { HIMI_DIST_REQUESTED_BY: req.requestedBy } : {},
|
|
2666
|
+
...req.env,
|
|
2667
|
+
...req.buildOrigin ? { HIMI_DIST_BUILD_ORIGIN: req.buildOrigin } : {},
|
|
2668
|
+
// AFTER `req.env`, deliberately. This one field is the SHELL's declared answer, and it is the
|
|
2669
|
+
// only thing standing between owner-lite and a build that reads the fetched contract under
|
|
2670
|
+
// branded-lite's key — i.e. ignores it and ships unbranded while reporting success. `req.env`
|
|
2671
|
+
// is operator config (`deps.env`), so a stray HIMI_DIST_PROVISIONING_ENV there is a plausible
|
|
2672
|
+
// misconfiguration, and it would silently unbrand EVERY shell at once. Generic overrides do
|
|
2673
|
+
// not get to answer a per-shell question.
|
|
2674
|
+
...req.provisioningEnv ? { HIMI_DIST_PROVISIONING_ENV: req.provisioningEnv } : {}
|
|
2675
|
+
};
|
|
2676
|
+
const command = `dist:${req.platform} ${DIST_PARAMS_FLAG} ${encodeDistParams(envVars)}`;
|
|
2677
|
+
if (command.length > MAX_COMMAND_CHARS) {
|
|
2678
|
+
throw new Error(
|
|
2679
|
+
`dist command is ${command.length} chars (cap ${MAX_COMMAND_CHARS}); shrink the job env \u2014 pass large values as a URL the Mac job fetches, as the brand contract does`
|
|
2680
|
+
);
|
|
2681
|
+
}
|
|
2682
|
+
return {
|
|
2683
|
+
gitUrl: req.gitUrl ?? DEFAULT_GIT_URL,
|
|
2684
|
+
gitCommitSha: req.gitCommitSha,
|
|
2685
|
+
packageName: DIST_PACKAGE_NAME,
|
|
2686
|
+
command,
|
|
2687
|
+
// Job Service renders this metadata in Buildkite's job label. User labels are sanitized,
|
|
2688
|
+
// and the runner also carries buildOrigin so it does not treat them as GitHub PR refs.
|
|
2689
|
+
branchName: req.buildLabel ?? req.branchName ?? "master",
|
|
2690
|
+
envVars,
|
|
2691
|
+
...req.xcodeVersion ? { xcodeVersion: req.xcodeVersion } : {}
|
|
2692
|
+
};
|
|
2693
|
+
}
|
|
2694
|
+
var IN_FLIGHT, SCOPE_CREATE, SCOPE_READ, SCOPE_CANCEL, DEFAULT_BASE_URL, DEFAULT_OAUTH_URL, TOKEN_TTL_MS, JobServiceError, JobServiceBroker, CUSTOMER_UPLOAD_LEASE_MS, MAX_MEASURABLE_IDENTITY_WINDOW, DIST_SHELLS, DEFAULT_DIST_SHELL, DEFAULT_BORROWABLE_IOS_IDS, BUNDLE_ID_RE, DEFAULT_DIST_SIGNING, WIX_MANAGED_SIGNING_ALIASES, DEFAULT_ANDROID_SIGNING, ANDROID_SIGNING_POLICIES, ANDROID_SIGNING_ALIASES, DEFAULT_ANDROID_FORMAT, ANDROID_FORMATS, ANDROID_FORMAT_NOT_BUILT, ANDROID_FORMAT_WRONG_SIGNER, ANDROID_FORMAT_NOT_REQUESTED, DEFAULT_GIT_URL, DIST_PACKAGE_NAME, DIST_PARAMS_FLAG, MAX_COMMAND_CHARS;
|
|
2384
2695
|
var init_dist_jobs = __esm({
|
|
2385
2696
|
"../../core/serve-control/src/dist-jobs.ts"() {
|
|
2697
|
+
IN_FLIGHT = /* @__PURE__ */ new Set(["CREATED", "QUEUED", "WORKING"]);
|
|
2698
|
+
SCOPE_CREATE = "MRE.JOB_CREATE";
|
|
2699
|
+
SCOPE_READ = "MRE.JOB_READ";
|
|
2700
|
+
SCOPE_CANCEL = "MRE.CANCEL_JOB";
|
|
2701
|
+
DEFAULT_BASE_URL = "https://bo.wix.com/job-service";
|
|
2702
|
+
DEFAULT_OAUTH_URL = "https://www.wixapis.com/oauth/access";
|
|
2386
2703
|
TOKEN_TTL_MS = 5 * 60 * 1e3;
|
|
2704
|
+
JobServiceError = class extends Error {
|
|
2705
|
+
constructor(message2, status, body) {
|
|
2706
|
+
super(message2);
|
|
2707
|
+
this.status = status;
|
|
2708
|
+
this.body = body;
|
|
2709
|
+
this.name = "JobServiceError";
|
|
2710
|
+
}
|
|
2711
|
+
};
|
|
2712
|
+
JobServiceBroker = class {
|
|
2713
|
+
baseUrl;
|
|
2714
|
+
oauthUrl;
|
|
2715
|
+
fetchImpl;
|
|
2716
|
+
now;
|
|
2717
|
+
creds;
|
|
2718
|
+
/** scope -> { token, expiresAt } */
|
|
2719
|
+
tokens = /* @__PURE__ */ new Map();
|
|
2720
|
+
constructor(opts) {
|
|
2721
|
+
if (!opts.creds?.appDefId || !opts.creds?.appSecret) {
|
|
2722
|
+
throw new JobServiceError("job service credentials missing (POCO_APP_DEF_ID / POCO_APP_SECRET)");
|
|
2723
|
+
}
|
|
2724
|
+
this.creds = opts.creds;
|
|
2725
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
2726
|
+
this.oauthUrl = opts.oauthUrl ?? DEFAULT_OAUTH_URL;
|
|
2727
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
2728
|
+
this.now = opts.now ?? Date.now;
|
|
2729
|
+
}
|
|
2730
|
+
/** Mint (or reuse) a token for one MRE scope. */
|
|
2731
|
+
async token(scope2) {
|
|
2732
|
+
const cached3 = this.tokens.get(scope2);
|
|
2733
|
+
if (cached3 && cached3.expiresAt > this.now()) return cached3.token;
|
|
2734
|
+
const res = await this.fetchImpl(this.oauthUrl, {
|
|
2735
|
+
method: "POST",
|
|
2736
|
+
headers: { "content-type": "application/json" },
|
|
2737
|
+
body: JSON.stringify({
|
|
2738
|
+
grant_type: "client_credentials",
|
|
2739
|
+
client_id: this.creds.appDefId,
|
|
2740
|
+
client_secret: this.creds.appSecret,
|
|
2741
|
+
scope: scope2
|
|
2742
|
+
})
|
|
2743
|
+
});
|
|
2744
|
+
const text11 = await res.text();
|
|
2745
|
+
if (!res.ok) {
|
|
2746
|
+
throw new JobServiceError(`oauth failed for scope ${scope2}`, res.status, truncate(text11));
|
|
2747
|
+
}
|
|
2748
|
+
let token;
|
|
2749
|
+
try {
|
|
2750
|
+
token = JSON.parse(text11).access_token;
|
|
2751
|
+
} catch {
|
|
2752
|
+
throw new JobServiceError(`oauth returned non-JSON for scope ${scope2}`, res.status, truncate(text11));
|
|
2753
|
+
}
|
|
2754
|
+
if (!token) throw new JobServiceError(`oauth returned no access_token for scope ${scope2}`, res.status);
|
|
2755
|
+
this.tokens.set(scope2, { token, expiresAt: this.now() + TOKEN_TTL_MS });
|
|
2756
|
+
return token;
|
|
2757
|
+
}
|
|
2758
|
+
async call(scope2, method, path2, body) {
|
|
2759
|
+
const token = await this.token(scope2);
|
|
2760
|
+
const res = await this.fetchImpl(`${this.baseUrl}${path2}`, {
|
|
2761
|
+
method,
|
|
2762
|
+
// BARE token, not `Bearer <token>` — matches jobServiceApi's own header.
|
|
2763
|
+
headers: { Authorization: token, ...body ? { "content-type": "application/json" } : {} },
|
|
2764
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
2765
|
+
});
|
|
2766
|
+
const text11 = await res.text();
|
|
2767
|
+
if (!res.ok) {
|
|
2768
|
+
throw new JobServiceError(`job service ${method} ${path2} failed`, res.status, truncate(text11));
|
|
2769
|
+
}
|
|
2770
|
+
if (!text11) return {};
|
|
2771
|
+
try {
|
|
2772
|
+
return JSON.parse(text11);
|
|
2773
|
+
} catch {
|
|
2774
|
+
throw new JobServiceError(`job service ${method} ${path2} returned non-JSON`, res.status, truncate(text11));
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Create a NODE_COMMAND job on the Mac (or Linux) pool. Returns as soon as Job Service has
|
|
2779
|
+
* queued it — this never waits for the build.
|
|
2780
|
+
*/
|
|
2781
|
+
async createNodeCommand(spec, os2 = "mac", notify) {
|
|
2782
|
+
for (const key3 of ["gitUrl", "gitCommitSha", "packageName", "command", "branchName"]) {
|
|
2783
|
+
if (!spec[key3]) throw new JobServiceError(`createNodeCommand: missing ${key3}`);
|
|
2784
|
+
}
|
|
2785
|
+
const optionsKey = os2 === "linux" ? "linuxNodeCommandOptions" : "nodeCommandOptions";
|
|
2786
|
+
const type = os2 === "linux" ? "LINUX_NODE_COMMAND" : "NODE_COMMAND";
|
|
2787
|
+
const options = {
|
|
2788
|
+
packageManager: "YARN",
|
|
2789
|
+
// the only value Job Service accepts
|
|
2790
|
+
gitUrl: spec.gitUrl,
|
|
2791
|
+
gitCommitSha: spec.gitCommitSha,
|
|
2792
|
+
packageName: spec.packageName,
|
|
2793
|
+
command: spec.command,
|
|
2794
|
+
branchName: spec.branchName,
|
|
2795
|
+
...spec.envVars ? { envVars: spec.envVars } : {}
|
|
2796
|
+
};
|
|
2797
|
+
if (os2 === "mac" && spec.xcodeVersion) options.xcodeVersion = spec.xcodeVersion;
|
|
2798
|
+
const subscriptions = {
|
|
2799
|
+
...notify?.ownershipTags?.length ? { subscribedOwnershipTags: notify.ownershipTags } : {},
|
|
2800
|
+
...notify?.userIds?.length ? { subscribedUserIds: notify.userIds } : {}
|
|
2801
|
+
};
|
|
2802
|
+
const data = await this.call(SCOPE_CREATE, "POST", "/v1/job", {
|
|
2803
|
+
job: { type, [optionsKey]: options, ...subscriptions }
|
|
2804
|
+
});
|
|
2805
|
+
const job = data?.job;
|
|
2806
|
+
if (!job?.id) throw new JobServiceError("job service create returned no job id");
|
|
2807
|
+
return snapshot(job);
|
|
2808
|
+
}
|
|
2809
|
+
/** Current state of a job. */
|
|
2810
|
+
async read(jobId) {
|
|
2811
|
+
const data = await this.call(SCOPE_READ, "GET", `/v1/job/${encodeURIComponent(jobId)}`);
|
|
2812
|
+
const job = data?.job;
|
|
2813
|
+
if (!job) throw new JobServiceError(`job service read returned no job for ${jobId}`);
|
|
2814
|
+
return snapshot({ id: jobId, ...job });
|
|
2815
|
+
}
|
|
2816
|
+
/** Ask Job Service to cancel a queued/running job. */
|
|
2817
|
+
async cancel(jobId) {
|
|
2818
|
+
await this.call(SCOPE_CANCEL, "POST", `/v1/job/${encodeURIComponent(jobId)}/cancel`);
|
|
2819
|
+
}
|
|
2820
|
+
};
|
|
2387
2821
|
CUSTOMER_UPLOAD_LEASE_MS = 15 * 60 * 1e3;
|
|
2822
|
+
MAX_MEASURABLE_IDENTITY_WINDOW = 100;
|
|
2388
2823
|
DIST_SHELLS = {
|
|
2389
2824
|
"branded-lite": {
|
|
2390
2825
|
appDir: "apps/himi-branded-lite",
|
|
@@ -2437,6 +2872,11 @@ var init_dist_jobs = __esm({
|
|
|
2437
2872
|
}
|
|
2438
2873
|
};
|
|
2439
2874
|
DEFAULT_DIST_SHELL = "branded-lite";
|
|
2875
|
+
DEFAULT_BORROWABLE_IOS_IDS = ["ent.*"];
|
|
2876
|
+
BUNDLE_ID_RE = /^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)+$/;
|
|
2877
|
+
DEFAULT_DIST_SIGNING = "wix-managed";
|
|
2878
|
+
WIX_MANAGED_SIGNING_ALIASES = ["wix-managed", "wix", "pool-enterprise"];
|
|
2879
|
+
DEFAULT_ANDROID_SIGNING = "qa-keystore";
|
|
2440
2880
|
ANDROID_SIGNING_POLICIES = ["qa-keystore", "wix-keystore", "debug"];
|
|
2441
2881
|
ANDROID_SIGNING_ALIASES = {
|
|
2442
2882
|
// The canonical spellings, derived so the two lists cannot drift apart.
|
|
@@ -2446,6 +2886,15 @@ var init_dist_jobs = __esm({
|
|
|
2446
2886
|
wix: "wix-keystore",
|
|
2447
2887
|
oneapp: "wix-keystore"
|
|
2448
2888
|
};
|
|
2889
|
+
DEFAULT_ANDROID_FORMAT = "apk";
|
|
2890
|
+
ANDROID_FORMATS = ["apk", "aab"];
|
|
2891
|
+
ANDROID_FORMAT_NOT_BUILT = "android_format_not_built";
|
|
2892
|
+
ANDROID_FORMAT_WRONG_SIGNER = "android_format_wrong_signer";
|
|
2893
|
+
ANDROID_FORMAT_NOT_REQUESTED = "android_format_not_requested";
|
|
2894
|
+
DEFAULT_GIT_URL = "https://github.com/wix-private/himalaya";
|
|
2895
|
+
DIST_PACKAGE_NAME = "@himalaya/native-ci";
|
|
2896
|
+
DIST_PARAMS_FLAG = "--himi-dist";
|
|
2897
|
+
MAX_COMMAND_CHARS = 2e3;
|
|
2449
2898
|
}
|
|
2450
2899
|
});
|
|
2451
2900
|
|
|
@@ -9726,7 +10175,6 @@ function resolveTranslation(value2, catalog4, sourceCatalog) {
|
|
|
9726
10175
|
var BINDING_SIGILS, COLON_SIGILS, BINDING_SIGIL_RE, APP_BINDING_PREFIX, APP_BINDING_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
9727
10176
|
var init_bindings = __esm({
|
|
9728
10177
|
"../../core/ts/src/bindings.ts"() {
|
|
9729
|
-
"use strict";
|
|
9730
10178
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
9731
10179
|
COLON_SIGILS = /* @__PURE__ */ new Set(["t"]);
|
|
9732
10180
|
BINDING_SIGIL_RE = new RegExp(
|
|
@@ -9874,16 +10322,16 @@ function scanWidgetPayload(node, family, path2, bindings, disallowed, timeRefs,
|
|
|
9874
10322
|
scanWidgetPayload(v2, family, `${path2}.${k2}`, bindings, disallowed, timeRefs, intents, actionSites2);
|
|
9875
10323
|
}
|
|
9876
10324
|
}
|
|
9877
|
-
function validateWidget(
|
|
10325
|
+
function validateWidget(snapshot3) {
|
|
9878
10326
|
const validate5 = compileWidgetSchema();
|
|
9879
|
-
const schemaOk = validate5(
|
|
10327
|
+
const schemaOk = validate5(snapshot3);
|
|
9880
10328
|
const schemaErrors = schemaOk ? [] : validate5.errors ?? [];
|
|
9881
10329
|
const bindingViolations = [];
|
|
9882
10330
|
const disallowedComponents = [];
|
|
9883
10331
|
const timeRefViolations = [];
|
|
9884
10332
|
const intentViolations = [];
|
|
9885
10333
|
const actionSites2 = [];
|
|
9886
|
-
const snap =
|
|
10334
|
+
const snap = snapshot3 ?? {};
|
|
9887
10335
|
const family = snap.family;
|
|
9888
10336
|
scanWidgetPayload(snap.payload, family, "$.payload", bindingViolations, disallowedComponents, timeRefViolations, intentViolations, actionSites2);
|
|
9889
10337
|
if (snap.placeholderWhenStale !== void 0) {
|
|
@@ -13557,12 +14005,12 @@ function responseBytes(value2) {
|
|
|
13557
14005
|
return 0;
|
|
13558
14006
|
}
|
|
13559
14007
|
}
|
|
13560
|
-
function restoredState(def,
|
|
14008
|
+
function restoredState(def, snapshot3) {
|
|
13561
14009
|
const declared = def?.state ?? {};
|
|
13562
|
-
if (!
|
|
14010
|
+
if (!snapshot3 || typeof snapshot3 !== "object" || Array.isArray(snapshot3)) return declared;
|
|
13563
14011
|
const fresh = [def?.notHydrated, def?.perVisit].flatMap((keys) => Array.isArray(keys) ? keys : []);
|
|
13564
14012
|
const merged = { ...declared };
|
|
13565
|
-
for (const [key3, value2] of Object.entries(
|
|
14013
|
+
for (const [key3, value2] of Object.entries(snapshot3)) {
|
|
13566
14014
|
if (key3 !== "_error" && !fresh.includes(key3)) merged[key3] = value2;
|
|
13567
14015
|
}
|
|
13568
14016
|
return merged;
|
|
@@ -28063,7 +28511,7 @@ function json(res, status, obj5) {
|
|
|
28063
28511
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
28064
28512
|
res.end(body);
|
|
28065
28513
|
}
|
|
28066
|
-
function
|
|
28514
|
+
function truncate2(s2) {
|
|
28067
28515
|
if (s2 === void 0) return void 0;
|
|
28068
28516
|
return s2.length > BODY_CAP ? s2.slice(0, BODY_CAP) + `\u2026[+${s2.length - BODY_CAP}B]` : s2;
|
|
28069
28517
|
}
|
|
@@ -28078,8 +28526,8 @@ function redactHeaders(h2) {
|
|
|
28078
28526
|
}
|
|
28079
28527
|
function recordWixTraffic(gw, app, adminUrl, ev) {
|
|
28080
28528
|
const full = { ...ev, id: ++gw.seq, app };
|
|
28081
|
-
full.reqBody =
|
|
28082
|
-
full.respBody =
|
|
28529
|
+
full.reqBody = truncate2(redactBodyString(full.reqBody));
|
|
28530
|
+
full.respBody = truncate2(redactBodyString(full.respBody));
|
|
28083
28531
|
gw.traffic.push(full);
|
|
28084
28532
|
if (gw.traffic.length > TRAFFIC_CAP) gw.traffic.splice(0, gw.traffic.length - TRAFFIC_CAP);
|
|
28085
28533
|
const text11 = `event: wix.traffic
|
|
@@ -116690,7 +117138,7 @@ function ensureListAnimateRuntime() {
|
|
|
116690
117138
|
listAnimateRuntimeInstalled = true;
|
|
116691
117139
|
const prevRects = /* @__PURE__ */ new WeakMap();
|
|
116692
117140
|
const rowKey = (c2) => c2.dataset?.componentId ?? c2.querySelector("[data-component-id]")?.dataset?.componentId;
|
|
116693
|
-
const
|
|
117141
|
+
const snapshot3 = (host) => {
|
|
116694
117142
|
const m2 = /* @__PURE__ */ new Map();
|
|
116695
117143
|
Array.from(host.children).forEach((c2) => {
|
|
116696
117144
|
const id = rowKey(c2);
|
|
@@ -116702,7 +117150,7 @@ function ensureListAnimateRuntime() {
|
|
|
116702
117150
|
const flip = (host) => {
|
|
116703
117151
|
const prev = prevRects.get(host);
|
|
116704
117152
|
if (!prev) {
|
|
116705
|
-
|
|
117153
|
+
snapshot3(host);
|
|
116706
117154
|
return;
|
|
116707
117155
|
}
|
|
116708
117156
|
const next = /* @__PURE__ */ new Map();
|
|
@@ -116745,7 +117193,7 @@ function ensureListAnimateRuntime() {
|
|
|
116745
117193
|
const scan = () => {
|
|
116746
117194
|
document.querySelectorAll(hostSel).forEach((h2) => {
|
|
116747
117195
|
if (!prevRects.has(h2)) {
|
|
116748
|
-
|
|
117196
|
+
snapshot3(h2);
|
|
116749
117197
|
childObs.observe(h2, { childList: true });
|
|
116750
117198
|
}
|
|
116751
117199
|
});
|
|
@@ -121245,7 +121693,7 @@ var init_renderNode = __esm({
|
|
|
121245
121693
|
}, [startPositionPath, boundStartPosition, status]);
|
|
121246
121694
|
const emit = React12.useCallback((action, extra = {}) => {
|
|
121247
121695
|
if (!action || !ctx.onAction) return;
|
|
121248
|
-
const
|
|
121696
|
+
const snapshot3 = {
|
|
121249
121697
|
sessionId,
|
|
121250
121698
|
state: status,
|
|
121251
121699
|
status,
|
|
@@ -121260,7 +121708,7 @@ var init_renderNode = __esm({
|
|
|
121260
121708
|
artist: String(item?.artist ?? ""),
|
|
121261
121709
|
error
|
|
121262
121710
|
};
|
|
121263
|
-
ctx.onAction({ ...action, args: { ...action.args ?? {}, ...
|
|
121711
|
+
ctx.onAction({ ...action, args: { ...action.args ?? {}, ...snapshot3, ...extra }, params: { ...action.params ?? {}, sessionId, index: String(index), ...Object.fromEntries(Object.entries(extra).map(([k2, v2]) => [k2, String(v2)])) } });
|
|
121264
121712
|
}, [ctx.onAction, sessionId, status, index, position, duration2, item, buffered, rate, props.muted, fullscreen, error]);
|
|
121265
121713
|
React12.useEffect(() => {
|
|
121266
121714
|
if (!isUnsupportedProvider || status === "error") return;
|
|
@@ -127553,15 +128001,15 @@ function interpretProduce(services, parsed) {
|
|
|
127553
128001
|
}
|
|
127554
128002
|
return { services, widgets, views };
|
|
127555
128003
|
}
|
|
127556
|
-
function contentEtag(
|
|
128004
|
+
function contentEtag(snapshot3) {
|
|
127557
128005
|
const canonical7 = JSON.stringify({
|
|
127558
|
-
widgetId:
|
|
127559
|
-
family:
|
|
127560
|
-
size:
|
|
127561
|
-
payload:
|
|
127562
|
-
deepLink:
|
|
128006
|
+
widgetId: snapshot3.widgetId,
|
|
128007
|
+
family: snapshot3.family,
|
|
128008
|
+
size: snapshot3.size,
|
|
128009
|
+
payload: snapshot3.payload,
|
|
128010
|
+
deepLink: snapshot3.deepLink,
|
|
127563
128011
|
// Lever A — a timeline change must bump the etag (frame values/times are content).
|
|
127564
|
-
frames:
|
|
128012
|
+
frames: snapshot3.frames ?? null
|
|
127565
128013
|
});
|
|
127566
128014
|
return "sha256-" + createHash15("sha256").update(canonical7).digest("base64");
|
|
127567
128015
|
}
|
|
@@ -127604,8 +128052,8 @@ function freezeCaptured(def, widgetId, opts = {}) {
|
|
|
127604
128052
|
generatedAt: opts.generatedAt ?? Math.floor(Date.now() / 1e3),
|
|
127605
128053
|
...frames ? { frames } : {}
|
|
127606
128054
|
};
|
|
127607
|
-
const
|
|
127608
|
-
const result = validateWidget(
|
|
128055
|
+
const snapshot3 = { ...base, contentEtag: contentEtag(base) };
|
|
128056
|
+
const result = validateWidget(snapshot3);
|
|
127609
128057
|
if (!result.ok) {
|
|
127610
128058
|
const reasons = [];
|
|
127611
128059
|
if (result.bindingViolations.length) {
|
|
@@ -127627,7 +128075,7 @@ function freezeCaptured(def, widgetId, opts = {}) {
|
|
|
127627
128075
|
}
|
|
127628
128076
|
throw new Error(`widget "${widgetId}" produced an invalid snapshot \u2014 ${reasons.join(" | ")}`);
|
|
127629
128077
|
}
|
|
127630
|
-
return
|
|
128078
|
+
return snapshot3;
|
|
127631
128079
|
}
|
|
127632
128080
|
function viewWidgetId(viewId, family) {
|
|
127633
128081
|
return `${viewId}.${family}`;
|
|
@@ -127727,8 +128175,8 @@ function freezeOverrideSnapshot(input, opts = {}) {
|
|
|
127727
128175
|
...input.placeholderWhenStale !== void 0 ? { placeholderWhenStale: input.placeholderWhenStale } : {},
|
|
127728
128176
|
...input.frames !== void 0 ? { frames: input.frames } : {}
|
|
127729
128177
|
};
|
|
127730
|
-
const
|
|
127731
|
-
const result = validateWidget(
|
|
128178
|
+
const snapshot3 = { ...base, contentEtag: contentEtag(base) };
|
|
128179
|
+
const result = validateWidget(snapshot3);
|
|
127732
128180
|
if (!result.ok) {
|
|
127733
128181
|
const reasons = [];
|
|
127734
128182
|
if (result.bindingViolations.length) {
|
|
@@ -127750,7 +128198,7 @@ function freezeOverrideSnapshot(input, opts = {}) {
|
|
|
127750
128198
|
}
|
|
127751
128199
|
throw new Error(`override snapshot for "${input.widgetId}" is invalid \u2014 ${reasons.join(" | ")}`);
|
|
127752
128200
|
}
|
|
127753
|
-
return
|
|
128201
|
+
return snapshot3;
|
|
127754
128202
|
}
|
|
127755
128203
|
var MAX_TIMELINE_FRAMES, WIDGET_BUDGET_MS, realmPromise, WidgetRealmUnavailableError, PRODUCE_CACHE_TTL_MS, MAX_PRODUCE_CACHE_ENTRIES, MAX_PRODUCE_ENTRY_BYTES, MAX_PRODUCE_CACHE_BYTES, produceCache, produceCacheGeneration, CAPTURE_SLOT, READBACK_SERVICE;
|
|
127756
128204
|
var init_widgets = __esm({
|
|
@@ -130388,9 +130836,9 @@ async function buildSnapshotForId(widgetId, dir) {
|
|
|
130388
130836
|
try {
|
|
130389
130837
|
const js2 = loaded.bytes.toString("utf8");
|
|
130390
130838
|
if (entry.view) {
|
|
130391
|
-
const
|
|
130392
|
-
if (!
|
|
130393
|
-
return { ok: true, snapshot:
|
|
130839
|
+
const snapshot3 = await buildViewSnapshot(js2, entry.view.viewId, entry.view.surfaceId);
|
|
130840
|
+
if (!snapshot3) return { ok: false, status: 404, error: "widget_not_found" };
|
|
130841
|
+
return { ok: true, snapshot: snapshot3 };
|
|
130394
130842
|
}
|
|
130395
130843
|
return { ok: true, snapshot: await buildWidgetSnapshot(js2, widgetId) };
|
|
130396
130844
|
} catch (err) {
|
|
@@ -133651,7 +134099,7 @@ __export(screen_crawl_exports, {
|
|
|
133651
134099
|
recordScreenTraffic: () => recordScreenTraffic,
|
|
133652
134100
|
renderedNameGaps: () => renderedNameGaps,
|
|
133653
134101
|
rootOnAppear: () => rootOnAppear,
|
|
133654
|
-
snapshot: () =>
|
|
134102
|
+
snapshot: () => snapshot2,
|
|
133655
134103
|
structuralSignature: () => structuralSignature,
|
|
133656
134104
|
unverifiableNodes: () => unverifiableNodes,
|
|
133657
134105
|
workerArgs: () => workerArgs
|
|
@@ -134389,7 +134837,7 @@ function hasOwnError(state) {
|
|
|
134389
134837
|
}
|
|
134390
134838
|
return false;
|
|
134391
134839
|
}
|
|
134392
|
-
function
|
|
134840
|
+
function snapshot2(w2) {
|
|
134393
134841
|
const state = {};
|
|
134394
134842
|
const defects = {};
|
|
134395
134843
|
for (const [name, h2] of Object.entries(w2.handles)) {
|
|
@@ -134455,7 +134903,7 @@ async function bootScreenWorker(opts) {
|
|
|
134455
134903
|
}
|
|
134456
134904
|
}
|
|
134457
134905
|
for (let i2 = 0; i2 < 20; i2++) await yieldMacrotask();
|
|
134458
|
-
const { state, defects } =
|
|
134906
|
+
const { state, defects } = snapshot2(w2);
|
|
134459
134907
|
return { ...w2, hostCalls, deniedCapabilities, state: Object.keys(state).length ? state : w2.services, defects, ...deadLifecycle ? { deadLifecycle } : {} };
|
|
134460
134908
|
}
|
|
134461
134909
|
function effectSince(w2, mark, action, componentId) {
|
|
@@ -134577,7 +135025,7 @@ async function crawlScreenJourney(opts) {
|
|
|
134577
135025
|
fail6(`journey "${opts.journey.name}" cannot find ${step.component ? `${step.component} \u2192 ` : ""}${step.action} in this screen`, step);
|
|
134578
135026
|
continue;
|
|
134579
135027
|
}
|
|
134580
|
-
const state =
|
|
135028
|
+
const state = snapshot2(worker).state;
|
|
134581
135029
|
const site = effectiveSiteFor(declared, state);
|
|
134582
135030
|
if (!site) {
|
|
134583
135031
|
fail6(`journey "${opts.journey.name}" cannot dispatch ${step.action}: its list has no rendered row`, step);
|
|
@@ -134604,7 +135052,7 @@ async function crawlScreenJourney(opts) {
|
|
|
134604
135052
|
const stepEffect = effectSince(worker, mark, site.actionId, site.componentId);
|
|
134605
135053
|
if (stepEffect) effects.push(stepEffect);
|
|
134606
135054
|
}
|
|
134607
|
-
const settled =
|
|
135055
|
+
const settled = snapshot2(worker);
|
|
134608
135056
|
if (worker.errors.length) {
|
|
134609
135057
|
for (const error of worker.errors) fail6(`journey "${opts.journey.name}" worker error: ${error.service}: ${error.message}`);
|
|
134610
135058
|
}
|
|
@@ -135025,7 +135473,7 @@ async function crawlScreenInner(opts) {
|
|
|
135025
135473
|
continue;
|
|
135026
135474
|
}
|
|
135027
135475
|
const trigger = { tap: site.componentId, key: site.key, action: site.actionId };
|
|
135028
|
-
const preState =
|
|
135476
|
+
const preState = snapshot2(w2).state;
|
|
135029
135477
|
const effective = effectiveSiteFor(site, preState);
|
|
135030
135478
|
if (!effective) {
|
|
135031
135479
|
actionsSkipped.push({ action: site.actionId, why: "no-row-value" });
|
|
@@ -135044,7 +135492,7 @@ async function crawlScreenInner(opts) {
|
|
|
135044
135492
|
errors.push({ service: parsed.service, message: `${parsed.action}: ${errText(e2)}`, ...e2.stack ? { stack: e2.stack } : {}, argless: workerArgs(dispatched).length === 0 });
|
|
135045
135493
|
}
|
|
135046
135494
|
exercised += 1;
|
|
135047
|
-
const { state, defects } =
|
|
135495
|
+
const { state, defects } = snapshot2(w2);
|
|
135048
135496
|
check(trigger, state, errors, defects);
|
|
135049
135497
|
reportDenied(w2.deniedCapabilities.slice(deniedBefore), trigger);
|
|
135050
135498
|
const navCountBefore = navEdges.length;
|
|
@@ -135303,7 +135751,7 @@ async function bootAndSnapshotState(opts) {
|
|
|
135303
135751
|
}
|
|
135304
135752
|
try {
|
|
135305
135753
|
for (let i2 = 0; i2 < 20; i2++) await yieldMacrotask();
|
|
135306
|
-
return
|
|
135754
|
+
return snapshot2(w2).state;
|
|
135307
135755
|
} finally {
|
|
135308
135756
|
w2.dispose();
|
|
135309
135757
|
}
|
|
@@ -135378,7 +135826,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
135378
135826
|
threwAt = "unreachable";
|
|
135379
135827
|
break;
|
|
135380
135828
|
}
|
|
135381
|
-
const effective = effectiveSiteFor(site,
|
|
135829
|
+
const effective = effectiveSiteFor(site, snapshot2(w2).state);
|
|
135382
135830
|
if (!effective) {
|
|
135383
135831
|
threwAt = "unreachable";
|
|
135384
135832
|
break;
|
|
@@ -135417,7 +135865,7 @@ async function crawlScreenDeep(opts, deep) {
|
|
|
135417
135865
|
}
|
|
135418
135866
|
for (let i2 = 0; i2 < 20; i2++) await yieldMacrotask();
|
|
135419
135867
|
flushStep();
|
|
135420
|
-
const { state, defects } =
|
|
135868
|
+
const { state, defects } = snapshot2(w2);
|
|
135421
135869
|
const hash2 = deepStateSignature(state, defects);
|
|
135422
135870
|
if (visited.has(hash2)) continue;
|
|
135423
135871
|
visited.add(hash2);
|
|
@@ -135551,7 +135999,7 @@ async function crawlScreenRelations(opts) {
|
|
|
135551
135999
|
const w2 = await boot();
|
|
135552
136000
|
try {
|
|
135553
136001
|
if (w2.errors.length) return null;
|
|
135554
|
-
let prev =
|
|
136002
|
+
let prev = snapshot2(w2).state;
|
|
135555
136003
|
const bootState = prev;
|
|
135556
136004
|
for (const [i2, site] of path2.entries()) {
|
|
135557
136005
|
const parsed = parseWorkerAction(site.actionId);
|
|
@@ -135568,7 +136016,7 @@ async function crawlScreenRelations(opts) {
|
|
|
135568
136016
|
}
|
|
135569
136017
|
for (let k2 = 0; k2 < 20; k2++) await yieldMacrotask();
|
|
135570
136018
|
if (w2.errors.length) return null;
|
|
135571
|
-
prev =
|
|
136019
|
+
prev = snapshot2(w2).state;
|
|
135572
136020
|
}
|
|
135573
136021
|
return prev;
|
|
135574
136022
|
} finally {
|
|
@@ -136775,7 +137223,7 @@ async function liveRenderServices(bundleJs, opts) {
|
|
|
136775
137223
|
}
|
|
136776
137224
|
}
|
|
136777
137225
|
if (opts.host) await settleUnawaitedWork();
|
|
136778
|
-
return { services:
|
|
137226
|
+
return { services: snapshot2(w2).state, calls: w2.calls, errors: w2.errors };
|
|
136779
137227
|
} finally {
|
|
136780
137228
|
w2.dispose();
|
|
136781
137229
|
}
|
|
@@ -136790,7 +137238,7 @@ async function loadAndSettle(bundleJs, options) {
|
|
|
136790
137238
|
const w2 = await bootBundleWorker(bundleJs, options);
|
|
136791
137239
|
try {
|
|
136792
137240
|
await settleUnawaitedWork();
|
|
136793
|
-
return { services:
|
|
137241
|
+
return { services: snapshot2(w2).state, calls: w2.calls, errors: w2.errors };
|
|
136794
137242
|
} finally {
|
|
136795
137243
|
w2.dispose();
|
|
136796
137244
|
}
|
|
@@ -137494,7 +137942,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137494
137942
|
}
|
|
137495
137943
|
}
|
|
137496
137944
|
}
|
|
137497
|
-
const
|
|
137945
|
+
const snapshot3 = await snapshotTokens(
|
|
137498
137946
|
app,
|
|
137499
137947
|
base,
|
|
137500
137948
|
async () => {
|
|
@@ -137524,10 +137972,10 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
|
|
|
137524
137972
|
},
|
|
137525
137973
|
(text11) => store.putTokens(app, text11)
|
|
137526
137974
|
);
|
|
137527
|
-
if (
|
|
137528
|
-
if (
|
|
137529
|
-
tokensSnapshotFailure =
|
|
137530
|
-
console.error(
|
|
137975
|
+
if (snapshot3.hash) tokensHash = snapshot3.hash;
|
|
137976
|
+
if (snapshot3.failure) {
|
|
137977
|
+
tokensSnapshotFailure = snapshot3.failure;
|
|
137978
|
+
console.error(snapshot3.failure.message);
|
|
137531
137979
|
}
|
|
137532
137980
|
Object.assign(catalogs, await bakeCatalogs(
|
|
137533
137981
|
app,
|
|
@@ -140161,13 +140609,237 @@ var init_wix_owner = __esm({
|
|
|
140161
140609
|
}
|
|
140162
140610
|
});
|
|
140163
140611
|
|
|
140612
|
+
// src/captcha-auth.ts
|
|
140613
|
+
function captchaAuthFinding(auth, siteId, platforms) {
|
|
140614
|
+
const login = auth;
|
|
140615
|
+
if (login?.providerId !== "wix-consumer") return void 0;
|
|
140616
|
+
const inline = login.config?.captcha;
|
|
140617
|
+
const hasInline = typeof inline === "object" && inline !== null;
|
|
140618
|
+
const inlineFor = (platform) => hasInline && !!inline[platform];
|
|
140619
|
+
const inlineKeys = platforms?.length ? platforms.every(inlineFor) : inlineFor("ios") || inlineFor("android");
|
|
140620
|
+
const site = siteId?.trim().toLowerCase();
|
|
140621
|
+
const bound2 = typeof login.config?.siteId === "string" ? login.config.siteId : "";
|
|
140622
|
+
const uncovered = hasInline ? (platforms ?? []).filter((platform) => !inlineFor(platform)) : [];
|
|
140623
|
+
if (bound2 && uncovered.length) return {
|
|
140624
|
+
code: "captcha_auth_inline_key_missing",
|
|
140625
|
+
keyless: true,
|
|
140626
|
+
message: `auth (WixConsumerAuthProvider) declares inline captcha keys but none for ${uncovered.join(" and ")}, and the inline block replaces the baked key file on device \u2014 a native ${uncovered.join("/")} build ships with no member CAPTCHA key. Add captcha.${uncovered[0]} (or remove the captcha block to use the baked key), push a new release, and build from it.`
|
|
140627
|
+
};
|
|
140628
|
+
if (!bound2) return {
|
|
140629
|
+
code: "captcha_auth_site_missing",
|
|
140630
|
+
keyless: true,
|
|
140631
|
+
message: `auth (WixConsumerAuthProvider) names no siteId, so a native build cannot carry a member CAPTCHA key: the build drops the key file and the device refuses the key \u2014 member sign-in on a CAPTCHA-protected site fails with "Complete verification to continue". Add siteId: "${site ?? "<the site's metaSiteId, lower case>"}" to WixConsumerAuthProvider in config.ts, push a new release, and build from it.`
|
|
140632
|
+
};
|
|
140633
|
+
if (bound2 !== bound2.trim().toLowerCase() && !inlineKeys) return {
|
|
140634
|
+
code: "captcha_auth_site_case",
|
|
140635
|
+
keyless: true,
|
|
140636
|
+
message: `auth (WixConsumerAuthProvider) names siteId "${bound2}", but member CAPTCHA keys are stored and matched under the lower-case id, exactly, so a native build would ship without one. Write siteId: "${bound2.trim().toLowerCase()}", push a new release, and build from it.`
|
|
140637
|
+
};
|
|
140638
|
+
if (site && bound2.trim().toLowerCase() !== site) return {
|
|
140639
|
+
code: "captcha_auth_site_mismatch",
|
|
140640
|
+
keyless: false,
|
|
140641
|
+
message: `auth (WixConsumerAuthProvider) names siteId "${bound2}", not ${site}, so a member CAPTCHA key for ${site} cannot bind to this app's login and native member sign-in on a CAPTCHA-protected site fails. Bind the login and the build to the same site.`
|
|
140642
|
+
};
|
|
140643
|
+
return void 0;
|
|
140644
|
+
}
|
|
140645
|
+
var init_captcha_auth = __esm({
|
|
140646
|
+
"src/captcha-auth.ts"() {
|
|
140647
|
+
}
|
|
140648
|
+
});
|
|
140649
|
+
|
|
140650
|
+
// ../../stdlib/auth-providers/wix/src/member-captcha-policy.ts
|
|
140651
|
+
function acceptsClientSiteKeyToken(option) {
|
|
140652
|
+
return CLIENT_SITE_KEY_OPTIONS.includes(option);
|
|
140653
|
+
}
|
|
140654
|
+
function asOption(value2) {
|
|
140655
|
+
return value2 === "ALWAYS" || value2 === "SUSPECTED_BOTS_ONLY" || value2 === "NEVER" ? value2 : "UNKNOWN";
|
|
140656
|
+
}
|
|
140657
|
+
function parseMemberCaptchaPolicy(raw) {
|
|
140658
|
+
const settings = raw?.settings ?? {};
|
|
140659
|
+
return {
|
|
140660
|
+
login: asOption(settings.loginRecaptchaOption),
|
|
140661
|
+
signup: asOption(settings.signupRecaptchaOption)
|
|
140662
|
+
};
|
|
140663
|
+
}
|
|
140664
|
+
var MEMBER_SITE_SETTINGS_URL, CLIENT_SITE_KEY_OPTIONS;
|
|
140665
|
+
var init_member_captcha_policy = __esm({
|
|
140666
|
+
"../../stdlib/auth-providers/wix/src/member-captcha-policy.ts"() {
|
|
140667
|
+
MEMBER_SITE_SETTINGS_URL = "https://manage.wix.com/_api/wix-sm-webapp/v1/collection/settings";
|
|
140668
|
+
CLIENT_SITE_KEY_OPTIONS = ["ALWAYS", "SUSPECTED_BOTS_ONLY"];
|
|
140669
|
+
}
|
|
140670
|
+
});
|
|
140671
|
+
|
|
140672
|
+
// src/site-analyze/rest.ts
|
|
140673
|
+
var rest_exports = {};
|
|
140674
|
+
__export(rest_exports, {
|
|
140675
|
+
WIX_API: () => WIX_API2,
|
|
140676
|
+
WixApiError: () => WixApiError2,
|
|
140677
|
+
classifyHttp: () => classifyHttp,
|
|
140678
|
+
compactWixstaticUrl: () => compactWixstaticUrl,
|
|
140679
|
+
isGenericWixFavicon: () => isGenericWixFavicon,
|
|
140680
|
+
makeTransport: () => makeTransport,
|
|
140681
|
+
mediaUrlFromLogo: () => mediaUrlFromLogo,
|
|
140682
|
+
ownerTransportFrom: () => ownerTransportFrom,
|
|
140683
|
+
probeCall: () => probeCall,
|
|
140684
|
+
resolveWixUrl: () => resolveWixUrl,
|
|
140685
|
+
uploadMediaBytes: () => uploadMediaBytes,
|
|
140686
|
+
visitorTransportFrom: () => visitorTransportFrom,
|
|
140687
|
+
wixMediaFileId: () => wixMediaFileId
|
|
140688
|
+
});
|
|
140689
|
+
function resolveWixUrl(path2) {
|
|
140690
|
+
if (/^https?:\/\//i.test(path2)) return path2;
|
|
140691
|
+
return `${WIX_API2}${path2}`;
|
|
140692
|
+
}
|
|
140693
|
+
function classifyHttp(status, count2) {
|
|
140694
|
+
if (status === 428) return "not-installed";
|
|
140695
|
+
if (status === 404) return "wrong-path";
|
|
140696
|
+
if (status && status >= 400) return "error";
|
|
140697
|
+
return count2 > 0 ? "ok" : "empty";
|
|
140698
|
+
}
|
|
140699
|
+
function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS2) {
|
|
140700
|
+
return async (method, path2, body) => {
|
|
140701
|
+
const headers2 = { Accept: "application/json" };
|
|
140702
|
+
if (auth?.token) headers2.Authorization = auth.token;
|
|
140703
|
+
if (auth?.msid) headers2["wix-site-id"] = auth.msid;
|
|
140704
|
+
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
140705
|
+
const res = await fetchImpl(resolveWixUrl(path2), {
|
|
140706
|
+
method,
|
|
140707
|
+
headers: headers2,
|
|
140708
|
+
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
140709
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
140710
|
+
});
|
|
140711
|
+
const text11 = await res.text();
|
|
140712
|
+
let parsed = text11;
|
|
140713
|
+
try {
|
|
140714
|
+
parsed = text11 ? JSON.parse(text11) : null;
|
|
140715
|
+
} catch {
|
|
140716
|
+
}
|
|
140717
|
+
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
140718
|
+
return parsed;
|
|
140719
|
+
};
|
|
140720
|
+
}
|
|
140721
|
+
function ownerTransportFrom(fetchImpl, owner) {
|
|
140722
|
+
return makeTransport(fetchImpl, { token: owner.token, msid: owner.msid });
|
|
140723
|
+
}
|
|
140724
|
+
function visitorTransportFrom(fetchImpl, token, msid) {
|
|
140725
|
+
return makeTransport(fetchImpl, { token, msid });
|
|
140726
|
+
}
|
|
140727
|
+
async function probeCall(call, method, path2, body) {
|
|
140728
|
+
try {
|
|
140729
|
+
return { data: await call(method, path2, body), err: null };
|
|
140730
|
+
} catch (e2) {
|
|
140731
|
+
if (e2 instanceof WixApiError2) return { data: null, err: e2 };
|
|
140732
|
+
throw e2;
|
|
140733
|
+
}
|
|
140734
|
+
}
|
|
140735
|
+
function mediaUrlFromLogo(logo) {
|
|
140736
|
+
const s2 = (logo ?? "").trim();
|
|
140737
|
+
if (!s2) return null;
|
|
140738
|
+
if (/^https?:\/\//i.test(s2)) return s2;
|
|
140739
|
+
const id = s2.replace(/^wix:image:\/\/v1\//, "").split("/")[0].split("#")[0];
|
|
140740
|
+
if (!id) return null;
|
|
140741
|
+
if (/^https?:\/\//i.test(id)) return id;
|
|
140742
|
+
return `https://static.wixstatic.com/media/${id}`;
|
|
140743
|
+
}
|
|
140744
|
+
function isGenericWixFavicon(url) {
|
|
140745
|
+
try {
|
|
140746
|
+
const h2 = new URL(url).hostname.toLowerCase();
|
|
140747
|
+
return h2 === "wix.com" || h2.endsWith(".wix.com");
|
|
140748
|
+
} catch {
|
|
140749
|
+
return false;
|
|
140750
|
+
}
|
|
140751
|
+
}
|
|
140752
|
+
function wixMediaFileId(url) {
|
|
140753
|
+
const m2 = url.match(/static\.wixstatic\.com\/media\/([^/?#]+)/i);
|
|
140754
|
+
return m2?.[1] ? decodeURIComponent(m2[1]) : void 0;
|
|
140755
|
+
}
|
|
140756
|
+
function compactWixstaticUrl(url, maxEdge = 800) {
|
|
140757
|
+
if (!/static\.wixstatic\.com\/media\//i.test(url)) return url;
|
|
140758
|
+
if (/\.(svg|ico)(\?|#|$)/i.test(url.split("?")[0] ?? url)) return url;
|
|
140759
|
+
const w2 = url.match(/(?:\/|,)w_(\d+)/)?.[1];
|
|
140760
|
+
if (w2 && Number(w2) <= maxEdge) return url;
|
|
140761
|
+
const id = wixMediaFileId(url);
|
|
140762
|
+
if (!id) return url;
|
|
140763
|
+
return `https://static.wixstatic.com/media/${id}/v1/fill/w_${maxEdge},h_${maxEdge},al_c,q_80,enc_auto/file.jpg`;
|
|
140764
|
+
}
|
|
140765
|
+
async function uploadMediaBytes(call, fetchImpl, bytes2, fileName, mimeType) {
|
|
140766
|
+
const { uploadUrl } = await call(
|
|
140767
|
+
"POST",
|
|
140768
|
+
"/site-media/v1/files/generate-upload-url",
|
|
140769
|
+
{ mimeType, fileName: `himi-business-book/${fileName}` }
|
|
140770
|
+
);
|
|
140771
|
+
const put = await fetchImpl(`${uploadUrl}?filename=${encodeURIComponent(fileName)}`, {
|
|
140772
|
+
method: "PUT",
|
|
140773
|
+
headers: { "Content-Type": mimeType },
|
|
140774
|
+
body: bytes2,
|
|
140775
|
+
signal: AbortSignal.timeout(12e4)
|
|
140776
|
+
});
|
|
140777
|
+
if (!put.ok) throw new Error(`media upload PUT failed: ${put.status}`);
|
|
140778
|
+
const payload = await put.json();
|
|
140779
|
+
const file2 = payload.file ?? payload;
|
|
140780
|
+
const id = file2?.id ?? file2?.fileId;
|
|
140781
|
+
const url = file2?.url ?? (id ? `https://static.wixstatic.com/media/${id}` : void 0);
|
|
140782
|
+
if (!id || !url) throw new Error("media upload returned no file id");
|
|
140783
|
+
return { id, url };
|
|
140784
|
+
}
|
|
140785
|
+
var WIX_API2, DEFAULT_TIMEOUT_MS2, WixApiError2;
|
|
140786
|
+
var init_rest = __esm({
|
|
140787
|
+
"src/site-analyze/rest.ts"() {
|
|
140788
|
+
WIX_API2 = "https://www.wixapis.com";
|
|
140789
|
+
DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
140790
|
+
WixApiError2 = class extends Error {
|
|
140791
|
+
constructor(status, method, path2, body) {
|
|
140792
|
+
super(`${method} ${path2} \u2192 ${status}`);
|
|
140793
|
+
this.status = status;
|
|
140794
|
+
this.method = method;
|
|
140795
|
+
this.path = path2;
|
|
140796
|
+
this.body = body;
|
|
140797
|
+
this.name = "WixApiError";
|
|
140798
|
+
}
|
|
140799
|
+
};
|
|
140800
|
+
}
|
|
140801
|
+
});
|
|
140802
|
+
|
|
140803
|
+
// src/site-analyze/visitor-auth.ts
|
|
140804
|
+
var visitor_auth_exports = {};
|
|
140805
|
+
__export(visitor_auth_exports, {
|
|
140806
|
+
mintVisitorToken: () => mintVisitorToken
|
|
140807
|
+
});
|
|
140808
|
+
async function mintVisitorToken(fetchImpl, clientId) {
|
|
140809
|
+
const res = await fetchImpl(`${WIX_API2}/oauth2/token`, {
|
|
140810
|
+
method: "POST",
|
|
140811
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
140812
|
+
body: JSON.stringify({ clientId, grantType: "anonymous" }),
|
|
140813
|
+
signal: AbortSignal.timeout(8e3)
|
|
140814
|
+
});
|
|
140815
|
+
const text11 = await res.text();
|
|
140816
|
+
let parsed = text11;
|
|
140817
|
+
try {
|
|
140818
|
+
parsed = text11 ? JSON.parse(text11) : null;
|
|
140819
|
+
} catch {
|
|
140820
|
+
}
|
|
140821
|
+
if (!res.ok) throw new WixApiError2(res.status, "POST", "/oauth2/token", parsed);
|
|
140822
|
+
const token = parsed?.access_token ?? parsed?.accessToken;
|
|
140823
|
+
if (!token) throw new Error("visitor mint returned no access_token");
|
|
140824
|
+
return token;
|
|
140825
|
+
}
|
|
140826
|
+
var init_visitor_auth = __esm({
|
|
140827
|
+
"src/site-analyze/visitor-auth.ts"() {
|
|
140828
|
+
init_rest();
|
|
140829
|
+
}
|
|
140830
|
+
});
|
|
140831
|
+
|
|
140164
140832
|
// src/captcha.ts
|
|
140165
140833
|
var captcha_exports = {};
|
|
140166
140834
|
__export(captcha_exports, {
|
|
140835
|
+
captchaAuthFinding: () => captchaAuthFinding,
|
|
140167
140836
|
captchaContentInput: () => captchaContentInput,
|
|
140168
|
-
|
|
140837
|
+
captchaDistGate: () => captchaDistGate,
|
|
140838
|
+
contentCaptchaAuthFinding: () => contentCaptchaAuthFinding,
|
|
140839
|
+
runCaptcha: () => runCaptcha,
|
|
140840
|
+
siteMemberCaptchaPolicy: () => siteMemberCaptchaPolicy
|
|
140169
140841
|
});
|
|
140170
|
-
import { readFileSync as readFileSync40 } from "node:fs";
|
|
140842
|
+
import { existsSync as existsSync36, readFileSync as readFileSync40 } from "node:fs";
|
|
140171
140843
|
import { resolve as resolve34 } from "node:path";
|
|
140172
140844
|
function readObject(path2) {
|
|
140173
140845
|
try {
|
|
@@ -140186,6 +140858,64 @@ function captchaContentInput(dir) {
|
|
|
140186
140858
|
androidApplicationId: text2(provisioning.native?.androidApplicationId)
|
|
140187
140859
|
};
|
|
140188
140860
|
}
|
|
140861
|
+
async function contentAuth(dir, app) {
|
|
140862
|
+
if (!existsSync36(resolve34(dir, "himalaya.content.json"))) return void 0;
|
|
140863
|
+
if (app !== void 0 && captchaContentInput(dir).app !== app) return void 0;
|
|
140864
|
+
try {
|
|
140865
|
+
const { loadAppConfigModule: loadAppConfigModule2 } = await Promise.resolve().then(() => (init_app_config_loader(), app_config_loader_exports));
|
|
140866
|
+
return (await loadAppConfigModule2(dir))?.auth;
|
|
140867
|
+
} catch {
|
|
140868
|
+
return void 0;
|
|
140869
|
+
}
|
|
140870
|
+
}
|
|
140871
|
+
async function contentCaptchaAuthFinding(dir, siteId, app, platforms) {
|
|
140872
|
+
const auth = await contentAuth(dir, app);
|
|
140873
|
+
return auth === void 0 ? void 0 : captchaAuthFinding(auth, siteId, platforms);
|
|
140874
|
+
}
|
|
140875
|
+
async function siteMemberCaptchaPolicy(clientId, fetchImpl = fetch) {
|
|
140876
|
+
const { mintVisitorToken: mintVisitorToken2 } = await Promise.resolve().then(() => (init_visitor_auth(), visitor_auth_exports));
|
|
140877
|
+
const token = await mintVisitorToken2(fetchImpl, clientId);
|
|
140878
|
+
const res = await fetchImpl(MEMBER_SITE_SETTINGS_URL, {
|
|
140879
|
+
headers: { Authorization: token, Accept: "application/json" },
|
|
140880
|
+
signal: AbortSignal.timeout(8e3)
|
|
140881
|
+
});
|
|
140882
|
+
if (!res.ok) throw new Error(`the member settings read answered HTTP ${res.status}`);
|
|
140883
|
+
return parseMemberCaptchaPolicy(await res.json());
|
|
140884
|
+
}
|
|
140885
|
+
async function releaseAuth(client2, app, release2) {
|
|
140886
|
+
try {
|
|
140887
|
+
let previewToken;
|
|
140888
|
+
if (release2) {
|
|
140889
|
+
const minted = await client2.previewToken(app, release2);
|
|
140890
|
+
previewToken = minted.json?.previewToken;
|
|
140891
|
+
if (!minted.ok || typeof previewToken !== "string") return { error: `no preview token for release ${release2} (HTTP ${minted.status})` };
|
|
140892
|
+
}
|
|
140893
|
+
const read = await client2.fetchAppConfig(app, release2, previewToken);
|
|
140894
|
+
if (!read.ok) return { error: `its app-config read answered HTTP ${read.status}` };
|
|
140895
|
+
return { auth: read.json?.authConfig ?? null };
|
|
140896
|
+
} catch (error) {
|
|
140897
|
+
return { error: error?.message ?? String(error) };
|
|
140898
|
+
}
|
|
140899
|
+
}
|
|
140900
|
+
async function captchaDistGate(options) {
|
|
140901
|
+
const { auth, error } = await releaseAuth(options.client, options.app, options.release);
|
|
140902
|
+
if (error) return { advisory: `member CAPTCHA check skipped: the release's login could not be read (${error}). If the login names no siteId and the site requires a member CAPTCHA, member sign-in in this build will fail.` };
|
|
140903
|
+
const finding2 = captchaAuthFinding(auth, options.requestedSite, options.platforms);
|
|
140904
|
+
if (!finding2) return {};
|
|
140905
|
+
if (!finding2.keyless) return { advisory: `${finding2.code}: ${finding2.message}` };
|
|
140906
|
+
const clientId = auth.config?.clientId;
|
|
140907
|
+
const unasked = (why) => ({ advisory: `${finding2.code}: ${finding2.message} Not refused: ${why}, so whether the site requires a member CAPTCHA is unknown \u2014 if it does, member sign-in in this build will fail.` });
|
|
140908
|
+
if (typeof clientId !== "string" || !clientId || clientId === PLACEHOLDER_CLIENT_ID) return unasked("the login has no Wix client to ask with");
|
|
140909
|
+
let policy;
|
|
140910
|
+
try {
|
|
140911
|
+
policy = await siteMemberCaptchaPolicy(clientId, options.fetchImpl ?? fetch);
|
|
140912
|
+
} catch (error2) {
|
|
140913
|
+
return unasked(`the site's member settings could not be read (${error2?.message ?? String(error2)})`);
|
|
140914
|
+
}
|
|
140915
|
+
const demands = ["login", "signup"].filter((source) => acceptsClientSiteKeyToken(policy[source]));
|
|
140916
|
+
if (demands.length === 0) return {};
|
|
140917
|
+
return { refuse: { code: finding2.code, captchaPolicy: policy, message: `${finding2.message} The site requires a CAPTCHA for member ${demands.map((source) => `${source} (${policy[source]})`).join(" and ")}. The key is baked only for a build bound to the site (--site, provisioning.json, or the app's own site binding).` } };
|
|
140918
|
+
}
|
|
140189
140919
|
async function runCaptcha(pos, flags, io2, deps = {}) {
|
|
140190
140920
|
const operation = pos[1];
|
|
140191
140921
|
if (operation !== "setup" && operation !== "status") {
|
|
@@ -140215,6 +140945,14 @@ async function runCaptcha(pos, flags, io2, deps = {}) {
|
|
|
140215
140945
|
fetchImpl: deps.fetchImpl
|
|
140216
140946
|
});
|
|
140217
140947
|
io2.log(JSON.stringify(result.body));
|
|
140948
|
+
const anyReady = (result.body.records ?? []).some((record2) => record2?.status === "ready");
|
|
140949
|
+
const finding2 = operation === "setup" && anyReady ? await contentCaptchaAuthFinding(
|
|
140950
|
+
text2(flags.content) ?? process.cwd(),
|
|
140951
|
+
input.siteId,
|
|
140952
|
+
input.app,
|
|
140953
|
+
[...input.iosBundleId ? ["ios"] : [], ...input.androidApplicationId ? ["android"] : []]
|
|
140954
|
+
) : void 0;
|
|
140955
|
+
if (finding2) io2.error(`\u26A0 ${finding2.code}: ${finding2.message}`);
|
|
140218
140956
|
return result.ok ? 0 : 1;
|
|
140219
140957
|
} catch {
|
|
140220
140958
|
io2.error(JSON.stringify({ error: "captcha_service_unavailable", complete: false }));
|
|
@@ -140228,6 +140966,9 @@ var init_captcha2 = __esm({
|
|
|
140228
140966
|
init_captcha();
|
|
140229
140967
|
init_captcha_service();
|
|
140230
140968
|
init_wix_owner();
|
|
140969
|
+
init_captcha_auth();
|
|
140970
|
+
init_wix_placeholders();
|
|
140971
|
+
init_member_captcha_policy();
|
|
140231
140972
|
text2 = (value2) => typeof value2 === "string" ? value2 : void 0;
|
|
140232
140973
|
}
|
|
140233
140974
|
});
|
|
@@ -140241,7 +140982,7 @@ __export(preflight_exports, {
|
|
|
140241
140982
|
parseStoreConfig: () => parseStoreConfig,
|
|
140242
140983
|
requireEnv: () => requireEnv
|
|
140243
140984
|
});
|
|
140244
|
-
import { existsSync as
|
|
140985
|
+
import { existsSync as existsSync37, readFileSync as readFileSync41 } from "node:fs";
|
|
140245
140986
|
import { isAbsolute as isAbsolute2, relative as relative7, resolve as resolve35 } from "node:path";
|
|
140246
140987
|
function isInsideRepo(p2) {
|
|
140247
140988
|
const rel = relative7(REPO_ROOT, resolve35(p2));
|
|
@@ -140298,7 +141039,7 @@ function parseStoreConfig(text11) {
|
|
|
140298
141039
|
}
|
|
140299
141040
|
function loadStoreConfig(app) {
|
|
140300
141041
|
const p2 = storeConfigPath(app);
|
|
140301
|
-
if (!
|
|
141042
|
+
if (!existsSync37(p2)) {
|
|
140302
141043
|
throw new Error(`No store config at ${p2}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
|
|
140303
141044
|
}
|
|
140304
141045
|
return parseStoreConfig(readFileSync41(p2, "utf8"));
|
|
@@ -143989,10 +144730,10 @@ var init_Matcher = __esm({
|
|
|
143989
144730
|
* Restore state from snapshot.
|
|
143990
144731
|
* @param {Object} snapshot
|
|
143991
144732
|
*/
|
|
143992
|
-
restore(
|
|
144733
|
+
restore(snapshot3) {
|
|
143993
144734
|
this._pathStringCache = null;
|
|
143994
|
-
this.path =
|
|
143995
|
-
this.siblingStacks =
|
|
144735
|
+
this.path = snapshot3.path.map((node) => ({ ...node }));
|
|
144736
|
+
this.siblingStacks = snapshot3.siblingStacks.map((map) => new Map(map));
|
|
143996
144737
|
}
|
|
143997
144738
|
/**
|
|
143998
144739
|
* Return the read-only {@link MatcherView} for this matcher.
|
|
@@ -147030,7 +147771,7 @@ var init_customer_signing_inspect = __esm({
|
|
|
147030
147771
|
});
|
|
147031
147772
|
|
|
147032
147773
|
// src/push-onboarding.ts
|
|
147033
|
-
import { existsSync as
|
|
147774
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync19, readFileSync as readFileSync42, statSync as statSync9, writeFileSync as writeFileSync13, chmodSync as chmodSync2 } from "node:fs";
|
|
147034
147775
|
import { basename as basename11, dirname as dirname24, join as join32, resolve as resolve36 } from "node:path";
|
|
147035
147776
|
function readJson4(path2) {
|
|
147036
147777
|
try {
|
|
@@ -147042,7 +147783,7 @@ function readJson4(path2) {
|
|
|
147042
147783
|
}
|
|
147043
147784
|
function pushInputsFromContent(dir) {
|
|
147044
147785
|
const root = resolve36(dir);
|
|
147045
|
-
if (!
|
|
147786
|
+
if (!existsSync38(join32(root, "himalaya.content.json"))) return { initialized: false };
|
|
147046
147787
|
const content = readJson4(join32(root, "himalaya.content.json"));
|
|
147047
147788
|
const provisioning = readJson4(join32(root, "provisioning.json"));
|
|
147048
147789
|
const native = provisioning.native ?? {};
|
|
@@ -147174,7 +147915,7 @@ function buildPushSetupBody(i2, keys) {
|
|
|
147174
147915
|
}
|
|
147175
147916
|
function readPushOnboarding(dir) {
|
|
147176
147917
|
const path2 = join32(resolve36(dir), PUSH_ONBOARDING_PATH);
|
|
147177
|
-
if (!
|
|
147918
|
+
if (!existsSync38(path2)) return { version: 1 };
|
|
147178
147919
|
const parsed = readJson4(path2);
|
|
147179
147920
|
return { version: 1, ...parsed };
|
|
147180
147921
|
}
|
|
@@ -147209,7 +147950,7 @@ function recordPushDeferral(dir, d2) {
|
|
|
147209
147950
|
}
|
|
147210
147951
|
function clearPushDeferral(dir) {
|
|
147211
147952
|
const path2 = join32(resolve36(dir), PUSH_ONBOARDING_PATH);
|
|
147212
|
-
if (!
|
|
147953
|
+
if (!existsSync38(path2)) return;
|
|
147213
147954
|
const { push: _dropped, ...rest } = readPushOnboarding(dir);
|
|
147214
147955
|
writeFile(dir, { ...rest, version: 1 });
|
|
147215
147956
|
}
|
|
@@ -147277,7 +148018,7 @@ var signing_inspect_exports = {};
|
|
|
147277
148018
|
__export(signing_inspect_exports, {
|
|
147278
148019
|
runSigningInspect: () => runSigningInspect
|
|
147279
148020
|
});
|
|
147280
|
-
import { existsSync as
|
|
148021
|
+
import { existsSync as existsSync39, readFileSync as readFileSync43, statSync as statSync10 } from "node:fs";
|
|
147281
148022
|
import { isAbsolute as isAbsolute3, resolve as resolve37 } from "node:path";
|
|
147282
148023
|
function fail4(io2, code, fields = {}) {
|
|
147283
148024
|
io2.error(JSON.stringify({ ok: false, code, ...fields }));
|
|
@@ -147367,7 +148108,7 @@ async function runSigningInspect(pos, flags, io2, deps = {}) {
|
|
|
147367
148108
|
} catch (error) {
|
|
147368
148109
|
return fail4(io2, "signing_inspect_key_inside_repo", { error: error.message });
|
|
147369
148110
|
}
|
|
147370
|
-
if (!
|
|
148111
|
+
if (!existsSync39(certPath) || !existsSync39(profilePath2)) {
|
|
147371
148112
|
return fail4(io2, "signing_inspect_local_assets_unreadable", { error: "cannot read --cert-file or --profile-file" });
|
|
147372
148113
|
}
|
|
147373
148114
|
if (statSync10(certPath).size > 1048576 || statSync10(profilePath2).size > 1048576) {
|
|
@@ -147901,7 +148642,7 @@ __export(template_trim_exports, {
|
|
|
147901
148642
|
routeMatcher: () => routeMatcher,
|
|
147902
148643
|
runTemplateTrim: () => runTemplateTrim
|
|
147903
148644
|
});
|
|
147904
|
-
import { cpSync, existsSync as
|
|
148645
|
+
import { cpSync, existsSync as existsSync40, mkdirSync as mkdirSync20, readdirSync as readdirSync21, readFileSync as readFileSync45, renameSync as renameSync8, rmSync as rmSync11, statSync as statSync11, writeFileSync as writeFileSync15 } from "node:fs";
|
|
147905
148646
|
import { dirname as dirname25, join as join34 } from "node:path";
|
|
147906
148647
|
function routeMatcher(pattern) {
|
|
147907
148648
|
const detail = /^\^([A-Za-z0-9_]+)\(\?:\[_\/\]\(\.\+\)\)\?\$$/.exec(pattern);
|
|
@@ -148646,7 +149387,7 @@ function homeModulesPass(app, kept, edited) {
|
|
|
148646
149387
|
}
|
|
148647
149388
|
function listWorkers(dir) {
|
|
148648
149389
|
const root = join34(dir, "tier5-src");
|
|
148649
|
-
if (!
|
|
149390
|
+
if (!existsSync40(root)) return { dirs: [], files: {} };
|
|
148650
149391
|
const dirs = readdirSync21(root).filter((n2) => statSync11(join34(root, n2)).isDirectory()).sort();
|
|
148651
149392
|
const files = {};
|
|
148652
149393
|
const walk2 = (abs, rel) => {
|
|
@@ -148683,7 +149424,7 @@ async function runTemplateTrim(req, deps) {
|
|
|
148683
149424
|
const dir = req.dir;
|
|
148684
149425
|
const devPath = join34(dir, "dev/index.ts");
|
|
148685
149426
|
const configPath = join34(dir, "config.ts");
|
|
148686
|
-
if (!
|
|
149427
|
+
if (!existsSync40(devPath) || !existsSync40(configPath)) {
|
|
148687
149428
|
return refuse3(new TrimRefusal(`${dir} has no dev/index.ts + config.ts \u2014 point --content at an app scaffolded with \`himi init --template\``));
|
|
148688
149429
|
}
|
|
148689
149430
|
if (isTemplateSourceTree(dir)) {
|
|
@@ -148730,7 +149471,7 @@ async function runTemplateTrim(req, deps) {
|
|
|
148730
149471
|
}
|
|
148731
149472
|
}
|
|
148732
149473
|
if (req.dryRun) return { code: 0, result: { ok: true, dryRun: true, ...plan.report, validate: null } };
|
|
148733
|
-
const hadHimi =
|
|
149474
|
+
const hadHimi = existsSync40(join34(dir, ".himi"));
|
|
148734
149475
|
const backupRel = join34(".himi", "trim-backup", (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-"));
|
|
148735
149476
|
const backup = join34(dir, backupRel);
|
|
148736
149477
|
const originals = [[devPath, "dev/index.ts"], [configPath, "config.ts"], ...trimmedContent !== void 0 ? [[contentPath, "himalaya.content.json"]] : []];
|
|
@@ -148739,7 +149480,7 @@ async function runTemplateTrim(req, deps) {
|
|
|
148739
149480
|
for (const [path2, rel] of originals) {
|
|
148740
149481
|
if (rel === "himalaya.content.json") contentManifestPath(dir);
|
|
148741
149482
|
const original = readFileSync45(join34(backup, rel));
|
|
148742
|
-
if (!
|
|
149483
|
+
if (!existsSync40(path2) || !readFileSync45(path2).equals(original)) {
|
|
148743
149484
|
if (rel === "himalaya.content.json") writeContentManifest(dir, original);
|
|
148744
149485
|
else writeFileSync15(path2, original);
|
|
148745
149486
|
}
|
|
@@ -149096,17 +149837,17 @@ __export(template_adopt_exports, {
|
|
|
149096
149837
|
workerReach: () => workerReach,
|
|
149097
149838
|
writeInventory: () => writeInventory
|
|
149098
149839
|
});
|
|
149099
|
-
import { existsSync as
|
|
149840
|
+
import { existsSync as existsSync41, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readdirSync as readdirSync22, readFileSync as readFileSync46, renameSync as renameSync9, statSync as statSync12, writeFileSync as writeFileSync16 } from "node:fs";
|
|
149100
149841
|
import { dirname as dirname26, join as join35, posix as posix2 } from "node:path";
|
|
149101
149842
|
function readAppSources(dir) {
|
|
149102
149843
|
const devPath = join35(dir, "dev", "index.ts");
|
|
149103
149844
|
const configPath = join35(dir, "config.ts");
|
|
149104
|
-
if (!
|
|
149845
|
+
if (!existsSync41(devPath) || !existsSync41(configPath)) {
|
|
149105
149846
|
throw new TrimRefusal(`no dev/index.ts + config.ts under ${dir} \u2014 run this in (or point --content at) an app \`himi init --template\` scaffolded`);
|
|
149106
149847
|
}
|
|
149107
149848
|
const workers = /* @__PURE__ */ new Map();
|
|
149108
149849
|
const root = join35(dir, "tier5-src");
|
|
149109
|
-
if (
|
|
149850
|
+
if (existsSync41(root)) {
|
|
149110
149851
|
for (const name of readdirSync22(root).sort()) {
|
|
149111
149852
|
const abs = join35(root, name);
|
|
149112
149853
|
if (!statSync12(abs).isDirectory()) continue;
|
|
@@ -149346,7 +150087,7 @@ function inventoryOf(dir, src, app) {
|
|
|
149346
150087
|
sampleCopy: copyHits(dir, SAMPLE_COPY, 50),
|
|
149347
150088
|
matrix,
|
|
149348
150089
|
journeys,
|
|
149349
|
-
netMocks:
|
|
150090
|
+
netMocks: existsSync41(join35(dir, "dev", "net-mocks.json"))
|
|
149350
150091
|
};
|
|
149351
150092
|
}
|
|
149352
150093
|
function matrixMarkdown(rows) {
|
|
@@ -149382,9 +150123,9 @@ function inventorySummary(inv) {
|
|
|
149382
150123
|
function writeNoFollow(dir, rel, body) {
|
|
149383
150124
|
const p2 = join35(dir, rel);
|
|
149384
150125
|
const parent = dirname26(p2);
|
|
149385
|
-
if (
|
|
150126
|
+
if (existsSync41(parent) && lstatSync11(parent).isSymbolicLink()) throw new TrimRefusal(`${dirname26(rel)} is a symlink \u2014 refusing to write through it`);
|
|
149386
150127
|
mkdirSync21(parent, { recursive: true });
|
|
149387
|
-
if (
|
|
150128
|
+
if (existsSync41(p2) && lstatSync11(p2).isSymbolicLink()) throw new TrimRefusal(`${rel} is a symlink \u2014 refusing to write through it`);
|
|
149388
150129
|
const tmp = `${p2}.${process.pid}.${Date.now()}.tmp`;
|
|
149389
150130
|
writeFileSync16(tmp, body, { flag: "wx" });
|
|
149390
150131
|
renameSync9(tmp, p2);
|
|
@@ -149393,7 +150134,7 @@ function writeInventory(dir, inv, opts = {}) {
|
|
|
149393
150134
|
const written = [];
|
|
149394
150135
|
const keep = opts.companions === "if-missing";
|
|
149395
150136
|
const put = (rel, body, companion) => {
|
|
149396
|
-
if (companion && keep &&
|
|
150137
|
+
if (companion && keep && existsSync41(join35(dir, rel))) return;
|
|
149397
150138
|
writeNoFollow(dir, rel, body);
|
|
149398
150139
|
written.push(rel);
|
|
149399
150140
|
};
|
|
@@ -149499,7 +150240,7 @@ function addScreen(dir, id, entry, opts = {}) {
|
|
|
149499
150240
|
}
|
|
149500
150241
|
for (const rel of ["dev", "dev/index.ts", ...config !== src.config ? ["config.ts"] : [], ...contentWithView !== void 0 ? ["himalaya.content.json"] : []]) {
|
|
149501
150242
|
const p2 = join35(dir, rel);
|
|
149502
|
-
if (
|
|
150243
|
+
if (existsSync41(p2) && lstatSync11(p2).isSymbolicLink()) throw new TrimRefusal(`${rel} is a symlink \u2014 refusing to write through it (nothing written)`);
|
|
149503
150244
|
}
|
|
149504
150245
|
writeNoFollow(dir, "dev/index.ts", dev);
|
|
149505
150246
|
if (config !== src.config) writeNoFollow(dir, "config.ts", config);
|
|
@@ -149522,7 +150263,7 @@ function specScreens(spec) {
|
|
|
149522
150263
|
return [...new Set(out2)];
|
|
149523
150264
|
}
|
|
149524
150265
|
function keepFromSpec(dir, specPath) {
|
|
149525
|
-
if (!
|
|
150266
|
+
if (!existsSync41(specPath)) throw new TrimRefusal(`no ${specPath} \u2014 --from-spec reads the approved plan's \`## Screen catalogue\``);
|
|
149526
150267
|
const ids = specScreens(readFileSync46(specPath, "utf8"));
|
|
149527
150268
|
if (!ids.length) {
|
|
149528
150269
|
throw new TrimRefusal("SPEC.md's `## Screen catalogue` names no screen ids \u2014 put each screen's id (`himi template screens` lists them) in the first column, in backticks");
|
|
@@ -150275,7 +151016,7 @@ __export(pack_exports, {
|
|
|
150275
151016
|
});
|
|
150276
151017
|
import { createHash as createHash24 } from "node:crypto";
|
|
150277
151018
|
import { deflateRawSync, inflateRawSync } from "node:zlib";
|
|
150278
|
-
import { existsSync as
|
|
151019
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync22, readFileSync as readFileSync48, readdirSync as readdirSync23, rmSync as rmSync12, statSync as statSync13, writeFileSync as writeFileSync17 } from "node:fs";
|
|
150279
151020
|
import { dirname as dirname27, join as join37, resolve as resolve39 } from "node:path";
|
|
150280
151021
|
function writeZip(entries) {
|
|
150281
151022
|
const sorted2 = entries.slice().sort((a2, b2) => a2.path < b2.path ? -1 : a2.path > b2.path ? 1 : 0);
|
|
@@ -150370,10 +151111,10 @@ function inflateEntry(buf, entry) {
|
|
|
150370
151111
|
return bytes2;
|
|
150371
151112
|
}
|
|
150372
151113
|
function readIf(path2) {
|
|
150373
|
-
return
|
|
151114
|
+
return existsSync42(path2) && statSync13(path2).isFile() ? readFileSync48(path2) : null;
|
|
150374
151115
|
}
|
|
150375
151116
|
function listDir(dir) {
|
|
150376
|
-
return
|
|
151117
|
+
return existsSync42(dir) ? readdirSync23(dir).filter((f2) => statSync13(join37(dir, f2)).isFile()) : [];
|
|
150377
151118
|
}
|
|
150378
151119
|
function gatherReleaseEntries(appDir3) {
|
|
150379
151120
|
const manifestPath = join37(appDir3, HIMI_PACKAGE_MANIFEST_PATH);
|
|
@@ -150452,7 +151193,7 @@ function packRelease(releaseRoot, app, out2, opts = {}) {
|
|
|
150452
151193
|
const appDir3 = join37(resolve39(releaseRoot), app);
|
|
150453
151194
|
const { all, header, skipped } = buildEntries(appDir3, app, opts);
|
|
150454
151195
|
const buf = writeZip(all);
|
|
150455
|
-
const isDir2 =
|
|
151196
|
+
const isDir2 = existsSync42(out2) && statSync13(out2).isDirectory();
|
|
150456
151197
|
const outFile = isDir2 ? join37(resolve39(out2), packageFileName(app, header.releaseId)) : resolve39(out2);
|
|
150457
151198
|
mkdirSync22(dirname27(outFile), { recursive: true });
|
|
150458
151199
|
writeFileSync17(outFile, buf);
|
|
@@ -150469,11 +151210,11 @@ function resolvePackageDirDest(outDir, app, releaseId) {
|
|
|
150469
151210
|
}
|
|
150470
151211
|
};
|
|
150471
151212
|
const replaceable = (dir) => {
|
|
150472
|
-
if (!
|
|
151213
|
+
if (!existsSync42(dir)) return true;
|
|
150473
151214
|
if (!statSync13(dir).isDirectory()) return false;
|
|
150474
151215
|
return readdirSync23(dir).length === 0 || packagedApp(dir) === app;
|
|
150475
151216
|
};
|
|
150476
|
-
if (
|
|
151217
|
+
if (existsSync42(outDir) && !statSync13(outDir).isDirectory()) {
|
|
150477
151218
|
throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
|
|
150478
151219
|
}
|
|
150479
151220
|
if (replaceable(outDir)) return outDir;
|
|
@@ -150534,7 +151275,7 @@ function openPackageDir(dir) {
|
|
|
150534
151275
|
else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync48(childAbs));
|
|
150535
151276
|
}
|
|
150536
151277
|
};
|
|
150537
|
-
if (!
|
|
151278
|
+
if (!existsSync42(root)) throw new Error(`no such package directory: ${root}`);
|
|
150538
151279
|
walk2("");
|
|
150539
151280
|
const manifestBytes = entries.get(HIMI_PACKAGE_MANIFEST_PATH);
|
|
150540
151281
|
if (manifestBytes) {
|
|
@@ -150619,7 +151360,7 @@ __export(app_source_exports, {
|
|
|
150619
151360
|
zipAppSource: () => zipAppSource
|
|
150620
151361
|
});
|
|
150621
151362
|
import { createHash as createHash25 } from "node:crypto";
|
|
150622
|
-
import { readdirSync as readdirSync24, lstatSync as lstatSync13, readFileSync as readFileSync49, mkdirSync as mkdirSync23, writeFileSync as writeFileSync18, existsSync as
|
|
151363
|
+
import { readdirSync as readdirSync24, lstatSync as lstatSync13, readFileSync as readFileSync49, mkdirSync as mkdirSync23, writeFileSync as writeFileSync18, existsSync as existsSync43, rmSync as rmSync13, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3 } from "node:fs";
|
|
150623
151364
|
import { join as join38, resolve as resolve40, sep as sep13 } from "node:path";
|
|
150624
151365
|
import { createRequire as createRequire3 } from "node:module";
|
|
150625
151366
|
import { deflateRawSync as deflateRawSync2 } from "node:zlib";
|
|
@@ -150635,7 +151376,7 @@ function walkSourceTree(dir, file2, skip, enter = () => {
|
|
|
150635
151376
|
continue;
|
|
150636
151377
|
}
|
|
150637
151378
|
if (st2.isDirectory()) {
|
|
150638
|
-
if (isDeniedSourceDir(name, relDir) ||
|
|
151379
|
+
if (isDeniedSourceDir(name, relDir) || existsSync43(join38(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
|
|
150639
151380
|
else walk2(rel);
|
|
150640
151381
|
continue;
|
|
150641
151382
|
}
|
|
@@ -150803,7 +151544,7 @@ function writeAppSource(entries, destDir) {
|
|
|
150803
151544
|
return written;
|
|
150804
151545
|
}
|
|
150805
151546
|
function staleSourcePaths(entries, destDir) {
|
|
150806
|
-
if (!
|
|
151547
|
+
if (!existsSync43(destDir)) return [];
|
|
150807
151548
|
const archived = new Set(entries.map((e2) => e2.path));
|
|
150808
151549
|
const stale = [];
|
|
150809
151550
|
walkSourceTree(destDir, (archivePath) => {
|
|
@@ -150859,7 +151600,7 @@ function removeStaleSource(entries, destDir) {
|
|
|
150859
151600
|
const segments = entry.path.split("/");
|
|
150860
151601
|
for (let i2 = 1; i2 < segments.length; i2++) needed.add(segments.slice(0, i2).join("/"));
|
|
150861
151602
|
}
|
|
150862
|
-
if (
|
|
151603
|
+
if (existsSync43(root)) pruneEmptyDirs(root, "", needed, removed);
|
|
150863
151604
|
return removed.sort();
|
|
150864
151605
|
}
|
|
150865
151606
|
function pruneEmptyDirs(root, rel, needed, removed) {
|
|
@@ -150948,7 +151689,7 @@ __export(run_watch_exports, {
|
|
|
150948
151689
|
watchedContentDir: () => watchedContentDir,
|
|
150949
151690
|
writeRunRecord: () => writeRunRecord
|
|
150950
151691
|
});
|
|
150951
|
-
import { closeSync as closeSync4, constants as constants3, existsSync as
|
|
151692
|
+
import { closeSync as closeSync4, constants as constants3, existsSync as existsSync44, fstatSync, lstatSync as lstatSync14, statSync as statSync14, readdirSync as readdirSync25, mkdirSync as mkdirSync24, openSync as openSync4, readFileSync as readFileSync50, realpathSync as realpathSync8, renameSync as renameSync10, rmSync as rmSync14, writeFileSync as writeFileSync19, watch as fsWatch } from "node:fs";
|
|
150952
151693
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
150953
151694
|
import { extname as extname4, join as join39, relative as relative8, resolve as resolve41, sep as sep14 } from "node:path";
|
|
150954
151695
|
function diffReleases(prev, next) {
|
|
@@ -151016,7 +151757,7 @@ function watchContent(dir, onChange, opts = {}) {
|
|
|
151016
151757
|
}, debounceMs);
|
|
151017
151758
|
};
|
|
151018
151759
|
let watcher2, polling;
|
|
151019
|
-
const
|
|
151760
|
+
const snapshot3 = () => {
|
|
151020
151761
|
const files = /* @__PURE__ */ new Map();
|
|
151021
151762
|
const visit = (directory, prefix = "") => {
|
|
151022
151763
|
let entries;
|
|
@@ -151039,12 +151780,12 @@ function watchContent(dir, onChange, opts = {}) {
|
|
|
151039
151780
|
visit(dir);
|
|
151040
151781
|
return files;
|
|
151041
151782
|
};
|
|
151042
|
-
let before =
|
|
151783
|
+
let before = snapshot3();
|
|
151043
151784
|
const fallback = () => {
|
|
151044
151785
|
if (polling) return;
|
|
151045
151786
|
watcher2?.close();
|
|
151046
151787
|
polling = setInterval(() => {
|
|
151047
|
-
const after =
|
|
151788
|
+
const after = snapshot3();
|
|
151048
151789
|
for (const path2 of /* @__PURE__ */ new Set([...before.keys(), ...after.keys()])) if (before.get(path2) !== after.get(path2)) changed("change", path2);
|
|
151049
151790
|
before = after;
|
|
151050
151791
|
}, opts.pollMs ?? 500);
|
|
@@ -151067,7 +151808,7 @@ function watchedContentDir(source) {
|
|
|
151067
151808
|
if (!source || /^https?:\/\//i.test(source)) return null;
|
|
151068
151809
|
const dir = resolve41(source);
|
|
151069
151810
|
try {
|
|
151070
|
-
return statSync14(dir).isDirectory() &&
|
|
151811
|
+
return statSync14(dir).isDirectory() && existsSync44(join39(dir, "himalaya.content.json")) ? dir : null;
|
|
151071
151812
|
} catch {
|
|
151072
151813
|
return null;
|
|
151073
151814
|
}
|
|
@@ -151723,7 +152464,7 @@ __export(milestones_exports, {
|
|
|
151723
152464
|
});
|
|
151724
152465
|
import { createHash as createHash28, randomUUID as randomUUID8 } from "node:crypto";
|
|
151725
152466
|
import { spawn as spawn4 } from "node:child_process";
|
|
151726
|
-
import { closeSync as closeSync5, existsSync as
|
|
152467
|
+
import { closeSync as closeSync5, existsSync as existsSync45, lstatSync as lstatSync17, readFileSync as readFileSync54, statSync as statSync15 } from "node:fs";
|
|
151727
152468
|
import { createServer as createServer3 } from "node:net";
|
|
151728
152469
|
import { basename as basename14, dirname as dirname28, isAbsolute as isAbsolute4, join as join43, relative as relative9, resolve as resolve42, sep as sep15 } from "node:path";
|
|
151729
152470
|
function homeShotPath(dir, home) {
|
|
@@ -151836,7 +152577,7 @@ function autoPictureGate(dir) {
|
|
|
151836
152577
|
}
|
|
151837
152578
|
async function homePictureAtValidate(dir, opts) {
|
|
151838
152579
|
if (!opts.ok) return { skipped: "validate found errors, so the picture was left as it is" };
|
|
151839
|
-
if (!
|
|
152580
|
+
if (!existsSync45(join43(dir, "himalaya.content.json"))) return { skipped: "not a content package" };
|
|
151840
152581
|
const env = opts.env ?? process.env;
|
|
151841
152582
|
if (ciSet(env)) return { skipped: "the CI environment variable is set" };
|
|
151842
152583
|
if (env.NODE_TEST_CONTEXT) return { skipped: "running under `node --test`" };
|
|
@@ -151906,7 +152647,7 @@ function stillBuilding(dir, image, now) {
|
|
|
151906
152647
|
}
|
|
151907
152648
|
}
|
|
151908
152649
|
function firstLookBeforeOwnPostcard(dir, image, now) {
|
|
151909
|
-
if (!image || !
|
|
152650
|
+
if (!image || !existsSync45(image) || initDivergence(dir).state !== "diverged") return void 0;
|
|
151910
152651
|
return journal(dir, "first-look", withHomeCaveat(yourFirstLookMessage(dir), homeCaveat(dir, image)), { image, ...now ? { now } : {} });
|
|
151911
152652
|
}
|
|
151912
152653
|
function afterRenderPng(dir, input) {
|
|
@@ -151971,13 +152712,13 @@ function testChangeNote(headline2, change) {
|
|
|
151971
152712
|
}
|
|
151972
152713
|
function afterTestRun(dir, input) {
|
|
151973
152714
|
const firstLook = firstLookBeforeOwnPostcard(dir, input.homeShot, input.now);
|
|
151974
|
-
const shot = input.homeShot &&
|
|
152715
|
+
const shot = input.homeShot && existsSync45(input.homeShot) ? input.homeShot : void 0;
|
|
151975
152716
|
const caveat = shot ? homeCaveat(dir, shot) : void 0;
|
|
151976
152717
|
const counts = testPostcardMessage(input);
|
|
151977
152718
|
const headline2 = caveat ? `${counts} But ${caveat}.` : counts;
|
|
151978
152719
|
const postcard = journal(dir, "test", headline2, {
|
|
151979
152720
|
ref: input.runId,
|
|
151980
|
-
...input.homeShot &&
|
|
152721
|
+
...input.homeShot && existsSync45(input.homeShot) ? { image: input.homeShot } : {},
|
|
151981
152722
|
...input.now ? { now: input.now } : {},
|
|
151982
152723
|
unlessUnchanged: true,
|
|
151983
152724
|
changeNote: (change) => testChangeNote(headline2, change)
|
|
@@ -152020,7 +152761,7 @@ function draftPictureGap(input) {
|
|
|
152020
152761
|
if (!input.home) return { reason: "the app's dev/index.ts names no literal homeScreenId, so there is no home screen to picture" };
|
|
152021
152762
|
if (!input.homeShot) return { reason: "the homeScreenId does not name a file under .himi/shots" };
|
|
152022
152763
|
const render = `himi render ${shellQuote(input.home)} --png${contentArg(input.content)}`;
|
|
152023
|
-
if (!
|
|
152764
|
+
if (!existsSync45(input.homeShot)) return { reason: "there is no home shot yet", render };
|
|
152024
152765
|
if (input.sourceChangedAtMs === void 0) return { reason: "the source's last change could not be read, so the home shot cannot be shown to be current", render };
|
|
152025
152766
|
if (!shotIsCurrent(input.homeShot, input.sourceChangedAtMs)) return { reason: "the home shot is older than the last source edit, so it is not a picture of this draft", render };
|
|
152026
152767
|
return null;
|
|
@@ -152098,7 +152839,7 @@ function draftChangeNote(dir, input) {
|
|
|
152098
152839
|
if (!previous) return void 0;
|
|
152099
152840
|
const shaOf = (i2) => i2 && typeof i2 === "object" && typeof i2.sha256 === "string" ? i2.sha256 : void 0;
|
|
152100
152841
|
const had = Array.isArray(previous.images) ? previous.images.map(shaOf).find(Boolean) : void 0;
|
|
152101
|
-
const has = input.picture &&
|
|
152842
|
+
const has = input.picture && existsSync45(input.picture) ? sha256Of2(input.picture) : void 0;
|
|
152102
152843
|
if (had && has) parts.push(had === has ? "the home screen looks the same" : "the home screen changed");
|
|
152103
152844
|
else if (has) parts.push("a home picture this time");
|
|
152104
152845
|
else return void 0;
|
|
@@ -152164,7 +152905,7 @@ function homeShotForPostcard(dir, opts = {}) {
|
|
|
152164
152905
|
const shot = homeShotPath(dir, home);
|
|
152165
152906
|
if (!shot) return { skipped: "the homeScreenId does not name a file under .himi/shots" };
|
|
152166
152907
|
const render = `\`himi render ${shellQuote(home)} --png\``;
|
|
152167
|
-
if (!
|
|
152908
|
+
if (!existsSync45(shot)) return { skipped: `no home shot yet \u2014 ${render} makes one, and the next postcard carries it` };
|
|
152168
152909
|
let changed;
|
|
152169
152910
|
try {
|
|
152170
152911
|
changed = newestSourceChangeMs(dir);
|
|
@@ -152244,7 +152985,7 @@ function liveWatchRunning(dir, isAlive = pidAlive, now) {
|
|
|
152244
152985
|
}
|
|
152245
152986
|
function watchReminder(dir, opts = {}) {
|
|
152246
152987
|
try {
|
|
152247
|
-
if (!
|
|
152988
|
+
if (!existsSync45(join43(dir, "himalaya.content.json"))) return void 0;
|
|
152248
152989
|
const nowDate = opts.now ?? /* @__PURE__ */ new Date();
|
|
152249
152990
|
const live3 = liveWatch(dir, opts.isAlive, nowDate);
|
|
152250
152991
|
const now = nowDate.getTime();
|
|
@@ -152919,12 +153660,12 @@ var init_brand_color_math = __esm({
|
|
|
152919
153660
|
});
|
|
152920
153661
|
|
|
152921
153662
|
// src/token-lint.ts
|
|
152922
|
-
import { existsSync as
|
|
153663
|
+
import { existsSync as existsSync48, readFileSync as readFileSync56 } from "node:fs";
|
|
152923
153664
|
import { join as join46 } from "node:path";
|
|
152924
153665
|
function configuredTokensPath(dir) {
|
|
152925
153666
|
for (const name of ["config.ts", "config.js", "himi.config.ts"]) {
|
|
152926
153667
|
const f2 = join46(dir, name);
|
|
152927
|
-
if (!
|
|
153668
|
+
if (!existsSync48(f2)) continue;
|
|
152928
153669
|
const src = readFileSync56(f2, "utf8");
|
|
152929
153670
|
const m2 = /designTokensPath\s*:\s*["'`]([^"'`]+)["'`]/.exec(src);
|
|
152930
153671
|
if (m2) return { path: m2[1].replace(/^\.\//, "") };
|
|
@@ -153002,7 +153743,7 @@ function tokenColorIssues(dir, tokensPathOverride) {
|
|
|
153002
153743
|
}
|
|
153003
153744
|
const tokensPath = configured.path ?? "tokens.json";
|
|
153004
153745
|
const p2 = join46(dir, tokensPath);
|
|
153005
|
-
if (!
|
|
153746
|
+
if (!existsSync48(p2)) {
|
|
153006
153747
|
if (tokensPath !== "tokens.json") {
|
|
153007
153748
|
warn3(`config designTokensPath points at ${tokensPath}, which does not exist -- colour tokens were not checked`);
|
|
153008
153749
|
}
|
|
@@ -153324,7 +154065,7 @@ __export(fonts_exports, {
|
|
|
153324
154065
|
listReport: () => listReport,
|
|
153325
154066
|
resolveFamilyName: () => resolveFamilyName
|
|
153326
154067
|
});
|
|
153327
|
-
import { existsSync as
|
|
154068
|
+
import { existsSync as existsSync49, readFileSync as readFileSync57 } from "node:fs";
|
|
153328
154069
|
import { join as join47 } from "node:path";
|
|
153329
154070
|
function readJson6(path2, fallback) {
|
|
153330
154071
|
try {
|
|
@@ -153358,7 +154099,7 @@ function listReport(opts = {}) {
|
|
|
153358
154099
|
}
|
|
153359
154100
|
async function fontFindings(appDir3, opts = {}) {
|
|
153360
154101
|
const tokensPath = join47(appDir3, configuredTokensPath(appDir3).path ?? "tokens.json");
|
|
153361
|
-
if (!
|
|
154102
|
+
if (!existsSync49(tokensPath)) return null;
|
|
153362
154103
|
const catalog4 = loadCatalog2();
|
|
153363
154104
|
const tokens2 = readJson6(tokensPath, {});
|
|
153364
154105
|
const policy = readJson6(join47(appDir3, "fonts.json"), {});
|
|
@@ -153866,17 +154607,17 @@ __export(template_recommend_exports, {
|
|
|
153866
154607
|
recommendTemplates: () => recommendTemplates,
|
|
153867
154608
|
verticalsFromBook: () => verticalsFromBook
|
|
153868
154609
|
});
|
|
153869
|
-
import { existsSync as
|
|
154610
|
+
import { existsSync as existsSync51, readFileSync as readFileSync60 } from "node:fs";
|
|
153870
154611
|
import { join as join50 } from "node:path";
|
|
153871
154612
|
function verticalsFromBook(path2) {
|
|
153872
|
-
const dir =
|
|
154613
|
+
const dir = existsSync51(join50(path2, "book.json")) || existsSync51(join50(path2, "provisioning.overlay.json")) ? path2 : join50(path2, ".himi", "business-book");
|
|
153873
154614
|
const overlay = join50(dir, "provisioning.overlay.json");
|
|
153874
|
-
if (
|
|
154615
|
+
if (existsSync51(overlay)) {
|
|
153875
154616
|
const v2 = JSON.parse(readFileSync60(overlay, "utf8")).installedVerticals;
|
|
153876
154617
|
if (Array.isArray(v2) && v2.length) return v2.filter((x2) => typeof x2 === "string");
|
|
153877
154618
|
}
|
|
153878
154619
|
const book = join50(dir, "book.json");
|
|
153879
|
-
if (
|
|
154620
|
+
if (existsSync51(book)) {
|
|
153880
154621
|
const probes = JSON.parse(readFileSync60(book, "utf8")).probes;
|
|
153881
154622
|
if (Array.isArray(probes)) return installedFromProbes(probes);
|
|
153882
154623
|
}
|
|
@@ -154491,7 +155232,7 @@ var init_glyphs = __esm({
|
|
|
154491
155232
|
});
|
|
154492
155233
|
|
|
154493
155234
|
// ../app-icons/plan.ts
|
|
154494
|
-
import { existsSync as
|
|
155235
|
+
import { existsSync as existsSync52, readFileSync as readFileSync61, readdirSync as readdirSync27 } from "node:fs";
|
|
154495
155236
|
import { createHash as createHash29 } from "node:crypto";
|
|
154496
155237
|
import { dirname as dirname29, join as join51, resolve as resolve44 } from "node:path";
|
|
154497
155238
|
function stripComments(src) {
|
|
@@ -154627,7 +155368,7 @@ function resolveTokensPath(app, configTs) {
|
|
|
154627
155368
|
}
|
|
154628
155369
|
function resolveToken(app, token, tokensPathOverride) {
|
|
154629
155370
|
const tokensPath = tokensPathOverride ?? join51(appDir(app), "tokens.json");
|
|
154630
|
-
if (!
|
|
155371
|
+
if (!existsSync52(tokensPath)) {
|
|
154631
155372
|
throw new Error(`app-icons: ${app} has no tokens.json at ${tokensPath} (needed to resolve "${token}").`);
|
|
154632
155373
|
}
|
|
154633
155374
|
const tokens2 = JSON.parse(readFileSync61(tokensPath, "utf8"));
|
|
@@ -154672,7 +155413,7 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
|
|
|
154672
155413
|
const tokens2 = tokensPathOverride ?? resolveTokensPath(app, configTs).path;
|
|
154673
155414
|
if (cfg.source) {
|
|
154674
155415
|
const abs = resolve44(appDir(app), cfg.source);
|
|
154675
|
-
if (!
|
|
155416
|
+
if (!existsSync52(abs)) {
|
|
154676
155417
|
throw new Error(`app-icons: ${app} declares icon.source "${cfg.source}" but ${abs} does not exist.`);
|
|
154677
155418
|
}
|
|
154678
155419
|
return {
|
|
@@ -154712,9 +155453,9 @@ function iosAssetCatalog2(app) {
|
|
|
154712
155453
|
return assetCatalogIn(join51(appDir(app), "ios"));
|
|
154713
155454
|
}
|
|
154714
155455
|
function assetCatalogIn(platformDir) {
|
|
154715
|
-
if (!
|
|
155456
|
+
if (!existsSync52(platformDir)) return void 0;
|
|
154716
155457
|
const children = readdirSync27(platformDir).filter((c2) => !c2.startsWith("build")).sort();
|
|
154717
|
-
const catalogs = children.map((c2) => join51(platformDir, c2, "Assets.xcassets")).filter(
|
|
155458
|
+
const catalogs = children.map((c2) => join51(platformDir, c2, "Assets.xcassets")).filter(existsSync52);
|
|
154718
155459
|
if (catalogs.length === 1) return catalogs[0];
|
|
154719
155460
|
if (catalogs.length > 1) return void 0;
|
|
154720
155461
|
const targets = [];
|
|
@@ -154737,14 +155478,14 @@ function androidResDir2(manifestPath) {
|
|
|
154737
155478
|
}
|
|
154738
155479
|
function androidManifestPath(app) {
|
|
154739
155480
|
const androidDir = join51(appDir(app), "android");
|
|
154740
|
-
if (!
|
|
155481
|
+
if (!existsSync52(androidDir)) return void 0;
|
|
154741
155482
|
const preferred = join51(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
154742
|
-
if (
|
|
154743
|
-
const candidates = readdirSync27(androidDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && d2.name.endsWith("-app")).map((d2) => join51(androidDir, d2.name, "src", "main", "AndroidManifest.xml")).filter(
|
|
155483
|
+
if (existsSync52(preferred)) return preferred;
|
|
155484
|
+
const candidates = readdirSync27(androidDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && d2.name.endsWith("-app")).map((d2) => join51(androidDir, d2.name, "src", "main", "AndroidManifest.xml")).filter(existsSync52);
|
|
154744
155485
|
return candidates.length === 1 ? candidates[0] : void 0;
|
|
154745
155486
|
}
|
|
154746
155487
|
function androidOptedIn2(manifestPath) {
|
|
154747
|
-
if (!manifestPath || !
|
|
155488
|
+
if (!manifestPath || !existsSync52(manifestPath)) return false;
|
|
154748
155489
|
return readFileSync61(manifestPath, "utf8").includes("@mipmap/ic_launcher");
|
|
154749
155490
|
}
|
|
154750
155491
|
function templateIconSha256() {
|
|
@@ -154769,7 +155510,7 @@ function generationAllowed(app, configTs, opts = {}) {
|
|
|
154769
155510
|
}
|
|
154770
155511
|
const iosCat = iosAssetCatalog2(app);
|
|
154771
155512
|
const iosIcon = iosCat ? join51(iosCat, "AppIcon.appiconset", "icon_1024.png") : void 0;
|
|
154772
|
-
if (!iosIcon || !
|
|
155513
|
+
if (!iosIcon || !existsSync52(iosIcon)) return { allowed: true, reason: "no icon yet" };
|
|
154773
155514
|
const hash2 = fileSha256(iosIcon);
|
|
154774
155515
|
const placeholders = opts.placeholderHashes ?? placeholderHashes();
|
|
154775
155516
|
if (app === "_template") return { allowed: true, reason: "the template itself" };
|
|
@@ -154793,7 +155534,7 @@ var init_plan2 = __esm({
|
|
|
154793
155534
|
});
|
|
154794
155535
|
|
|
154795
155536
|
// ../native-config/icon.ts
|
|
154796
|
-
import { existsSync as
|
|
155537
|
+
import { existsSync as existsSync53, readFileSync as readFileSync62 } from "node:fs";
|
|
154797
155538
|
import { join as join52 } from "node:path";
|
|
154798
155539
|
function androidAdaptiveIconXml() {
|
|
154799
155540
|
return [
|
|
@@ -154822,7 +155563,7 @@ function androidIconArtifacts(app, configTs) {
|
|
|
154822
155563
|
if (!generationAllowed(app, configTs).allowed) return [];
|
|
154823
155564
|
const res = androidResDir2(manifest2);
|
|
154824
155565
|
const foreground = join52(res, "mipmap-mdpi", "ic_launcher_foreground.png");
|
|
154825
|
-
if (!
|
|
155566
|
+
if (!existsSync53(foreground)) {
|
|
154826
155567
|
throw new Error(
|
|
154827
155568
|
`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.`
|
|
154828
155569
|
);
|
|
@@ -155124,7 +155865,7 @@ var init_localweb = __esm({
|
|
|
155124
155865
|
});
|
|
155125
155866
|
|
|
155126
155867
|
// ../native-config/capability-registrations.ts
|
|
155127
|
-
import { existsSync as
|
|
155868
|
+
import { existsSync as existsSync54, readdirSync as readdirSync28, readFileSync as readFileSync63, statSync as statSync16 } from "node:fs";
|
|
155128
155869
|
import { dirname as dirname30, join as join53, resolve as resolve45 } from "node:path";
|
|
155129
155870
|
import { fileURLToPath as fileURLToPath22 } from "node:url";
|
|
155130
155871
|
function registrarClasses(path2, re2) {
|
|
@@ -155168,7 +155909,7 @@ function renderKotlinRegistrations(ids, appIdExpr = "APP_NAME", classes = androi
|
|
|
155168
155909
|
];
|
|
155169
155910
|
}
|
|
155170
155911
|
function filesWithRegisterMarkers(root, ext) {
|
|
155171
|
-
if (!
|
|
155912
|
+
if (!existsSync54(root)) return [];
|
|
155172
155913
|
const out2 = [];
|
|
155173
155914
|
const stack = [[root, 0, ext === ".kt" ? "project" : "main"]];
|
|
155174
155915
|
while (stack.length) {
|
|
@@ -155360,7 +156101,7 @@ __export(gen_native_config_exports, {
|
|
|
155360
156101
|
xmlAttr: () => xmlAttr,
|
|
155361
156102
|
yamlScalar: () => yamlScalar
|
|
155362
156103
|
});
|
|
155363
|
-
import { existsSync as
|
|
156104
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync25, readFileSync as readFileSync64, readdirSync as readdirSync29, rmSync as rmSync15, statSync as statSync17, writeFileSync as writeFileSync21 } from "node:fs";
|
|
155364
156105
|
import { dirname as dirname31, join as join54 } from "node:path";
|
|
155365
156106
|
import { fileURLToPath as fileURLToPath23 } from "node:url";
|
|
155366
156107
|
function parseStringArray(configTs, field) {
|
|
@@ -155438,7 +156179,7 @@ function buildSet(capabilities, envelope = []) {
|
|
|
155438
156179
|
}
|
|
155439
156180
|
function loadOverrides(app) {
|
|
155440
156181
|
const p2 = join54(appDir(app), "native-config.overrides.json");
|
|
155441
|
-
if (!
|
|
156182
|
+
if (!existsSync55(p2)) return {};
|
|
155442
156183
|
return JSON.parse(readFileSync64(p2, "utf8"));
|
|
155443
156184
|
}
|
|
155444
156185
|
function needsQuote(s2) {
|
|
@@ -155665,7 +156406,7 @@ function genCoreModuleInstallers(check) {
|
|
|
155665
156406
|
}
|
|
155666
156407
|
function swiftFilesWithModuleMarkers(app) {
|
|
155667
156408
|
const root = join54(appDir(app), "ios");
|
|
155668
|
-
if (!
|
|
156409
|
+
if (!existsSync55(root)) return [];
|
|
155669
156410
|
const out2 = [];
|
|
155670
156411
|
const stack = [root];
|
|
155671
156412
|
while (stack.length) {
|
|
@@ -155687,7 +156428,7 @@ function kotlinFilesWithModuleInstall(app) {
|
|
|
155687
156428
|
return kotlinBootSourcesUnder(join54(appDir(app), "android"));
|
|
155688
156429
|
}
|
|
155689
156430
|
function kotlinBootSourcesUnder(root) {
|
|
155690
|
-
if (!
|
|
156431
|
+
if (!existsSync55(root)) return [];
|
|
155691
156432
|
const out2 = [];
|
|
155692
156433
|
const stack = [[root, 0, "project"]];
|
|
155693
156434
|
while (stack.length) {
|
|
@@ -155758,7 +156499,7 @@ function endText(kind, label3, indent) {
|
|
|
155758
156499
|
}
|
|
155759
156500
|
function hostAppliesDeferredWidgetActions(app) {
|
|
155760
156501
|
const root = join54(appDir(app), "ios");
|
|
155761
|
-
if (!
|
|
156502
|
+
if (!existsSync55(root)) return false;
|
|
155762
156503
|
const stack = [root];
|
|
155763
156504
|
while (stack.length) {
|
|
155764
156505
|
const dir = stack.pop();
|
|
@@ -155816,15 +156557,15 @@ function androidAppGradle(app) {
|
|
|
155816
156557
|
function androidManifestPath2(app) {
|
|
155817
156558
|
const androidDir = join54(appDir(app), "android");
|
|
155818
156559
|
const preferred = join54(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
|
|
155819
|
-
if (
|
|
155820
|
-
const candidates =
|
|
156560
|
+
if (existsSync55(preferred)) return preferred;
|
|
156561
|
+
const candidates = existsSync55(androidDir) ? readdirSync29(androidDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && d2.name.endsWith("-app")).map((d2) => join54(androidDir, d2.name, "src", "main", "AndroidManifest.xml")).filter(existsSync55) : [];
|
|
155821
156562
|
return candidates.length === 1 ? candidates[0] : preferred;
|
|
155822
156563
|
}
|
|
155823
156564
|
function automotiveAppDescPath(app) {
|
|
155824
156565
|
return join54(dirname31(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
|
|
155825
156566
|
}
|
|
155826
156567
|
function applyToFile(path2, kind, label3, render, check) {
|
|
155827
|
-
if (!
|
|
156568
|
+
if (!existsSync55(path2)) return { path: path2, outcome: "skipped" };
|
|
155828
156569
|
const before = readFileSync64(path2, "utf8");
|
|
155829
156570
|
assertSingleMarkerPair(before, kind, label3, path2);
|
|
155830
156571
|
if (!hasMarkers(before, kind, label3)) return { path: path2, outcome: "skipped" };
|
|
@@ -155836,7 +156577,7 @@ function applyToFile(path2, kind, label3, render, check) {
|
|
|
155836
156577
|
}
|
|
155837
156578
|
function assertModuleFlagsMarkers(paths2) {
|
|
155838
156579
|
for (const path2 of paths2) {
|
|
155839
|
-
if (!
|
|
156580
|
+
if (!existsSync55(path2)) continue;
|
|
155840
156581
|
const text11 = readFileSync64(path2, "utf8");
|
|
155841
156582
|
if (hasMarkers(text11, "yaml", LABEL_MODULES_IOS_LINK) && !hasMarkers(text11, "yaml", LABEL_MODULES_IOS_FLAGS)) {
|
|
155842
156583
|
throw new Error(`${path2} links modules (${LABEL_MODULES_IOS_LINK}) but has no ${LABEL_MODULES_IOS_FLAGS} block under its project-level settings:, so no module would install. Add the markers (see apps/_template).`);
|
|
@@ -155848,7 +156589,7 @@ function applyModuleFlags(path2, products, check) {
|
|
|
155848
156589
|
return applyToFile(path2, "yaml", LABEL_MODULES_IOS_FLAGS, (i2) => renderModulesIosFlags(products, i2), check);
|
|
155849
156590
|
}
|
|
155850
156591
|
function applyWholeFile(path2, content, check) {
|
|
155851
|
-
const current =
|
|
156592
|
+
const current = existsSync55(path2) ? readFileSync64(path2, "utf8") : null;
|
|
155852
156593
|
if (current === content) return { path: path2, outcome: "unchanged" };
|
|
155853
156594
|
if (check) return { path: path2, outcome: "drift" };
|
|
155854
156595
|
mkdirSync25(dirname31(path2), { recursive: true });
|
|
@@ -155856,7 +156597,7 @@ function applyWholeFile(path2, content, check) {
|
|
|
155856
156597
|
return { path: path2, outcome: "written" };
|
|
155857
156598
|
}
|
|
155858
156599
|
function removeWholeFile(path2, check) {
|
|
155859
|
-
if (!
|
|
156600
|
+
if (!existsSync55(path2)) return { path: path2, outcome: "skipped" };
|
|
155860
156601
|
if (check) return { path: path2, outcome: "drift" };
|
|
155861
156602
|
rmSync15(path2);
|
|
155862
156603
|
return { path: path2, outcome: "removed" };
|
|
@@ -155895,7 +156636,7 @@ function genCapabilityRegistrations(root, declared, check) {
|
|
|
155895
156636
|
}
|
|
155896
156637
|
function buildSetOfAppDir(root) {
|
|
155897
156638
|
const configPath = join54(root, "config.ts");
|
|
155898
|
-
const configTs =
|
|
156639
|
+
const configTs = existsSync55(configPath) ? readFileSync64(configPath, "utf8") : "";
|
|
155899
156640
|
return buildSet(parseStringArray(configTs, "capabilities"), parseStringArray(configTs, "capabilityEnvelope"));
|
|
155900
156641
|
}
|
|
155901
156642
|
function genNativeConfig(app, opts = {}) {
|
|
@@ -155904,7 +156645,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
155904
156645
|
assertSingleModuleInstall(app, kotlinFilesWithModuleInstall(app));
|
|
155905
156646
|
assertModuleFlagsMarkers([iosProjectYml(app), macosProjectYml(app)]);
|
|
155906
156647
|
const configPath = appConfigTs(app);
|
|
155907
|
-
const configTs =
|
|
156648
|
+
const configTs = existsSync55(configPath) ? readFileSync64(configPath, "utf8") : "";
|
|
155908
156649
|
const capabilities = parseStringArray(configTs, "capabilities");
|
|
155909
156650
|
const envelope = parseStringArray(configTs, "capabilityEnvelope");
|
|
155910
156651
|
const ownIds = buildSet(capabilities, envelope);
|
|
@@ -155913,7 +156654,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
155913
156654
|
const ids = dist ? dist.build : ownIds;
|
|
155914
156655
|
const healthLinked = ids.includes("health");
|
|
155915
156656
|
const distJsonPath = join54(appDir(app), "distribution.json");
|
|
155916
|
-
const distJsonText =
|
|
156657
|
+
const distJsonText = existsSync55(distJsonPath) ? readFileSync64(distJsonPath, "utf8") : void 0;
|
|
155917
156658
|
const optIns = distributionOptIns(distJsonText);
|
|
155918
156659
|
const binaryCore = isBinaryCore(configTs, distJsonText);
|
|
155919
156660
|
const modules = modulesFor(ids, optIns);
|
|
@@ -155929,7 +156670,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
155929
156670
|
if (!v2) throw new Error(`${app}: a binary-core app that links native modules (${modules.gradle.join(", ")}) needs distribution.json coreVersion`);
|
|
155930
156671
|
return v2;
|
|
155931
156672
|
},
|
|
155932
|
-
corePackage: () =>
|
|
156673
|
+
corePackage: () => existsSync55(iosProjectYml(app)) ? binaryCorePackage(readFileSync64(iosProjectYml(app), "utf8")) : void 0
|
|
155933
156674
|
} : void 0
|
|
155934
156675
|
);
|
|
155935
156676
|
if (binaryCore) {
|
|
@@ -155948,9 +156689,9 @@ function genNativeConfig(app, opts = {}) {
|
|
|
155948
156689
|
const iosBundleId = watchConfig.iosBundleId ?? parseIosBundleId(configTs);
|
|
155949
156690
|
const watch2 = watchInfoPlan(watchConfig, iosBundleId);
|
|
155950
156691
|
const watchYml = watchosProjectYml(app);
|
|
155951
|
-
const watchYmlText =
|
|
156692
|
+
const watchYmlText = existsSync55(watchYml) ? readFileSync64(watchYml, "utf8") : "";
|
|
155952
156693
|
const watchSettings = watchSettingsPlan(watchMode(watchConfig.mode), iosBundleId, watchTargetBundleId(watchYmlText));
|
|
155953
|
-
const watchName =
|
|
156694
|
+
const watchName = existsSync55(watchYml) ? watchProjectName(readFileSync64(watchYml, "utf8")) : void 0;
|
|
155954
156695
|
const watchEmbedFor = (lines) => (indent) => {
|
|
155955
156696
|
const mode = watchMode(watchConfig.mode);
|
|
155956
156697
|
if (mode === "standalone") return [];
|
|
@@ -155964,7 +156705,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
155964
156705
|
const carBlock = applyToFile(carManifestPath, "xml", LABEL_CAR, (i2) => renderCarManifestXml(carCategory, i2), check);
|
|
155965
156706
|
assertCarBlockLanded(app, carCategory, carManifestPath, carBlock.outcome, LABEL_CAR);
|
|
155966
156707
|
const iosYml = iosProjectYml(app);
|
|
155967
|
-
const project =
|
|
156708
|
+
const project = existsSync55(iosYml) ? readFileSync64(iosYml, "utf8") : "";
|
|
155968
156709
|
const targetManaged = hasMarkers(project, "yaml", LABEL_LIVE_TARGET);
|
|
155969
156710
|
const embedManaged = hasMarkers(project, "yaml", LABEL_LIVE_EMBED);
|
|
155970
156711
|
if (targetManaged !== embedManaged) throw new Error(`${app}: Live Activity target and embedding markers must be installed together`);
|
|
@@ -156048,7 +156789,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
156048
156789
|
];
|
|
156049
156790
|
if (dist) {
|
|
156050
156791
|
const manifestPath = androidManifestPath2(app);
|
|
156051
|
-
const marked = (path2, kind, label3) => !
|
|
156792
|
+
const marked = (path2, kind, label3) => !existsSync55(path2) || hasMarkers(readFileSync64(path2, "utf8"), kind, label3);
|
|
156052
156793
|
if (!marked(iosYml, "yaml", LABEL_IOS_INFO)) throw new Error(`${app}: dist capabilities need the ${LABEL_IOS_INFO} markers in ${iosYml}`);
|
|
156053
156794
|
if (!marked(manifestPath, "xml", LABEL_ANDROID_SERVICES)) {
|
|
156054
156795
|
throw new Error(`${app}: dist capabilities need the ${LABEL_ANDROID_SERVICES} markers inside <application> in ${manifestPath}`);
|
|
@@ -156059,7 +156800,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
156059
156800
|
const addsGradle = added.gradle.some((p2) => !ownModules.gradle.includes(p2));
|
|
156060
156801
|
if (addsSpm || addsGradle) {
|
|
156061
156802
|
const requireMarkers = (path2, kind, label3) => {
|
|
156062
|
-
if (!
|
|
156803
|
+
if (!existsSync55(path2) || !hasMarkers(readFileSync64(path2, "utf8"), kind, label3)) {
|
|
156063
156804
|
throw new Error(`${app}: dist added ${dist.added.join(", ")} but ${path2} has no ${label3} markers \u2014 the module would stay unlinked and every verb would answer module_not_linked`);
|
|
156064
156805
|
}
|
|
156065
156806
|
};
|
|
@@ -156084,9 +156825,9 @@ function genNativeConfig(app, opts = {}) {
|
|
|
156084
156825
|
files.push(...genCapabilityRegistrations(appDir(app), ids, check));
|
|
156085
156826
|
const rce = declaresRichContentEditor(configTs);
|
|
156086
156827
|
for (const yml of [iosYml, macosProjectYml(app)]) {
|
|
156087
|
-
const text11 =
|
|
156828
|
+
const text11 = existsSync55(yml) ? readFileSync64(yml, "utf8") : "";
|
|
156088
156829
|
const r3 = applyToFile(yml, "yaml", LABEL_LOCALWEB, renderLocalWebYaml(resourcesDirOf(text11), rce), check);
|
|
156089
|
-
if (
|
|
156830
|
+
if (existsSync55(yml)) assertLocalWebBlockLanded(app, rce, yml, r3.outcome);
|
|
156090
156831
|
files.push(r3);
|
|
156091
156832
|
}
|
|
156092
156833
|
if (targetManaged) {
|
|
@@ -156098,7 +156839,7 @@ function genNativeConfig(app, opts = {}) {
|
|
|
156098
156839
|
const entitlements = join54(dirname31(iosYml), LIVE_ENTITLEMENTS_PATH);
|
|
156099
156840
|
files.push(plan.entitlements ? applyWholeFile(entitlements, plan.entitlements, check) : removeWholeFile(entitlements, check));
|
|
156100
156841
|
}
|
|
156101
|
-
const iosSplashManaged =
|
|
156842
|
+
const iosSplashManaged = existsSync55(iosYml) && hasMarkers(readFileSync64(iosYml, "utf8"), "yaml", LABEL_IOS_SPLASH);
|
|
156102
156843
|
const manifest2 = androidManifestPath2(app);
|
|
156103
156844
|
const splash = splashPlan(app, configTs, manifest2, iosSplashManaged);
|
|
156104
156845
|
for (const artifact of splash.artifacts) files.push(applyWholeFile(artifact.path, artifact.content, check));
|
|
@@ -156191,7 +156932,7 @@ __export(capabilities_exports, {
|
|
|
156191
156932
|
shellSupport: () => shellSupport,
|
|
156192
156933
|
writeLastDist: () => writeLastDist
|
|
156193
156934
|
});
|
|
156194
|
-
import { existsSync as
|
|
156935
|
+
import { existsSync as existsSync56, lstatSync as lstatSync18, readFileSync as readFileSync65 } from "node:fs";
|
|
156195
156936
|
import { join as join55 } from "node:path";
|
|
156196
156937
|
function declareHintFor(id) {
|
|
156197
156938
|
return catalogKey(id) === "app_services" ? "each calling screen's `logicBundle.declaredCapabilities` (the runtime gate) \u2014 an app need not list app_services in config.ts `capabilities`, which only a shell that hosts app services must (an HHP app declares it there, since HHP copies that list onto every screen)" : DECLARE_HINT;
|
|
@@ -156273,7 +157014,7 @@ function allCapabilities(sdkRef = []) {
|
|
|
156273
157014
|
function contentShell(dir, flag) {
|
|
156274
157015
|
if (flag) return flag;
|
|
156275
157016
|
const path2 = join55(dir, "himalaya.content.json");
|
|
156276
|
-
if (!
|
|
157017
|
+
if (!existsSync56(path2)) return null;
|
|
156277
157018
|
try {
|
|
156278
157019
|
const shell = JSON.parse(readFileSync65(path2, "utf8")).shell;
|
|
156279
157020
|
return typeof shell === "string" && shell ? shell : null;
|
|
@@ -156571,7 +157312,7 @@ function envelopeSubsetIssues(app, envelope) {
|
|
|
156571
157312
|
function capabilityConfigFindings(sourceDir, builtDir) {
|
|
156572
157313
|
const out2 = [];
|
|
156573
157314
|
const configPath = join55(sourceDir, "config.ts");
|
|
156574
|
-
if (
|
|
157315
|
+
if (existsSync56(configPath)) {
|
|
156575
157316
|
const configSrc = readFileSync65(configPath, "utf8");
|
|
156576
157317
|
const declared = parseStringArray(configSrc, "capabilities");
|
|
156577
157318
|
for (const id of new Set(declared)) {
|
|
@@ -156740,6 +157481,9 @@ async function navIssues(dir, strict) {
|
|
|
156740
157481
|
pushScreenMapIssues(cfg.push, provisioning, warn3);
|
|
156741
157482
|
pushAuthIssues(cfg.push, cfg.auth, provisioning, warn3);
|
|
156742
157483
|
pushFamilyIssues(cfg.push, warn3);
|
|
157484
|
+
const captcha = provisioning.siteId && !placeholderLogin(cfg.auth) ? captchaAuthFinding(cfg.auth, provisioning.siteId) : void 0;
|
|
157485
|
+
if (captcha && captcha.code !== "captcha_auth_site_case" && !issues.some((i2) => i2.ruleCode === "push-auth-site"))
|
|
157486
|
+
push("warning", "auth-captcha-site", captcha.message);
|
|
156743
157487
|
if (nav === void 0 || nav === null) return issues;
|
|
156744
157488
|
if (!isPlainObject2(nav)) {
|
|
156745
157489
|
error("nav-not-an-object", `navigation must be an object (got ${Array.isArray(nav) ? "array" : typeof nav}).`);
|
|
@@ -156877,6 +157621,9 @@ function pushAuthIssues(push, auth, provisioning, warn3) {
|
|
|
156877
157621
|
`push.registrar is "wix-ping", which registers a signed-in member's device with Wix Ping, but ${problem}. Use auth: WixConsumerAuthProvider({ siteId: "${provisioning.siteId ?? "<metaSiteId>"}", \u2026 }).`
|
|
156878
157622
|
);
|
|
156879
157623
|
}
|
|
157624
|
+
function placeholderLogin(auth) {
|
|
157625
|
+
return isPlainObject2(auth) && isPlainObject2(auth.config) && auth.config.clientId === PLACEHOLDER_CLIENT_ID;
|
|
157626
|
+
}
|
|
156880
157627
|
function pushFamilyIssues(push, warn3) {
|
|
156881
157628
|
if (!isPlainObject2(push) || push.registrar !== "wix-ping" || typeof push.pingAppName !== "string") return;
|
|
156882
157629
|
const replacement = replacementPingFamily(push.pingAppName);
|
|
@@ -156939,6 +157686,8 @@ var init_nav_lint = __esm({
|
|
|
156939
157686
|
init_nav_slots();
|
|
156940
157687
|
init_home_screen_id();
|
|
156941
157688
|
init_wix_push_links();
|
|
157689
|
+
init_captcha_auth();
|
|
157690
|
+
init_wix_placeholders();
|
|
156942
157691
|
NAVIGATION_KEYS = /* @__PURE__ */ new Set([
|
|
156943
157692
|
"tabBar",
|
|
156944
157693
|
"drawer",
|
|
@@ -157019,7 +157768,7 @@ __export(base44_types_exports, {
|
|
|
157019
157768
|
renderBase44Types: () => renderBase44Types,
|
|
157020
157769
|
writeBase44Types: () => writeBase44Types
|
|
157021
157770
|
});
|
|
157022
|
-
import { existsSync as
|
|
157771
|
+
import { existsSync as existsSync57, mkdirSync as mkdirSync26, readFileSync as readFileSync66, writeFileSync as writeFileSync22 } from "node:fs";
|
|
157023
157772
|
import { dirname as dirname32, join as join56 } from "node:path";
|
|
157024
157773
|
function logicalName(spec) {
|
|
157025
157774
|
return (isAdoptedEntity(spec) ? spec.base44Name : spec.name) ?? "";
|
|
@@ -157099,7 +157848,7 @@ async function writeBase44Types(dir, app) {
|
|
|
157099
157848
|
if (!list2?.length) throw new Base44TypesError("no_base44_entities", "config.ts declares no base44.entities \u2014 nothing to type. Declare them (or run `himi base44 adopt`) first.");
|
|
157100
157849
|
const text11 = renderBase44Types(list2, app);
|
|
157101
157850
|
const path2 = join56(dir, BASE44_TYPES_PATH);
|
|
157102
|
-
const changed = !
|
|
157851
|
+
const changed = !existsSync57(path2) || readFileSync66(path2, "utf8") !== text11;
|
|
157103
157852
|
if (changed) {
|
|
157104
157853
|
mkdirSync26(dirname32(path2), { recursive: true });
|
|
157105
157854
|
writeFileSync22(path2, text11);
|
|
@@ -157108,7 +157857,7 @@ async function writeBase44Types(dir, app) {
|
|
|
157108
157857
|
}
|
|
157109
157858
|
async function base44TypesIssues(dir, app, strict) {
|
|
157110
157859
|
const path2 = join56(dir, BASE44_TYPES_PATH);
|
|
157111
|
-
if (!
|
|
157860
|
+
if (!existsSync57(path2)) return [];
|
|
157112
157861
|
let list2;
|
|
157113
157862
|
try {
|
|
157114
157863
|
list2 = await declaredEntities(dir);
|
|
@@ -157251,13 +158000,13 @@ __export(eject_exports, {
|
|
|
157251
158000
|
EJECTABLE: () => EJECTABLE,
|
|
157252
158001
|
ejectModule: () => ejectModule
|
|
157253
158002
|
});
|
|
157254
|
-
import { existsSync as
|
|
158003
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync27, readFileSync as readFileSync68, writeFileSync as writeFileSync23 } from "node:fs";
|
|
157255
158004
|
import { dirname as dirname33, join as join58, relative as relative10, resolve as resolve47, sep as sep16 } from "node:path";
|
|
157256
158005
|
function locate(repoRootOrCwd, mod) {
|
|
157257
158006
|
const inRepo = resolve47(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
|
|
157258
|
-
if (
|
|
158007
|
+
if (existsSync59(inRepo)) return { path: inRepo, form: "source" };
|
|
157259
158008
|
const dist = resolve47(repoRootOrCwd, `node_modules/@wix/himalaya/dist/${mod}.mjs`);
|
|
157260
|
-
if (
|
|
158009
|
+
if (existsSync59(dist)) return { path: dist, form: "bundle" };
|
|
157261
158010
|
return null;
|
|
157262
158011
|
}
|
|
157263
158012
|
function specifiersFor(mod) {
|
|
@@ -157302,7 +158051,7 @@ function ejectModule(opts) {
|
|
|
157302
158051
|
writeFileSync23(target, banner + normalized);
|
|
157303
158052
|
const rewired = [];
|
|
157304
158053
|
for (const f2 of files) {
|
|
157305
|
-
if (!
|
|
158054
|
+
if (!existsSync59(f2)) continue;
|
|
157306
158055
|
const before = readFileSync68(f2, "utf8");
|
|
157307
158056
|
let after = before;
|
|
157308
158057
|
let rel = relative10(dirname33(f2), target).split(sep16).join("/").replace(/\.tsx?$/, ".js");
|
|
@@ -157481,7 +158230,7 @@ __export(icon_exports, {
|
|
|
157481
158230
|
summarize: () => summarize3
|
|
157482
158231
|
});
|
|
157483
158232
|
import { createHash as createHash31 } from "node:crypto";
|
|
157484
|
-
import { existsSync as
|
|
158233
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync28, readFileSync as readFileSync69, statSync as statSync18, writeFileSync as writeFileSync24 } from "node:fs";
|
|
157485
158234
|
import { basename as basename16, dirname as dirname34, join as join59, resolve as resolve48, sep as sep17 } from "node:path";
|
|
157486
158235
|
function readManifest(dir) {
|
|
157487
158236
|
try {
|
|
@@ -157520,7 +158269,7 @@ function templateIconMatch(png) {
|
|
|
157520
158269
|
}
|
|
157521
158270
|
function playState(dir) {
|
|
157522
158271
|
const p2 = join59(resolve48(dir), PLAY_LISTING_ICON);
|
|
157523
|
-
if (!
|
|
158272
|
+
if (!existsSync60(p2)) return null;
|
|
157524
158273
|
try {
|
|
157525
158274
|
if (!statSync18(p2).isFile()) return { path: p2, issues: ["is a directory, not a PNG file"] };
|
|
157526
158275
|
return { path: p2, issues: playListingIconIssues(readFileSync69(p2)) };
|
|
@@ -157546,7 +158295,7 @@ async function iconStatus(dir) {
|
|
|
157546
158295
|
verdict: "missing",
|
|
157547
158296
|
policyChecklist: POLICY_CHECKLIST
|
|
157548
158297
|
};
|
|
157549
|
-
if (!path2 || !
|
|
158298
|
+
if (!path2 || !existsSync60(path2)) return base;
|
|
157550
158299
|
let png;
|
|
157551
158300
|
try {
|
|
157552
158301
|
if (!statSync18(path2).isFile()) {
|
|
@@ -157636,7 +158385,7 @@ function backdropFromTokens(dir, fallback = "#1F2933") {
|
|
|
157636
158385
|
}
|
|
157637
158386
|
async function installIcon(dir, sourcePath, opts = {}) {
|
|
157638
158387
|
const src = resolve48(sourcePath);
|
|
157639
|
-
if (!
|
|
158388
|
+
if (!existsSync60(src)) throw new Error(`himi icon: no such file: ${src}`);
|
|
157640
158389
|
const name = declaredIconName(dir) ?? DEFAULT_CONTENT_ICON;
|
|
157641
158390
|
const dest = iconDest(dir, name);
|
|
157642
158391
|
const wrote = [];
|
|
@@ -157690,11 +158439,11 @@ function declareIcon(dir, name) {
|
|
|
157690
158439
|
}
|
|
157691
158440
|
function siteBookIcon(bookDir) {
|
|
157692
158441
|
const p2 = join59(resolve48(bookDir), SITE_BOOK_ICON_REL);
|
|
157693
|
-
return
|
|
158442
|
+
return existsSync60(p2) ? p2 : null;
|
|
157694
158443
|
}
|
|
157695
158444
|
function siteLogoAbsence(bookDir) {
|
|
157696
158445
|
const bookJson = join59(resolve48(bookDir), "book.json");
|
|
157697
|
-
if (!
|
|
158446
|
+
if (!existsSync60(bookJson)) {
|
|
157698
158447
|
return { reason: "no-book", hint: `no business book at ${bookDir} \u2014 run \`himi site analyze --out <dir>\` first, or pass --book <dir>` };
|
|
157699
158448
|
}
|
|
157700
158449
|
let logoUrl;
|
|
@@ -157978,7 +158727,7 @@ var init_crawl_layers = __esm({
|
|
|
157978
158727
|
});
|
|
157979
158728
|
|
|
157980
158729
|
// src/wix-writes.ts
|
|
157981
|
-
import { existsSync as
|
|
158730
|
+
import { existsSync as existsSync62, readFileSync as readFileSync71 } from "node:fs";
|
|
157982
158731
|
import { join as join62 } from "node:path";
|
|
157983
158732
|
function isProvenRead(method, path2) {
|
|
157984
158733
|
if (/[#\x00-\x1F\x7F]/.test(path2)) return false;
|
|
@@ -158098,7 +158847,7 @@ function parseDataAccess(text11, from) {
|
|
|
158098
158847
|
function readDataAccess(dir) {
|
|
158099
158848
|
for (const name of ["SPEC.md", "MOBILE-UX.md"]) {
|
|
158100
158849
|
const p2 = join62(dir, name);
|
|
158101
|
-
if (!
|
|
158850
|
+
if (!existsSync62(p2)) continue;
|
|
158102
158851
|
let text11;
|
|
158103
158852
|
try {
|
|
158104
158853
|
text11 = readFileSync71(p2, "utf8");
|
|
@@ -158217,11 +158966,11 @@ __export(test_exports, {
|
|
|
158217
158966
|
scopeDescriptors: () => scopeDescriptors,
|
|
158218
158967
|
writeRecordedMocks: () => writeRecordedMocks
|
|
158219
158968
|
});
|
|
158220
|
-
import { existsSync as
|
|
158969
|
+
import { existsSync as existsSync63, mkdirSync as mkdirSync29, readFileSync as readFileSync72, writeFileSync as writeFileSync25 } from "node:fs";
|
|
158221
158970
|
import { join as join63, resolve as resolve49 } from "node:path";
|
|
158222
158971
|
function readTestConfig(dir) {
|
|
158223
158972
|
const p2 = resolve49(dir, TEST_CONFIG_FILE);
|
|
158224
|
-
if (!
|
|
158973
|
+
if (!existsSync63(p2)) return {};
|
|
158225
158974
|
let parsed;
|
|
158226
158975
|
try {
|
|
158227
158976
|
parsed = JSON.parse(readFileSync72(p2, "utf8"));
|
|
@@ -158292,7 +159041,7 @@ function readNetRules(path2) {
|
|
|
158292
159041
|
function defaultNetRules(dir) {
|
|
158293
159042
|
for (const rel of ["dev/net-mocks.json", "tests/net-mocks.json"]) {
|
|
158294
159043
|
const p2 = resolve49(dir, rel);
|
|
158295
|
-
if (
|
|
159044
|
+
if (existsSync63(p2)) {
|
|
158296
159045
|
const rules = readNetRules(p2);
|
|
158297
159046
|
if (rules.length) return { rules, from: rel };
|
|
158298
159047
|
}
|
|
@@ -159384,7 +160133,7 @@ var init_release_payload_hash = __esm({
|
|
|
159384
160133
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
159385
160134
|
import { createHash as createHash35, randomBytes as randomBytes2 } from "node:crypto";
|
|
159386
160135
|
import {
|
|
159387
|
-
existsSync as
|
|
160136
|
+
existsSync as existsSync64,
|
|
159388
160137
|
lstatSync as lstatSync20,
|
|
159389
160138
|
mkdirSync as mkdirSync31,
|
|
159390
160139
|
realpathSync as realpathSync9,
|
|
@@ -159514,7 +160263,7 @@ function readLatestAttestation(contentDir2) {
|
|
|
159514
160263
|
}
|
|
159515
160264
|
function readRetainedAttestations(contentDir2) {
|
|
159516
160265
|
const dir = join66(resolve53(contentDir2), ".himi", "attestations");
|
|
159517
|
-
if (!
|
|
160266
|
+
if (!existsSync64(dir)) return { runs: [], errors: [] };
|
|
159518
160267
|
try {
|
|
159519
160268
|
const names2 = readdirSync30(dir).filter((name) => name.endsWith(".json") && name !== "latest.json");
|
|
159520
160269
|
const parsedRuns = [];
|
|
@@ -159531,7 +160280,7 @@ function readRetainedAttestations(contentDir2) {
|
|
|
159531
160280
|
} else errors.push(`attestation history contains malformed retained run ${name}`);
|
|
159532
160281
|
}
|
|
159533
160282
|
const latest = readLatestAttestation(contentDir2);
|
|
159534
|
-
if (
|
|
160283
|
+
if (existsSync64(join66(dir, "latest.json")) && !latest) errors.push("attestation history has no valid latest.json");
|
|
159535
160284
|
else if (names2.length > 0 && !latest) errors.push("attestation history has no latest.json");
|
|
159536
160285
|
const byHash = new Map(parsedRuns.map((run2) => [run2.selfHash, run2]));
|
|
159537
160286
|
if (byHash.size !== parsedRuns.length) errors.push("attestation history contains duplicate self hashes");
|
|
@@ -159539,7 +160288,7 @@ function readRetainedAttestations(contentDir2) {
|
|
|
159539
160288
|
if (selfHashFor(run2) !== run2.selfHash) errors.push(`selfHash does not match retained run ${run2.runId}`);
|
|
159540
160289
|
for (const expected of Object.values(run2.screenshots)) {
|
|
159541
160290
|
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
159542
|
-
if (!
|
|
160291
|
+
if (!existsSync64(path2)) errors.push(`missing screenshot for retained run ${run2.runId}: ${basename18(path2)}`);
|
|
159543
160292
|
else if (sha2565(readFileSync74(path2)) !== expected) errors.push(`screenshot hash does not match retained run ${run2.runId}: ${basename18(path2)}`);
|
|
159544
160293
|
}
|
|
159545
160294
|
}
|
|
@@ -159610,7 +160359,7 @@ function writeAttestation(input, opts = {}) {
|
|
|
159610
160359
|
const descriptorHashes = Object.fromEntries(
|
|
159611
160360
|
Object.entries(input.descriptors).sort(([a2], [b2]) => a2.localeCompare(b2)).map(([screen, bytes2]) => [screen, sha2565(bytes2)])
|
|
159612
160361
|
);
|
|
159613
|
-
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a2], [b2]) => a2.localeCompare(b2)).filter(([, path2]) =>
|
|
160362
|
+
const screenshotEntries = Object.entries(input.screenshots ?? {}).sort(([a2], [b2]) => a2.localeCompare(b2)).filter(([, path2]) => existsSync64(path2)).map(([screen, path2]) => {
|
|
159614
160363
|
const bytes2 = readFileSync74(path2);
|
|
159615
160364
|
return { screen, bytes: bytes2, hash: sha2565(bytes2) };
|
|
159616
160365
|
});
|
|
@@ -159618,7 +160367,7 @@ function writeAttestation(input, opts = {}) {
|
|
|
159618
160367
|
for (const { bytes: bytes2, hash: hash2 } of screenshotEntries) {
|
|
159619
160368
|
const artifact = screenshotArtifactPath(contentDir2, hash2);
|
|
159620
160369
|
mkdirSync31(join66(dir, "artifacts"), { recursive: true });
|
|
159621
|
-
if (!
|
|
160370
|
+
if (!existsSync64(artifact)) writeFileSync27(artifact, bytes2);
|
|
159622
160371
|
}
|
|
159623
160372
|
const unsigned = {
|
|
159624
160373
|
attestation: 2,
|
|
@@ -159663,7 +160412,7 @@ function writeAttestation(input, opts = {}) {
|
|
|
159663
160412
|
retainedRuns.flatMap((run2) => Object.values(run2.screenshots))
|
|
159664
160413
|
);
|
|
159665
160414
|
const artifactDir = join66(dir, "artifacts");
|
|
159666
|
-
if (
|
|
160415
|
+
if (existsSync64(artifactDir)) {
|
|
159667
160416
|
for (const name of readdirSync30(artifactDir).filter((candidate) => candidate.endsWith(".png"))) {
|
|
159668
160417
|
if (!retainedScreenshotHashes.has(name.slice(0, -4))) unlinkSync4(join66(artifactDir, name));
|
|
159669
160418
|
}
|
|
@@ -159739,7 +160488,7 @@ function verifyAttestation(attestation, contentDir2, descriptors, expectedApp, r
|
|
|
159739
160488
|
}
|
|
159740
160489
|
for (const [screen, expected] of Object.entries(attestation.screenshots)) {
|
|
159741
160490
|
const path2 = screenshotArtifactPath(contentDir2, expected);
|
|
159742
|
-
if (!
|
|
160491
|
+
if (!existsSync64(path2)) {
|
|
159743
160492
|
errors.push(`missing screenshot for ${screen}: ${basename18(path2)}`);
|
|
159744
160493
|
continue;
|
|
159745
160494
|
}
|
|
@@ -159763,7 +160512,7 @@ var init_attestation = __esm({
|
|
|
159763
160512
|
});
|
|
159764
160513
|
|
|
159765
160514
|
// src/ux-evidence.ts
|
|
159766
|
-
import { existsSync as
|
|
160515
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync32, readFileSync as readFileSync75, writeFileSync as writeFileSync28 } from "node:fs";
|
|
159767
160516
|
import { dirname as dirname38, isAbsolute as isAbsolute6, join as join67, relative as relative12, resolve as resolve54 } from "node:path";
|
|
159768
160517
|
function isNativePlatform(value2) {
|
|
159769
160518
|
return typeof value2 === "string" && NATIVE_PLATFORMS.includes(value2);
|
|
@@ -159773,7 +160522,7 @@ function isNativeAuditStatus(value2) {
|
|
|
159773
160522
|
}
|
|
159774
160523
|
function readText(path2) {
|
|
159775
160524
|
try {
|
|
159776
|
-
return
|
|
160525
|
+
return existsSync65(path2) ? readFileSync75(path2, "utf8") : null;
|
|
159777
160526
|
} catch {
|
|
159778
160527
|
return null;
|
|
159779
160528
|
}
|
|
@@ -159875,7 +160624,7 @@ function uxEvidenceForRelease(content, release2) {
|
|
|
159875
160624
|
inheritedScreens: [],
|
|
159876
160625
|
malformed: []
|
|
159877
160626
|
};
|
|
159878
|
-
if (!
|
|
160627
|
+
if (!existsSync65(path2)) return { ...base, state: "absent" };
|
|
159879
160628
|
const parsed = parseEvidence(path2);
|
|
159880
160629
|
if (parsed.error) return { ...base, state: "unreadable", error: parsed.error };
|
|
159881
160630
|
if (!parsed.evidence) return { ...base, state: "absent" };
|
|
@@ -159946,11 +160695,11 @@ var mobile_ux_lint_exports = {};
|
|
|
159946
160695
|
__export(mobile_ux_lint_exports, {
|
|
159947
160696
|
mobileUxIssues: () => mobileUxIssues
|
|
159948
160697
|
});
|
|
159949
|
-
import { existsSync as
|
|
160698
|
+
import { existsSync as existsSync66, readFileSync as readFileSync76 } from "node:fs";
|
|
159950
160699
|
import { join as join68 } from "node:path";
|
|
159951
160700
|
function mobileUxIssues(dir, strict) {
|
|
159952
160701
|
const file2 = join68(dir, "MOBILE-UX.md");
|
|
159953
|
-
if (!
|
|
160702
|
+
if (!existsSync66(file2)) return [];
|
|
159954
160703
|
let text11;
|
|
159955
160704
|
try {
|
|
159956
160705
|
text11 = readFileSync76(file2, "utf8");
|
|
@@ -161634,7 +162383,7 @@ __export(functions_exports, {
|
|
|
161634
162383
|
resolveFunctionsTarget: () => resolveFunctionsTarget,
|
|
161635
162384
|
runRemoteFunctionOperation: () => runRemoteFunctionOperation
|
|
161636
162385
|
});
|
|
161637
|
-
import { readFileSync as readFileSync79, existsSync as
|
|
162386
|
+
import { readFileSync as readFileSync79, existsSync as existsSync69 } from "node:fs";
|
|
161638
162387
|
import { join as join71, resolve as resolve55 } from "node:path";
|
|
161639
162388
|
function resolveFunctionsTarget(input) {
|
|
161640
162389
|
const explicitUrl = input.functionsUrl?.trim();
|
|
@@ -161654,7 +162403,7 @@ async function loadFunctionsApp(dir) {
|
|
|
161654
162403
|
}
|
|
161655
162404
|
const sources = {};
|
|
161656
162405
|
for (const definition of config.functions.functions) {
|
|
161657
|
-
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join71(loaded.dir, "functions", `${definition.name}${extension}`)).find(
|
|
162406
|
+
const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join71(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync69);
|
|
161658
162407
|
if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
|
|
161659
162408
|
sources[definition.name] = readFileSync79(source, "utf8");
|
|
161660
162409
|
}
|
|
@@ -161844,7 +162593,7 @@ var init_cli_bridge = __esm({
|
|
|
161844
162593
|
});
|
|
161845
162594
|
|
|
161846
162595
|
// src/mcp/file-tools.ts
|
|
161847
|
-
import { closeSync as closeSync6, constants as constants4, lstatSync as lstatSync21, mkdirSync as mkdirSync33, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync81, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync18, statSync as statSync19, writeSync, existsSync as
|
|
162596
|
+
import { closeSync as closeSync6, constants as constants4, lstatSync as lstatSync21, mkdirSync as mkdirSync33, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync81, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync18, statSync as statSync19, writeSync, existsSync as existsSync70 } from "node:fs";
|
|
161848
162597
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
161849
162598
|
import { dirname as dirname39, isAbsolute as isAbsolute7, join as join72, relative as relative13, resolve as resolve56, sep as sep18 } from "node:path";
|
|
161850
162599
|
import * as z2 from "zod";
|
|
@@ -161854,7 +162603,7 @@ function within(root, p2) {
|
|
|
161854
162603
|
function realish(p2) {
|
|
161855
162604
|
let cur = p2;
|
|
161856
162605
|
const tail = [];
|
|
161857
|
-
while (!
|
|
162606
|
+
while (!existsSync70(cur)) {
|
|
161858
162607
|
const up = dirname39(cur);
|
|
161859
162608
|
if (up === cur) break;
|
|
161860
162609
|
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
@@ -161877,7 +162626,7 @@ function symlinkComponent(base, abs) {
|
|
|
161877
162626
|
function workspaceRefusal(root, target) {
|
|
161878
162627
|
const r3 = resolve56(root);
|
|
161879
162628
|
const t2 = resolve56(r3, target);
|
|
161880
|
-
if (!
|
|
162629
|
+
if (!existsSync70(r3)) return `the workspace folder ${r3} does not exist`;
|
|
161881
162630
|
if (!within(r3, t2) || !within(realpathSync10(r3), realish(t2))) return `"${target}" is outside the workspace folder ${r3}`;
|
|
161882
162631
|
const link = symlinkComponent(r3, t2);
|
|
161883
162632
|
if (link) return `"${link}" is a symlink \u2014 paths must stay in real folders inside the workspace`;
|
|
@@ -161886,13 +162635,13 @@ function workspaceRefusal(root, target) {
|
|
|
161886
162635
|
async function confinedAppDir(args, deps) {
|
|
161887
162636
|
const root = resolve56(await deps.defaultDir());
|
|
161888
162637
|
const dir = typeof args.dir === "string" && args.dir ? resolve56(root, args.dir) : root;
|
|
161889
|
-
if (!
|
|
162638
|
+
if (!existsSync70(root)) return refuse5("no_workspace", `the workspace folder ${root} does not exist`);
|
|
161890
162639
|
if (!within(root, dir) || !within(realpathSync10(root), realish(dir))) return refuse5("outside_workspace", `"${String(args.dir)}" is outside the workspace folder`);
|
|
161891
162640
|
const link = symlinkComponent(root, dir);
|
|
161892
162641
|
if (link) return refuse5("outside_workspace", `"${link}" is a symlink \u2014 the app folder must be a real folder in the workspace`);
|
|
161893
162642
|
const rel = relative13(root, dir);
|
|
161894
162643
|
if (rel && (isDeniedSourcePath(`${rel}/x`) || isDeniedSourcePath(`${rel.toLowerCase()}/x`))) return refuse5("denied", `"${rel}" is a folder this tool does not touch`);
|
|
161895
|
-
if (!
|
|
162644
|
+
if (!existsSync70(join72(dir, CONTENT_MARKER))) {
|
|
161896
162645
|
return refuse5("not_an_app", `"${rel || "."}" is not an app folder (no ${CONTENT_MARKER}) \u2014 see himi_list_apps, or create one with himi_init`);
|
|
161897
162646
|
}
|
|
161898
162647
|
return dir;
|
|
@@ -161900,7 +162649,7 @@ async function confinedAppDir(args, deps) {
|
|
|
161900
162649
|
function onDiskSpelling(abs) {
|
|
161901
162650
|
let cur = abs;
|
|
161902
162651
|
const tail = [];
|
|
161903
|
-
while (!
|
|
162652
|
+
while (!existsSync70(cur)) {
|
|
161904
162653
|
const up = dirname39(cur);
|
|
161905
162654
|
if (up === cur) break;
|
|
161906
162655
|
tail.unshift(cur.slice(up.length + (up.endsWith(sep18) ? 0 : 1)));
|
|
@@ -161924,7 +162673,7 @@ function confinedPath(appDir3, rel) {
|
|
|
161924
162673
|
const abs = resolve56(appDir3, rel);
|
|
161925
162674
|
if (!within(appDir3, abs) || abs === appDir3) return { error: `"${rel}" is outside the app folder` };
|
|
161926
162675
|
const real = realish(abs);
|
|
161927
|
-
const base =
|
|
162676
|
+
const base = existsSync70(appDir3) ? realpathSync10(appDir3) : realish(appDir3);
|
|
161928
162677
|
if (!within(base, real) || real === base) return { error: `"${rel}" is outside the app folder` };
|
|
161929
162678
|
const link = symlinkComponent(appDir3, abs);
|
|
161930
162679
|
if (link) return { error: `"${link}" is a symlink, which this tool does not follow` };
|
|
@@ -161981,11 +162730,11 @@ function fileTools() {
|
|
|
161981
162730
|
inputSchema: z2.object({}),
|
|
161982
162731
|
handler: async (_a3, d2) => {
|
|
161983
162732
|
const root = resolve56(await d2.defaultDir());
|
|
161984
|
-
if (!
|
|
162733
|
+
if (!existsSync70(root)) return ok({ ok: true, workspace: root, apps: [] });
|
|
161985
162734
|
const apps = [];
|
|
161986
|
-
if (
|
|
162735
|
+
if (existsSync70(join72(root, CONTENT_MARKER))) apps.push(".");
|
|
161987
162736
|
for (const e2 of readdirSync31(root, { withFileTypes: true })) {
|
|
161988
|
-
if (e2.isDirectory() && !e2.name.startsWith(".") &&
|
|
162737
|
+
if (e2.isDirectory() && !e2.name.startsWith(".") && existsSync70(join72(root, e2.name, CONTENT_MARKER))) apps.push(e2.name);
|
|
161989
162738
|
}
|
|
161990
162739
|
return ok({ ok: true, workspace: root, apps: apps.sort() });
|
|
161991
162740
|
}
|
|
@@ -161999,7 +162748,7 @@ function fileTools() {
|
|
|
161999
162748
|
handler: async (a2, d2) => {
|
|
162000
162749
|
const app = await confinedAppDir(a2, d2);
|
|
162001
162750
|
if (typeof app !== "string") return app;
|
|
162002
|
-
if (!
|
|
162751
|
+
if (!existsSync70(app) || !statSync19(app).isDirectory()) return refuse5("no_app", `no folder at ${app}`);
|
|
162003
162752
|
return ok({ ok: true, dir: app, ...listFiles(app) });
|
|
162004
162753
|
}
|
|
162005
162754
|
},
|
|
@@ -162014,7 +162763,7 @@ function fileTools() {
|
|
|
162014
162763
|
if (typeof app !== "string") return app;
|
|
162015
162764
|
const p2 = confinedPath(app, a2.path);
|
|
162016
162765
|
if (typeof p2 !== "string") return refuse5("bad_path", p2.error);
|
|
162017
|
-
if (!
|
|
162766
|
+
if (!existsSync70(p2) || !lstatSync21(p2).isFile()) return refuse5("not_found", `no file "${String(a2.path)}"`);
|
|
162018
162767
|
const size = statSync19(p2).size;
|
|
162019
162768
|
if (size > MAX_FILE_BYTES) return refuse5("too_large", `"${String(a2.path)}" is ${size} bytes \u2014 over the ${MAX_FILE_BYTES}-byte read limit`);
|
|
162020
162769
|
return ok({ ok: true, path: a2.path, bytes: size, content: readFileSync81(p2, "utf8") });
|
|
@@ -162041,7 +162790,7 @@ function fileTools() {
|
|
|
162041
162790
|
if (typeof p2 !== "string") refused2.push({ path: f2.path, error: p2.error });
|
|
162042
162791
|
else if (typeof f2.content !== "string") refused2.push({ path: f2.path, error: "content must be text" });
|
|
162043
162792
|
else if (Buffer.byteLength(f2.content) > MAX_FILE_BYTES) refused2.push({ path: f2.path, error: `over the ${MAX_FILE_BYTES}-byte limit` });
|
|
162044
|
-
else if (
|
|
162793
|
+
else if (existsSync70(p2) && !lstatSync21(p2).isFile()) refused2.push({ path: f2.path, error: "not a regular file" });
|
|
162045
162794
|
else if (planned2.some((q2) => q2.abs === p2)) refused2.push({ path: f2.path, error: "the same file twice in one call" });
|
|
162046
162795
|
else planned2.push({ abs: p2, rel: String(f2.path), content: f2.content });
|
|
162047
162796
|
}
|
|
@@ -162074,7 +162823,7 @@ function fileTools() {
|
|
|
162074
162823
|
for (const rel of paths2) {
|
|
162075
162824
|
const p2 = confinedPath(app, rel);
|
|
162076
162825
|
if (typeof p2 !== "string") refused2.push({ path: rel, error: p2.error });
|
|
162077
|
-
else if (!
|
|
162826
|
+
else if (!existsSync70(p2)) refused2.push({ path: rel, error: "no such file" });
|
|
162078
162827
|
else if (!lstatSync21(p2).isFile()) refused2.push({ path: rel, error: "not a regular file" });
|
|
162079
162828
|
else if (!planned2.includes(p2)) {
|
|
162080
162829
|
planned2.push(p2);
|
|
@@ -162869,14 +163618,14 @@ var init_open_url = __esm({
|
|
|
162869
163618
|
});
|
|
162870
163619
|
|
|
162871
163620
|
// src/ux-audit.ts
|
|
162872
|
-
import { existsSync as
|
|
163621
|
+
import { existsSync as existsSync73, readFileSync as readFileSync83, readdirSync as readdirSync32 } from "node:fs";
|
|
162873
163622
|
import { join as join76, relative as relative15, resolve as resolve61 } from "node:path";
|
|
162874
163623
|
function issue(issues, strict, code, message2, path2) {
|
|
162875
163624
|
issues.push({ code, message: message2, ...path2 ? { path: path2 } : {}, severity: strict ? "error" : "warning" });
|
|
162876
163625
|
}
|
|
162877
163626
|
function readText2(path2) {
|
|
162878
163627
|
try {
|
|
162879
|
-
return
|
|
163628
|
+
return existsSync73(path2) ? readFileSync83(path2, "utf8") : null;
|
|
162880
163629
|
} catch {
|
|
162881
163630
|
return null;
|
|
162882
163631
|
}
|
|
@@ -162976,7 +163725,7 @@ function auditUx(content, strict = false) {
|
|
|
162976
163725
|
}
|
|
162977
163726
|
if (usesAppNetwork(source)) {
|
|
162978
163727
|
const mocksPath = join76(dir, "dev", "net-mocks.json");
|
|
162979
|
-
if (!
|
|
163728
|
+
if (!existsSync73(mocksPath)) {
|
|
162980
163729
|
issue(issues, strict, "missing-app-mocks", "This package uses a Wix/network client but has no app-specific dev/net-mocks.json. `himi test --record` writes one from the live responses it sees; then add fixtures for dynamic, entitlement, or recovery flows.", "dev/net-mocks.json");
|
|
162981
163730
|
} else {
|
|
162982
163731
|
try {
|
|
@@ -163024,7 +163773,7 @@ __export(native_decode_exports, {
|
|
|
163024
163773
|
runNativeDecode: () => runNativeDecode
|
|
163025
163774
|
});
|
|
163026
163775
|
import { execFileSync as execFileSync6, spawnSync as spawnSync4 } from "node:child_process";
|
|
163027
|
-
import { existsSync as
|
|
163776
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync37, mkdtempSync as mkdtempSync5, readFileSync as readFileSync84, rmSync as rmSync20, writeFileSync as writeFileSync31 } from "node:fs";
|
|
163028
163777
|
import { homedir as homedir10, tmpdir as tmpdir6 } from "node:os";
|
|
163029
163778
|
import { join as join78 } from "node:path";
|
|
163030
163779
|
import { fileURLToPath as fileURLToPath27 } from "node:url";
|
|
@@ -163036,8 +163785,8 @@ function nativeDecodeAndroidHarnessDir() {
|
|
|
163036
163785
|
}
|
|
163037
163786
|
function nativeOracleShipped() {
|
|
163038
163787
|
return {
|
|
163039
|
-
ios:
|
|
163040
|
-
android:
|
|
163788
|
+
ios: existsSync74(join78(nativeDecodePackageDir(), "Package.swift")),
|
|
163789
|
+
android: existsSync74(join78(nativeDecodeAndroidHarnessDir(), "gradlew"))
|
|
163041
163790
|
};
|
|
163042
163791
|
}
|
|
163043
163792
|
function detectNativeDecode(options = {}) {
|
|
@@ -163048,7 +163797,7 @@ function detectNativeDecode(options = {}) {
|
|
|
163048
163797
|
return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
|
|
163049
163798
|
}
|
|
163050
163799
|
if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
|
|
163051
|
-
const packageAvailable = options.packageAvailable ??
|
|
163800
|
+
const packageAvailable = options.packageAvailable ?? existsSync74(join78(packageDir, "Package.swift"));
|
|
163052
163801
|
if (!packageAvailable) {
|
|
163053
163802
|
return {
|
|
163054
163803
|
platform: "ios",
|
|
@@ -163074,7 +163823,7 @@ function defaultAndroidSdkDir(hostPlatform, home) {
|
|
|
163074
163823
|
function detectAndroidNativeDecode(options = {}) {
|
|
163075
163824
|
const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
|
|
163076
163825
|
const gradlew = join78(harnessDir, "gradlew");
|
|
163077
|
-
const gradlewAvailable = options.gradlewAvailable ??
|
|
163826
|
+
const gradlewAvailable = options.gradlewAvailable ?? existsSync74(gradlew);
|
|
163078
163827
|
if (!gradlewAvailable) {
|
|
163079
163828
|
return {
|
|
163080
163829
|
platform: "android",
|
|
@@ -163082,7 +163831,7 @@ function detectAndroidNativeDecode(options = {}) {
|
|
|
163082
163831
|
reason: "the in-repo Android Gradle harness is unavailable (off-repo installs do not ship the decoder oracle)"
|
|
163083
163832
|
};
|
|
163084
163833
|
}
|
|
163085
|
-
const exists = typeof options.sdkAvailable === "function" ? options.sdkAvailable : typeof options.sdkAvailable === "boolean" ? /* @__PURE__ */ ((answer) => () => answer)(options.sdkAvailable) :
|
|
163834
|
+
const exists = typeof options.sdkAvailable === "function" ? options.sdkAvailable : typeof options.sdkAvailable === "boolean" ? /* @__PURE__ */ ((answer) => () => answer)(options.sdkAvailable) : existsSync74;
|
|
163086
163835
|
const defaultDir = defaultAndroidSdkDir(options.hostPlatform ?? process.platform, options.homeDir ?? homedir10());
|
|
163087
163836
|
const candidates = [
|
|
163088
163837
|
options.androidHome ?? process.env.ANDROID_HOME,
|
|
@@ -163344,7 +164093,7 @@ __export(browser_authoring_exports, {
|
|
|
163344
164093
|
});
|
|
163345
164094
|
import { createServer as createServer4 } from "node:http";
|
|
163346
164095
|
import { createHash as createHash38, randomBytes as randomBytes4 } from "node:crypto";
|
|
163347
|
-
import { existsSync as
|
|
164096
|
+
import { existsSync as existsSync75, readdirSync as readdirSync33, readFileSync as readFileSync85, realpathSync as realpathSync11, statSync as statSync20 } from "node:fs";
|
|
163348
164097
|
import { join as join79, posix as posix3, relative as relative16, sep as sep19 } from "node:path";
|
|
163349
164098
|
function humanMs(ms2) {
|
|
163350
164099
|
return ms2 < 1e3 ? `${ms2}ms` : `${Math.round(ms2 / 1e3)}s`;
|
|
@@ -163367,7 +164116,7 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
|
|
|
163367
164116
|
}
|
|
163368
164117
|
}
|
|
163369
164118
|
};
|
|
163370
|
-
if (!
|
|
164119
|
+
if (!existsSync75(root)) return null;
|
|
163371
164120
|
walk2(root, `/tier5-src/${bundleName}`);
|
|
163372
164121
|
const entry = [`/tier5-src/${bundleName}/index.ts`, `/tier5-src/${bundleName}/index.js`].find((p2) => p2 in files);
|
|
163373
164122
|
if (!entry) return null;
|
|
@@ -163394,7 +164143,7 @@ function collectRelativeSiblings(files, tier5SrcDir) {
|
|
|
163394
164143
|
join79(onDisk, "index.js")
|
|
163395
164144
|
];
|
|
163396
164145
|
for (const abs of candidates) {
|
|
163397
|
-
if (!
|
|
164146
|
+
if (!existsSync75(abs) || statSync20(abs).isDirectory()) continue;
|
|
163398
164147
|
const key3 = `/tier5-src/${relative16(tier5SrcDir, abs).split(sep19).join(posix3.sep)}`;
|
|
163399
164148
|
if (key3 in files) break;
|
|
163400
164149
|
files[key3] = readFileSync85(abs, "utf8");
|
|
@@ -163505,7 +164254,7 @@ async function readBody3(req) {
|
|
|
163505
164254
|
async function runBrowserAuthoring(opts) {
|
|
163506
164255
|
const log = opts.log ?? (() => {
|
|
163507
164256
|
});
|
|
163508
|
-
const timeoutMs = opts.timeoutMs ??
|
|
164257
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
163509
164258
|
const payload = encodeJob(opts.job);
|
|
163510
164259
|
const token = mintToken2(payload);
|
|
163511
164260
|
const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
|
|
@@ -163581,11 +164330,11 @@ async function runBrowserAuthoring(opts) {
|
|
|
163581
164330
|
});
|
|
163582
164331
|
});
|
|
163583
164332
|
}
|
|
163584
|
-
var
|
|
164333
|
+
var DEFAULT_TIMEOUT_MS3, PROBE_TIMEOUT_MS, POINT_ELSEWHERE, NO_SUCH_ROUTE, NOT_STAGED, MAX_CALLBACK_BYTES;
|
|
163585
164334
|
var init_browser_authoring = __esm({
|
|
163586
164335
|
"src/browser-authoring.ts"() {
|
|
163587
164336
|
init_open_url();
|
|
163588
|
-
|
|
164337
|
+
DEFAULT_TIMEOUT_MS3 = 5 * 60 * 1e3;
|
|
163589
164338
|
PROBE_TIMEOUT_MS = 5e3;
|
|
163590
164339
|
POINT_ELSEWHERE = "Point --serve-url at a plane that mounts /v1/authoring/* (the local serve stack does NOT: core/serve-authoring is a separate service), or pass --target to select a deployed one.";
|
|
163591
164340
|
NO_SUCH_ROUTE = /* @__PURE__ */ new Set([404, 410]);
|
|
@@ -163604,7 +164353,7 @@ __export(coverage_exports, {
|
|
|
163604
164353
|
suppressedNativeKeys: () => suppressedNativeKeys,
|
|
163605
164354
|
trendAndStore: () => trendAndStore
|
|
163606
164355
|
});
|
|
163607
|
-
import { existsSync as
|
|
164356
|
+
import { existsSync as existsSync76, mkdirSync as mkdirSync38, readFileSync as readFileSync86, writeFileSync as writeFileSync32 } from "node:fs";
|
|
163608
164357
|
import { dirname as dirname43, join as join80 } from "node:path";
|
|
163609
164358
|
function suppressedNativeKeys(oracle) {
|
|
163610
164359
|
return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
|
|
@@ -163788,7 +164537,7 @@ function trendAndStore(dir, entries, suppressed) {
|
|
|
163788
164537
|
const p2 = join80(dir, LEDGER_FILE);
|
|
163789
164538
|
let previous = null;
|
|
163790
164539
|
try {
|
|
163791
|
-
if (
|
|
164540
|
+
if (existsSync76(p2)) {
|
|
163792
164541
|
const parsed = JSON.parse(readFileSync86(p2, "utf8"));
|
|
163793
164542
|
if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k2) => typeof k2 === "string");
|
|
163794
164543
|
}
|
|
@@ -163831,7 +164580,7 @@ function diffAndStoreObservations(dir, current) {
|
|
|
163831
164580
|
const p2 = join80(dir, OBS_FILE);
|
|
163832
164581
|
let previous = null;
|
|
163833
164582
|
try {
|
|
163834
|
-
if (
|
|
164583
|
+
if (existsSync76(p2)) {
|
|
163835
164584
|
const parsed = JSON.parse(readFileSync86(p2, "utf8"));
|
|
163836
164585
|
if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
|
|
163837
164586
|
(v2) => Array.isArray(v2) && v2.every((l2) => typeof l2 === "string")
|
|
@@ -164204,11 +164953,11 @@ __export(design_kits_exports, {
|
|
|
164204
164953
|
kitsDir: () => kitsDir,
|
|
164205
164954
|
listKits: () => listKits2
|
|
164206
164955
|
});
|
|
164207
|
-
import { existsSync as
|
|
164956
|
+
import { existsSync as existsSync78, readFileSync as readFileSync88, readdirSync as readdirSync34 } from "node:fs";
|
|
164208
164957
|
import { join as join83, basename as basename20 } from "node:path";
|
|
164209
164958
|
import { fileURLToPath as fileURLToPath28 } from "node:url";
|
|
164210
164959
|
function kitsDir() {
|
|
164211
|
-
return KIT_DIR_CANDIDATES.find((p2) =>
|
|
164960
|
+
return KIT_DIR_CANDIDATES.find((p2) => existsSync78(p2));
|
|
164212
164961
|
}
|
|
164213
164962
|
function listKits2() {
|
|
164214
164963
|
const dir = kitsDir();
|
|
@@ -164703,7 +165452,7 @@ __export(coverage_exports2, {
|
|
|
164703
165452
|
verifyNativeProof: () => verifyNativeProof
|
|
164704
165453
|
});
|
|
164705
165454
|
import { createHash as createHash39 } from "node:crypto";
|
|
164706
|
-
import { existsSync as
|
|
165455
|
+
import { existsSync as existsSync80, readFileSync as readFileSync90, writeFileSync as writeFileSync33 } from "node:fs";
|
|
164707
165456
|
import { isAbsolute as isAbsolute8, join as join85, resolve as resolve64 } from "node:path";
|
|
164708
165457
|
function verifiedEvidence(evidenceDir) {
|
|
164709
165458
|
const manifest2 = obj3(JSON.parse(readFileSync90(join85(evidenceDir, "manifest.json"), "utf8")));
|
|
@@ -164799,7 +165548,7 @@ function deriveRequirements(evidenceDir) {
|
|
|
164799
165548
|
function verifyNativeProof(contentDir2, releaseHash, requirementIds) {
|
|
164800
165549
|
const root = resolve64(contentDir2);
|
|
164801
165550
|
const path2 = join85(root, NATIVE_PROOF_FILE);
|
|
164802
|
-
if (!
|
|
165551
|
+
if (!existsSync80(path2)) return { ok: false, issues: [`${NATIVE_PROOF_FILE} is absent.`] };
|
|
164803
165552
|
let proof;
|
|
164804
165553
|
try {
|
|
164805
165554
|
proof = obj3(JSON.parse(readFileSync90(path2, "utf8")));
|
|
@@ -164821,7 +165570,7 @@ function verifyNativeProof(contentDir2, releaseHash, requirementIds) {
|
|
|
164821
165570
|
continue;
|
|
164822
165571
|
}
|
|
164823
165572
|
const artifact = record2.artifact;
|
|
164824
|
-
if (typeof artifact !== "string" || !artifact.trim() || isAbsolute8(artifact) || artifact.split(/[\\/]/).includes("..") || !
|
|
165573
|
+
if (typeof artifact !== "string" || !artifact.trim() || isAbsolute8(artifact) || artifact.split(/[\\/]/).includes("..") || !existsSync80(join85(root, artifact))) {
|
|
164825
165574
|
issues.push(`Native walkthrough check ${id} needs a reviewable artifact file.`);
|
|
164826
165575
|
}
|
|
164827
165576
|
}
|
|
@@ -164830,7 +165579,7 @@ function verifyNativeProof(contentDir2, releaseHash, requirementIds) {
|
|
|
164830
165579
|
function syncCoverage(evidenceDir, contentDir2, write2 = true) {
|
|
164831
165580
|
const current = deriveRequirements(evidenceDir);
|
|
164832
165581
|
const path2 = join85(resolve64(contentDir2), COVERAGE_FILE);
|
|
164833
|
-
const existed =
|
|
165582
|
+
const existed = existsSync80(path2);
|
|
164834
165583
|
const old = existed ? obj3(JSON.parse(readFileSync90(path2, "utf8"))) : {};
|
|
164835
165584
|
const hashesChanged = existed && JSON.stringify(old.sourceHashes) !== JSON.stringify(current.sourceHashes);
|
|
164836
165585
|
const prior = Array.isArray(old.requirements) ? old.requirements : [];
|
|
@@ -164871,7 +165620,7 @@ function verifyCoverage(evidenceDir, contentDir2, releaseHash, builtScreenIds) {
|
|
|
164871
165620
|
const saved = result.existed ? obj3(JSON.parse(readFileSync90(join85(resolve64(contentDir2), COVERAGE_FILE), "utf8"))) : {};
|
|
164872
165621
|
const rows = Array.isArray(saved.requirements) ? saved.requirements.map(obj3) : [];
|
|
164873
165622
|
const contentManifest = join85(resolve64(contentDir2), "himalaya.content.json");
|
|
164874
|
-
const declaredScreens =
|
|
165623
|
+
const declaredScreens = existsSync80(contentManifest) ? obj3(obj3(JSON.parse(readFileSync90(contentManifest, "utf8"))).screens) : void 0;
|
|
164875
165624
|
const availableScreens = builtScreenIds ? new Set(builtScreenIds) : declaredScreens && Object.keys(declaredScreens).length ? new Set(Object.keys(declaredScreens)) : void 0;
|
|
164876
165625
|
for (const row2 of rows) {
|
|
164877
165626
|
const id = typeof row2.id === "string" ? row2.id : void 0;
|
|
@@ -164907,7 +165656,7 @@ function verifyCoverage(evidenceDir, contentDir2, releaseHash, builtScreenIds) {
|
|
|
164907
165656
|
const path2 = check.evidence;
|
|
164908
165657
|
if (typeof path2 !== "string" || !path2.trim() || isAbsolute8(path2) || path2.split(/[\\/]/).includes("..")) {
|
|
164909
165658
|
issues.push({ id, message: `Check ${required3} needs a safe relative evidence path.` });
|
|
164910
|
-
} else if (!
|
|
165659
|
+
} else if (!existsSync80(join85(resolve64(contentDir2), path2))) {
|
|
164911
165660
|
issues.push({ id, message: `Check ${required3} evidence file is absent: ${path2}.` });
|
|
164912
165661
|
} else {
|
|
164913
165662
|
try {
|
|
@@ -164918,7 +165667,7 @@ function verifyCoverage(evidenceDir, contentDir2, releaseHash, builtScreenIds) {
|
|
|
164918
165667
|
issues.push({ id, message: `Check ${required3} has no latest passed record for this requirement and target.` });
|
|
164919
165668
|
} else {
|
|
164920
165669
|
const artifact = record2.artifact;
|
|
164921
|
-
if (typeof artifact !== "string" || !artifact.trim() || isAbsolute8(artifact) || artifact.split(/[\\/]/).includes("..") || !
|
|
165670
|
+
if (typeof artifact !== "string" || !artifact.trim() || isAbsolute8(artifact) || artifact.split(/[\\/]/).includes("..") || !existsSync80(join85(resolve64(contentDir2), artifact))) {
|
|
164922
165671
|
issues.push({ id, message: `Check ${required3} needs a reviewable artifact file.` });
|
|
164923
165672
|
}
|
|
164924
165673
|
}
|
|
@@ -164958,7 +165707,7 @@ __export(validate_topbar_exports, {
|
|
|
164958
165707
|
runOneAppTopBarValidation: () => runOneAppTopBarValidation
|
|
164959
165708
|
});
|
|
164960
165709
|
import { createHash as createHash40 } from "node:crypto";
|
|
164961
|
-
import { existsSync as
|
|
165710
|
+
import { existsSync as existsSync81, readFileSync as readFileSync91, statSync as statSync22 } from "node:fs";
|
|
164962
165711
|
import { resolve as resolve65, join as join86 } from "node:path";
|
|
164963
165712
|
import ts8 from "typescript";
|
|
164964
165713
|
function enrichedControls(raw, views) {
|
|
@@ -165167,7 +165916,7 @@ function configActions(configPath) {
|
|
|
165167
165916
|
}
|
|
165168
165917
|
function screenActions2(contentDir2) {
|
|
165169
165918
|
const path2 = join86(contentDir2, "dev", "index.ts");
|
|
165170
|
-
if (!
|
|
165919
|
+
if (!existsSync81(path2)) return /* @__PURE__ */ new Map();
|
|
165171
165920
|
const source = ts8.createSourceFile(path2, readFileSync91(path2, "utf8"), ts8.ScriptTarget.Latest, true, ts8.ScriptKind.TS);
|
|
165172
165921
|
if (source.parseDiagnostics.length) throw Error("dev/index.ts could not be parsed.");
|
|
165173
165922
|
const declaration = source.statements.filter(ts8.isVariableStatement).flatMap((statement) => [...statement.declarationList.declarations]).find((item) => ts8.isIdentifier(item.name) && item.name.text === "SCREENS");
|
|
@@ -165268,7 +166017,7 @@ function validate3(evidenceDir, contentDir2) {
|
|
|
165268
166017
|
}
|
|
165269
166018
|
const mappings = /* @__PURE__ */ new Map();
|
|
165270
166019
|
const coveragePath = join86(contentDir2, "ONE-APP-COVERAGE.json");
|
|
165271
|
-
if (
|
|
166020
|
+
if (existsSync81(coveragePath)) {
|
|
165272
166021
|
try {
|
|
165273
166022
|
const coverage = readJson7(coveragePath);
|
|
165274
166023
|
for (const row2 of Array.isArray(coverage.requirements) ? coverage.requirements : []) {
|
|
@@ -166134,7 +166883,7 @@ async function generatePkce() {
|
|
|
166134
166883
|
return { verifier, challenge: base64url(new Uint8Array(digest2)) };
|
|
166135
166884
|
}
|
|
166136
166885
|
async function hostedAuthUrl(req, visitorToken, fetchImpl = fetch) {
|
|
166137
|
-
const res = await fetchImpl(`${
|
|
166886
|
+
const res = await fetchImpl(`${WIX_API3}${REDIRECT_SESSION_PATH}`, {
|
|
166138
166887
|
method: "POST",
|
|
166139
166888
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${visitorToken}` },
|
|
166140
166889
|
body: JSON.stringify({
|
|
@@ -166177,7 +166926,7 @@ async function hostedAuthUrl(req, visitorToken, fetchImpl = fetch) {
|
|
|
166177
166926
|
return fullUrl;
|
|
166178
166927
|
}
|
|
166179
166928
|
async function exchangeAuthCode(cfg, code, verifier, fetchImpl = fetch) {
|
|
166180
|
-
const res = await fetchImpl(`${
|
|
166929
|
+
const res = await fetchImpl(`${WIX_API3}${TOKEN_PATH}`, {
|
|
166181
166930
|
method: "POST",
|
|
166182
166931
|
headers: { "Content-Type": "application/json" },
|
|
166183
166932
|
body: JSON.stringify({
|
|
@@ -166226,10 +166975,10 @@ function safeReturnPath(value2, fallback) {
|
|
|
166226
166975
|
if (/[-]/.test(value2)) return fallback;
|
|
166227
166976
|
return value2;
|
|
166228
166977
|
}
|
|
166229
|
-
var
|
|
166978
|
+
var WIX_API3, REDIRECT_SESSION_PATH, TOKEN_PATH, MEMBER_SESSION_COOKIE, MEMBER_SESSION_TTL_MS, PENDING_LOGIN_TTL_MS, MEMBER_CALLBACK_PATH;
|
|
166230
166979
|
var init_wix_member_auth = __esm({
|
|
166231
166980
|
"../../core/serve-runtime/src/wix-member-auth.ts"() {
|
|
166232
|
-
|
|
166981
|
+
WIX_API3 = "https://www.wixapis.com";
|
|
166233
166982
|
REDIRECT_SESSION_PATH = "/_api/redirects-api/v1/redirect-session";
|
|
166234
166983
|
TOKEN_PATH = "/oauth2/token";
|
|
166235
166984
|
MEMBER_SESSION_COOKIE = "himi_wm_sid";
|
|
@@ -168101,7 +168850,7 @@ __export(run_exports, {
|
|
|
168101
168850
|
runPackage: () => runPackage,
|
|
168102
168851
|
withoutProdServe: () => withoutProdServe
|
|
168103
168852
|
});
|
|
168104
|
-
import { cpSync as cpSync2, existsSync as
|
|
168853
|
+
import { cpSync as cpSync2, existsSync as existsSync84, mkdirSync as mkdirSync39, mkdtempSync as mkdtempSync7, readFileSync as readFileSync93, rmSync as rmSync23, statSync as statSync24 } from "node:fs";
|
|
168105
168854
|
import { networkInterfaces as osNetworkInterfaces, tmpdir as tmpdir8 } from "node:os";
|
|
168106
168855
|
import { dirname as dirname44, join as join89 } from "node:path";
|
|
168107
168856
|
import { fileURLToPath as fileURLToPath29 } from "node:url";
|
|
@@ -168131,9 +168880,9 @@ async function fetchBytes(url) {
|
|
|
168131
168880
|
}
|
|
168132
168881
|
async function resolvePackage(source, workDir) {
|
|
168133
168882
|
const isUrl2 = /^https?:\/\//i.test(source);
|
|
168134
|
-
if (!isUrl2 &&
|
|
168883
|
+
if (!isUrl2 && existsSync84(source) && statSync24(source).isDirectory()) {
|
|
168135
168884
|
const appDirManifest = join89(source, "release-manifest.json");
|
|
168136
|
-
if (
|
|
168885
|
+
if (existsSync84(appDirManifest)) {
|
|
168137
168886
|
const opened2 = openPackageDir(source);
|
|
168138
168887
|
if (!opened2.validation.ok) {
|
|
168139
168888
|
throw new Error(`package is not valid:
|
|
@@ -168191,7 +168940,7 @@ async function loadPreviewAssets() {
|
|
|
168191
168940
|
// in-repo checkout
|
|
168192
168941
|
];
|
|
168193
168942
|
for (const path2 of candidates) {
|
|
168194
|
-
if (!
|
|
168943
|
+
if (!existsSync84(path2)) continue;
|
|
168195
168944
|
const blob = readFileSync93(path2);
|
|
168196
168945
|
return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
168197
168946
|
}
|
|
@@ -168330,7 +169079,7 @@ __export(run_browser_exports, {
|
|
|
168330
169079
|
runInBrowser: () => runInBrowser
|
|
168331
169080
|
});
|
|
168332
169081
|
import { createServer as createServer6 } from "node:http";
|
|
168333
|
-
import { existsSync as
|
|
169082
|
+
import { existsSync as existsSync85, readFileSync as readFileSync94 } from "node:fs";
|
|
168334
169083
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
168335
169084
|
import { dirname as dirname45, resolve as resolve69 } from "node:path";
|
|
168336
169085
|
import { fileURLToPath as fileURLToPath30 } from "node:url";
|
|
@@ -168338,7 +169087,7 @@ function stagedDir() {
|
|
|
168338
169087
|
return process.env.HIMI_BROWSER_PLANE_OUT ? resolve69(process.env.HIMI_BROWSER_PLANE_OUT) : resolve69(REPO2, "packages", "serve", "dist", "browser-plane");
|
|
168339
169088
|
}
|
|
168340
169089
|
function missingStaged() {
|
|
168341
|
-
return [...SERVED].filter((f2) => !
|
|
169090
|
+
return [...SERVED].filter((f2) => !existsSync85(resolve69(stagedDir(), f2))).sort();
|
|
168342
169091
|
}
|
|
168343
169092
|
function ensureBrowserPlaneStaged() {
|
|
168344
169093
|
if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
|
|
@@ -168428,7 +169177,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
|
|
|
168428
169177
|
}
|
|
168429
169178
|
const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
|
|
168430
169179
|
if (SERVED.has(name)) {
|
|
168431
|
-
if (!
|
|
169180
|
+
if (!existsSync85(resolve69(stagedDir(), name))) {
|
|
168432
169181
|
const restaged = ensureBrowserPlaneStaged();
|
|
168433
169182
|
if (!restaged.ok) {
|
|
168434
169183
|
res.writeHead(503, { "content-type": "application/json" });
|
|
@@ -168491,14 +169240,14 @@ var hhp_preview_exports = {};
|
|
|
168491
169240
|
__export(hhp_preview_exports, {
|
|
168492
169241
|
hhpPreviewResponse: () => hhpPreviewResponse
|
|
168493
169242
|
});
|
|
168494
|
-
import { existsSync as
|
|
169243
|
+
import { existsSync as existsSync86, readFileSync as readFileSync95 } from "node:fs";
|
|
168495
169244
|
import { join as join90 } from "node:path";
|
|
168496
169245
|
function hhpPreviewResponse(root, request) {
|
|
168497
|
-
if (new URL(request.url).pathname !== "/__himi/hhp-preview" || !
|
|
169246
|
+
if (new URL(request.url).pathname !== "/__himi/hhp-preview" || !existsSync86(join90(root, "hhp.json"))) return null;
|
|
168498
169247
|
if (request.method !== "GET") return new Response(null, { status: 405 });
|
|
168499
169248
|
try {
|
|
168500
169249
|
const file2 = localPath(root, ".himi/hhp-preview.json");
|
|
168501
|
-
const authored2 =
|
|
169250
|
+
const authored2 = existsSync86(file2) ? JSON.parse(readFileSync95(file2, "utf8")) : {};
|
|
168502
169251
|
if (authored2.mockCapabilities && (!Array.isArray(authored2.mockCapabilities) || authored2.mockCapabilities.some((v2) => typeof v2 !== "string"))) throw new Error("mockCapabilities must be a string array.");
|
|
168503
169252
|
const fixtures = authored2.fixtures ?? {};
|
|
168504
169253
|
if (typeof fixtures !== "object" || Array.isArray(fixtures) || fixtures === null) throw new Error("fixtures must be an object.");
|
|
@@ -171195,7 +171944,7 @@ __export(credential_profile_exports, {
|
|
|
171195
171944
|
profilePath: () => profilePath,
|
|
171196
171945
|
resolveStoreCredentials: () => resolveStoreCredentials
|
|
171197
171946
|
});
|
|
171198
|
-
import { existsSync as
|
|
171947
|
+
import { existsSync as existsSync88, readFileSync as readFileSync101 } from "node:fs";
|
|
171199
171948
|
import { homedir as homedir11 } from "node:os";
|
|
171200
171949
|
import { join as join93 } from "node:path";
|
|
171201
171950
|
function credentialsDir(home = homedir11()) {
|
|
@@ -171239,7 +171988,7 @@ function resolveStoreCredentials(opts) {
|
|
|
171239
171988
|
const env = opts.env ?? process.env;
|
|
171240
171989
|
const home = opts.home ?? homedir11();
|
|
171241
171990
|
const read = opts.readProfile ?? ((p2) => readFileSync101(p2, "utf8"));
|
|
171242
|
-
const exists = opts.profileExists ??
|
|
171991
|
+
const exists = opts.profileExists ?? existsSync88;
|
|
171243
171992
|
const ios = cfg.ios ?? {};
|
|
171244
171993
|
const flagName = opts.profileFlag?.trim();
|
|
171245
171994
|
const named = namedProfile(cfg, opts.profileFlag);
|
|
@@ -171305,7 +172054,7 @@ var init_credential_profile = __esm({
|
|
|
171305
172054
|
|
|
171306
172055
|
// ../store-release/iap-credentials.ts
|
|
171307
172056
|
import { createHash as createHash45 } from "node:crypto";
|
|
171308
|
-
import { existsSync as
|
|
172057
|
+
import { existsSync as existsSync89, readFileSync as readFileSync102, realpathSync as realpathSync12 } from "node:fs";
|
|
171309
172058
|
import { homedir as homedir12 } from "node:os";
|
|
171310
172059
|
function accountFingerprint(keyId, issuerId) {
|
|
171311
172060
|
return `sha256:${createHash45("sha256").update(`${issuerId}:${keyId}`).digest("hex").slice(0, 16)}`;
|
|
@@ -171352,7 +172101,7 @@ function resolveIapCredentials(options) {
|
|
|
171352
172101
|
env: {},
|
|
171353
172102
|
home,
|
|
171354
172103
|
readProfile: readFile3,
|
|
171355
|
-
profileExists: options.exists ??
|
|
172104
|
+
profileExists: options.exists ?? existsSync89
|
|
171356
172105
|
});
|
|
171357
172106
|
assertCredentialOutsideRepo(`credential profile "${profile}"`, realpath(profilePath(profile, home)));
|
|
171358
172107
|
assertCredentialOutsideRepo(`credential profile "${profile}" ascKeyPath`, canonicalKeyPath(creds.ascKeyPath, profile, realpath));
|
|
@@ -171857,7 +172606,7 @@ var init_store_spec = __esm({
|
|
|
171857
172606
|
});
|
|
171858
172607
|
|
|
171859
172608
|
// src/iap-config-edit.ts
|
|
171860
|
-
import { existsSync as
|
|
172609
|
+
import { existsSync as existsSync90, readFileSync as readFileSync104 } from "node:fs";
|
|
171861
172610
|
import { basename as basename24, join as join94 } from "node:path";
|
|
171862
172611
|
import ts9 from "typescript";
|
|
171863
172612
|
function bindPurchasesAppInConfig(source, options) {
|
|
@@ -171938,7 +172687,7 @@ function capabilityFinding(app, fileName) {
|
|
|
171938
172687
|
function withStoreBundle(dir, options) {
|
|
171939
172688
|
if (options.storeBundleId) return options;
|
|
171940
172689
|
const path2 = join94(dir, "store", "store.config.yaml");
|
|
171941
|
-
if (!
|
|
172690
|
+
if (!existsSync90(path2)) return options;
|
|
171942
172691
|
const storeBundleId = parseStoreConfig(readFileSync104(path2, "utf8")).ios?.bundleId;
|
|
171943
172692
|
return storeBundleId ? { ...options, storeBundleId } : options;
|
|
171944
172693
|
}
|
|
@@ -172678,7 +173427,7 @@ var init_store_iap_screenshots = __esm({
|
|
|
172678
173427
|
});
|
|
172679
173428
|
|
|
172680
173429
|
// src/store-iap-screenshot-render.ts
|
|
172681
|
-
import { existsSync as
|
|
173430
|
+
import { existsSync as existsSync91, mkdtempSync as mkdtempSync9, readFileSync as readFileSync105, rmSync as rmSync25 } from "node:fs";
|
|
172682
173431
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
172683
173432
|
import { join as join96 } from "node:path";
|
|
172684
173433
|
function renderProblems(render, entityId) {
|
|
@@ -172741,7 +173490,7 @@ function createReviewScreenRenderer() {
|
|
|
172741
173490
|
async capture(html, contentDir2) {
|
|
172742
173491
|
const { pngPageHtml: pngPageHtml2, stabilizePngPage: stabilizePngPage2 } = await Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports));
|
|
172743
173492
|
const tokensPath = join96(contentDir2, "tokens.json");
|
|
172744
|
-
const tokens2 =
|
|
173493
|
+
const tokens2 = existsSync91(tokensPath) ? JSON.parse(readFileSync105(tokensPath, "utf8")) : null;
|
|
172745
173494
|
const { width, height, scale } = REVIEW_SCREENSHOT_FRAME;
|
|
172746
173495
|
const page = await (await (browser ??= launch())).newPage({ viewport: { width, height }, deviceScaleFactor: scale, colorScheme: "light" });
|
|
172747
173496
|
try {
|
|
@@ -172812,166 +173561,6 @@ var init_serve_preview = __esm({
|
|
|
172812
173561
|
}
|
|
172813
173562
|
});
|
|
172814
173563
|
|
|
172815
|
-
// src/site-analyze/rest.ts
|
|
172816
|
-
var rest_exports = {};
|
|
172817
|
-
__export(rest_exports, {
|
|
172818
|
-
WIX_API: () => WIX_API3,
|
|
172819
|
-
WixApiError: () => WixApiError2,
|
|
172820
|
-
classifyHttp: () => classifyHttp,
|
|
172821
|
-
compactWixstaticUrl: () => compactWixstaticUrl,
|
|
172822
|
-
isGenericWixFavicon: () => isGenericWixFavicon,
|
|
172823
|
-
makeTransport: () => makeTransport,
|
|
172824
|
-
mediaUrlFromLogo: () => mediaUrlFromLogo,
|
|
172825
|
-
ownerTransportFrom: () => ownerTransportFrom,
|
|
172826
|
-
probeCall: () => probeCall,
|
|
172827
|
-
resolveWixUrl: () => resolveWixUrl,
|
|
172828
|
-
uploadMediaBytes: () => uploadMediaBytes,
|
|
172829
|
-
visitorTransportFrom: () => visitorTransportFrom,
|
|
172830
|
-
wixMediaFileId: () => wixMediaFileId
|
|
172831
|
-
});
|
|
172832
|
-
function resolveWixUrl(path2) {
|
|
172833
|
-
if (/^https?:\/\//i.test(path2)) return path2;
|
|
172834
|
-
return `${WIX_API3}${path2}`;
|
|
172835
|
-
}
|
|
172836
|
-
function classifyHttp(status, count2) {
|
|
172837
|
-
if (status === 428) return "not-installed";
|
|
172838
|
-
if (status === 404) return "wrong-path";
|
|
172839
|
-
if (status && status >= 400) return "error";
|
|
172840
|
-
return count2 > 0 ? "ok" : "empty";
|
|
172841
|
-
}
|
|
172842
|
-
function makeTransport(fetchImpl, auth, timeoutMs = DEFAULT_TIMEOUT_MS3) {
|
|
172843
|
-
return async (method, path2, body) => {
|
|
172844
|
-
const headers2 = { Accept: "application/json" };
|
|
172845
|
-
if (auth?.token) headers2.Authorization = auth.token;
|
|
172846
|
-
if (auth?.msid) headers2["wix-site-id"] = auth.msid;
|
|
172847
|
-
if (body !== void 0) headers2["Content-Type"] = "application/json";
|
|
172848
|
-
const res = await fetchImpl(resolveWixUrl(path2), {
|
|
172849
|
-
method,
|
|
172850
|
-
headers: headers2,
|
|
172851
|
-
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
172852
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
172853
|
-
});
|
|
172854
|
-
const text11 = await res.text();
|
|
172855
|
-
let parsed = text11;
|
|
172856
|
-
try {
|
|
172857
|
-
parsed = text11 ? JSON.parse(text11) : null;
|
|
172858
|
-
} catch {
|
|
172859
|
-
}
|
|
172860
|
-
if (!res.ok) throw new WixApiError2(res.status, method, path2, parsed);
|
|
172861
|
-
return parsed;
|
|
172862
|
-
};
|
|
172863
|
-
}
|
|
172864
|
-
function ownerTransportFrom(fetchImpl, owner) {
|
|
172865
|
-
return makeTransport(fetchImpl, { token: owner.token, msid: owner.msid });
|
|
172866
|
-
}
|
|
172867
|
-
function visitorTransportFrom(fetchImpl, token, msid) {
|
|
172868
|
-
return makeTransport(fetchImpl, { token, msid });
|
|
172869
|
-
}
|
|
172870
|
-
async function probeCall(call, method, path2, body) {
|
|
172871
|
-
try {
|
|
172872
|
-
return { data: await call(method, path2, body), err: null };
|
|
172873
|
-
} catch (e2) {
|
|
172874
|
-
if (e2 instanceof WixApiError2) return { data: null, err: e2 };
|
|
172875
|
-
throw e2;
|
|
172876
|
-
}
|
|
172877
|
-
}
|
|
172878
|
-
function mediaUrlFromLogo(logo) {
|
|
172879
|
-
const s2 = (logo ?? "").trim();
|
|
172880
|
-
if (!s2) return null;
|
|
172881
|
-
if (/^https?:\/\//i.test(s2)) return s2;
|
|
172882
|
-
const id = s2.replace(/^wix:image:\/\/v1\//, "").split("/")[0].split("#")[0];
|
|
172883
|
-
if (!id) return null;
|
|
172884
|
-
if (/^https?:\/\//i.test(id)) return id;
|
|
172885
|
-
return `https://static.wixstatic.com/media/${id}`;
|
|
172886
|
-
}
|
|
172887
|
-
function isGenericWixFavicon(url) {
|
|
172888
|
-
try {
|
|
172889
|
-
const h2 = new URL(url).hostname.toLowerCase();
|
|
172890
|
-
return h2 === "wix.com" || h2.endsWith(".wix.com");
|
|
172891
|
-
} catch {
|
|
172892
|
-
return false;
|
|
172893
|
-
}
|
|
172894
|
-
}
|
|
172895
|
-
function wixMediaFileId(url) {
|
|
172896
|
-
const m2 = url.match(/static\.wixstatic\.com\/media\/([^/?#]+)/i);
|
|
172897
|
-
return m2?.[1] ? decodeURIComponent(m2[1]) : void 0;
|
|
172898
|
-
}
|
|
172899
|
-
function compactWixstaticUrl(url, maxEdge = 800) {
|
|
172900
|
-
if (!/static\.wixstatic\.com\/media\//i.test(url)) return url;
|
|
172901
|
-
if (/\.(svg|ico)(\?|#|$)/i.test(url.split("?")[0] ?? url)) return url;
|
|
172902
|
-
const w2 = url.match(/(?:\/|,)w_(\d+)/)?.[1];
|
|
172903
|
-
if (w2 && Number(w2) <= maxEdge) return url;
|
|
172904
|
-
const id = wixMediaFileId(url);
|
|
172905
|
-
if (!id) return url;
|
|
172906
|
-
return `https://static.wixstatic.com/media/${id}/v1/fill/w_${maxEdge},h_${maxEdge},al_c,q_80,enc_auto/file.jpg`;
|
|
172907
|
-
}
|
|
172908
|
-
async function uploadMediaBytes(call, fetchImpl, bytes2, fileName, mimeType) {
|
|
172909
|
-
const { uploadUrl } = await call(
|
|
172910
|
-
"POST",
|
|
172911
|
-
"/site-media/v1/files/generate-upload-url",
|
|
172912
|
-
{ mimeType, fileName: `himi-business-book/${fileName}` }
|
|
172913
|
-
);
|
|
172914
|
-
const put = await fetchImpl(`${uploadUrl}?filename=${encodeURIComponent(fileName)}`, {
|
|
172915
|
-
method: "PUT",
|
|
172916
|
-
headers: { "Content-Type": mimeType },
|
|
172917
|
-
body: bytes2,
|
|
172918
|
-
signal: AbortSignal.timeout(12e4)
|
|
172919
|
-
});
|
|
172920
|
-
if (!put.ok) throw new Error(`media upload PUT failed: ${put.status}`);
|
|
172921
|
-
const payload = await put.json();
|
|
172922
|
-
const file2 = payload.file ?? payload;
|
|
172923
|
-
const id = file2?.id ?? file2?.fileId;
|
|
172924
|
-
const url = file2?.url ?? (id ? `https://static.wixstatic.com/media/${id}` : void 0);
|
|
172925
|
-
if (!id || !url) throw new Error("media upload returned no file id");
|
|
172926
|
-
return { id, url };
|
|
172927
|
-
}
|
|
172928
|
-
var WIX_API3, DEFAULT_TIMEOUT_MS3, WixApiError2;
|
|
172929
|
-
var init_rest = __esm({
|
|
172930
|
-
"src/site-analyze/rest.ts"() {
|
|
172931
|
-
WIX_API3 = "https://www.wixapis.com";
|
|
172932
|
-
DEFAULT_TIMEOUT_MS3 = 8e3;
|
|
172933
|
-
WixApiError2 = class extends Error {
|
|
172934
|
-
constructor(status, method, path2, body) {
|
|
172935
|
-
super(`${method} ${path2} \u2192 ${status}`);
|
|
172936
|
-
this.status = status;
|
|
172937
|
-
this.method = method;
|
|
172938
|
-
this.path = path2;
|
|
172939
|
-
this.body = body;
|
|
172940
|
-
this.name = "WixApiError";
|
|
172941
|
-
}
|
|
172942
|
-
};
|
|
172943
|
-
}
|
|
172944
|
-
});
|
|
172945
|
-
|
|
172946
|
-
// src/site-analyze/visitor-auth.ts
|
|
172947
|
-
var visitor_auth_exports = {};
|
|
172948
|
-
__export(visitor_auth_exports, {
|
|
172949
|
-
mintVisitorToken: () => mintVisitorToken
|
|
172950
|
-
});
|
|
172951
|
-
async function mintVisitorToken(fetchImpl, clientId) {
|
|
172952
|
-
const res = await fetchImpl(`${WIX_API3}/oauth2/token`, {
|
|
172953
|
-
method: "POST",
|
|
172954
|
-
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
172955
|
-
body: JSON.stringify({ clientId, grantType: "anonymous" }),
|
|
172956
|
-
signal: AbortSignal.timeout(8e3)
|
|
172957
|
-
});
|
|
172958
|
-
const text11 = await res.text();
|
|
172959
|
-
let parsed = text11;
|
|
172960
|
-
try {
|
|
172961
|
-
parsed = text11 ? JSON.parse(text11) : null;
|
|
172962
|
-
} catch {
|
|
172963
|
-
}
|
|
172964
|
-
if (!res.ok) throw new WixApiError2(res.status, "POST", "/oauth2/token", parsed);
|
|
172965
|
-
const token = parsed?.access_token ?? parsed?.accessToken;
|
|
172966
|
-
if (!token) throw new Error("visitor mint returned no access_token");
|
|
172967
|
-
return token;
|
|
172968
|
-
}
|
|
172969
|
-
var init_visitor_auth = __esm({
|
|
172970
|
-
"src/site-analyze/visitor-auth.ts"() {
|
|
172971
|
-
init_rest();
|
|
172972
|
-
}
|
|
172973
|
-
});
|
|
172974
|
-
|
|
172975
173564
|
// src/store-iap.ts
|
|
172976
173565
|
var store_iap_exports = {};
|
|
172977
173566
|
__export(store_iap_exports, {
|
|
@@ -174183,7 +174772,7 @@ __export(preflight_app_exports, {
|
|
|
174183
174772
|
profileAccount: () => profileAccount,
|
|
174184
174773
|
readXcconfigVars: () => readXcconfigVars
|
|
174185
174774
|
});
|
|
174186
|
-
import { readFileSync as readFileSync107, existsSync as
|
|
174775
|
+
import { readFileSync as readFileSync107, existsSync as existsSync92, readdirSync as readdirSync38, statSync as statSync25 } from "node:fs";
|
|
174187
174776
|
import { createHash as createHash47 } from "node:crypto";
|
|
174188
174777
|
import { dirname as dirname48, join as join98 } from "node:path";
|
|
174189
174778
|
function analyze(projectYml, storeConfig, icon, account) {
|
|
@@ -174310,7 +174899,7 @@ function readXcconfigVars(iosDir, projectYml) {
|
|
|
174310
174899
|
const vars = {};
|
|
174311
174900
|
const seen = /* @__PURE__ */ new Set();
|
|
174312
174901
|
const read = (path2) => {
|
|
174313
|
-
if (seen.has(path2) || !
|
|
174902
|
+
if (seen.has(path2) || !existsSync92(path2)) return;
|
|
174314
174903
|
seen.add(path2);
|
|
174315
174904
|
for (const raw of readFileSync107(path2, "utf8").split("\n")) {
|
|
174316
174905
|
const inc = /^\s*#include\??\s+"([^"]+)"/.exec(raw);
|
|
@@ -174339,8 +174928,8 @@ function profileAccount(app, storeConfig, opts = {}) {
|
|
|
174339
174928
|
}
|
|
174340
174929
|
}
|
|
174341
174930
|
async function preflightApp(app, opts = {}) {
|
|
174342
|
-
const projectYml =
|
|
174343
|
-
const storeConfig =
|
|
174931
|
+
const projectYml = existsSync92(iosProjectYml(app)) ? readFileSync107(iosProjectYml(app), "utf8") : "";
|
|
174932
|
+
const storeConfig = existsSync92(storeConfigPath(app)) ? readFileSync107(storeConfigPath(app), "utf8") : "";
|
|
174344
174933
|
const identity = projectYml ? analyzeStoreIdentity(projectYml, storeConfig, readXcconfigVars(join98(appDir(app), "ios"), projectYml)) : [];
|
|
174345
174934
|
if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }, ...identity];
|
|
174346
174935
|
const findings = analyze(
|
|
@@ -174378,15 +174967,15 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
|
|
|
174378
174967
|
function appLevelMetadataFiles(app, locale = "en-US") {
|
|
174379
174968
|
const root = join98(storeDir(app), "metadata");
|
|
174380
174969
|
const out2 = /* @__PURE__ */ new Set();
|
|
174381
|
-
if (
|
|
174970
|
+
if (existsSync92(root)) {
|
|
174382
174971
|
for (const n2 of readdirSync38(root)) if (n2.endsWith(".txt")) out2.add(n2);
|
|
174383
174972
|
}
|
|
174384
|
-
if (
|
|
174973
|
+
if (existsSync92(join98(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
|
|
174385
174974
|
return out2;
|
|
174386
174975
|
}
|
|
174387
174976
|
function reviewInfoFiles(app) {
|
|
174388
174977
|
const dir = join98(storeDir(app), "review_information");
|
|
174389
|
-
if (!
|
|
174978
|
+
if (!existsSync92(dir)) return /* @__PURE__ */ new Set();
|
|
174390
174979
|
return new Set(readdirSync38(dir).filter((n2) => n2.endsWith(".txt")));
|
|
174391
174980
|
}
|
|
174392
174981
|
function isValidAppStoreSize(w2, h2) {
|
|
@@ -174533,20 +175122,20 @@ function analyzeListing(metaFiles, shots) {
|
|
|
174533
175122
|
}
|
|
174534
175123
|
function metadataFilesPresent(app, locale = "en-US") {
|
|
174535
175124
|
const dir = join98(storeDir(app), "metadata", locale);
|
|
174536
|
-
if (!
|
|
175125
|
+
if (!existsSync92(dir)) return /* @__PURE__ */ new Set();
|
|
174537
175126
|
return new Set(readdirSync38(dir).filter((n2) => n2.endsWith(".txt")));
|
|
174538
175127
|
}
|
|
174539
175128
|
function listScreenshots(app, locale = "en-US") {
|
|
174540
175129
|
const out2 = [];
|
|
174541
175130
|
const flat = join98(storeDir(app), "screenshots", locale);
|
|
174542
|
-
if (
|
|
175131
|
+
if (existsSync92(flat)) {
|
|
174543
175132
|
for (const png of readdirSync38(flat).filter((n2) => n2.endsWith(".png"))) {
|
|
174544
175133
|
const sz = pngSize2(readFileSync107(join98(flat, png)));
|
|
174545
175134
|
if (sz) out2.push({ name: png, w: sz.w, h: sz.h });
|
|
174546
175135
|
}
|
|
174547
175136
|
}
|
|
174548
175137
|
const legacy = join98(storeDir(app), "metadata", locale, "screenshots");
|
|
174549
|
-
if (
|
|
175138
|
+
if (existsSync92(legacy)) {
|
|
174550
175139
|
for (const deviceDir of readdirSync38(legacy)) {
|
|
174551
175140
|
const d2 = join98(legacy, deviceDir);
|
|
174552
175141
|
if (!statSync25(d2).isDirectory()) continue;
|
|
@@ -174560,7 +175149,7 @@ function listScreenshots(app, locale = "en-US") {
|
|
|
174560
175149
|
}
|
|
174561
175150
|
function placeholderHashes2() {
|
|
174562
175151
|
const templateIos = join98(appDir("_template"), "ios");
|
|
174563
|
-
if (!
|
|
175152
|
+
if (!existsSync92(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
|
|
174564
175153
|
for (const target of readdirSync38(templateIos)) {
|
|
174565
175154
|
const p2 = join98(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
174566
175155
|
try {
|
|
@@ -174596,7 +175185,7 @@ async function pixelIssues(bytes2) {
|
|
|
174596
175185
|
}
|
|
174597
175186
|
}
|
|
174598
175187
|
async function appIconState(iosDir) {
|
|
174599
|
-
if (!
|
|
175188
|
+
if (!existsSync92(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
|
|
174600
175189
|
for (const target of readdirSync38(iosDir)) {
|
|
174601
175190
|
const p2 = join98(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
|
|
174602
175191
|
try {
|
|
@@ -174732,6 +175321,19 @@ var init_asc_status = __esm({
|
|
|
174732
175321
|
}
|
|
174733
175322
|
});
|
|
174734
175323
|
|
|
175324
|
+
// ../../core/serve-control/src/captcha-bindable.ts
|
|
175325
|
+
var captcha_bindable_exports = {};
|
|
175326
|
+
__export(captcha_bindable_exports, {
|
|
175327
|
+
captchaBindable: () => captchaBindable
|
|
175328
|
+
});
|
|
175329
|
+
function captchaBindable(shell, externalContract) {
|
|
175330
|
+
return !externalContract && ["branded-lite", "owner-lite"].includes(shell);
|
|
175331
|
+
}
|
|
175332
|
+
var init_captcha_bindable = __esm({
|
|
175333
|
+
"../../core/serve-control/src/captcha-bindable.ts"() {
|
|
175334
|
+
}
|
|
175335
|
+
});
|
|
175336
|
+
|
|
174735
175337
|
// src/browser-login.ts
|
|
174736
175338
|
import { createServer as createServer7 } from "node:http";
|
|
174737
175339
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
@@ -175663,7 +176265,7 @@ function headers(session) {
|
|
|
175663
176265
|
...session ? { "X-Admin-Session": session } : {}
|
|
175664
176266
|
};
|
|
175665
176267
|
}
|
|
175666
|
-
function
|
|
176268
|
+
function truncate3(token) {
|
|
175667
176269
|
return token.length <= 20 ? token : `${token.slice(0, 8)}\u2026${token.slice(-8)}`;
|
|
175668
176270
|
}
|
|
175669
176271
|
function parseDataFlag(raw) {
|
|
@@ -175789,7 +176391,7 @@ async function runNotify(pos, flags, io2, deps = {}) {
|
|
|
175789
176391
|
const bits = [
|
|
175790
176392
|
String(t2.id).padStart(4),
|
|
175791
176393
|
t2.platform.padEnd(8),
|
|
175792
|
-
|
|
176394
|
+
truncate3(t2.token).padEnd(19),
|
|
175793
176395
|
(t2.environment ?? "-").padEnd(11),
|
|
175794
176396
|
(t2.appVersion ?? "-").padEnd(10),
|
|
175795
176397
|
t2.lastSeen,
|
|
@@ -176001,7 +176603,7 @@ __export(base44_adopt_exports, {
|
|
|
176001
176603
|
renderAdoptModule: () => renderAdoptModule,
|
|
176002
176604
|
runBase44Adopt: () => runBase44Adopt
|
|
176003
176605
|
});
|
|
176004
|
-
import { existsSync as
|
|
176606
|
+
import { existsSync as existsSync96, readFileSync as readFileSync114, writeFileSync as writeFileSync38 } from "node:fs";
|
|
176005
176607
|
import { join as join104, resolve as resolve74 } from "node:path";
|
|
176006
176608
|
function prop(entity, key3) {
|
|
176007
176609
|
const props = entity.schema?.properties;
|
|
@@ -176110,7 +176712,7 @@ function runBase44Adopt(opts) {
|
|
|
176110
176712
|
const issues = validateBase44Entities({ entities: result.entities, functions: result.functions }, opts.app);
|
|
176111
176713
|
if (opts.write === void 0 || opts.write === false || issues.some((i2) => i2.severity === "error")) return { result, module, issues };
|
|
176112
176714
|
const target = typeof opts.write === "string" ? resolve74(opts.cwd, opts.write) : join104(opts.cwd, ADOPT_MODULE_FILENAME);
|
|
176113
|
-
if (
|
|
176715
|
+
if (existsSync96(target)) {
|
|
176114
176716
|
throw new AdoptError("adopt_target_exists", `${target} already exists \u2014 adopt never overwrites. Delete or rename it, or pass --write <other path>.`, 1, { path: target });
|
|
176115
176717
|
}
|
|
176116
176718
|
writeFileSync38(target, module);
|
|
@@ -176359,7 +176961,7 @@ __export(generate_exports, {
|
|
|
176359
176961
|
writeGenerated: () => writeGenerated
|
|
176360
176962
|
});
|
|
176361
176963
|
import { createHash as createHash50 } from "node:crypto";
|
|
176362
|
-
import { existsSync as
|
|
176964
|
+
import { existsSync as existsSync97, mkdirSync as mkdirSync42, readdirSync as readdirSync39, readFileSync as readFileSync115, writeFileSync as writeFileSync39 } from "node:fs";
|
|
176363
176965
|
import { dirname as dirname51, join as join105 } from "node:path";
|
|
176364
176966
|
function withHeader(body) {
|
|
176365
176967
|
return `${GENERATED_HEADER}${sha2566(body)}
|
|
@@ -176486,7 +177088,7 @@ function writeGenerated(dir, files, opts = {}) {
|
|
|
176486
177088
|
const abs = join105(dir, f2.path);
|
|
176487
177089
|
const next = withHeader(f2.body);
|
|
176488
177090
|
let outcome;
|
|
176489
|
-
if (!
|
|
177091
|
+
if (!existsSync97(abs)) outcome = "written";
|
|
176490
177092
|
else {
|
|
176491
177093
|
const cur = readFileSync115(abs, "utf8");
|
|
176492
177094
|
if (cur === next) outcome = "unchanged";
|
|
@@ -176505,14 +177107,14 @@ function orphanedFiles(dir, current) {
|
|
|
176505
177107
|
const keep = new Set(current.map((f2) => f2.path));
|
|
176506
177108
|
const found = [];
|
|
176507
177109
|
const t5 = join105(dir, "tier5-src");
|
|
176508
|
-
if (!
|
|
177110
|
+
if (!existsSync97(t5)) return found;
|
|
176509
177111
|
const candidates = readdirSync39(t5).filter((d2) => d2.startsWith("b44-")).map((d2) => `tier5-src/${d2}/index.ts`);
|
|
176510
177112
|
const shared = join105(t5, "_shared");
|
|
176511
|
-
if (
|
|
177113
|
+
if (existsSync97(shared)) {
|
|
176512
177114
|
for (const f2 of readdirSync39(shared)) if (/^b44-.*-plan\.ts$/.test(f2)) candidates.push(`tier5-src/_shared/${f2}`);
|
|
176513
177115
|
}
|
|
176514
177116
|
for (const rel of candidates.sort()) {
|
|
176515
|
-
if (keep.has(rel) || !
|
|
177117
|
+
if (keep.has(rel) || !existsSync97(join105(dir, rel))) continue;
|
|
176516
177118
|
if (readFileSync115(join105(dir, rel), "utf8").startsWith(GENERATED_HEADER)) found.push(rel);
|
|
176517
177119
|
}
|
|
176518
177120
|
return found;
|
|
@@ -176551,7 +177153,7 @@ __export(base44_auth_exports, {
|
|
|
176551
177153
|
usableBase44Auth: () => usableBase44Auth,
|
|
176552
177154
|
writeBase44Session: () => writeBase44Session
|
|
176553
177155
|
});
|
|
176554
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
177156
|
+
import { chmodSync as chmodSync4, existsSync as existsSync98, mkdirSync as mkdirSync43, readFileSync as readFileSync116, rmSync as rmSync27, writeFileSync as writeFileSync40 } from "node:fs";
|
|
176555
177157
|
import { homedir as homedir15 } from "node:os";
|
|
176556
177158
|
import { dirname as dirname52, join as join106 } from "node:path";
|
|
176557
177159
|
function base44ApiBase(env = process.env) {
|
|
@@ -176562,7 +177164,7 @@ function base44SessionPath(home = homedir15()) {
|
|
|
176562
177164
|
}
|
|
176563
177165
|
function readBase44Session(home) {
|
|
176564
177166
|
const p2 = base44SessionPath(home);
|
|
176565
|
-
if (!
|
|
177167
|
+
if (!existsSync98(p2)) return void 0;
|
|
176566
177168
|
try {
|
|
176567
177169
|
const s2 = JSON.parse(readFileSync116(p2, "utf8"));
|
|
176568
177170
|
return typeof s2.accessToken === "string" && s2.accessToken ? s2 : void 0;
|
|
@@ -176580,7 +177182,7 @@ function writeBase44Session(session, home) {
|
|
|
176580
177182
|
}
|
|
176581
177183
|
function deleteBase44Session(home) {
|
|
176582
177184
|
const p2 = base44SessionPath(home);
|
|
176583
|
-
if (!
|
|
177185
|
+
if (!existsSync98(p2)) return false;
|
|
176584
177186
|
rmSync27(p2, { force: true });
|
|
176585
177187
|
return true;
|
|
176586
177188
|
}
|
|
@@ -176683,7 +177285,7 @@ function hasBase44WriteScope(auth) {
|
|
|
176683
177285
|
}
|
|
176684
177286
|
function importBase44CliSession(home = homedir15(), env = process.env) {
|
|
176685
177287
|
const src = join106(home, ".base44", "auth", "auth.json");
|
|
176686
|
-
if (!
|
|
177288
|
+
if (!existsSync98(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
|
|
176687
177289
|
const a2 = JSON.parse(readFileSync116(src, "utf8"));
|
|
176688
177290
|
if (typeof a2.accessToken !== "string" || !a2.accessToken) throw new Error(`${src} holds no access token`);
|
|
176689
177291
|
const session = {
|
|
@@ -176781,11 +177383,11 @@ __export(seed_exports, {
|
|
|
176781
177383
|
seedBase44Entities: () => seedBase44Entities,
|
|
176782
177384
|
writeBase44SeedRows: () => writeBase44SeedRows
|
|
176783
177385
|
});
|
|
176784
|
-
import { existsSync as
|
|
177386
|
+
import { existsSync as existsSync99, readFileSync as readFileSync117, writeFileSync as writeFileSync41 } from "node:fs";
|
|
176785
177387
|
import { join as join107 } from "node:path";
|
|
176786
177388
|
function readBase44SeedFile(dir) {
|
|
176787
177389
|
const file2 = join107(dir, BASE44_SEED_FILE);
|
|
176788
|
-
if (!
|
|
177390
|
+
if (!existsSync99(file2)) return {};
|
|
176789
177391
|
let parsed;
|
|
176790
177392
|
try {
|
|
176791
177393
|
parsed = JSON.parse(readFileSync117(file2, "utf8"));
|
|
@@ -176945,7 +177547,7 @@ function writeBase44SeedRows(opts) {
|
|
|
176945
177547
|
return { ok: false, path: path2, entities: {}, agentPrompt: "", next: [], note: opts.only ? `--only ${opts.only.join(",")} matched no owned entity` : `no owned Base44 entities declared \u2014 add one with \`name\` (physically ${base44Prefix(app)}<Name>). Adopted entities are never seeded.` };
|
|
176946
177548
|
}
|
|
176947
177549
|
let existing = {};
|
|
176948
|
-
if (
|
|
177550
|
+
if (existsSync99(path2)) {
|
|
176949
177551
|
let parsed;
|
|
176950
177552
|
try {
|
|
176951
177553
|
parsed = JSON.parse(readFileSync117(path2, "utf8"));
|
|
@@ -177300,7 +177902,7 @@ __export(functions_exports2, {
|
|
|
177300
177902
|
markerContent: () => markerContent,
|
|
177301
177903
|
readFunctionSource: () => readFunctionSource
|
|
177302
177904
|
});
|
|
177303
|
-
import { existsSync as
|
|
177905
|
+
import { existsSync as existsSync100, lstatSync as lstatSync22 } from "node:fs";
|
|
177304
177906
|
import { join as join108 } from "node:path";
|
|
177305
177907
|
function markerContent(app) {
|
|
177306
177908
|
return `${JSON.stringify({ app, by: "himi" })}
|
|
@@ -177309,7 +177911,7 @@ function markerContent(app) {
|
|
|
177309
177911
|
function readFunctionSource(appDir3, name, app) {
|
|
177310
177912
|
const rel = `base44/functions/${name}/`;
|
|
177311
177913
|
const folder = join108(appDir3, "base44", "functions", name);
|
|
177312
|
-
if (!
|
|
177914
|
+
if (!existsSync100(folder) || !lstatSync22(folder).isDirectory()) throw new FunctionSourceError("function_source_missing", `no source folder at ${rel}`);
|
|
177313
177915
|
const { entries, skipped } = collectAppSource(folder);
|
|
177314
177916
|
if (skipped.length) throw new FunctionSourceError("function_source_unsafe", `${rel} holds paths himi will not upload (symlinks or denied names): ${skipped.join(", ")} \u2014 remove them`);
|
|
177315
177917
|
const secrets = secretFindings(entries);
|
|
@@ -177464,9 +178066,9 @@ function propsOf2(schema) {
|
|
|
177464
178066
|
function isOwnedPhysical(name, app) {
|
|
177465
178067
|
return name.startsWith(base44Prefix(app));
|
|
177466
178068
|
}
|
|
177467
|
-
function foreignGuard(
|
|
178069
|
+
function foreignGuard(snapshot3, next, owned) {
|
|
177468
178070
|
const out2 = [];
|
|
177469
|
-
for (const e2 of
|
|
178071
|
+
for (const e2 of snapshot3) {
|
|
177470
178072
|
if (owned.has(e2.name)) continue;
|
|
177471
178073
|
if (!Object.prototype.hasOwnProperty.call(next, e2.name)) {
|
|
177472
178074
|
out2.push({ code: "would_delete_foreign_entity", entity: e2.name, detail: `"${e2.name}" is not himi's and would be left out of the full-set sync \u2014 Base44 would delete it and its rows` });
|
|
@@ -177503,20 +178105,20 @@ function inheritUndeclaredPermissions(desired, remote, spec) {
|
|
|
177503
178105
|
if (f2.rls === void 0 && remoteProps[f2.key]?.rls !== void 0) desiredProps[f2.key].rls = remoteProps[f2.key].rls;
|
|
177504
178106
|
}
|
|
177505
178107
|
}
|
|
177506
|
-
function planEntitySync(declared,
|
|
178108
|
+
function planEntitySync(declared, snapshot3, opts) {
|
|
177507
178109
|
const { app, allowDestructive = false, applyPermissions = false, emptyAppOk = false } = opts;
|
|
177508
178110
|
const plan = { next: {}, actions: [], refusals: [], warnings: [], owned: [] };
|
|
177509
|
-
if (
|
|
178111
|
+
if (snapshot3.length === 0 && !emptyAppOk) {
|
|
177510
178112
|
plan.refusals.push({ code: "schema_snapshot_empty", detail: "the project download holds no entity schemas \u2014 if the Base44 app really has no entities, pass --empty-app-ok" });
|
|
177511
178113
|
}
|
|
177512
178114
|
const specs = declared.filter((s2) => !!s2 && typeof s2 === "object");
|
|
177513
178115
|
const owned = new Map(specs.filter(isOwnedEntity).map((s2) => [physicalEntityName(s2, app), s2]));
|
|
177514
178116
|
const adopted = new Set(specs.filter(isAdoptedEntity).map((s2) => physicalEntityName(s2, app)));
|
|
177515
|
-
const live3 = new Map(
|
|
178117
|
+
const live3 = new Map(snapshot3.map((e2) => [e2.name, e2]));
|
|
177516
178118
|
const provisioned = new Set((opts.provisioned ?? []).filter((n2) => isOwnedPhysical(n2, app)));
|
|
177517
|
-
const ownedHere = /* @__PURE__ */ new Set([...
|
|
178119
|
+
const ownedHere = /* @__PURE__ */ new Set([...snapshot3.map((e2) => e2.name).filter((n2) => provisioned.has(n2)), ...[...owned.keys()].filter((n2) => !live3.has(n2))]);
|
|
177518
178120
|
plan.owned = [...ownedHere].sort();
|
|
177519
|
-
for (const e2 of
|
|
178121
|
+
for (const e2 of snapshot3) {
|
|
177520
178122
|
if (!ownedHere.has(e2.name)) {
|
|
177521
178123
|
plan.next[e2.name] = e2.schema;
|
|
177522
178124
|
if (owned.has(e2.name)) {
|
|
@@ -177580,7 +178182,7 @@ function planEntitySync(declared, snapshot2, opts) {
|
|
|
177580
178182
|
for (const name of adopted) {
|
|
177581
178183
|
if (!live3.has(name)) plan.warnings.push(`adopted entity "${name}" is not on the live app \u2014 himi never creates an entity it does not own`);
|
|
177582
178184
|
}
|
|
177583
|
-
plan.refusals.push(...foreignGuard(
|
|
178185
|
+
plan.refusals.push(...foreignGuard(snapshot3, plan.next, ownedHere));
|
|
177584
178186
|
return plan;
|
|
177585
178187
|
}
|
|
177586
178188
|
var BUILTINS2;
|
|
@@ -177647,12 +178249,12 @@ __export(apply_exports, {
|
|
|
177647
178249
|
createBase44Entities: () => createBase44Entities,
|
|
177648
178250
|
fileLedger: () => fileLedger
|
|
177649
178251
|
});
|
|
177650
|
-
import { existsSync as
|
|
178252
|
+
import { existsSync as existsSync101, readFileSync as readFileSync118, writeFileSync as writeFileSync42 } from "node:fs";
|
|
177651
178253
|
import { join as join109 } from "node:path";
|
|
177652
178254
|
function fileLedger(dir, appId2) {
|
|
177653
178255
|
const path2 = join109(dir, LEDGER_FILE2);
|
|
177654
178256
|
const load3 = () => {
|
|
177655
|
-
if (!
|
|
178257
|
+
if (!existsSync101(path2)) return {};
|
|
177656
178258
|
let v2;
|
|
177657
178259
|
try {
|
|
177658
178260
|
v2 = JSON.parse(readFileSync118(path2, "utf8"));
|
|
@@ -180697,7 +181299,7 @@ var init_analyze = __esm({
|
|
|
180697
181299
|
});
|
|
180698
181300
|
|
|
180699
181301
|
// src/base44-analyze/write-artifacts.ts
|
|
180700
|
-
import { existsSync as
|
|
181302
|
+
import { existsSync as existsSync102, mkdirSync as mkdirSync45, readFileSync as readFileSync119, rmSync as rmSync29, writeFileSync as writeFileSync44 } from "node:fs";
|
|
180701
181303
|
import { dirname as dirname53, join as join111, resolve as resolve75, sep as sep20 } from "node:path";
|
|
180702
181304
|
function isBookFolder(dir) {
|
|
180703
181305
|
try {
|
|
@@ -180788,7 +181390,7 @@ function writeBase44Book(result, outDir, opts = {}) {
|
|
|
180788
181390
|
const md = renderBookMd(book);
|
|
180789
181391
|
assertNoSecrets(json8);
|
|
180790
181392
|
assertNoSecrets(md);
|
|
180791
|
-
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) =>
|
|
181393
|
+
const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync102(join111(out2, n2)));
|
|
180792
181394
|
if (owned.length) {
|
|
180793
181395
|
if (!isBookFolder(out2)) throw new Error(`refusing to write the app book into ${out2}: it already has ${owned.join(", ")} that ${owned.length === 1 ? "is" : "are"} not from an app book \u2014 pick an empty --out`);
|
|
180794
181396
|
for (const d2 of ["source", "screenshots"]) rmSync29(join111(out2, d2), { recursive: true, force: true });
|
|
@@ -184864,11 +185466,11 @@ async function collectOneApp(input, deps = {}) {
|
|
|
184864
185466
|
const enriched = {};
|
|
184865
185467
|
const contextWarnings = [];
|
|
184866
185468
|
for (const [index, platform] of ["ios", "android"].entries()) {
|
|
184867
|
-
const
|
|
184868
|
-
if (
|
|
184869
|
-
enriched[platform] =
|
|
185469
|
+
const snapshot3 = snapshots[index];
|
|
185470
|
+
if (snapshot3.status === "fulfilled") {
|
|
185471
|
+
enriched[platform] = snapshot3.value;
|
|
184870
185472
|
} else {
|
|
184871
|
-
const error =
|
|
185473
|
+
const error = snapshot3.reason;
|
|
184872
185474
|
if (!(error instanceof OneAppError) || ![
|
|
184873
185475
|
"source_not_found",
|
|
184874
185476
|
"source_request_failed",
|
|
@@ -187349,7 +187951,7 @@ var init_customer_build = __esm({
|
|
|
187349
187951
|
});
|
|
187350
187952
|
|
|
187351
187953
|
// src/site-analyze/apply.ts
|
|
187352
|
-
import { existsSync as
|
|
187954
|
+
import { existsSync as existsSync104, readFileSync as readFileSync121, writeFileSync as writeFileSync47, copyFileSync as copyFileSync2, mkdirSync as mkdirSync48, realpathSync as realpathSync15, statSync as statSync27 } from "node:fs";
|
|
187353
187955
|
import { dirname as dirname55, isAbsolute as isAbsolute9, join as join115, resolve as resolve79, sep as sep21 } from "node:path";
|
|
187354
187956
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
187355
187957
|
function unpairedRedirectNote(overlay) {
|
|
@@ -187365,7 +187967,7 @@ function committedShellProvisioning(path2) {
|
|
|
187365
187967
|
function findRepoRoot(cwd) {
|
|
187366
187968
|
let dir = cwd;
|
|
187367
187969
|
for (let i2 = 0; i2 < 8; i2++) {
|
|
187368
|
-
if (SHELL_NAMES.some((name) =>
|
|
187970
|
+
if (SHELL_NAMES.some((name) => existsSync104(join115(dir, shellAppDir(name), "package.json")))) return dir;
|
|
187369
187971
|
const next = dirname55(dir);
|
|
187370
187972
|
if (next === dir) break;
|
|
187371
187973
|
dir = next;
|
|
@@ -187469,7 +188071,7 @@ function sameKnownSite(previous, next) {
|
|
|
187469
188071
|
function buildMergedContract(options) {
|
|
187470
188072
|
const { appDir: appDir3, packageDir, overlay } = options;
|
|
187471
188073
|
const committedPath = join115(appDir3, "provisioning.json");
|
|
187472
|
-
if (!
|
|
188074
|
+
if (!existsSync104(committedPath)) {
|
|
187473
188075
|
throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
|
|
187474
188076
|
}
|
|
187475
188077
|
const committed = JSON.parse(readFileSync121(committedPath, "utf8"));
|
|
@@ -187485,7 +188087,7 @@ function buildMergedContract(options) {
|
|
|
187485
188087
|
const stage = (fromRel, toRel) => {
|
|
187486
188088
|
const from = contained(packageDir, fromRel);
|
|
187487
188089
|
const to2 = contained(join115(appDir3, STAGED), toRel.slice(STAGED.length + 1));
|
|
187488
|
-
if (!from || !to2 || !
|
|
188090
|
+
if (!from || !to2 || !existsSync104(from)) return void 0;
|
|
187489
188091
|
let real;
|
|
187490
188092
|
let realRoot;
|
|
187491
188093
|
try {
|
|
@@ -187508,7 +188110,7 @@ function buildMergedContract(options) {
|
|
|
187508
188110
|
const icon = stage("media/icon.png", `${STAGED}/icon.png`);
|
|
187509
188111
|
if (icon) branding.appIconPath = icon;
|
|
187510
188112
|
const facesPath = join115(packageDir, "media/fonts/faces.json");
|
|
187511
|
-
if (
|
|
188113
|
+
if (existsSync104(facesPath)) {
|
|
187512
188114
|
let faces = [];
|
|
187513
188115
|
try {
|
|
187514
188116
|
const parsed = JSON.parse(readFileSync121(facesPath, "utf8"));
|
|
@@ -187570,7 +188172,7 @@ function staticFaqFor(overlay, overlayPath) {
|
|
|
187570
188172
|
const own6 = overlay.faq;
|
|
187571
188173
|
if (own6 !== void 0) return deriveStaticFaq(own6);
|
|
187572
188174
|
const bookPath = join115(dirname55(resolve79(overlayPath)), "book.json");
|
|
187573
|
-
if (!
|
|
188175
|
+
if (!existsSync104(bookPath)) return void 0;
|
|
187574
188176
|
try {
|
|
187575
188177
|
const book = JSON.parse(readFileSync121(bookPath, "utf8"));
|
|
187576
188178
|
const copy = book?.copy;
|
|
@@ -187587,7 +188189,7 @@ function staticGalleriesFor(overlay, overlayPath) {
|
|
|
187587
188189
|
overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
|
|
187588
188190
|
);
|
|
187589
188191
|
const bookPath = join115(dirname55(resolve79(overlayPath)), "book.json");
|
|
187590
|
-
if (!
|
|
188192
|
+
if (!existsSync104(bookPath)) return void 0;
|
|
187591
188193
|
try {
|
|
187592
188194
|
const book = JSON.parse(readFileSync121(bookPath, "utf8"));
|
|
187593
188195
|
if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
|
|
@@ -187621,7 +188223,7 @@ async function applyOverlays(input) {
|
|
|
187621
188223
|
}
|
|
187622
188224
|
const appDir3 = join115(repoRoot2, shellAppDir(shell));
|
|
187623
188225
|
const committedPath = join115(appDir3, "provisioning.json");
|
|
187624
|
-
const committedSite =
|
|
188226
|
+
const committedSite = existsSync104(committedPath) ? JSON.parse(readFileSync121(committedPath, "utf8")).site : void 0;
|
|
187625
188227
|
if (committedSite !== void 0 && overlay.site === void 0) {
|
|
187626
188228
|
throw new Error(
|
|
187627
188229
|
`shell "${shell}" is a site shell: its contract names the customer's website (a \`site\` block), and this overlay has none. Re-run \`himi site analyze --url <site> --shell ${shell}\` to derive the site's page map (edit \`site.pages\` in provisioning.overlay.json if needed), then --apply.`
|
|
@@ -187662,7 +188264,7 @@ async function applyOverlays(input) {
|
|
|
187662
188264
|
};
|
|
187663
188265
|
let packageFaq = faq;
|
|
187664
188266
|
let packageGalleries = galleries;
|
|
187665
|
-
if (
|
|
188267
|
+
if (existsSync104(pkgProv)) {
|
|
187666
188268
|
const cur = JSON.parse(readFileSync121(pkgProv, "utf8"));
|
|
187667
188269
|
if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
|
|
187668
188270
|
const merged = deepMerge4(cur, overlay);
|
|
@@ -187680,7 +188282,7 @@ async function applyOverlays(input) {
|
|
|
187680
188282
|
overlay.installedVerticals.push("galleries");
|
|
187681
188283
|
}
|
|
187682
188284
|
const pkgTokens = join115(cwd, "tokens.json");
|
|
187683
|
-
if (
|
|
188285
|
+
if (existsSync104(pkgTokens) && (tokens2.colors || tokens2.typography)) {
|
|
187684
188286
|
const cur = JSON.parse(readFileSync121(pkgTokens, "utf8"));
|
|
187685
188287
|
let tokensIn = tokens2;
|
|
187686
188288
|
if (tokens2.typography) {
|
|
@@ -187707,7 +188309,7 @@ async function applyOverlays(input) {
|
|
|
187707
188309
|
}
|
|
187708
188310
|
const homeAction = homeRefreshActionId(shell);
|
|
187709
188311
|
const homeSrc = join115(cwd, "dev/index.ts");
|
|
187710
|
-
if (homeAction &&
|
|
188312
|
+
if (homeAction && existsSync104(homeSrc)) {
|
|
187711
188313
|
const prev = readFileSync121(homeSrc, "utf8");
|
|
187712
188314
|
const patched = patchBrandParams(prev, overlay, homeAction);
|
|
187713
188315
|
let next = patched.src;
|
|
@@ -187743,13 +188345,13 @@ async function applyOverlays(input) {
|
|
|
187743
188345
|
notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
|
|
187744
188346
|
}
|
|
187745
188347
|
}
|
|
187746
|
-
if (!input.iconPath || !
|
|
188348
|
+
if (!input.iconPath || !existsSync104(input.iconPath)) {
|
|
187747
188349
|
const book = input.iconPath ? dirname55(dirname55(resolve79(input.iconPath))) : void 0;
|
|
187748
188350
|
notes.push(
|
|
187749
188351
|
book ? `no icon installed \u2014 ${siteLogoAbsence(book).hint}` : "no icon installed and no business book to say why \u2014 `himi icon generate` draws one from the accent, or `himi icon set <file.png>` installs the customer's own mark"
|
|
187750
188352
|
);
|
|
187751
188353
|
}
|
|
187752
|
-
if (input.iconPath &&
|
|
188354
|
+
if (input.iconPath && existsSync104(input.iconPath)) {
|
|
187753
188355
|
try {
|
|
187754
188356
|
const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
|
|
187755
188357
|
wrote.push(...installed.wrote);
|
|
@@ -188708,7 +189310,7 @@ __export(cli_exports3, {
|
|
|
188708
189310
|
runSiteAnalyze: () => runSiteAnalyze,
|
|
188709
189311
|
runSiteFunctionCli: () => runSiteFunctionCli
|
|
188710
189312
|
});
|
|
188711
|
-
import { existsSync as
|
|
189313
|
+
import { existsSync as existsSync105, readFileSync as readFileSync122 } from "node:fs";
|
|
188712
189314
|
import { resolve as resolve80 } from "node:path";
|
|
188713
189315
|
function applyNeedsClient(shell) {
|
|
188714
189316
|
if (shell === void 0 || !SHELL_NAMES.includes(shell)) return true;
|
|
@@ -188776,7 +189378,7 @@ async function runSiteAnalyze(opts) {
|
|
|
188776
189378
|
if (book?.skipped) result.warnings = [...result.warnings ?? [], book.skipped];
|
|
188777
189379
|
const derived = deriveSiteShell({ siteUrl: result.book.input.siteUrl, look: result.book.look, kind, routes });
|
|
188778
189380
|
const prevOverlayPath = resolve80(outDir, "provisioning.overlay.json");
|
|
188779
|
-
const prevSite =
|
|
189381
|
+
const prevSite = existsSync105(prevOverlayPath) ? (() => {
|
|
188780
189382
|
try {
|
|
188781
189383
|
return JSON.parse(readFileSync122(prevOverlayPath, "utf8")).site;
|
|
188782
189384
|
} catch {
|
|
@@ -188797,7 +189399,7 @@ async function runSiteAnalyze(opts) {
|
|
|
188797
189399
|
}
|
|
188798
189400
|
const previousOverlay = resolve80(outDir, "provisioning.overlay.json");
|
|
188799
189401
|
carryOverGoals(
|
|
188800
|
-
|
|
189402
|
+
existsSync105(previousOverlay) ? readFileSync122(previousOverlay, "utf8") : void 0,
|
|
188801
189403
|
result.provisioningOverlay
|
|
188802
189404
|
);
|
|
188803
189405
|
const ownerCall = ownerAuth ? ownerTransportFrom(fetchImpl, ownerAuth) : void 0;
|
|
@@ -188883,7 +189485,7 @@ async function runSiteFunctionCli(opts) {
|
|
|
188883
189485
|
});
|
|
188884
189486
|
}
|
|
188885
189487
|
function base44BookRoutes(bookPath, siteUrl) {
|
|
188886
|
-
if (!
|
|
189488
|
+
if (!existsSync105(bookPath)) return void 0;
|
|
188887
189489
|
try {
|
|
188888
189490
|
const book = JSON.parse(readFileSync122(bookPath, "utf8"));
|
|
188889
189491
|
if (book.kind !== "base44-app-book" || !Array.isArray(book.routes)) return void 0;
|
|
@@ -189140,7 +189742,7 @@ __export(site_create_exports, {
|
|
|
189140
189742
|
runSiteList: () => runSiteList,
|
|
189141
189743
|
writeProvisioningBinding: () => writeProvisioningBinding
|
|
189142
189744
|
});
|
|
189143
|
-
import { existsSync as
|
|
189745
|
+
import { existsSync as existsSync106, readFileSync as readFileSync123, writeFileSync as writeFileSync48 } from "node:fs";
|
|
189144
189746
|
import { resolve as resolvePath2 } from "node:path";
|
|
189145
189747
|
function oauthClientName(projectName) {
|
|
189146
189748
|
return `${projectName} client`;
|
|
@@ -189289,7 +189891,7 @@ async function runSiteCreate(opts) {
|
|
|
189289
189891
|
if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
|
|
189290
189892
|
return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
|
|
189291
189893
|
}
|
|
189292
|
-
function writeProvisioningBinding(target, binding2, fs2 = { existsSync:
|
|
189894
|
+
function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync106, readFileSync: readFileSync123, writeFileSync: writeFileSync48 }) {
|
|
189293
189895
|
const msid = binding2.siteId;
|
|
189294
189896
|
const path2 = resolvePath2(target);
|
|
189295
189897
|
const committed = committedShellProvisioning(path2);
|
|
@@ -190068,7 +190670,7 @@ __export(capture_exports, {
|
|
|
190068
190670
|
nativeNotConfigured: () => nativeNotConfigured,
|
|
190069
190671
|
variantWidth: () => variantWidth
|
|
190070
190672
|
});
|
|
190071
|
-
import { existsSync as
|
|
190673
|
+
import { existsSync as existsSync107, mkdirSync as mkdirSync49, rmSync as rmSync31, writeFileSync as writeFileSync49 } from "node:fs";
|
|
190072
190674
|
import { join as join116 } from "node:path";
|
|
190073
190675
|
import { pathToFileURL as pathToFileURL8 } from "node:url";
|
|
190074
190676
|
function variantWidth(variant) {
|
|
@@ -190081,7 +190683,7 @@ function frameFile(outDir, screen, variant, surface) {
|
|
|
190081
190683
|
async function captureMockup(root, screen, entry, variant, outDir, session) {
|
|
190082
190684
|
if (!entry.mockup) throw new MockupMissingError(`screen ${screen} declares no mockup in hhp.json`);
|
|
190083
190685
|
const file2 = localPath(root, entry.mockup);
|
|
190084
|
-
if (!
|
|
190686
|
+
if (!existsSync107(file2)) throw new MockupMissingError(`screen ${screen}: mockup ${entry.mockup} does not exist`);
|
|
190085
190687
|
const own6 = session ?? new MockupSession();
|
|
190086
190688
|
try {
|
|
190087
190689
|
const png = await own6.shoot(file2, variant);
|
|
@@ -190389,8 +190991,8 @@ var init_score = __esm({
|
|
|
190389
190991
|
});
|
|
190390
190992
|
|
|
190391
190993
|
// ../visual-proof/evidence.mjs
|
|
190392
|
-
import { existsSync as
|
|
190393
|
-
function resolveCaptionFont({ exists =
|
|
190994
|
+
import { existsSync as existsSync108, rmSync as rmSync34 } from "node:fs";
|
|
190995
|
+
function resolveCaptionFont({ exists = existsSync108, env = process.env } = {}) {
|
|
190394
190996
|
if (env?.VISUAL_PROOF_FONT) return env.VISUAL_PROOF_FONT;
|
|
190395
190997
|
return CAPTION_FONT_CANDIDATES.find((p2) => exists(p2)) ?? null;
|
|
190396
190998
|
}
|
|
@@ -190643,7 +191245,7 @@ __export(fidelity_exports, {
|
|
|
190643
191245
|
himalayaRepoRoot: () => himalayaRepoRoot
|
|
190644
191246
|
});
|
|
190645
191247
|
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
190646
|
-
import { existsSync as
|
|
191248
|
+
import { existsSync as existsSync109, realpathSync as realpathSync16 } from "node:fs";
|
|
190647
191249
|
import { join as join121, relative as relative19, sep as sep22 } from "node:path";
|
|
190648
191250
|
function himalayaRepoRoot(dir) {
|
|
190649
191251
|
let top;
|
|
@@ -190652,7 +191254,7 @@ function himalayaRepoRoot(dir) {
|
|
|
190652
191254
|
} catch {
|
|
190653
191255
|
return null;
|
|
190654
191256
|
}
|
|
190655
|
-
if (!
|
|
191257
|
+
if (!existsSync109(join121(top, "tools/judges/fidelity/JUDGE.md"))) return null;
|
|
190656
191258
|
const rel = relative19(realpathSync16(top), realpathSync16(dir));
|
|
190657
191259
|
return rel.startsWith(`..${sep22}`) || rel === ".." ? null : top;
|
|
190658
191260
|
}
|
|
@@ -190662,7 +191264,7 @@ function fidelityEnvelope(report3) {
|
|
|
190662
191264
|
async function fidelityCommand(ctx) {
|
|
190663
191265
|
const { io: io2, flags, print } = ctx;
|
|
190664
191266
|
const dir = contentDir(flags);
|
|
190665
|
-
if (!
|
|
191267
|
+
if (!existsSync109(dir)) {
|
|
190666
191268
|
io2.error(failure("fidelity_bad_flag", `content dir ${dir} does not exist`));
|
|
190667
191269
|
return 2;
|
|
190668
191270
|
}
|
|
@@ -190836,8 +191438,11 @@ var ServeCliClient = class {
|
|
|
190836
191438
|
fetchTokens(app, release2) {
|
|
190837
191439
|
return this.request("serve", "GET", `/v1/tokens?app=${encodeURIComponent(app)}${this.pinQ(release2)}`);
|
|
190838
191440
|
}
|
|
190839
|
-
|
|
190840
|
-
|
|
191441
|
+
/** A pinned non-live [release] on a deployed plane needs [previewToken] (see `fetchScreen`). */
|
|
191442
|
+
fetchAppConfig(app, release2, previewToken) {
|
|
191443
|
+
return this.request("serve", "GET", `/v1/app-config/${encodeURIComponent(app)}${release2 ? `?release=${encodeURIComponent(release2)}` : ""}`, {
|
|
191444
|
+
...previewToken ? { headers: { "x-himalaya-preview-token": previewToken } } : {}
|
|
191445
|
+
});
|
|
190841
191446
|
}
|
|
190842
191447
|
fetchBundle(app, hash2) {
|
|
190843
191448
|
return this.request("serve", "GET", `/v1/bundles/${hash2}.bundle.js?app=${encodeURIComponent(app)}`);
|
|
@@ -191378,7 +191983,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
191378
191983
|
"empty-app-ok",
|
|
191379
191984
|
"aab",
|
|
191380
191985
|
"managed",
|
|
191381
|
-
"source-hash"
|
|
191986
|
+
"source-hash",
|
|
191987
|
+
"skip-captcha-check"
|
|
191382
191988
|
]);
|
|
191383
191989
|
var SWITCH_FLAGS = new Set([...BOOLEAN_FLAGS].filter((name) => name !== "deep"));
|
|
191384
191990
|
var SWITCH_CONSEQUENCE = {
|
|
@@ -192288,7 +192894,7 @@ var COMMANDS = [
|
|
|
192288
192894
|
{ name: "patch", summary: 'change ONE item of a published app \u2014 a screen descriptor, a Tier-5 bundle, tokens, or the app-config baseline \u2014 from a RAW FILE, with no content package and no build. The low-level door: it does not lint your package, because there is no package here; `himi push --only <selector>` is the same edit with the full build + lint gate and is what to reach for when the package is in hand. Derives a new release from the app\'s current LIVE release, or from `--from-release <id>`. An explicit `--draft` or `--live` is REQUIRED \u2014 a patch has no default blast radius \u2014 and `--notes` is required with `--live` on a screen or app-config patch, because off-repo `gitSha` is "dev" and the ledger notes are then the only durable record of bytes that correspond to no commit. A branch does not merge: activating one derived from an older release reverts every item the patch does not move, so that case is refused until `--accept-regressions`. A bundle patch must repoint a screen (`--for-screen`) or the bytes land under a manifest key nothing reads. It cannot ADD a screen (screens are git-only, RFC 0012), never claims a slug \u2014 the app must already be published \u2014 and carries no attestation, source archive, assets, icon or minBinaryVersion, each named in the output.', required: "screen <id> --file <descriptor.json> [--bundle <sha256|none>] | bundle --file <bundle.js> (--for-screen <id>[,<id>] | --no-rebind) | tokens --file <tokens.json> | app-config --file <app-config.json> ; (--draft|--live) --app <a> [--from-release <id>] [--accept-regressions] [--label <n>] [--notes <t>] [--force] [--allow-binary-gap] [--target <t>] (--control-token)" },
|
|
192289
192895
|
{ name: "flags", summary: "read and change the app's OPERATIONAL flags (RFC 0013) \u2014 `list` prints what the DEVICE door serves, `set <key> --definition` creates or replaces one, `ramp <key>` moves its rollout share or kills it, `rm <key>` deletes it and echoes the definition back so the removal is reversible. Every write is followed by a read of the same door the device uses, and the answer is reported as `servedNow`: flags are stored in the app's git-committed flags.json, so a control plane with no checkout accepts a write it will never serve.", required: "list|set|ramp|rm [<key>] [--definition <json|@file>] [--percent 0-100] [--enabled true|false] [--app <a>] (--control-token)" },
|
|
192290
192896
|
{ name: "visibility", summary: "read (no value) or set whether the public registry (/v1/apps + the Himi Player picker) LISTS the app. `public` lists it for everyone; `unlisted` hides it from listings while direct reads by app id \u2014 deep links, previews \u2014 keep working. App from --app or the content dir. Setting it needs no republish.", required: "[public|unlisted] [--app <a>] [--content <dir>] (--control-token)" },
|
|
192291
|
-
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | brandy | base44 | player | demo-app) and defaults to the content package's himalaya.content.json `shell` (templates carry the one they were written for), else branded-lite. The per-app shells ADD the release's declared capabilities to the binary, while Himi Player and demo-app refuse a release declaring one they lack; `--plan` previews it without building; `brandy` is the site shell \u2014 the customer's own website as native-framed tabs. `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo --site <id>` reuses an existing customer ad-hoc profile and certificate for iOS; requires an owned site and a completed personal signing binding. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). `--aab` builds an Android App Bundle (.aab) for the owner to upload to Google Play AND an APK from the same build \u2014 a download link for the .aab, an install link and QR for the APK; Android only; the bundle is signed with the Wix production key (`wix-keystore`, the upload key Branded apps use) \u2014 any other `--android-signing` is refused \u2014 and the APK with the committed QA key; a self-serve caller gets one only as the store build of its own Containers app (it must own the app's site, and `--aab` sends your Wix login); any other self-serve `--aab` gets 403 android_format_not_allowed. NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|brandy|base44|player|demo-app] [--signing wix-managed|byo] [--site <id>] [--android-signing qa-keystore|wix-keystore|debug] [--aab] [--borrow-ios-id <bundleId>] [--no-wait] [--force] [--plan] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
192897
|
+
{ name: "dist", summary: "build an INSTALLABLE QA binary (signed IPA / APK) on the Wix Job Service Mac pool and return an install link \u2014 the serve plane brokers the job, the pool builds it. WAITS for the build by default (~4 min) and prints the install link; `--no-wait` returns a jobId immediately instead. Omitting `--release` builds whatever is LIVE for the app. A named draft is refused unless `--allow-draft` makes that exceptional build explicit. `status <jobId>` / `watch <jobId>` / `list --app <a>` / `cancel <jobId>` inspect and stop builds (`watch` reports up front whether the job mints its own signing identity or borrows one, so a doomed iOS build is cancellable in seconds rather than after the archive). Off-repo, name a target \u2014 `--target wix` for a self-serve Wix login or `--target bo` for the internal employee path (the in-repo default is a local dev plane that isn't reachable off-repo); self-serve callers may build their OWN apps under a tighter budget (2 in flight / 5 per 24h), while a manage-only owner-role credential is refused. `--shell` picks the native host to sign into (branded-lite | owner-lite | brandy | base44 | player | demo-app) and defaults to the content package's himalaya.content.json `shell` (templates carry the one they were written for), else branded-lite. The per-app shells ADD the release's declared capabilities to the binary, while Himi Player and demo-app refuse a release declaring one they lack; `--plan` previews it without building; `brandy` is the site shell \u2014 the customer's own website as native-framed tabs. `--signing` defaults to `wix-managed` \u2014 the Wix Apple account mints a per-app signing identity for the build, so the caller provisions no Apple credentials of their own; `--signing byo --site <id>` reuses an existing customer ad-hoc profile and certificate for iOS; requires an owned site and a completed personal signing binding. `--android-signing` is the Android counterpart and a SEPARATE axis (a keystore, not an Apple account): `qa-keystore` (default \u2014 the repo's committed QA key, identical on every pool machine, so a build installs over the previous one), `wix-keystore` (the Wix key the pool machine carries; the build FAILS naming the paths searched if it carries none, rather than quietly signing with something else), or `debug` (the old per-machine key \u2014 QA must uninstall any previous build first). `--aab` builds an Android App Bundle (.aab) for the owner to upload to Google Play AND an APK from the same build \u2014 a download link for the .aab, an install link and QR for the APK; Android only; the bundle is signed with the Wix production key (`wix-keystore`, the upload key Branded apps use) \u2014 any other `--android-signing` is refused \u2014 and the APK with the committed QA key; a self-serve caller gets one only as the store build of its own Containers app (it must own the app's site, and `--aab` sends your Wix login); any other self-serve `--aab` gets 403 android_format_not_allowed. NOT the normal way to ship: screens, Tier-5 bundles, tokens and app-config all go over the air with `himi push` in seconds \u2014 a binary trip is only needed for a NATIVE delta (a new SDUI component, a new declared capability/entitlement, a new bundle id, or a minBinaryVersion floor bump). Refuses to build an app whose launcher icon is missing, a placeholder, or one a store would reject \u2014 the one thing a binary carries that no later OTA push can fix; `--force` builds anyway. Also refuses a release whose member login (WixConsumerAuthProvider) names no siteId, or not in lower case, when Wix says its site requires a member CAPTCHA \u2014 such a binary ships without the CAPTCHA key and every member sign-in fails; whatever it cannot read (the release, the site's setting) only warns and builds; `--skip-captcha-check` builds anyway", required: "[--app <a>] [--platform ios,android] [--release <id>] [--allow-draft] [--target <t>] [--shell branded-lite|owner-lite|brandy|base44|player|demo-app] [--signing wix-managed|byo] [--site <id>] [--android-signing qa-keystore|wix-keystore|debug] [--aab] [--borrow-ios-id <bundleId>] [--no-wait] [--force] [--skip-captcha-check] [--plan] | status <jobId> [--target <t>] | watch <jobId> [--target <t>] [--interval <ms>] | list --app <a> [--target <t>] | cancel <jobId> [--target <t>]" },
|
|
192292
192898
|
{ name: "testflight", summary: 'build, sign and upload an app to TestFlight (internal testers \u2014 no Beta App Review), then WAIT until App Store Connect finishes processing it. Sugar for `store upload --track testflight`. Prompts first: a build number is consumed permanently on a real Apple account and cannot be reused \u2014 `--yes` for CI, `--dry-run` to see the plan without touching anything. The wait is the real check, not a nicety: fastlane prints "Successfully uploaded" for a binary App Store Connect then rejects in processing, and a rejected binary leaves NO build record at all (the reason is emailed). Public App Store review is deliberately NOT automatable here \u2014 `--track appstore` is refused; use /submit-ios-app when you mean to go public', required: "<app> [--track testflight|internal] [--profile <name>] [--yes] [--dry-run] [--skip-build] [--no-wait] [--json]" },
|
|
192293
192899
|
{ name: "store", summary: "the App Store Connect group behind `testflight`. `preflight <app>` checks readiness offline (icon, entitlements, encryption flag, version, store.config ids, listing + review record); `upload <app>` is what `testflight` runs; `status <app>` reads live build + processing state. `--profile` selects WHICH App Store Connect account: an app built for a Wix customer ships under the CUSTOMER's Apple team (Apple guideline 4.2.6 forbids an app-generation service submitting on a client's behalf), declared per-app as ios.credentialProfile in store.config.yaml and resolved from ~/.himalaya/store-credentials/<name>.json \u2014 the .p8 itself never enters the repo. `iap draft|plan|apply|status|connect|screenshots|check|mappings` registers an app owner's digital products as in-app purchases (non-consumables, or consumable price tiers): draft reads the Wix catalog and writes the manifest, plan and status only read, apply is the one App Store mutation boundary, connect readies the Wix site to sell them (purchases app, In-App Purchase key, appleIAP provider, product mappings; --preview-tag routes only its Serve calls to a deploy preview), legacy screenshots --profile renders each product's purchase screen from the app (--content) as a bound iPhone shows it to a signed-in member and names the 1290\xD72796 PNG as the item's App Review screenshot, and none of them builds, signs or needs a checkout (`himi docs iap-products`) IAP provisioning defaults to Catalog; managed apply generates screenshots on the server with no local .p8 or profile fallback; --managed is optional and --profile selects legacy mode; --catalog-route or HIMI_IAP_CATALOG_ROUTE has no default.", required: "preflight <app> [--profile <n>] | upload <app> [--track <t>] [--profile <n>] [--yes] [--dry-run] | status <app> [--profile <n>] | iap draft --site <msid> " + IAP_CREDENTIAL_OPTIONS + " --apple-app <id> --bundle <id> --base-territory <t> --out <f> [--territories <a,b>] [--locale <l>] [--mode per-item|tiers] [--merge <f>] [--report <f>] [--json] | iap plan --manifest <f> " + IAP_CREDENTIAL_OPTIONS + " --out <f> [--json] | iap apply --plan <f> " + IAP_CREDENTIAL_OPTIONS + " --out <f> [--yes] [--limit <n>] [--no-submit] [--json] | iap status --manifest <f> " + IAP_CREDENTIAL_OPTIONS + " [--out <f>] [--json] | iap connect --manifest <f> [--profile <n>] [--catalog-route <prefix>] [--iap-key <AuthKey.p8> --iap-key-id <id>] [--content <dir>] [--preview-tag dp-<tag>] [--dry-run] [--yes] [--out <f>] [--json] | iap screenshots --manifest <f> --content <dir> --profile <n> [--out-dir <d>] [--only <id,\u2026>] [--force] [--dry-run] [--json] | iap check --manifest <f> --catalog-route <prefix> [--purchases-app <id>] [--content <dir>] [--plist <file>] [--visitor-client <id>] [--json] | iap mappings --site <msid> --purchases-app <id> --catalog-route <prefix> [--product <id> --active true|false --yes] [--json]" },
|
|
192294
192900
|
{ name: "guide", summary: "print the Himalaya overview + headless dev loop + available topics (offline)", required: "[--json]" },
|
|
@@ -192899,7 +193505,7 @@ async function hhpCommand(ctx) {
|
|
|
192899
193505
|
// src/commands/init.ts
|
|
192900
193506
|
init_scaffold();
|
|
192901
193507
|
init_store();
|
|
192902
|
-
import { existsSync as
|
|
193508
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
192903
193509
|
import { join as join44, resolve as resolve43 } from "node:path";
|
|
192904
193510
|
init_cli_shared();
|
|
192905
193511
|
async function adoptAtInit(dir) {
|
|
@@ -192926,7 +193532,7 @@ var NoBase44SlotError = class extends Error {
|
|
|
192926
193532
|
};
|
|
192927
193533
|
async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {}) {
|
|
192928
193534
|
const dir = resolve43(parentDir, name);
|
|
192929
|
-
if (
|
|
193535
|
+
if (existsSync46(join44(dir, "himalaya.content.json"))) {
|
|
192930
193536
|
throw new Error(`content package already exists at ${dir}`);
|
|
192931
193537
|
}
|
|
192932
193538
|
const r3 = await c2.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
|
|
@@ -193002,7 +193608,7 @@ async function initCommand(ctx) {
|
|
|
193002
193608
|
const owed = openApprovals2(readApprovals2(dir).events).length;
|
|
193003
193609
|
next.push(`carried the planning journal into the app (${carried.join(", ")}${owed ? `; ${owed} approval${owed === 1 ? "" : "s"} still owed` : ""}) \u2014 \`himi progress --brief\` there shows it`);
|
|
193004
193610
|
}
|
|
193005
|
-
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) =>
|
|
193611
|
+
const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync46(join44(parentDir, f2)));
|
|
193006
193612
|
if (planInParent.length) {
|
|
193007
193613
|
next.push(`${planInParent.join(" and ")} in ${parentDir} ${planInParent.length > 1 ? "are" : "is"} not the app's \u2014 if that is the approved plan, move it over the template's boilerplate in ${dir}`);
|
|
193008
193614
|
}
|
|
@@ -193069,7 +193675,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
|
|
|
193069
193675
|
}
|
|
193070
193676
|
|
|
193071
193677
|
// src/commands/template.ts
|
|
193072
|
-
import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync67, existsSync as
|
|
193678
|
+
import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync67, existsSync as existsSync58, rmSync as rmSync16 } from "node:fs";
|
|
193073
193679
|
import { createHash as createHash30 } from "node:crypto";
|
|
193074
193680
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
193075
193681
|
import { join as join57, resolve as resolve46, basename as basename15 } from "node:path";
|
|
@@ -193136,7 +193742,7 @@ async function cmsIssues(dir, app, strict, opts) {
|
|
|
193136
193742
|
// src/surface-lint.ts
|
|
193137
193743
|
init_car();
|
|
193138
193744
|
init_preview_surfaces();
|
|
193139
|
-
import { existsSync as
|
|
193745
|
+
import { existsSync as existsSync47, readFileSync as readFileSync55 } from "node:fs";
|
|
193140
193746
|
import { join as join45 } from "node:path";
|
|
193141
193747
|
var VALID_PLATFORM_KEYS2 = /* @__PURE__ */ new Set([
|
|
193142
193748
|
...PREVIEW_SURFACES.map((s2) => s2.platformKey).filter((k2) => k2 !== null),
|
|
@@ -193149,7 +193755,7 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
193149
193755
|
let platforms = {};
|
|
193150
193756
|
let envelopeUnreadable = false;
|
|
193151
193757
|
const p2 = join45(dir, "platforms.json");
|
|
193152
|
-
if (
|
|
193758
|
+
if (existsSync47(p2)) {
|
|
193153
193759
|
let raw;
|
|
193154
193760
|
try {
|
|
193155
193761
|
raw = JSON.parse(readFileSync55(p2, "utf8"));
|
|
@@ -193182,7 +193788,7 @@ function surfaceIssues(dir, surfaceNav, strict) {
|
|
|
193182
193788
|
}
|
|
193183
193789
|
if (envelopeUnreadable) return issues;
|
|
193184
193790
|
const configTs = join45(dir, "config.ts");
|
|
193185
|
-
if (
|
|
193791
|
+
if (existsSync47(configTs)) {
|
|
193186
193792
|
const declared = parseCarConfig(readFileSync55(configTs, "utf8")).category;
|
|
193187
193793
|
const inEnvelope = platforms.androidauto === true;
|
|
193188
193794
|
if (inEnvelope && !declared) {
|
|
@@ -193242,10 +193848,10 @@ async function fontIssues(dir, strict, opts = {}) {
|
|
|
193242
193848
|
}
|
|
193243
193849
|
|
|
193244
193850
|
// src/stores-api-lint.ts
|
|
193245
|
-
import { existsSync as
|
|
193851
|
+
import { existsSync as existsSync50, readdirSync as readdirSync26, readFileSync as readFileSync58 } from "node:fs";
|
|
193246
193852
|
import { join as join48 } from "node:path";
|
|
193247
193853
|
function storesV1Issues(contentDir2, strict) {
|
|
193248
|
-
const roots2 = [join48(contentDir2, "tier5-src"), join48(contentDir2, "dev")].filter(
|
|
193854
|
+
const roots2 = [join48(contentDir2, "tier5-src"), join48(contentDir2, "dev")].filter(existsSync50);
|
|
193249
193855
|
const files = [];
|
|
193250
193856
|
const visit = (dir) => {
|
|
193251
193857
|
for (const entry of readdirSync26(dir, { withFileTypes: true })) {
|
|
@@ -193518,7 +194124,7 @@ async function templateCommand(ctx) {
|
|
|
193518
194124
|
const result = { ...outcome.result, ...fromSpec };
|
|
193519
194125
|
const adoptDir = contentDir(flags);
|
|
193520
194126
|
const kept = flags["dry-run"] !== true && (outcome.code === 0 || outcome.result.forcedKeep === true);
|
|
193521
|
-
if (kept &&
|
|
194127
|
+
if (kept && existsSync58(join57(adoptDir, adoptBits.ADOPT_FILE))) {
|
|
193522
194128
|
try {
|
|
193523
194129
|
const inv = adoptBits.inspectApp(adoptDir);
|
|
193524
194130
|
adoptBits.writeInventory(adoptDir, inv, { companions: "if-missing" });
|
|
@@ -193903,16 +194509,16 @@ async function ejectCommand(ctx) {
|
|
|
193903
194509
|
// src/commands/validate.ts
|
|
193904
194510
|
init_wix_placeholders();
|
|
193905
194511
|
init_lint_report();
|
|
193906
|
-
import { readFileSync as readFileSync77, existsSync as
|
|
194512
|
+
import { readFileSync as readFileSync77, existsSync as existsSync67 } from "node:fs";
|
|
193907
194513
|
import { join as join69 } from "node:path";
|
|
193908
194514
|
init_token_lint();
|
|
193909
194515
|
|
|
193910
194516
|
// src/icon-lint.ts
|
|
193911
194517
|
init_icon2();
|
|
193912
|
-
import { existsSync as
|
|
194518
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
193913
194519
|
import { join as join60 } from "node:path";
|
|
193914
194520
|
async function iconIssues(dir, strict, opts = {}) {
|
|
193915
|
-
if (!
|
|
194521
|
+
if (!existsSync61(join60(dir, "himalaya.content.json"))) return [];
|
|
193916
194522
|
const status = await iconStatus(dir);
|
|
193917
194523
|
const issue2 = (severity, message2) => ({
|
|
193918
194524
|
screen: null,
|
|
@@ -193975,7 +194581,7 @@ async function nativeConfigAdvisories(app, configSource) {
|
|
|
193975
194581
|
const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
193976
194582
|
const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
|
|
193977
194583
|
const iosYmlPath = iosProjectYml2(app);
|
|
193978
|
-
const iosYml =
|
|
194584
|
+
const iosYml = existsSync67(iosYmlPath) ? readFileSync77(iosYmlPath, "utf8") : "";
|
|
193979
194585
|
let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
|
|
193980
194586
|
if (!optedIn) {
|
|
193981
194587
|
const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
|
|
@@ -194065,7 +194671,7 @@ import { readFileSync as readFileSync80 } from "node:fs";
|
|
|
194065
194671
|
|
|
194066
194672
|
// src/dpx.ts
|
|
194067
194673
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
194068
|
-
import { existsSync as
|
|
194674
|
+
import { existsSync as existsSync68, readFileSync as readFileSync78 } from "node:fs";
|
|
194069
194675
|
import { homedir as homedir9 } from "node:os";
|
|
194070
194676
|
import { join as join70 } from "node:path";
|
|
194071
194677
|
var BO_COOKIE = "WixBoAuthentication_1_19_0";
|
|
@@ -194093,7 +194699,7 @@ function dpxSessionTokenPath() {
|
|
|
194093
194699
|
var DPX_SESSION_PORT = 5151;
|
|
194094
194700
|
function dpxSessionPresent(path2 = dpxSessionTokenPath()) {
|
|
194095
194701
|
try {
|
|
194096
|
-
return
|
|
194702
|
+
return existsSync68(path2) && readFileSync78(path2, "utf8").trim().length > 0;
|
|
194097
194703
|
} catch {
|
|
194098
194704
|
return false;
|
|
194099
194705
|
}
|
|
@@ -194328,13 +194934,13 @@ async function mcpCommand(ctx) {
|
|
|
194328
194934
|
|
|
194329
194935
|
// src/commands/studio.ts
|
|
194330
194936
|
init_cli_shared();
|
|
194331
|
-
import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync30, existsSync as
|
|
194937
|
+
import { mkdirSync as mkdirSync36, writeFileSync as writeFileSync30, existsSync as existsSync71 } from "node:fs";
|
|
194332
194938
|
import { join as join74, resolve as resolve60, basename as basename19, dirname as dirname42 } from "node:path";
|
|
194333
194939
|
async function studioCommand(ctx) {
|
|
194334
194940
|
const { io: io2, pos, flags, print } = ctx;
|
|
194335
194941
|
const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
|
|
194336
194942
|
const dir = contentDir(flags);
|
|
194337
|
-
if (!
|
|
194943
|
+
if (!existsSync71(join74(dir, "himalaya.content.json"))) {
|
|
194338
194944
|
io2.error(JSON.stringify({ ok: false, error: "not_a_content_package", dir, hint: "run from the app directory (or pass --content <dir>) \u2014 the board reads that package's .himi/" }));
|
|
194339
194945
|
return 2;
|
|
194340
194946
|
}
|
|
@@ -194394,7 +195000,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
|
|
|
194394
195000
|
|
|
194395
195001
|
// src/commands/progress.ts
|
|
194396
195002
|
init_cli_shared();
|
|
194397
|
-
import { existsSync as
|
|
195003
|
+
import { existsSync as existsSync72 } from "node:fs";
|
|
194398
195004
|
import { join as join75 } from "node:path";
|
|
194399
195005
|
async function progressCommand2(ctx) {
|
|
194400
195006
|
const { io: io2, pos, flags, print } = ctx;
|
|
@@ -194418,7 +195024,7 @@ async function progressCommand2(ctx) {
|
|
|
194418
195024
|
} = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
194419
195025
|
const dir = contentDir(flags);
|
|
194420
195026
|
const journal2 = journalPath2(dir);
|
|
194421
|
-
const isContentPackage =
|
|
195027
|
+
const isContentPackage = existsSync72(join75(dir, "himalaya.content.json"));
|
|
194422
195028
|
const hint = isContentPackage ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
|
|
194423
195029
|
const message2 = pos.slice(1).join(" ").trim();
|
|
194424
195030
|
const approvalFlags = ["approve", "done", "drop"].filter((f2) => flags[f2] !== void 0);
|
|
@@ -194608,7 +195214,7 @@ init_himi_report();
|
|
|
194608
195214
|
init_attestation();
|
|
194609
195215
|
init_wix_placeholders();
|
|
194610
195216
|
init_lint_report();
|
|
194611
|
-
import { existsSync as
|
|
195217
|
+
import { existsSync as existsSync77, rmSync as rmSync21 } from "node:fs";
|
|
194612
195218
|
import { join as join81 } from "node:path";
|
|
194613
195219
|
init_crawl_layers();
|
|
194614
195220
|
init_cli_shared();
|
|
@@ -194631,7 +195237,7 @@ async function testCommand(ctx) {
|
|
|
194631
195237
|
const { io: io2, deps, pos, flags, print, serveBase } = ctx;
|
|
194632
195238
|
const dir = contentDir(flags);
|
|
194633
195239
|
const structuredOutput = flags.json === true || io2.isTTY !== true;
|
|
194634
|
-
if (
|
|
195240
|
+
if (existsSync77(join81(dir, "functions"))) {
|
|
194635
195241
|
const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
194636
195242
|
const loaded = await loadFunctionsApp2(dir);
|
|
194637
195243
|
const results = [];
|
|
@@ -195296,7 +195902,7 @@ async function iconsCommand(ctx) {
|
|
|
195296
195902
|
|
|
195297
195903
|
// src/commands/pull.ts
|
|
195298
195904
|
init_cli_shared();
|
|
195299
|
-
import { existsSync as
|
|
195905
|
+
import { existsSync as existsSync79, readdirSync as readdirSync35, statSync as statSync21 } from "node:fs";
|
|
195300
195906
|
import { join as join84, resolve as resolve63 } from "node:path";
|
|
195301
195907
|
async function pullCommand(ctx) {
|
|
195302
195908
|
const { io: io2, pos, flags, print, client: client2 } = ctx;
|
|
@@ -195314,7 +195920,7 @@ async function pullCommand(ctx) {
|
|
|
195314
195920
|
io2.error(JSON.stringify(linked));
|
|
195315
195921
|
return 1;
|
|
195316
195922
|
}
|
|
195317
|
-
if (
|
|
195923
|
+
if (existsSync79(dest)) {
|
|
195318
195924
|
if (!statSync21(dest).isDirectory()) {
|
|
195319
195925
|
io2.error(JSON.stringify({
|
|
195320
195926
|
error: `${dest} exists and is not a directory`,
|
|
@@ -195327,7 +195933,7 @@ async function pullCommand(ctx) {
|
|
|
195327
195933
|
io2.error(JSON.stringify({ error: `${dest} already exists and is not empty`, hint: "pass --force to write into it anyway (merging, and naming what it keeps), --replace to restore exactly what was archived, or --out/--name to land somewhere else" }));
|
|
195328
195934
|
return 1;
|
|
195329
195935
|
}
|
|
195330
|
-
if (replace && occupied && !
|
|
195936
|
+
if (replace && occupied && !existsSync79(join84(dest, "himalaya.content.json"))) {
|
|
195331
195937
|
io2.error(JSON.stringify({
|
|
195332
195938
|
error: `${dest} is not a content package \u2014 refusing to --replace it`,
|
|
195333
195939
|
hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
|
|
@@ -195408,7 +196014,7 @@ async function pullCommand(ctx) {
|
|
|
195408
196014
|
|
|
195409
196015
|
// src/commands/push.ts
|
|
195410
196016
|
import { createHash as createHash41 } from "node:crypto";
|
|
195411
|
-
import { existsSync as
|
|
196017
|
+
import { existsSync as existsSync82 } from "node:fs";
|
|
195412
196018
|
import { join as join87, relative as relative17 } from "node:path";
|
|
195413
196019
|
init_config();
|
|
195414
196020
|
init_release();
|
|
@@ -195576,7 +196182,7 @@ async function pushCommand(ctx) {
|
|
|
195576
196182
|
const payload = await loadReleaseFromDir(declared, out2);
|
|
195577
196183
|
const oneAppEvidence = join87(dir, ".himi", "one-app");
|
|
195578
196184
|
const oneAppCoverage = join87(dir, "ONE-APP-COVERAGE.json");
|
|
195579
|
-
const oneAppMarked =
|
|
196185
|
+
const oneAppMarked = existsSync82(join87(oneAppEvidence, "manifest.json")) || existsSync82(oneAppCoverage);
|
|
195580
196186
|
let oneAppCoverageCount = 0;
|
|
195581
196187
|
let oneAppCoverageReady = false;
|
|
195582
196188
|
let oneAppNativeProof;
|
|
@@ -196244,12 +196850,12 @@ async function packCommand(ctx) {
|
|
|
196244
196850
|
|
|
196245
196851
|
// src/commands/import.ts
|
|
196246
196852
|
init_cli_shared();
|
|
196247
|
-
import { existsSync as
|
|
196853
|
+
import { existsSync as existsSync83, readdirSync as readdirSync36, statSync as statSync23 } from "node:fs";
|
|
196248
196854
|
import { resolve as resolve67 } from "node:path";
|
|
196249
196855
|
function restoreDestinationIssue(dest, force) {
|
|
196250
196856
|
const link = symlinkDestinationIssue(dest);
|
|
196251
196857
|
if (link) return link;
|
|
196252
|
-
if (!
|
|
196858
|
+
if (!existsSync83(dest)) return null;
|
|
196253
196859
|
if (!statSync23(dest).isDirectory()) {
|
|
196254
196860
|
return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
|
|
196255
196861
|
}
|
|
@@ -197441,7 +198047,7 @@ async function promoteCommand(ctx) {
|
|
|
197441
198047
|
// src/commands/patch.ts
|
|
197442
198048
|
init_lint_report();
|
|
197443
198049
|
init_cli_shared();
|
|
197444
|
-
import { readFileSync as readFileSync98, existsSync as
|
|
198050
|
+
import { readFileSync as readFileSync98, existsSync as existsSync87 } from "node:fs";
|
|
197445
198051
|
import { createHash as createHash42 } from "node:crypto";
|
|
197446
198052
|
var PATCH_HELP = `himi patch \u2014 change ONE item of a published app, from a raw file, on a machine
|
|
197447
198053
|
that does not have the content package.
|
|
@@ -197520,7 +198126,7 @@ async function patchCommand(ctx) {
|
|
|
197520
198126
|
io2.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
|
|
197521
198127
|
return 2;
|
|
197522
198128
|
}
|
|
197523
|
-
if (!
|
|
198129
|
+
if (!existsSync87(file2)) {
|
|
197524
198130
|
io2.error(JSON.stringify({ error: `no such file: ${file2}` }));
|
|
197525
198131
|
return 2;
|
|
197526
198132
|
}
|
|
@@ -198081,7 +198687,7 @@ async function testflightCommand(ctx) {
|
|
|
198081
198687
|
}
|
|
198082
198688
|
|
|
198083
198689
|
// src/commands/dist.ts
|
|
198084
|
-
import { existsSync as
|
|
198690
|
+
import { existsSync as existsSync93 } from "node:fs";
|
|
198085
198691
|
import { join as join99 } from "node:path";
|
|
198086
198692
|
init_wix_owner();
|
|
198087
198693
|
init_cli_shared();
|
|
@@ -198121,7 +198727,7 @@ async function distCommand(ctx) {
|
|
|
198121
198727
|
const rememberLastDist = async (jobs2) => {
|
|
198122
198728
|
try {
|
|
198123
198729
|
const dir = contentDir(flags);
|
|
198124
|
-
if (!
|
|
198730
|
+
if (!existsSync93(join99(dir, "himalaya.content.json"))) return;
|
|
198125
198731
|
const { lastDistFromJob: lastDistFromJob2, writeLastDist: writeLastDist2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
|
|
198126
198732
|
const own6 = await appId(dir);
|
|
198127
198733
|
for (const job of jobs2) {
|
|
@@ -198365,9 +198971,35 @@ ${label3}`);
|
|
|
198365
198971
|
return 0;
|
|
198366
198972
|
}
|
|
198367
198973
|
const platform = str3(flags.platform)?.split(",").map((p2) => p2.trim()).filter(Boolean);
|
|
198974
|
+
const { captchaContentInput: captchaContentInput2, captchaDistGate: captchaDistGate2 } = await Promise.resolve().then(() => (init_captcha2(), captcha_exports));
|
|
198975
|
+
const captchaSiteId = str3(flags.site) ?? (await appId(contentDir(flags)) === app ? captchaContentInput2(contentDir(flags)).siteId : void 0);
|
|
198976
|
+
const { captchaBindable: captchaBindable2 } = await Promise.resolve().then(() => (init_captcha_bindable(), captcha_bindable_exports));
|
|
198977
|
+
const { DEFAULT_DIST_SHELL: DEFAULT_DIST_SHELL2 } = await Promise.resolve().then(() => (init_dist_jobs(), dist_jobs_exports));
|
|
198978
|
+
if (flags.force !== true && flags["skip-captcha-check"] !== true && captchaBindable2(distShell ?? DEFAULT_DIST_SHELL2, false)) {
|
|
198979
|
+
const verdict = await captchaDistGate2({
|
|
198980
|
+
client: c2,
|
|
198981
|
+
app,
|
|
198982
|
+
release: str3(flags.release),
|
|
198983
|
+
requestedSite: captchaSiteId,
|
|
198984
|
+
// The plane's own default when --platform is absent: Android (iOS for a customer TestFlight build).
|
|
198985
|
+
platforms: platform?.length ? platform : str3(flags.destination) === "testflight" ? ["ios"] : ["android"]
|
|
198986
|
+
});
|
|
198987
|
+
if (verdict.refuse) {
|
|
198988
|
+
print({
|
|
198989
|
+
ok: false,
|
|
198990
|
+
code: verdict.refuse.code,
|
|
198991
|
+
error: verdict.refuse.code,
|
|
198992
|
+
message: verdict.refuse.message,
|
|
198993
|
+
captchaPolicy: verdict.refuse.captchaPolicy,
|
|
198994
|
+
hint: "fix config.ts and `himi push`, then build that release: `himi dist --release <its id> --allow-draft` (a draft), or promote it first \u2014 or `himi dist --skip-captcha-check` to build without the member CAPTCHA key"
|
|
198995
|
+
});
|
|
198996
|
+
return 1;
|
|
198997
|
+
}
|
|
198998
|
+
if (verdict.advisory) (flags.json === true ? io2.error : io2.log)(`\u26A0 ${verdict.advisory}`);
|
|
198999
|
+
}
|
|
198368
199000
|
{
|
|
198369
199001
|
const distDir = contentDir(flags);
|
|
198370
|
-
if (
|
|
199002
|
+
if (existsSync93(join99(distDir, "himalaya.content.json"))) {
|
|
198371
199003
|
const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
|
|
198372
199004
|
const errors = issues.filter((i2) => i2.severity === "error");
|
|
198373
199005
|
for (const i2 of issues.filter((i3) => i3.severity === "warning")) {
|
|
@@ -198384,8 +199016,6 @@ ${label3}`);
|
|
|
198384
199016
|
}
|
|
198385
199017
|
}
|
|
198386
199018
|
}
|
|
198387
|
-
const { captchaContentInput: captchaContentInput2 } = await Promise.resolve().then(() => (init_captcha2(), captcha_exports));
|
|
198388
|
-
const captchaSiteId = str3(flags.site) ?? captchaContentInput2(contentDir(flags)).siteId;
|
|
198389
199019
|
let wixAuthorization;
|
|
198390
199020
|
const customerTestflight = str3(flags.signing)?.trim().toLowerCase() === "byo" && str3(flags.destination) === "testflight";
|
|
198391
199021
|
if (str3(flags.signing)?.trim().toLowerCase() === "byo") {
|
|
@@ -199377,7 +200007,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
|
|
|
199377
200007
|
// src/commands/guide.ts
|
|
199378
200008
|
init_guides();
|
|
199379
200009
|
init_cli_shared();
|
|
199380
|
-
import { existsSync as
|
|
200010
|
+
import { existsSync as existsSync94 } from "node:fs";
|
|
199381
200011
|
import { join as join101, resolve as resolve72 } from "node:path";
|
|
199382
200012
|
async function runGuideCommand(command, pos, flags, io2, print) {
|
|
199383
200013
|
const { referenceCache: referenceCache2, referenceIdentity: referenceIdentity2 } = await Promise.resolve().then(() => (init_guides(), guides_exports));
|
|
@@ -199605,7 +200235,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
|
|
|
199605
200235
|
...res.removed.length ? { removed: res.removed, note: "older copies at the app root, moved to .himi/legacy-agent-files/ (a backup, in case one became app code) \u2014 the current ones live in .agents/skills/himalaya/" } : {},
|
|
199606
200236
|
// In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
|
|
199607
200237
|
// hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
|
|
199608
|
-
...
|
|
200238
|
+
...existsSync94(join101(dir, ".himi", "attestations", "latest.json")) ? { next: "if `himi push` then refuses the attestation as stale, re-run `himi test` \u2014 in a git checkout this refresh changed the tree it covered" } : {},
|
|
199609
200239
|
...res.skipped.length ? { skipped: res.skipped } : {},
|
|
199610
200240
|
portalUrl: idx.portalUrl
|
|
199611
200241
|
});
|
|
@@ -199673,7 +200303,7 @@ init_schema2();
|
|
|
199673
200303
|
// src/cms.ts
|
|
199674
200304
|
init_cms_schema();
|
|
199675
200305
|
init_wix_owner();
|
|
199676
|
-
import { existsSync as
|
|
200306
|
+
import { existsSync as existsSync95, readFileSync as readFileSync112, writeFileSync as writeFileSync36 } from "node:fs";
|
|
199677
200307
|
import { join as join102 } from "node:path";
|
|
199678
200308
|
var FOREIGN_DETAIL_LIMIT = 25;
|
|
199679
200309
|
var MAX_COLLECTION_PAGES = 40;
|
|
@@ -200106,7 +200736,7 @@ async function seedCms(opts) {
|
|
|
200106
200736
|
}
|
|
200107
200737
|
function readSeedFile(dir) {
|
|
200108
200738
|
const file2 = join102(dir, "cms-seed.json");
|
|
200109
|
-
if (!
|
|
200739
|
+
if (!existsSync95(file2)) return {};
|
|
200110
200740
|
let parsed;
|
|
200111
200741
|
try {
|
|
200112
200742
|
parsed = JSON.parse(readFileSync112(file2, "utf8"));
|
|
@@ -200168,7 +200798,7 @@ async function writeSeedRows(opts) {
|
|
|
200168
200798
|
};
|
|
200169
200799
|
}
|
|
200170
200800
|
let existing = {};
|
|
200171
|
-
if (
|
|
200801
|
+
if (existsSync95(file2)) {
|
|
200172
200802
|
let parsed;
|
|
200173
200803
|
try {
|
|
200174
200804
|
parsed = JSON.parse(readFileSync112(file2, "utf8"));
|
|
@@ -200483,7 +201113,7 @@ async function cmsCommand(ctx) {
|
|
|
200483
201113
|
|
|
200484
201114
|
// src/commands/base44.ts
|
|
200485
201115
|
init_cli_shared();
|
|
200486
|
-
import { existsSync as
|
|
201116
|
+
import { existsSync as existsSync103 } from "node:fs";
|
|
200487
201117
|
import { join as join113, resolve as resolve77 } from "node:path";
|
|
200488
201118
|
async function base44Command(ctx) {
|
|
200489
201119
|
const { io: io2, pos, flags, print } = ctx;
|
|
@@ -200555,7 +201185,7 @@ async function base44Command(ctx) {
|
|
|
200555
201185
|
return 1;
|
|
200556
201186
|
};
|
|
200557
201187
|
const gen = await Promise.resolve().then(() => (init_generate(), generate_exports));
|
|
200558
|
-
const missing3 = gen.ENGINE_FILES.filter((f2) => !
|
|
201188
|
+
const missing3 = gen.ENGINE_FILES.filter((f2) => !existsSync103(join113(dir, f2)));
|
|
200559
201189
|
if (missing3.length) {
|
|
200560
201190
|
return fail6("content_dir_not_base44_starter", `${dir} is not a base44-starter content package: the generated screens import a shared engine it does not have (${missing3.join(", ")})`, { missing: missing3, hint: "scaffold one with `himi init <name> --template base44-starter --base44-app-id <id>`" });
|
|
200561
201191
|
}
|
|
@@ -200641,7 +201271,7 @@ async function base44Command(ctx) {
|
|
|
200641
201271
|
if (!provisioning || str3(flags.content) !== void 0 || !slug) return contentDir(flags);
|
|
200642
201272
|
if (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) return void 0;
|
|
200643
201273
|
const dir = resolve77("apps", slug);
|
|
200644
|
-
return
|
|
201274
|
+
return existsSync103(join113(dir, "config.ts")) || existsSync103(join113(dir, "config.mjs")) ? dir : void 0;
|
|
200645
201275
|
};
|
|
200646
201276
|
if (sub === "entities" || sub === "functions") {
|
|
200647
201277
|
if (sub === "entities" && !["query", "create", "seed"].includes(pos[2] ?? "")) {
|