peachsim 0.1.527 → 0.1.570
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 +26 -26
- package/cli/app-fonts.ts +1 -1
- package/cli/app-splash.ts +1 -1
- package/cli/bin.ts +1 -1
- package/cli/bridge-diagnostics.ts +1 -1
- package/cli/bridge-flow-runner.ts +57 -5
- package/cli/cloud-client.ts +273 -6
- package/cli/cloud-dispatch.ts +22 -2
- package/cli/cloud-session.ts +60 -4
- package/cli/cloud-test-tunnel.ts +354 -0
- package/cli/commands/box/bundle-plane.ts +2 -2
- package/cli/commands/box/checkout-plane.ts +1 -1
- package/cli/commands/box/rnx-command.ts +2 -2
- package/cli/commands/box/search-command.ts +2 -2
- package/cli/commands/box.ts +8 -8
- package/cli/commands/compat.ts +1 -1
- package/cli/commands/control.ts +22 -3
- package/cli/commands/detox.ts +1 -1
- package/cli/commands/device.ts +1 -1
- package/cli/commands/diagnose.ts +1 -1
- package/cli/commands/film.ts +1 -1
- package/cli/commands/flow.ts +60 -3
- package/cli/commands/inspect/actions.ts +1 -1
- package/cli/commands/inspect/core.ts +6 -7
- package/cli/commands/inspect/find.ts +2 -1
- package/cli/commands/inspect/resolve-target.ts +5 -3
- package/cli/commands/inspect/shared.ts +1 -1
- package/cli/commands/inspect/wait-event.ts +1 -1
- package/cli/commands/inspect/wait-selector.ts +15 -4
- package/cli/commands/inspect.ts +19 -14
- package/cli/commands/maestro.ts +464 -43
- package/cli/commands/permissions.ts +1 -1
- package/cli/commands/platform.ts +205 -8
- package/cli/commands/preview.ts +2 -2
- package/cli/commands/record.ts +2 -2
- package/cli/commands/report-issue.ts +2 -2
- package/cli/commands/screenshot-layers.ts +1 -1
- package/cli/commands/screenshot.ts +1 -1
- package/cli/commands/setup.ts +2 -2
- package/cli/commands/test.ts +440 -115
- package/cli/commands/three-mode.ts +1 -1
- package/cli/commands/upload.ts +5 -5
- package/cli/commands/what-happened.ts +1 -1
- package/cli/desktop-companion.ts +3 -3
- package/cli/drivers/playwright-sim-host.ts +2 -2
- package/cli/flow-file.ts +7 -0
- package/cli/flow-live-status.ts +65 -8
- package/cli/help-core.ts +3 -3
- package/cli/hidden-runtime-alias.ts +1 -1
- package/cli/maestro-report.ts +178 -0
- package/cli/main.ts +1 -1
- package/cli/outbound-endpoints.ts +185 -136
- package/cli/parse-args.ts +1 -1
- package/cli/registry.ts +1 -1
- package/cli/resolve-assets.ts +1 -1
- package/cli/run-registry.ts +8 -0
- package/cli/send-to-box.ts +4 -4
- package/cli/ws-bridge.ts +3 -5
- package/detox/expectations.ts +1 -1
- package/detox/gestures.ts +2 -2
- package/detox/index.ts +71 -29
- package/detox/jest-preset.cjs +3 -3
- package/detox/jest-setup-after-env.cjs +1 -1
- package/dist-lib/agent-daemon-client.cjs +2 -2
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +2 -2
- package/dist-lib/attached-projects.cjs +2 -2
- 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 +94 -3
- package/dist-lib/capture-contract.mjs +93 -3
- 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.cjs +2 -2
- package/dist-lib/cloud.mjs +2 -2
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +106 -25
- package/dist-lib/detox/jest-preset.cjs +3 -3
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +137 -61
- package/dist-lib/host/fetch-proxy-handler.cjs +28 -2
- package/dist-lib/host/fetch-proxy-overrides.cjs +33 -3
- package/dist-lib/host/fetch-proxy-overrides.mjs +30 -2
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +209 -16
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +2 -2
- package/dist-lib/menu.mjs +2 -2
- 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 +3 -3
- package/dist-lib/metro-production-bundle.mjs +3 -3
- package/dist-lib/metro.cjs +8 -8
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +2 -2
- 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 +31 -15
- package/dist-lib/sdk.cjs +3 -2
- package/dist-lib/sdk.mjs +3 -2
- package/dist-lib/skills.cjs +362 -163
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +583 -16
- package/dist-lib/vite.cjs +29 -14
- package/package.json +9 -9
- package/scripts/dev-server-scanner.ts +41 -14
- package/scripts/optional-demo-registry.ts +3 -3
- package/skills/contrast/SKILL.md +9 -9
- package/skills/rnx-debug/SKILL.md +14 -4
- package/skills/rnx-perf/SKILL.md +5 -5
- package/skills/rnx-setup/SKILL.md +11 -11
- package/skills/rnx-test/SKILL.md +11 -11
- package/skills/rnx-visual/SKILL.md +6 -6
- package/src/agent-sessions.ts +3 -3
- package/src/attached-projects.ts +1 -1
- package/src/bridge-contract-input.ts +1 -1
- package/src/bridge-contract.ts +23 -5
- package/src/capture-contract.ts +145 -3
- package/src/config.ts +2 -2
- package/src/connect.ts +2 -2
- package/src/home-paths.ts +3 -3
- package/src/host/bridge-host.ts +2 -2
- package/src/host/fetch-proxy-handler.ts +4 -3
- package/src/host/fetch-proxy-overrides.ts +41 -0
- package/src/host/plane-host.ts +2 -2
- package/src/index.ts +3 -0
- package/src/metro-plugin.ts +4 -4
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-seam-manifest.ts +6 -6
- package/src/public-brand.ts +1 -1
- package/src/rolldown-plugin-swift.ts +8 -5
- package/src/runtime-assets.ts +8 -6
- package/src/screenshots/frame-compose.ts +24 -56
- package/src/screenshots/org-deck.ts +1 -1
- package/src/screenshots/registry.ts +4 -4
- package/src/screenshots/schema.ts +1 -1
- package/src/sdk.ts +2 -2
- package/src/settings-bundle.ts +1 -1
- package/src/sim-client.ts +2 -4
- package/src/skills/builtin/compat-check.ts +1 -1
- package/src/vite-plugin-one.ts +1 -1
- package/src/vite-plugin-swift.ts +11 -6
- package/src/vite-plugin.ts +30 -17
- package/src/worklets-babel.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.570 | (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;
|
|
@@ -114,7 +114,7 @@ var init_optional_demo_registry = __esm({
|
|
|
114
114
|
import_node_fs = require("node:fs");
|
|
115
115
|
import_node_path2 = require("node:path");
|
|
116
116
|
import_node_url = require("node:url");
|
|
117
|
-
REGISTRY_REPO_PATH = "packages/
|
|
117
|
+
REGISTRY_REPO_PATH = "packages/peachsim/scripts/demo-app-registry.ts";
|
|
118
118
|
MAX_ANCESTOR_STEPS = 8;
|
|
119
119
|
cached = null;
|
|
120
120
|
}
|
|
@@ -128,7 +128,7 @@ var init_public_brand = __esm({
|
|
|
128
128
|
name = "rnx";
|
|
129
129
|
rnxPublicBrand = Object.freeze({
|
|
130
130
|
name,
|
|
131
|
-
packageName: "
|
|
131
|
+
packageName: "peachsim",
|
|
132
132
|
commandName: "rnx",
|
|
133
133
|
domain: "rnxsim.com",
|
|
134
134
|
origin: "https://rnxsim.com"
|
|
@@ -721,7 +721,7 @@ var init_auth = __esm({
|
|
|
721
721
|
}
|
|
722
722
|
});
|
|
723
723
|
|
|
724
|
-
// ../
|
|
724
|
+
// ../peach-engine/src/preview/storage-snapshot-contract.ts
|
|
725
725
|
function isRecord3(value) {
|
|
726
726
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
727
727
|
}
|
|
@@ -768,12 +768,12 @@ function isStorageSnapshot(value) {
|
|
|
768
768
|
return isRecord3(value) && Array.isArray(value.entries) && value.entries.every(isStorageSnapshotEntry) && (value.secureStore == null || Array.isArray(value.secureStore) && value.secureStore.every(isSecureStoreSnapshotEntry)) && (value.indexedDB == null || Array.isArray(value.indexedDB) && value.indexedDB.every(isIndexedDBSnapshot)) && (value.route == null || isPreviewRouteSnapshot(value.route));
|
|
769
769
|
}
|
|
770
770
|
var init_storage_snapshot_contract = __esm({
|
|
771
|
-
"../
|
|
771
|
+
"../peach-engine/src/preview/storage-snapshot-contract.ts"() {
|
|
772
772
|
"use strict";
|
|
773
773
|
}
|
|
774
774
|
});
|
|
775
775
|
|
|
776
|
-
// ../
|
|
776
|
+
// ../peach-engine/src/tenant-runtime-environment.ts
|
|
777
777
|
function readBrowserLocation() {
|
|
778
778
|
try {
|
|
779
779
|
return typeof location === "undefined" ? null : location;
|
|
@@ -783,25 +783,25 @@ function readBrowserLocation() {
|
|
|
783
783
|
}
|
|
784
784
|
var nativeRuntimeLocation;
|
|
785
785
|
var init_tenant_runtime_environment = __esm({
|
|
786
|
-
"../
|
|
786
|
+
"../peach-engine/src/tenant-runtime-environment.ts"() {
|
|
787
787
|
"use strict";
|
|
788
788
|
nativeRuntimeLocation = readBrowserLocation();
|
|
789
789
|
}
|
|
790
790
|
});
|
|
791
791
|
|
|
792
|
-
// ../
|
|
792
|
+
// ../peach-engine/src/development-mode.ts
|
|
793
793
|
var bridgeConstants, DEFAULT_SOOTSIM_BRIDGE_PORT2, DAEMON_RUNTIME_PORT_MAX;
|
|
794
794
|
var init_development_mode = __esm({
|
|
795
|
-
"../
|
|
795
|
+
"../peach-engine/src/development-mode.ts"() {
|
|
796
796
|
"use strict";
|
|
797
|
-
bridgeConstants = __toESM(require("
|
|
797
|
+
bridgeConstants = __toESM(require("peachsim/bridge-constants"), 1);
|
|
798
798
|
init_tenant_runtime_environment();
|
|
799
799
|
({ DEFAULT_SOOTSIM_BRIDGE_PORT: DEFAULT_SOOTSIM_BRIDGE_PORT2 } = bridgeConstants);
|
|
800
800
|
DAEMON_RUNTIME_PORT_MAX = DEFAULT_SOOTSIM_BRIDGE_PORT2 + 10;
|
|
801
801
|
}
|
|
802
802
|
});
|
|
803
803
|
|
|
804
|
-
// ../
|
|
804
|
+
// ../peach-engine/src/settings/devices.ts
|
|
805
805
|
function modernButtons(action, volumeUp, volumeDown, power) {
|
|
806
806
|
return {
|
|
807
807
|
width: 3,
|
|
@@ -850,23 +850,27 @@ function getDevice(model, posture) {
|
|
|
850
850
|
return {
|
|
851
851
|
...device,
|
|
852
852
|
// inner display size from apple's ios 27 ui kit. corners and insets are
|
|
853
|
-
// measured from apple's 2d inner product art: every display corner
|
|
854
|
-
// 53pt circle within 0.4px,
|
|
855
|
-
// display on every edge as
|
|
853
|
+
// measured from apple's 2d inner product art at 3x: every display corner
|
|
854
|
+
// fits a 53pt circle within 0.4px, the silhouette sits 20.67pt outside the
|
|
855
|
+
// display on every edge as 16.33pt of black glass plus a 4.33pt rail, and
|
|
856
|
+
// the body itself curves at 75pt. the barrel is hidden when open.
|
|
856
857
|
width: 951,
|
|
857
858
|
height: 669,
|
|
858
859
|
statusBarHeight: 44,
|
|
859
860
|
cornerRadius: cornerRadii(53),
|
|
860
861
|
continuousCornerRadius: cornerRadii(53),
|
|
861
|
-
frameInsets: uniformFrameInsets(
|
|
862
|
-
|
|
862
|
+
frameInsets: uniformFrameInsets(20.6667),
|
|
863
|
+
frameCornerRadius: cornerRadii(75),
|
|
864
|
+
housing: { rail: uniformFrameInsets(4.3333), hingeBarrel: null },
|
|
863
865
|
cameraCutout: null,
|
|
864
866
|
physicalPPI: 430,
|
|
865
867
|
posture: "open",
|
|
866
|
-
// open inner display
|
|
867
|
-
//
|
|
868
|
-
//
|
|
869
|
-
|
|
868
|
+
// open inner display in landscape carries the same trailing column as
|
|
869
|
+
// the closed outer display, so it takes the same 84pt inset: a ~50pt
|
|
870
|
+
// control at a ~23pt inset needs 73pt, and anything narrower would shift
|
|
871
|
+
// controls horizontally on unfold, defeating the continuous experience
|
|
872
|
+
// Apple states as the reason for the design.
|
|
873
|
+
safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 84 }
|
|
870
874
|
};
|
|
871
875
|
}
|
|
872
876
|
function listDeviceModels() {
|
|
@@ -877,9 +881,9 @@ function getRuntimePlatform(model) {
|
|
|
877
881
|
}
|
|
878
882
|
var import_menu, LEGACY_HARDWARE_BUTTONS, PIXEL_HARDWARE_BUTTONS, GALAXY_HARDWARE_BUTTONS, ANDROID_GESTURE_NAV_BAR_HEIGHT, ANDROID_OS_VERSION, ANDROID_API_LEVEL, PIXEL_8_WIDTH, PIXEL_8_HEIGHT, PIXEL_8_STATUS_BAR_HEIGHT, devices, DEFAULT_DEVICE, DEFAULT_DEVICE_BY_PLATFORM;
|
|
879
883
|
var init_devices = __esm({
|
|
880
|
-
"../
|
|
884
|
+
"../peach-engine/src/settings/devices.ts"() {
|
|
881
885
|
"use strict";
|
|
882
|
-
import_menu = require("
|
|
886
|
+
import_menu = require("peachsim/menu");
|
|
883
887
|
init_development_mode();
|
|
884
888
|
LEGACY_HARDWARE_BUTTONS = {
|
|
885
889
|
width: 2.5,
|
|
@@ -912,6 +916,7 @@ var init_devices = __esm({
|
|
|
912
916
|
PIXEL_8_STATUS_BAR_HEIGHT = 132 / 2.625;
|
|
913
917
|
devices = {
|
|
914
918
|
"canvas-workspace": iosDevice({
|
|
919
|
+
model: "canvas-workspace",
|
|
915
920
|
name: "Canvas Workspace",
|
|
916
921
|
width: 1440,
|
|
917
922
|
height: 900,
|
|
@@ -937,6 +942,7 @@ var init_devices = __esm({
|
|
|
937
942
|
experimental: true
|
|
938
943
|
}),
|
|
939
944
|
"iphone-se": iosDevice({
|
|
945
|
+
model: "iphone-se",
|
|
940
946
|
name: "iPhone SE",
|
|
941
947
|
width: 375,
|
|
942
948
|
height: 667,
|
|
@@ -957,6 +963,7 @@ var init_devices = __esm({
|
|
|
957
963
|
hardwareButtons: LEGACY_HARDWARE_BUTTONS
|
|
958
964
|
}),
|
|
959
965
|
"iphone-14": iosDevice({
|
|
966
|
+
model: "iphone-14",
|
|
960
967
|
name: "iPhone 14",
|
|
961
968
|
width: 390,
|
|
962
969
|
height: 844,
|
|
@@ -979,6 +986,7 @@ var init_devices = __esm({
|
|
|
979
986
|
)
|
|
980
987
|
}),
|
|
981
988
|
"iphone-15": iosDevice({
|
|
989
|
+
model: "iphone-15",
|
|
982
990
|
name: "iPhone 15",
|
|
983
991
|
width: 393,
|
|
984
992
|
height: 852,
|
|
@@ -1001,6 +1009,7 @@ var init_devices = __esm({
|
|
|
1001
1009
|
)
|
|
1002
1010
|
}),
|
|
1003
1011
|
"iphone-15-plus": iosDevice({
|
|
1012
|
+
model: "iphone-15-plus",
|
|
1004
1013
|
name: "iPhone 15 Plus",
|
|
1005
1014
|
width: 430,
|
|
1006
1015
|
height: 932,
|
|
@@ -1023,6 +1032,7 @@ var init_devices = __esm({
|
|
|
1023
1032
|
)
|
|
1024
1033
|
}),
|
|
1025
1034
|
"iphone-15-pro": iosDevice({
|
|
1035
|
+
model: "iphone-15-pro",
|
|
1026
1036
|
name: "iPhone 15 Pro",
|
|
1027
1037
|
width: 393,
|
|
1028
1038
|
height: 852,
|
|
@@ -1045,6 +1055,7 @@ var init_devices = __esm({
|
|
|
1045
1055
|
)
|
|
1046
1056
|
}),
|
|
1047
1057
|
"iphone-15-pro-max": iosDevice({
|
|
1058
|
+
model: "iphone-15-pro-max",
|
|
1048
1059
|
name: "iPhone 15 Pro Max",
|
|
1049
1060
|
width: 430,
|
|
1050
1061
|
height: 932,
|
|
@@ -1067,6 +1078,7 @@ var init_devices = __esm({
|
|
|
1067
1078
|
)
|
|
1068
1079
|
}),
|
|
1069
1080
|
"iphone-16": iosDevice({
|
|
1081
|
+
model: "iphone-16",
|
|
1070
1082
|
name: "iPhone 16",
|
|
1071
1083
|
width: 393,
|
|
1072
1084
|
height: 852,
|
|
@@ -1075,7 +1087,7 @@ var init_devices = __esm({
|
|
|
1075
1087
|
homeIndicatorHeight: 34,
|
|
1076
1088
|
// 2026-07-10: cornerRadius corrected 58 → 53.9 to Apple's own framebuffer
|
|
1077
1089
|
// mask (extracted from the simdevicetype bundle PDF; see
|
|
1078
|
-
// packages/
|
|
1090
|
+
// packages/peach-engine/assets/device-frame-geometry). radius is a paint clip only — the
|
|
1079
1091
|
// calibrated conformance-oracle layout fields below are unchanged.
|
|
1080
1092
|
cornerRadius: cornerRadii(53.9),
|
|
1081
1093
|
continuousCornerRadius: cornerRadii(73.402),
|
|
@@ -1095,6 +1107,7 @@ var init_devices = __esm({
|
|
|
1095
1107
|
)
|
|
1096
1108
|
}),
|
|
1097
1109
|
"iphone-16-plus": iosDevice({
|
|
1110
|
+
model: "iphone-16-plus",
|
|
1098
1111
|
name: "iPhone 16 Plus",
|
|
1099
1112
|
width: 430,
|
|
1100
1113
|
height: 932,
|
|
@@ -1117,6 +1130,7 @@ var init_devices = __esm({
|
|
|
1117
1130
|
)
|
|
1118
1131
|
}),
|
|
1119
1132
|
"iphone-16-pro": iosDevice({
|
|
1133
|
+
model: "iphone-16-pro",
|
|
1120
1134
|
name: "iPhone 16 Pro",
|
|
1121
1135
|
width: 402,
|
|
1122
1136
|
height: 874,
|
|
@@ -1141,6 +1155,7 @@ var init_devices = __esm({
|
|
|
1141
1155
|
)
|
|
1142
1156
|
}),
|
|
1143
1157
|
"iphone-16-pro-max": iosDevice({
|
|
1158
|
+
model: "iphone-16-pro-max",
|
|
1144
1159
|
name: "iPhone 16 Pro Max",
|
|
1145
1160
|
width: 440,
|
|
1146
1161
|
height: 956,
|
|
@@ -1166,6 +1181,7 @@ var init_devices = __esm({
|
|
|
1166
1181
|
)
|
|
1167
1182
|
}),
|
|
1168
1183
|
"iphone-17": iosDevice({
|
|
1184
|
+
model: "iphone-17",
|
|
1169
1185
|
name: "iPhone 17",
|
|
1170
1186
|
width: 402,
|
|
1171
1187
|
height: 874,
|
|
@@ -1189,6 +1205,7 @@ var init_devices = __esm({
|
|
|
1189
1205
|
)
|
|
1190
1206
|
}),
|
|
1191
1207
|
"iphone-17-air": iosDevice({
|
|
1208
|
+
model: "iphone-17-air",
|
|
1192
1209
|
// apple markets this as "iphone air" (not "iphone 17 air"). the real air
|
|
1193
1210
|
// is 420x912 with thin bezels and a lower-sitting island. it is not the
|
|
1194
1211
|
// 430x932 Plus body it used to be cloned from.
|
|
@@ -1229,6 +1246,7 @@ var init_devices = __esm({
|
|
|
1229
1246
|
)
|
|
1230
1247
|
}),
|
|
1231
1248
|
"iphone-17-pro": iosDevice({
|
|
1249
|
+
model: "iphone-17-pro",
|
|
1232
1250
|
name: "iPhone 17 Pro",
|
|
1233
1251
|
width: 402,
|
|
1234
1252
|
height: 874,
|
|
@@ -1256,6 +1274,7 @@ var init_devices = __esm({
|
|
|
1256
1274
|
)
|
|
1257
1275
|
}),
|
|
1258
1276
|
"iphone-17-pro-max": iosDevice({
|
|
1277
|
+
model: "iphone-17-pro-max",
|
|
1259
1278
|
name: "iPhone 17 Pro Max",
|
|
1260
1279
|
width: 440,
|
|
1261
1280
|
height: 956,
|
|
@@ -1285,6 +1304,7 @@ var init_devices = __esm({
|
|
|
1285
1304
|
// measurements are still settling (nate, 2026-09-15).
|
|
1286
1305
|
developmentOnly: true,
|
|
1287
1306
|
...iosDevice({
|
|
1307
|
+
model: "iphone-duo",
|
|
1288
1308
|
name: "iPhone Duo",
|
|
1289
1309
|
width: 466,
|
|
1290
1310
|
height: 678,
|
|
@@ -1300,12 +1320,21 @@ var init_devices = __esm({
|
|
|
1300
1320
|
bottomRight: 61,
|
|
1301
1321
|
bottomLeft: 5
|
|
1302
1322
|
},
|
|
1303
|
-
// display edge to silhouette
|
|
1304
|
-
//
|
|
1305
|
-
|
|
1323
|
+
// display edge to silhouette, measured off apple's 2d outer product art
|
|
1324
|
+
// at 3x. the barrel is not part of the body: it protrudes 11.67pt past
|
|
1325
|
+
// the left silhouette, so the full outer width is frame + protrusion.
|
|
1326
|
+
frameInsets: { top: 16.3333, right: 16.3333, bottom: 16, left: 14 },
|
|
1327
|
+
// the spine is a flat cut, so its corners are tiny; the free side keeps
|
|
1328
|
+
// the 75pt body curve the pro bodies use.
|
|
1329
|
+
frameCornerRadius: {
|
|
1330
|
+
topLeft: 4.3333,
|
|
1331
|
+
topRight: 75,
|
|
1332
|
+
bottomRight: 75,
|
|
1333
|
+
bottomLeft: 3.3333
|
|
1334
|
+
},
|
|
1306
1335
|
housing: {
|
|
1307
|
-
rail: { top:
|
|
1308
|
-
hingeBarrel: { width:
|
|
1336
|
+
rail: { top: 7.5, right: 8, bottom: 7.3333, left: 5.3333 },
|
|
1337
|
+
hingeBarrel: { width: 16.6667, endInset: 7.3333, protrusion: 11.6667 }
|
|
1309
1338
|
},
|
|
1310
1339
|
dynamicIsland: null,
|
|
1311
1340
|
// 84pt trailing Vertical Bar on the outer display (Apple iOS 27 UI kit).
|
|
@@ -1325,6 +1354,7 @@ var init_devices = __esm({
|
|
|
1325
1354
|
}
|
|
1326
1355
|
},
|
|
1327
1356
|
"pixel-8": {
|
|
1357
|
+
model: "pixel-8",
|
|
1328
1358
|
platform: "android",
|
|
1329
1359
|
name: "Pixel 8",
|
|
1330
1360
|
width: PIXEL_8_WIDTH,
|
|
@@ -1373,6 +1403,7 @@ var init_devices = __esm({
|
|
|
1373
1403
|
hardwareButtons: PIXEL_HARDWARE_BUTTONS
|
|
1374
1404
|
},
|
|
1375
1405
|
"pixel-8-three-button": {
|
|
1406
|
+
model: "pixel-8-three-button",
|
|
1376
1407
|
platform: "android",
|
|
1377
1408
|
name: "Pixel 8 (3-button)",
|
|
1378
1409
|
width: PIXEL_8_WIDTH,
|
|
@@ -1418,6 +1449,7 @@ var init_devices = __esm({
|
|
|
1418
1449
|
hardwareButtons: PIXEL_HARDWARE_BUTTONS
|
|
1419
1450
|
},
|
|
1420
1451
|
"pixel-9-pro-xl": {
|
|
1452
|
+
model: "pixel-9-pro-xl",
|
|
1421
1453
|
platform: "android",
|
|
1422
1454
|
name: "Pixel 9 Pro XL",
|
|
1423
1455
|
width: 448,
|
|
@@ -1454,6 +1486,7 @@ var init_devices = __esm({
|
|
|
1454
1486
|
hardwareButtons: PIXEL_HARDWARE_BUTTONS
|
|
1455
1487
|
},
|
|
1456
1488
|
"pixel-10": {
|
|
1489
|
+
model: "pixel-10",
|
|
1457
1490
|
platform: "android",
|
|
1458
1491
|
name: "Pixel 10",
|
|
1459
1492
|
width: 360,
|
|
@@ -1491,6 +1524,7 @@ var init_devices = __esm({
|
|
|
1491
1524
|
hardwareButtons: PIXEL_HARDWARE_BUTTONS
|
|
1492
1525
|
},
|
|
1493
1526
|
"galaxy-s24": {
|
|
1527
|
+
model: "galaxy-s24",
|
|
1494
1528
|
platform: "android",
|
|
1495
1529
|
name: "Galaxy S24",
|
|
1496
1530
|
width: 360,
|
|
@@ -1528,6 +1562,7 @@ var init_devices = __esm({
|
|
|
1528
1562
|
hardwareButtons: GALAXY_HARDWARE_BUTTONS
|
|
1529
1563
|
},
|
|
1530
1564
|
"galaxy-s24-ultra": {
|
|
1565
|
+
model: "galaxy-s24-ultra",
|
|
1531
1566
|
platform: "android",
|
|
1532
1567
|
name: "Galaxy S24 Ultra",
|
|
1533
1568
|
width: 384,
|
|
@@ -1576,7 +1611,7 @@ var init_devices = __esm({
|
|
|
1576
1611
|
// src/metro-production-bundle.ts
|
|
1577
1612
|
function toRNXProductionBundleUrl(bundleUrl) {
|
|
1578
1613
|
const relative2 = bundleUrl.startsWith("/");
|
|
1579
|
-
const url = new URL(bundleUrl, "http://
|
|
1614
|
+
const url = new URL(bundleUrl, "http://peachsim.local");
|
|
1580
1615
|
url.searchParams.set("dev", "false");
|
|
1581
1616
|
url.searchParams.set("hot", "false");
|
|
1582
1617
|
url.searchParams.set("minify", "true");
|
|
@@ -2571,7 +2606,7 @@ var import_metro_production_bundle, import_terser, MODULE_PATHS_REQUIRED, SOURCE
|
|
|
2571
2606
|
var init_metroCloudArtifact = __esm({
|
|
2572
2607
|
"../contrast-bundler/src/metroCloudArtifact.ts"() {
|
|
2573
2608
|
"use strict";
|
|
2574
|
-
import_metro_production_bundle = require("
|
|
2609
|
+
import_metro_production_bundle = require("peachsim/metro-production-bundle");
|
|
2575
2610
|
import_terser = require("terser");
|
|
2576
2611
|
init_metroAssetArtifact();
|
|
2577
2612
|
init_metroDebugSourceMap();
|
|
@@ -2586,7 +2621,7 @@ var init_metroCloudArtifact = __esm({
|
|
|
2586
2621
|
}
|
|
2587
2622
|
});
|
|
2588
2623
|
|
|
2589
|
-
// ../
|
|
2624
|
+
// ../peach-engine/src/metro-fingerprint-registry-client.ts
|
|
2590
2625
|
function pointerUrl(options) {
|
|
2591
2626
|
return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
|
|
2592
2627
|
}
|
|
@@ -2751,19 +2786,19 @@ async function loadMetroFingerprintRegistry(options = {}) {
|
|
|
2751
2786
|
}
|
|
2752
2787
|
var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
|
|
2753
2788
|
var init_metro_fingerprint_registry_client = __esm({
|
|
2754
|
-
"../
|
|
2789
|
+
"../peach-engine/src/metro-fingerprint-registry-client.ts"() {
|
|
2755
2790
|
"use strict";
|
|
2756
|
-
import_metro_fingerprint_registry = require("
|
|
2791
|
+
import_metro_fingerprint_registry = require("peachsim/metro-fingerprint-registry");
|
|
2757
2792
|
REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
|
|
2758
2793
|
DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
|
|
2759
2794
|
memoryReceipts = /* @__PURE__ */ new Map();
|
|
2760
2795
|
}
|
|
2761
2796
|
});
|
|
2762
2797
|
|
|
2763
|
-
// ../compat/src/stub-manifest.ts
|
|
2798
|
+
// ../peach-compat/src/stub-manifest.ts
|
|
2764
2799
|
var COMPAT_REACT_NATIVE_DEEP_STUBS;
|
|
2765
2800
|
var init_stub_manifest = __esm({
|
|
2766
|
-
"../compat/src/stub-manifest.ts"() {
|
|
2801
|
+
"../peach-compat/src/stub-manifest.ts"() {
|
|
2767
2802
|
"use strict";
|
|
2768
2803
|
COMPAT_REACT_NATIVE_DEEP_STUBS = {
|
|
2769
2804
|
usePressability: {
|
|
@@ -2921,17 +2956,17 @@ var init_stub_manifest = __esm({
|
|
|
2921
2956
|
}
|
|
2922
2957
|
});
|
|
2923
2958
|
|
|
2924
|
-
// ../
|
|
2959
|
+
// ../peach-engine/src/metro-asset-path.ts
|
|
2925
2960
|
function isMetroAssetRegistryModulePath(modulePath) {
|
|
2926
|
-
return modulePath.includes("polyfill:assets-registry") || modulePath.includes("@react-native/assets-registry/registry") || modulePath.includes("assets-registry/registry") || modulePath.includes("react-native/src/asset-registry");
|
|
2961
|
+
return modulePath.includes("polyfill:assets-registry") || modulePath.includes("@react-native/assets-registry/registry") || modulePath.includes("assets-registry/registry") || modulePath.includes("react-native/asset-registry") || modulePath.includes("react-native/src/asset-registry");
|
|
2927
2962
|
}
|
|
2928
2963
|
var init_metro_asset_path = __esm({
|
|
2929
|
-
"../
|
|
2964
|
+
"../peach-engine/src/metro-asset-path.ts"() {
|
|
2930
2965
|
"use strict";
|
|
2931
2966
|
}
|
|
2932
2967
|
});
|
|
2933
2968
|
|
|
2934
|
-
// ../
|
|
2969
|
+
// ../peach-engine/src/stub-pattern-matcher.ts
|
|
2935
2970
|
function matchesModuleEntry(modulePath, pattern) {
|
|
2936
2971
|
if (!modulePath || !pattern) return false;
|
|
2937
2972
|
if (modulePath === pattern) return true;
|
|
@@ -2959,12 +2994,12 @@ function isReactNativeWorkletsGeneratedWorkletModule(modulePath) {
|
|
|
2959
2994
|
return subpath?.startsWith(".worklets/") === true;
|
|
2960
2995
|
}
|
|
2961
2996
|
var init_stub_pattern_matcher = __esm({
|
|
2962
|
-
"../
|
|
2997
|
+
"../peach-engine/src/stub-pattern-matcher.ts"() {
|
|
2963
2998
|
"use strict";
|
|
2964
2999
|
}
|
|
2965
3000
|
});
|
|
2966
3001
|
|
|
2967
|
-
// ../
|
|
3002
|
+
// ../peach-engine/src/metro-fingerprint.ts
|
|
2968
3003
|
function compareStrings(left, right) {
|
|
2969
3004
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
2970
3005
|
}
|
|
@@ -3528,11 +3563,11 @@ async function inferMetroModuleIdentity(args) {
|
|
|
3528
3563
|
}
|
|
3529
3564
|
var import_metro_production_bundle2, import_react_native_host_modules, IDENTIFIER, MAX_CANDIDATE_EMBEDDINGS, MIN_DUPLICATE_ROOT_EXACT_FACTORIES, REQUIRED_INTERCEPT_PACKAGES;
|
|
3530
3565
|
var init_metro_fingerprint = __esm({
|
|
3531
|
-
"../
|
|
3566
|
+
"../peach-engine/src/metro-fingerprint.ts"() {
|
|
3532
3567
|
"use strict";
|
|
3533
3568
|
init_stub_manifest();
|
|
3534
|
-
import_metro_production_bundle2 = require("
|
|
3535
|
-
import_react_native_host_modules = require("
|
|
3569
|
+
import_metro_production_bundle2 = require("peachsim/metro-production-bundle");
|
|
3570
|
+
import_react_native_host_modules = require("peachsim/react-native-host-modules");
|
|
3536
3571
|
init_metro_asset_path();
|
|
3537
3572
|
init_stub_pattern_matcher();
|
|
3538
3573
|
IDENTIFIER = "[A-Za-z_$][A-Za-z0-9_$]*";
|
|
@@ -5087,7 +5122,7 @@ async function resolveLocalIconPath(hostname, port, rawIcon) {
|
|
|
5087
5122
|
const res = await httpGet(hostname, port, candidate, "HEAD", ENRICH_TIMEOUT_MS);
|
|
5088
5123
|
if (res?.statusCode === 200) {
|
|
5089
5124
|
localIconPathCache.set(port, candidate);
|
|
5090
|
-
|
|
5125
|
+
invalidatePortCache(port);
|
|
5091
5126
|
return;
|
|
5092
5127
|
}
|
|
5093
5128
|
}
|
|
@@ -5209,7 +5244,7 @@ async function fetchManifestEnrichment(result, buildIconProxyUrl) {
|
|
|
5209
5244
|
iconPath: parsed.iconPath,
|
|
5210
5245
|
bundleId: parsed.bundleId
|
|
5211
5246
|
});
|
|
5212
|
-
|
|
5247
|
+
invalidatePortCache(result.port);
|
|
5213
5248
|
}
|
|
5214
5249
|
var knownNonPatched = /* @__PURE__ */ new Set();
|
|
5215
5250
|
var knownNonExpo = /* @__PURE__ */ new Set();
|
|
@@ -5249,16 +5284,19 @@ async function probePort(port, buildIconProxyUrl, listeningProcess) {
|
|
|
5249
5284
|
const framework = launchUrl2.includes(
|
|
5250
5285
|
"/one/metro-entry.bundle"
|
|
5251
5286
|
) ? "one" : "expo";
|
|
5252
|
-
return
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5287
|
+
return enrichWithManifest(
|
|
5288
|
+
applyManifest(
|
|
5289
|
+
{
|
|
5290
|
+
port,
|
|
5291
|
+
framework,
|
|
5292
|
+
bundleUrl: withRuntimeConfig(port, launchUrl2, owner.cwd),
|
|
5293
|
+
hmrUrl: `${buildLoopbackProbeBaseUrl("ws:", probeHostname, port)}/hot`,
|
|
5294
|
+
lastSeen: Date.now(),
|
|
5295
|
+
...owner
|
|
5296
|
+
},
|
|
5297
|
+
manifestRes,
|
|
5298
|
+
buildIconProxyUrl
|
|
5299
|
+
),
|
|
5262
5300
|
buildIconProxyUrl
|
|
5263
5301
|
);
|
|
5264
5302
|
}
|
|
@@ -5336,6 +5374,11 @@ function isSootSimSelfServer(server) {
|
|
|
5336
5374
|
return false;
|
|
5337
5375
|
}
|
|
5338
5376
|
var portCache = /* @__PURE__ */ new Map();
|
|
5377
|
+
var portCacheInvalidatedAt = /* @__PURE__ */ new Map();
|
|
5378
|
+
function invalidatePortCache(port) {
|
|
5379
|
+
portCache.delete(port);
|
|
5380
|
+
portCacheInvalidatedAt.set(port, Date.now());
|
|
5381
|
+
}
|
|
5339
5382
|
var NEGATIVE_CACHE_TTL_MS = 3e4;
|
|
5340
5383
|
var WEAK_RESULT_CACHE_TTL_MS = 1500;
|
|
5341
5384
|
function isWeakCachedResult(result) {
|
|
@@ -5390,6 +5433,9 @@ async function scanDevServers(opts = {}) {
|
|
|
5390
5433
|
for (const p of [...localIconPathCache.keys()]) {
|
|
5391
5434
|
if (!currentPorts.has(p)) localIconPathCache.delete(p);
|
|
5392
5435
|
}
|
|
5436
|
+
for (const p of [...portCacheInvalidatedAt.keys()]) {
|
|
5437
|
+
if (!currentPorts.has(p)) portCacheInvalidatedAt.delete(p);
|
|
5438
|
+
}
|
|
5393
5439
|
const results = [];
|
|
5394
5440
|
const toProbe = [];
|
|
5395
5441
|
for (const { port, pid } of processes) {
|
|
@@ -5408,12 +5454,16 @@ async function scanDevServers(opts = {}) {
|
|
|
5408
5454
|
toProbe.push({ port, pid });
|
|
5409
5455
|
}
|
|
5410
5456
|
if (toProbe.length > 0) {
|
|
5457
|
+
const scanStartedAt = Date.now();
|
|
5411
5458
|
const probed = await Promise.all(
|
|
5412
5459
|
toProbe.map((p) => probePort(p.port, opts.buildIconProxyUrl, p))
|
|
5413
5460
|
);
|
|
5414
5461
|
probed.forEach((result, i) => {
|
|
5415
5462
|
const { port, pid } = toProbe[i];
|
|
5416
|
-
|
|
5463
|
+
const invalidatedAt = portCacheInvalidatedAt.get(port) ?? 0;
|
|
5464
|
+
if (pid !== 0 && invalidatedAt < scanStartedAt) {
|
|
5465
|
+
portCache.set(port, { pid, result, cachedAt: Date.now() });
|
|
5466
|
+
}
|
|
5417
5467
|
if (result) results.push(result);
|
|
5418
5468
|
});
|
|
5419
5469
|
}
|
|
@@ -5905,7 +5955,7 @@ function findMonorepoRoot() {
|
|
|
5905
5955
|
if (_monorepoRootCache !== void 0) return _monorepoRootCache;
|
|
5906
5956
|
let dir = import_path.default.dirname((0, import_url.fileURLToPath)(__sootsim_import_meta_url));
|
|
5907
5957
|
for (let i = 0; i < 12 && dir !== import_path.default.dirname(dir); i++) {
|
|
5908
|
-
if (import_fs.default.existsSync(import_path.default.join(dir, "packages/
|
|
5958
|
+
if (import_fs.default.existsSync(import_path.default.join(dir, "packages/peach-engine/package.json")) && import_fs.default.existsSync(import_path.default.join(dir, "public/sootsim"))) {
|
|
5909
5959
|
_monorepoRootCache = dir;
|
|
5910
5960
|
return dir;
|
|
5911
5961
|
}
|
|
@@ -5919,7 +5969,7 @@ function resolveDevCheckoutRuntimeRoot() {
|
|
|
5919
5969
|
const root = findMonorepoRoot();
|
|
5920
5970
|
if (!root) return null;
|
|
5921
5971
|
const devBuild = import_path.default.join(root, "public/sootsim");
|
|
5922
|
-
if (import_fs.default.existsSync(import_path.default.join(devBuild, "index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine/index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.js"))) {
|
|
5972
|
+
if (import_fs.default.existsSync(import_path.default.join(devBuild, "index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine/index.html")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.js")) && import_fs.default.existsSync(import_path.default.join(devBuild, "engine-tenant/worker.prod.js"))) {
|
|
5923
5973
|
return devBuild;
|
|
5924
5974
|
}
|
|
5925
5975
|
return null;
|
|
@@ -7398,6 +7448,32 @@ function headerOverridesFor(hostname) {
|
|
|
7398
7448
|
}
|
|
7399
7449
|
return void 0;
|
|
7400
7450
|
}
|
|
7451
|
+
var PUBLIC_RPC_TENANT = "rnx-public-rpc";
|
|
7452
|
+
var QUICKNODE_HOST_SUFFIX = ".quiknode.pro";
|
|
7453
|
+
var PUBLIC_RPC_BY_QUICKNODE_CHAIN = {
|
|
7454
|
+
"": "https://ethereum-rpc.publicnode.com",
|
|
7455
|
+
"arbitrum-mainnet": "https://arbitrum-one-rpc.publicnode.com",
|
|
7456
|
+
"avalanche-mainnet": "https://avalanche-c-chain-rpc.publicnode.com",
|
|
7457
|
+
"base-mainnet": "https://base-rpc.publicnode.com",
|
|
7458
|
+
"blast-mainnet": "https://blast-rpc.publicnode.com",
|
|
7459
|
+
bsc: "https://bsc-rpc.publicnode.com",
|
|
7460
|
+
"celo-mainnet": "https://celo-rpc.publicnode.com",
|
|
7461
|
+
matic: "https://polygon-bor-rpc.publicnode.com",
|
|
7462
|
+
optimism: "https://optimism-rpc.publicnode.com",
|
|
7463
|
+
"soneium-mainnet": "https://soneium-rpc.publicnode.com",
|
|
7464
|
+
"unichain-mainnet": "https://unichain-rpc.publicnode.com"
|
|
7465
|
+
};
|
|
7466
|
+
function resolveFetchProxyTargetUrl(requested) {
|
|
7467
|
+
const host = requested.hostname.toLowerCase();
|
|
7468
|
+
if (!host.endsWith(QUICKNODE_HOST_SUFFIX)) return requested;
|
|
7469
|
+
const tenant = host.slice(0, -QUICKNODE_HOST_SUFFIX.length);
|
|
7470
|
+
if (tenant !== PUBLIC_RPC_TENANT && !tenant.startsWith(`${PUBLIC_RPC_TENANT}.`)) {
|
|
7471
|
+
return requested;
|
|
7472
|
+
}
|
|
7473
|
+
const chain = tenant === PUBLIC_RPC_TENANT ? "" : tenant.slice(PUBLIC_RPC_TENANT.length + 1);
|
|
7474
|
+
const replacement = PUBLIC_RPC_BY_QUICKNODE_CHAIN[chain];
|
|
7475
|
+
return replacement ? new URL(replacement) : requested;
|
|
7476
|
+
}
|
|
7401
7477
|
function getFetchProxyTargetHeaders(targetUrl) {
|
|
7402
7478
|
const hostOverrides = headerOverridesFor(targetUrl.hostname);
|
|
7403
7479
|
return {
|
|
@@ -7518,7 +7594,7 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
7518
7594
|
}
|
|
7519
7595
|
let upstreamUrl;
|
|
7520
7596
|
try {
|
|
7521
|
-
upstreamUrl = new URL(targetUrl);
|
|
7597
|
+
upstreamUrl = resolveFetchProxyTargetUrl(new URL(targetUrl));
|
|
7522
7598
|
} catch {
|
|
7523
7599
|
applyFetchProxyCors(res);
|
|
7524
7600
|
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
@@ -7781,7 +7857,7 @@ async function openUrl(url, options = {}) {
|
|
|
7781
7857
|
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
7782
7858
|
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
7783
7859
|
|
|
7784
|
-
// ../
|
|
7860
|
+
// ../peach-box/src/planeProtocol.ts
|
|
7785
7861
|
var PLANE_FLAG_READ_ONLY = 1;
|
|
7786
7862
|
var PLANE_FLAG_BINARY = 2;
|
|
7787
7863
|
function encodeBase64(bytes) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.570 | (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;
|
|
@@ -78,6 +78,32 @@ function headerOverridesFor(hostname) {
|
|
|
78
78
|
}
|
|
79
79
|
return void 0;
|
|
80
80
|
}
|
|
81
|
+
var PUBLIC_RPC_TENANT = "rnx-public-rpc";
|
|
82
|
+
var QUICKNODE_HOST_SUFFIX = ".quiknode.pro";
|
|
83
|
+
var PUBLIC_RPC_BY_QUICKNODE_CHAIN = {
|
|
84
|
+
"": "https://ethereum-rpc.publicnode.com",
|
|
85
|
+
"arbitrum-mainnet": "https://arbitrum-one-rpc.publicnode.com",
|
|
86
|
+
"avalanche-mainnet": "https://avalanche-c-chain-rpc.publicnode.com",
|
|
87
|
+
"base-mainnet": "https://base-rpc.publicnode.com",
|
|
88
|
+
"blast-mainnet": "https://blast-rpc.publicnode.com",
|
|
89
|
+
bsc: "https://bsc-rpc.publicnode.com",
|
|
90
|
+
"celo-mainnet": "https://celo-rpc.publicnode.com",
|
|
91
|
+
matic: "https://polygon-bor-rpc.publicnode.com",
|
|
92
|
+
optimism: "https://optimism-rpc.publicnode.com",
|
|
93
|
+
"soneium-mainnet": "https://soneium-rpc.publicnode.com",
|
|
94
|
+
"unichain-mainnet": "https://unichain-rpc.publicnode.com"
|
|
95
|
+
};
|
|
96
|
+
function resolveFetchProxyTargetUrl(requested) {
|
|
97
|
+
const host = requested.hostname.toLowerCase();
|
|
98
|
+
if (!host.endsWith(QUICKNODE_HOST_SUFFIX)) return requested;
|
|
99
|
+
const tenant = host.slice(0, -QUICKNODE_HOST_SUFFIX.length);
|
|
100
|
+
if (tenant !== PUBLIC_RPC_TENANT && !tenant.startsWith(`${PUBLIC_RPC_TENANT}.`)) {
|
|
101
|
+
return requested;
|
|
102
|
+
}
|
|
103
|
+
const chain = tenant === PUBLIC_RPC_TENANT ? "" : tenant.slice(PUBLIC_RPC_TENANT.length + 1);
|
|
104
|
+
const replacement = PUBLIC_RPC_BY_QUICKNODE_CHAIN[chain];
|
|
105
|
+
return replacement ? new URL(replacement) : requested;
|
|
106
|
+
}
|
|
81
107
|
function getFetchProxyTargetHeaders(targetUrl) {
|
|
82
108
|
const hostOverrides = headerOverridesFor(targetUrl.hostname);
|
|
83
109
|
return {
|
|
@@ -201,7 +227,7 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
201
227
|
}
|
|
202
228
|
let upstreamUrl;
|
|
203
229
|
try {
|
|
204
|
-
upstreamUrl = new URL(targetUrl);
|
|
230
|
+
upstreamUrl = resolveFetchProxyTargetUrl(new URL(targetUrl));
|
|
205
231
|
} catch {
|
|
206
232
|
applyFetchProxyCors(res);
|
|
207
233
|
res.writeHead(400, { "Content-Type": "text/plain" });
|