peachsim 0.1.527
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/LICENSE +22 -0
- package/README.md +640 -0
- package/cli/app-config.ts +82 -0
- package/cli/app-fonts.ts +388 -0
- package/cli/app-project.ts +59 -0
- package/cli/app-splash.ts +171 -0
- package/cli/app-state-reset.ts +26 -0
- package/cli/auth.ts +184 -0
- package/cli/bin.ts +59 -0
- package/cli/bridge-diagnostics.ts +226 -0
- package/cli/bridge-flow-runner.ts +2806 -0
- package/cli/browser-backend.ts +44 -0
- package/cli/browser-evals.ts +96 -0
- package/cli/cli-update.ts +261 -0
- package/cli/cloud-client.ts +1530 -0
- package/cli/cloud-dispatch.ts +206 -0
- package/cli/cloud-session.ts +227 -0
- package/cli/command-contract.ts +221 -0
- package/cli/command-registry.ts +304 -0
- package/cli/commands/agent-wrapper.ts +1048 -0
- package/cli/commands/agent.ts +439 -0
- package/cli/commands/app-fonts.ts +99 -0
- package/cli/commands/assert.ts +542 -0
- package/cli/commands/auth.ts +71 -0
- package/cli/commands/box/bundle-plane.ts +71 -0
- package/cli/commands/box/checkout-plane.ts +256 -0
- package/cli/commands/box/plane-share.ts +208 -0
- package/cli/commands/box/rnx-command.ts +60 -0
- package/cli/commands/box/search-command.ts +157 -0
- package/cli/commands/box.ts +925 -0
- package/cli/commands/camera.ts +266 -0
- package/cli/commands/cleanup.ts +169 -0
- package/cli/commands/compat.ts +176 -0
- package/cli/commands/config.ts +34 -0
- package/cli/commands/control.ts +2154 -0
- package/cli/commands/cpu-profile.ts +941 -0
- package/cli/commands/daemon-mac-app.ts +165 -0
- package/cli/commands/daemon.ts +800 -0
- package/cli/commands/debug.ts +751 -0
- package/cli/commands/desktop.ts +39 -0
- package/cli/commands/detect.ts +201 -0
- package/cli/commands/detox.ts +481 -0
- package/cli/commands/device.ts +134 -0
- package/cli/commands/diagnose.ts +589 -0
- package/cli/commands/do-chain.ts +408 -0
- package/cli/commands/electron.ts +94 -0
- package/cli/commands/film.ts +379 -0
- package/cli/commands/flow.ts +1240 -0
- package/cli/commands/inspect/actions.ts +516 -0
- package/cli/commands/inspect/core.ts +2086 -0
- package/cli/commands/inspect/count.ts +17 -0
- package/cli/commands/inspect/describe.ts +119 -0
- package/cli/commands/inspect/env.ts +25 -0
- package/cli/commands/inspect/find.ts +169 -0
- package/cli/commands/inspect/get-layout.ts +53 -0
- package/cli/commands/inspect/keyboard.ts +54 -0
- package/cli/commands/inspect/list.ts +175 -0
- package/cli/commands/inspect/memory.ts +215 -0
- package/cli/commands/inspect/redaction.ts +39 -0
- package/cli/commands/inspect/resolve-target.ts +77 -0
- package/cli/commands/inspect/screens.ts +78 -0
- package/cli/commands/inspect/settle.ts +32 -0
- package/cli/commands/inspect/settling.ts +197 -0
- package/cli/commands/inspect/shared.ts +259 -0
- package/cli/commands/inspect/sleep.ts +15 -0
- package/cli/commands/inspect/tree.ts +23 -0
- package/cli/commands/inspect/url.ts +17 -0
- package/cli/commands/inspect/wait-event.ts +211 -0
- package/cli/commands/inspect/wait-idle.ts +25 -0
- package/cli/commands/inspect/wait-ready.ts +87 -0
- package/cli/commands/inspect/wait-selector.ts +59 -0
- package/cli/commands/inspect/wait.ts +32 -0
- package/cli/commands/inspect.ts +4738 -0
- package/cli/commands/install-cli.ts +275 -0
- package/cli/commands/install-desktop.ts +385 -0
- package/cli/commands/login.ts +357 -0
- package/cli/commands/logout.ts +24 -0
- package/cli/commands/maestro-generate.ts +375 -0
- package/cli/commands/maestro.ts +536 -0
- package/cli/commands/mode.ts +58 -0
- package/cli/commands/no-bridge-hint.ts +80 -0
- package/cli/commands/perf.ts +67 -0
- package/cli/commands/permissions.ts +203 -0
- package/cli/commands/platform.ts +410 -0
- package/cli/commands/preview.ts +103 -0
- package/cli/commands/profile.ts +106 -0
- package/cli/commands/react.ts +353 -0
- package/cli/commands/record.ts +1435 -0
- package/cli/commands/report-issue.ts +305 -0
- package/cli/commands/reset.ts +89 -0
- package/cli/commands/runtime.ts +348 -0
- package/cli/commands/screenshot-command.ts +106 -0
- package/cli/commands/screenshot-layers.ts +144 -0
- package/cli/commands/screenshot-mode.ts +38 -0
- package/cli/commands/screenshot.ts +492 -0
- package/cli/commands/screenshots-capture.ts +608 -0
- package/cli/commands/screenshots.ts +127 -0
- package/cli/commands/serve.ts +139 -0
- package/cli/commands/setup.ts +416 -0
- package/cli/commands/shell-boolean-mode.ts +82 -0
- package/cli/commands/skills.ts +468 -0
- package/cli/commands/slides.ts +357 -0
- package/cli/commands/state.ts +94 -0
- package/cli/commands/storage.ts +58 -0
- package/cli/commands/telemetry.ts +55 -0
- package/cli/commands/test.ts +535 -0
- package/cli/commands/three-mode.ts +771 -0
- package/cli/commands/timeline.ts +121 -0
- package/cli/commands/upgrade.ts +167 -0
- package/cli/commands/upload.ts +1203 -0
- package/cli/commands/version.ts +63 -0
- package/cli/commands/welcome.ts +17 -0
- package/cli/commands/what-happened.ts +328 -0
- package/cli/current-sim.ts +217 -0
- package/cli/desktop-companion.ts +315 -0
- package/cli/drivers/electron.ts +70 -0
- package/cli/drivers/index.ts +20 -0
- package/cli/drivers/playwright-provisioning.ts +184 -0
- package/cli/drivers/playwright-sim-host.ts +537 -0
- package/cli/drivers/playwright.ts +209 -0
- package/cli/drivers/registry.ts +65 -0
- package/cli/drivers/types.ts +102 -0
- package/cli/flow-export.ts +55 -0
- package/cli/flow-file.ts +142 -0
- package/cli/flow-live-status.ts +126 -0
- package/cli/flow-session.ts +140 -0
- package/cli/help-core.ts +143 -0
- package/cli/help.ts +44 -0
- package/cli/hidden-runtime-alias.ts +19 -0
- package/cli/hints.ts +214 -0
- package/cli/inspect-notice-state.ts +114 -0
- package/cli/internal-child.ts +176 -0
- package/cli/maestro-js.ts +323 -0
- package/cli/main.ts +704 -0
- package/cli/open-url.ts +8 -0
- package/cli/outbound-endpoints.ts +830 -0
- package/cli/parent-pid.ts +204 -0
- package/cli/parse-args.ts +189 -0
- package/cli/privacy.ts +53 -0
- package/cli/prompt.ts +56 -0
- package/cli/recording-access.ts +108 -0
- package/cli/registry.ts +2 -0
- package/cli/resolve-assets.ts +63 -0
- package/cli/rnx-in-process.ts +98 -0
- package/cli/run-registry.ts +226 -0
- package/cli/run-rnx-core.ts +148 -0
- package/cli/run-rnx.ts +137 -0
- package/cli/runtime-notes.ts +66 -0
- package/cli/runtime-summary.ts +25 -0
- package/cli/secure-file.ts +31 -0
- package/cli/self-invocation.ts +58 -0
- package/cli/send-to-box.ts +109 -0
- package/cli/setup-repository.ts +191 -0
- package/cli/shell-init.ts +98 -0
- package/cli/standalone.ts +4 -0
- package/cli/telemetry.ts +84 -0
- package/cli/ui.ts +68 -0
- package/cli/ws-bridge.ts +1020 -0
- package/detox/attempt-events.cjs +23 -0
- package/detox/colors.ts +54 -0
- package/detox/config-loader.ts +135 -0
- package/detox/element-types.ts +48 -0
- package/detox/expectations.ts +534 -0
- package/detox/gestures.ts +501 -0
- package/detox/index.ts +2694 -0
- package/detox/jest-preset.cjs +29 -0
- package/detox/jest-setup-after-env.cjs +22 -0
- package/detox/matchers.ts +30 -0
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/detox/navigation-lifecycle.ts +290 -0
- package/detox/navigation.ts +43 -0
- package/detox/proof-frame.cjs +114 -0
- package/detox/record-block-execution.cjs +78 -0
- package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
- package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
- package/detox/screenshots/color-test-rest-norngh.png +0 -0
- package/detox/screenshots/theme-blue-toggle.png +0 -0
- package/detox/screenshots/theme-blue.png +0 -0
- package/detox/screenshots/theme-red-toggle.png +0 -0
- package/detox/screenshots/theme-red.png +0 -0
- package/dist-lib/agent-daemon-client.cjs +502 -0
- package/dist-lib/agent-events.cjs +48 -0
- package/dist-lib/agent-identity.cjs +53 -0
- package/dist-lib/agent-sessions.cjs +759 -0
- package/dist-lib/attached-projects.cjs +526 -0
- package/dist-lib/auth/shared-session.cjs +208 -0
- package/dist-lib/backend-origin.cjs +88 -0
- package/dist-lib/beta.cjs +41 -0
- package/dist-lib/beta.mjs +13 -0
- package/dist-lib/bridge-constants.cjs +161 -0
- package/dist-lib/bridge-contract-input.cjs +451 -0
- package/dist-lib/bridge-contract-input.mjs +414 -0
- package/dist-lib/bridge-contract.cjs +130 -0
- package/dist-lib/bridge-contract.mjs +94 -0
- package/dist-lib/capture-contract.cjs +220 -0
- package/dist-lib/capture-contract.mjs +190 -0
- package/dist-lib/cli-constants.cjs +32 -0
- package/dist-lib/cloud-contract.cjs +194 -0
- package/dist-lib/cloud-contract.mjs +145 -0
- package/dist-lib/cloud.cjs +670 -0
- package/dist-lib/cloud.mjs +639 -0
- package/dist-lib/config.cjs +96 -0
- package/dist-lib/detox/index.cjs +3789 -0
- package/dist-lib/detox/jest-preset.cjs +29 -0
- package/dist-lib/dev-bundle-resolution.cjs +290 -0
- package/dist-lib/home-paths.cjs +638 -0
- package/dist-lib/host/bridge-host.cjs +10903 -0
- package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
- package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
- package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
- package/dist-lib/host/replacement-module-handler.cjs +469 -0
- package/dist-lib/host/websocket-proxy.cjs +298 -0
- package/dist-lib/index.cjs +4268 -0
- package/dist-lib/jump-to-source-babel.cjs +93 -0
- package/dist-lib/jump-to-source-native.cjs +112 -0
- package/dist-lib/menu.cjs +646 -0
- package/dist-lib/menu.mjs +604 -0
- package/dist-lib/metro-fingerprint-registry.cjs +186 -0
- package/dist-lib/metro-fingerprint-registry.mjs +156 -0
- package/dist-lib/metro-production-bundle.cjs +329 -0
- package/dist-lib/metro-production-bundle.mjs +295 -0
- package/dist-lib/metro.cjs +904 -0
- package/dist-lib/profiles.cjs +246 -0
- package/dist-lib/public-brand.cjs +39 -0
- package/dist-lib/react-native-host-modules.cjs +51 -0
- package/dist-lib/react-native-host-modules.mjs +25 -0
- package/dist-lib/render-mode.cjs +54 -0
- package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
- package/dist-lib/sdk.cjs +2433 -0
- package/dist-lib/sdk.mjs +2336 -0
- package/dist-lib/skills.cjs +39132 -0
- package/dist-lib/swift-submit.cjs +92 -0
- package/dist-lib/swift-submit.mjs +65 -0
- package/dist-lib/swift.cjs +1646 -0
- package/dist-lib/vite.cjs +1591 -0
- package/package.json +290 -0
- package/scripts/dev-server-scanner.ts +1291 -0
- package/scripts/optional-demo-registry.ts +113 -0
- package/skills/contrast/SKILL.md +165 -0
- package/skills/rnx-debug/SKILL.md +433 -0
- package/skills/rnx-perf/SKILL.md +399 -0
- package/skills/rnx-setup/SKILL.md +172 -0
- package/skills/rnx-test/SKILL.md +321 -0
- package/skills/rnx-visual/SKILL.md +126 -0
- package/src/agent-daemon-client.ts +410 -0
- package/src/agent-events.ts +71 -0
- package/src/agent-identity.ts +23 -0
- package/src/agent-prompt.ts +71 -0
- package/src/agent-sessions.ts +580 -0
- package/src/app-url.ts +39 -0
- package/src/attached-projects.ts +539 -0
- package/src/auth/shared-session.ts +235 -0
- package/src/backend-origin.ts +70 -0
- package/src/beta.ts +19 -0
- package/src/bridge-constants.ts +175 -0
- package/src/bridge-contract-input.ts +502 -0
- package/src/bridge-contract.ts +558 -0
- package/src/browser-cache.ts +16 -0
- package/src/capture-contract.ts +587 -0
- package/src/cli-constants.ts +1 -0
- package/src/cli-version.ts +40 -0
- package/src/cloud-contract.ts +274 -0
- package/src/cloud.ts +762 -0
- package/src/codex-client.ts +234 -0
- package/src/config.ts +132 -0
- package/src/connect.ts +101 -0
- package/src/dev-bundle-resolution.ts +346 -0
- package/src/dev-server-open.ts +198 -0
- package/src/disk-cleanup.ts +540 -0
- package/src/flow-timeout-scale.ts +15 -0
- package/src/home-paths.ts +806 -0
- package/src/host/agent-host.ts +666 -0
- package/src/host/bridge-host.ts +2788 -0
- package/src/host/fetch-proxy-handler.ts +449 -0
- package/src/host/fetch-proxy-overrides.ts +51 -0
- package/src/host/open-url.ts +89 -0
- package/src/host/plane-host.ts +203 -0
- package/src/host/replacement-module-handler.ts +158 -0
- package/src/host/websocket-proxy.ts +315 -0
- package/src/index.ts +71 -0
- package/src/jump-to-source-babel.ts +135 -0
- package/src/jump-to-source-native.ts +102 -0
- package/src/menu.ts +777 -0
- package/src/metro-fingerprint-registry.ts +302 -0
- package/src/metro-plugin.ts +341 -0
- package/src/metro-production-bundle.ts +471 -0
- package/src/native-dev-bundle-url.ts +118 -0
- package/src/native-seam-manifest.ts +341 -0
- package/src/playwright-host-log.ts +16 -0
- package/src/plist.ts +27 -0
- package/src/poll-until.ts +123 -0
- package/src/profiles.ts +179 -0
- package/src/public-brand.ts +9 -0
- package/src/react-native-host-modules.ts +26 -0
- package/src/render-mode.ts +27 -0
- package/src/rolldown-plugin-swift.ts +240 -0
- package/src/runtime-assets.ts +233 -0
- package/src/runtime-delivery.ts +54 -0
- package/src/screenshots/compose.ts +422 -0
- package/src/screenshots/frame-compose.ts +514 -0
- package/src/screenshots/orchestrate.ts +256 -0
- package/src/screenshots/org-deck.ts +91 -0
- package/src/screenshots/registry.ts +58 -0
- package/src/screenshots/schema.ts +364 -0
- package/src/sdk.ts +15 -0
- package/src/settings-bundle.ts +418 -0
- package/src/shell-bridge-identity.ts +15 -0
- package/src/sim-client.ts +697 -0
- package/src/skills/builtin/a11y-review.ts +132 -0
- package/src/skills/builtin/compat-check.ts +71 -0
- package/src/skills/builtin/maestro-test.ts +121 -0
- package/src/skills/builtin/perf-profile.ts +90 -0
- package/src/skills/builtin/screenshot-all.ts +52 -0
- package/src/skills/builtin/visual-diff.ts +100 -0
- package/src/skills/registry.ts +107 -0
- package/src/skills/types.ts +41 -0
- package/src/swift-submit.ts +185 -0
- package/src/swift.ts +7 -0
- package/src/team-machine-prompt.ts +73 -0
- package/src/vite-plugin-one.ts +264 -0
- package/src/vite-plugin-swift.ts +620 -0
- package/src/vite-plugin.ts +1946 -0
- package/src/worklets-babel.ts +250 -0
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
// public, runtime-neutral screen capture contract. semantic evidence and pixel
|
|
2
|
+
// evidence are separate because neither one proves the other.
|
|
3
|
+
|
|
4
|
+
export const RNX_SCREEN_CAPTURE_VERSION = 1 as const
|
|
5
|
+
|
|
6
|
+
export interface RnxCaptureRect {
|
|
7
|
+
x: number
|
|
8
|
+
y: number
|
|
9
|
+
width: number
|
|
10
|
+
height: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface RnxCaptureAccessibilityState {
|
|
14
|
+
disabled: boolean
|
|
15
|
+
selected: boolean
|
|
16
|
+
checked: boolean | 'mixed'
|
|
17
|
+
busy: boolean
|
|
18
|
+
expanded: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface RnxCaptureAccessibilityValue {
|
|
22
|
+
min?: number
|
|
23
|
+
max?: number
|
|
24
|
+
now?: number
|
|
25
|
+
text?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface RnxCaptureAccessibility {
|
|
29
|
+
accessible: boolean
|
|
30
|
+
label: string | null
|
|
31
|
+
role: string | null
|
|
32
|
+
hint: string | null
|
|
33
|
+
liveRegion: 'none' | 'polite' | 'assertive' | null
|
|
34
|
+
state: RnxCaptureAccessibilityState | null
|
|
35
|
+
value: RnxCaptureAccessibilityValue | null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface RnxCaptureInteractionState {
|
|
39
|
+
pressed: boolean
|
|
40
|
+
pressable: boolean
|
|
41
|
+
textInput: boolean
|
|
42
|
+
textSelection: { start: number | null; end: number | null } | null
|
|
43
|
+
secureTextEntry: boolean
|
|
44
|
+
placeholder: string | null
|
|
45
|
+
scrollOffset: { x: number; y: number }
|
|
46
|
+
zoomScale: number | null
|
|
47
|
+
nativePinchEnabled: boolean
|
|
48
|
+
contentOffsetProp: { x?: number; y?: number } | null
|
|
49
|
+
decelerationRateProp: unknown
|
|
50
|
+
strokeDashoffsetProp: number | null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface RnxCaptureStyleTokenBinding {
|
|
54
|
+
token: string
|
|
55
|
+
theme: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface RnxCaptureTextSegment {
|
|
59
|
+
text: string
|
|
60
|
+
color?: string | number
|
|
61
|
+
fontFamily?: string
|
|
62
|
+
fontSize?: number
|
|
63
|
+
fontStyle?: string
|
|
64
|
+
fontWeight?: string | number
|
|
65
|
+
letterSpacing?: number
|
|
66
|
+
textDecorationLine?: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface RnxCaptureTextLine {
|
|
70
|
+
text: string
|
|
71
|
+
x: number
|
|
72
|
+
y: number
|
|
73
|
+
width: number
|
|
74
|
+
height: number
|
|
75
|
+
baseline: number
|
|
76
|
+
segments?: RnxCaptureTextSegment[]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface RnxCaptureSource {
|
|
80
|
+
location?: string
|
|
81
|
+
file?: string
|
|
82
|
+
componentName?: string
|
|
83
|
+
componentStack?: string[]
|
|
84
|
+
react?: {
|
|
85
|
+
component?: string
|
|
86
|
+
owners?: string[]
|
|
87
|
+
source?: string
|
|
88
|
+
key?: string
|
|
89
|
+
hasRef?: boolean
|
|
90
|
+
hooks?: {
|
|
91
|
+
total: number
|
|
92
|
+
counts: Record<string, number>
|
|
93
|
+
}
|
|
94
|
+
contexts?: string[]
|
|
95
|
+
lastCommit?: {
|
|
96
|
+
ageMs: number
|
|
97
|
+
causes: string[]
|
|
98
|
+
propDiffs?: string[]
|
|
99
|
+
stateChanged?: boolean
|
|
100
|
+
actualDurationMs?: number
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface RnxCaptureNode {
|
|
106
|
+
nodeId: number
|
|
107
|
+
parentNodeId: number | null
|
|
108
|
+
childNodeIds: number[]
|
|
109
|
+
paintIndex: number
|
|
110
|
+
type: string
|
|
111
|
+
id: string | null
|
|
112
|
+
testID: string | null
|
|
113
|
+
text: string | null
|
|
114
|
+
childCount: number
|
|
115
|
+
accessibility: RnxCaptureAccessibility
|
|
116
|
+
interaction: RnxCaptureInteractionState
|
|
117
|
+
layout: {
|
|
118
|
+
local: RnxCaptureRect
|
|
119
|
+
frame: RnxCaptureRect | null
|
|
120
|
+
absolutePosition: { x: number; y: number }
|
|
121
|
+
visibleFrame: RnxCaptureRect | null
|
|
122
|
+
}
|
|
123
|
+
style: {
|
|
124
|
+
resolved: Record<string, unknown>
|
|
125
|
+
authored: Record<string, unknown>
|
|
126
|
+
computed: Record<string, unknown>
|
|
127
|
+
tokenBindings: Record<string, RnxCaptureStyleTokenBinding>
|
|
128
|
+
}
|
|
129
|
+
source: RnxCaptureSource
|
|
130
|
+
props: Record<string, unknown>
|
|
131
|
+
textLines?: RnxCaptureTextLine[]
|
|
132
|
+
/** additional generic inspect fields preserved for tooling adapters */
|
|
133
|
+
inspection: Record<string, unknown>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface RnxCaptureTree {
|
|
137
|
+
viewport: { width: number; height: number }
|
|
138
|
+
rootNodeId: number
|
|
139
|
+
nodes: RnxCaptureNode[]
|
|
140
|
+
/** reconciler commit shared by semantic, layout, and visual evidence */
|
|
141
|
+
commitRevision?: number
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface RnxCaptureVisualEvidence {
|
|
145
|
+
kind: 'png'
|
|
146
|
+
/** names the runtime that produced these pixels without claiming visibility */
|
|
147
|
+
producer: 'headless-cpu-app-surface' | 'browser-compositor-app-surface'
|
|
148
|
+
dataUri: string
|
|
149
|
+
pixelWidth: number
|
|
150
|
+
pixelHeight: number
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface RnxCaptureRegionRequest {
|
|
154
|
+
key: string
|
|
155
|
+
/** host node whose own subtree is rendered into this transparent atlas region */
|
|
156
|
+
nodeId: number
|
|
157
|
+
frame: RnxCaptureRect
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface RnxRasterRegionTree {
|
|
161
|
+
width: number
|
|
162
|
+
height: number
|
|
163
|
+
nodes: readonly {
|
|
164
|
+
nodeId: number
|
|
165
|
+
parentNodeId: number | null
|
|
166
|
+
type: string
|
|
167
|
+
text?: string | null
|
|
168
|
+
style: Record<string, unknown>
|
|
169
|
+
layout: RnxCaptureRect
|
|
170
|
+
frame: RnxCaptureRect | null
|
|
171
|
+
absolutePosition: { x: number; y: number }
|
|
172
|
+
visibleFrame?: RnxCaptureRect | null
|
|
173
|
+
}[]
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function selectRnxRasterNodeIds(tree: RnxRasterRegionTree): Set<number> {
|
|
177
|
+
const nodesById = new Map(tree.nodes.map((node) => [node.nodeId, node]))
|
|
178
|
+
const unsupported = new Set<number>()
|
|
179
|
+
for (const node of tree.nodes) {
|
|
180
|
+
const visibleFrame = node.visibleFrame ?? node.frame
|
|
181
|
+
if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue
|
|
182
|
+
if (
|
|
183
|
+
node.type === 'masked-view' ||
|
|
184
|
+
(node.type === 'text' &&
|
|
185
|
+
typeof node.text === 'string' &&
|
|
186
|
+
(/\p{Emoji_Presentation}/u.test(node.text) ||
|
|
187
|
+
/\uFE0F|\u200D|\u20E3|\p{Emoji_Modifier}|\p{Regional_Indicator}/u.test(
|
|
188
|
+
node.text,
|
|
189
|
+
))) ||
|
|
190
|
+
node.style._liquidGlass !== undefined ||
|
|
191
|
+
node.style._liquidGlassEdge !== undefined
|
|
192
|
+
) {
|
|
193
|
+
unsupported.add(node.nodeId)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
for (const nodeId of [...unsupported]) {
|
|
198
|
+
let parentNodeId = nodesById.get(nodeId)?.parentNodeId ?? null
|
|
199
|
+
while (parentNodeId !== null) {
|
|
200
|
+
if (unsupported.has(parentNodeId)) {
|
|
201
|
+
unsupported.delete(nodeId)
|
|
202
|
+
break
|
|
203
|
+
}
|
|
204
|
+
parentNodeId = nodesById.get(parentNodeId)?.parentNodeId ?? null
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const screenArea = tree.width * tree.height
|
|
209
|
+
const maxLayerArea = screenArea * 0.25
|
|
210
|
+
const maxAtlasArea = screenArea * 0.5
|
|
211
|
+
const candidates = [...unsupported]
|
|
212
|
+
.map((nodeId) => {
|
|
213
|
+
const node = nodesById.get(nodeId)
|
|
214
|
+
const frame = node?.visibleFrame ?? node?.frame
|
|
215
|
+
return frame ? { nodeId, area: frame.width * frame.height } : null
|
|
216
|
+
})
|
|
217
|
+
.filter(
|
|
218
|
+
(candidate): candidate is { nodeId: number; area: number } =>
|
|
219
|
+
candidate !== null && candidate.area <= maxLayerArea,
|
|
220
|
+
)
|
|
221
|
+
.sort((left, right) => left.area - right.area || left.nodeId - right.nodeId)
|
|
222
|
+
const selected = new Set<number>()
|
|
223
|
+
let atlasArea = 0
|
|
224
|
+
for (const candidate of candidates) {
|
|
225
|
+
if (atlasArea + candidate.area > maxAtlasArea) continue
|
|
226
|
+
selected.add(candidate.nodeId)
|
|
227
|
+
atlasArea += candidate.area
|
|
228
|
+
}
|
|
229
|
+
return selected
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function rnxRasterFrames(
|
|
233
|
+
tree: RnxRasterRegionTree,
|
|
234
|
+
nodeIds: ReadonlySet<number>,
|
|
235
|
+
): Map<number, RnxCaptureRect> {
|
|
236
|
+
const frames = new Map<number, RnxCaptureRect>()
|
|
237
|
+
for (const node of tree.nodes) {
|
|
238
|
+
if (!nodeIds.has(node.nodeId)) continue
|
|
239
|
+
const frame = node.frame ?? {
|
|
240
|
+
x: node.absolutePosition.x,
|
|
241
|
+
y: node.absolutePosition.y,
|
|
242
|
+
width: node.layout.width,
|
|
243
|
+
height: node.layout.height,
|
|
244
|
+
}
|
|
245
|
+
const liquidGlass = node.style._liquidGlass
|
|
246
|
+
const capturePadding =
|
|
247
|
+
liquidGlass &&
|
|
248
|
+
typeof liquidGlass === 'object' &&
|
|
249
|
+
typeof Reflect.get(liquidGlass, 'capturePadding') === 'number'
|
|
250
|
+
? Reflect.get(liquidGlass, 'capturePadding')
|
|
251
|
+
: 0
|
|
252
|
+
const shadowRadius =
|
|
253
|
+
typeof node.style.shadowRadius === 'number' ? node.style.shadowRadius : 0
|
|
254
|
+
const shadowOffset = node.style.shadowOffset
|
|
255
|
+
const shadowOffsetX =
|
|
256
|
+
shadowOffset &&
|
|
257
|
+
typeof shadowOffset === 'object' &&
|
|
258
|
+
typeof Reflect.get(shadowOffset, 'width') === 'number'
|
|
259
|
+
? Reflect.get(shadowOffset, 'width')
|
|
260
|
+
: 0
|
|
261
|
+
const shadowOffsetY =
|
|
262
|
+
shadowOffset &&
|
|
263
|
+
typeof shadowOffset === 'object' &&
|
|
264
|
+
typeof Reflect.get(shadowOffset, 'height') === 'number'
|
|
265
|
+
? Reflect.get(shadowOffset, 'height')
|
|
266
|
+
: 0
|
|
267
|
+
const left = Math.max(
|
|
268
|
+
0,
|
|
269
|
+
frame.x - Math.max(capturePadding, shadowRadius - shadowOffsetX),
|
|
270
|
+
)
|
|
271
|
+
const top = Math.max(
|
|
272
|
+
0,
|
|
273
|
+
frame.y - Math.max(capturePadding, shadowRadius - shadowOffsetY),
|
|
274
|
+
)
|
|
275
|
+
const right = Math.min(
|
|
276
|
+
tree.width,
|
|
277
|
+
frame.x + frame.width + Math.max(capturePadding, shadowRadius + shadowOffsetX),
|
|
278
|
+
)
|
|
279
|
+
const bottom = Math.min(
|
|
280
|
+
tree.height,
|
|
281
|
+
frame.y + frame.height + Math.max(capturePadding, shadowRadius + shadowOffsetY),
|
|
282
|
+
)
|
|
283
|
+
if (right > left && bottom > top) {
|
|
284
|
+
frames.set(node.nodeId, {
|
|
285
|
+
x: left,
|
|
286
|
+
y: top,
|
|
287
|
+
width: right - left,
|
|
288
|
+
height: bottom - top,
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return frames
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function rnxCaptureRasterRegions(
|
|
296
|
+
capture: RnxScreenCapture,
|
|
297
|
+
): RnxCaptureRegionRequest[] {
|
|
298
|
+
const tree: RnxRasterRegionTree = {
|
|
299
|
+
width: capture.tree.viewport.width,
|
|
300
|
+
height: capture.tree.viewport.height,
|
|
301
|
+
nodes: capture.tree.nodes.map((node) => ({
|
|
302
|
+
nodeId: node.nodeId,
|
|
303
|
+
parentNodeId: node.parentNodeId,
|
|
304
|
+
type: node.type,
|
|
305
|
+
text: node.text,
|
|
306
|
+
style: node.style.resolved,
|
|
307
|
+
layout: node.layout.local,
|
|
308
|
+
frame: node.layout.frame,
|
|
309
|
+
absolutePosition: node.layout.absolutePosition,
|
|
310
|
+
visibleFrame: node.layout.visibleFrame,
|
|
311
|
+
})),
|
|
312
|
+
}
|
|
313
|
+
const nodeIds = selectRnxRasterNodeIds(tree)
|
|
314
|
+
const frames = rnxRasterFrames(tree, nodeIds)
|
|
315
|
+
return [...nodeIds].flatMap((nodeId) => {
|
|
316
|
+
const frame = frames.get(nodeId)
|
|
317
|
+
return frame ? [{ key: String(nodeId), nodeId, frame }] : []
|
|
318
|
+
})
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export interface RnxCaptureAtlasRegion extends RnxCaptureRegionRequest {
|
|
322
|
+
/** source rectangle inside the packed atlas, in logical atlas coordinates */
|
|
323
|
+
source: RnxCaptureRect
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface RnxCaptureRegionAtlas {
|
|
327
|
+
kind: 'png-atlas'
|
|
328
|
+
producer: 'headless-cpu-app-surface'
|
|
329
|
+
dataUri: string
|
|
330
|
+
/** logical atlas dimensions; the encoded PNG uses pixelWidth × pixelHeight */
|
|
331
|
+
width: number
|
|
332
|
+
height: number
|
|
333
|
+
pixelWidth: number
|
|
334
|
+
pixelHeight: number
|
|
335
|
+
regions: RnxCaptureAtlasRegion[]
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export interface RnxCaptureFontRegistration {
|
|
339
|
+
url?: string
|
|
340
|
+
family: string
|
|
341
|
+
sourceLabel?: string
|
|
342
|
+
parsedFamily?: string | null
|
|
343
|
+
parsedPostScript?: string | null
|
|
344
|
+
fullName?: string | null
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export interface RnxScreenCapture {
|
|
348
|
+
contractVersion: typeof RNX_SCREEN_CAPTURE_VERSION
|
|
349
|
+
capturedAt: number
|
|
350
|
+
tree: RnxCaptureTree
|
|
351
|
+
/** app fonts registered in the captured tenant, included only when requested */
|
|
352
|
+
fonts?: RnxCaptureFontRegistration[]
|
|
353
|
+
/** optional full-frame diagnostic evidence, never required by tree consumers */
|
|
354
|
+
visual?: RnxCaptureVisualEvidence
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function captureRecord(value: unknown): value is Record<string, unknown> {
|
|
358
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function captureInteger(value: unknown): value is number {
|
|
362
|
+
return typeof value === 'number' && Number.isSafeInteger(value)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function captureNumber(value: unknown): value is number {
|
|
366
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function captureNullableString(value: unknown): value is string | null {
|
|
370
|
+
return value === null || typeof value === 'string'
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function captureRect(value: unknown): value is RnxCaptureRect {
|
|
374
|
+
return (
|
|
375
|
+
captureRecord(value) &&
|
|
376
|
+
captureNumber(value.x) &&
|
|
377
|
+
captureNumber(value.y) &&
|
|
378
|
+
captureNumber(value.width) &&
|
|
379
|
+
captureNumber(value.height)
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function captureOptionalString(value: unknown): value is string | undefined {
|
|
384
|
+
return value === undefined || typeof value === 'string'
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function captureOptionalNullableString(
|
|
388
|
+
value: unknown,
|
|
389
|
+
): value is string | null | undefined {
|
|
390
|
+
return value === undefined || captureNullableString(value)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function captureFontRegistration(value: unknown): value is RnxCaptureFontRegistration {
|
|
394
|
+
return (
|
|
395
|
+
captureRecord(value) &&
|
|
396
|
+
typeof value.family === 'string' &&
|
|
397
|
+
value.family.length > 0 &&
|
|
398
|
+
captureOptionalString(value.url) &&
|
|
399
|
+
captureOptionalString(value.sourceLabel) &&
|
|
400
|
+
captureOptionalNullableString(value.parsedFamily) &&
|
|
401
|
+
captureOptionalNullableString(value.parsedPostScript) &&
|
|
402
|
+
captureOptionalNullableString(value.fullName)
|
|
403
|
+
)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function capturePoint(value: unknown): value is { x: number; y: number } {
|
|
407
|
+
return captureRecord(value) && captureNumber(value.x) && captureNumber(value.y)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function captureNode(value: unknown): value is RnxCaptureNode {
|
|
411
|
+
if (
|
|
412
|
+
!captureRecord(value) ||
|
|
413
|
+
!captureInteger(value.nodeId) ||
|
|
414
|
+
!(value.parentNodeId === null || captureInteger(value.parentNodeId)) ||
|
|
415
|
+
!Array.isArray(value.childNodeIds) ||
|
|
416
|
+
!value.childNodeIds.every(captureInteger) ||
|
|
417
|
+
!captureInteger(value.paintIndex) ||
|
|
418
|
+
typeof value.type !== 'string' ||
|
|
419
|
+
!captureNullableString(value.id) ||
|
|
420
|
+
!captureNullableString(value.testID) ||
|
|
421
|
+
!captureNullableString(value.text) ||
|
|
422
|
+
!captureInteger(value.childCount) ||
|
|
423
|
+
!captureRecord(value.accessibility) ||
|
|
424
|
+
!captureRecord(value.interaction) ||
|
|
425
|
+
!captureRecord(value.layout) ||
|
|
426
|
+
!captureRecord(value.style) ||
|
|
427
|
+
!captureRecord(value.source) ||
|
|
428
|
+
!captureRecord(value.props) ||
|
|
429
|
+
!captureRecord(value.inspection)
|
|
430
|
+
) {
|
|
431
|
+
return false
|
|
432
|
+
}
|
|
433
|
+
const accessibility = value.accessibility
|
|
434
|
+
if (
|
|
435
|
+
typeof accessibility.accessible !== 'boolean' ||
|
|
436
|
+
!captureNullableString(accessibility.label) ||
|
|
437
|
+
!captureNullableString(accessibility.role) ||
|
|
438
|
+
!captureNullableString(accessibility.hint) ||
|
|
439
|
+
!(
|
|
440
|
+
accessibility.liveRegion === null ||
|
|
441
|
+
accessibility.liveRegion === 'none' ||
|
|
442
|
+
accessibility.liveRegion === 'polite' ||
|
|
443
|
+
accessibility.liveRegion === 'assertive'
|
|
444
|
+
) ||
|
|
445
|
+
!(accessibility.state === null || captureRecord(accessibility.state)) ||
|
|
446
|
+
!(accessibility.value === null || captureRecord(accessibility.value))
|
|
447
|
+
) {
|
|
448
|
+
return false
|
|
449
|
+
}
|
|
450
|
+
const interaction = value.interaction
|
|
451
|
+
if (
|
|
452
|
+
typeof interaction.pressed !== 'boolean' ||
|
|
453
|
+
typeof interaction.pressable !== 'boolean' ||
|
|
454
|
+
typeof interaction.textInput !== 'boolean' ||
|
|
455
|
+
!(interaction.textSelection === null || captureRecord(interaction.textSelection)) ||
|
|
456
|
+
typeof interaction.secureTextEntry !== 'boolean' ||
|
|
457
|
+
!captureNullableString(interaction.placeholder) ||
|
|
458
|
+
!capturePoint(interaction.scrollOffset) ||
|
|
459
|
+
!(interaction.zoomScale === null || captureNumber(interaction.zoomScale)) ||
|
|
460
|
+
typeof interaction.nativePinchEnabled !== 'boolean' ||
|
|
461
|
+
!(
|
|
462
|
+
interaction.contentOffsetProp === null ||
|
|
463
|
+
captureRecord(interaction.contentOffsetProp)
|
|
464
|
+
) ||
|
|
465
|
+
!(
|
|
466
|
+
interaction.strokeDashoffsetProp === null ||
|
|
467
|
+
captureNumber(interaction.strokeDashoffsetProp)
|
|
468
|
+
)
|
|
469
|
+
) {
|
|
470
|
+
return false
|
|
471
|
+
}
|
|
472
|
+
const layout = value.layout
|
|
473
|
+
if (
|
|
474
|
+
!captureRect(layout.local) ||
|
|
475
|
+
!(layout.frame === null || captureRect(layout.frame)) ||
|
|
476
|
+
!capturePoint(layout.absolutePosition) ||
|
|
477
|
+
!(layout.visibleFrame === null || captureRect(layout.visibleFrame))
|
|
478
|
+
) {
|
|
479
|
+
return false
|
|
480
|
+
}
|
|
481
|
+
const style = value.style
|
|
482
|
+
return (
|
|
483
|
+
captureRecord(style.resolved) &&
|
|
484
|
+
captureRecord(style.authored) &&
|
|
485
|
+
captureRecord(style.computed) &&
|
|
486
|
+
captureRecord(style.tokenBindings) &&
|
|
487
|
+
(value.textLines === undefined || Array.isArray(value.textLines))
|
|
488
|
+
)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export function isRnxScreenCapture(value: unknown): value is RnxScreenCapture {
|
|
492
|
+
if (
|
|
493
|
+
!captureRecord(value) ||
|
|
494
|
+
value.contractVersion !== RNX_SCREEN_CAPTURE_VERSION ||
|
|
495
|
+
!captureInteger(value.capturedAt) ||
|
|
496
|
+
!captureRecord(value.tree) ||
|
|
497
|
+
!(
|
|
498
|
+
value.fonts === undefined ||
|
|
499
|
+
(Array.isArray(value.fonts) &&
|
|
500
|
+
value.fonts.length <= 200 &&
|
|
501
|
+
value.fonts.every(captureFontRegistration))
|
|
502
|
+
) ||
|
|
503
|
+
!(value.visual === undefined || captureRecord(value.visual))
|
|
504
|
+
) {
|
|
505
|
+
return false
|
|
506
|
+
}
|
|
507
|
+
const tree = value.tree
|
|
508
|
+
const visual = value.visual
|
|
509
|
+
return (
|
|
510
|
+
captureRecord(tree.viewport) &&
|
|
511
|
+
captureInteger(tree.viewport.width) &&
|
|
512
|
+
tree.viewport.width > 0 &&
|
|
513
|
+
captureInteger(tree.viewport.height) &&
|
|
514
|
+
tree.viewport.height > 0 &&
|
|
515
|
+
captureInteger(tree.rootNodeId) &&
|
|
516
|
+
(tree.commitRevision === undefined || captureInteger(tree.commitRevision)) &&
|
|
517
|
+
Array.isArray(tree.nodes) &&
|
|
518
|
+
tree.nodes.every(captureNode) &&
|
|
519
|
+
(visual === undefined ||
|
|
520
|
+
(visual.kind === 'png' &&
|
|
521
|
+
(visual.producer === 'headless-cpu-app-surface' ||
|
|
522
|
+
visual.producer === 'browser-compositor-app-surface') &&
|
|
523
|
+
typeof visual.dataUri === 'string' &&
|
|
524
|
+
visual.dataUri.startsWith('data:image/png;base64,') &&
|
|
525
|
+
captureInteger(visual.pixelWidth) &&
|
|
526
|
+
visual.pixelWidth > 0 &&
|
|
527
|
+
captureInteger(visual.pixelHeight) &&
|
|
528
|
+
visual.pixelHeight > 0))
|
|
529
|
+
)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export function isRnxCaptureRegionAtlas(value: unknown): value is RnxCaptureRegionAtlas {
|
|
533
|
+
if (
|
|
534
|
+
!captureRecord(value) ||
|
|
535
|
+
value.kind !== 'png-atlas' ||
|
|
536
|
+
value.producer !== 'headless-cpu-app-surface' ||
|
|
537
|
+
typeof value.dataUri !== 'string' ||
|
|
538
|
+
!value.dataUri.startsWith('data:image/png;base64,') ||
|
|
539
|
+
!captureNumber(value.width) ||
|
|
540
|
+
value.width <= 0 ||
|
|
541
|
+
!captureNumber(value.height) ||
|
|
542
|
+
value.height <= 0 ||
|
|
543
|
+
!captureInteger(value.pixelWidth) ||
|
|
544
|
+
value.pixelWidth <= 0 ||
|
|
545
|
+
!captureInteger(value.pixelHeight) ||
|
|
546
|
+
value.pixelHeight <= 0 ||
|
|
547
|
+
!Array.isArray(value.regions) ||
|
|
548
|
+
value.regions.length === 0 ||
|
|
549
|
+
value.regions.length > 256
|
|
550
|
+
) {
|
|
551
|
+
return false
|
|
552
|
+
}
|
|
553
|
+
const scale = value.pixelWidth / value.width
|
|
554
|
+
if (
|
|
555
|
+
!Number.isInteger(scale) ||
|
|
556
|
+
scale < 1 ||
|
|
557
|
+
scale > 4 ||
|
|
558
|
+
Math.abs(value.height * scale - value.pixelHeight) > 0.000_001
|
|
559
|
+
) {
|
|
560
|
+
return false
|
|
561
|
+
}
|
|
562
|
+
const keys = new Set<string>()
|
|
563
|
+
for (const region of value.regions) {
|
|
564
|
+
if (
|
|
565
|
+
!captureRecord(region) ||
|
|
566
|
+
typeof region.key !== 'string' ||
|
|
567
|
+
region.key.length === 0 ||
|
|
568
|
+
keys.has(region.key) ||
|
|
569
|
+
!captureInteger(region.nodeId) ||
|
|
570
|
+
region.nodeId <= 0 ||
|
|
571
|
+
!captureRect(region.frame) ||
|
|
572
|
+
region.frame.width <= 0 ||
|
|
573
|
+
region.frame.height <= 0 ||
|
|
574
|
+
!captureRect(region.source) ||
|
|
575
|
+
region.source.x < 0 ||
|
|
576
|
+
region.source.y < 0 ||
|
|
577
|
+
region.source.width !== region.frame.width ||
|
|
578
|
+
region.source.height !== region.frame.height ||
|
|
579
|
+
region.source.x + region.source.width > value.width ||
|
|
580
|
+
region.source.y + region.source.height > value.height
|
|
581
|
+
) {
|
|
582
|
+
return false
|
|
583
|
+
}
|
|
584
|
+
keys.add(region.key)
|
|
585
|
+
}
|
|
586
|
+
return true
|
|
587
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_SOOTSIM_SHELL_URL = 'http://localhost:5173/'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// rnx cli version, resolved once and cached. standalone builds embed it so
|
|
2
|
+
// lazy command chunks do not depend on an npm package layout at runtime.
|
|
3
|
+
|
|
4
|
+
import { readFileSync } from 'node:fs'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
import { rnxPublicBrand } from './public-brand.ts'
|
|
7
|
+
|
|
8
|
+
declare const __RNX_CLI_VERSION__: string
|
|
9
|
+
|
|
10
|
+
let cached: string | null = null
|
|
11
|
+
|
|
12
|
+
export function getCliVersion(): string {
|
|
13
|
+
if (cached != null) return cached
|
|
14
|
+
if (
|
|
15
|
+
typeof __RNX_CLI_VERSION__ !== 'undefined' &&
|
|
16
|
+
typeof __RNX_CLI_VERSION__ === 'string' &&
|
|
17
|
+
__RNX_CLI_VERSION__
|
|
18
|
+
) {
|
|
19
|
+
cached = __RNX_CLI_VERSION__
|
|
20
|
+
return cached
|
|
21
|
+
}
|
|
22
|
+
// prefer package resolution (works for npm/global installs); fall back to
|
|
23
|
+
// the package.json next to this module's source for repo / bundled runs.
|
|
24
|
+
const candidates: Array<() => string> = [
|
|
25
|
+
() =>
|
|
26
|
+
fileURLToPath(import.meta.resolve(`${rnxPublicBrand.packageName}/package.json`)),
|
|
27
|
+
() => fileURLToPath(new URL('../package.json', import.meta.url)),
|
|
28
|
+
]
|
|
29
|
+
for (const resolve of candidates) {
|
|
30
|
+
try {
|
|
31
|
+
const version = JSON.parse(readFileSync(resolve(), 'utf8')).version
|
|
32
|
+
if (typeof version === 'string' && version) {
|
|
33
|
+
cached = version
|
|
34
|
+
return cached
|
|
35
|
+
}
|
|
36
|
+
} catch {}
|
|
37
|
+
}
|
|
38
|
+
cached = '0.0.0'
|
|
39
|
+
return cached
|
|
40
|
+
}
|