[APPS][Connections Part 4] Resolve same-module connection ID object values#354
Conversation
cd42b54 to
2a5b6a3
Compare
8b1d800 to
df714c3
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df714c36aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // literal in this file, directly or through const aliases: | ||
| // const CONNECTIONS = { HTTP: 'abc' }; | ||
| // const ACTIVE_CONNECTIONS = CONNECTIONS; | ||
| return objectExpression; |
There was a problem hiding this comment.
Reject mutable const connection maps
When a const binding resolves to an object literal, this path treats the initializer as the runtime value even though const does not freeze object properties. In files such as const CONNECTIONS = { HTTP: 'conn-a' }; CONNECTIONS.HTTP = getConnectionId(); request({ connectionId: CONNECTIONS.HTTP }), the extractor now records conn-a instead of failing closed or including the actual runtime ID, which can produce an incorrect allowlist. Please detect writes to member chains of these connection maps (including aliases/nested objects) or only accept frozen/otherwise immutable shapes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I'm fine with this being allowed. While the object could be mutated I think the other options are either too restrictive or a lot of work to detect mutations.
2a5b6a3 to
2826a40
Compare
df714c3 to
d3255cb
Compare
72401e7 to
3b2301a
Compare
2826a40 to
acbf509
Compare
3b2301a to
91ea1f0
Compare
| if (binding.kind === 'mutable') { | ||
| // A mutable map can change before the action call runs: | ||
| // let CONNECTIONS = { HTTP: 'abc' }; | ||
| // CONNECTIONS = loadConnections(); | ||
| throw unsupportedConnectionId( | ||
| context.filePath, | ||
| `mutable ${binding.declarationKind} connectionId object binding ${node.name}`, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Just to be sure, is this mutable feature something we could realistically see a user wanting in the future?
There was a problem hiding this comment.
We can always iterate on customer feedback and prioritize trying to support this if our customers ask for it.

Motivation
The parent PR adds direct same-file connection ID constants. App code also commonly groups same-file connection IDs in local object maps, for example
CONNECTIONS.HTTPorCONNECTIONS.HTTP.PROD.This PR adds that object-map support separately from the basic constant resolver so reviewers can evaluate the property-access rules on their own.
Changes
Adds same-module object member resolution for supported
connectionIdforms:The algorithm works in two steps.
First, it treats
CONNECTIONS.HTTPas a static object lookup. It resolvesCONNECTIONSto the same-file const object, finds theHTTPproperty, and returns the expression stored at that property. In the example above, that expression is the string literal'77c14b8b-27e1-4901-985d-8817908b9706'.That property value does not need to be a string literal directly. It can also be another same-file const identifier:
In that case, the object lookup returns the identifier expression
HTTP_CONNECTION_ID.Second, the returned expression goes back through the existing connection ID value resolver. If the expression is a string literal, it becomes the final connection ID immediately. If the expression is an identifier, the resolver follows that identifier to its same-file const initializer and then resolves that initializer to the final string.
This same two-step shape also supports nested static reads such as
CONNECTIONS.HTTP.PROD: each object member lookup returns the next expression, and the general resolver keeps resolving until it reaches a final supported string value.The resolver intentionally fails closed for dynamic forms that could hide the runtime value, including computed member reads, imported object roots, mutable object roots, object spreads, computed object properties, duplicate keys, accessors, missing properties, and non-object intermediate values. Imported connection ID tracing remains out of scope for a later PR.
QA Instructions
Ran:
Child branch result: 58 tests passed.
Blast Radius
This affects Apps backend function discovery/upload/dev-server manifest generation for action-catalog connection allowlists. Runtime backend execution is unchanged. The resolver remains conservative and throws on object shapes that could hide the actual runtime connection ID.
Documentation