Skip to content

Commit 21d43d5

Browse files
committed
feat: add source config fields (allowed_http_methods, custom_response) to connection create/upsert
- Add --source-allowed-http-methods flag (comma-separated: GET,POST,PUT,PATCH,DELETE) - Add --source-custom-response-content-type flag (json, text, xml) - Add --source-custom-response-body flag (max 1000 chars) - Update buildSourceConfig() with validation for new fields - Fix hasAnySourceFlag() to detect all source config flags - Fix needsExisting logic to detect source config-only updates - Add buildSourceInputForUpdate() for proper config merging during upsert - Add 23 unit tests in connection_source_config_test.go - Add 6 acceptance tests covering create and upsert scenarios - Update REFERENCE.md with documentation and examples
1 parent 28623d9 commit 21d43d5

File tree

5 files changed

+899
-47
lines changed

5 files changed

+899
-47
lines changed

REFERENCE.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,18 @@ hookdeck connection create \
992992
--destination-type HTTP \
993993
--destination-url "https://ci.example.com/webhook" \
994994
--destination-bearer-token "bearer_token_xyz"
995+
996+
**5. Source with Custom Response and Allowed HTTP Methods**
997+
```bash
998+
hookdeck connection create \
999+
--source-name "api-webhooks" \
1000+
--source-type WEBHOOK \
1001+
--source-allowed-http-methods "POST,PUT,PATCH" \
1002+
--source-custom-response-content-type "json" \
1003+
--source-custom-response-body '{"status":"received","timestamp":"2024-01-01T00:00:00Z"}' \
1004+
--destination-name "webhook-handler" \
1005+
--destination-type HTTP \
1006+
--destination-url "https://api.example.com/webhooks"
9951007
```
9961008

9971009
#### Rule Configuration Examples
@@ -1064,6 +1076,9 @@ hookdeck connection create \
10641076
- `--source-basic-auth-pass <pass>` - Basic auth password
10651077
- `--source-hmac-secret <secret>` - HMAC secret
10661078
- `--source-hmac-algo <algo>` - HMAC algorithm
1079+
- `--source-allowed-http-methods <methods>` - Comma-separated list of allowed HTTP methods: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
1080+
- `--source-custom-response-content-type <type>` - Custom response content type: `json`, `text`, `xml`
1081+
- `--source-custom-response-body <body>` - Custom response body (max 1000 chars)
10671082
- `--source-config <json>` - JSON authentication config
10681083
- `--source-config-file <path>` - Path to JSON config file
10691084

pkg/cmd/connection_create.go

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ type connectionCreateCmd struct {
3737
SourceHMACSecret string
3838
SourceHMACAlgo string
3939

40+
// Source configuration flags
41+
SourceAllowedHTTPMethods string
42+
SourceCustomResponseType string
43+
SourceCustomResponseBody string
44+
4045
// JSON config fallback
4146
SourceConfig string
4247
SourceConfigFile string
@@ -125,21 +130,30 @@ func newConnectionCreateCmd() *connectionCreateCmd {
125130
Args: validators.NoArgs,
126131
Short: "Create a new connection",
127132
Long: `Create a connection between a source and destination.
128-
129-
You can either reference existing resources by ID or create them inline.
130-
131-
Examples:
132-
# Create with inline source and destination
133-
hookdeck connection create \
134-
--name "test-webhooks-to-local" \
135-
--source-type WEBHOOK --source-name "test-webhooks" \
136-
--destination-type CLI --destination-name "local-dev"
137-
138-
# Create with existing resources
139-
hookdeck connection create \
140-
--name "github-to-api" \
141-
--source-id src_abc123 \
142-
--destination-id dst_def456`,
133+
134+
You can either reference existing resources by ID or create them inline.
135+
136+
Examples:
137+
# Create with inline source and destination
138+
hookdeck connection create \
139+
--name "test-webhooks-to-local" \
140+
--source-type WEBHOOK --source-name "test-webhooks" \
141+
--destination-type CLI --destination-name "local-dev"
142+
143+
# Create with existing resources
144+
hookdeck connection create \
145+
--name "github-to-api" \
146+
--source-id src_abc123 \
147+
--destination-id dst_def456
148+
149+
# Create with source configuration options
150+
hookdeck connection create \
151+
--name "api-webhooks" \
152+
--source-type WEBHOOK --source-name "api-source" \
153+
--source-allowed-http-methods "POST,PUT,PATCH" \
154+
--source-custom-response-content-type "json" \
155+
--source-custom-response-body '{"status":"received"}' \
156+
--destination-type CLI --destination-name "local-dev"`,
143157
PreRunE: cc.validateFlags,
144158
RunE: cc.runConnectionCreateCmd,
145159
}
@@ -161,6 +175,11 @@ Examples:
161175
cc.cmd.Flags().StringVar(&cc.SourceHMACSecret, "source-hmac-secret", "", "HMAC secret for signature verification")
162176
cc.cmd.Flags().StringVar(&cc.SourceHMACAlgo, "source-hmac-algo", "", "HMAC algorithm (SHA256, etc.)")
163177

178+
// Source configuration flags
179+
cc.cmd.Flags().StringVar(&cc.SourceAllowedHTTPMethods, "source-allowed-http-methods", "", "Comma-separated list of allowed HTTP methods (GET, POST, PUT, PATCH, DELETE)")
180+
cc.cmd.Flags().StringVar(&cc.SourceCustomResponseType, "source-custom-response-content-type", "", "Custom response content type (json, text, xml)")
181+
cc.cmd.Flags().StringVar(&cc.SourceCustomResponseBody, "source-custom-response-body", "", "Custom response body (max 1000 chars)")
182+
164183
// JSON config fallback
165184
cc.cmd.Flags().StringVar(&cc.SourceConfig, "source-config", "", "JSON string for source authentication config")
166185
cc.cmd.Flags().StringVar(&cc.SourceConfigFile, "source-config-file", "", "Path to a JSON file for source authentication config")
@@ -828,6 +847,49 @@ func (cc *connectionCreateCmd) buildSourceConfig() (map[string]interface{}, erro
828847
config["hmac"] = hmacConfig
829848
}
830849

850+
// Add allowed HTTP methods
851+
if cc.SourceAllowedHTTPMethods != "" {
852+
methods := strings.Split(cc.SourceAllowedHTTPMethods, ",")
853+
// Trim whitespace and validate
854+
validMethods := []string{}
855+
allowedMethods := map[string]bool{"GET": true, "POST": true, "PUT": true, "PATCH": true, "DELETE": true}
856+
for _, method := range methods {
857+
method = strings.TrimSpace(strings.ToUpper(method))
858+
if !allowedMethods[method] {
859+
return nil, fmt.Errorf("invalid HTTP method '%s' in --source-allowed-http-methods (allowed: GET, POST, PUT, PATCH, DELETE)", method)
860+
}
861+
validMethods = append(validMethods, method)
862+
}
863+
config["allowed_http_methods"] = validMethods
864+
}
865+
866+
// Add custom response configuration
867+
if cc.SourceCustomResponseType != "" || cc.SourceCustomResponseBody != "" {
868+
if cc.SourceCustomResponseType == "" {
869+
return nil, fmt.Errorf("--source-custom-response-content-type is required when using --source-custom-response-body")
870+
}
871+
if cc.SourceCustomResponseBody == "" {
872+
return nil, fmt.Errorf("--source-custom-response-body is required when using --source-custom-response-content-type")
873+
}
874+
875+
// Validate content type
876+
validContentTypes := map[string]bool{"json": true, "text": true, "xml": true}
877+
contentType := strings.ToLower(cc.SourceCustomResponseType)
878+
if !validContentTypes[contentType] {
879+
return nil, fmt.Errorf("invalid content type '%s' in --source-custom-response-content-type (allowed: json, text, xml)", cc.SourceCustomResponseType)
880+
}
881+
882+
// Validate body length (max 1000 chars per API spec)
883+
if len(cc.SourceCustomResponseBody) > 1000 {
884+
return nil, fmt.Errorf("--source-custom-response-body exceeds maximum length of 1000 characters (got %d)", len(cc.SourceCustomResponseBody))
885+
}
886+
887+
config["custom_response"] = map[string]interface{}{
888+
"content_type": contentType,
889+
"body": cc.SourceCustomResponseBody,
890+
}
891+
}
892+
831893
if len(config) == 0 {
832894
return make(map[string]interface{}), nil
833895
}

0 commit comments

Comments
 (0)