peachsim 0.1.628 → 0.1.630
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/README.md +8 -4
- package/cli/bridge-flow-runner.ts +10 -3
- package/cli/cli-update.ts +2 -7
- package/cli/cloud-test-tunnel.ts +16 -3
- package/cli/commands/config.ts +1 -1
- package/cli/commands/control.ts +28 -3
- package/cli/commands/daemon-mac-app.ts +4 -2
- package/cli/commands/daemon.ts +4 -4
- package/cli/commands/device.ts +2 -3
- package/cli/commands/inspect/actions.ts +125 -90
- package/cli/commands/inspect/core.ts +5 -0
- package/cli/commands/inspect.ts +27 -13
- package/cli/commands/platform.ts +1 -1
- package/cli/commands/screenshot-layers.ts +1 -1
- package/cli/commands/screenshot.ts +1 -1
- package/cli/commands/skills.ts +0 -31
- package/cli/drivers/playwright-provisioning.ts +3 -2
- package/cli/drivers/playwright-sim-host.ts +25 -9
- package/cli/main.ts +8 -2
- package/cli/outbound-endpoints.ts +0 -4
- package/detox/index.ts +74 -43
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +129 -27
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +290 -315
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +253 -121
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/{vite-kotlin.cjs → kotlin-host.cjs} +130 -19
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +132 -9
- package/dist-lib/native-app-identity.cjs +278 -0
- package/dist-lib/native-app-identity.mjs +245 -0
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +110 -87
- package/dist-lib/sdk.mjs +110 -87
- package/dist-lib/skills.cjs +841 -643
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +282 -177
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +11 -28
- package/kotlin/README.md +32 -4
- package/kotlin/fixtures/counter/Counter.kt +26 -0
- package/kotlin/fixtures/counter/CounterScreen.kt +40 -0
- package/kotlin/fixtures/headless-counter/Headless.kt +228 -0
- package/kotlin/fixtures/runtime-state/RuntimeState.kt +200 -0
- package/kotlin/fork/LICENSE +178 -0
- package/kotlin/fork/NOTICE +25 -0
- package/kotlin/fork/README.md +59 -0
- package/kotlin/fork/build.sh +128 -0
- package/kotlin/fork/compose-worker-globals.patch +96 -0
- package/kotlin/fork/fork.json +33 -0
- package/kotlin/fork/publish.ts +77 -0
- package/kotlin/fork/skiko-worker-clock.patch +33 -0
- package/kotlin/toolchain.json +288 -0
- package/package.json +12 -5
- package/src/automatic-update-policy.ts +17 -0
- package/src/host/bridge-host.ts +3 -1
- package/src/{vite-plugin-kotlin.ts → kotlin-host.ts} +155 -12
- package/src/metro-plugin.ts +18 -0
- package/src/native-app-identity.ts +376 -0
- package/src/native-firebase-config.ts +90 -0
- package/src/screenshots/frame-compose.ts +5 -2
- package/src/screenshots/registry.ts +1 -1
- package/src/screenshots/schema.ts +2 -2
- package/src/vite-plugin-one.ts +11 -28
- package/src/vite-plugin.ts +6 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/host/fetch-proxy-overrides.ts
|
|
4
4
|
var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -2461,16 +2461,26 @@ function payloadFromResolved(resolved, match, extra = {}) {
|
|
|
2461
2461
|
...extra
|
|
2462
2462
|
};
|
|
2463
2463
|
}
|
|
2464
|
-
function collectTextCandidates(nodes, ancestors = [], pressableOwnerText = "") {
|
|
2464
|
+
function collectTextCandidates(nodes, ancestors = [], pressableOwnerText = "", actionableAncestor = false, actionableRole) {
|
|
2465
2465
|
const out = [];
|
|
2466
2466
|
for (const node of nodes) {
|
|
2467
2467
|
const text = nodeText(node);
|
|
2468
2468
|
const caption = !!text && text === pressableOwnerText && !node.pressable;
|
|
2469
|
-
|
|
2469
|
+
const actionable = !!node.pressable || actionableAncestor;
|
|
2470
|
+
const role = node.role ?? actionableRole;
|
|
2471
|
+
if (!caption) out.push({ node, ancestorTestIDs: ancestors, actionable, role });
|
|
2470
2472
|
if (node.children?.length) {
|
|
2471
2473
|
const next = node.testID ? [...ancestors, node.testID] : ancestors;
|
|
2472
2474
|
const owner = text ? node.pressable ? text : "" : pressableOwnerText;
|
|
2473
|
-
out.push(
|
|
2475
|
+
out.push(
|
|
2476
|
+
...collectTextCandidates(
|
|
2477
|
+
node.children,
|
|
2478
|
+
next,
|
|
2479
|
+
owner,
|
|
2480
|
+
actionable,
|
|
2481
|
+
node.pressable ? node.role : actionableRole
|
|
2482
|
+
)
|
|
2483
|
+
);
|
|
2474
2484
|
}
|
|
2475
2485
|
}
|
|
2476
2486
|
return out;
|
|
@@ -2494,85 +2504,102 @@ async function tapByText(bridge, query, options = {}, opts = {}) {
|
|
|
2494
2504
|
agent: opts.agent,
|
|
2495
2505
|
timing: opts.timing,
|
|
2496
2506
|
textFallback: query,
|
|
2497
|
-
resolve:
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
const ay = node2.geometry.y;
|
|
2511
|
-
if (options.minX != null && !(ax >= options.minX)) return false;
|
|
2512
|
-
if (options.maxX != null && !(ax <= options.maxX)) return false;
|
|
2513
|
-
if (options.minY != null && !(ay >= options.minY)) return false;
|
|
2514
|
-
if (options.maxY != null && !(ay <= options.maxY)) return false;
|
|
2515
|
-
return true;
|
|
2516
|
-
});
|
|
2517
|
-
if (options.near) {
|
|
2518
|
-
const { x, y } = options.near;
|
|
2519
|
-
candidates.sort(
|
|
2520
|
-
(a, b) => Math.hypot(a.node.geometry.x - x, a.node.geometry.y - y) - Math.hypot(b.node.geometry.x - x, b.node.geometry.y - y)
|
|
2521
|
-
);
|
|
2522
|
-
} else {
|
|
2523
|
-
candidates.sort((a, b) => {
|
|
2524
|
-
if (Math.abs(a.node.geometry.y - b.node.geometry.y) > 2) {
|
|
2525
|
-
return a.node.geometry.y - b.node.geometry.y;
|
|
2526
|
-
}
|
|
2527
|
-
return a.node.geometry.x - b.node.geometry.x;
|
|
2528
|
-
});
|
|
2529
|
-
}
|
|
2530
|
-
const total = candidates.length;
|
|
2531
|
-
if (total === 0) return { matched: 0, total: 0 };
|
|
2532
|
-
let idx = 0;
|
|
2533
|
-
if (options.nth != null) {
|
|
2534
|
-
idx = options.nth < 0 ? total + options.nth : options.nth;
|
|
2535
|
-
if (idx < 0 || idx >= total) {
|
|
2536
|
-
return { matched: 0, total, nthOutOfRange: true, nth: options.nth };
|
|
2537
|
-
}
|
|
2538
|
-
} else if (total > 1 && !options.first && !options.near) {
|
|
2539
|
-
return {
|
|
2540
|
-
ambiguous: true,
|
|
2541
|
-
total,
|
|
2542
|
-
candidates: candidates.slice(0, 10).map((candidate, index) => ({
|
|
2543
|
-
idx: index,
|
|
2544
|
-
nodeId: candidate.node.nodeId,
|
|
2545
|
-
type: candidate.node.type,
|
|
2546
|
-
testID: candidate.node.testID ?? null,
|
|
2547
|
-
text: nodeText(candidate.node).slice(0, 60),
|
|
2548
|
-
abs: { x: candidate.node.geometry.x, y: candidate.node.geometry.y },
|
|
2549
|
-
layout: {
|
|
2550
|
-
width: Math.round(candidate.node.geometry.width),
|
|
2551
|
-
height: Math.round(candidate.node.geometry.height)
|
|
2552
|
-
},
|
|
2553
|
-
ancestorTestIDs: candidate.ancestorTestIDs.slice(0, 5)
|
|
2554
|
-
}))
|
|
2555
|
-
};
|
|
2507
|
+
resolve: () => resolveTextTapTarget(bridge, query, options)
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
async function resolveTextTapTarget(bridge, query, options = {}) {
|
|
2511
|
+
const { tree } = await inspectTree(bridge, 50);
|
|
2512
|
+
if (!Array.isArray(tree)) return { matched: 0, total: 0 };
|
|
2513
|
+
const needle = options.exact ? query : query.toLowerCase();
|
|
2514
|
+
let candidates = collectTextCandidates(tree).filter(
|
|
2515
|
+
({ node: node2, ancestorTestIDs, role }) => {
|
|
2516
|
+
const text = nodeText(node2);
|
|
2517
|
+
if (!text) return false;
|
|
2518
|
+
if (options.exact ? text !== needle : !text.toLowerCase().includes(needle)) {
|
|
2519
|
+
return false;
|
|
2556
2520
|
}
|
|
2557
|
-
|
|
2558
|
-
if (!
|
|
2559
|
-
const
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
if (!
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2521
|
+
if (options.role && role !== options.role) return false;
|
|
2522
|
+
if (options.within && !ancestorTestIDs.includes(options.within)) return false;
|
|
2523
|
+
const ax = node2.geometry.x;
|
|
2524
|
+
const ay = node2.geometry.y;
|
|
2525
|
+
if (options.minX != null && !(ax >= options.minX)) return false;
|
|
2526
|
+
if (options.maxX != null && !(ax <= options.maxX)) return false;
|
|
2527
|
+
if (options.minY != null && !(ay >= options.minY)) return false;
|
|
2528
|
+
if (options.maxY != null && !(ay <= options.maxY)) return false;
|
|
2529
|
+
return true;
|
|
2530
|
+
}
|
|
2531
|
+
);
|
|
2532
|
+
if (options.nth == null && !options.first && !options.near) {
|
|
2533
|
+
const actionable = candidates.filter((candidate) => candidate.actionable);
|
|
2534
|
+
if (actionable.length > 0) candidates = actionable;
|
|
2535
|
+
}
|
|
2536
|
+
if (options.near) {
|
|
2537
|
+
const { x, y } = options.near;
|
|
2538
|
+
candidates.sort(
|
|
2539
|
+
(a, b) => Math.hypot(a.node.geometry.x - x, a.node.geometry.y - y) - Math.hypot(b.node.geometry.x - x, b.node.geometry.y - y)
|
|
2540
|
+
);
|
|
2541
|
+
} else {
|
|
2542
|
+
candidates.sort((a, b) => {
|
|
2543
|
+
if (Math.abs(a.node.geometry.y - b.node.geometry.y) > 2) {
|
|
2544
|
+
return a.node.geometry.y - b.node.geometry.y;
|
|
2572
2545
|
}
|
|
2573
|
-
return
|
|
2546
|
+
return a.node.geometry.x - b.node.geometry.x;
|
|
2547
|
+
});
|
|
2548
|
+
}
|
|
2549
|
+
const total = candidates.length;
|
|
2550
|
+
if (total === 0) return { matched: 0, total: 0 };
|
|
2551
|
+
let idx = 0;
|
|
2552
|
+
if (options.nth != null) {
|
|
2553
|
+
idx = options.nth < 0 ? total + options.nth : options.nth;
|
|
2554
|
+
if (idx < 0 || idx >= total) {
|
|
2555
|
+
return { matched: 0, total, nthOutOfRange: true, nth: options.nth };
|
|
2574
2556
|
}
|
|
2557
|
+
} else if (total > 1 && !options.first && !options.near) {
|
|
2558
|
+
return {
|
|
2559
|
+
ambiguous: true,
|
|
2560
|
+
total,
|
|
2561
|
+
candidates: candidates.slice(0, 10).map((candidate, index) => ({
|
|
2562
|
+
idx: index,
|
|
2563
|
+
nodeId: candidate.node.nodeId,
|
|
2564
|
+
type: candidate.node.type,
|
|
2565
|
+
testID: candidate.node.testID ?? null,
|
|
2566
|
+
text: nodeText(candidate.node).slice(0, 60),
|
|
2567
|
+
abs: { x: candidate.node.geometry.x, y: candidate.node.geometry.y },
|
|
2568
|
+
layout: {
|
|
2569
|
+
width: Math.round(candidate.node.geometry.width),
|
|
2570
|
+
height: Math.round(candidate.node.geometry.height)
|
|
2571
|
+
},
|
|
2572
|
+
ancestorTestIDs: candidate.ancestorTestIDs.slice(0, 5)
|
|
2573
|
+
}))
|
|
2574
|
+
};
|
|
2575
|
+
}
|
|
2576
|
+
const picked = candidates[idx];
|
|
2577
|
+
if (!picked) return { matched: 0, total };
|
|
2578
|
+
const node = picked.node;
|
|
2579
|
+
const tap = await bridge.send({
|
|
2580
|
+
type: "call",
|
|
2581
|
+
path: "SootSim.bridges.test.resolveTapTarget",
|
|
2582
|
+
args: [node.nodeId]
|
|
2575
2583
|
});
|
|
2584
|
+
if (!isTapTargetInfo(tap)) return { matched: 0, total };
|
|
2585
|
+
return payloadFromResolved(
|
|
2586
|
+
{
|
|
2587
|
+
x: tap.cx,
|
|
2588
|
+
y: tap.cy,
|
|
2589
|
+
nodeId: tap.target.nodeId,
|
|
2590
|
+
testID: tap.target.testID,
|
|
2591
|
+
text: tap.target.text ?? tap.target.accessibilityLabel,
|
|
2592
|
+
type: tap.target.type
|
|
2593
|
+
},
|
|
2594
|
+
node,
|
|
2595
|
+
{ total, idx }
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
function isTapNode(value) {
|
|
2599
|
+
return value !== null && typeof value === "object" && typeof Reflect.get(value, "nodeId") === "number";
|
|
2600
|
+
}
|
|
2601
|
+
function isTapTargetInfo(value) {
|
|
2602
|
+
return value !== null && typeof value === "object" && typeof Reflect.get(value, "cx") === "number" && typeof Reflect.get(value, "cy") === "number" && isTapNode(Reflect.get(value, "target"));
|
|
2576
2603
|
}
|
|
2577
2604
|
async function tapBest(bridge, query, opts = {}) {
|
|
2578
2605
|
return tapResolvedTarget(bridge, {
|
|
@@ -2594,17 +2621,19 @@ async function tapBest(bridge, query, opts = {}) {
|
|
|
2594
2621
|
}
|
|
2595
2622
|
};
|
|
2596
2623
|
}
|
|
2597
|
-
const byText = await
|
|
2598
|
-
if (byText) {
|
|
2624
|
+
const byText = await resolveTextTapTarget(bridge, query);
|
|
2625
|
+
if ("ambiguous" in byText) {
|
|
2626
|
+
return {
|
|
2627
|
+
ambiguous: true,
|
|
2628
|
+
error: `multiple text matches for "${query}"; use tap-text with --nth, --within or --near`
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
if ("cx" in byText && typeof byText.cx === "number") {
|
|
2599
2632
|
return {
|
|
2600
|
-
...
|
|
2633
|
+
...byText,
|
|
2601
2634
|
strategy: "text",
|
|
2602
2635
|
node: {
|
|
2603
|
-
|
|
2604
|
-
id: byText.testID ?? null,
|
|
2605
|
-
testID: byText.testID ?? null,
|
|
2606
|
-
type: byText.type ?? null,
|
|
2607
|
-
text: byText.text ?? query
|
|
2636
|
+
...byText.target
|
|
2608
2637
|
}
|
|
2609
2638
|
};
|
|
2610
2639
|
}
|
|
@@ -4160,7 +4189,7 @@ var swiftHost;
|
|
|
4160
4189
|
var loadSwiftHost = () => swiftHost ??= import("peachsim/vite-swift");
|
|
4161
4190
|
var KOTLIN_ROUTE_PREFIX = "/__peach/kotlin";
|
|
4162
4191
|
var kotlinHost;
|
|
4163
|
-
var loadKotlinHost = () => kotlinHost ??= import("peachsim/
|
|
4192
|
+
var loadKotlinHost = () => kotlinHost ??= import("peachsim/kotlin-host");
|
|
4164
4193
|
function rnxPlugin(options = {}) {
|
|
4165
4194
|
const prefix2 = options.prefix || "/__soot";
|
|
4166
4195
|
return {
|
|
@@ -4243,34 +4272,17 @@ function rnxPlugin(options = {}) {
|
|
|
4243
4272
|
const pathname = (req.url ?? "").split("?")[0];
|
|
4244
4273
|
if (!pathname.startsWith(KOTLIN_ROUTE_PREFIX)) return next();
|
|
4245
4274
|
loadKotlinHost().then(async (host) => {
|
|
4246
|
-
if (host.serveKotlinArtifact(pathname, res)) return;
|
|
4247
|
-
if (pathname !== "/__peach/kotlin-package") return next();
|
|
4248
4275
|
if (!kotlinModuleRoot) {
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
(0, import_node_module.createRequire)(import_path3.default.join(server.config.root, "package.json")).resolve(
|
|
4252
|
-
"peachsim/package.json"
|
|
4253
|
-
)
|
|
4254
|
-
),
|
|
4255
|
-
"kotlin"
|
|
4256
|
-
);
|
|
4257
|
-
kotlinModuleRoot = moduleRoot;
|
|
4258
|
-
server.watcher.add(import_path3.default.join(moduleRoot, "Sources"));
|
|
4259
|
-
}
|
|
4260
|
-
try {
|
|
4261
|
-
const artifact = await host.kotlinArtifact(
|
|
4262
|
-
server.config.root,
|
|
4263
|
-
kotlinModuleRoot,
|
|
4264
|
-
devOrigin()
|
|
4265
|
-
);
|
|
4266
|
-
res.setHeader("access-control-allow-origin", "*");
|
|
4267
|
-
res.setHeader("content-type", "application/json");
|
|
4268
|
-
res.end(JSON.stringify({ ...artifact, hmrPath }));
|
|
4269
|
-
} catch (error) {
|
|
4270
|
-
res.statusCode = 500;
|
|
4271
|
-
res.setHeader("access-control-allow-origin", "*");
|
|
4272
|
-
res.end(error instanceof Error ? error.message : String(error));
|
|
4276
|
+
kotlinModuleRoot = host.peachKotlinModuleRoot(server.config.root);
|
|
4277
|
+
server.watcher.add(import_path3.default.join(kotlinModuleRoot, "Sources"));
|
|
4273
4278
|
}
|
|
4279
|
+
const served = await host.serveKotlinRequest(pathname, res, {
|
|
4280
|
+
root: server.config.root,
|
|
4281
|
+
moduleRoot: kotlinModuleRoot,
|
|
4282
|
+
origin: devOrigin(),
|
|
4283
|
+
hmrPath
|
|
4284
|
+
});
|
|
4285
|
+
if (!served) next();
|
|
4274
4286
|
}).catch(next);
|
|
4275
4287
|
});
|
|
4276
4288
|
server.watcher.on("change", (file) => {
|
|
@@ -4482,6 +4494,110 @@ var import_fs5 = __toESM(require("fs"), 1);
|
|
|
4482
4494
|
var import_module2 = require("module");
|
|
4483
4495
|
var import_node_crypto5 = require("node:crypto");
|
|
4484
4496
|
var import_path4 = __toESM(require("path"), 1);
|
|
4497
|
+
|
|
4498
|
+
// src/native-firebase-config.ts
|
|
4499
|
+
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
4500
|
+
var import_node_module2 = require("node:module");
|
|
4501
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
4502
|
+
|
|
4503
|
+
// src/plist.ts
|
|
4504
|
+
var import_plist = __toESM(require("@expo/plist"), 1);
|
|
4505
|
+
function resolvePlistParser(value) {
|
|
4506
|
+
if (!isRecord(value)) return null;
|
|
4507
|
+
const direct = value.parse;
|
|
4508
|
+
if (typeof direct === "function") {
|
|
4509
|
+
return (source) => Reflect.apply(direct, value, [source]);
|
|
4510
|
+
}
|
|
4511
|
+
const nested = value.default;
|
|
4512
|
+
if (!isRecord(nested)) return null;
|
|
4513
|
+
const nestedParse = nested.parse;
|
|
4514
|
+
return typeof nestedParse === "function" ? (source) => Reflect.apply(nestedParse, nested, [source]) : null;
|
|
4515
|
+
}
|
|
4516
|
+
var parsePlist = resolvePlistParser(import_plist.default);
|
|
4517
|
+
function parsePlistSource(source) {
|
|
4518
|
+
return parsePlist?.(source) ?? null;
|
|
4519
|
+
}
|
|
4520
|
+
|
|
4521
|
+
// src/native-firebase-config.ts
|
|
4522
|
+
function readNativeFirebaseConfig(projectRoot) {
|
|
4523
|
+
const result = {};
|
|
4524
|
+
if (![
|
|
4525
|
+
"app.json",
|
|
4526
|
+
"app.config.js",
|
|
4527
|
+
"app.config.ts",
|
|
4528
|
+
"app.config.cjs",
|
|
4529
|
+
"app.config.mjs"
|
|
4530
|
+
].some((name2) => import_node_fs5.default.existsSync(import_node_path6.default.join(projectRoot, name2))))
|
|
4531
|
+
return result;
|
|
4532
|
+
const require2 = (0, import_node_module2.createRequire)(import_node_path6.default.join(projectRoot, "package.json"));
|
|
4533
|
+
const configModule = require2("@expo/config");
|
|
4534
|
+
if (!isRecord(configModule) || typeof configModule.getConfig !== "function") {
|
|
4535
|
+
throw new Error("Expo native configuration is unavailable.");
|
|
4536
|
+
}
|
|
4537
|
+
const resolved = Reflect.apply(configModule.getConfig, configModule, [
|
|
4538
|
+
projectRoot,
|
|
4539
|
+
{ skipSDKVersionRequirement: true }
|
|
4540
|
+
]);
|
|
4541
|
+
const config = isRecord(resolved) && isRecord(resolved.exp) ? resolved.exp : {};
|
|
4542
|
+
for (const platform of ["ios", "android"]) {
|
|
4543
|
+
const native = config[platform];
|
|
4544
|
+
if (!isRecord(native) || typeof native.googleServicesFile !== "string") continue;
|
|
4545
|
+
try {
|
|
4546
|
+
const source = import_node_fs5.default.readFileSync(
|
|
4547
|
+
import_node_path6.default.resolve(projectRoot, native.googleServicesFile),
|
|
4548
|
+
"utf8"
|
|
4549
|
+
);
|
|
4550
|
+
const parsed = platform === "ios" ? parsePlistSource(source) : JSON.parse(source);
|
|
4551
|
+
if (!isRecord(parsed)) throw new Error("Invalid Google services file.");
|
|
4552
|
+
if (platform === "ios") {
|
|
4553
|
+
result[platform] = {
|
|
4554
|
+
apiKey: parsed.API_KEY,
|
|
4555
|
+
appId: parsed.GOOGLE_APP_ID,
|
|
4556
|
+
projectId: parsed.PROJECT_ID,
|
|
4557
|
+
databaseURL: parsed.DATABASE_URL,
|
|
4558
|
+
gaTrackingId: parsed.TRACKING_ID,
|
|
4559
|
+
storageBucket: parsed.STORAGE_BUCKET,
|
|
4560
|
+
messagingSenderId: parsed.GCM_SENDER_ID,
|
|
4561
|
+
clientId: parsed.CLIENT_ID,
|
|
4562
|
+
androidClientID: parsed.ANDROID_CLIENT_ID,
|
|
4563
|
+
deepLinkUrlScheme: parsed.REVERSED_CLIENT_ID
|
|
4564
|
+
};
|
|
4565
|
+
} else {
|
|
4566
|
+
const project = isRecord(parsed.project_info) ? parsed.project_info : {};
|
|
4567
|
+
const clients = Array.isArray(parsed.client) ? parsed.client : [];
|
|
4568
|
+
const client = clients.find((value) => {
|
|
4569
|
+
if (!isRecord(value) || !isRecord(value.client_info)) return false;
|
|
4570
|
+
const android = value.client_info.android_client_info;
|
|
4571
|
+
return isRecord(android) && android.package_name === native.package;
|
|
4572
|
+
});
|
|
4573
|
+
if (!isRecord(client) || !isRecord(client.client_info))
|
|
4574
|
+
throw new Error("No Google services client matches the Android package.");
|
|
4575
|
+
const apiKeys = Array.isArray(client.api_key) ? client.api_key : [];
|
|
4576
|
+
const apiKey = apiKeys.find(
|
|
4577
|
+
(value) => isRecord(value) && typeof value.current_key === "string"
|
|
4578
|
+
);
|
|
4579
|
+
const oauthClients = Array.isArray(client.oauth_client) ? client.oauth_client : [];
|
|
4580
|
+
const oauth = oauthClients.find(
|
|
4581
|
+
(value) => isRecord(value) && value.client_type === 3
|
|
4582
|
+
);
|
|
4583
|
+
result[platform] = {
|
|
4584
|
+
apiKey: isRecord(apiKey) ? apiKey.current_key : void 0,
|
|
4585
|
+
appId: client.client_info.mobilesdk_app_id,
|
|
4586
|
+
projectId: project.project_id,
|
|
4587
|
+
databaseURL: project.firebase_url,
|
|
4588
|
+
storageBucket: project.storage_bucket,
|
|
4589
|
+
messagingSenderId: project.project_number,
|
|
4590
|
+
clientId: isRecord(oauth) ? oauth.client_id : void 0
|
|
4591
|
+
};
|
|
4592
|
+
}
|
|
4593
|
+
} catch (error) {
|
|
4594
|
+
result[platform] = { error: error instanceof Error ? error.message : String(error) };
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
return result;
|
|
4598
|
+
}
|
|
4599
|
+
|
|
4600
|
+
// src/metro-plugin.ts
|
|
4485
4601
|
var prefix = "/__soot";
|
|
4486
4602
|
function readCallableMetroExport(moduleValue, label) {
|
|
4487
4603
|
const callable = typeof moduleValue === "function" ? moduleValue : typeof moduleValue === "object" && moduleValue !== null ? Reflect.get(moduleValue, "default") : void 0;
|
|
@@ -4602,6 +4718,22 @@ function withRNX(config) {
|
|
|
4602
4718
|
});
|
|
4603
4719
|
return;
|
|
4604
4720
|
}
|
|
4721
|
+
if ((req.url || "").split("?")[0] === "/__peach-native-firebase-config") {
|
|
4722
|
+
try {
|
|
4723
|
+
res.setHeader("Content-Type", "application/json");
|
|
4724
|
+
res.setHeader("Cache-Control", "no-store");
|
|
4725
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
4726
|
+
res.end(JSON.stringify(readNativeFirebaseConfig(cfgProjectRoot)));
|
|
4727
|
+
} catch (error) {
|
|
4728
|
+
res.statusCode = 400;
|
|
4729
|
+
res.end(
|
|
4730
|
+
JSON.stringify({
|
|
4731
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4732
|
+
})
|
|
4733
|
+
);
|
|
4734
|
+
}
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4605
4737
|
const url = req.url || "";
|
|
4606
4738
|
const pathname = url.split("?")[0];
|
|
4607
4739
|
const runtimeRoot = resolveRuntimeRootForRequestHost(req.headers?.host);
|
|
@@ -4670,13 +4802,13 @@ function resolveMetroPort(server) {
|
|
|
4670
4802
|
var metro_plugin_default = withRNX;
|
|
4671
4803
|
|
|
4672
4804
|
// src/jump-to-source-babel.ts
|
|
4673
|
-
function normalizeSourcePath(
|
|
4674
|
-
const queryStart =
|
|
4675
|
-
const clean = queryStart >= 0 ?
|
|
4805
|
+
function normalizeSourcePath(path9) {
|
|
4806
|
+
const queryStart = path9.indexOf("?");
|
|
4807
|
+
const clean = queryStart >= 0 ? path9.slice(0, queryStart) : path9;
|
|
4676
4808
|
return clean.replace(/\\/g, "/");
|
|
4677
4809
|
}
|
|
4678
|
-
function matchesPath(
|
|
4679
|
-
return typeof matcher === "string" ?
|
|
4810
|
+
function matchesPath(path9, matcher) {
|
|
4811
|
+
return typeof matcher === "string" ? path9.includes(matcher) : matcher.test(path9);
|
|
4680
4812
|
}
|
|
4681
4813
|
function shouldStampFile(filename, options) {
|
|
4682
4814
|
const normalized = normalizeSourcePath(filename);
|
|
@@ -4709,11 +4841,11 @@ function sootsimJumpToSourceBabelPlugin(api, options = {}) {
|
|
|
4709
4841
|
return {
|
|
4710
4842
|
name: "sootsim-jump-to-source",
|
|
4711
4843
|
visitor: {
|
|
4712
|
-
JSXOpeningElement(
|
|
4844
|
+
JSXOpeningElement(path9, state) {
|
|
4713
4845
|
if (options.enabled === false) return;
|
|
4714
4846
|
const filename = state.file?.opts?.filename;
|
|
4715
4847
|
if (!filename || !shouldStampFile(filename, options)) return;
|
|
4716
|
-
const node =
|
|
4848
|
+
const node = path9.node;
|
|
4717
4849
|
const tagName = getJSXName(node.name);
|
|
4718
4850
|
if (!tagName || tagName === "Fragment" || tagName.endsWith(".Fragment")) return;
|
|
4719
4851
|
if (hasAttribute(node, attrName)) return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.630 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|