rnxsim 0.1.514 → 0.1.516

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.
Files changed (60) hide show
  1. package/cli/cloud-client.ts +18 -8
  2. package/cli/commands/inspect/get-layout.ts +2 -1
  3. package/cli/outbound-endpoints.ts +1 -1
  4. package/dist-lib/agent-daemon-client.cjs +1 -1
  5. package/dist-lib/agent-events.cjs +1 -1
  6. package/dist-lib/agent-identity.cjs +1 -1
  7. package/dist-lib/agent-sessions.cjs +1 -1
  8. package/dist-lib/attached-projects.cjs +1 -1
  9. package/dist-lib/auth/shared-session.cjs +1 -1
  10. package/dist-lib/backend-origin.cjs +1 -1
  11. package/dist-lib/beta.cjs +1 -1
  12. package/dist-lib/beta.mjs +1 -1
  13. package/dist-lib/bridge-constants.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.cjs +64 -1
  15. package/dist-lib/bridge-contract-input.mjs +63 -1
  16. package/dist-lib/bridge-contract.cjs +73 -3
  17. package/dist-lib/bridge-contract.mjs +69 -2
  18. package/dist-lib/capture-contract.cjs +1 -1
  19. package/dist-lib/capture-contract.mjs +1 -1
  20. package/dist-lib/cli-constants.cjs +1 -1
  21. package/dist-lib/cloud-contract.cjs +63 -22
  22. package/dist-lib/cloud-contract.mjs +57 -21
  23. package/dist-lib/cloud.cjs +56 -20
  24. package/dist-lib/cloud.mjs +56 -20
  25. package/dist-lib/config.cjs +1 -1
  26. package/dist-lib/detox/index.cjs +1 -1
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/home-paths.cjs +1 -1
  29. package/dist-lib/host/bridge-host.cjs +45 -20
  30. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  31. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  32. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  33. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  34. package/dist-lib/host/websocket-proxy.cjs +1 -1
  35. package/dist-lib/index.cjs +62 -24
  36. package/dist-lib/jump-to-source-babel.cjs +1 -1
  37. package/dist-lib/jump-to-source-native.cjs +1 -1
  38. package/dist-lib/menu.cjs +1 -1
  39. package/dist-lib/menu.mjs +1 -1
  40. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  41. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  42. package/dist-lib/metro-production-bundle.cjs +1 -1
  43. package/dist-lib/metro-production-bundle.mjs +1 -1
  44. package/dist-lib/metro.cjs +1 -1
  45. package/dist-lib/profiles.cjs +1 -1
  46. package/dist-lib/public-brand.cjs +1 -1
  47. package/dist-lib/react-native-host-modules.cjs +1 -1
  48. package/dist-lib/react-native-host-modules.mjs +1 -1
  49. package/dist-lib/render-mode.cjs +1 -1
  50. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  51. package/dist-lib/sdk.cjs +1 -1
  52. package/dist-lib/sdk.mjs +1 -1
  53. package/dist-lib/skills.cjs +62 -24
  54. package/dist-lib/swift.cjs +1 -1
  55. package/dist-lib/vite.cjs +1 -1
  56. package/package.json +2 -1
  57. package/src/bridge-contract-input.ts +74 -0
  58. package/src/bridge-contract.ts +103 -0
  59. package/src/cloud-contract.ts +71 -19
  60. package/src/cloud.ts +10 -0
@@ -6,25 +6,51 @@ export const RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024
6
6
  export const RNX_CLOUD_TEST_FILES_MAX_COUNT = 256
7
7
  export const RNX_CLOUD_TEST_FILES_MAX_BYTES = 500_000
8
8
 
9
- export const RNX_CLOUD_COMMAND_TYPES = Object.freeze([
10
- 'state',
11
- 'query',
12
- 'resolve',
13
- 'perform',
14
- 'waitFor',
15
- 'reset',
16
- 'screenshot',
17
- 'capture',
18
- 'captureRegions',
19
- 'settle',
20
- 'setAppearance',
21
- 'openUrl',
22
- 'tree',
23
- 'tap',
24
- 'longPress',
25
- 'memory',
26
- 'diagnostics',
27
- ]) satisfies readonly BridgeCommandType[]
9
+ export type RnxCloudCommandScope = 'read' | 'drive' | 'reset' | 'media' | 'debug'
10
+
11
+ // one scope table for both remote planes: every bridge verb names the scope
12
+ // that may send it, so the nano service and the box relay admit the same
13
+ // vocabulary and differ only by caller scope. reads observe, drive moves,
14
+ // reset wipes, media injects camera fixtures, and debug evaluates.
15
+ export const RNX_CLOUD_COMMAND_SCOPES = {
16
+ state: 'read',
17
+ tree: 'read',
18
+ query: 'read',
19
+ resolve: 'read',
20
+ screenshot: 'read',
21
+ capture: 'read',
22
+ captureRegions: 'read',
23
+ memory: 'read',
24
+ diagnostics: 'read',
25
+ storageSnapshot: 'read',
26
+ perform: 'drive',
27
+ waitFor: 'drive',
28
+ tap: 'drive',
29
+ longPress: 'drive',
30
+ settle: 'drive',
31
+ openUrl: 'drive',
32
+ setAppearance: 'drive',
33
+ keyboard: 'drive',
34
+ focus: 'drive',
35
+ flowStatus: 'drive',
36
+ reset: 'reset',
37
+ camera: 'media',
38
+ // string evaluation and arbitrary bridge calls are maestro's boundary: the
39
+ // customer sdk never carries this scope, and the service grants it only to
40
+ // the account api key caller. close rides along, since ending the page ends
41
+ // the sim and belongs to the sim's owner rather than any driver.
42
+ evaluate: 'debug',
43
+ call: 'debug',
44
+ close: 'debug',
45
+ } satisfies Record<BridgeCommandType, RnxCloudCommandScope>
46
+
47
+ function scopeTableKeys(): BridgeCommandType[] {
48
+ return Object.keys(RNX_CLOUD_COMMAND_SCOPES).filter((key): key is BridgeCommandType =>
49
+ Object.prototype.hasOwnProperty.call(RNX_CLOUD_COMMAND_SCOPES, key),
50
+ )
51
+ }
52
+
53
+ export const RNX_CLOUD_COMMAND_TYPES = Object.freeze(scopeTableKeys())
28
54
 
29
55
  const RNX_CLOUD_COMMAND_TYPE_SET = new Set<string>(RNX_CLOUD_COMMAND_TYPES)
30
56
 
@@ -34,6 +60,32 @@ export function isRnxCloudCommandType(
34
60
  return RNX_CLOUD_COMMAND_TYPE_SET.has(value)
35
61
  }
36
62
 
63
+ export function rnxCloudCommandScope(type: BridgeCommandType): RnxCloudCommandScope {
64
+ return RNX_CLOUD_COMMAND_SCOPES[type]
65
+ }
66
+
67
+ // what the full per-simulator token and the box token carry until scoped
68
+ // tokens exist: every scope except debug.
69
+ export const RNX_CLOUD_TOKEN_SCOPES: readonly RnxCloudCommandScope[] = Object.freeze([
70
+ 'read',
71
+ 'drive',
72
+ 'reset',
73
+ 'media',
74
+ ])
75
+
76
+ // every scope, granted only to the account api key caller through the account
77
+ // service. the only credential the services accept for it today is the shared
78
+ // service key, which only the account service holds.
79
+ export const RNX_CLOUD_ALL_COMMAND_SCOPES: readonly RnxCloudCommandScope[] =
80
+ Object.freeze(['read', 'drive', 'reset', 'media', 'debug'])
81
+
82
+ export function rnxCloudScopesAllowCommand(
83
+ scopes: readonly RnxCloudCommandScope[],
84
+ type: BridgeCommandType,
85
+ ): boolean {
86
+ return scopes.includes(RNX_CLOUD_COMMAND_SCOPES[type])
87
+ }
88
+
37
89
  export interface RnxCloudClaim {
38
90
  id: string
39
91
  expiresAt: number
package/src/cloud.ts CHANGED
@@ -14,6 +14,9 @@ import {
14
14
  isRnxCloudCommandType,
15
15
  RNX_CLOUD_COMMAND_TYPES,
16
16
  RNX_CLOUD_MAX_ARTIFACT_BYTES,
17
+ RNX_CLOUD_TOKEN_SCOPES,
18
+ rnxCloudCommandScope,
19
+ rnxCloudScopesAllowCommand,
17
20
  type RnxCloudBoxCreateReceipt,
18
21
  type RnxCloudClaim,
19
22
  type RnxCloudCreateReceipt,
@@ -338,6 +341,13 @@ function cloudCommand(command: { type: string; [key: string]: unknown }): Remote
338
341
  if (!isRnxCloudCommandType(command.type)) {
339
342
  throw new Error(`RNX Cloud does not support bridge command type ${command.type}`)
340
343
  }
344
+ // the customer sdk never carries debug: evaluate/call/close belong to the
345
+ // account api key caller. refusing here names the scope before a request.
346
+ if (!rnxCloudScopesAllowCommand(RNX_CLOUD_TOKEN_SCOPES, command.type)) {
347
+ throw new Error(
348
+ `RNX Cloud command ${command.type} requires the ${rnxCloudCommandScope(command.type)} scope`,
349
+ )
350
+ }
341
351
  return { ...clean, type: command.type }
342
352
  }
343
353