Skip to content

Commit 6b93100

Browse files
committed
fix(webhooks): gate the opt-in trigger outputs on their switches
`method` and `headers` exist only once their switch is on, but the reference dropdown offered them either way, so a user could select a field the running webhook would never send. Trigger outputs already support `condition`, which exists for exactly this — narrowing the declared outputs to the selected trigger configuration. Both truthy forms are matched, because a YAML- or Copilot-authored workflow can write the string rather than the boolean, and the dropdown should agree with what the delivery path does with that value. `query` stays unconditional: it has no switch to gate on.
1 parent 8a2994a commit 6b93100

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

apps/sim/triggers/generic/webhook.test.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,25 @@ describe('genericWebhookTrigger', () => {
5353
})
5454

5555
/**
56-
* Each output says what makes it present, because two of the three are opt-in — a description
57-
* that omits that reads as a promise the trigger does not keep.
56+
* Two of the three outputs only exist once a switch is on, so they are conditioned on it: the
57+
* reference dropdown must not offer a field the running webhook will not send.
5858
*/
5959
it.each([
60-
['method', 'Accept All HTTP Methods'],
61-
['headers', 'Expose Request Headers'],
62-
])('says in the %s description which switch produces it', (key, switchTitle) => {
63-
expect(genericWebhookTrigger.outputs[key].description).toContain(switchTitle)
60+
['method', 'acceptAllMethods'],
61+
['headers', 'exposeRequestHeaders'],
62+
])('gates the %s output on the switch that produces it', (key, field) => {
63+
expect(genericWebhookTrigger.outputs[key].condition).toEqual({
64+
field,
65+
value: [true, 'true'],
66+
})
67+
})
68+
69+
/**
70+
* Query parameters are the one key that is not opt-in, so offering them unconditionally is
71+
* correct — gating them on a switch that does not exist would hide them entirely.
72+
*/
73+
it('offers query unconditionally', () => {
74+
expect(genericWebhookTrigger.outputs.query.condition).toBeUndefined()
6475
})
6576

6677
/**

apps/sim/triggers/generic/webhook.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,24 +154,29 @@ export const genericWebhookTrigger: TriggerConfig = {
154154
/**
155155
* Body fields stay undeclared because a generic webhook receives whatever JSON the caller
156156
* sends. The request metadata below is known ahead of time, so it can be offered for reference.
157-
* Each entry says what makes it present, because two of the three are opt-in and all three
158-
* yield to a body field of the same name.
157+
*
158+
* `method` and `headers` are conditioned on the switch that produces them, so the reference
159+
* dropdown never offers a field the running webhook will not send. Both truthy forms are
160+
* matched because a YAML- or Copilot-authored workflow can write the string rather than the
161+
* boolean — the same tolerance `isProviderConfigFlagEnabled` applies at delivery time.
159162
*/
160163
outputs: {
161164
method: {
162165
type: 'string',
163166
description:
164-
'HTTP method of the request. Present when "Accept All HTTP Methods" is on, unless the body has its own "method" field.',
167+
'HTTP method of the request. Yields to a body field of the same name if the caller sends one.',
168+
condition: { field: 'acceptAllMethods', value: [true, 'true'] },
165169
},
166170
query: {
167171
type: 'object',
168172
description:
169-
'Query parameters from the request URL. Present when the URL has any, unless the body has its own "query" field.',
173+
'Query parameters from the request URL, when it has any. Yields to a body field of the same name if the caller sends one.',
170174
},
171175
headers: {
172176
type: 'object',
173177
description:
174-
'Request headers, excluding the ones that carry credentials. Present when "Expose Request Headers" is on, unless the body has its own "headers" field.',
178+
'Request headers, excluding the ones that carry credentials. Yields to a body field of the same name if the caller sends one.',
179+
condition: { field: 'exposeRequestHeaders', value: [true, 'true'] },
175180
},
176181
},
177182

0 commit comments

Comments
 (0)