From 5c0cc7eff0e4c1c8b1c2ad3c87961ff3a8fd2eb0 Mon Sep 17 00:00:00 2001 From: Sung-Kyu Yoo Date: Sat, 5 Sep 2026 18:44:55 +0900 Subject: [PATCH 1/2] refactor: extract the URI route matcher into internal/shared/httproute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The matcher lived only inside router.go.tmpl, so it was emitted into 148 generated packages and could not be imported. The CRUD engine needs the same answer from the same data to resolve a rest-json operation, and writing it a 149th time is how the two would drift. PathParams and OperationRoute become type aliases, so the four hand-written callers (cloudfront, efs and their tests) compile and pass unchanged — that is the behavioural proof this is a refactor. RED: go test ./internal/shared/httproute/ failed to build — match_test.go:12:11: undefined: Params match_test.go:85:15: undefined: MatchURI match_test.go:163:14: undefined: Route FAIL ... [build failed] (a standalone RED commit is impossible here: the repo's pre-commit go-vet hook refuses a non-compiling tree, so the evidence is recorded here.) GREEN: go test ./internal/shared/httproute/ -v — 20/20 subtests PASS. Full suite: CGO_ENABLED=0 go test ./... all pass. gen_router_test.go swaps its "type OperationRoute struct" assertion for one on the delegation, which is what stops the algorithm being re-inlined. Net -16,728 lines across 136 regenerated routers. --- internal/codegen/gen_router_test.go | 6 +- internal/codegen/templates/router.go.tmpl | 139 +----------- internal/generated/acm/router.go | 139 +----------- internal/generated/acmpca/router.go | 139 +----------- internal/generated/amplify/router.go | 139 +----------- internal/generated/apigatewayv2/router.go | 139 +----------- internal/generated/appconfig/router.go | 139 +----------- .../applicationautoscaling/router.go | 139 +----------- internal/generated/appsync/router.go | 139 +----------- internal/generated/athena/router.go | 139 +----------- internal/generated/autoscaling/router.go | 139 +----------- internal/generated/backup/router.go | 139 +----------- internal/generated/batch/router.go | 139 +----------- internal/generated/bedrock/router.go | 139 +----------- internal/generated/bedrockagent/router.go | 139 +----------- internal/generated/bedrockagentcore/router.go | 139 +----------- .../bedrockagentcorecontrol/router.go | 139 +----------- .../generated/bedrockagentruntime/router.go | 139 +----------- .../generated/bedrockdataautomation/router.go | 139 +----------- .../bedrockdataautomationruntime/router.go | 139 +----------- internal/generated/bedrockruntime/router.go | 139 +----------- internal/generated/cloudformation/router.go | 139 +----------- internal/generated/cloudfront/router.go | 139 +----------- internal/generated/cloudsearch/router.go | 139 +----------- internal/generated/cloudtrail/router.go | 139 +----------- internal/generated/cloudwatch/router.go | 139 +----------- internal/generated/cloudwatchlogs/router.go | 139 +----------- internal/generated/codeartifact/router.go | 139 +----------- internal/generated/codebuild/router.go | 139 +----------- internal/generated/codecommit/router.go | 139 +----------- internal/generated/codedeploy/router.go | 139 +----------- internal/generated/codeguruprofiler/router.go | 139 +----------- internal/generated/codegurureviewer/router.go | 139 +----------- internal/generated/codegurusecurity/router.go | 139 +----------- internal/generated/codepipeline/router.go | 139 +----------- internal/generated/cognitoidentity/router.go | 139 +----------- .../cognitoidentityprovider/router.go | 139 +----------- internal/generated/comprehend/router.go | 139 +----------- .../generated/comprehendmedical/router.go | 139 +----------- internal/generated/configservice/router.go | 139 +----------- internal/generated/costexplorer/router.go | 139 +----------- internal/generated/devopsguru/router.go | 139 +----------- internal/generated/docdb/router.go | 139 +----------- internal/generated/dynamodb/router.go | 139 +----------- internal/generated/dynamodbstreams/router.go | 139 +----------- internal/generated/ebs/router.go | 139 +----------- internal/generated/ec2/router.go | 139 +----------- internal/generated/ecr/router.go | 139 +----------- internal/generated/ecs/router.go | 139 +----------- internal/generated/efs/router.go | 139 +----------- internal/generated/eks/router.go | 139 +----------- internal/generated/elasticache/router.go | 139 +----------- internal/generated/elasticbeanstalk/router.go | 139 +----------- .../elasticloadbalancingv2/router.go | 139 +----------- .../generated/elasticsearchservice/router.go | 139 +----------- internal/generated/emr/router.go | 139 +----------- internal/generated/entityresolution/router.go | 139 +----------- internal/generated/eventbridge/router.go | 139 +----------- internal/generated/firehose/router.go | 139 +----------- internal/generated/fis/router.go | 139 +----------- internal/generated/forecast/router.go | 139 +----------- internal/generated/forecastquery/router.go | 139 +----------- internal/generated/frauddetector/router.go | 139 +----------- internal/generated/glacier/router.go | 139 +----------- internal/generated/glue/router.go | 139 +----------- internal/generated/healthlake/router.go | 139 +----------- internal/generated/iam/router.go | 139 +----------- internal/generated/iot/router.go | 139 +----------- internal/generated/iotdataplane/router.go | 139 +----------- internal/generated/iotwireless/router.go | 139 +----------- internal/generated/kafka/router.go | 139 +----------- internal/generated/kendra/router.go | 139 +----------- internal/generated/kendraranking/router.go | 139 +----------- internal/generated/kinesis/router.go | 139 +----------- .../generated/kinesisanalyticsv2/router.go | 139 +----------- internal/generated/kms/router.go | 139 +----------- internal/generated/lakeformation/router.go | 139 +----------- internal/generated/lambda/router.go | 139 +----------- .../lexmodelbuildingservice/router.go | 139 +----------- internal/generated/lexmodelsv2/router.go | 139 +----------- .../generated/lexruntimeservice/router.go | 139 +----------- internal/generated/lexruntimev2/router.go | 139 +----------- internal/generated/lookoutequipment/router.go | 139 +----------- .../generated/managedblockchain/router.go | 139 +----------- internal/generated/memorydb/router.go | 139 +----------- internal/generated/mq/router.go | 139 +----------- internal/generated/mwaa/router.go | 139 +----------- internal/generated/neptune/router.go | 139 +----------- internal/generated/omics/router.go | 139 +----------- internal/generated/opensearch/router.go | 139 +----------- internal/generated/organizations/router.go | 139 +----------- internal/generated/personalize/router.go | 139 +----------- .../generated/personalizeevents/router.go | 139 +----------- .../generated/personalizeruntime/router.go | 139 +----------- internal/generated/pinpoint/router.go | 139 +----------- internal/generated/polly/router.go | 139 +----------- internal/generated/qapps/router.go | 139 +----------- internal/generated/qbusiness/router.go | 139 +----------- internal/generated/ram/router.go | 139 +----------- internal/generated/rds/router.go | 139 +----------- internal/generated/redshift/router.go | 139 +----------- internal/generated/rekognition/router.go | 139 +----------- internal/generated/resourcegroups/router.go | 139 +----------- .../resourcegroupstaggingapi/router.go | 139 +----------- internal/generated/route53/router.go | 139 +----------- internal/generated/route53resolver/router.go | 139 +----------- internal/generated/s3/router.go | 139 +----------- internal/generated/sagemaker/router.go | 139 +----------- .../generated/sagemakera2iruntime/router.go | 139 +----------- internal/generated/sagemakeredge/router.go | 139 +----------- .../sagemakerfeaturestoreruntime/router.go | 139 +----------- .../generated/sagemakergeospatial/router.go | 139 +----------- .../generated/sagemakerjobruntime/router.go | 139 +----------- internal/generated/sagemakermetrics/router.go | 139 +----------- internal/generated/sagemakerruntime/router.go | 139 +----------- .../generated/sagemakerruntimehttp2/router.go | 139 +----------- internal/generated/secretsmanager/router.go | 139 +----------- internal/generated/servicediscovery/router.go | 139 +----------- internal/generated/ses/router.go | 139 +----------- internal/generated/sesv2/router.go | 139 +----------- internal/generated/sfn/router.go | 139 +----------- internal/generated/shield/router.go | 139 +----------- internal/generated/sns/router.go | 139 +----------- internal/generated/sqs/router.go | 139 +----------- internal/generated/ssm/router.go | 139 +----------- internal/generated/ssoadmin/router.go | 139 +----------- internal/generated/support/router.go | 139 +----------- internal/generated/swf/router.go | 139 +----------- internal/generated/textract/router.go | 139 +----------- internal/generated/timestreamwrite/router.go | 139 +----------- internal/generated/transcribe/router.go | 139 +----------- .../generated/transcribestreaming/router.go | 139 +----------- internal/generated/transfer/router.go | 139 +----------- internal/generated/translate/router.go | 139 +----------- internal/generated/voiceid/router.go | 139 +----------- internal/generated/waf/router.go | 139 +----------- internal/generated/wafv2/router.go | 139 +----------- internal/generated/xray/router.go | 139 +----------- internal/shared/httproute/match.go | 152 +++++++++++++ internal/shared/httproute/match_test.go | 202 ++++++++++++++++++ 140 files changed, 1455 insertions(+), 17948 deletions(-) create mode 100644 internal/shared/httproute/match.go create mode 100644 internal/shared/httproute/match_test.go diff --git a/internal/codegen/gen_router_test.go b/internal/codegen/gen_router_test.go index 07b74da7..6b5b2349 100644 --- a/internal/codegen/gen_router_test.go +++ b/internal/codegen/gen_router_test.go @@ -15,11 +15,15 @@ func TestGenerateRouter(t *testing.T) { output, err := gen.GenerateRouter("s3", model) require.NoError(t, err) assert.Contains(t, output, "package s3") - assert.Contains(t, output, "type OperationRoute struct") assert.Contains(t, output, "OperationRoutes") assert.Contains(t, output, `"CreateBucket"`) assert.Contains(t, output, `"PUT"`) assert.Contains(t, output, `"/{Bucket}"`) + // The route table is generated per service; the matching is not. Asserting + // the delegation is what stops a future edit from re-inlining the algorithm + // into 148 packages, which is the drift internal/shared/httproute exists to + // prevent. + assert.Contains(t, output, "httproute.Match(OperationRoutes, method, uri)") } func TestGenerateErrors(t *testing.T) { diff --git a/internal/codegen/templates/router.go.tmpl b/internal/codegen/templates/router.go.tmpl index 98b9ff66..2ca6c4ee 100644 --- a/internal/codegen/templates/router.go.tmpl +++ b/internal/codegen/templates/router.go.tmpl @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package {{ .PkgName }} -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -31,126 +24,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/acm/router.go b/internal/generated/acm/router.go index 7496e7c6..7f88bf80 100644 --- a/internal/generated/acm/router.go +++ b/internal/generated/acm/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package acm -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -45,126 +38,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/acmpca/router.go b/internal/generated/acmpca/router.go index ea691b2a..29f84603 100644 --- a/internal/generated/acmpca/router.go +++ b/internal/generated/acmpca/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package acmpca -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/amplify/router.go b/internal/generated/amplify/router.go index 2178650f..f55876ac 100644 --- a/internal/generated/amplify/router.go +++ b/internal/generated/amplify/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package amplify -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -65,126 +58,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/apigatewayv2/router.go b/internal/generated/apigatewayv2/router.go index a8a7bcec..d1b95b85 100644 --- a/internal/generated/apigatewayv2/router.go +++ b/internal/generated/apigatewayv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package apigatewayv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -131,126 +124,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/appconfig/router.go b/internal/generated/appconfig/router.go index 015cbef1..8861909b 100644 --- a/internal/generated/appconfig/router.go +++ b/internal/generated/appconfig/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package appconfig -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -73,126 +66,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/applicationautoscaling/router.go b/internal/generated/applicationautoscaling/router.go index a8d4e81f..32ed6c89 100644 --- a/internal/generated/applicationautoscaling/router.go +++ b/internal/generated/applicationautoscaling/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package applicationautoscaling -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -42,126 +35,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/appsync/router.go b/internal/generated/appsync/router.go index 10937d6b..17f47747 100644 --- a/internal/generated/appsync/router.go +++ b/internal/generated/appsync/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package appsync -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -102,126 +95,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/athena/router.go b/internal/generated/athena/router.go index a31c5efe..c0d3c3e7 100644 --- a/internal/generated/athena/router.go +++ b/internal/generated/athena/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package athena -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -98,126 +91,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/autoscaling/router.go b/internal/generated/autoscaling/router.go index 89856216..3faef439 100644 --- a/internal/generated/autoscaling/router.go +++ b/internal/generated/autoscaling/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package autoscaling -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -94,126 +87,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/backup/router.go b/internal/generated/backup/router.go index 3e5c1eb2..900a4c8e 100644 --- a/internal/generated/backup/router.go +++ b/internal/generated/backup/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package backup -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -136,126 +129,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/batch/router.go b/internal/generated/batch/router.go index c758518d..2dbf7f69 100644 --- a/internal/generated/batch/router.go +++ b/internal/generated/batch/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package batch -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -73,126 +66,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrock/router.go b/internal/generated/bedrock/router.go index 2b927b4c..0f81f8a3 100644 --- a/internal/generated/bedrock/router.go +++ b/internal/generated/bedrock/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrock -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -129,126 +122,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockagent/router.go b/internal/generated/bedrockagent/router.go index 4a185242..90c1463b 100644 --- a/internal/generated/bedrockagent/router.go +++ b/internal/generated/bedrockagent/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockagent -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -103,126 +96,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockagentcore/router.go b/internal/generated/bedrockagentcore/router.go index dd229012..0adb8c39 100644 --- a/internal/generated/bedrockagentcore/router.go +++ b/internal/generated/bedrockagentcore/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockagentcore -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -95,126 +88,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockagentcorecontrol/router.go b/internal/generated/bedrockagentcorecontrol/router.go index e3136f1f..01ced9b2 100644 --- a/internal/generated/bedrockagentcorecontrol/router.go +++ b/internal/generated/bedrockagentcorecontrol/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockagentcorecontrol -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -198,126 +191,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockagentruntime/router.go b/internal/generated/bedrockagentruntime/router.go index 699ba827..09dc8e43 100644 --- a/internal/generated/bedrockagentruntime/router.go +++ b/internal/generated/bedrockagentruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockagentruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -63,126 +56,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockdataautomation/router.go b/internal/generated/bedrockdataautomation/router.go index c209311e..a3a39768 100644 --- a/internal/generated/bedrockdataautomation/router.go +++ b/internal/generated/bedrockdataautomation/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockdataautomation -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -55,126 +48,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockdataautomationruntime/router.go b/internal/generated/bedrockdataautomationruntime/router.go index 1f7bb83c..60276895 100644 --- a/internal/generated/bedrockdataautomationruntime/router.go +++ b/internal/generated/bedrockdataautomationruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockdataautomationruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -34,126 +27,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/bedrockruntime/router.go b/internal/generated/bedrockruntime/router.go index 6004e478..4e253b9a 100644 --- a/internal/generated/bedrockruntime/router.go +++ b/internal/generated/bedrockruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package bedrockruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -39,126 +32,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudformation/router.go b/internal/generated/cloudformation/router.go index 91a99f82..b3ea18d9 100644 --- a/internal/generated/cloudformation/router.go +++ b/internal/generated/cloudformation/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudformation -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -118,126 +111,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudfront/router.go b/internal/generated/cloudfront/router.go index a53bc7e8..31879b8a 100644 --- a/internal/generated/cloudfront/router.go +++ b/internal/generated/cloudfront/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudfront -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -195,126 +188,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudsearch/router.go b/internal/generated/cloudsearch/router.go index ba837ff7..3c08ce84 100644 --- a/internal/generated/cloudsearch/router.go +++ b/internal/generated/cloudsearch/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudsearch -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -54,126 +47,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudtrail/router.go b/internal/generated/cloudtrail/router.go index be6fd157..48bac6bd 100644 --- a/internal/generated/cloudtrail/router.go +++ b/internal/generated/cloudtrail/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudtrail -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -88,126 +81,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudwatch/router.go b/internal/generated/cloudwatch/router.go index 7b69d710..c2d6f5a9 100644 --- a/internal/generated/cloudwatch/router.go +++ b/internal/generated/cloudwatch/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudwatch -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -74,126 +67,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cloudwatchlogs/router.go b/internal/generated/cloudwatchlogs/router.go index 9d2141a9..fbdfaed9 100644 --- a/internal/generated/cloudwatchlogs/router.go +++ b/internal/generated/cloudwatchlogs/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cloudwatchlogs -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -141,126 +134,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codeartifact/router.go b/internal/generated/codeartifact/router.go index f87416b3..6c5b17ff 100644 --- a/internal/generated/codeartifact/router.go +++ b/internal/generated/codeartifact/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codeartifact -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -76,126 +69,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codebuild/router.go b/internal/generated/codebuild/router.go index a54ada0e..43f88f86 100644 --- a/internal/generated/codebuild/router.go +++ b/internal/generated/codebuild/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codebuild -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -87,126 +80,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codecommit/router.go b/internal/generated/codecommit/router.go index 859dc650..6a36ac21 100644 --- a/internal/generated/codecommit/router.go +++ b/internal/generated/codecommit/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codecommit -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -107,126 +100,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codedeploy/router.go b/internal/generated/codedeploy/router.go index 8d4d8e5e..54be9a11 100644 --- a/internal/generated/codedeploy/router.go +++ b/internal/generated/codedeploy/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codedeploy -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -75,126 +68,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codeguruprofiler/router.go b/internal/generated/codeguruprofiler/router.go index 89d5265c..34cb0df4 100644 --- a/internal/generated/codeguruprofiler/router.go +++ b/internal/generated/codeguruprofiler/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codeguruprofiler -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codegurureviewer/router.go b/internal/generated/codegurureviewer/router.go index bb88a934..02f1c1e2 100644 --- a/internal/generated/codegurureviewer/router.go +++ b/internal/generated/codegurureviewer/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codegurureviewer -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -42,126 +35,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codegurusecurity/router.go b/internal/generated/codegurusecurity/router.go index de0b5065..a8749014 100644 --- a/internal/generated/codegurusecurity/router.go +++ b/internal/generated/codegurusecurity/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codegurusecurity -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -41,126 +34,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/codepipeline/router.go b/internal/generated/codepipeline/router.go index ac551024..0c2423cb 100644 --- a/internal/generated/codepipeline/router.go +++ b/internal/generated/codepipeline/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package codepipeline -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -72,126 +65,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cognitoidentity/router.go b/internal/generated/cognitoidentity/router.go index ac3cbddb..77958cce 100644 --- a/internal/generated/cognitoidentity/router.go +++ b/internal/generated/cognitoidentity/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cognitoidentity -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/cognitoidentityprovider/router.go b/internal/generated/cognitoidentityprovider/router.go index 395d9fd0..8383e623 100644 --- a/internal/generated/cognitoidentityprovider/router.go +++ b/internal/generated/cognitoidentityprovider/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package cognitoidentityprovider -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -150,126 +143,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/comprehend/router.go b/internal/generated/comprehend/router.go index 0a804368..1a3c598d 100644 --- a/internal/generated/comprehend/router.go +++ b/internal/generated/comprehend/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package comprehend -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -113,126 +106,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/comprehendmedical/router.go b/internal/generated/comprehendmedical/router.go index 84d54ea4..37d03c36 100644 --- a/internal/generated/comprehendmedical/router.go +++ b/internal/generated/comprehendmedical/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package comprehendmedical -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -54,126 +47,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/configservice/router.go b/internal/generated/configservice/router.go index 255d7728..e4fff207 100644 --- a/internal/generated/configservice/router.go +++ b/internal/generated/configservice/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package configservice -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -125,126 +118,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/costexplorer/router.go b/internal/generated/costexplorer/router.go index 6d2973b5..b88e118c 100644 --- a/internal/generated/costexplorer/router.go +++ b/internal/generated/costexplorer/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package costexplorer -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -75,126 +68,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/devopsguru/router.go b/internal/generated/devopsguru/router.go index 9aca8ff0..6f0245a7 100644 --- a/internal/generated/devopsguru/router.go +++ b/internal/generated/devopsguru/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package devopsguru -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -59,126 +52,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/docdb/router.go b/internal/generated/docdb/router.go index 2a2b5362..bff61827 100644 --- a/internal/generated/docdb/router.go +++ b/internal/generated/docdb/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package docdb -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -83,126 +76,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/dynamodb/router.go b/internal/generated/dynamodb/router.go index 231c1c19..a81ed4b2 100644 --- a/internal/generated/dynamodb/router.go +++ b/internal/generated/dynamodb/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package dynamodb -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -85,126 +78,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/dynamodbstreams/router.go b/internal/generated/dynamodbstreams/router.go index ddd0c136..94eed756 100644 --- a/internal/generated/dynamodbstreams/router.go +++ b/internal/generated/dynamodbstreams/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package dynamodbstreams -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -32,126 +25,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ebs/router.go b/internal/generated/ebs/router.go index 57f1dc0e..0c692e38 100644 --- a/internal/generated/ebs/router.go +++ b/internal/generated/ebs/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ebs -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -34,126 +27,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ec2/router.go b/internal/generated/ec2/router.go index d1f63176..fe7769b7 100644 --- a/internal/generated/ec2/router.go +++ b/internal/generated/ec2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ec2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -784,126 +777,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ecr/router.go b/internal/generated/ecr/router.go index 13730ce4..54df2dc5 100644 --- a/internal/generated/ecr/router.go +++ b/internal/generated/ecr/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ecr -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -86,126 +79,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ecs/router.go b/internal/generated/ecs/router.go index eeb46c95..40564d13 100644 --- a/internal/generated/ecs/router.go +++ b/internal/generated/ecs/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ecs -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -104,126 +97,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/efs/router.go b/internal/generated/efs/router.go index 6c3a442e..9df13a97 100644 --- a/internal/generated/efs/router.go +++ b/internal/generated/efs/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package efs -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -59,126 +52,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/eks/router.go b/internal/generated/eks/router.go index 4d4003f3..8392791b 100644 --- a/internal/generated/eks/router.go +++ b/internal/generated/eks/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package eks -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -92,126 +85,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/elasticache/router.go b/internal/generated/elasticache/router.go index a227634a..42df9352 100644 --- a/internal/generated/elasticache/router.go +++ b/internal/generated/elasticache/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package elasticache -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -103,126 +96,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/elasticbeanstalk/router.go b/internal/generated/elasticbeanstalk/router.go index 1cad3867..77e8bd71 100644 --- a/internal/generated/elasticbeanstalk/router.go +++ b/internal/generated/elasticbeanstalk/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package elasticbeanstalk -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -75,126 +68,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/elasticloadbalancingv2/router.go b/internal/generated/elasticloadbalancingv2/router.go index 80322861..f28f7548 100644 --- a/internal/generated/elasticloadbalancingv2/router.go +++ b/internal/generated/elasticloadbalancingv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package elasticloadbalancingv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -79,126 +72,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/elasticsearchservice/router.go b/internal/generated/elasticsearchservice/router.go index 1aea7447..55f9d2dd 100644 --- a/internal/generated/elasticsearchservice/router.go +++ b/internal/generated/elasticsearchservice/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package elasticsearchservice -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -79,126 +72,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/emr/router.go b/internal/generated/emr/router.go index 6d01d72a..773673cf 100644 --- a/internal/generated/emr/router.go +++ b/internal/generated/emr/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package emr -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -88,126 +81,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/entityresolution/router.go b/internal/generated/entityresolution/router.go index 13699d32..002838da 100644 --- a/internal/generated/entityresolution/router.go +++ b/internal/generated/entityresolution/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package entityresolution -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -66,126 +59,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/eventbridge/router.go b/internal/generated/eventbridge/router.go index 3616563c..0aef66c4 100644 --- a/internal/generated/eventbridge/router.go +++ b/internal/generated/eventbridge/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package eventbridge -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -85,126 +78,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/firehose/router.go b/internal/generated/firehose/router.go index 274e1252..9677b611 100644 --- a/internal/generated/firehose/router.go +++ b/internal/generated/firehose/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package firehose -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -40,126 +33,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/fis/router.go b/internal/generated/fis/router.go index d74d4cac..71a9d906 100644 --- a/internal/generated/fis/router.go +++ b/internal/generated/fis/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package fis -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -54,126 +47,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/forecast/router.go b/internal/generated/forecast/router.go index 0935d29a..93ba5977 100644 --- a/internal/generated/forecast/router.go +++ b/internal/generated/forecast/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package forecast -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -91,126 +84,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/forecastquery/router.go b/internal/generated/forecastquery/router.go index 34e85a5e..c21df4b7 100644 --- a/internal/generated/forecastquery/router.go +++ b/internal/generated/forecastquery/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package forecastquery -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -30,126 +23,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/frauddetector/router.go b/internal/generated/frauddetector/router.go index 4a34e070..524dc0d4 100644 --- a/internal/generated/frauddetector/router.go +++ b/internal/generated/frauddetector/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package frauddetector -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -101,126 +94,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/glacier/router.go b/internal/generated/glacier/router.go index 869c2187..572ffb06 100644 --- a/internal/generated/glacier/router.go +++ b/internal/generated/glacier/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package glacier -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -61,126 +54,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/glue/router.go b/internal/generated/glue/router.go index 34b279d5..0c97d13b 100644 --- a/internal/generated/glue/router.go +++ b/internal/generated/glue/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package glue -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -293,126 +286,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/healthlake/router.go b/internal/generated/healthlake/router.go index 203c31ab..22a92b77 100644 --- a/internal/generated/healthlake/router.go +++ b/internal/generated/healthlake/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package healthlake -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -54,126 +47,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/iam/router.go b/internal/generated/iam/router.go index 65b3549c..cce5b751 100644 --- a/internal/generated/iam/router.go +++ b/internal/generated/iam/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package iam -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -204,126 +197,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/iot/router.go b/internal/generated/iot/router.go index a148480a..08f40de2 100644 --- a/internal/generated/iot/router.go +++ b/internal/generated/iot/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package iot -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -300,126 +293,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/iotdataplane/router.go b/internal/generated/iotdataplane/router.go index 523df8bd..142014be 100644 --- a/internal/generated/iotdataplane/router.go +++ b/internal/generated/iotdataplane/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package iotdataplane -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -36,126 +29,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/iotwireless/router.go b/internal/generated/iotwireless/router.go index 6ee6168b..13835f1e 100644 --- a/internal/generated/iotwireless/router.go +++ b/internal/generated/iotwireless/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package iotwireless -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -140,126 +133,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kafka/router.go b/internal/generated/kafka/router.go index a2904c33..bd39da93 100644 --- a/internal/generated/kafka/router.go +++ b/internal/generated/kafka/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kafka -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -87,126 +80,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kendra/router.go b/internal/generated/kendra/router.go index 553669de..8c9fdcfd 100644 --- a/internal/generated/kendra/router.go +++ b/internal/generated/kendra/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kendra -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -94,126 +87,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kendraranking/router.go b/internal/generated/kendraranking/router.go index 781fd974..042dd68d 100644 --- a/internal/generated/kendraranking/router.go +++ b/internal/generated/kendraranking/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kendraranking -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -37,126 +30,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kinesis/router.go b/internal/generated/kinesis/router.go index 42ded85c..1d113f44 100644 --- a/internal/generated/kinesis/router.go +++ b/internal/generated/kinesis/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kinesis -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -67,126 +60,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kinesisanalyticsv2/router.go b/internal/generated/kinesisanalyticsv2/router.go index 2a2f4e29..093c1018 100644 --- a/internal/generated/kinesisanalyticsv2/router.go +++ b/internal/generated/kinesisanalyticsv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kinesisanalyticsv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -61,126 +54,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/kms/router.go b/internal/generated/kms/router.go index 4f2a4e95..de38d9f5 100644 --- a/internal/generated/kms/router.go +++ b/internal/generated/kms/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package kms -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -81,126 +74,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lakeformation/router.go b/internal/generated/lakeformation/router.go index c0e009cd..6f30239f 100644 --- a/internal/generated/lakeformation/router.go +++ b/internal/generated/lakeformation/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lakeformation -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -89,126 +82,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lambda/router.go b/internal/generated/lambda/router.go index bcdb9720..8b3f04d8 100644 --- a/internal/generated/lambda/router.go +++ b/internal/generated/lambda/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lambda -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -113,126 +106,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lexmodelbuildingservice/router.go b/internal/generated/lexmodelbuildingservice/router.go index 78572506..ec3085d7 100644 --- a/internal/generated/lexmodelbuildingservice/router.go +++ b/internal/generated/lexmodelbuildingservice/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lexmodelbuildingservice -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -70,126 +63,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lexmodelsv2/router.go b/internal/generated/lexmodelsv2/router.go index 7e4c09ab..41c08343 100644 --- a/internal/generated/lexmodelsv2/router.go +++ b/internal/generated/lexmodelsv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lexmodelsv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -135,126 +128,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lexruntimeservice/router.go b/internal/generated/lexruntimeservice/router.go index 935beb45..9bada19b 100644 --- a/internal/generated/lexruntimeservice/router.go +++ b/internal/generated/lexruntimeservice/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lexruntimeservice -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -33,126 +26,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lexruntimev2/router.go b/internal/generated/lexruntimev2/router.go index 045b0c6d..00d3e310 100644 --- a/internal/generated/lexruntimev2/router.go +++ b/internal/generated/lexruntimev2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lexruntimev2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -34,126 +27,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/lookoutequipment/router.go b/internal/generated/lookoutequipment/router.go index 665597a5..a49134ab 100644 --- a/internal/generated/lookoutequipment/router.go +++ b/internal/generated/lookoutequipment/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package lookoutequipment -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -77,126 +70,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/managedblockchain/router.go b/internal/generated/managedblockchain/router.go index 62b78912..77baa239 100644 --- a/internal/generated/managedblockchain/router.go +++ b/internal/generated/managedblockchain/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package managedblockchain -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -55,126 +48,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/memorydb/router.go b/internal/generated/memorydb/router.go index 9ae1ebf7..99797bf6 100644 --- a/internal/generated/memorydb/router.go +++ b/internal/generated/memorydb/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package memorydb -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -73,126 +66,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/mq/router.go b/internal/generated/mq/router.go index 4720387f..23cf4aec 100644 --- a/internal/generated/mq/router.go +++ b/internal/generated/mq/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package mq -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -52,126 +45,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/mwaa/router.go b/internal/generated/mwaa/router.go index 72351c13..a36e1930 100644 --- a/internal/generated/mwaa/router.go +++ b/internal/generated/mwaa/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package mwaa -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -40,126 +33,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/neptune/router.go b/internal/generated/neptune/router.go index 499384d1..53c4efa6 100644 --- a/internal/generated/neptune/router.go +++ b/internal/generated/neptune/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package neptune -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -98,126 +91,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/omics/router.go b/internal/generated/omics/router.go index 8b350245..2931420b 100644 --- a/internal/generated/omics/router.go +++ b/internal/generated/omics/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package omics -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -135,126 +128,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/opensearch/router.go b/internal/generated/opensearch/router.go index d95df00d..ec6c27ff 100644 --- a/internal/generated/opensearch/router.go +++ b/internal/generated/opensearch/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package opensearch -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -115,126 +108,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/organizations/router.go b/internal/generated/organizations/router.go index 7ac5674e..2bb239c6 100644 --- a/internal/generated/organizations/router.go +++ b/internal/generated/organizations/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package organizations -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -91,126 +84,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/personalize/router.go b/internal/generated/personalize/router.go index fd5e3311..42a00416 100644 --- a/internal/generated/personalize/router.go +++ b/internal/generated/personalize/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package personalize -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -99,126 +92,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/personalizeevents/router.go b/internal/generated/personalizeevents/router.go index 83a0c6e8..f597ff51 100644 --- a/internal/generated/personalizeevents/router.go +++ b/internal/generated/personalizeevents/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package personalizeevents -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -33,126 +26,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/personalizeruntime/router.go b/internal/generated/personalizeruntime/router.go index e2466025..d6652d9c 100644 --- a/internal/generated/personalizeruntime/router.go +++ b/internal/generated/personalizeruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package personalizeruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -31,126 +24,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/pinpoint/router.go b/internal/generated/pinpoint/router.go index d2f1d86a..2ae44cab 100644 --- a/internal/generated/pinpoint/router.go +++ b/internal/generated/pinpoint/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package pinpoint -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -150,126 +143,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/polly/router.go b/internal/generated/polly/router.go index 4398dd0c..01ca2ef9 100644 --- a/internal/generated/polly/router.go +++ b/internal/generated/polly/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package polly -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -38,126 +31,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/qapps/router.go b/internal/generated/qapps/router.go index 91de7375..deae8eb1 100644 --- a/internal/generated/qapps/router.go +++ b/internal/generated/qapps/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package qapps -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -63,126 +56,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/qbusiness/router.go b/internal/generated/qbusiness/router.go index ba272db5..bab6b04c 100644 --- a/internal/generated/qbusiness/router.go +++ b/internal/generated/qbusiness/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package qbusiness -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -111,126 +104,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ram/router.go b/internal/generated/ram/router.go index 17fdfe2a..80155097 100644 --- a/internal/generated/ram/router.go +++ b/internal/generated/ram/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ram -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -63,126 +56,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/rds/router.go b/internal/generated/rds/router.go index 6bd85fa9..8f8ee8a0 100644 --- a/internal/generated/rds/router.go +++ b/internal/generated/rds/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package rds -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -191,126 +184,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/redshift/router.go b/internal/generated/redshift/router.go index 6361830b..2e048140 100644 --- a/internal/generated/redshift/router.go +++ b/internal/generated/redshift/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package redshift -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -169,126 +162,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/rekognition/router.go b/internal/generated/rekognition/router.go index a50f3187..ffd53d5c 100644 --- a/internal/generated/rekognition/router.go +++ b/internal/generated/rekognition/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package rekognition -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -103,126 +96,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/resourcegroups/router.go b/internal/generated/resourcegroups/router.go index a3ef894b..114443b0 100644 --- a/internal/generated/resourcegroups/router.go +++ b/internal/generated/resourcegroups/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package resourcegroups -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/resourcegroupstaggingapi/router.go b/internal/generated/resourcegroupstaggingapi/router.go index a20a0b84..6af6ddd9 100644 --- a/internal/generated/resourcegroupstaggingapi/router.go +++ b/internal/generated/resourcegroupstaggingapi/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package resourcegroupstaggingapi -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -37,126 +30,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/route53/router.go b/internal/generated/route53/router.go index 0d33bac6..0f75aac1 100644 --- a/internal/generated/route53/router.go +++ b/internal/generated/route53/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package route53 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -99,126 +92,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/route53resolver/router.go b/internal/generated/route53resolver/router.go index 012ac76c..bbea1075 100644 --- a/internal/generated/route53resolver/router.go +++ b/internal/generated/route53resolver/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package route53resolver -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -96,126 +89,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/s3/router.go b/internal/generated/s3/router.go index 22c4dbca..08e0e03e 100644 --- a/internal/generated/s3/router.go +++ b/internal/generated/s3/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package s3 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -135,126 +128,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemaker/router.go b/internal/generated/sagemaker/router.go index b8d03268..5c0d84a9 100644 --- a/internal/generated/sagemaker/router.go +++ b/internal/generated/sagemaker/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemaker -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -409,126 +402,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakera2iruntime/router.go b/internal/generated/sagemakera2iruntime/router.go index cc5569f9..11ea7e66 100644 --- a/internal/generated/sagemakera2iruntime/router.go +++ b/internal/generated/sagemakera2iruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakera2iruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -33,126 +26,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakeredge/router.go b/internal/generated/sagemakeredge/router.go index b367e4fe..61a24510 100644 --- a/internal/generated/sagemakeredge/router.go +++ b/internal/generated/sagemakeredge/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakeredge -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -31,126 +24,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakerfeaturestoreruntime/router.go b/internal/generated/sagemakerfeaturestoreruntime/router.go index 0f22bb5f..5a281d2d 100644 --- a/internal/generated/sagemakerfeaturestoreruntime/router.go +++ b/internal/generated/sagemakerfeaturestoreruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakerfeaturestoreruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -35,126 +28,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakergeospatial/router.go b/internal/generated/sagemakergeospatial/router.go index 42e9020b..7d6217b6 100644 --- a/internal/generated/sagemakergeospatial/router.go +++ b/internal/generated/sagemakergeospatial/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakergeospatial -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -47,126 +40,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakerjobruntime/router.go b/internal/generated/sagemakerjobruntime/router.go index 765cdd95..84696097 100644 --- a/internal/generated/sagemakerjobruntime/router.go +++ b/internal/generated/sagemakerjobruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakerjobruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -32,126 +25,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakermetrics/router.go b/internal/generated/sagemakermetrics/router.go index 058b74aa..d808a3cf 100644 --- a/internal/generated/sagemakermetrics/router.go +++ b/internal/generated/sagemakermetrics/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakermetrics -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -30,126 +23,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakerruntime/router.go b/internal/generated/sagemakerruntime/router.go index 0146e830..6ab4a088 100644 --- a/internal/generated/sagemakerruntime/router.go +++ b/internal/generated/sagemakerruntime/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakerruntime -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -31,126 +24,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sagemakerruntimehttp2/router.go b/internal/generated/sagemakerruntimehttp2/router.go index f0a1667f..e159fe0d 100644 --- a/internal/generated/sagemakerruntimehttp2/router.go +++ b/internal/generated/sagemakerruntimehttp2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sagemakerruntimehttp2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -29,126 +22,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/secretsmanager/router.go b/internal/generated/secretsmanager/router.go index 6a21c720..9cdd29e9 100644 --- a/internal/generated/secretsmanager/router.go +++ b/internal/generated/secretsmanager/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package secretsmanager -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/servicediscovery/router.go b/internal/generated/servicediscovery/router.go index 55c3b9e9..ca224168 100644 --- a/internal/generated/servicediscovery/router.go +++ b/internal/generated/servicediscovery/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package servicediscovery -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -58,126 +51,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ses/router.go b/internal/generated/ses/router.go index 995d9536..3cd96566 100644 --- a/internal/generated/ses/router.go +++ b/internal/generated/ses/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ses -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -99,126 +92,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sesv2/router.go b/internal/generated/sesv2/router.go index a9de8d0c..d9523d50 100644 --- a/internal/generated/sesv2/router.go +++ b/internal/generated/sesv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sesv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -138,126 +131,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sfn/router.go b/internal/generated/sfn/router.go index afcdc077..d45a57b9 100644 --- a/internal/generated/sfn/router.go +++ b/internal/generated/sfn/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sfn -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -65,126 +58,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/shield/router.go b/internal/generated/shield/router.go index 016db791..e1d42748 100644 --- a/internal/generated/shield/router.go +++ b/internal/generated/shield/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package shield -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -64,126 +57,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sns/router.go b/internal/generated/sns/router.go index 538ff78f..996aecb9 100644 --- a/internal/generated/sns/router.go +++ b/internal/generated/sns/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sns -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -70,126 +63,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/sqs/router.go b/internal/generated/sqs/router.go index 10845b17..a3ad87fd 100644 --- a/internal/generated/sqs/router.go +++ b/internal/generated/sqs/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package sqs -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -51,126 +44,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ssm/router.go b/internal/generated/ssm/router.go index 95fdcaf9..d3a3c3c0 100644 --- a/internal/generated/ssm/router.go +++ b/internal/generated/ssm/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ssm -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -174,126 +167,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/ssoadmin/router.go b/internal/generated/ssoadmin/router.go index 06534fff..c17178b9 100644 --- a/internal/generated/ssoadmin/router.go +++ b/internal/generated/ssoadmin/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package ssoadmin -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -107,126 +100,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/support/router.go b/internal/generated/support/router.go index 798fd37e..67d552cd 100644 --- a/internal/generated/support/router.go +++ b/internal/generated/support/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package support -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -44,126 +37,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/swf/router.go b/internal/generated/swf/router.go index e23e1cc6..3fd51b15 100644 --- a/internal/generated/swf/router.go +++ b/internal/generated/swf/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package swf -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -67,126 +60,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/textract/router.go b/internal/generated/textract/router.go index 4871026e..222023f5 100644 --- a/internal/generated/textract/router.go +++ b/internal/generated/textract/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package textract -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -53,126 +46,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/timestreamwrite/router.go b/internal/generated/timestreamwrite/router.go index 7f506eaa..00031e3a 100644 --- a/internal/generated/timestreamwrite/router.go +++ b/internal/generated/timestreamwrite/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package timestreamwrite -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -47,126 +40,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/transcribe/router.go b/internal/generated/transcribe/router.go index 8616414b..f13e4d22 100644 --- a/internal/generated/transcribe/router.go +++ b/internal/generated/transcribe/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package transcribe -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -71,126 +64,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/transcribestreaming/router.go b/internal/generated/transcribestreaming/router.go index de2f43d2..ccbe67c2 100644 --- a/internal/generated/transcribestreaming/router.go +++ b/internal/generated/transcribestreaming/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package transcribestreaming -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -33,126 +26,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/transfer/router.go b/internal/generated/transfer/router.go index 3b4c5b6e..d34e92d3 100644 --- a/internal/generated/transfer/router.go +++ b/internal/generated/transfer/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package transfer -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -99,126 +92,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/translate/router.go b/internal/generated/translate/router.go index ef8390f5..98b36c8c 100644 --- a/internal/generated/translate/router.go +++ b/internal/generated/translate/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package translate -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -47,126 +40,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/voiceid/router.go b/internal/generated/voiceid/router.go index 3e866e2d..2c8f9094 100644 --- a/internal/generated/voiceid/router.go +++ b/internal/generated/voiceid/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package voiceid -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -57,126 +50,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/waf/router.go b/internal/generated/waf/router.go index e5155e7a..ecd85f21 100644 --- a/internal/generated/waf/router.go +++ b/internal/generated/waf/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package waf -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -105,126 +98,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/wafv2/router.go b/internal/generated/wafv2/router.go index a6e98f05..aa2cb0e3 100644 --- a/internal/generated/wafv2/router.go +++ b/internal/generated/wafv2/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package wafv2 -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -83,126 +76,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/generated/xray/router.go b/internal/generated/xray/router.go index cf6425fa..a8bb195a 100644 --- a/internal/generated/xray/router.go +++ b/internal/generated/xray/router.go @@ -2,20 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 package xray -import ( - "net/url" - "strings" -) +import "github.com/skyoo2003/devcloud/internal/shared/httproute" // PathParams holds the URL path parameters extracted by the router. -type PathParams map[string]string +type PathParams = httproute.Params // OperationRoute maps an HTTP method and URI pattern to an operation name. -type OperationRoute struct { - Method string - Pattern string - Operation string -} +type OperationRoute = httproute.Route // OperationRoutes is the list of all routes for this service. var OperationRoutes = []OperationRoute{ @@ -66,126 +59,10 @@ var OperationRoutes = []OperationRoute{ // Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are // distinguished only by a query string (".../tagging?Operation=Tag"), and a // bare path can never satisfy those routes. +// +// The matching itself lives in internal/shared/httproute so the generic CRUD +// engine resolves a rest-json operation exactly the way this router does, +// rather than carrying a second copy of the algorithm. func MatchOperation(method, uri string) (string, PathParams) { - // Two passes. A route that constrains the query is more specific than one - // that does not, and OperationRoutes is ordered by operation name rather - // than specificity — so trying constrained routes first keeps - // ".../distribution" from shadowing ".../distribution?WithTags". - for _, constrained := range []bool{true, false} { - for _, route := range OperationRoutes { - if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { - continue - } - if params, ok := matchURI(route.Pattern, uri); ok { - return route.Operation, params - } - } - } - return "", nil -} - -// matchURI matches a request URI against a pattern that may contain {Label} and -// {Label+} (greedy) segments, and may constrain the query string after a "?". -// Returns the extracted parameters and true on match, or nil and false -// otherwise. -func matchURI(pattern, uri string) (PathParams, bool) { - patPath, patQuery, _ := strings.Cut(pattern, "?") - uriPath, uriQuery, _ := strings.Cut(uri, "?") - if !matchQuery(patQuery, uriQuery) { - return nil, false - } - - patParts := splitPath(patPath) - pathParts := splitPath(uriPath) - - params := PathParams{} - pi := 0 - for i, pat := range patParts { - if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { - // Greedy label: consumes all remaining path segments. - label := pat[1 : len(pat)-2] - if pi >= len(pathParts) { - return nil, false - } - params[label] = joinPath(pathParts[pi:]) - pi = len(pathParts) - // Greedy must be the last pattern segment. - if i != len(patParts)-1 { - return nil, false - } - } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { - // Single-segment label. - label := pat[1 : len(pat)-1] - if pi >= len(pathParts) { - return nil, false - } - params[label] = pathParts[pi] - pi++ - } else { - // Literal segment. - if pi >= len(pathParts) || pathParts[pi] != pat { - return nil, false - } - pi++ - } - } - if pi != len(pathParts) { - return nil, false - } - return params, true -} - -// matchQuery reports whether a request's query string satisfies the constraint -// a route pattern carries after its "?". Each "&"-separated term is either a -// bare key that must be present ("?WithTags") or a key=value that must be -// present with that value ("?Operation=Tag"). An empty constraint matches -// anything, which is every route that has no "?". -func matchQuery(constraint, query string) bool { - if constraint == "" { - return true - } - // ParseQuery returns what it could parse alongside any error, so a - // malformed tail cannot hide a valid term earlier in the string. - values, _ := url.ParseQuery(query) - for _, term := range strings.Split(constraint, "&") { - if term == "" { - continue - } - key, want, hasValue := strings.Cut(term, "=") - got, present := values[key] - if !present { - return false - } - if !hasValue { - continue - } - matched := false - for _, v := range got { - if v == want { - matched = true - break - } - } - if !matched { - return false - } - } - return true -} - -// splitPath splits a URI path into non-empty segments. -func splitPath(path string) []string { - parts := strings.Split(strings.Trim(path, "/"), "/") - out := parts[:0] - for _, p := range parts { - if p != "" { - out = append(out, p) - } - } - return out -} - -// joinPath joins path segments back with "/" separators. -func joinPath(parts []string) string { - return strings.Join(parts, "/") + return httproute.Match(OperationRoutes, method, uri) } diff --git a/internal/shared/httproute/match.go b/internal/shared/httproute/match.go new file mode 100644 index 00000000..6eab1094 --- /dev/null +++ b/internal/shared/httproute/match.go @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package httproute matches an HTTP request against a service's REST route +// table — the (method, URI template) pairs a model declares for each operation. +// +// It exists because two callers need the same answer from the same data. The +// generated per-service routers have always had it; the generic CRUD engine +// needs it too, because a rest-json request carries its operation name in the +// method and path rather than in an X-Amz-Target header. Emitting the algorithm +// into 148 generated packages and writing it a 149th time for the engine is how +// the two would drift. +package httproute + +import ( + "net/url" + "strings" +) + +// Params holds the URL path parameters extracted from a matched route. +type Params map[string]string + +// Route maps an HTTP method and URI pattern to an operation name. +type Route struct { + Method string + Pattern string + Operation string +} + +// Match returns the operation name and extracted path parameters for the given +// HTTP method and request URI. It returns ("", nil) if no route matches. +// +// Pass req.URL.RequestURI(), not req.URL.Path: some AWS operations are +// distinguished only by a query string (".../tagging?Operation=Tag"), and a +// bare path can never satisfy those routes. +func Match(routes []Route, method, uri string) (string, Params) { + // Two passes. A route that constrains the query is more specific than one + // that does not, and route tables are ordered by operation name rather + // than specificity — so trying constrained routes first keeps + // ".../distribution" from shadowing ".../distribution?WithTags". + for _, constrained := range []bool{true, false} { + for _, route := range routes { + if route.Method != method || strings.Contains(route.Pattern, "?") != constrained { + continue + } + if params, ok := MatchURI(route.Pattern, uri); ok { + return route.Operation, params + } + } + } + return "", nil +} + +// MatchURI matches a request URI against a pattern that may contain {Label} and +// {Label+} (greedy) segments, and may constrain the query string after a "?". +// Returns the extracted parameters and true on match, or nil and false +// otherwise. +func MatchURI(pattern, uri string) (Params, bool) { + patPath, patQuery, _ := strings.Cut(pattern, "?") + uriPath, uriQuery, _ := strings.Cut(uri, "?") + if !matchQuery(patQuery, uriQuery) { + return nil, false + } + + patParts := splitPath(patPath) + pathParts := splitPath(uriPath) + + params := Params{} + pi := 0 + for i, pat := range patParts { + if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "+}") { + // Greedy label: consumes all remaining path segments. + label := pat[1 : len(pat)-2] + if pi >= len(pathParts) { + return nil, false + } + params[label] = strings.Join(pathParts[pi:], "/") + pi = len(pathParts) + // Greedy must be the last pattern segment. + if i != len(patParts)-1 { + return nil, false + } + } else if strings.HasPrefix(pat, "{") && strings.HasSuffix(pat, "}") { + // Single-segment label. + label := pat[1 : len(pat)-1] + if pi >= len(pathParts) { + return nil, false + } + params[label] = pathParts[pi] + pi++ + } else { + // Literal segment. + if pi >= len(pathParts) || pathParts[pi] != pat { + return nil, false + } + pi++ + } + } + if pi != len(pathParts) { + return nil, false + } + return params, true +} + +// matchQuery reports whether a request's query string satisfies the constraint +// a route pattern carries after its "?". Each "&"-separated term is either a +// bare key that must be present ("?WithTags") or a key=value that must be +// present with that value ("?Operation=Tag"). An empty constraint matches +// anything, which is every route that has no "?". +func matchQuery(constraint, query string) bool { + if constraint == "" { + return true + } + // ParseQuery returns what it could parse alongside any error, so a + // malformed tail cannot hide a valid term earlier in the string. + values, _ := url.ParseQuery(query) + for _, term := range strings.Split(constraint, "&") { + if term == "" { + continue + } + key, want, hasValue := strings.Cut(term, "=") + got, present := values[key] + if !present { + return false + } + if !hasValue { + continue + } + matched := false + for _, v := range got { + if v == want { + matched = true + break + } + } + if !matched { + return false + } + } + return true +} + +// splitPath splits a URI path into non-empty segments. +func splitPath(path string) []string { + parts := strings.Split(strings.Trim(path, "/"), "/") + out := parts[:0] + for _, p := range parts { + if p != "" { + out = append(out, p) + } + } + return out +} diff --git a/internal/shared/httproute/match_test.go b/internal/shared/httproute/match_test.go new file mode 100644 index 00000000..5a1d2d7d --- /dev/null +++ b/internal/shared/httproute/match_test.go @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: Apache-2.0 + +package httproute + +import "testing" + +func TestMatchURILabels(t *testing.T) { + tests := []struct { + name string + pattern string + uri string + want Params + ok bool + }{ + { + name: "literal path", + pattern: "/2020-05-31/distribution", + uri: "/2020-05-31/distribution", + want: Params{}, + ok: true, + }, + { + name: "single-segment label", + pattern: "/2020-05-31/distribution/{Id}", + uri: "/2020-05-31/distribution/E123", + want: Params{"Id": "E123"}, + ok: true, + }, + { + name: "two labels", + pattern: "/v1/{Bucket}/object/{Key}", + uri: "/v1/mybucket/object/mykey", + want: Params{"Bucket": "mybucket", "Key": "mykey"}, + ok: true, + }, + { + name: "greedy label consumes the remaining segments", + pattern: "/v1/objects/{Key+}", + uri: "/v1/objects/a/b/c.txt", + want: Params{"Key": "a/b/c.txt"}, + ok: true, + }, + { + name: "greedy label needs at least one segment", + pattern: "/v1/objects/{Key+}", + uri: "/v1/objects", + ok: false, + }, + { + name: "trailing slash is not an extra segment", + pattern: "/2020-05-31/distribution", + uri: "/2020-05-31/distribution/", + want: Params{}, + ok: true, + }, + { + name: "literal segment mismatch", + pattern: "/2020-05-31/distribution", + uri: "/2020-05-31/streaming-distribution", + ok: false, + }, + { + name: "request has too few segments", + pattern: "/2020-05-31/distribution/{Id}", + uri: "/2020-05-31/distribution", + ok: false, + }, + { + name: "request has too many segments", + pattern: "/2020-05-31/distribution/{Id}", + uri: "/2020-05-31/distribution/E123/config", + ok: false, + }, + { + name: "query string is ignored when the pattern does not constrain it", + pattern: "/2020-05-31/distribution", + uri: "/2020-05-31/distribution?Marker=abc&MaxItems=10", + want: Params{}, + ok: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got, ok := MatchURI(tc.pattern, tc.uri) + if ok != tc.ok { + t.Fatalf("MatchURI(%q, %q) ok = %v, want %v", tc.pattern, tc.uri, ok, tc.ok) + } + if !ok { + return + } + if len(got) != len(tc.want) { + t.Fatalf("params = %v, want %v", got, tc.want) + } + for k, v := range tc.want { + if got[k] != v { + t.Errorf("params[%q] = %q, want %q", k, got[k], v) + } + } + }) + } +} + +func TestMatchURIQueryConstraints(t *testing.T) { + tests := []struct { + name string + pattern string + uri string + ok bool + }{ + { + name: "bare key must be present", + pattern: "/2020-05-31/distribution?WithTags", + uri: "/2020-05-31/distribution?WithTags", + ok: true, + }, + { + name: "bare key absent does not match", + pattern: "/2020-05-31/distribution?WithTags", + uri: "/2020-05-31/distribution", + ok: false, + }, + { + name: "key=value must match the value", + pattern: "/2020-05-31/tagging?Operation=Tag", + uri: "/2020-05-31/tagging?Operation=Tag&Resource=arn", + ok: true, + }, + { + name: "key present with the wrong value does not match", + pattern: "/2020-05-31/tagging?Operation=Tag", + uri: "/2020-05-31/tagging?Operation=Untag", + ok: false, + }, + { + name: "every term of a multi-term constraint must hold", + pattern: "/v1/thing?a=1&b=2", + uri: "/v1/thing?a=1", + ok: false, + }, + { + name: "a malformed tail cannot hide a valid earlier term", + pattern: "/v1/thing?a=1", + uri: "/v1/thing?a=1&%zz", + ok: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if _, ok := MatchURI(tc.pattern, tc.uri); ok != tc.ok { + t.Errorf("MatchURI(%q, %q) ok = %v, want %v", tc.pattern, tc.uri, ok, tc.ok) + } + }) + } +} + +// TestMatchPrefersConstrainedRoutes locks the two-pass ordering the generated +// routers depend on. OperationRoutes is sorted by operation name, not by +// specificity, so an unconstrained "/distribution" route appears before +// "/distribution?WithTags" and would shadow it in a single pass. +func TestMatchPrefersConstrainedRoutes(t *testing.T) { + routes := []Route{ + // Deliberately in the order codegen emits: alphabetical by operation. + {Method: "POST", Pattern: "/2020-05-31/distribution", Operation: "CreateDistribution"}, + {Method: "POST", Pattern: "/2020-05-31/distribution?WithTags", Operation: "CreateDistributionWithTags"}, + } + + if op, _ := Match(routes, "POST", "/2020-05-31/distribution?WithTags"); op != "CreateDistributionWithTags" { + t.Errorf("constrained route lost to the unconstrained one: got %q", op) + } + if op, _ := Match(routes, "POST", "/2020-05-31/distribution"); op != "CreateDistribution" { + t.Errorf("unconstrained route did not match: got %q", op) + } +} + +func TestMatchMethodAndMiss(t *testing.T) { + routes := []Route{ + {Method: "GET", Pattern: "/2020-05-31/distribution/{Id}", Operation: "GetDistribution"}, + {Method: "DELETE", Pattern: "/2020-05-31/distribution/{Id}", Operation: "DeleteDistribution"}, + } + + op, params := Match(routes, "GET", "/2020-05-31/distribution/E123") + if op != "GetDistribution" { + t.Fatalf("op = %q, want GetDistribution", op) + } + if params["Id"] != "E123" { + t.Errorf("params[Id] = %q, want E123", params["Id"]) + } + + if op, _ := Match(routes, "PUT", "/2020-05-31/distribution/E123"); op != "" { + t.Errorf("method mismatch matched %q, want no match", op) + } + + // A miss must be an empty operation and nil params, never a zero-value + // route: the CRUD engine treats "" as unclassified, and a non-nil empty + // params map would read as a successful match with no labels. + op, params = Match(routes, "GET", "/some/other/path") + if op != "" || params != nil { + t.Errorf("miss returned (%q, %v), want (\"\", nil)", op, params) + } +} From a9b2f76f19fffd5b3af56ece659b5aff57d833c6 Mon Sep 17 00:00:00 2001 From: Sung-Kyu Yoo Date: Sat, 5 Sep 2026 19:00:28 +0900 Subject: [PATCH 2/2] feat: serve rest-json from the generic CRUD engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rest-json carries no X-Amz-Target header, so the engine had nothing to classify and 59 registered services served nothing. The operation was always recoverable: every rest-json operation is bound to a method and URI template in the model, and the generated per-service routers have matched on that pair since day one. The gateway just threw the answer away. crud.OpMeta now carries the REST binding, crud.Handle takes a Call and resolves the operation through internal/shared/httproute, and the gateway buffers rest-json bodies so a Create sees its parameters. rest-xml stays unbuffered: S3 bodies are large binary uploads and the engine refuses the protocol anyway. Fleet effect, before a single new service is added: services serving >=1 op 117 -> 145 registered-only 31 -> 3 auto-crud operations 1,415 -> 2,200 unimplemented 3,119 -> 2,334 The 3 that remain are not a protocol problem: forecastquery and the two SageMaker Runtime variants have no CRUD-shaped operation at all. RED (engine): go test ./internal/shared/crud/ — undefined: Call; unknown field Method/URI in struct literal of type OpMeta. FAIL [build]. RED (codegen): go test ./internal/codegen/ -run TestServiceCRUDData — crudOpData has no field or method Method/URI. FAIL [build]. RED (gateway): TestServiceRouter_RESTJSONBodyReachesEngine — "request body did not reach the engine": expected "g1", actual . The other two rest-json gateway cases already passed, which is what showed routing was live and only buffering was missing. GREEN: go test ./... all pass; make test-compat 790 passed, 2 skipped. Also: the fidelity manifest now publishes EngineWired per service. TestFidelityManifestCoversCRUDRegistry assumed registry membership implied the engine serves an operation; that broke honestly on apigatewayv2 and xray, whose hand-written providers never return ErrUnhandledOp and so are never routed to the engine. The manifest was right and the test was inferring — it now reads the fact instead. polly, qbusiness and codeguru-reviewer move to ENGINE_SERVED_SERVICES; personalize-runtime leaves REGISTERED_ONLY_SERVICES (GetRecommendations classifies as a Get) but has no parameterless read to smoke-test with, so the manifest is its record. --- changes/unreleased/Added-20260905-184000.yaml | 5 + cmd/devcloud/fidelity_test.go | 18 +- docs/coverage.md | 69 +- internal/codegen/gen_crud_meta.go | 33 +- internal/codegen/gen_crud_meta_test.go | 127 + internal/codegen/gen_fidelity.go | 8 + .../codegen/templates/crud_registry.go.tmpl | 2 +- .../templates/fidelity_manifest.go.tmpl | 12 +- internal/gateway/router.go | 18 +- internal/gateway/router_test.go | 126 + .../generated/crudregistry/registry_gen.go | 2633 ++++++++++++++++- internal/generated/fidelity/manifest_gen.go | 1894 ++++++------ internal/shared/crud/crud.go | 156 +- internal/shared/crud/crud_test.go | 193 +- tests/compatibility/test_service_smoke.py | 29 +- 15 files changed, 4241 insertions(+), 1082 deletions(-) create mode 100644 changes/unreleased/Added-20260905-184000.yaml create mode 100644 internal/codegen/gen_crud_meta_test.go diff --git a/changes/unreleased/Added-20260905-184000.yaml b/changes/unreleased/Added-20260905-184000.yaml new file mode 100644 index 00000000..f7fcd3a2 --- /dev/null +++ b/changes/unreleased/Added-20260905-184000.yaml @@ -0,0 +1,5 @@ +kind: Added +body: 'The generic CRUD engine now serves `rest-json` services. That protocol carries no `X-Amz-Target` header, so the operation is recovered from the request method and path using the route table the model already declares — the same matcher the generated per-service routers use, now shared in `internal/shared/httproute`. 28 already-registered services stopped being registered-only without any change to their providers: services serving at least one operation went 117 to 145, and `auto-crud` operations 1,415 to 2,200. A path the route table does not know still declines with a clean AWS error rather than a fabricated success' +time: 2026-09-05T18:40:00.000000+09:00 +custom: + Issue: "139" diff --git a/cmd/devcloud/fidelity_test.go b/cmd/devcloud/fidelity_test.go index 9a24e1f2..0e31ce04 100644 --- a/cmd/devcloud/fidelity_test.go +++ b/cmd/devcloud/fidelity_test.go @@ -103,6 +103,16 @@ func TestFidelityManifestCoversRegisteredServices(t *testing.T) { // lists. func TestFidelityManifestCoversCRUDRegistry(t *testing.T) { for _, id := range plugin.DefaultRegistry.RegisteredServices() { + // Registry membership is classifiability, not reachability. The CRUD + // registry is built from the model, so it also holds operations for + // services whose hand-written provider refuses unknown operations + // itself (apigatewayv2, xray) — the engine is never routed to for + // those, so "unimplemented" is the truth and this check would be + // asserting the opposite. TestFidelityManifestCoverage's `served == 0 + // && RegisteredOps > 0` guard is what catches wiring that goes missing. + if !fidelity.Services[id].EngineWired { + continue + } for op := range crud.RegisteredOps(id) { tier, ok := fidelity.Lookup(id, op) if !ok { @@ -129,7 +139,13 @@ func TestAutoCRUDIsServedOverJSON(t *testing.T) { if tier != fidelity.TierAutoCRUD { continue } - if _, err := crud.Handle(id, op, "json-1.1", []byte("{}")); err != nil { + // Asked through the JSON path regardless of the service's real + // protocol: what "auto-crud" claims is that the operation is + // registered and CRUD-classified, which is exactly what this + // exercises. Whether a rest-json request also resolves to it is + // route matching, covered in internal/shared/crud and the compat + // suite. + if _, err := crud.Handle(crud.Call{Service: id, Protocol: "json-1.1", Op: op, Body: []byte("{}")}); err != nil { t.Errorf("%s/%s: declared auto-crud but the engine refused it: %v", id, op, err) } } diff --git a/docs/coverage.md b/docs/coverage.md index 548091eb..009c4b5a 100644 --- a/docs/coverage.md +++ b/docs/coverage.md @@ -10,37 +10,58 @@ things: | Number | What it means | Today | |---|---|---| | **Registered** | The gateway routes the service. A call reaches DevCloud instead of falling through to real AWS. | **148** | -| **Serving ≥1 operation** | At least one operation returns a real, store-backed answer — hand-written or served by the generic CRUD engine. | **117** | -| **Registered-only** | Routed, but every operation declines with a clean AWS error. Nothing is served. | **31** | +| **Serving ≥1 operation** | At least one operation returns a real, store-backed answer — hand-written or served by the generic CRUD engine. | **145** | +| **Registered-only** | Routed, but every operation declines with a clean AWS error. Nothing is served. | **3** | Per operation, from the [fidelity manifest](fidelity-manifest.md): | Tier | Operations | |---|---| | `hand-verified` | 4,496 | -| `auto-crud` | 1,415 | -| `unimplemented` | 3,119 | +| `auto-crud` | 2,200 | +| `unimplemented` | 2,334 | | **total known** | **9,030** | ## Why a registered service can serve nothing -The generic CRUD engine classifies an operation by its name, and only the -`X-Amz-Target` JSON protocols put the operation name where the router can see it -(`internal/shared/crud/crud.go`, `JSONProtocol`). A `rest-json`, `query` or -`rest-xml` service is therefore unreachable by the engine and serves nothing -until somebody writes its provider by hand. +The generic CRUD engine has to know which operation a request is for, and it has +to recognise that operation as CRUD-shaped. Two things can stop it. + +**The protocol does not say which operation.** The `X-Amz-Target` JSON protocols +name the operation in a header. `rest-json` does not, but every one of its +operations is bound to an HTTP method and a URI template in the model, and +`internal/shared/httproute` matches a request back to the operation from that +pair — so the engine serves it too. `query` and `rest-xml` have neither a target +header nor a modelled path the engine can match, so they are unreachable by it +and serve nothing until somebody writes the provider by hand. + +**The operation is not CRUD-shaped.** `GetThing`, `ListThings`, `CreateThing` +and their siblings map onto a generic store. `ExecuteStatement`, `InvokeEndpoint` +and `QueryForecast` do not, and the engine refuses them rather than inventing an +answer. A service whose entire API is that shape serves nothing whatever its +protocol. Registered services by protocol: | Protocol | Services | Engine-servable | |---|---|---| -| `json-1.1` | 49 | yes | -| `json-1.0` | 11 | yes | -| `rest-json` | 59 | no | +| `json-1.1` | 49 | yes — operation from `X-Amz-Target` | +| `json-1.0` | 11 | yes — operation from `X-Amz-Target` | +| `rest-json` | 59 | yes — operation from method + path | | `query` | 14 | no | | `rest-xml` | 3 | no | | no in-tree model | 12 | n/a — hand-written providers | +The three services that are registered and serve nothing are all the second +case, not the first: `forecastquery` (`json-1.1`, only `QueryForecast` and +`QueryWhatIfForecast`) and the two SageMaker Runtime variants (`rest-json`, only +`InvokeEndpoint*`). + +A registered operation is not automatically a reachable one. The engine is +entered only when a provider returns `plugin.ErrUnhandledOp`, so a hand-written +provider that refuses unknown operations itself — `apigatewayv2`, `xray` — never +reaches it, and the manifest records that per service as `EngineWired`. + Registering a service the engine cannot serve is deliberate, not an oversight. The alternative is worse: an unregistered service is not routed, so the SDK call leaves the machine and bills a real AWS account. A registered-only service @@ -56,19 +77,17 @@ The first category taken to completion. All 48 upstream models are registered. | | Count | |---|---| | Registered | 48 | -| Engine-served or hand-written | 17 | -| Registered-only | 31 | -| Operations served across the category | 935 | - -Engine-served: `bedrock`, `bedrock-data-automation-runtime`, `comprehend`, -`comprehendmedical`, `forecast`, `frauddetector`, `healthlake`, `kendra`, -`kendra-ranking`, `lookoutequipment`, `personalize`, `rekognition`, `sagemaker`, -`textract`, `transcribe`, `translate`, `voice-id`. - -Of the 31 registered-only, 30 are `rest-json`. The exception is `forecastquery`, -which is `json-1.1` but whose entire API is `QueryForecast` and -`QueryWhatIfForecast` — neither is CRUD-shaped, so there is nothing for the -engine to serve generically. +| Engine-served or hand-written | 45 | +| Registered-only | 3 | + +When this category was completed, only 17 of its 48 members served anything: 30 +of the other 31 were `rest-json`, which the engine could not read at all. Teaching +it that protocol moved 28 of those 30 into coverage without touching a single one +of their providers. + +The three that remain are the ones no protocol change can help — `forecastquery` +and the two SageMaker Runtime variants, none of which has a CRUD-shaped +operation. See [Why a registered service can serve nothing](#why-a-registered-service-can-serve-nothing). ## What counts as a service diff --git a/internal/codegen/gen_crud_meta.go b/internal/codegen/gen_crud_meta.go index 478058d3..3cb06ccb 100644 --- a/internal/codegen/gen_crud_meta.go +++ b/internal/codegen/gen_crud_meta.go @@ -28,6 +28,12 @@ type crudOpData struct { Resource string ListKey string ItemKey string + // Method and URI are the operation's REST binding, empty for a protocol + // that has none. rest-json names its operation in the method and path + // rather than in a header, so this pair is what lets the engine get back + // from a request to an operation name. + Method string + URI string } // verbPrefixes maps operation-name prefixes to canonical CRUD verbs, longest and @@ -117,21 +123,34 @@ func classifyOps(model *ir.Model) []crudOpData { Resource: resource, ListKey: listKey, ItemKey: itemKey, + Method: op.HTTPMethod, + URI: op.HTTPUri, }) } return ops } -// isJSONProtocol reports whether the engine can serve a service's protocol. -// Only X-Amz-Target JSON protocols carry an operation name at the router. -func isJSONProtocol(protocol string) bool { - return strings.HasPrefix(protocol, "json") +// engineServable reports whether the engine can serve a service's protocol. +// +// The JSON protocols carry the operation name in X-Amz-Target. rest-json does +// not, but every one of its operations is bound to a method and URI template, +// and internal/shared/httproute turns that pair back into an operation name — +// so the engine can classify it too. query and rest-xml have neither, which is +// what PRD Milestone 5 owns; admitting them here would mean guessing. +// +// This is deliberately the same question crud.Servable answers at runtime. The +// two must agree: a protocol classified here but refused there registers +// operations nothing can reach, and the fidelity manifest would call them +// auto-crud. +func engineServable(protocol string) bool { + return strings.HasPrefix(protocol, "json") || protocol == "rest-json" } -// ServiceCRUDData classifies a JSON-protocol model's CRUD operations. It returns -// (data, false) when the service is not engine-servable or has no CRUD ops. +// ServiceCRUDData classifies an engine-servable model's CRUD operations. It +// returns (data, false) when the service's protocol cannot be served or the +// model has no CRUD-shaped operation at all. func ServiceCRUDData(model *ir.Model) (CRUDServiceData, bool) { - if !isJSONProtocol(model.Protocol) { + if !engineServable(model.Protocol) { return CRUDServiceData{}, false } ops := classifyOps(model) diff --git a/internal/codegen/gen_crud_meta_test.go b/internal/codegen/gen_crud_meta_test.go new file mode 100644 index 00000000..932b60df --- /dev/null +++ b/internal/codegen/gen_crud_meta_test.go @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: Apache-2.0 + +// internal/codegen/gen_crud_meta_test.go +package codegen + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/skyoo2003/devcloud/internal/codegen/ir" +) + +// crudModel builds a minimal model with one list-returning and one +// item-returning output shape, so classifyOps has both output keys to find. +func crudModel(protocol string, ops ...ir.Operation) *ir.Model { + return &ir.Model{ + ServiceID: "testsvc", + Protocol: protocol, + Operations: ops, + Shapes: map[string]*ir.Shape{ + "GraphList": {Name: "GraphList", Type: ir.ShapeList}, + "Graph": {Name: "Graph", Type: ir.ShapeStructure}, + "ListGraphsOutput": {Name: "ListGraphsOutput", Type: ir.ShapeStructure, Members: []ir.Member{ + {Name: "Graphs", TargetName: "GraphList"}, + }}, + "GetGraphOutput": {Name: "GetGraphOutput", Type: ir.ShapeStructure, Members: []ir.Member{ + {Name: "Graph", TargetName: "Graph"}, + }}, + }, + } +} + +func opsOf(data CRUDServiceData) map[string]crudOpData { + out := make(map[string]crudOpData, len(data.Ops)) + for _, op := range data.Ops { + out[op.Op] = op + } + return out +} + +// TestServiceCRUDDataAcceptsRESTJSON is the change that makes Milestone 4 +// possible: 33 of the 57 demand-set services are restJson1, and refusing the +// protocol here is what left them registered but serving nothing. +func TestServiceCRUDDataAcceptsRESTJSON(t *testing.T) { + model := crudModel("rest-json", + ir.Operation{Name: "ListGraphs", OutputName: "ListGraphsOutput", + HTTPMethod: "GET", HTTPUri: "/v1/graphs"}, + ir.Operation{Name: "GetGraph", OutputName: "GetGraphOutput", + HTTPMethod: "GET", HTTPUri: "/v1/graphs/{GraphName}"}, + ) + + data, ok := ServiceCRUDData(model) + require.True(t, ok, "rest-json service must be engine-servable") + + ops := opsOf(data) + require.Contains(t, ops, "ListGraphs") + require.Contains(t, ops, "GetGraph") + + // Without the REST binding the engine has no way back from a request to an + // operation name, so carrying it is the whole point. + assert.Equal(t, "GET", ops["ListGraphs"].Method) + assert.Equal(t, "/v1/graphs", ops["ListGraphs"].URI) + assert.Equal(t, "/v1/graphs/{GraphName}", ops["GetGraph"].URI) + + // Classification itself is unchanged: the verb still comes from the name. + assert.Equal(t, "List", ops["ListGraphs"].Verb) + assert.Equal(t, "Graphs", ops["ListGraphs"].ListKey) + assert.Equal(t, "Get", ops["GetGraph"].Verb) + assert.Equal(t, "Graph", ops["GetGraph"].ItemKey) +} + +// TestServiceCRUDDataJSONUnchanged pins that admitting rest-json did not alter +// what the JSON protocols produce. A JSON model has no HTTP binding, and +// emitting an empty URI must not create a route that matches everything. +func TestServiceCRUDDataJSONUnchanged(t *testing.T) { + for _, protocol := range []string{"json-1.0", "json-1.1"} { + t.Run(protocol, func(t *testing.T) { + model := crudModel(protocol, + ir.Operation{Name: "ListGraphs", OutputName: "ListGraphsOutput"}, + ) + + data, ok := ServiceCRUDData(model) + require.True(t, ok) + + ops := opsOf(data) + assert.Equal(t, "List", ops["ListGraphs"].Verb) + assert.Empty(t, ops["ListGraphs"].Method) + assert.Empty(t, ops["ListGraphs"].URI) + }) + } +} + +// TestServiceCRUDDataRejectsUnservableProtocols holds the boundary Milestone 5 +// owns. query and rest-xml put the operation neither in a header nor in a +// modelled path the engine can match, so admitting them would serve fabricated +// answers to callers the engine cannot actually understand. +func TestServiceCRUDDataRejectsUnservableProtocols(t *testing.T) { + for _, protocol := range []string{"query", "rest-xml"} { + t.Run(protocol, func(t *testing.T) { + model := crudModel(protocol, + ir.Operation{Name: "ListGraphs", OutputName: "ListGraphsOutput", + HTTPMethod: "GET", HTTPUri: "/v1/graphs"}, + ) + + _, ok := ServiceCRUDData(model) + assert.False(t, ok, "%s must not be engine-servable", protocol) + }) + } +} + +// TestServiceCRUDDataSkipsUnclassifiableService is the rds-data case: a +// rest-json service whose entire API is ExecuteStatement-shaped classifies +// nothing, so it registers nothing and routes nothing, and every call to it +// gets a clean error instead of an invented success. +func TestServiceCRUDDataSkipsUnclassifiableService(t *testing.T) { + model := crudModel("rest-json", + ir.Operation{Name: "ExecuteStatement", OutputName: "GetGraphOutput", + HTTPMethod: "POST", HTTPUri: "/Execute"}, + ir.Operation{Name: "BeginTransaction", OutputName: "GetGraphOutput", + HTTPMethod: "POST", HTTPUri: "/BeginTransaction"}, + ) + + _, ok := ServiceCRUDData(model) + assert.False(t, ok, "a service with no CRUD-shaped operation must register nothing") +} diff --git a/internal/codegen/gen_fidelity.go b/internal/codegen/gen_fidelity.go index 6400956d..9326e610 100644 --- a/internal/codegen/gen_fidelity.go +++ b/internal/codegen/gen_fidelity.go @@ -24,6 +24,13 @@ type FidelityServiceData struct { // only this field lets a reader tell them apart. Protocol string ModelBacked bool + // EngineWired mirrors ProviderScan.EngineWired: does this provider hand + // unimplemented operations to the CRUD engine? Published because the CRUD + // registry is model-derived and so holds operations for providers the + // engine is never reached from; without this, "registered in the engine" + // reads as "served", which is the overstatement the manifest exists to + // prevent. + EngineWired bool Ops []FidelityOpData } @@ -109,6 +116,7 @@ func BuildFidelityData( ServiceID: serviceID, Protocol: protocols[serviceID], ModelBacked: len(modelOps[serviceID]) > 0, + EngineWired: provider.EngineWired, Ops: ops, }) } diff --git a/internal/codegen/templates/crud_registry.go.tmpl b/internal/codegen/templates/crud_registry.go.tmpl index 4f96ae67..b1578714 100644 --- a/internal/codegen/templates/crud_registry.go.tmpl +++ b/internal/codegen/templates/crud_registry.go.tmpl @@ -12,7 +12,7 @@ func init() { {{- range .Services }} crud.Register("{{ .ServiceID }}", map[string]crud.OpMeta{ {{- range .Ops }} - "{{ .Op }}": {Verb: "{{ .Verb }}", Resource: "{{ .Resource }}", OutputListKey: "{{ .ListKey }}", OutputItemKey: "{{ .ItemKey }}"}, + "{{ .Op }}": {Verb: "{{ .Verb }}", Resource: "{{ .Resource }}", OutputListKey: "{{ .ListKey }}", OutputItemKey: "{{ .ItemKey }}"{{ if .URI }}, Method: "{{ .Method }}", URI: "{{ .URI }}"{{ end }}}, {{- end }} }) {{- end }} diff --git a/internal/codegen/templates/fidelity_manifest.go.tmpl b/internal/codegen/templates/fidelity_manifest.go.tmpl index ea84c92d..4138008d 100644 --- a/internal/codegen/templates/fidelity_manifest.go.tmpl +++ b/internal/codegen/templates/fidelity_manifest.go.tmpl @@ -46,13 +46,23 @@ type Service struct { // service's API. When false the unimplemented tail is not knowable, so the // manifest lists only what DevCloud serves. ModelBacked bool + // EngineWired reports whether the provider hands the operations it does not + // implement to the generic CRUD engine, by returning plugin.ErrUnhandledOp. + // + // It is the difference between an operation being *classifiable* and being + // *reachable*. The CRUD registry is built from the model, so it holds + // entries for services whose hand-written provider refuses unknown + // operations itself and never routes to the engine — for those, a + // registered operation is genuinely unimplemented, and only this field says + // so without guessing. + EngineWired bool Operations map[string]Tier } // Services maps a registered service ID to its operations. var Services = map[string]Service{ {{- range .Services }} - "{{ .ServiceID }}": {Protocol: "{{ .Protocol }}", ModelBacked: {{ .ModelBacked }}, Operations: map[string]Tier{ + "{{ .ServiceID }}": {Protocol: "{{ .Protocol }}", ModelBacked: {{ .ModelBacked }}, EngineWired: {{ .EngineWired }}, Operations: map[string]Tier{ {{- range .Ops }} "{{ .Name }}": Tier{{ .TierConst }}, {{- end }} diff --git a/internal/gateway/router.go b/internal/gateway/router.go index 78a49f3f..dc3a18e9 100644 --- a/internal/gateway/router.go +++ b/internal/gateway/router.go @@ -54,11 +54,12 @@ func (sr *ServiceRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) { op := extractOperationName(r, protocol) - // Buffer the body for JSON protocols so the CRUD fallback engine can re-read - // it if the provider does not handle the operation. Cheap for JSON payloads; - // skipped for REST-XML (S3) where bodies may be large binary uploads. + // Buffer the body for the protocols the CRUD fallback engine can serve, so + // it can re-read it if the provider does not handle the operation. Cheap for + // JSON and rest-json payloads; skipped for REST-XML (S3), where bodies may + // be large binary uploads and the engine would refuse them anyway. var body []byte - if crud.JSONProtocol(protocol) { + if crud.Servable(protocol) { var rerr error if body, rerr = io.ReadAll(r.Body); rerr != nil { writeAWSError(w, protocol, http.StatusBadRequest, "SerializationException", "failed to read request body") @@ -73,7 +74,14 @@ func (sr *ServiceRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) { // fallback for operations it does not implement. If the engine cannot // classify the operation either, emit the standard "unknown action" error. if errors.Is(err, plugin.ErrUnhandledOp) { - res, cerr := crud.Handle(serviceID, op, protocol, body) + res, cerr := crud.Handle(crud.Call{ + Service: serviceID, + Protocol: protocol, + Op: op, + Method: r.Method, + URI: r.URL.RequestURI(), + Body: body, + }) if cerr != nil { writeAWSError(w, protocol, http.StatusBadRequest, "InvalidAction", "unknown action: "+op) return diff --git a/internal/gateway/router_test.go b/internal/gateway/router_test.go index 022e1115..50e939f0 100644 --- a/internal/gateway/router_test.go +++ b/internal/gateway/router_test.go @@ -4,12 +4,16 @@ package gateway import ( "context" + "encoding/json" + "io" "net/http" "net/http/httptest" + "strings" "testing" "github.com/skyoo2003/devcloud/internal/admin" "github.com/skyoo2003/devcloud/internal/plugin" + "github.com/skyoo2003/devcloud/internal/shared/crud" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -128,3 +132,125 @@ func TestServiceRouter_NilUnroutedCollector(t *testing.T) { assert.NotPanics(t, func() { router.ServeHTTP(w, unroutedJSONRequest("amp")) }) assert.Equal(t, http.StatusBadRequest, w.Code) } + +// --- rest-json reaching the CRUD engine --- + +// decliningPlugin implements nothing and says so, which is what every +// scaffolded service does and what hands the request to the engine. +type decliningPlugin struct { + serviceID string + protocol plugin.ProtocolType +} + +func (d *decliningPlugin) ServiceID() string { return d.serviceID } +func (d *decliningPlugin) ServiceName() string { return d.serviceID } +func (d *decliningPlugin) Protocol() plugin.ProtocolType { return d.protocol } +func (d *decliningPlugin) Init(_ plugin.PluginConfig) error { return nil } +func (d *decliningPlugin) Shutdown(_ context.Context) error { return nil } +func (d *decliningPlugin) HandleRequest(_ context.Context, _ string, _ *http.Request) (*plugin.Response, error) { + return nil, plugin.ErrUnhandledOp +} +func (d *decliningPlugin) ListResources(_ context.Context) ([]plugin.Resource, error) { + return nil, nil +} + +func newDecliningRegistry(serviceID string, protocol plugin.ProtocolType) *plugin.Registry { + reg := plugin.NewRegistry() + p := &decliningPlugin{serviceID: serviceID, protocol: protocol} + reg.Register(serviceID, func() plugin.ServicePlugin { return p }) + _, _ = reg.Init(serviceID, plugin.PluginConfig{}) + return reg +} + +// restJSONRequest builds a SigV4-signed REST call, which is how DetectProtocol +// recognises a rest-json service (step 3, protocol.go). +func restJSONRequest(service, method, uri, body string) *http.Request { + var req *http.Request + if body == "" { + req = httptest.NewRequest(method, uri, nil) + } else { + req = httptest.NewRequest(method, uri, strings.NewReader(body)) + } + req.Header.Set("Authorization", + "AWS4-HMAC-SHA256 Credential=AKIA/20130524/us-east-1/"+service+"/aws4_request, Signature=abc") + return req +} + +// TestServiceRouter_RESTJSONBodyReachesEngine is the gateway half of the +// rest-json change. The engine can classify the operation from the path, but a +// Create takes its parameters from the body — and the body was only buffered +// for the JSON protocols, so it arrived empty and every created resource came +// back with a generated id instead of the caller's name. +func TestServiceRouter_RESTJSONBodyReachesEngine(t *testing.T) { + const svc = "gwrestsvc" + crud.Register(svc, map[string]crud.OpMeta{ + "CreateGadget": {Verb: "Create", Resource: "Gadget", OutputItemKey: "Gadget", + Method: "POST", URI: "/v1/gadgets"}, + }) + router := NewServiceRouter(newDecliningRegistry(svc, plugin.ProtocolRESTJSON), nil) + + w := httptest.NewRecorder() + router.ServeHTTP(w, restJSONRequest(svc, http.MethodPost, "/v1/gadgets", `{"GadgetName":"g1","Colour":"red"}`)) + + require.Equal(t, http.StatusOK, w.Code, "body: %s", w.Body.String()) + var out map[string]any + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &out)) + gadget, ok := out["Gadget"].(map[string]any) + require.True(t, ok, "no Gadget in %v", out) + assert.Equal(t, "g1", gadget["GadgetName"], "request body did not reach the engine") + assert.Equal(t, "red", gadget["Colour"]) +} + +// TestServiceRouter_RESTJSONUnmatchedPathDeclinesCleanly is the guarantee the +// coverage claim rests on: a registered service that cannot serve a request +// must answer with an AWS error, never a fabricated success. +func TestServiceRouter_RESTJSONUnmatchedPathDeclinesCleanly(t *testing.T) { + const svc = "gwmisssvc" + crud.Register(svc, map[string]crud.OpMeta{ + "ListGadgets": {Verb: "List", Resource: "MGadget", OutputListKey: "Gadgets", + Method: "GET", URI: "/v1/gadgets"}, + }) + router := NewServiceRouter(newDecliningRegistry(svc, plugin.ProtocolRESTJSON), nil) + + w := httptest.NewRecorder() + router.ServeHTTP(w, restJSONRequest(svc, http.MethodPost, "/v1/nothing/here", `{}`)) + + assert.Equal(t, http.StatusBadRequest, w.Code) + assert.Contains(t, w.Body.String(), "InvalidAction") +} + +// TestServiceRouter_RESTXMLBodyStillUnbuffered pins the exception. S3 bodies are +// large binary uploads, and reading one into memory to offer it to an engine +// that refuses rest-xml anyway would be a straight regression. +func TestServiceRouter_RESTXMLBodyStillUnbuffered(t *testing.T) { + var seen []byte + reg := plugin.NewRegistry() + p := &bodyCapturingPlugin{serviceID: "s3", seen: &seen} + reg.Register("s3", func() plugin.ServicePlugin { return p }) + _, _ = reg.Init("s3", plugin.PluginConfig{}) + router := NewServiceRouter(reg, nil) + + req := httptest.NewRequest(http.MethodPut, "/bucket/key", strings.NewReader("binary-payload")) + router.ServeHTTP(httptest.NewRecorder(), req) + + // The provider still reads the stream itself; the gateway did not consume it. + assert.Equal(t, "binary-payload", string(seen)) +} + +type bodyCapturingPlugin struct { + serviceID string + seen *[]byte +} + +func (b *bodyCapturingPlugin) ServiceID() string { return b.serviceID } +func (b *bodyCapturingPlugin) ServiceName() string { return b.serviceID } +func (b *bodyCapturingPlugin) Protocol() plugin.ProtocolType { return plugin.ProtocolRESTXML } +func (b *bodyCapturingPlugin) Init(_ plugin.PluginConfig) error { return nil } +func (b *bodyCapturingPlugin) Shutdown(_ context.Context) error { return nil } +func (b *bodyCapturingPlugin) HandleRequest(_ context.Context, _ string, req *http.Request) (*plugin.Response, error) { + *b.seen, _ = io.ReadAll(req.Body) + return &plugin.Response{StatusCode: http.StatusOK, Body: []byte("")}, nil +} +func (b *bodyCapturingPlugin) ListResources(_ context.Context) ([]plugin.Resource, error) { + return nil, nil +} diff --git a/internal/generated/crudregistry/registry_gen.go b/internal/generated/crudregistry/registry_gen.go index 3de79e91..645f2f47 100644 --- a/internal/generated/crudregistry/registry_gen.go +++ b/internal/generated/crudregistry/registry_gen.go @@ -40,6 +40,183 @@ func init() { "UntagCertificateAuthority": {Verb: "Untag", Resource: "CertificateAuthority", OutputListKey: "", OutputItemKey: ""}, "UpdateCertificateAuthority": {Verb: "Update", Resource: "CertificateAuthority", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("amplify", map[string]crud.OpMeta{ + "CreateApp": {Verb: "Create", Resource: "App", OutputListKey: "", OutputItemKey: "app", Method: "POST", URI: "/apps"}, + "CreateBackendEnvironment": {Verb: "Create", Resource: "BackendEnvironment", OutputListKey: "", OutputItemKey: "backendEnvironment", Method: "POST", URI: "/apps/{appId}/backendenvironments"}, + "CreateBranch": {Verb: "Create", Resource: "Branch", OutputListKey: "", OutputItemKey: "branch", Method: "POST", URI: "/apps/{appId}/branches"}, + "CreateDeployment": {Verb: "Create", Resource: "Deployment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/apps/{appId}/branches/{branchName}/deployments"}, + "CreateDomainAssociation": {Verb: "Create", Resource: "DomainAssociation", OutputListKey: "", OutputItemKey: "domainAssociation", Method: "POST", URI: "/apps/{appId}/domains"}, + "CreateWebhook": {Verb: "Create", Resource: "Webhook", OutputListKey: "", OutputItemKey: "webhook", Method: "POST", URI: "/apps/{appId}/webhooks"}, + "DeleteApp": {Verb: "Delete", Resource: "App", OutputListKey: "", OutputItemKey: "app", Method: "DELETE", URI: "/apps/{appId}"}, + "DeleteBackendEnvironment": {Verb: "Delete", Resource: "BackendEnvironment", OutputListKey: "", OutputItemKey: "backendEnvironment", Method: "DELETE", URI: "/apps/{appId}/backendenvironments/{environmentName}"}, + "DeleteBranch": {Verb: "Delete", Resource: "Branch", OutputListKey: "", OutputItemKey: "branch", Method: "DELETE", URI: "/apps/{appId}/branches/{branchName}"}, + "DeleteDomainAssociation": {Verb: "Delete", Resource: "DomainAssociation", OutputListKey: "", OutputItemKey: "domainAssociation", Method: "DELETE", URI: "/apps/{appId}/domains/{domainName}"}, + "DeleteJob": {Verb: "Delete", Resource: "Job", OutputListKey: "", OutputItemKey: "jobSummary", Method: "DELETE", URI: "/apps/{appId}/branches/{branchName}/jobs/{jobId}"}, + "DeleteWebhook": {Verb: "Delete", Resource: "Webhook", OutputListKey: "", OutputItemKey: "webhook", Method: "DELETE", URI: "/webhooks/{webhookId}"}, + "GetApp": {Verb: "Get", Resource: "App", OutputListKey: "", OutputItemKey: "app", Method: "GET", URI: "/apps/{appId}"}, + "GetArtifactUrl": {Verb: "Get", Resource: "ArtifactUrl", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/artifacts/{artifactId}"}, + "GetBackendEnvironment": {Verb: "Get", Resource: "BackendEnvironment", OutputListKey: "", OutputItemKey: "backendEnvironment", Method: "GET", URI: "/apps/{appId}/backendenvironments/{environmentName}"}, + "GetBranch": {Verb: "Get", Resource: "Branch", OutputListKey: "", OutputItemKey: "branch", Method: "GET", URI: "/apps/{appId}/branches/{branchName}"}, + "GetDomainAssociation": {Verb: "Get", Resource: "DomainAssociation", OutputListKey: "", OutputItemKey: "domainAssociation", Method: "GET", URI: "/apps/{appId}/domains/{domainName}"}, + "GetJob": {Verb: "Get", Resource: "Job", OutputListKey: "", OutputItemKey: "job", Method: "GET", URI: "/apps/{appId}/branches/{branchName}/jobs/{jobId}"}, + "GetWebhook": {Verb: "Get", Resource: "Webhook", OutputListKey: "", OutputItemKey: "webhook", Method: "GET", URI: "/webhooks/{webhookId}"}, + "ListApps": {Verb: "List", Resource: "App", OutputListKey: "apps", OutputItemKey: "", Method: "GET", URI: "/apps"}, + "ListArtifacts": {Verb: "List", Resource: "Artifact", OutputListKey: "artifacts", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/branches/{branchName}/jobs/{jobId}/artifacts"}, + "ListBackendEnvironments": {Verb: "List", Resource: "BackendEnvironment", OutputListKey: "backendEnvironments", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/backendenvironments"}, + "ListBranches": {Verb: "List", Resource: "Branche", OutputListKey: "branches", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/branches"}, + "ListDomainAssociations": {Verb: "List", Resource: "DomainAssociation", OutputListKey: "domainAssociations", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/domains"}, + "ListJobs": {Verb: "List", Resource: "Job", OutputListKey: "jobSummaries", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/branches/{branchName}/jobs"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "ListWebhooks": {Verb: "List", Resource: "Webhook", OutputListKey: "webhooks", OutputItemKey: "", Method: "GET", URI: "/apps/{appId}/webhooks"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateApp": {Verb: "Update", Resource: "App", OutputListKey: "", OutputItemKey: "app", Method: "POST", URI: "/apps/{appId}"}, + "UpdateBranch": {Verb: "Update", Resource: "Branch", OutputListKey: "", OutputItemKey: "branch", Method: "POST", URI: "/apps/{appId}/branches/{branchName}"}, + "UpdateDomainAssociation": {Verb: "Update", Resource: "DomainAssociation", OutputListKey: "", OutputItemKey: "domainAssociation", Method: "POST", URI: "/apps/{appId}/domains/{domainName}"}, + "UpdateWebhook": {Verb: "Update", Resource: "Webhook", OutputListKey: "", OutputItemKey: "webhook", Method: "POST", URI: "/webhooks/{webhookId}"}, + }) + crud.Register("apigatewayv2", map[string]crud.OpMeta{ + "CreateApi": {Verb: "Create", Resource: "Api", OutputListKey: "ImportInfo", OutputItemKey: "CorsConfiguration", Method: "POST", URI: "/v2/apis"}, + "CreateApiMapping": {Verb: "Create", Resource: "ApiMapping", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/domainnames/{DomainName}/apimappings"}, + "CreateAuthorizer": {Verb: "Create", Resource: "Authorizer", OutputListKey: "IdentitySource", OutputItemKey: "JwtConfiguration", Method: "POST", URI: "/v2/apis/{ApiId}/authorizers"}, + "CreateDeployment": {Verb: "Create", Resource: "Deployment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/apis/{ApiId}/deployments"}, + "CreateDomainName": {Verb: "Create", Resource: "DomainName", OutputListKey: "DomainNameConfigurations", OutputItemKey: "MutualTlsAuthentication", Method: "POST", URI: "/v2/domainnames"}, + "CreateIntegration": {Verb: "Create", Resource: "Integration", OutputListKey: "", OutputItemKey: "TlsConfig", Method: "POST", URI: "/v2/apis/{ApiId}/integrations"}, + "CreateIntegrationResponse": {Verb: "Create", Resource: "IntegrationResponse", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}/integrationresponses"}, + "CreateModel": {Verb: "Create", Resource: "Model", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/apis/{ApiId}/models"}, + "CreatePortal": {Verb: "Create", Resource: "Portal", OutputListKey: "IncludedPortalProductArns", OutputItemKey: "Authorization", Method: "POST", URI: "/v2/portals"}, + "CreatePortalProduct": {Verb: "Create", Resource: "PortalProduct", OutputListKey: "", OutputItemKey: "DisplayOrder", Method: "POST", URI: "/v2/portalproducts"}, + "CreateProductPage": {Verb: "Create", Resource: "ProductPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "POST", URI: "/v2/portalproducts/{PortalProductId}/productpages"}, + "CreateProductRestEndpointPage": {Verb: "Create", Resource: "ProductRestEndpointPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "POST", URI: "/v2/portalproducts/{PortalProductId}/productrestendpointpages"}, + "CreateRoute": {Verb: "Create", Resource: "Route", OutputListKey: "AuthorizationScopes", OutputItemKey: "", Method: "POST", URI: "/v2/apis/{ApiId}/routes"}, + "CreateRouteResponse": {Verb: "Create", Resource: "RouteResponse", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/apis/{ApiId}/routes/{RouteId}/routeresponses"}, + "CreateRoutingRule": {Verb: "Create", Resource: "RoutingRule", OutputListKey: "Actions", OutputItemKey: "", Method: "POST", URI: "/v2/domainnames/{DomainName}/routingrules"}, + "CreateStage": {Verb: "Create", Resource: "Stage", OutputListKey: "", OutputItemKey: "AccessLogSettings", Method: "POST", URI: "/v2/apis/{ApiId}/stages"}, + "CreateVpcLink": {Verb: "Create", Resource: "VpcLink", OutputListKey: "SecurityGroupIds", OutputItemKey: "", Method: "POST", URI: "/v2/vpclinks"}, + "DeleteAccessLogSettings": {Verb: "Delete", Resource: "AccessLogSetting", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/stages/{StageName}/accesslogsettings"}, + "DeleteApi": {Verb: "Delete", Resource: "Api", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}"}, + "DeleteApiMapping": {Verb: "Delete", Resource: "ApiMapping", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/domainnames/{DomainName}/apimappings/{ApiMappingId}"}, + "DeleteAuthorizer": {Verb: "Delete", Resource: "Authorizer", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/authorizers/{AuthorizerId}"}, + "DeleteCorsConfiguration": {Verb: "Delete", Resource: "CorsConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/cors"}, + "DeleteDeployment": {Verb: "Delete", Resource: "Deployment", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/deployments/{DeploymentId}"}, + "DeleteDomainName": {Verb: "Delete", Resource: "DomainName", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/domainnames/{DomainName}"}, + "DeleteIntegration": {Verb: "Delete", Resource: "Integration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}"}, + "DeleteIntegrationResponse": {Verb: "Delete", Resource: "IntegrationResponse", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}/integrationresponses/{IntegrationResponseId}"}, + "DeleteModel": {Verb: "Delete", Resource: "Model", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/models/{ModelId}"}, + "DeletePortal": {Verb: "Delete", Resource: "Portal", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/portals/{PortalId}"}, + "DeletePortalProduct": {Verb: "Delete", Resource: "PortalProduct", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/portalproducts/{PortalProductId}"}, + "DeletePortalProductSharingPolicy": {Verb: "Delete", Resource: "PortalProductSharingPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/portalproducts/{PortalProductId}/sharingpolicy"}, + "DeleteProductPage": {Verb: "Delete", Resource: "ProductPage", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/portalproducts/{PortalProductId}/productpages/{ProductPageId}"}, + "DeleteProductRestEndpointPage": {Verb: "Delete", Resource: "ProductRestEndpointPage", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/portalproducts/{PortalProductId}/productrestendpointpages/{ProductRestEndpointPageId}"}, + "DeleteRoute": {Verb: "Delete", Resource: "Route", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/routes/{RouteId}"}, + "DeleteRouteRequestParameter": {Verb: "Delete", Resource: "RouteRequestParameter", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/routes/{RouteId}/requestparameters/{RequestParameterKey}"}, + "DeleteRouteResponse": {Verb: "Delete", Resource: "RouteResponse", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/routes/{RouteId}/routeresponses/{RouteResponseId}"}, + "DeleteRouteSettings": {Verb: "Delete", Resource: "RouteSetting", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/stages/{StageName}/routesettings/{RouteKey}"}, + "DeleteRoutingRule": {Verb: "Delete", Resource: "RoutingRule", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/domainnames/{DomainName}/routingrules/{RoutingRuleId}"}, + "DeleteStage": {Verb: "Delete", Resource: "Stage", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{ApiId}/stages/{StageName}"}, + "DeleteVpcLink": {Verb: "Delete", Resource: "VpcLink", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/vpclinks/{VpcLinkId}"}, + "GetApi": {Verb: "Get", Resource: "Api", OutputListKey: "ImportInfo", OutputItemKey: "CorsConfiguration", Method: "GET", URI: "/v2/apis/{ApiId}"}, + "GetApiMapping": {Verb: "Get", Resource: "ApiMapping", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/domainnames/{DomainName}/apimappings/{ApiMappingId}"}, + "GetApiMappings": {Verb: "Get", Resource: "ApiMapping", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/domainnames/{DomainName}/apimappings"}, + "GetApis": {Verb: "Get", Resource: "Api", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis"}, + "GetAuthorizer": {Verb: "Get", Resource: "Authorizer", OutputListKey: "IdentitySource", OutputItemKey: "JwtConfiguration", Method: "GET", URI: "/v2/apis/{ApiId}/authorizers/{AuthorizerId}"}, + "GetAuthorizers": {Verb: "Get", Resource: "Authorizer", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/authorizers"}, + "GetDeployment": {Verb: "Get", Resource: "Deployment", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/deployments/{DeploymentId}"}, + "GetDeployments": {Verb: "Get", Resource: "Deployment", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/deployments"}, + "GetDomainName": {Verb: "Get", Resource: "DomainName", OutputListKey: "DomainNameConfigurations", OutputItemKey: "MutualTlsAuthentication", Method: "GET", URI: "/v2/domainnames/{DomainName}"}, + "GetDomainNames": {Verb: "Get", Resource: "DomainName", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/domainnames"}, + "GetIntegration": {Verb: "Get", Resource: "Integration", OutputListKey: "", OutputItemKey: "TlsConfig", Method: "GET", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}"}, + "GetIntegrationResponse": {Verb: "Get", Resource: "IntegrationResponse", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}/integrationresponses/{IntegrationResponseId}"}, + "GetIntegrationResponses": {Verb: "Get", Resource: "IntegrationResponse", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}/integrationresponses"}, + "GetIntegrations": {Verb: "Get", Resource: "Integration", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/integrations"}, + "GetModel": {Verb: "Get", Resource: "Model", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/models/{ModelId}"}, + "GetModelTemplate": {Verb: "Get", Resource: "ModelTemplate", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/models/{ModelId}/template"}, + "GetModels": {Verb: "Get", Resource: "Model", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/models"}, + "GetPortal": {Verb: "Get", Resource: "Portal", OutputListKey: "IncludedPortalProductArns", OutputItemKey: "Authorization", Method: "GET", URI: "/v2/portals/{PortalId}"}, + "GetPortalProduct": {Verb: "Get", Resource: "PortalProduct", OutputListKey: "", OutputItemKey: "DisplayOrder", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}"}, + "GetPortalProductSharingPolicy": {Verb: "Get", Resource: "PortalProductSharingPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}/sharingpolicy"}, + "GetProductPage": {Verb: "Get", Resource: "ProductPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}/productpages/{ProductPageId}"}, + "GetProductRestEndpointPage": {Verb: "Get", Resource: "ProductRestEndpointPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}/productrestendpointpages/{ProductRestEndpointPageId}"}, + "GetRoute": {Verb: "Get", Resource: "Route", OutputListKey: "AuthorizationScopes", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/routes/{RouteId}"}, + "GetRouteResponse": {Verb: "Get", Resource: "RouteResponse", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/routes/{RouteId}/routeresponses/{RouteResponseId}"}, + "GetRouteResponses": {Verb: "Get", Resource: "RouteResponse", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/routes/{RouteId}/routeresponses"}, + "GetRoutes": {Verb: "Get", Resource: "Route", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/routes"}, + "GetRoutingRule": {Verb: "Get", Resource: "RoutingRule", OutputListKey: "Actions", OutputItemKey: "", Method: "GET", URI: "/v2/domainnames/{DomainName}/routingrules/{RoutingRuleId}"}, + "GetStage": {Verb: "Get", Resource: "Stage", OutputListKey: "", OutputItemKey: "AccessLogSettings", Method: "GET", URI: "/v2/apis/{ApiId}/stages/{StageName}"}, + "GetStages": {Verb: "Get", Resource: "Stage", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{ApiId}/stages"}, + "GetTags": {Verb: "Get", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/tags/{ResourceArn}"}, + "GetVpcLink": {Verb: "Get", Resource: "VpcLink", OutputListKey: "SecurityGroupIds", OutputItemKey: "", Method: "GET", URI: "/v2/vpclinks/{VpcLinkId}"}, + "GetVpcLinks": {Verb: "Get", Resource: "VpcLink", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/vpclinks"}, + "ListPortalProducts": {Verb: "List", Resource: "PortalProduct", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/portalproducts"}, + "ListPortals": {Verb: "List", Resource: "Portal", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/portals"}, + "ListProductPages": {Verb: "List", Resource: "ProductPage", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}/productpages"}, + "ListProductRestEndpointPages": {Verb: "List", Resource: "ProductRestEndpointPage", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/v2/portalproducts/{PortalProductId}/productrestendpointpages"}, + "ListRoutingRules": {Verb: "List", Resource: "RoutingRule", OutputListKey: "RoutingRules", OutputItemKey: "", Method: "GET", URI: "/v2/domainnames/{DomainName}/routingrules"}, + "PutPortalProductSharingPolicy": {Verb: "Update", Resource: "PortalProductSharingPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/portalproducts/{PortalProductId}/sharingpolicy"}, + "PutRoutingRule": {Verb: "Update", Resource: "RoutingRule", OutputListKey: "Actions", OutputItemKey: "", Method: "PUT", URI: "/v2/domainnames/{DomainName}/routingrules/{RoutingRuleId}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/tags/{ResourceArn}"}, + "UpdateApi": {Verb: "Update", Resource: "Api", OutputListKey: "ImportInfo", OutputItemKey: "CorsConfiguration", Method: "PATCH", URI: "/v2/apis/{ApiId}"}, + "UpdateApiMapping": {Verb: "Update", Resource: "ApiMapping", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v2/domainnames/{DomainName}/apimappings/{ApiMappingId}"}, + "UpdateAuthorizer": {Verb: "Update", Resource: "Authorizer", OutputListKey: "IdentitySource", OutputItemKey: "JwtConfiguration", Method: "PATCH", URI: "/v2/apis/{ApiId}/authorizers/{AuthorizerId}"}, + "UpdateDeployment": {Verb: "Update", Resource: "Deployment", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v2/apis/{ApiId}/deployments/{DeploymentId}"}, + "UpdateDomainName": {Verb: "Update", Resource: "DomainName", OutputListKey: "DomainNameConfigurations", OutputItemKey: "MutualTlsAuthentication", Method: "PATCH", URI: "/v2/domainnames/{DomainName}"}, + "UpdateIntegration": {Verb: "Update", Resource: "Integration", OutputListKey: "", OutputItemKey: "TlsConfig", Method: "PATCH", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}"}, + "UpdateIntegrationResponse": {Verb: "Update", Resource: "IntegrationResponse", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v2/apis/{ApiId}/integrations/{IntegrationId}/integrationresponses/{IntegrationResponseId}"}, + "UpdateModel": {Verb: "Update", Resource: "Model", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v2/apis/{ApiId}/models/{ModelId}"}, + "UpdatePortal": {Verb: "Update", Resource: "Portal", OutputListKey: "IncludedPortalProductArns", OutputItemKey: "Authorization", Method: "PATCH", URI: "/v2/portals/{PortalId}"}, + "UpdatePortalProduct": {Verb: "Update", Resource: "PortalProduct", OutputListKey: "", OutputItemKey: "DisplayOrder", Method: "PATCH", URI: "/v2/portalproducts/{PortalProductId}"}, + "UpdateProductPage": {Verb: "Update", Resource: "ProductPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "PATCH", URI: "/v2/portalproducts/{PortalProductId}/productpages/{ProductPageId}"}, + "UpdateProductRestEndpointPage": {Verb: "Update", Resource: "ProductRestEndpointPage", OutputListKey: "", OutputItemKey: "DisplayContent", Method: "PATCH", URI: "/v2/portalproducts/{PortalProductId}/productrestendpointpages/{ProductRestEndpointPageId}"}, + "UpdateRoute": {Verb: "Update", Resource: "Route", OutputListKey: "AuthorizationScopes", OutputItemKey: "", Method: "PATCH", URI: "/v2/apis/{ApiId}/routes/{RouteId}"}, + "UpdateRouteResponse": {Verb: "Update", Resource: "RouteResponse", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v2/apis/{ApiId}/routes/{RouteId}/routeresponses/{RouteResponseId}"}, + "UpdateStage": {Verb: "Update", Resource: "Stage", OutputListKey: "", OutputItemKey: "AccessLogSettings", Method: "PATCH", URI: "/v2/apis/{ApiId}/stages/{StageName}"}, + "UpdateVpcLink": {Verb: "Update", Resource: "VpcLink", OutputListKey: "SecurityGroupIds", OutputItemKey: "", Method: "PATCH", URI: "/v2/vpclinks/{VpcLinkId}"}, + }) + crud.Register("appconfig", map[string]crud.OpMeta{ + "CreateApplication": {Verb: "Create", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications"}, + "CreateConfigurationProfile": {Verb: "Create", Resource: "ConfigurationProfile", OutputListKey: "Validators", OutputItemKey: "", Method: "POST", URI: "/applications/{ApplicationId}/configurationprofiles"}, + "CreateDeploymentStrategy": {Verb: "Create", Resource: "DeploymentStrategy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/deploymentstrategies"}, + "CreateEnvironment": {Verb: "Create", Resource: "Environment", OutputListKey: "Monitors", OutputItemKey: "", Method: "POST", URI: "/applications/{ApplicationId}/environments"}, + "CreateExtension": {Verb: "Create", Resource: "Extension", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/extensions"}, + "CreateExtensionAssociation": {Verb: "Create", Resource: "ExtensionAssociation", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/extensionassociations"}, + "CreateHostedConfigurationVersion": {Verb: "Create", Resource: "HostedConfigurationVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}/hostedconfigurationversions"}, + "DeleteApplication": {Verb: "Delete", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{ApplicationId}"}, + "DeleteConfigurationProfile": {Verb: "Delete", Resource: "ConfigurationProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}"}, + "DeleteDeploymentStrategy": {Verb: "Delete", Resource: "DeploymentStrategy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/deployementstrategies/{DeploymentStrategyId}"}, + "DeleteEnvironment": {Verb: "Delete", Resource: "Environment", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{ApplicationId}/environments/{EnvironmentId}"}, + "DeleteExtension": {Verb: "Delete", Resource: "Extension", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/extensions/{ExtensionIdentifier}"}, + "DeleteExtensionAssociation": {Verb: "Delete", Resource: "ExtensionAssociation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/extensionassociations/{ExtensionAssociationId}"}, + "DeleteHostedConfigurationVersion": {Verb: "Delete", Resource: "HostedConfigurationVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}/hostedconfigurationversions/{VersionNumber}"}, + "GetAccountSettings": {Verb: "Get", Resource: "AccountSetting", OutputListKey: "", OutputItemKey: "DeletionProtection", Method: "GET", URI: "/settings"}, + "GetApplication": {Verb: "Get", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}"}, + "GetConfiguration": {Verb: "Get", Resource: "Configuration", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{Application}/environments/{Environment}/configurations/{Configuration}"}, + "GetConfigurationProfile": {Verb: "Get", Resource: "ConfigurationProfile", OutputListKey: "Validators", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}"}, + "GetDeployment": {Verb: "Get", Resource: "Deployment", OutputListKey: "AppliedExtensions", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/environments/{EnvironmentId}/deployments/{DeploymentNumber}"}, + "GetDeploymentStrategy": {Verb: "Get", Resource: "DeploymentStrategy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/deploymentstrategies/{DeploymentStrategyId}"}, + "GetEnvironment": {Verb: "Get", Resource: "Environment", OutputListKey: "Monitors", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/environments/{EnvironmentId}"}, + "GetExtension": {Verb: "Get", Resource: "Extension", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/extensions/{ExtensionIdentifier}"}, + "GetExtensionAssociation": {Verb: "Get", Resource: "ExtensionAssociation", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/extensionassociations/{ExtensionAssociationId}"}, + "GetHostedConfigurationVersion": {Verb: "Get", Resource: "HostedConfigurationVersion", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}/hostedconfigurationversions/{VersionNumber}"}, + "ListApplications": {Verb: "List", Resource: "Application", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/applications"}, + "ListConfigurationProfiles": {Verb: "List", Resource: "ConfigurationProfile", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/configurationprofiles"}, + "ListDeploymentStrategies": {Verb: "List", Resource: "DeploymentStrategy", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/deploymentstrategies"}, + "ListDeployments": {Verb: "List", Resource: "Deployment", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/environments/{EnvironmentId}/deployments"}, + "ListEnvironments": {Verb: "List", Resource: "Environment", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/environments"}, + "ListExtensionAssociations": {Verb: "List", Resource: "ExtensionAssociation", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/extensionassociations"}, + "ListExtensions": {Verb: "List", Resource: "Extension", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/extensions"}, + "ListHostedConfigurationVersions": {Verb: "List", Resource: "HostedConfigurationVersion", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}/hostedconfigurationversions"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{ResourceArn}"}, + "UpdateAccountSettings": {Verb: "Update", Resource: "AccountSetting", OutputListKey: "", OutputItemKey: "DeletionProtection", Method: "PATCH", URI: "/settings"}, + "UpdateApplication": {Verb: "Update", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/applications/{ApplicationId}"}, + "UpdateConfigurationProfile": {Verb: "Update", Resource: "ConfigurationProfile", OutputListKey: "Validators", OutputItemKey: "", Method: "PATCH", URI: "/applications/{ApplicationId}/configurationprofiles/{ConfigurationProfileId}"}, + "UpdateDeploymentStrategy": {Verb: "Update", Resource: "DeploymentStrategy", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/deploymentstrategies/{DeploymentStrategyId}"}, + "UpdateEnvironment": {Verb: "Update", Resource: "Environment", OutputListKey: "Monitors", OutputItemKey: "", Method: "PATCH", URI: "/applications/{ApplicationId}/environments/{EnvironmentId}"}, + "UpdateExtension": {Verb: "Update", Resource: "Extension", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/extensions/{ExtensionIdentifier}"}, + "UpdateExtensionAssociation": {Verb: "Update", Resource: "ExtensionAssociation", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/extensionassociations/{ExtensionAssociationId}"}, + }) crud.Register("applicationautoscaling", map[string]crud.OpMeta{ "DeleteScalingPolicy": {Verb: "Delete", Resource: "ScalingPolicy", OutputListKey: "", OutputItemKey: ""}, "DeleteScheduledAction": {Verb: "Delete", Resource: "ScheduledAction", OutputListKey: "", OutputItemKey: ""}, @@ -56,6 +233,70 @@ func init() { "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("appsync", map[string]crud.OpMeta{ + "CreateApi": {Verb: "Create", Resource: "Api", OutputListKey: "", OutputItemKey: "api", Method: "POST", URI: "/v2/apis"}, + "CreateApiCache": {Verb: "Create", Resource: "ApiCache", OutputListKey: "", OutputItemKey: "apiCache", Method: "POST", URI: "/v1/apis/{apiId}/ApiCaches"}, + "CreateApiKey": {Verb: "Create", Resource: "ApiKey", OutputListKey: "", OutputItemKey: "apiKey", Method: "POST", URI: "/v1/apis/{apiId}/apikeys"}, + "CreateChannelNamespace": {Verb: "Create", Resource: "ChannelNamespace", OutputListKey: "", OutputItemKey: "channelNamespace", Method: "POST", URI: "/v2/apis/{apiId}/channelNamespaces"}, + "CreateDataSource": {Verb: "Create", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "POST", URI: "/v1/apis/{apiId}/datasources"}, + "CreateDomainName": {Verb: "Create", Resource: "DomainName", OutputListKey: "", OutputItemKey: "domainNameConfig", Method: "POST", URI: "/v1/domainnames"}, + "CreateFunction": {Verb: "Create", Resource: "Function", OutputListKey: "", OutputItemKey: "functionConfiguration", Method: "POST", URI: "/v1/apis/{apiId}/functions"}, + "CreateGraphqlApi": {Verb: "Create", Resource: "GraphqlApi", OutputListKey: "", OutputItemKey: "graphqlApi", Method: "POST", URI: "/v1/apis"}, + "CreateResolver": {Verb: "Create", Resource: "Resolver", OutputListKey: "", OutputItemKey: "resolver", Method: "POST", URI: "/v1/apis/{apiId}/types/{typeName}/resolvers"}, + "CreateType": {Verb: "Create", Resource: "Type", OutputListKey: "", OutputItemKey: "type", Method: "POST", URI: "/v1/apis/{apiId}/types"}, + "DeleteApi": {Verb: "Delete", Resource: "Api", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{apiId}"}, + "DeleteApiCache": {Verb: "Delete", Resource: "ApiCache", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/ApiCaches"}, + "DeleteApiKey": {Verb: "Delete", Resource: "ApiKey", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/apikeys/{id}"}, + "DeleteChannelNamespace": {Verb: "Delete", Resource: "ChannelNamespace", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/apis/{apiId}/channelNamespaces/{name}"}, + "DeleteDataSource": {Verb: "Delete", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/datasources/{name}"}, + "DeleteDomainName": {Verb: "Delete", Resource: "DomainName", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/domainnames/{domainName}"}, + "DeleteFunction": {Verb: "Delete", Resource: "Function", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/functions/{functionId}"}, + "DeleteGraphqlApi": {Verb: "Delete", Resource: "GraphqlApi", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}"}, + "DeleteResolver": {Verb: "Delete", Resource: "Resolver", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}"}, + "DeleteType": {Verb: "Delete", Resource: "Type", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/apis/{apiId}/types/{typeName}"}, + "GetApi": {Verb: "Get", Resource: "Api", OutputListKey: "", OutputItemKey: "api", Method: "GET", URI: "/v2/apis/{apiId}"}, + "GetApiAssociation": {Verb: "Get", Resource: "ApiAssociation", OutputListKey: "", OutputItemKey: "apiAssociation", Method: "GET", URI: "/v1/domainnames/{domainName}/apiassociation"}, + "GetApiCache": {Verb: "Get", Resource: "ApiCache", OutputListKey: "", OutputItemKey: "apiCache", Method: "GET", URI: "/v1/apis/{apiId}/ApiCaches"}, + "GetChannelNamespace": {Verb: "Get", Resource: "ChannelNamespace", OutputListKey: "", OutputItemKey: "channelNamespace", Method: "GET", URI: "/v2/apis/{apiId}/channelNamespaces/{name}"}, + "GetDataSource": {Verb: "Get", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "GET", URI: "/v1/apis/{apiId}/datasources/{name}"}, + "GetDataSourceIntrospection": {Verb: "Get", Resource: "DataSourceIntrospection", OutputListKey: "", OutputItemKey: "introspectionResult", Method: "GET", URI: "/v1/datasources/introspections/{introspectionId}"}, + "GetDomainName": {Verb: "Get", Resource: "DomainName", OutputListKey: "", OutputItemKey: "domainNameConfig", Method: "GET", URI: "/v1/domainnames/{domainName}"}, + "GetFunction": {Verb: "Get", Resource: "Function", OutputListKey: "", OutputItemKey: "functionConfiguration", Method: "GET", URI: "/v1/apis/{apiId}/functions/{functionId}"}, + "GetGraphqlApi": {Verb: "Get", Resource: "GraphqlApi", OutputListKey: "", OutputItemKey: "graphqlApi", Method: "GET", URI: "/v1/apis/{apiId}"}, + "GetGraphqlApiEnvironmentVariables": {Verb: "Get", Resource: "GraphqlApiEnvironmentVariable", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/environmentVariables"}, + "GetIntrospectionSchema": {Verb: "Get", Resource: "IntrospectionSchema", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/schema"}, + "GetResolver": {Verb: "Get", Resource: "Resolver", OutputListKey: "", OutputItemKey: "resolver", Method: "GET", URI: "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}"}, + "GetSchemaCreationStatus": {Verb: "Get", Resource: "SchemaCreationStatu", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/schemacreation"}, + "GetSourceApiAssociation": {Verb: "Get", Resource: "SourceApiAssociation", OutputListKey: "", OutputItemKey: "sourceApiAssociation", Method: "GET", URI: "/v1/mergedApis/{mergedApiIdentifier}/sourceApiAssociations/{associationId}"}, + "GetType": {Verb: "Get", Resource: "Type", OutputListKey: "", OutputItemKey: "type", Method: "GET", URI: "/v1/apis/{apiId}/types/{typeName}"}, + "ListApiKeys": {Verb: "List", Resource: "ApiKey", OutputListKey: "apiKeys", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/apikeys"}, + "ListApis": {Verb: "List", Resource: "Api", OutputListKey: "apis", OutputItemKey: "", Method: "GET", URI: "/v2/apis"}, + "ListChannelNamespaces": {Verb: "List", Resource: "ChannelNamespace", OutputListKey: "channelNamespaces", OutputItemKey: "", Method: "GET", URI: "/v2/apis/{apiId}/channelNamespaces"}, + "ListDataSources": {Verb: "List", Resource: "DataSource", OutputListKey: "dataSources", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/datasources"}, + "ListDomainNames": {Verb: "List", Resource: "DomainName", OutputListKey: "domainNameConfigs", OutputItemKey: "", Method: "GET", URI: "/v1/domainnames"}, + "ListFunctions": {Verb: "List", Resource: "Function", OutputListKey: "functions", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/functions"}, + "ListGraphqlApis": {Verb: "List", Resource: "GraphqlApi", OutputListKey: "graphqlApis", OutputItemKey: "", Method: "GET", URI: "/v1/apis"}, + "ListResolvers": {Verb: "List", Resource: "Resolver", OutputListKey: "resolvers", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/types/{typeName}/resolvers"}, + "ListResolversByFunction": {Verb: "List", Resource: "ResolversByFunction", OutputListKey: "resolvers", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/functions/{functionId}/resolvers"}, + "ListSourceApiAssociations": {Verb: "List", Resource: "SourceApiAssociation", OutputListKey: "sourceApiAssociationSummaries", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/sourceApiAssociations"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/tags/{resourceArn}"}, + "ListTypes": {Verb: "List", Resource: "Type", OutputListKey: "types", OutputItemKey: "", Method: "GET", URI: "/v1/apis/{apiId}/types"}, + "ListTypesByAssociation": {Verb: "List", Resource: "TypesByAssociation", OutputListKey: "types", OutputItemKey: "", Method: "GET", URI: "/v1/mergedApis/{mergedApiIdentifier}/sourceApiAssociations/{associationId}/types"}, + "PutGraphqlApiEnvironmentVariables": {Verb: "Update", Resource: "GraphqlApiEnvironmentVariable", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/apis/{apiId}/environmentVariables"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{resourceArn}"}, + "UpdateApi": {Verb: "Update", Resource: "Api", OutputListKey: "", OutputItemKey: "api", Method: "POST", URI: "/v2/apis/{apiId}"}, + "UpdateApiCache": {Verb: "Update", Resource: "ApiCache", OutputListKey: "", OutputItemKey: "apiCache", Method: "POST", URI: "/v1/apis/{apiId}/ApiCaches/update"}, + "UpdateApiKey": {Verb: "Update", Resource: "ApiKey", OutputListKey: "", OutputItemKey: "apiKey", Method: "POST", URI: "/v1/apis/{apiId}/apikeys/{id}"}, + "UpdateChannelNamespace": {Verb: "Update", Resource: "ChannelNamespace", OutputListKey: "", OutputItemKey: "channelNamespace", Method: "POST", URI: "/v2/apis/{apiId}/channelNamespaces/{name}"}, + "UpdateDataSource": {Verb: "Update", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "POST", URI: "/v1/apis/{apiId}/datasources/{name}"}, + "UpdateDomainName": {Verb: "Update", Resource: "DomainName", OutputListKey: "", OutputItemKey: "domainNameConfig", Method: "POST", URI: "/v1/domainnames/{domainName}"}, + "UpdateFunction": {Verb: "Update", Resource: "Function", OutputListKey: "", OutputItemKey: "functionConfiguration", Method: "POST", URI: "/v1/apis/{apiId}/functions/{functionId}"}, + "UpdateGraphqlApi": {Verb: "Update", Resource: "GraphqlApi", OutputListKey: "", OutputItemKey: "graphqlApi", Method: "POST", URI: "/v1/apis/{apiId}"}, + "UpdateResolver": {Verb: "Update", Resource: "Resolver", OutputListKey: "", OutputItemKey: "resolver", Method: "POST", URI: "/v1/apis/{apiId}/types/{typeName}/resolvers/{fieldName}"}, + "UpdateSourceApiAssociation": {Verb: "Update", Resource: "SourceApiAssociation", OutputListKey: "", OutputItemKey: "sourceApiAssociation", Method: "POST", URI: "/v1/mergedApis/{mergedApiIdentifier}/sourceApiAssociations/{associationId}"}, + "UpdateType": {Verb: "Update", Resource: "Type", OutputListKey: "", OutputItemKey: "type", Method: "POST", URI: "/v1/apis/{apiId}/types/{typeName}"}, + }) crud.Register("athena", map[string]crud.OpMeta{ "BatchGetNamedQuery": {Verb: "List", Resource: "NamedQuery", OutputListKey: "NamedQueries", OutputItemKey: ""}, "BatchGetPreparedStatement": {Verb: "List", Resource: "PreparedStatement", OutputListKey: "PreparedStatements", OutputItemKey: ""}, @@ -119,12 +360,577 @@ func init() { "UpdatePreparedStatement": {Verb: "Update", Resource: "PreparedStatement", OutputListKey: "", OutputItemKey: ""}, "UpdateWorkGroup": {Verb: "Update", Resource: "WorkGroup", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("backup", map[string]crud.OpMeta{ + "CreateBackupPlan": {Verb: "Create", Resource: "BackupPlan", OutputListKey: "AdvancedBackupSettings", OutputItemKey: "", Method: "PUT", URI: "/backup/plans"}, + "CreateBackupSelection": {Verb: "Create", Resource: "BackupSelection", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/backup/plans/{BackupPlanId}/selections"}, + "CreateBackupVault": {Verb: "Create", Resource: "BackupVault", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/backup-vaults/{BackupVaultName}"}, + "CreateFramework": {Verb: "Create", Resource: "Framework", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/audit/frameworks"}, + "CreateLegalHold": {Verb: "Create", Resource: "LegalHold", OutputListKey: "", OutputItemKey: "RecoveryPointSelection", Method: "POST", URI: "/legal-holds"}, + "CreateLogicallyAirGappedBackupVault": {Verb: "Create", Resource: "LogicallyAirGappedBackupVault", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/logically-air-gapped-backup-vaults/{BackupVaultName}"}, + "CreateReportPlan": {Verb: "Create", Resource: "ReportPlan", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/audit/report-plans"}, + "CreateRestoreAccessBackupVault": {Verb: "Create", Resource: "RestoreAccessBackupVault", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-access-backup-vaults"}, + "CreateRestoreTestingPlan": {Verb: "Create", Resource: "RestoreTestingPlan", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-testing/plans"}, + "CreateRestoreTestingSelection": {Verb: "Create", Resource: "RestoreTestingSelection", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-testing/plans/{RestoreTestingPlanName}/selections"}, + "CreateTieringConfiguration": {Verb: "Create", Resource: "TieringConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/tiering-configurations"}, + "DeleteBackupPlan": {Verb: "Delete", Resource: "BackupPlan", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup/plans/{BackupPlanId}"}, + "DeleteBackupSelection": {Verb: "Delete", Resource: "BackupSelection", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup/plans/{BackupPlanId}/selections/{SelectionId}"}, + "DeleteBackupVault": {Verb: "Delete", Resource: "BackupVault", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup-vaults/{BackupVaultName}"}, + "DeleteBackupVaultAccessPolicy": {Verb: "Delete", Resource: "BackupVaultAccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup-vaults/{BackupVaultName}/access-policy"}, + "DeleteBackupVaultLockConfiguration": {Verb: "Delete", Resource: "BackupVaultLockConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup-vaults/{BackupVaultName}/vault-lock"}, + "DeleteBackupVaultNotifications": {Verb: "Delete", Resource: "BackupVaultNotification", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup-vaults/{BackupVaultName}/notification-configuration"}, + "DeleteFramework": {Verb: "Delete", Resource: "Framework", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/audit/frameworks/{FrameworkName}"}, + "DeleteRecoveryPoint": {Verb: "Delete", Resource: "RecoveryPoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}"}, + "DeleteReportPlan": {Verb: "Delete", Resource: "ReportPlan", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/audit/report-plans/{ReportPlanName}"}, + "DeleteRestoreTestingPlan": {Verb: "Delete", Resource: "RestoreTestingPlan", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/restore-testing/plans/{RestoreTestingPlanName}"}, + "DeleteRestoreTestingSelection": {Verb: "Delete", Resource: "RestoreTestingSelection", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/restore-testing/plans/{RestoreTestingPlanName}/selections/{RestoreTestingSelectionName}"}, + "DeleteTieringConfiguration": {Verb: "Delete", Resource: "TieringConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tiering-configurations/{TieringConfigurationName}"}, + "DescribeBackupJob": {Verb: "Get", Resource: "BackupJob", OutputListKey: "", OutputItemKey: "CreatedBy", Method: "GET", URI: "/backup-jobs/{BackupJobId}"}, + "DescribeBackupVault": {Verb: "Get", Resource: "BackupVault", OutputListKey: "", OutputItemKey: "LatestMpaApprovalTeamUpdate", Method: "GET", URI: "/backup-vaults/{BackupVaultName}"}, + "DescribeCopyJob": {Verb: "Get", Resource: "CopyJob", OutputListKey: "", OutputItemKey: "CopyJob", Method: "GET", URI: "/copy-jobs/{CopyJobId}"}, + "DescribeFramework": {Verb: "Get", Resource: "Framework", OutputListKey: "FrameworkControls", OutputItemKey: "", Method: "GET", URI: "/audit/frameworks/{FrameworkName}"}, + "DescribeGlobalSettings": {Verb: "Get", Resource: "GlobalSetting", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/global-settings"}, + "DescribeProtectedResource": {Verb: "Get", Resource: "ProtectedResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resources/{ResourceArn}"}, + "DescribeRecoveryPoint": {Verb: "Get", Resource: "RecoveryPoint", OutputListKey: "ScanResults", OutputItemKey: "CalculatedLifecycle", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}"}, + "DescribeRegionSettings": {Verb: "Get", Resource: "RegionSetting", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/account-settings"}, + "DescribeReportJob": {Verb: "Get", Resource: "ReportJob", OutputListKey: "", OutputItemKey: "ReportJob", Method: "GET", URI: "/audit/report-jobs/{ReportJobId}"}, + "DescribeReportPlan": {Verb: "Get", Resource: "ReportPlan", OutputListKey: "", OutputItemKey: "ReportPlan", Method: "GET", URI: "/audit/report-plans/{ReportPlanName}"}, + "DescribeRestoreJob": {Verb: "Get", Resource: "RestoreJob", OutputListKey: "", OutputItemKey: "CreatedBy", Method: "GET", URI: "/restore-jobs/{RestoreJobId}"}, + "DescribeScanJob": {Verb: "Get", Resource: "ScanJob", OutputListKey: "", OutputItemKey: "CreatedBy", Method: "GET", URI: "/scan/jobs/{ScanJobId}"}, + "GetBackupPlan": {Verb: "Get", Resource: "BackupPlan", OutputListKey: "AdvancedBackupSettings", OutputItemKey: "BackupPlan", Method: "GET", URI: "/backup/plans/{BackupPlanId}"}, + "GetBackupPlanFromJSON": {Verb: "Get", Resource: "BackupPlanFromJSON", OutputListKey: "", OutputItemKey: "BackupPlan", Method: "POST", URI: "/backup/template/json/toPlan"}, + "GetBackupPlanFromTemplate": {Verb: "Get", Resource: "BackupPlanFromTemplate", OutputListKey: "", OutputItemKey: "BackupPlanDocument", Method: "GET", URI: "/backup/template/plans/{BackupPlanTemplateId}/toPlan"}, + "GetBackupSelection": {Verb: "Get", Resource: "BackupSelection", OutputListKey: "", OutputItemKey: "BackupSelection", Method: "GET", URI: "/backup/plans/{BackupPlanId}/selections/{SelectionId}"}, + "GetBackupVaultAccessPolicy": {Verb: "Get", Resource: "BackupVaultAccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/access-policy"}, + "GetBackupVaultNotifications": {Verb: "Get", Resource: "BackupVaultNotification", OutputListKey: "BackupVaultEvents", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/notification-configuration"}, + "GetLegalHold": {Verb: "Get", Resource: "LegalHold", OutputListKey: "", OutputItemKey: "RecoveryPointSelection", Method: "GET", URI: "/legal-holds/{LegalHoldId}"}, + "GetRecoveryPointIndexDetails": {Verb: "Get", Resource: "RecoveryPointIndexDetail", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}/index"}, + "GetRecoveryPointRestoreMetadata": {Verb: "Get", Resource: "RecoveryPointRestoreMetadata", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}/restore-metadata"}, + "GetRestoreJobMetadata": {Verb: "Get", Resource: "RestoreJobMetadata", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/restore-jobs/{RestoreJobId}/metadata"}, + "GetRestoreTestingInferredMetadata": {Verb: "Get", Resource: "RestoreTestingInferredMetadata", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/restore-testing/inferred-metadata"}, + "GetRestoreTestingPlan": {Verb: "Get", Resource: "RestoreTestingPlan", OutputListKey: "", OutputItemKey: "RestoreTestingPlan", Method: "GET", URI: "/restore-testing/plans/{RestoreTestingPlanName}"}, + "GetRestoreTestingSelection": {Verb: "Get", Resource: "RestoreTestingSelection", OutputListKey: "", OutputItemKey: "RestoreTestingSelection", Method: "GET", URI: "/restore-testing/plans/{RestoreTestingPlanName}/selections/{RestoreTestingSelectionName}"}, + "GetSupportedResourceTypes": {Verb: "Get", Resource: "SupportedResourceType", OutputListKey: "ResourceTypes", OutputItemKey: "", Method: "GET", URI: "/supported-resource-types"}, + "GetTieringConfiguration": {Verb: "Get", Resource: "TieringConfiguration", OutputListKey: "", OutputItemKey: "TieringConfiguration", Method: "GET", URI: "/tiering-configurations/{TieringConfigurationName}"}, + "ListBackupJobSummaries": {Verb: "List", Resource: "BackupJobSummary", OutputListKey: "BackupJobSummaries", OutputItemKey: "", Method: "GET", URI: "/audit/backup-job-summaries"}, + "ListBackupJobs": {Verb: "List", Resource: "BackupJob", OutputListKey: "BackupJobs", OutputItemKey: "", Method: "GET", URI: "/backup-jobs"}, + "ListBackupPlanTemplates": {Verb: "List", Resource: "BackupPlanTemplate", OutputListKey: "BackupPlanTemplatesList", OutputItemKey: "", Method: "GET", URI: "/backup/template/plans"}, + "ListBackupPlanVersions": {Verb: "List", Resource: "BackupPlanVersion", OutputListKey: "BackupPlanVersionsList", OutputItemKey: "", Method: "GET", URI: "/backup/plans/{BackupPlanId}/versions"}, + "ListBackupPlans": {Verb: "List", Resource: "BackupPlan", OutputListKey: "BackupPlansList", OutputItemKey: "", Method: "GET", URI: "/backup/plans"}, + "ListBackupSelections": {Verb: "List", Resource: "BackupSelection", OutputListKey: "BackupSelectionsList", OutputItemKey: "", Method: "GET", URI: "/backup/plans/{BackupPlanId}/selections"}, + "ListBackupVaults": {Verb: "List", Resource: "BackupVault", OutputListKey: "BackupVaultList", OutputItemKey: "", Method: "GET", URI: "/backup-vaults"}, + "ListCopyJobSummaries": {Verb: "List", Resource: "CopyJobSummary", OutputListKey: "CopyJobSummaries", OutputItemKey: "", Method: "GET", URI: "/audit/copy-job-summaries"}, + "ListCopyJobs": {Verb: "List", Resource: "CopyJob", OutputListKey: "CopyJobs", OutputItemKey: "", Method: "GET", URI: "/copy-jobs"}, + "ListFrameworks": {Verb: "List", Resource: "Framework", OutputListKey: "Frameworks", OutputItemKey: "", Method: "GET", URI: "/audit/frameworks"}, + "ListIndexedRecoveryPoints": {Verb: "List", Resource: "IndexedRecoveryPoint", OutputListKey: "IndexedRecoveryPoints", OutputItemKey: "", Method: "GET", URI: "/indexes/recovery-point"}, + "ListLegalHolds": {Verb: "List", Resource: "LegalHold", OutputListKey: "LegalHolds", OutputItemKey: "", Method: "GET", URI: "/legal-holds"}, + "ListProtectedResources": {Verb: "List", Resource: "ProtectedResource", OutputListKey: "Results", OutputItemKey: "", Method: "GET", URI: "/resources"}, + "ListProtectedResourcesByBackupVault": {Verb: "List", Resource: "ProtectedResourcesByBackupVault", OutputListKey: "Results", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/resources"}, + "ListRecoveryPointsByBackupVault": {Verb: "List", Resource: "RecoveryPointsByBackupVault", OutputListKey: "RecoveryPoints", OutputItemKey: "", Method: "GET", URI: "/backup-vaults/{BackupVaultName}/recovery-points"}, + "ListRecoveryPointsByLegalHold": {Verb: "List", Resource: "RecoveryPointsByLegalHold", OutputListKey: "RecoveryPoints", OutputItemKey: "", Method: "GET", URI: "/legal-holds/{LegalHoldId}/recovery-points"}, + "ListRecoveryPointsByResource": {Verb: "List", Resource: "RecoveryPointsByResource", OutputListKey: "RecoveryPoints", OutputItemKey: "", Method: "GET", URI: "/resources/{ResourceArn}/recovery-points"}, + "ListReportJobs": {Verb: "List", Resource: "ReportJob", OutputListKey: "ReportJobs", OutputItemKey: "", Method: "GET", URI: "/audit/report-jobs"}, + "ListReportPlans": {Verb: "List", Resource: "ReportPlan", OutputListKey: "ReportPlans", OutputItemKey: "", Method: "GET", URI: "/audit/report-plans"}, + "ListRestoreAccessBackupVaults": {Verb: "List", Resource: "RestoreAccessBackupVault", OutputListKey: "RestoreAccessBackupVaults", OutputItemKey: "", Method: "GET", URI: "/logically-air-gapped-backup-vaults/{BackupVaultName}/restore-access-backup-vaults"}, + "ListRestoreJobSummaries": {Verb: "List", Resource: "RestoreJobSummary", OutputListKey: "RestoreJobSummaries", OutputItemKey: "", Method: "GET", URI: "/audit/restore-job-summaries"}, + "ListRestoreJobs": {Verb: "List", Resource: "RestoreJob", OutputListKey: "RestoreJobs", OutputItemKey: "", Method: "GET", URI: "/restore-jobs"}, + "ListRestoreJobsByProtectedResource": {Verb: "List", Resource: "RestoreJobsByProtectedResource", OutputListKey: "RestoreJobs", OutputItemKey: "", Method: "GET", URI: "/resources/{ResourceArn}/restore-jobs"}, + "ListRestoreTestingPlans": {Verb: "List", Resource: "RestoreTestingPlan", OutputListKey: "RestoreTestingPlans", OutputItemKey: "", Method: "GET", URI: "/restore-testing/plans"}, + "ListRestoreTestingSelections": {Verb: "List", Resource: "RestoreTestingSelection", OutputListKey: "RestoreTestingSelections", OutputItemKey: "", Method: "GET", URI: "/restore-testing/plans/{RestoreTestingPlanName}/selections"}, + "ListScanJobSummaries": {Verb: "List", Resource: "ScanJobSummary", OutputListKey: "ScanJobSummaries", OutputItemKey: "", Method: "GET", URI: "/audit/scan-job-summaries"}, + "ListScanJobs": {Verb: "List", Resource: "ScanJob", OutputListKey: "ScanJobs", OutputItemKey: "", Method: "GET", URI: "/scan/jobs"}, + "ListTags": {Verb: "List", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "ListTieringConfigurations": {Verb: "List", Resource: "TieringConfiguration", OutputListKey: "TieringConfigurations", OutputItemKey: "", Method: "GET", URI: "/tiering-configurations"}, + "PutBackupVaultAccessPolicy": {Verb: "Update", Resource: "BackupVaultAccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/backup-vaults/{BackupVaultName}/access-policy"}, + "PutBackupVaultLockConfiguration": {Verb: "Update", Resource: "BackupVaultLockConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/backup-vaults/{BackupVaultName}/vault-lock"}, + "PutBackupVaultNotifications": {Verb: "Update", Resource: "BackupVaultNotification", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/backup-vaults/{BackupVaultName}/notification-configuration"}, + "PutRestoreValidationResult": {Verb: "Update", Resource: "RestoreValidationResult", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-jobs/{RestoreJobId}/validations"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/untag/{ResourceArn}"}, + "UpdateBackupPlan": {Verb: "Update", Resource: "BackupPlan", OutputListKey: "AdvancedBackupSettings", OutputItemKey: "", Method: "POST", URI: "/backup/plans/{BackupPlanId}"}, + "UpdateFramework": {Verb: "Update", Resource: "Framework", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/audit/frameworks/{FrameworkName}"}, + "UpdateGlobalSettings": {Verb: "Update", Resource: "GlobalSetting", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/global-settings"}, + "UpdateRecoveryPointIndexSettings": {Verb: "Update", Resource: "RecoveryPointIndexSetting", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}/index"}, + "UpdateRecoveryPointLifecycle": {Verb: "Update", Resource: "RecoveryPointLifecycle", OutputListKey: "", OutputItemKey: "CalculatedLifecycle", Method: "POST", URI: "/backup-vaults/{BackupVaultName}/recovery-points/{RecoveryPointArn}"}, + "UpdateRegionSettings": {Verb: "Update", Resource: "RegionSetting", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/account-settings"}, + "UpdateReportPlan": {Verb: "Update", Resource: "ReportPlan", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/audit/report-plans/{ReportPlanName}"}, + "UpdateRestoreTestingPlan": {Verb: "Update", Resource: "RestoreTestingPlan", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-testing/plans/{RestoreTestingPlanName}"}, + "UpdateRestoreTestingSelection": {Verb: "Update", Resource: "RestoreTestingSelection", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/restore-testing/plans/{RestoreTestingPlanName}/selections/{RestoreTestingSelectionName}"}, + "UpdateTieringConfiguration": {Verb: "Update", Resource: "TieringConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/tiering-configurations/{TieringConfigurationName}"}, + }) + crud.Register("batch", map[string]crud.OpMeta{ + "CreateComputeEnvironment": {Verb: "Create", Resource: "ComputeEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createcomputeenvironment"}, + "CreateConsumableResource": {Verb: "Create", Resource: "ConsumableResource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createconsumableresource"}, + "CreateJobQueue": {Verb: "Create", Resource: "JobQueue", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createjobqueue"}, + "CreateQuotaShare": {Verb: "Create", Resource: "QuotaShare", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createquotashare"}, + "CreateSchedulingPolicy": {Verb: "Create", Resource: "SchedulingPolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createschedulingpolicy"}, + "CreateServiceEnvironment": {Verb: "Create", Resource: "ServiceEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/createserviceenvironment"}, + "DeleteComputeEnvironment": {Verb: "Delete", Resource: "ComputeEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deletecomputeenvironment"}, + "DeleteConsumableResource": {Verb: "Delete", Resource: "ConsumableResource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deleteconsumableresource"}, + "DeleteJobQueue": {Verb: "Delete", Resource: "JobQueue", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deletejobqueue"}, + "DeleteQuotaShare": {Verb: "Delete", Resource: "QuotaShare", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deletequotashare"}, + "DeleteSchedulingPolicy": {Verb: "Delete", Resource: "SchedulingPolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deleteschedulingpolicy"}, + "DeleteServiceEnvironment": {Verb: "Delete", Resource: "ServiceEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deleteserviceenvironment"}, + "DeregisterJobDefinition": {Verb: "Delete", Resource: "JobDefinition", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/deregisterjobdefinition"}, + "DescribeComputeEnvironments": {Verb: "Get", Resource: "ComputeEnvironment", OutputListKey: "computeEnvironments", OutputItemKey: "", Method: "POST", URI: "/v1/describecomputeenvironments"}, + "DescribeConsumableResource": {Verb: "Get", Resource: "ConsumableResource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/describeconsumableresource"}, + "DescribeJobDefinitions": {Verb: "Get", Resource: "JobDefinition", OutputListKey: "jobDefinitions", OutputItemKey: "", Method: "POST", URI: "/v1/describejobdefinitions"}, + "DescribeJobQueues": {Verb: "Get", Resource: "JobQueue", OutputListKey: "jobQueues", OutputItemKey: "", Method: "POST", URI: "/v1/describejobqueues"}, + "DescribeJobs": {Verb: "Get", Resource: "Job", OutputListKey: "jobs", OutputItemKey: "", Method: "POST", URI: "/v1/describejobs"}, + "DescribeQuotaShare": {Verb: "Get", Resource: "QuotaShare", OutputListKey: "capacityLimits", OutputItemKey: "preemptionConfiguration", Method: "POST", URI: "/v1/describequotashare"}, + "DescribeSchedulingPolicies": {Verb: "Get", Resource: "SchedulingPolicy", OutputListKey: "schedulingPolicies", OutputItemKey: "", Method: "POST", URI: "/v1/describeschedulingpolicies"}, + "DescribeServiceEnvironments": {Verb: "Get", Resource: "ServiceEnvironment", OutputListKey: "serviceEnvironments", OutputItemKey: "", Method: "POST", URI: "/v1/describeserviceenvironments"}, + "DescribeServiceJob": {Verb: "Get", Resource: "ServiceJob", OutputListKey: "attempts", OutputItemKey: "latestAttempt", Method: "POST", URI: "/v1/describeservicejob"}, + "GetJobQueueSnapshot": {Verb: "Get", Resource: "JobQueueSnapshot", OutputListKey: "", OutputItemKey: "frontOfQueue", Method: "POST", URI: "/v1/getjobqueuesnapshot"}, + "ListConsumableResources": {Verb: "List", Resource: "ConsumableResource", OutputListKey: "consumableResources", OutputItemKey: "", Method: "POST", URI: "/v1/listconsumableresources"}, + "ListJobs": {Verb: "List", Resource: "Job", OutputListKey: "jobSummaryList", OutputItemKey: "", Method: "POST", URI: "/v1/listjobs"}, + "ListJobsByConsumableResource": {Verb: "List", Resource: "JobsByConsumableResource", OutputListKey: "jobs", OutputItemKey: "", Method: "POST", URI: "/v1/listjobsbyconsumableresource"}, + "ListQuotaShares": {Verb: "List", Resource: "QuotaShare", OutputListKey: "quotaShares", OutputItemKey: "", Method: "POST", URI: "/v1/listquotashares"}, + "ListSchedulingPolicies": {Verb: "List", Resource: "SchedulingPolicy", OutputListKey: "schedulingPolicies", OutputItemKey: "", Method: "POST", URI: "/v1/listschedulingpolicies"}, + "ListServiceJobs": {Verb: "List", Resource: "ServiceJob", OutputListKey: "jobSummaryList", OutputItemKey: "", Method: "POST", URI: "/v1/listservicejobs"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/tags/{resourceArn}"}, + "RegisterJobDefinition": {Verb: "Create", Resource: "JobDefinition", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/registerjobdefinition"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{resourceArn}"}, + "UpdateComputeEnvironment": {Verb: "Update", Resource: "ComputeEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updatecomputeenvironment"}, + "UpdateConsumableResource": {Verb: "Update", Resource: "ConsumableResource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updateconsumableresource"}, + "UpdateJobQueue": {Verb: "Update", Resource: "JobQueue", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updatejobqueue"}, + "UpdateQuotaShare": {Verb: "Update", Resource: "QuotaShare", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updatequotashare"}, + "UpdateSchedulingPolicy": {Verb: "Update", Resource: "SchedulingPolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updateschedulingpolicy"}, + "UpdateServiceEnvironment": {Verb: "Update", Resource: "ServiceEnvironment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updateserviceenvironment"}, + "UpdateServiceJob": {Verb: "Update", Resource: "ServiceJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/updateservicejob"}, + }) + crud.Register("bedrock", map[string]crud.OpMeta{ + "CreateAutomatedReasoningPolicy": {Verb: "Create", Resource: "AutomatedReasoningPolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/automated-reasoning-policies"}, + "CreateAutomatedReasoningPolicyTestCase": {Verb: "Create", Resource: "AutomatedReasoningPolicyTestCase", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/automated-reasoning-policies/{policyArn}/test-cases"}, + "CreateAutomatedReasoningPolicyVersion": {Verb: "Create", Resource: "AutomatedReasoningPolicyVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/automated-reasoning-policies/{policyArn}/versions"}, + "CreateCustomModel": {Verb: "Create", Resource: "CustomModel", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/custom-models/create-custom-model"}, + "CreateCustomModelDeployment": {Verb: "Create", Resource: "CustomModelDeployment", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/model-customization/custom-model-deployments"}, + "CreateEvaluationJob": {Verb: "Create", Resource: "EvaluationJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/evaluation-jobs"}, + "CreateFoundationModelAgreement": {Verb: "Create", Resource: "FoundationModelAgreement", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/create-foundation-model-agreement"}, + "CreateGuardrail": {Verb: "Create", Resource: "Guardrail", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/guardrails"}, + "CreateGuardrailVersion": {Verb: "Create", Resource: "GuardrailVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/guardrails/{guardrailIdentifier}"}, + "CreateInferenceProfile": {Verb: "Create", Resource: "InferenceProfile", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/inference-profiles"}, + "CreateMarketplaceModelEndpoint": {Verb: "Create", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "marketplaceModelEndpoint", Method: "POST", URI: "/marketplace-model/endpoints"}, + "CreateModelCopyJob": {Verb: "Create", Resource: "ModelCopyJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/model-copy-jobs"}, + "CreateModelCustomizationJob": {Verb: "Create", Resource: "ModelCustomizationJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/model-customization-jobs"}, + "CreateModelImportJob": {Verb: "Create", Resource: "ModelImportJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/model-import-jobs"}, + "CreateModelInvocationJob": {Verb: "Create", Resource: "ModelInvocationJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/model-invocation-job"}, + "CreatePromptRouter": {Verb: "Create", Resource: "PromptRouter", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/prompt-routers"}, + "CreateProvisionedModelThroughput": {Verb: "Create", Resource: "ProvisionedModelThroughput", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/provisioned-model-throughput"}, + "DeleteAutomatedReasoningPolicy": {Verb: "Delete", Resource: "AutomatedReasoningPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/automated-reasoning-policies/{policyArn}"}, + "DeleteAutomatedReasoningPolicyBuildWorkflow": {Verb: "Delete", Resource: "AutomatedReasoningPolicyBuildWorkflow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}"}, + "DeleteAutomatedReasoningPolicyTestCase": {Verb: "Delete", Resource: "AutomatedReasoningPolicyTestCase", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/automated-reasoning-policies/{policyArn}/test-cases/{testCaseId}"}, + "DeleteCustomModel": {Verb: "Delete", Resource: "CustomModel", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/custom-models/{modelIdentifier}"}, + "DeleteCustomModelDeployment": {Verb: "Delete", Resource: "CustomModelDeployment", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/model-customization/custom-model-deployments/{customModelDeploymentIdentifier}"}, + "DeleteEnforcedGuardrailConfiguration": {Verb: "Delete", Resource: "EnforcedGuardrailConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/enforcedGuardrailsConfiguration/{configId}"}, + "DeleteFoundationModelAgreement": {Verb: "Delete", Resource: "FoundationModelAgreement", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/delete-foundation-model-agreement"}, + "DeleteGuardrail": {Verb: "Delete", Resource: "Guardrail", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/guardrails/{guardrailIdentifier}"}, + "DeleteImportedModel": {Verb: "Delete", Resource: "ImportedModel", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/imported-models/{modelIdentifier}"}, + "DeleteInferenceProfile": {Verb: "Delete", Resource: "InferenceProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/inference-profiles/{inferenceProfileIdentifier}"}, + "DeleteMarketplaceModelEndpoint": {Verb: "Delete", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/marketplace-model/endpoints/{endpointArn}"}, + "DeleteModelInvocationLoggingConfiguration": {Verb: "Delete", Resource: "ModelInvocationLoggingConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/logging/modelinvocations"}, + "DeletePromptRouter": {Verb: "Delete", Resource: "PromptRouter", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/prompt-routers/{promptRouterArn}"}, + "DeleteProvisionedModelThroughput": {Verb: "Delete", Resource: "ProvisionedModelThroughput", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/provisioned-model-throughput/{provisionedModelId}"}, + "DeleteResourcePolicy": {Verb: "Delete", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/resource-policy/{resourceArn}"}, + "DeregisterMarketplaceModelEndpoint": {Verb: "Delete", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/marketplace-model/endpoints/{endpointArn}/registration"}, + "GetAutomatedReasoningPolicy": {Verb: "Get", Resource: "AutomatedReasoningPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}"}, + "GetAutomatedReasoningPolicyAnnotations": {Verb: "Get", Resource: "AutomatedReasoningPolicyAnnotation", OutputListKey: "annotations", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/annotations"}, + "GetAutomatedReasoningPolicyBuildWorkflow": {Verb: "Get", Resource: "AutomatedReasoningPolicyBuildWorkflow", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}"}, + "GetAutomatedReasoningPolicyBuildWorkflowResultAssets": {Verb: "Get", Resource: "AutomatedReasoningPolicyBuildWorkflowResultAsset", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/result-assets"}, + "GetAutomatedReasoningPolicyNextScenario": {Verb: "Get", Resource: "AutomatedReasoningPolicyNextScenario", OutputListKey: "", OutputItemKey: "scenario", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/scenarios"}, + "GetAutomatedReasoningPolicyTestCase": {Verb: "Get", Resource: "AutomatedReasoningPolicyTestCase", OutputListKey: "", OutputItemKey: "testCase", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/test-cases/{testCaseId}"}, + "GetAutomatedReasoningPolicyTestResult": {Verb: "Get", Resource: "AutomatedReasoningPolicyTestResult", OutputListKey: "", OutputItemKey: "testResult", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/test-cases/{testCaseId}/test-results"}, + "GetCustomModel": {Verb: "Get", Resource: "CustomModel", OutputListKey: "validationMetrics", OutputItemKey: "outputDataConfig", Method: "GET", URI: "/custom-models/{modelIdentifier}"}, + "GetCustomModelDeployment": {Verb: "Get", Resource: "CustomModelDeployment", OutputListKey: "", OutputItemKey: "updateDetails", Method: "GET", URI: "/model-customization/custom-model-deployments/{customModelDeploymentIdentifier}"}, + "GetEvaluationJob": {Verb: "Get", Resource: "EvaluationJob", OutputListKey: "failureMessages", OutputItemKey: "outputDataConfig", Method: "GET", URI: "/evaluation-jobs/{jobIdentifier}"}, + "GetFoundationModel": {Verb: "Get", Resource: "FoundationModel", OutputListKey: "", OutputItemKey: "modelDetails", Method: "GET", URI: "/foundation-models/{modelIdentifier}"}, + "GetFoundationModelAvailability": {Verb: "Get", Resource: "FoundationModelAvailability", OutputListKey: "", OutputItemKey: "agreementAvailability", Method: "GET", URI: "/foundation-model-availability/{modelId}"}, + "GetGuardrail": {Verb: "Get", Resource: "Guardrail", OutputListKey: "failureRecommendations", OutputItemKey: "automatedReasoningPolicy", Method: "GET", URI: "/guardrails/{guardrailIdentifier}"}, + "GetImportedModel": {Verb: "Get", Resource: "ImportedModel", OutputListKey: "", OutputItemKey: "customModelUnits", Method: "GET", URI: "/imported-models/{modelIdentifier}"}, + "GetInferenceProfile": {Verb: "Get", Resource: "InferenceProfile", OutputListKey: "models", OutputItemKey: "", Method: "GET", URI: "/inference-profiles/{inferenceProfileIdentifier}"}, + "GetMarketplaceModelEndpoint": {Verb: "Get", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "marketplaceModelEndpoint", Method: "GET", URI: "/marketplace-model/endpoints/{endpointArn}"}, + "GetModelCopyJob": {Verb: "Get", Resource: "ModelCopyJob", OutputListKey: "targetModelTags", OutputItemKey: "", Method: "GET", URI: "/model-copy-jobs/{jobArn}"}, + "GetModelCustomizationJob": {Verb: "Get", Resource: "ModelCustomizationJob", OutputListKey: "validationMetrics", OutputItemKey: "outputDataConfig", Method: "GET", URI: "/model-customization-jobs/{jobIdentifier}"}, + "GetModelImportJob": {Verb: "Get", Resource: "ModelImportJob", OutputListKey: "", OutputItemKey: "vpcConfig", Method: "GET", URI: "/model-import-jobs/{jobIdentifier}"}, + "GetModelInvocationJob": {Verb: "Get", Resource: "ModelInvocationJob", OutputListKey: "", OutputItemKey: "vpcConfig", Method: "GET", URI: "/model-invocation-job/{jobIdentifier}"}, + "GetModelInvocationLoggingConfiguration": {Verb: "Get", Resource: "ModelInvocationLoggingConfiguration", OutputListKey: "", OutputItemKey: "loggingConfig", Method: "GET", URI: "/logging/modelinvocations"}, + "GetPromptRouter": {Verb: "Get", Resource: "PromptRouter", OutputListKey: "models", OutputItemKey: "fallbackModel", Method: "GET", URI: "/prompt-routers/{promptRouterArn}"}, + "GetProvisionedModelThroughput": {Verb: "Get", Resource: "ProvisionedModelThroughput", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/provisioned-model-throughput/{provisionedModelId}"}, + "GetResourcePolicy": {Verb: "Get", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resource-policy/{resourceArn}"}, + "GetUseCaseForModelAccess": {Verb: "Get", Resource: "UseCaseForModelAccess", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/use-case-for-model-access"}, + "ListAutomatedReasoningPolicies": {Verb: "List", Resource: "AutomatedReasoningPolicy", OutputListKey: "automatedReasoningPolicySummaries", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies"}, + "ListAutomatedReasoningPolicyBuildWorkflows": {Verb: "List", Resource: "AutomatedReasoningPolicyBuildWorkflow", OutputListKey: "automatedReasoningPolicyBuildWorkflowSummaries", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows"}, + "ListAutomatedReasoningPolicyTestCases": {Verb: "List", Resource: "AutomatedReasoningPolicyTestCase", OutputListKey: "testCases", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/test-cases"}, + "ListAutomatedReasoningPolicyTestResults": {Verb: "List", Resource: "AutomatedReasoningPolicyTestResult", OutputListKey: "testResults", OutputItemKey: "", Method: "GET", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/test-results"}, + "ListCustomModelDeployments": {Verb: "List", Resource: "CustomModelDeployment", OutputListKey: "modelDeploymentSummaries", OutputItemKey: "", Method: "GET", URI: "/model-customization/custom-model-deployments"}, + "ListCustomModels": {Verb: "List", Resource: "CustomModel", OutputListKey: "modelSummaries", OutputItemKey: "", Method: "GET", URI: "/custom-models"}, + "ListEnforcedGuardrailsConfiguration": {Verb: "List", Resource: "EnforcedGuardrailsConfiguration", OutputListKey: "guardrailsConfig", OutputItemKey: "", Method: "GET", URI: "/enforcedGuardrailsConfiguration"}, + "ListEvaluationJobs": {Verb: "List", Resource: "EvaluationJob", OutputListKey: "jobSummaries", OutputItemKey: "", Method: "GET", URI: "/evaluation-jobs"}, + "ListFoundationModelAgreementOffers": {Verb: "List", Resource: "FoundationModelAgreementOffer", OutputListKey: "offers", OutputItemKey: "", Method: "GET", URI: "/list-foundation-model-agreement-offers/{modelId}"}, + "ListFoundationModels": {Verb: "List", Resource: "FoundationModel", OutputListKey: "modelSummaries", OutputItemKey: "", Method: "GET", URI: "/foundation-models"}, + "ListGuardrails": {Verb: "List", Resource: "Guardrail", OutputListKey: "guardrails", OutputItemKey: "", Method: "GET", URI: "/guardrails"}, + "ListImportedModels": {Verb: "List", Resource: "ImportedModel", OutputListKey: "modelSummaries", OutputItemKey: "", Method: "GET", URI: "/imported-models"}, + "ListInferenceProfiles": {Verb: "List", Resource: "InferenceProfile", OutputListKey: "inferenceProfileSummaries", OutputItemKey: "", Method: "GET", URI: "/inference-profiles"}, + "ListMarketplaceModelEndpoints": {Verb: "List", Resource: "MarketplaceModelEndpoint", OutputListKey: "marketplaceModelEndpoints", OutputItemKey: "", Method: "GET", URI: "/marketplace-model/endpoints"}, + "ListModelCopyJobs": {Verb: "List", Resource: "ModelCopyJob", OutputListKey: "modelCopyJobSummaries", OutputItemKey: "", Method: "GET", URI: "/model-copy-jobs"}, + "ListModelCustomizationJobs": {Verb: "List", Resource: "ModelCustomizationJob", OutputListKey: "modelCustomizationJobSummaries", OutputItemKey: "", Method: "GET", URI: "/model-customization-jobs"}, + "ListModelImportJobs": {Verb: "List", Resource: "ModelImportJob", OutputListKey: "modelImportJobSummaries", OutputItemKey: "", Method: "GET", URI: "/model-import-jobs"}, + "ListModelInvocationJobs": {Verb: "List", Resource: "ModelInvocationJob", OutputListKey: "invocationJobSummaries", OutputItemKey: "", Method: "GET", URI: "/model-invocation-jobs"}, + "ListPromptRouters": {Verb: "List", Resource: "PromptRouter", OutputListKey: "promptRouterSummaries", OutputItemKey: "", Method: "GET", URI: "/prompt-routers"}, + "ListProvisionedModelThroughputs": {Verb: "List", Resource: "ProvisionedModelThroughput", OutputListKey: "provisionedModelSummaries", OutputItemKey: "", Method: "GET", URI: "/provisioned-model-throughputs"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "POST", URI: "/listTagsForResource"}, + "PutEnforcedGuardrailConfiguration": {Verb: "Update", Resource: "EnforcedGuardrailConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/enforcedGuardrailsConfiguration"}, + "PutModelInvocationLoggingConfiguration": {Verb: "Update", Resource: "ModelInvocationLoggingConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/logging/modelinvocations"}, + "PutResourcePolicy": {Verb: "Update", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/resource-policy"}, + "PutUseCaseForModelAccess": {Verb: "Update", Resource: "UseCaseForModelAccess", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/use-case-for-model-access"}, + "RegisterMarketplaceModelEndpoint": {Verb: "Create", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "marketplaceModelEndpoint", Method: "POST", URI: "/marketplace-model/endpoints/{endpointIdentifier}/registration"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tagResource"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/untagResource"}, + "UpdateAutomatedReasoningPolicy": {Verb: "Update", Resource: "AutomatedReasoningPolicy", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/automated-reasoning-policies/{policyArn}"}, + "UpdateAutomatedReasoningPolicyAnnotations": {Verb: "Update", Resource: "AutomatedReasoningPolicyAnnotation", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/automated-reasoning-policies/{policyArn}/build-workflows/{buildWorkflowId}/annotations"}, + "UpdateAutomatedReasoningPolicyTestCase": {Verb: "Update", Resource: "AutomatedReasoningPolicyTestCase", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/automated-reasoning-policies/{policyArn}/test-cases/{testCaseId}"}, + "UpdateCustomModelDeployment": {Verb: "Update", Resource: "CustomModelDeployment", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/model-customization/custom-model-deployments/{customModelDeploymentIdentifier}"}, + "UpdateGuardrail": {Verb: "Update", Resource: "Guardrail", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/guardrails/{guardrailIdentifier}"}, + "UpdateMarketplaceModelEndpoint": {Verb: "Update", Resource: "MarketplaceModelEndpoint", OutputListKey: "", OutputItemKey: "marketplaceModelEndpoint", Method: "PATCH", URI: "/marketplace-model/endpoints/{endpointArn}"}, + "UpdateProvisionedModelThroughput": {Verb: "Update", Resource: "ProvisionedModelThroughput", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/provisioned-model-throughput/{provisionedModelId}"}, + }) + crud.Register("bedrockagent", map[string]crud.OpMeta{ + "CreateAgent": {Verb: "Create", Resource: "Agent", OutputListKey: "", OutputItemKey: "agent", Method: "PUT", URI: "/agents/"}, + "CreateAgentActionGroup": {Verb: "Create", Resource: "AgentActionGroup", OutputListKey: "", OutputItemKey: "agentActionGroup", Method: "PUT", URI: "/agents/{agentId}/agentversions/{agentVersion}/actiongroups/"}, + "CreateAgentAlias": {Verb: "Create", Resource: "AgentAlia", OutputListKey: "", OutputItemKey: "agentAlias", Method: "PUT", URI: "/agents/{agentId}/agentaliases/"}, + "CreateDataSource": {Verb: "Create", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "PUT", URI: "/knowledgebases/{knowledgeBaseId}/datasources/"}, + "CreateFlow": {Verb: "Create", Resource: "Flow", OutputListKey: "", OutputItemKey: "definition", Method: "POST", URI: "/flows/"}, + "CreateFlowAlias": {Verb: "Create", Resource: "FlowAlia", OutputListKey: "routingConfiguration", OutputItemKey: "concurrencyConfiguration", Method: "POST", URI: "/flows/{flowIdentifier}/aliases"}, + "CreateFlowVersion": {Verb: "Create", Resource: "FlowVersion", OutputListKey: "", OutputItemKey: "definition", Method: "POST", URI: "/flows/{flowIdentifier}/versions"}, + "CreateKnowledgeBase": {Verb: "Create", Resource: "KnowledgeBase", OutputListKey: "", OutputItemKey: "knowledgeBase", Method: "PUT", URI: "/knowledgebases/"}, + "CreatePrompt": {Verb: "Create", Resource: "Prompt", OutputListKey: "variants", OutputItemKey: "", Method: "POST", URI: "/prompts/"}, + "CreatePromptVersion": {Verb: "Create", Resource: "PromptVersion", OutputListKey: "variants", OutputItemKey: "", Method: "POST", URI: "/prompts/{promptIdentifier}/versions"}, + "DeleteAgent": {Verb: "Delete", Resource: "Agent", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/agents/{agentId}/"}, + "DeleteAgentActionGroup": {Verb: "Delete", Resource: "AgentActionGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/agents/{agentId}/agentversions/{agentVersion}/actiongroups/{actionGroupId}/"}, + "DeleteAgentAlias": {Verb: "Delete", Resource: "AgentAlia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/agents/{agentId}/agentaliases/{agentAliasId}/"}, + "DeleteAgentVersion": {Verb: "Delete", Resource: "AgentVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/agents/{agentId}/agentversions/{agentVersion}/"}, + "DeleteDataSource": {Verb: "Delete", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}"}, + "DeleteFlow": {Verb: "Delete", Resource: "Flow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/flows/{flowIdentifier}/"}, + "DeleteFlowAlias": {Verb: "Delete", Resource: "FlowAlia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/flows/{flowIdentifier}/aliases/{aliasIdentifier}"}, + "DeleteFlowVersion": {Verb: "Delete", Resource: "FlowVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/flows/{flowIdentifier}/versions/{flowVersion}/"}, + "DeleteKnowledgeBase": {Verb: "Delete", Resource: "KnowledgeBase", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/knowledgebases/{knowledgeBaseId}"}, + "DeleteKnowledgeBaseDocuments": {Verb: "Delete", Resource: "KnowledgeBaseDocument", OutputListKey: "documentDetails", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/documents/deleteDocuments"}, + "DeletePrompt": {Verb: "Delete", Resource: "Prompt", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/prompts/{promptIdentifier}/"}, + "DeleteResourcePolicy": {Verb: "Delete", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/resourcepolicy/{resourceArn}"}, + "GetAgent": {Verb: "Get", Resource: "Agent", OutputListKey: "", OutputItemKey: "agent", Method: "GET", URI: "/agents/{agentId}/"}, + "GetAgentActionGroup": {Verb: "Get", Resource: "AgentActionGroup", OutputListKey: "", OutputItemKey: "agentActionGroup", Method: "GET", URI: "/agents/{agentId}/agentversions/{agentVersion}/actiongroups/{actionGroupId}/"}, + "GetAgentAlias": {Verb: "Get", Resource: "AgentAlia", OutputListKey: "", OutputItemKey: "agentAlias", Method: "GET", URI: "/agents/{agentId}/agentaliases/{agentAliasId}/"}, + "GetAgentCollaborator": {Verb: "Get", Resource: "AgentCollaborator", OutputListKey: "", OutputItemKey: "agentCollaborator", Method: "GET", URI: "/agents/{agentId}/agentversions/{agentVersion}/agentcollaborators/{collaboratorId}/"}, + "GetAgentKnowledgeBase": {Verb: "Get", Resource: "AgentKnowledgeBase", OutputListKey: "", OutputItemKey: "agentKnowledgeBase", Method: "GET", URI: "/agents/{agentId}/agentversions/{agentVersion}/knowledgebases/{knowledgeBaseId}/"}, + "GetAgentVersion": {Verb: "Get", Resource: "AgentVersion", OutputListKey: "", OutputItemKey: "agentVersion", Method: "GET", URI: "/agents/{agentId}/agentversions/{agentVersion}/"}, + "GetDataSource": {Verb: "Get", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "GET", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}"}, + "GetFlow": {Verb: "Get", Resource: "Flow", OutputListKey: "validations", OutputItemKey: "definition", Method: "GET", URI: "/flows/{flowIdentifier}/"}, + "GetFlowAlias": {Verb: "Get", Resource: "FlowAlia", OutputListKey: "routingConfiguration", OutputItemKey: "concurrencyConfiguration", Method: "GET", URI: "/flows/{flowIdentifier}/aliases/{aliasIdentifier}"}, + "GetFlowVersion": {Verb: "Get", Resource: "FlowVersion", OutputListKey: "", OutputItemKey: "definition", Method: "GET", URI: "/flows/{flowIdentifier}/versions/{flowVersion}/"}, + "GetIngestionJob": {Verb: "Get", Resource: "IngestionJob", OutputListKey: "", OutputItemKey: "ingestionJob", Method: "GET", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/ingestionjobs/{ingestionJobId}"}, + "GetKnowledgeBase": {Verb: "Get", Resource: "KnowledgeBase", OutputListKey: "", OutputItemKey: "knowledgeBase", Method: "GET", URI: "/knowledgebases/{knowledgeBaseId}"}, + "GetKnowledgeBaseDocuments": {Verb: "Get", Resource: "KnowledgeBaseDocument", OutputListKey: "documentDetails", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/documents/getDocuments"}, + "GetPrompt": {Verb: "Get", Resource: "Prompt", OutputListKey: "variants", OutputItemKey: "", Method: "GET", URI: "/prompts/{promptIdentifier}/"}, + "GetResourcePolicy": {Verb: "Get", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resourcepolicy/{resourceArn}"}, + "ListAgentActionGroups": {Verb: "List", Resource: "AgentActionGroup", OutputListKey: "actionGroupSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/{agentId}/agentversions/{agentVersion}/actiongroups/"}, + "ListAgentAliases": {Verb: "List", Resource: "AgentAliase", OutputListKey: "agentAliasSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/{agentId}/agentaliases/"}, + "ListAgentCollaborators": {Verb: "List", Resource: "AgentCollaborator", OutputListKey: "agentCollaboratorSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/{agentId}/agentversions/{agentVersion}/agentcollaborators/"}, + "ListAgentKnowledgeBases": {Verb: "List", Resource: "AgentKnowledgeBase", OutputListKey: "agentKnowledgeBaseSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/{agentId}/agentversions/{agentVersion}/knowledgebases/"}, + "ListAgentVersions": {Verb: "List", Resource: "AgentVersion", OutputListKey: "agentVersionSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/{agentId}/agentversions/"}, + "ListAgents": {Verb: "List", Resource: "Agent", OutputListKey: "agentSummaries", OutputItemKey: "", Method: "POST", URI: "/agents/"}, + "ListDataSources": {Verb: "List", Resource: "DataSource", OutputListKey: "dataSourceSummaries", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/"}, + "ListFlowAliases": {Verb: "List", Resource: "FlowAliase", OutputListKey: "flowAliasSummaries", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/aliases"}, + "ListFlowVersions": {Verb: "List", Resource: "FlowVersion", OutputListKey: "flowVersionSummaries", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/versions"}, + "ListFlows": {Verb: "List", Resource: "Flow", OutputListKey: "flowSummaries", OutputItemKey: "", Method: "GET", URI: "/flows/"}, + "ListIngestionJobs": {Verb: "List", Resource: "IngestionJob", OutputListKey: "ingestionJobSummaries", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/ingestionjobs/"}, + "ListKnowledgeBaseDocuments": {Verb: "List", Resource: "KnowledgeBaseDocument", OutputListKey: "documentDetails", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/documents"}, + "ListKnowledgeBases": {Verb: "List", Resource: "KnowledgeBase", OutputListKey: "knowledgeBaseSummaries", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/"}, + "ListPrompts": {Verb: "List", Resource: "Prompt", OutputListKey: "promptSummaries", OutputItemKey: "", Method: "GET", URI: "/prompts/"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutResourcePolicy": {Verb: "Update", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/resourcepolicy/{resourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateAgent": {Verb: "Update", Resource: "Agent", OutputListKey: "", OutputItemKey: "agent", Method: "PUT", URI: "/agents/{agentId}/"}, + "UpdateAgentActionGroup": {Verb: "Update", Resource: "AgentActionGroup", OutputListKey: "", OutputItemKey: "agentActionGroup", Method: "PUT", URI: "/agents/{agentId}/agentversions/{agentVersion}/actiongroups/{actionGroupId}/"}, + "UpdateAgentAlias": {Verb: "Update", Resource: "AgentAlia", OutputListKey: "", OutputItemKey: "agentAlias", Method: "PUT", URI: "/agents/{agentId}/agentaliases/{agentAliasId}/"}, + "UpdateAgentCollaborator": {Verb: "Update", Resource: "AgentCollaborator", OutputListKey: "", OutputItemKey: "agentCollaborator", Method: "PUT", URI: "/agents/{agentId}/agentversions/{agentVersion}/agentcollaborators/{collaboratorId}/"}, + "UpdateAgentKnowledgeBase": {Verb: "Update", Resource: "AgentKnowledgeBase", OutputListKey: "", OutputItemKey: "agentKnowledgeBase", Method: "PUT", URI: "/agents/{agentId}/agentversions/{agentVersion}/knowledgebases/{knowledgeBaseId}/"}, + "UpdateDataSource": {Verb: "Update", Resource: "DataSource", OutputListKey: "", OutputItemKey: "dataSource", Method: "PUT", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}"}, + "UpdateFlow": {Verb: "Update", Resource: "Flow", OutputListKey: "", OutputItemKey: "definition", Method: "PUT", URI: "/flows/{flowIdentifier}/"}, + "UpdateFlowAlias": {Verb: "Update", Resource: "FlowAlia", OutputListKey: "routingConfiguration", OutputItemKey: "concurrencyConfiguration", Method: "PUT", URI: "/flows/{flowIdentifier}/aliases/{aliasIdentifier}"}, + "UpdateKnowledgeBase": {Verb: "Update", Resource: "KnowledgeBase", OutputListKey: "", OutputItemKey: "knowledgeBase", Method: "PUT", URI: "/knowledgebases/{knowledgeBaseId}"}, + "UpdatePrompt": {Verb: "Update", Resource: "Prompt", OutputListKey: "variants", OutputItemKey: "", Method: "PUT", URI: "/prompts/{promptIdentifier}/"}, + }) + crud.Register("bedrockagentcore", map[string]crud.OpMeta{ + "CreateABTest": {Verb: "Create", Resource: "ABTest", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/ab-tests"}, + "CreateEvent": {Verb: "Create", Resource: "Event", OutputListKey: "", OutputItemKey: "event", Method: "POST", URI: "/memories/{memoryId}/events"}, + "CreatePaymentInstrument": {Verb: "Create", Resource: "PaymentInstrument", OutputListKey: "", OutputItemKey: "paymentInstrument", Method: "POST", URI: "/payments/createPaymentInstrument"}, + "CreatePaymentSession": {Verb: "Create", Resource: "PaymentSession", OutputListKey: "", OutputItemKey: "paymentSession", Method: "POST", URI: "/payments/createPaymentSession"}, + "DeleteABTest": {Verb: "Delete", Resource: "ABTest", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/ab-tests/{abTestId}"}, + "DeleteBatchEvaluation": {Verb: "Delete", Resource: "BatchEvaluation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/evaluations/batch-evaluate/{batchEvaluationId}"}, + "DeleteCapacityProviderSession": {Verb: "Delete", Resource: "CapacityProviderSession", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/capacity-providers/{capacityProviderId}/sessions/{sessionId}"}, + "DeleteEvent": {Verb: "Delete", Resource: "Event", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/memories/{memoryId}/actor/{actorId}/sessions/{sessionId}/events/{eventId}"}, + "DeleteMemoryRecord": {Verb: "Delete", Resource: "MemoryRecord", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/memories/{memoryId}/memoryRecords/{memoryRecordId}"}, + "DeletePaymentInstrument": {Verb: "Delete", Resource: "PaymentInstrument", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/payments/deletePaymentInstrument"}, + "DeletePaymentSession": {Verb: "Delete", Resource: "PaymentSession", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/payments/deletePaymentSession"}, + "DeleteRecommendation": {Verb: "Delete", Resource: "Recommendation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/recommendations/{recommendationId}"}, + "GetABTest": {Verb: "Get", Resource: "ABTest", OutputListKey: "errorDetails", OutputItemKey: "gatewayFilter", Method: "GET", URI: "/ab-tests/{abTestId}"}, + "GetAgentCard": {Verb: "Get", Resource: "AgentCard", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/runtimes/{agentRuntimeArn}/invocations/.well-known/agent-card.json"}, + "GetBatchEvaluation": {Verb: "Get", Resource: "BatchEvaluation", OutputListKey: "errorDetails", OutputItemKey: "evaluationResults", Method: "GET", URI: "/evaluations/batch-evaluate/{batchEvaluationId}"}, + "GetBrowserSession": {Verb: "Get", Resource: "BrowserSession", OutputListKey: "certificates", OutputItemKey: "profileConfiguration", Method: "GET", URI: "/browsers/{browserIdentifier}/sessions/get"}, + "GetCodeInterpreterSession": {Verb: "Get", Resource: "CodeInterpreterSession", OutputListKey: "certificates", OutputItemKey: "", Method: "GET", URI: "/code-interpreters/{codeInterpreterIdentifier}/sessions/get"}, + "GetEvent": {Verb: "Get", Resource: "Event", OutputListKey: "", OutputItemKey: "event", Method: "GET", URI: "/memories/{memoryId}/actor/{actorId}/sessions/{sessionId}/events/{eventId}"}, + "GetMemoryRecord": {Verb: "Get", Resource: "MemoryRecord", OutputListKey: "", OutputItemKey: "memoryRecord", Method: "GET", URI: "/memories/{memoryId}/memoryRecord/{memoryRecordId}"}, + "GetPaymentInstrument": {Verb: "Get", Resource: "PaymentInstrument", OutputListKey: "", OutputItemKey: "paymentInstrument", Method: "POST", URI: "/payments/getPaymentInstrument"}, + "GetPaymentInstrumentBalance": {Verb: "Get", Resource: "PaymentInstrumentBalance", OutputListKey: "", OutputItemKey: "tokenBalance", Method: "POST", URI: "/payments/getPaymentInstrumentBalance"}, + "GetPaymentSession": {Verb: "Get", Resource: "PaymentSession", OutputListKey: "", OutputItemKey: "paymentSession", Method: "POST", URI: "/payments/getPaymentSession"}, + "GetRecommendation": {Verb: "Get", Resource: "Recommendation", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/recommendations/{recommendationId}"}, + "GetResourceApiKey": {Verb: "Get", Resource: "ResourceApiKey", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/api-key"}, + "GetResourceOauth2Token": {Verb: "Get", Resource: "ResourceOauth2Token", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/oauth2/token"}, + "GetResourcePaymentToken": {Verb: "Get", Resource: "ResourcePaymentToken", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/payment/token"}, + "GetWorkloadAccessToken": {Verb: "Get", Resource: "WorkloadAccessToken", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/GetWorkloadAccessToken"}, + "GetWorkloadAccessTokenForJWT": {Verb: "Get", Resource: "WorkloadAccessTokenForJWT", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/GetWorkloadAccessTokenForJWT"}, + "GetWorkloadAccessTokenForUserId": {Verb: "Get", Resource: "WorkloadAccessTokenForUserId", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/GetWorkloadAccessTokenForUserId"}, + "ListABTests": {Verb: "List", Resource: "ABTest", OutputListKey: "abTests", OutputItemKey: "", Method: "GET", URI: "/ab-tests"}, + "ListActors": {Verb: "List", Resource: "Actor", OutputListKey: "actorSummaries", OutputItemKey: "", Method: "POST", URI: "/memories/{memoryId}/actors"}, + "ListBatchEvaluations": {Verb: "List", Resource: "BatchEvaluation", OutputListKey: "batchEvaluations", OutputItemKey: "", Method: "GET", URI: "/evaluations/batch-evaluate"}, + "ListBrowserSessions": {Verb: "List", Resource: "BrowserSession", OutputListKey: "items", OutputItemKey: "", Method: "POST", URI: "/browsers/{browserIdentifier}/sessions/list"}, + "ListCodeInterpreterSessions": {Verb: "List", Resource: "CodeInterpreterSession", OutputListKey: "items", OutputItemKey: "", Method: "POST", URI: "/code-interpreters/{codeInterpreterIdentifier}/sessions/list"}, + "ListEvents": {Verb: "List", Resource: "Event", OutputListKey: "events", OutputItemKey: "", Method: "POST", URI: "/memories/{memoryId}/actor/{actorId}/sessions/{sessionId}"}, + "ListMemoryExtractionJobs": {Verb: "List", Resource: "MemoryExtractionJob", OutputListKey: "jobs", OutputItemKey: "", Method: "POST", URI: "/memories/{memoryId}/extractionJobs"}, + "ListMemoryRecords": {Verb: "List", Resource: "MemoryRecord", OutputListKey: "memoryRecordSummaries", OutputItemKey: "", Method: "POST", URI: "/memories/{memoryId}/memoryRecords"}, + "ListPaymentInstruments": {Verb: "List", Resource: "PaymentInstrument", OutputListKey: "paymentInstruments", OutputItemKey: "", Method: "POST", URI: "/payments/listPaymentInstruments"}, + "ListPaymentSessions": {Verb: "List", Resource: "PaymentSession", OutputListKey: "paymentSessions", OutputItemKey: "", Method: "POST", URI: "/payments/listPaymentSessions"}, + "ListRecommendations": {Verb: "List", Resource: "Recommendation", OutputListKey: "recommendationSummaries", OutputItemKey: "", Method: "GET", URI: "/recommendations"}, + "ListSessions": {Verb: "List", Resource: "Session", OutputListKey: "sessionSummaries", OutputItemKey: "", Method: "POST", URI: "/memories/{memoryId}/actor/{actorId}/sessions"}, + "UpdateABTest": {Verb: "Update", Resource: "ABTest", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/ab-tests/{abTestId}"}, + "UpdateBrowserStream": {Verb: "Update", Resource: "BrowserStream", OutputListKey: "", OutputItemKey: "streams", Method: "PUT", URI: "/browsers/{browserIdentifier}/sessions/streams/update"}, + }) + crud.Register("bedrockagentcorecontrol", map[string]crud.OpMeta{ + "CreateAgentRuntime": {Verb: "Create", Resource: "AgentRuntime", OutputListKey: "", OutputItemKey: "workloadIdentityDetails", Method: "PUT", URI: "/runtimes/"}, + "CreateAgentRuntimeEndpoint": {Verb: "Create", Resource: "AgentRuntimeEndpoint", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/runtimes/{agentRuntimeId}/runtime-endpoints/"}, + "CreateApiKeyCredentialProvider": {Verb: "Create", Resource: "ApiKeyCredentialProvider", OutputListKey: "", OutputItemKey: "apiKeySecretArn", Method: "POST", URI: "/identities/CreateApiKeyCredentialProvider"}, + "CreateBrowser": {Verb: "Create", Resource: "Browser", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/browsers"}, + "CreateBrowserProfile": {Verb: "Create", Resource: "BrowserProfile", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/browser-profiles"}, + "CreateCapacityProvider": {Verb: "Create", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/capacity-providers"}, + "CreateCodeInterpreter": {Verb: "Create", Resource: "CodeInterpreter", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/code-interpreters"}, + "CreateConfigurationBundle": {Verb: "Create", Resource: "ConfigurationBundle", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/configuration-bundles/create"}, + "CreateConsentPortal": {Verb: "Create", Resource: "ConsentPortal", OutputListKey: "sources", OutputItemKey: "idpConfig", Method: "POST", URI: "/identities/CreateConsentPortal"}, + "CreateDataset": {Verb: "Create", Resource: "Dataset", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/datasets"}, + "CreateDatasetVersion": {Verb: "Create", Resource: "DatasetVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/datasets/{datasetId}/versions"}, + "CreateEvaluator": {Verb: "Create", Resource: "Evaluator", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/evaluators/create"}, + "CreateGateway": {Verb: "Create", Resource: "Gateway", OutputListKey: "interceptorConfigurations", OutputItemKey: "customTransformConfiguration", Method: "POST", URI: "/gateways/"}, + "CreateGatewayRateLimit": {Verb: "Create", Resource: "GatewayRateLimit", OutputListKey: "dimensionKeys", OutputItemKey: "", Method: "POST", URI: "/gateways/{gatewayIdentifier}/rate-limits"}, + "CreateGatewayRule": {Verb: "Create", Resource: "GatewayRule", OutputListKey: "actions", OutputItemKey: "system", Method: "POST", URI: "/gateways/{gatewayIdentifier}/rules"}, + "CreateGatewayTarget": {Verb: "Create", Resource: "GatewayTarget", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "metadataConfiguration", Method: "POST", URI: "/gateways/{gatewayIdentifier}/targets/"}, + "CreateHarness": {Verb: "Create", Resource: "Harness", OutputListKey: "", OutputItemKey: "harness", Method: "POST", URI: "/harnesses"}, + "CreateHarnessEndpoint": {Verb: "Create", Resource: "HarnessEndpoint", OutputListKey: "", OutputItemKey: "endpoint", Method: "POST", URI: "/harnesses/{harnessId}/endpoints"}, + "CreateMemory": {Verb: "Create", Resource: "Memory", OutputListKey: "", OutputItemKey: "memory", Method: "POST", URI: "/memories/create"}, + "CreateOauth2CredentialProvider": {Verb: "Create", Resource: "Oauth2CredentialProvider", OutputListKey: "", OutputItemKey: "clientSecretArn", Method: "POST", URI: "/identities/CreateOauth2CredentialProvider"}, + "CreateOnlineEvaluationConfig": {Verb: "Create", Resource: "OnlineEvaluationConfig", OutputListKey: "", OutputItemKey: "outputConfig", Method: "POST", URI: "/online-evaluation-configs/create"}, + "CreatePaymentConnector": {Verb: "Create", Resource: "PaymentConnector", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "", Method: "POST", URI: "/payments/managers/{paymentManagerId}/connectors"}, + "CreatePaymentCredentialProvider": {Verb: "Create", Resource: "PaymentCredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/CreatePaymentCredentialProvider"}, + "CreatePaymentManager": {Verb: "Create", Resource: "PaymentManager", OutputListKey: "", OutputItemKey: "workloadIdentityDetails", Method: "POST", URI: "/payments/managers"}, + "CreatePolicy": {Verb: "Create", Resource: "Policy", OutputListKey: "statusReasons", OutputItemKey: "", Method: "POST", URI: "/policy-engines/{policyEngineId}/policies"}, + "CreatePolicyEngine": {Verb: "Create", Resource: "PolicyEngine", OutputListKey: "statusReasons", OutputItemKey: "", Method: "POST", URI: "/policy-engines"}, + "CreateRegistry": {Verb: "Create", Resource: "Registry", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/registries"}, + "CreateRegistryRecord": {Verb: "Create", Resource: "RegistryRecord", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/registries/{registryId}/records"}, + "CreateWorkloadIdentity": {Verb: "Create", Resource: "WorkloadIdentity", OutputListKey: "allowedResourceOauth2ReturnUrls", OutputItemKey: "", Method: "POST", URI: "/identities/CreateWorkloadIdentity"}, + "DeleteAgentRuntime": {Verb: "Delete", Resource: "AgentRuntime", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/runtimes/{agentRuntimeId}/"}, + "DeleteAgentRuntimeEndpoint": {Verb: "Delete", Resource: "AgentRuntimeEndpoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/runtimes/{agentRuntimeId}/runtime-endpoints/{endpointName}/"}, + "DeleteApiKeyCredentialProvider": {Verb: "Delete", Resource: "ApiKeyCredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/DeleteApiKeyCredentialProvider"}, + "DeleteBrowser": {Verb: "Delete", Resource: "Browser", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/browsers/{browserId}"}, + "DeleteBrowserProfile": {Verb: "Delete", Resource: "BrowserProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/browser-profiles/{profileId}"}, + "DeleteCapacityProvider": {Verb: "Delete", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/capacity-providers/{capacityProviderId}"}, + "DeleteCodeInterpreter": {Verb: "Delete", Resource: "CodeInterpreter", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/code-interpreters/{codeInterpreterId}"}, + "DeleteConfigurationBundle": {Verb: "Delete", Resource: "ConfigurationBundle", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/configuration-bundles/{bundleId}"}, + "DeleteConsentPortal": {Verb: "Delete", Resource: "ConsentPortal", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/DeleteConsentPortal"}, + "DeleteDataset": {Verb: "Delete", Resource: "Dataset", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/datasets/{datasetId}"}, + "DeleteDatasetExamples": {Verb: "Delete", Resource: "DatasetExample", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/datasets/{datasetId}/examples/delete"}, + "DeleteEvaluator": {Verb: "Delete", Resource: "Evaluator", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/evaluators/{evaluatorId}"}, + "DeleteGateway": {Verb: "Delete", Resource: "Gateway", OutputListKey: "statusReasons", OutputItemKey: "", Method: "DELETE", URI: "/gateways/{gatewayIdentifier}/"}, + "DeleteGatewayRateLimit": {Verb: "Delete", Resource: "GatewayRateLimit", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/gateways/{gatewayIdentifier}/rate-limits/{rateLimitId}"}, + "DeleteGatewayRule": {Verb: "Delete", Resource: "GatewayRule", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/gateways/{gatewayIdentifier}/rules/{ruleId}"}, + "DeleteGatewayTarget": {Verb: "Delete", Resource: "GatewayTarget", OutputListKey: "statusReasons", OutputItemKey: "", Method: "DELETE", URI: "/gateways/{gatewayIdentifier}/targets/{targetId}/"}, + "DeleteHarness": {Verb: "Delete", Resource: "Harness", OutputListKey: "", OutputItemKey: "harness", Method: "DELETE", URI: "/harnesses/{harnessId}"}, + "DeleteHarnessEndpoint": {Verb: "Delete", Resource: "HarnessEndpoint", OutputListKey: "", OutputItemKey: "endpoint", Method: "DELETE", URI: "/harnesses/{harnessId}/endpoints/{endpointName}"}, + "DeleteMemory": {Verb: "Delete", Resource: "Memory", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/memories/{memoryId}/delete"}, + "DeleteOauth2CredentialProvider": {Verb: "Delete", Resource: "Oauth2CredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/DeleteOauth2CredentialProvider"}, + "DeleteOnlineEvaluationConfig": {Verb: "Delete", Resource: "OnlineEvaluationConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/online-evaluation-configs/{onlineEvaluationConfigId}"}, + "DeletePaymentConnector": {Verb: "Delete", Resource: "PaymentConnector", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/payments/managers/{paymentManagerId}/connectors/{paymentConnectorId}"}, + "DeletePaymentCredentialProvider": {Verb: "Delete", Resource: "PaymentCredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/DeletePaymentCredentialProvider"}, + "DeletePaymentManager": {Verb: "Delete", Resource: "PaymentManager", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/payments/managers/{paymentManagerId}"}, + "DeletePolicy": {Verb: "Delete", Resource: "Policy", OutputListKey: "statusReasons", OutputItemKey: "", Method: "DELETE", URI: "/policy-engines/{policyEngineId}/policies/{policyId}"}, + "DeletePolicyEngine": {Verb: "Delete", Resource: "PolicyEngine", OutputListKey: "statusReasons", OutputItemKey: "", Method: "DELETE", URI: "/policy-engines/{policyEngineId}"}, + "DeleteRegistry": {Verb: "Delete", Resource: "Registry", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/registries/{registryId}"}, + "DeleteRegistryRecord": {Verb: "Delete", Resource: "RegistryRecord", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/registries/{registryId}/records/{recordId}"}, + "DeleteResourcePolicy": {Verb: "Delete", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/resourcepolicy/{resourceArn}"}, + "DeleteWorkloadIdentity": {Verb: "Delete", Resource: "WorkloadIdentity", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/DeleteWorkloadIdentity"}, + "GetAgentRuntime": {Verb: "Get", Resource: "AgentRuntime", OutputListKey: "filesystemConfigurations", OutputItemKey: "capacityProviderConfiguration", Method: "GET", URI: "/runtimes/{agentRuntimeId}/"}, + "GetAgentRuntimeEndpoint": {Verb: "Get", Resource: "AgentRuntimeEndpoint", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/runtimes/{agentRuntimeId}/runtime-endpoints/{endpointName}/"}, + "GetApiKeyCredentialProvider": {Verb: "Get", Resource: "ApiKeyCredentialProvider", OutputListKey: "", OutputItemKey: "apiKeySecretArn", Method: "POST", URI: "/identities/GetApiKeyCredentialProvider"}, + "GetBrowser": {Verb: "Get", Resource: "Browser", OutputListKey: "certificates", OutputItemKey: "browserSigning", Method: "GET", URI: "/browsers/{browserId}"}, + "GetBrowserProfile": {Verb: "Get", Resource: "BrowserProfile", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/browser-profiles/{profileId}"}, + "GetCapacityProvider": {Verb: "Get", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "permissionsConfiguration", Method: "GET", URI: "/capacity-providers/{capacityProviderId}"}, + "GetCodeInterpreter": {Verb: "Get", Resource: "CodeInterpreter", OutputListKey: "certificates", OutputItemKey: "networkConfiguration", Method: "GET", URI: "/code-interpreters/{codeInterpreterId}"}, + "GetConfigurationBundle": {Verb: "Get", Resource: "ConfigurationBundle", OutputListKey: "", OutputItemKey: "lineageMetadata", Method: "GET", URI: "/configuration-bundles/{bundleId}"}, + "GetConfigurationBundleVersion": {Verb: "Get", Resource: "ConfigurationBundleVersion", OutputListKey: "", OutputItemKey: "lineageMetadata", Method: "GET", URI: "/configuration-bundles/{bundleId}/versions/{versionId}"}, + "GetConsentPortal": {Verb: "Get", Resource: "ConsentPortal", OutputListKey: "sources", OutputItemKey: "idpConfig", Method: "POST", URI: "/identities/GetConsentPortal"}, + "GetDataset": {Verb: "Get", Resource: "Dataset", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/datasets/{datasetId}"}, + "GetEvaluator": {Verb: "Get", Resource: "Evaluator", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/evaluators/{evaluatorId}"}, + "GetGateway": {Verb: "Get", Resource: "Gateway", OutputListKey: "interceptorConfigurations", OutputItemKey: "customTransformConfiguration", Method: "GET", URI: "/gateways/{gatewayIdentifier}/"}, + "GetGatewayRateLimit": {Verb: "Get", Resource: "GatewayRateLimit", OutputListKey: "dimensionKeys", OutputItemKey: "", Method: "GET", URI: "/gateways/{gatewayIdentifier}/rate-limits/{rateLimitId}"}, + "GetGatewayRule": {Verb: "Get", Resource: "GatewayRule", OutputListKey: "actions", OutputItemKey: "system", Method: "GET", URI: "/gateways/{gatewayIdentifier}/rules/{ruleId}"}, + "GetGatewayTarget": {Verb: "Get", Resource: "GatewayTarget", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "metadataConfiguration", Method: "GET", URI: "/gateways/{gatewayIdentifier}/targets/{targetId}/"}, + "GetHarness": {Verb: "Get", Resource: "Harness", OutputListKey: "", OutputItemKey: "harness", Method: "GET", URI: "/harnesses/{harnessId}"}, + "GetHarnessEndpoint": {Verb: "Get", Resource: "HarnessEndpoint", OutputListKey: "", OutputItemKey: "endpoint", Method: "GET", URI: "/harnesses/{harnessId}/endpoints/{endpointName}"}, + "GetMemory": {Verb: "Get", Resource: "Memory", OutputListKey: "", OutputItemKey: "memory", Method: "GET", URI: "/memories/{memoryId}/details"}, + "GetOauth2CredentialProvider": {Verb: "Get", Resource: "Oauth2CredentialProvider", OutputListKey: "", OutputItemKey: "clientSecretArn", Method: "POST", URI: "/identities/GetOauth2CredentialProvider"}, + "GetOnlineEvaluationConfig": {Verb: "Get", Resource: "OnlineEvaluationConfig", OutputListKey: "evaluators", OutputItemKey: "clusteringConfig", Method: "GET", URI: "/online-evaluation-configs/{onlineEvaluationConfigId}"}, + "GetPaymentConnector": {Verb: "Get", Resource: "PaymentConnector", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "", Method: "GET", URI: "/payments/managers/{paymentManagerId}/connectors/{paymentConnectorId}"}, + "GetPaymentCredentialProvider": {Verb: "Get", Resource: "PaymentCredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/GetPaymentCredentialProvider"}, + "GetPaymentManager": {Verb: "Get", Resource: "PaymentManager", OutputListKey: "", OutputItemKey: "workloadIdentityDetails", Method: "GET", URI: "/payments/managers/{paymentManagerId}"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "statusReasons", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policies/{policyId}"}, + "GetPolicyEngine": {Verb: "Get", Resource: "PolicyEngine", OutputListKey: "statusReasons", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}"}, + "GetPolicyEngineSummary": {Verb: "Get", Resource: "PolicyEngineSummary", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policy-engine-summaries/{policyEngineId}"}, + "GetPolicyGeneration": {Verb: "Get", Resource: "PolicyGeneration", OutputListKey: "statusReasons", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-generations/{policyGenerationId}"}, + "GetPolicyGenerationSummary": {Verb: "Get", Resource: "PolicyGenerationSummary", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-generation-summaries/{policyGenerationId}"}, + "GetPolicySummary": {Verb: "Get", Resource: "PolicySummary", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-summaries/{policyId}"}, + "GetRegistry": {Verb: "Get", Resource: "Registry", OutputListKey: "", OutputItemKey: "approvalConfiguration", Method: "GET", URI: "/registries/{registryId}"}, + "GetRegistryRecord": {Verb: "Get", Resource: "RegistryRecord", OutputListKey: "", OutputItemKey: "descriptors", Method: "GET", URI: "/registries/{registryId}/records/{recordId}"}, + "GetResourcePolicy": {Verb: "Get", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resourcepolicy/{resourceArn}"}, + "GetTokenVault": {Verb: "Get", Resource: "TokenVault", OutputListKey: "", OutputItemKey: "kmsConfiguration", Method: "POST", URI: "/identities/get-token-vault"}, + "GetWorkloadIdentity": {Verb: "Get", Resource: "WorkloadIdentity", OutputListKey: "allowedResourceOauth2ReturnUrls", OutputItemKey: "", Method: "POST", URI: "/identities/GetWorkloadIdentity"}, + "ListAgentRuntimeEndpoints": {Verb: "List", Resource: "AgentRuntimeEndpoint", OutputListKey: "runtimeEndpoints", OutputItemKey: "", Method: "POST", URI: "/runtimes/{agentRuntimeId}/runtime-endpoints/"}, + "ListAgentRuntimeVersions": {Verb: "List", Resource: "AgentRuntimeVersion", OutputListKey: "agentRuntimes", OutputItemKey: "", Method: "POST", URI: "/runtimes/{agentRuntimeId}/versions/"}, + "ListAgentRuntimeVersionsByCapacityProvider": {Verb: "List", Resource: "AgentRuntimeVersionsByCapacityProvider", OutputListKey: "agentRuntimes", OutputItemKey: "", Method: "POST", URI: "/capacity-providers/{capacityProviderId}/runtime-versions"}, + "ListAgentRuntimes": {Verb: "List", Resource: "AgentRuntime", OutputListKey: "agentRuntimes", OutputItemKey: "", Method: "POST", URI: "/runtimes/"}, + "ListApiKeyCredentialProviders": {Verb: "List", Resource: "ApiKeyCredentialProvider", OutputListKey: "credentialProviders", OutputItemKey: "", Method: "POST", URI: "/identities/ListApiKeyCredentialProviders"}, + "ListBrowserProfiles": {Verb: "List", Resource: "BrowserProfile", OutputListKey: "profileSummaries", OutputItemKey: "", Method: "POST", URI: "/browser-profiles"}, + "ListBrowsers": {Verb: "List", Resource: "Browser", OutputListKey: "browserSummaries", OutputItemKey: "", Method: "POST", URI: "/browsers"}, + "ListCapacityProviders": {Verb: "List", Resource: "CapacityProvider", OutputListKey: "capacityProviders", OutputItemKey: "", Method: "POST", URI: "/capacity-providers"}, + "ListCodeInterpreters": {Verb: "List", Resource: "CodeInterpreter", OutputListKey: "codeInterpreterSummaries", OutputItemKey: "", Method: "POST", URI: "/code-interpreters"}, + "ListConfigurationBundleVersions": {Verb: "List", Resource: "ConfigurationBundleVersion", OutputListKey: "versions", OutputItemKey: "", Method: "POST", URI: "/configuration-bundles/{bundleId}/versions"}, + "ListConfigurationBundles": {Verb: "List", Resource: "ConfigurationBundle", OutputListKey: "bundles", OutputItemKey: "", Method: "POST", URI: "/configuration-bundles"}, + "ListConsentPortals": {Verb: "List", Resource: "ConsentPortal", OutputListKey: "consentPortals", OutputItemKey: "", Method: "POST", URI: "/identities/ListConsentPortals"}, + "ListDatasetExamples": {Verb: "List", Resource: "DatasetExample", OutputListKey: "examples", OutputItemKey: "", Method: "GET", URI: "/datasets/{datasetId}/examples"}, + "ListDatasetVersions": {Verb: "List", Resource: "DatasetVersion", OutputListKey: "versions", OutputItemKey: "", Method: "GET", URI: "/datasets/{datasetId}/versions"}, + "ListDatasets": {Verb: "List", Resource: "Dataset", OutputListKey: "datasets", OutputItemKey: "", Method: "GET", URI: "/datasets"}, + "ListEvaluators": {Verb: "List", Resource: "Evaluator", OutputListKey: "evaluators", OutputItemKey: "", Method: "POST", URI: "/evaluators"}, + "ListGatewayRateLimits": {Verb: "List", Resource: "GatewayRateLimit", OutputListKey: "rateLimits", OutputItemKey: "", Method: "GET", URI: "/gateways/{gatewayIdentifier}/rate-limits"}, + "ListGatewayRules": {Verb: "List", Resource: "GatewayRule", OutputListKey: "gatewayRules", OutputItemKey: "", Method: "GET", URI: "/gateways/{gatewayIdentifier}/rules"}, + "ListGatewayTargets": {Verb: "List", Resource: "GatewayTarget", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/gateways/{gatewayIdentifier}/targets/"}, + "ListGateways": {Verb: "List", Resource: "Gateway", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/gateways/"}, + "ListHarnessEndpoints": {Verb: "List", Resource: "HarnessEndpoint", OutputListKey: "endpoints", OutputItemKey: "", Method: "GET", URI: "/harnesses/{harnessId}/endpoints"}, + "ListHarnessVersions": {Verb: "List", Resource: "HarnessVersion", OutputListKey: "harnessVersions", OutputItemKey: "", Method: "GET", URI: "/harnesses/{harnessId}/versions"}, + "ListHarnesses": {Verb: "List", Resource: "Harness", OutputListKey: "harnesses", OutputItemKey: "", Method: "GET", URI: "/harnesses"}, + "ListMemories": {Verb: "List", Resource: "Memory", OutputListKey: "memories", OutputItemKey: "", Method: "POST", URI: "/memories/"}, + "ListOauth2CredentialProviders": {Verb: "List", Resource: "Oauth2CredentialProvider", OutputListKey: "credentialProviders", OutputItemKey: "", Method: "POST", URI: "/identities/ListOauth2CredentialProviders"}, + "ListOnlineEvaluationConfigs": {Verb: "List", Resource: "OnlineEvaluationConfig", OutputListKey: "onlineEvaluationConfigs", OutputItemKey: "", Method: "POST", URI: "/online-evaluation-configs"}, + "ListPaymentConnectors": {Verb: "List", Resource: "PaymentConnector", OutputListKey: "paymentConnectors", OutputItemKey: "", Method: "POST", URI: "/payments/managers/{paymentManagerId}/connectors-list"}, + "ListPaymentCredentialProviders": {Verb: "List", Resource: "PaymentCredentialProvider", OutputListKey: "credentialProviders", OutputItemKey: "", Method: "POST", URI: "/identities/ListPaymentCredentialProviders"}, + "ListPaymentManagers": {Verb: "List", Resource: "PaymentManager", OutputListKey: "paymentManagers", OutputItemKey: "", Method: "POST", URI: "/payments/managers-list"}, + "ListPolicies": {Verb: "List", Resource: "Policy", OutputListKey: "policies", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policies"}, + "ListPolicyEngineSummaries": {Verb: "List", Resource: "PolicyEngineSummary", OutputListKey: "policyEngines", OutputItemKey: "", Method: "GET", URI: "/policy-engine-summaries"}, + "ListPolicyEngines": {Verb: "List", Resource: "PolicyEngine", OutputListKey: "policyEngines", OutputItemKey: "", Method: "GET", URI: "/policy-engines"}, + "ListPolicyGenerationAssets": {Verb: "List", Resource: "PolicyGenerationAsset", OutputListKey: "policyGenerationAssets", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-generations/{policyGenerationId}/assets"}, + "ListPolicyGenerationSummaries": {Verb: "List", Resource: "PolicyGenerationSummary", OutputListKey: "policyGenerations", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-generation-summaries"}, + "ListPolicyGenerations": {Verb: "List", Resource: "PolicyGeneration", OutputListKey: "policyGenerations", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-generations"}, + "ListPolicySummaries": {Verb: "List", Resource: "PolicySummary", OutputListKey: "policies", OutputItemKey: "", Method: "GET", URI: "/policy-engines/{policyEngineId}/policy-summaries"}, + "ListRegistries": {Verb: "List", Resource: "Registry", OutputListKey: "registries", OutputItemKey: "", Method: "GET", URI: "/registries"}, + "ListRegistryRecords": {Verb: "List", Resource: "RegistryRecord", OutputListKey: "registryRecords", OutputItemKey: "", Method: "GET", URI: "/registries/{registryId}/records"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "ListWorkloadIdentities": {Verb: "List", Resource: "WorkloadIdentity", OutputListKey: "workloadIdentities", OutputItemKey: "", Method: "POST", URI: "/identities/ListWorkloadIdentities"}, + "PutResourcePolicy": {Verb: "Update", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/resourcepolicy/{resourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateAgentRuntime": {Verb: "Update", Resource: "AgentRuntime", OutputListKey: "", OutputItemKey: "workloadIdentityDetails", Method: "PUT", URI: "/runtimes/{agentRuntimeId}/"}, + "UpdateAgentRuntimeEndpoint": {Verb: "Update", Resource: "AgentRuntimeEndpoint", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/runtimes/{agentRuntimeId}/runtime-endpoints/{endpointName}/"}, + "UpdateApiKeyCredentialProvider": {Verb: "Update", Resource: "ApiKeyCredentialProvider", OutputListKey: "", OutputItemKey: "apiKeySecretArn", Method: "POST", URI: "/identities/UpdateApiKeyCredentialProvider"}, + "UpdateCapacityProvider": {Verb: "Update", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/capacity-providers/{capacityProviderId}"}, + "UpdateConfigurationBundle": {Verb: "Update", Resource: "ConfigurationBundle", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/configuration-bundles/{bundleId}"}, + "UpdateConsentPortal": {Verb: "Update", Resource: "ConsentPortal", OutputListKey: "sources", OutputItemKey: "idpConfig", Method: "POST", URI: "/identities/UpdateConsentPortal"}, + "UpdateDataset": {Verb: "Update", Resource: "Dataset", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/datasets/{datasetId}"}, + "UpdateDatasetExamples": {Verb: "Update", Resource: "DatasetExample", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/datasets/{datasetId}/examples/update"}, + "UpdateEvaluator": {Verb: "Update", Resource: "Evaluator", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/evaluators/{evaluatorId}"}, + "UpdateGateway": {Verb: "Update", Resource: "Gateway", OutputListKey: "interceptorConfigurations", OutputItemKey: "customTransformConfiguration", Method: "PUT", URI: "/gateways/{gatewayIdentifier}/"}, + "UpdateGatewayRateLimit": {Verb: "Update", Resource: "GatewayRateLimit", OutputListKey: "dimensionKeys", OutputItemKey: "", Method: "PATCH", URI: "/gateways/{gatewayIdentifier}/rate-limits/{rateLimitId}"}, + "UpdateGatewayRule": {Verb: "Update", Resource: "GatewayRule", OutputListKey: "actions", OutputItemKey: "system", Method: "PATCH", URI: "/gateways/{gatewayIdentifier}/rules/{ruleId}"}, + "UpdateGatewayTarget": {Verb: "Update", Resource: "GatewayTarget", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "metadataConfiguration", Method: "PUT", URI: "/gateways/{gatewayIdentifier}/targets/{targetId}/"}, + "UpdateHarness": {Verb: "Update", Resource: "Harness", OutputListKey: "", OutputItemKey: "harness", Method: "PATCH", URI: "/harnesses/{harnessId}"}, + "UpdateHarnessEndpoint": {Verb: "Update", Resource: "HarnessEndpoint", OutputListKey: "", OutputItemKey: "endpoint", Method: "PATCH", URI: "/harnesses/{harnessId}/endpoints/{endpointName}"}, + "UpdateMemory": {Verb: "Update", Resource: "Memory", OutputListKey: "", OutputItemKey: "memory", Method: "PUT", URI: "/memories/{memoryId}/update"}, + "UpdateOauth2CredentialProvider": {Verb: "Update", Resource: "Oauth2CredentialProvider", OutputListKey: "", OutputItemKey: "clientSecretArn", Method: "POST", URI: "/identities/UpdateOauth2CredentialProvider"}, + "UpdateOnlineEvaluationConfig": {Verb: "Update", Resource: "OnlineEvaluationConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/online-evaluation-configs/{onlineEvaluationConfigId}"}, + "UpdatePaymentConnector": {Verb: "Update", Resource: "PaymentConnector", OutputListKey: "credentialProviderConfigurations", OutputItemKey: "", Method: "PATCH", URI: "/payments/managers/{paymentManagerId}/connectors/{paymentConnectorId}"}, + "UpdatePaymentCredentialProvider": {Verb: "Update", Resource: "PaymentCredentialProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/identities/UpdatePaymentCredentialProvider"}, + "UpdatePaymentManager": {Verb: "Update", Resource: "PaymentManager", OutputListKey: "", OutputItemKey: "workloadIdentityDetails", Method: "PATCH", URI: "/payments/managers/{paymentManagerId}"}, + "UpdatePolicy": {Verb: "Update", Resource: "Policy", OutputListKey: "statusReasons", OutputItemKey: "", Method: "PATCH", URI: "/policy-engines/{policyEngineId}/policies/{policyId}"}, + "UpdatePolicyEngine": {Verb: "Update", Resource: "PolicyEngine", OutputListKey: "statusReasons", OutputItemKey: "", Method: "PATCH", URI: "/policy-engines/{policyEngineId}"}, + "UpdateRegistry": {Verb: "Update", Resource: "Registry", OutputListKey: "", OutputItemKey: "approvalConfiguration", Method: "PATCH", URI: "/registries/{registryId}"}, + "UpdateRegistryRecord": {Verb: "Update", Resource: "RegistryRecord", OutputListKey: "", OutputItemKey: "descriptors", Method: "PATCH", URI: "/registries/{registryId}/records/{recordId}"}, + "UpdateRegistryRecordStatus": {Verb: "Update", Resource: "RegistryRecordStatu", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/registries/{registryId}/records/{recordId}/status"}, + "UpdateWorkloadIdentity": {Verb: "Update", Resource: "WorkloadIdentity", OutputListKey: "allowedResourceOauth2ReturnUrls", OutputItemKey: "", Method: "POST", URI: "/identities/UpdateWorkloadIdentity"}, + }) + crud.Register("bedrockagentruntime", map[string]crud.OpMeta{ + "CreateInvocation": {Verb: "Create", Resource: "Invocation", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/sessions/{sessionIdentifier}/invocations/"}, + "CreateSession": {Verb: "Create", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/sessions/"}, + "DeleteAgentMemory": {Verb: "Delete", Resource: "AgentMemory", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/agents/{agentId}/agentAliases/{agentAliasId}/memories"}, + "DeleteSession": {Verb: "Delete", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/sessions/{sessionIdentifier}/"}, + "GetAgentMemory": {Verb: "Get", Resource: "AgentMemory", OutputListKey: "memoryContents", OutputItemKey: "", Method: "GET", URI: "/agents/{agentId}/agentAliases/{agentAliasId}/memories"}, + "GetDocumentContent": {Verb: "Get", Resource: "DocumentContent", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/documents/{documentId}/content"}, + "GetExecutionFlowSnapshot": {Verb: "Get", Resource: "ExecutionFlowSnapshot", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/aliases/{flowAliasIdentifier}/executions/{executionIdentifier}/flowsnapshot"}, + "GetFlowExecution": {Verb: "Get", Resource: "FlowExecution", OutputListKey: "errors", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/aliases/{flowAliasIdentifier}/executions/{executionIdentifier}"}, + "GetIngestedDocumentAcl": {Verb: "Get", Resource: "IngestedDocumentAcl", OutputListKey: "", OutputItemKey: "documentAcl", Method: "POST", URI: "/knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId}/get-ingested-document-acl"}, + "GetInvocationStep": {Verb: "Get", Resource: "InvocationStep", OutputListKey: "", OutputItemKey: "invocationStep", Method: "POST", URI: "/sessions/{sessionIdentifier}/invocationSteps/{invocationStepId}"}, + "GetSession": {Verb: "Get", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/sessions/{sessionIdentifier}/"}, + "ListFlowExecutionEvents": {Verb: "List", Resource: "FlowExecutionEvent", OutputListKey: "flowExecutionEvents", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/aliases/{flowAliasIdentifier}/executions/{executionIdentifier}/events"}, + "ListFlowExecutions": {Verb: "List", Resource: "FlowExecution", OutputListKey: "flowExecutionSummaries", OutputItemKey: "", Method: "GET", URI: "/flows/{flowIdentifier}/executions"}, + "ListInvocationSteps": {Verb: "List", Resource: "InvocationStep", OutputListKey: "invocationStepSummaries", OutputItemKey: "", Method: "POST", URI: "/sessions/{sessionIdentifier}/invocationSteps/"}, + "ListInvocations": {Verb: "List", Resource: "Invocation", OutputListKey: "invocationSummaries", OutputItemKey: "", Method: "POST", URI: "/sessions/{sessionIdentifier}/invocations/"}, + "ListSessions": {Verb: "List", Resource: "Session", OutputListKey: "sessionSummaries", OutputItemKey: "", Method: "POST", URI: "/sessions/"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutInvocationStep": {Verb: "Update", Resource: "InvocationStep", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/sessions/{sessionIdentifier}/invocationSteps/"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateSession": {Verb: "Update", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/sessions/{sessionIdentifier}/"}, + }) + crud.Register("bedrockdataautomation", map[string]crud.OpMeta{ + "CreateBlueprint": {Verb: "Create", Resource: "Blueprint", OutputListKey: "", OutputItemKey: "blueprint", Method: "PUT", URI: "/blueprints/"}, + "CreateBlueprintVersion": {Verb: "Create", Resource: "BlueprintVersion", OutputListKey: "", OutputItemKey: "blueprint", Method: "POST", URI: "/blueprints/{blueprintArn}/versions/"}, + "CreateDataAutomationLibrary": {Verb: "Create", Resource: "DataAutomationLibrary", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/data-automation-libraries/"}, + "CreateDataAutomationProject": {Verb: "Create", Resource: "DataAutomationProject", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/data-automation-projects/"}, + "DeleteBlueprint": {Verb: "Delete", Resource: "Blueprint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/blueprints/{blueprintArn}/"}, + "DeleteDataAutomationLibrary": {Verb: "Delete", Resource: "DataAutomationLibrary", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/data-automation-libraries/{libraryArn}/"}, + "DeleteDataAutomationProject": {Verb: "Delete", Resource: "DataAutomationProject", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/data-automation-projects/{projectArn}/"}, + "GetBlueprint": {Verb: "Get", Resource: "Blueprint", OutputListKey: "", OutputItemKey: "blueprint", Method: "POST", URI: "/blueprints/{blueprintArn}/"}, + "GetBlueprintOptimizationStatus": {Verb: "Get", Resource: "BlueprintOptimizationStatu", OutputListKey: "", OutputItemKey: "outputConfiguration", Method: "POST", URI: "/getBlueprintOptimizationStatus/{invocationArn}"}, + "GetDataAutomationLibrary": {Verb: "Get", Resource: "DataAutomationLibrary", OutputListKey: "", OutputItemKey: "library", Method: "POST", URI: "/data-automation-libraries/{libraryArn}/"}, + "GetDataAutomationLibraryEntity": {Verb: "Get", Resource: "DataAutomationLibraryEntity", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/data-automation-libraries/{libraryArn}/entityType/{entityType}/entities/{entityId}"}, + "GetDataAutomationLibraryIngestionJob": {Verb: "Get", Resource: "DataAutomationLibraryIngestionJob", OutputListKey: "", OutputItemKey: "job", Method: "POST", URI: "/data-automation-libraries/{libraryArn}/library-ingestion-jobs/{jobArn}"}, + "GetDataAutomationProject": {Verb: "Get", Resource: "DataAutomationProject", OutputListKey: "", OutputItemKey: "project", Method: "POST", URI: "/data-automation-projects/{projectArn}/"}, + "ListBlueprints": {Verb: "List", Resource: "Blueprint", OutputListKey: "blueprints", OutputItemKey: "", Method: "POST", URI: "/blueprints/"}, + "ListDataAutomationLibraries": {Verb: "List", Resource: "DataAutomationLibrary", OutputListKey: "libraries", OutputItemKey: "", Method: "POST", URI: "/data-automation-libraries/"}, + "ListDataAutomationLibraryEntities": {Verb: "List", Resource: "DataAutomationLibraryEntity", OutputListKey: "entities", OutputItemKey: "", Method: "POST", URI: "/data-automation-libraries/{libraryArn}/entityType/{entityType}/entities/"}, + "ListDataAutomationLibraryIngestionJobs": {Verb: "List", Resource: "DataAutomationLibraryIngestionJob", OutputListKey: "jobs", OutputItemKey: "", Method: "POST", URI: "/data-automation-libraries/{libraryArn}/library-ingestion-jobs/"}, + "ListDataAutomationProjects": {Verb: "List", Resource: "DataAutomationProject", OutputListKey: "projects", OutputItemKey: "", Method: "POST", URI: "/data-automation-projects/"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "POST", URI: "/listTagsForResource"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tagResource"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/untagResource"}, + "UpdateBlueprint": {Verb: "Update", Resource: "Blueprint", OutputListKey: "", OutputItemKey: "blueprint", Method: "PUT", URI: "/blueprints/{blueprintArn}/"}, + "UpdateDataAutomationLibrary": {Verb: "Update", Resource: "DataAutomationLibrary", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/data-automation-libraries/{libraryArn}/"}, + "UpdateDataAutomationProject": {Verb: "Update", Resource: "DataAutomationProject", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/data-automation-projects/{projectArn}/"}, + }) crud.Register("bedrockdataautomationruntime", map[string]crud.OpMeta{ "GetDataAutomationStatus": {Verb: "Get", Resource: "DataAutomationStatu", OutputListKey: "", OutputItemKey: "outputConfiguration"}, "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: ""}, "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("bedrockruntime", map[string]crud.OpMeta{ + "GetAsyncInvoke": {Verb: "Get", Resource: "AsyncInvoke", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/async-invoke/{invocationArn}"}, + "ListAsyncInvokes": {Verb: "List", Resource: "AsyncInvoke", OutputListKey: "asyncInvokeSummaries", OutputItemKey: "", Method: "GET", URI: "/async-invoke"}, + }) crud.Register("cloudtrail", map[string]crud.OpMeta{ "CreateChannel": {Verb: "Create", Resource: "Channel", OutputListKey: "Destinations", OutputItemKey: ""}, "CreateDashboard": {Verb: "Create", Resource: "Dashboard", OutputListKey: "TagsList", OutputItemKey: "RefreshSchedule"}, @@ -312,6 +1118,51 @@ func init() { "UpdateLookupTable": {Verb: "Update", Resource: "LookupTable", OutputListKey: "", OutputItemKey: ""}, "UpdateScheduledQuery": {Verb: "Update", Resource: "ScheduledQuery", OutputListKey: "logGroupIdentifiers", OutputItemKey: "destinationConfiguration"}, }) + crud.Register("codeartifact", map[string]crud.OpMeta{ + "CreateDomain": {Verb: "Create", Resource: "Domain", OutputListKey: "", OutputItemKey: "domain", Method: "POST", URI: "/v1/domain"}, + "CreatePackageGroup": {Verb: "Create", Resource: "PackageGroup", OutputListKey: "", OutputItemKey: "packageGroup", Method: "POST", URI: "/v1/package-group"}, + "CreateRepository": {Verb: "Create", Resource: "Repository", OutputListKey: "", OutputItemKey: "repository", Method: "POST", URI: "/v1/repository"}, + "DeleteDomain": {Verb: "Delete", Resource: "Domain", OutputListKey: "", OutputItemKey: "domain", Method: "DELETE", URI: "/v1/domain"}, + "DeleteDomainPermissionsPolicy": {Verb: "Delete", Resource: "DomainPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "DELETE", URI: "/v1/domain/permissions/policy"}, + "DeletePackage": {Verb: "Delete", Resource: "Package", OutputListKey: "", OutputItemKey: "deletedPackage", Method: "DELETE", URI: "/v1/package"}, + "DeletePackageGroup": {Verb: "Delete", Resource: "PackageGroup", OutputListKey: "", OutputItemKey: "packageGroup", Method: "DELETE", URI: "/v1/package-group"}, + "DeletePackageVersions": {Verb: "Delete", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/package/versions/delete"}, + "DeleteRepository": {Verb: "Delete", Resource: "Repository", OutputListKey: "", OutputItemKey: "repository", Method: "DELETE", URI: "/v1/repository"}, + "DeleteRepositoryPermissionsPolicy": {Verb: "Delete", Resource: "RepositoryPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "DELETE", URI: "/v1/repository/permissions/policies"}, + "DescribeDomain": {Verb: "Get", Resource: "Domain", OutputListKey: "", OutputItemKey: "domain", Method: "GET", URI: "/v1/domain"}, + "DescribePackage": {Verb: "Get", Resource: "Package", OutputListKey: "", OutputItemKey: "package", Method: "GET", URI: "/v1/package"}, + "DescribePackageGroup": {Verb: "Get", Resource: "PackageGroup", OutputListKey: "", OutputItemKey: "packageGroup", Method: "GET", URI: "/v1/package-group"}, + "DescribePackageVersion": {Verb: "Get", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "packageVersion", Method: "GET", URI: "/v1/package/version"}, + "DescribeRepository": {Verb: "Get", Resource: "Repository", OutputListKey: "", OutputItemKey: "repository", Method: "GET", URI: "/v1/repository"}, + "GetAssociatedPackageGroup": {Verb: "Get", Resource: "AssociatedPackageGroup", OutputListKey: "", OutputItemKey: "packageGroup", Method: "GET", URI: "/v1/get-associated-package-group"}, + "GetAuthorizationToken": {Verb: "Get", Resource: "AuthorizationToken", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/authorization-token"}, + "GetDomainPermissionsPolicy": {Verb: "Get", Resource: "DomainPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "GET", URI: "/v1/domain/permissions/policy"}, + "GetPackageVersionAsset": {Verb: "Get", Resource: "PackageVersionAsset", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/package/version/asset"}, + "GetPackageVersionReadme": {Verb: "Get", Resource: "PackageVersionReadme", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/package/version/readme"}, + "GetRepositoryEndpoint": {Verb: "Get", Resource: "RepositoryEndpoint", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/repository/endpoint"}, + "GetRepositoryPermissionsPolicy": {Verb: "Get", Resource: "RepositoryPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "GET", URI: "/v1/repository/permissions/policy"}, + "ListAllowedRepositoriesForGroup": {Verb: "List", Resource: "AllowedRepositoriesForGroup", OutputListKey: "allowedRepositories", OutputItemKey: "", Method: "GET", URI: "/v1/package-group-allowed-repositories"}, + "ListAssociatedPackages": {Verb: "List", Resource: "AssociatedPackage", OutputListKey: "packages", OutputItemKey: "", Method: "GET", URI: "/v1/list-associated-packages"}, + "ListDomains": {Verb: "List", Resource: "Domain", OutputListKey: "domains", OutputItemKey: "", Method: "POST", URI: "/v1/domains"}, + "ListPackageGroups": {Verb: "List", Resource: "PackageGroup", OutputListKey: "packageGroups", OutputItemKey: "", Method: "POST", URI: "/v1/package-groups"}, + "ListPackageVersionAssets": {Verb: "List", Resource: "PackageVersionAsset", OutputListKey: "assets", OutputItemKey: "", Method: "POST", URI: "/v1/package/version/assets"}, + "ListPackageVersionDependencies": {Verb: "List", Resource: "PackageVersionDependency", OutputListKey: "dependencies", OutputItemKey: "", Method: "POST", URI: "/v1/package/version/dependencies"}, + "ListPackageVersions": {Verb: "List", Resource: "PackageVersion", OutputListKey: "versions", OutputItemKey: "", Method: "POST", URI: "/v1/package/versions"}, + "ListPackages": {Verb: "List", Resource: "Package", OutputListKey: "packages", OutputItemKey: "", Method: "POST", URI: "/v1/packages"}, + "ListRepositories": {Verb: "List", Resource: "Repository", OutputListKey: "repositories", OutputItemKey: "", Method: "POST", URI: "/v1/repositories"}, + "ListRepositoriesInDomain": {Verb: "List", Resource: "RepositoriesInDomain", OutputListKey: "repositories", OutputItemKey: "", Method: "POST", URI: "/v1/domain/repositories"}, + "ListSubPackageGroups": {Verb: "List", Resource: "SubPackageGroup", OutputListKey: "packageGroups", OutputItemKey: "", Method: "POST", URI: "/v1/package-groups/sub-groups"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "POST", URI: "/v1/tags"}, + "PutDomainPermissionsPolicy": {Verb: "Update", Resource: "DomainPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "PUT", URI: "/v1/domain/permissions/policy"}, + "PutPackageOriginConfiguration": {Verb: "Update", Resource: "PackageOriginConfiguration", OutputListKey: "", OutputItemKey: "originConfiguration", Method: "POST", URI: "/v1/package"}, + "PutRepositoryPermissionsPolicy": {Verb: "Update", Resource: "RepositoryPermissionsPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "PUT", URI: "/v1/repository/permissions/policy"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tag"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/untag"}, + "UpdatePackageGroup": {Verb: "Update", Resource: "PackageGroup", OutputListKey: "", OutputItemKey: "packageGroup", Method: "PUT", URI: "/v1/package-group"}, + "UpdatePackageGroupOriginConfiguration": {Verb: "Update", Resource: "PackageGroupOriginConfiguration", OutputListKey: "", OutputItemKey: "packageGroup", Method: "PUT", URI: "/v1/package-group-origin-configuration"}, + "UpdatePackageVersionsStatus": {Verb: "Update", Resource: "PackageVersionsStatu", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/package/versions/update_status"}, + "UpdateRepository": {Verb: "Update", Resource: "Repository", OutputListKey: "", OutputItemKey: "repository", Method: "PUT", URI: "/v1/repository"}, + }) crud.Register("codebuild", map[string]crud.OpMeta{ "BatchGetBuildBatches": {Verb: "List", Resource: "BuildBatche", OutputListKey: "buildBatches", OutputItemKey: ""}, "BatchGetBuilds": {Verb: "List", Resource: "Build", OutputListKey: "builds", OutputItemKey: ""}, @@ -468,6 +1319,54 @@ func init() { "UpdateApplication": {Verb: "Update", Resource: "Application", OutputListKey: "", OutputItemKey: ""}, "UpdateDeploymentGroup": {Verb: "Update", Resource: "DeploymentGroup", OutputListKey: "hooksNotCleanedUp", OutputItemKey: ""}, }) + crud.Register("codeguruprofiler", map[string]crud.OpMeta{ + "BatchGetFrameMetricData": {Verb: "List", Resource: "FrameMetricData", OutputListKey: "endTimes", OutputItemKey: "", Method: "POST", URI: "/profilingGroups/{profilingGroupName}/frames/-/metrics"}, + "CreateProfilingGroup": {Verb: "Create", Resource: "ProfilingGroup", OutputListKey: "", OutputItemKey: "profilingGroup", Method: "POST", URI: "/profilingGroups"}, + "DeleteProfilingGroup": {Verb: "Delete", Resource: "ProfilingGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/profilingGroups/{profilingGroupName}"}, + "DescribeProfilingGroup": {Verb: "Get", Resource: "ProfilingGroup", OutputListKey: "", OutputItemKey: "profilingGroup", Method: "GET", URI: "/profilingGroups/{profilingGroupName}"}, + "GetFindingsReportAccountSummary": {Verb: "Get", Resource: "FindingsReportAccountSummary", OutputListKey: "reportSummaries", OutputItemKey: "", Method: "GET", URI: "/internal/findingsReports"}, + "GetNotificationConfiguration": {Verb: "Get", Resource: "NotificationConfiguration", OutputListKey: "", OutputItemKey: "notificationConfiguration", Method: "GET", URI: "/profilingGroups/{profilingGroupName}/notificationConfiguration"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/profilingGroups/{profilingGroupName}/policy"}, + "GetProfile": {Verb: "Get", Resource: "Profile", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/profilingGroups/{profilingGroupName}/profile"}, + "GetRecommendations": {Verb: "Get", Resource: "Recommendation", OutputListKey: "anomalies", OutputItemKey: "", Method: "GET", URI: "/internal/profilingGroups/{profilingGroupName}/recommendations"}, + "ListFindingsReports": {Verb: "List", Resource: "FindingsReport", OutputListKey: "findingsReportSummaries", OutputItemKey: "", Method: "GET", URI: "/internal/profilingGroups/{profilingGroupName}/findingsReports"}, + "ListProfileTimes": {Verb: "List", Resource: "ProfileTime", OutputListKey: "profileTimes", OutputItemKey: "", Method: "GET", URI: "/profilingGroups/{profilingGroupName}/profileTimes"}, + "ListProfilingGroups": {Verb: "List", Resource: "ProfilingGroup", OutputListKey: "profilingGroupNames", OutputItemKey: "", Method: "GET", URI: "/profilingGroups"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutPermission": {Verb: "Update", Resource: "Permission", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/profilingGroups/{profilingGroupName}/policy/{actionGroup}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateProfilingGroup": {Verb: "Update", Resource: "ProfilingGroup", OutputListKey: "", OutputItemKey: "profilingGroup", Method: "PUT", URI: "/profilingGroups/{profilingGroupName}"}, + }) + crud.Register("codegurureviewer", map[string]crud.OpMeta{ + "CreateCodeReview": {Verb: "Create", Resource: "CodeReview", OutputListKey: "", OutputItemKey: "CodeReview", Method: "POST", URI: "/codereviews"}, + "DescribeCodeReview": {Verb: "Get", Resource: "CodeReview", OutputListKey: "", OutputItemKey: "CodeReview", Method: "GET", URI: "/codereviews/{CodeReviewArn}"}, + "DescribeRecommendationFeedback": {Verb: "Get", Resource: "RecommendationFeedback", OutputListKey: "", OutputItemKey: "RecommendationFeedback", Method: "GET", URI: "/feedback/{CodeReviewArn}"}, + "DescribeRepositoryAssociation": {Verb: "Get", Resource: "RepositoryAssociation", OutputListKey: "", OutputItemKey: "RepositoryAssociation", Method: "GET", URI: "/associations/{AssociationArn}"}, + "ListCodeReviews": {Verb: "List", Resource: "CodeReview", OutputListKey: "CodeReviewSummaries", OutputItemKey: "", Method: "GET", URI: "/codereviews"}, + "ListRecommendationFeedback": {Verb: "List", Resource: "RecommendationFeedback", OutputListKey: "RecommendationFeedbackSummaries", OutputItemKey: "", Method: "GET", URI: "/feedback/{CodeReviewArn}/RecommendationFeedback"}, + "ListRecommendations": {Verb: "List", Resource: "Recommendation", OutputListKey: "RecommendationSummaries", OutputItemKey: "", Method: "GET", URI: "/codereviews/{CodeReviewArn}/Recommendations"}, + "ListRepositoryAssociations": {Verb: "List", Resource: "RepositoryAssociation", OutputListKey: "RepositoryAssociationSummaries", OutputItemKey: "", Method: "GET", URI: "/associations"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutRecommendationFeedback": {Verb: "Update", Resource: "RecommendationFeedback", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/feedback"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + }) + crud.Register("codegurusecurity", map[string]crud.OpMeta{ + "BatchGetFindings": {Verb: "List", Resource: "Finding", OutputListKey: "failedFindings", OutputItemKey: "", Method: "POST", URI: "/batchGetFindings"}, + "CreateScan": {Verb: "Create", Resource: "Scan", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/scans"}, + "CreateUploadUrl": {Verb: "Create", Resource: "UploadUrl", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/uploadUrl"}, + "GetAccountConfiguration": {Verb: "Get", Resource: "AccountConfiguration", OutputListKey: "", OutputItemKey: "encryptionConfig", Method: "GET", URI: "/accountConfiguration/get"}, + "GetFindings": {Verb: "Get", Resource: "Finding", OutputListKey: "findings", OutputItemKey: "", Method: "GET", URI: "/findings/{scanName}"}, + "GetMetricsSummary": {Verb: "Get", Resource: "MetricsSummary", OutputListKey: "", OutputItemKey: "metricsSummary", Method: "GET", URI: "/metrics/summary"}, + "GetScan": {Verb: "Get", Resource: "Scan", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/scans/{scanName}"}, + "ListFindingsMetrics": {Verb: "List", Resource: "FindingsMetric", OutputListKey: "findingsMetrics", OutputItemKey: "", Method: "GET", URI: "/metrics/findings"}, + "ListScans": {Verb: "List", Resource: "Scan", OutputListKey: "summaries", OutputItemKey: "", Method: "GET", URI: "/scans"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateAccountConfiguration": {Verb: "Update", Resource: "AccountConfiguration", OutputListKey: "", OutputItemKey: "encryptionConfig", Method: "PUT", URI: "/updateAccountConfiguration"}, + }) crud.Register("codepipeline", map[string]crud.OpMeta{ "CreateCustomActionType": {Verb: "Create", Resource: "CustomActionType", OutputListKey: "tags", OutputItemKey: "actionType"}, "CreatePipeline": {Verb: "Create", Resource: "Pipeline", OutputListKey: "tags", OutputItemKey: "pipeline"}, @@ -790,6 +1689,34 @@ func init() { "UpdateCostAllocationTagsStatus": {Verb: "Update", Resource: "CostAllocationTagsStatu", OutputListKey: "Errors", OutputItemKey: ""}, "UpdateCostCategoryDefinition": {Verb: "Update", Resource: "CostCategoryDefinition", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("devopsguru", map[string]crud.OpMeta{ + "DeleteInsight": {Verb: "Delete", Resource: "Insight", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/insights/{Id}"}, + "DescribeAccountHealth": {Verb: "Get", Resource: "AccountHealth", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/accounts/health"}, + "DescribeAccountOverview": {Verb: "Get", Resource: "AccountOverview", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/accounts/overview"}, + "DescribeAnomaly": {Verb: "Get", Resource: "Anomaly", OutputListKey: "", OutputItemKey: "ProactiveAnomaly", Method: "GET", URI: "/anomalies/{Id}"}, + "DescribeEventSourcesConfig": {Verb: "Get", Resource: "EventSourcesConfig", OutputListKey: "", OutputItemKey: "EventSources", Method: "POST", URI: "/event-sources"}, + "DescribeFeedback": {Verb: "Get", Resource: "Feedback", OutputListKey: "", OutputItemKey: "InsightFeedback", Method: "POST", URI: "/feedback"}, + "DescribeInsight": {Verb: "Get", Resource: "Insight", OutputListKey: "", OutputItemKey: "ProactiveInsight", Method: "GET", URI: "/insights/{Id}"}, + "DescribeOrganizationHealth": {Verb: "Get", Resource: "OrganizationHealth", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/organization/health"}, + "DescribeOrganizationOverview": {Verb: "Get", Resource: "OrganizationOverview", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/organization/overview"}, + "DescribeOrganizationResourceCollectionHealth": {Verb: "Get", Resource: "OrganizationResourceCollectionHealth", OutputListKey: "Account", OutputItemKey: "", Method: "POST", URI: "/organization/health/resource-collection"}, + "DescribeResourceCollectionHealth": {Verb: "Get", Resource: "ResourceCollectionHealth", OutputListKey: "CloudFormation", OutputItemKey: "", Method: "GET", URI: "/accounts/health/resource-collection/{ResourceCollectionType}"}, + "DescribeServiceIntegration": {Verb: "Get", Resource: "ServiceIntegration", OutputListKey: "", OutputItemKey: "ServiceIntegration", Method: "GET", URI: "/service-integrations"}, + "GetCostEstimation": {Verb: "Get", Resource: "CostEstimation", OutputListKey: "Costs", OutputItemKey: "ResourceCollection", Method: "GET", URI: "/cost-estimation"}, + "GetResourceCollection": {Verb: "Get", Resource: "ResourceCollection", OutputListKey: "", OutputItemKey: "ResourceCollection", Method: "GET", URI: "/resource-collections/{ResourceCollectionType}"}, + "ListAnomaliesForInsight": {Verb: "List", Resource: "AnomaliesForInsight", OutputListKey: "ProactiveAnomalies", OutputItemKey: "", Method: "POST", URI: "/anomalies/insight/{InsightId}"}, + "ListAnomalousLogGroups": {Verb: "List", Resource: "AnomalousLogGroup", OutputListKey: "AnomalousLogGroups", OutputItemKey: "", Method: "POST", URI: "/list-log-anomalies"}, + "ListEvents": {Verb: "List", Resource: "Event", OutputListKey: "Events", OutputItemKey: "", Method: "POST", URI: "/events"}, + "ListInsights": {Verb: "List", Resource: "Insight", OutputListKey: "ProactiveInsights", OutputItemKey: "", Method: "POST", URI: "/insights"}, + "ListMonitoredResources": {Verb: "List", Resource: "MonitoredResource", OutputListKey: "MonitoredResourceIdentifiers", OutputItemKey: "", Method: "POST", URI: "/monitoredResources"}, + "ListNotificationChannels": {Verb: "List", Resource: "NotificationChannel", OutputListKey: "Channels", OutputItemKey: "", Method: "POST", URI: "/channels"}, + "ListOrganizationInsights": {Verb: "List", Resource: "OrganizationInsight", OutputListKey: "ProactiveInsights", OutputItemKey: "", Method: "POST", URI: "/organization/insights"}, + "ListRecommendations": {Verb: "List", Resource: "Recommendation", OutputListKey: "Recommendations", OutputItemKey: "", Method: "POST", URI: "/recommendations"}, + "PutFeedback": {Verb: "Update", Resource: "Feedback", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/feedback"}, + "UpdateEventSourcesConfig": {Verb: "Update", Resource: "EventSourcesConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/event-sources"}, + "UpdateResourceCollection": {Verb: "Update", Resource: "ResourceCollection", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/resource-collections"}, + "UpdateServiceIntegration": {Verb: "Update", Resource: "ServiceIntegration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/service-integrations"}, + }) crud.Register("dynamodb", map[string]crud.OpMeta{ "BatchGetItem": {Verb: "List", Resource: "Item", OutputListKey: "ConsumedCapacity", OutputItemKey: ""}, "CreateBackup": {Verb: "Create", Resource: "Backup", OutputListKey: "", OutputItemKey: "BackupDetails"}, @@ -841,6 +1768,12 @@ func init() { "GetShardIterator": {Verb: "Get", Resource: "ShardIterator", OutputListKey: "", OutputItemKey: ""}, "ListStreams": {Verb: "List", Resource: "Stream", OutputListKey: "Streams", OutputItemKey: ""}, }) + crud.Register("ebs", map[string]crud.OpMeta{ + "GetSnapshotBlock": {Verb: "Get", Resource: "SnapshotBlock", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/snapshots/{SnapshotId}/blocks/{BlockIndex}"}, + "ListChangedBlocks": {Verb: "List", Resource: "ChangedBlock", OutputListKey: "ChangedBlocks", OutputItemKey: "", Method: "GET", URI: "/snapshots/{SecondSnapshotId}/changedblocks"}, + "ListSnapshotBlocks": {Verb: "List", Resource: "SnapshotBlock", OutputListKey: "Blocks", OutputItemKey: "", Method: "GET", URI: "/snapshots/{SnapshotId}/blocks"}, + "PutSnapshotBlock": {Verb: "Update", Resource: "SnapshotBlock", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/snapshots/{SnapshotId}/blocks/{BlockIndex}"}, + }) crud.Register("ecr", map[string]crud.OpMeta{ "BatchGetImage": {Verb: "List", Resource: "Image", OutputListKey: "failures", OutputItemKey: ""}, "BatchGetRepositoryScanningConfiguration": {Verb: "List", Resource: "RepositoryScanningConfiguration", OutputListKey: "failures", OutputItemKey: ""}, @@ -961,6 +1894,139 @@ func init() { "UpdateTaskProtection": {Verb: "Update", Resource: "TaskProtection", OutputListKey: "failures", OutputItemKey: ""}, "UpdateTaskSet": {Verb: "Update", Resource: "TaskSet", OutputListKey: "", OutputItemKey: "taskSet"}, }) + crud.Register("efs", map[string]crud.OpMeta{ + "CreateAccessPoint": {Verb: "Create", Resource: "AccessPoint", OutputListKey: "Tags", OutputItemKey: "PosixUser", Method: "POST", URI: "/2015-02-01/access-points"}, + "CreateFileSystem": {Verb: "Create", Resource: "FileSystem", OutputListKey: "Tags", OutputItemKey: "FileSystemProtection", Method: "POST", URI: "/2015-02-01/file-systems"}, + "CreateMountTarget": {Verb: "Create", Resource: "MountTarget", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2015-02-01/mount-targets"}, + "CreateReplicationConfiguration": {Verb: "Create", Resource: "ReplicationConfiguration", OutputListKey: "Destinations", OutputItemKey: "", Method: "POST", URI: "/2015-02-01/file-systems/{SourceFileSystemId}/replication-configuration"}, + "CreateTags": {Verb: "Create", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2015-02-01/create-tags/{FileSystemId}"}, + "DeleteAccessPoint": {Verb: "Delete", Resource: "AccessPoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/access-points/{AccessPointId}"}, + "DeleteFileSystem": {Verb: "Delete", Resource: "FileSystem", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/file-systems/{FileSystemId}"}, + "DeleteFileSystemPolicy": {Verb: "Delete", Resource: "FileSystemPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/file-systems/{FileSystemId}/policy"}, + "DeleteMountTarget": {Verb: "Delete", Resource: "MountTarget", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/mount-targets/{MountTargetId}"}, + "DeleteReplicationConfiguration": {Verb: "Delete", Resource: "ReplicationConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/file-systems/{SourceFileSystemId}/replication-configuration"}, + "DeleteTags": {Verb: "Delete", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2015-02-01/delete-tags/{FileSystemId}"}, + "DescribeAccessPoints": {Verb: "Get", Resource: "AccessPoint", OutputListKey: "AccessPoints", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/access-points"}, + "DescribeAccountPreferences": {Verb: "Get", Resource: "AccountPreference", OutputListKey: "", OutputItemKey: "ResourceIdPreference", Method: "GET", URI: "/2015-02-01/account-preferences"}, + "DescribeBackupPolicy": {Verb: "Get", Resource: "BackupPolicy", OutputListKey: "", OutputItemKey: "BackupPolicy", Method: "GET", URI: "/2015-02-01/file-systems/{FileSystemId}/backup-policy"}, + "DescribeFileSystemPolicy": {Verb: "Get", Resource: "FileSystemPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/file-systems/{FileSystemId}/policy"}, + "DescribeFileSystems": {Verb: "Get", Resource: "FileSystem", OutputListKey: "FileSystems", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/file-systems"}, + "DescribeLifecycleConfiguration": {Verb: "Get", Resource: "LifecycleConfiguration", OutputListKey: "LifecyclePolicies", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/file-systems/{FileSystemId}/lifecycle-configuration"}, + "DescribeMountTargetSecurityGroups": {Verb: "Get", Resource: "MountTargetSecurityGroup", OutputListKey: "SecurityGroups", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/mount-targets/{MountTargetId}/security-groups"}, + "DescribeMountTargets": {Verb: "Get", Resource: "MountTarget", OutputListKey: "MountTargets", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/mount-targets"}, + "DescribeReplicationConfigurations": {Verb: "Get", Resource: "ReplicationConfiguration", OutputListKey: "Replications", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/file-systems/replication-configurations"}, + "DescribeTags": {Verb: "Get", Resource: "Tag", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/tags/{FileSystemId}"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/2015-02-01/resource-tags/{ResourceId}"}, + "ModifyMountTargetSecurityGroups": {Verb: "Update", Resource: "MountTargetSecurityGroup", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2015-02-01/mount-targets/{MountTargetId}/security-groups"}, + "PutAccountPreferences": {Verb: "Update", Resource: "AccountPreference", OutputListKey: "", OutputItemKey: "ResourceIdPreference", Method: "PUT", URI: "/2015-02-01/account-preferences"}, + "PutBackupPolicy": {Verb: "Update", Resource: "BackupPolicy", OutputListKey: "", OutputItemKey: "BackupPolicy", Method: "PUT", URI: "/2015-02-01/file-systems/{FileSystemId}/backup-policy"}, + "PutFileSystemPolicy": {Verb: "Update", Resource: "FileSystemPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2015-02-01/file-systems/{FileSystemId}/policy"}, + "PutLifecycleConfiguration": {Verb: "Update", Resource: "LifecycleConfiguration", OutputListKey: "LifecyclePolicies", OutputItemKey: "", Method: "PUT", URI: "/2015-02-01/file-systems/{FileSystemId}/lifecycle-configuration"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2015-02-01/resource-tags/{ResourceId}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-02-01/resource-tags/{ResourceId}"}, + "UpdateFileSystem": {Verb: "Update", Resource: "FileSystem", OutputListKey: "Tags", OutputItemKey: "FileSystemProtection", Method: "PUT", URI: "/2015-02-01/file-systems/{FileSystemId}"}, + "UpdateFileSystemProtection": {Verb: "Update", Resource: "FileSystemProtection", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2015-02-01/file-systems/{FileSystemId}/protection"}, + }) + crud.Register("eks", map[string]crud.OpMeta{ + "CreateAccessEntry": {Verb: "Create", Resource: "AccessEntry", OutputListKey: "", OutputItemKey: "accessEntry", Method: "POST", URI: "/clusters/{clusterName}/access-entries"}, + "CreateAddon": {Verb: "Create", Resource: "Addon", OutputListKey: "", OutputItemKey: "addon", Method: "POST", URI: "/clusters/{clusterName}/addons"}, + "CreateCapability": {Verb: "Create", Resource: "Capability", OutputListKey: "", OutputItemKey: "capability", Method: "POST", URI: "/clusters/{clusterName}/capabilities"}, + "CreateCluster": {Verb: "Create", Resource: "Cluster", OutputListKey: "", OutputItemKey: "cluster", Method: "POST", URI: "/clusters"}, + "CreateEksAnywhereSubscription": {Verb: "Create", Resource: "EksAnywhereSubscription", OutputListKey: "", OutputItemKey: "subscription", Method: "POST", URI: "/eks-anywhere-subscriptions"}, + "CreateFargateProfile": {Verb: "Create", Resource: "FargateProfile", OutputListKey: "", OutputItemKey: "fargateProfile", Method: "POST", URI: "/clusters/{clusterName}/fargate-profiles"}, + "CreateNodegroup": {Verb: "Create", Resource: "Nodegroup", OutputListKey: "", OutputItemKey: "nodegroup", Method: "POST", URI: "/clusters/{clusterName}/node-groups"}, + "CreatePodIdentityAssociation": {Verb: "Create", Resource: "PodIdentityAssociation", OutputListKey: "", OutputItemKey: "association", Method: "POST", URI: "/clusters/{clusterName}/pod-identity-associations"}, + "DeleteAccessEntry": {Verb: "Delete", Resource: "AccessEntry", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/clusters/{clusterName}/access-entries/{principalArn}"}, + "DeleteAddon": {Verb: "Delete", Resource: "Addon", OutputListKey: "", OutputItemKey: "addon", Method: "DELETE", URI: "/clusters/{clusterName}/addons/{addonName}"}, + "DeleteCapability": {Verb: "Delete", Resource: "Capability", OutputListKey: "", OutputItemKey: "capability", Method: "DELETE", URI: "/clusters/{clusterName}/capabilities/{capabilityName}"}, + "DeleteCluster": {Verb: "Delete", Resource: "Cluster", OutputListKey: "", OutputItemKey: "cluster", Method: "DELETE", URI: "/clusters/{name}"}, + "DeleteEksAnywhereSubscription": {Verb: "Delete", Resource: "EksAnywhereSubscription", OutputListKey: "", OutputItemKey: "subscription", Method: "DELETE", URI: "/eks-anywhere-subscriptions/{id}"}, + "DeleteFargateProfile": {Verb: "Delete", Resource: "FargateProfile", OutputListKey: "", OutputItemKey: "fargateProfile", Method: "DELETE", URI: "/clusters/{clusterName}/fargate-profiles/{fargateProfileName}"}, + "DeleteNodegroup": {Verb: "Delete", Resource: "Nodegroup", OutputListKey: "", OutputItemKey: "nodegroup", Method: "DELETE", URI: "/clusters/{clusterName}/node-groups/{nodegroupName}"}, + "DeletePodIdentityAssociation": {Verb: "Delete", Resource: "PodIdentityAssociation", OutputListKey: "", OutputItemKey: "association", Method: "DELETE", URI: "/clusters/{clusterName}/pod-identity-associations/{associationId}"}, + "DeregisterCluster": {Verb: "Delete", Resource: "Cluster", OutputListKey: "", OutputItemKey: "cluster", Method: "DELETE", URI: "/cluster-registrations/{name}"}, + "DescribeAccessEntry": {Verb: "Get", Resource: "AccessEntry", OutputListKey: "", OutputItemKey: "accessEntry", Method: "GET", URI: "/clusters/{clusterName}/access-entries/{principalArn}"}, + "DescribeAddon": {Verb: "Get", Resource: "Addon", OutputListKey: "", OutputItemKey: "addon", Method: "GET", URI: "/clusters/{clusterName}/addons/{addonName}"}, + "DescribeAddonConfiguration": {Verb: "Get", Resource: "AddonConfiguration", OutputListKey: "podIdentityConfiguration", OutputItemKey: "", Method: "GET", URI: "/addons/configuration-schemas"}, + "DescribeAddonVersions": {Verb: "Get", Resource: "AddonVersion", OutputListKey: "addons", OutputItemKey: "", Method: "GET", URI: "/addons/supported-versions"}, + "DescribeCapability": {Verb: "Get", Resource: "Capability", OutputListKey: "", OutputItemKey: "capability", Method: "GET", URI: "/clusters/{clusterName}/capabilities/{capabilityName}"}, + "DescribeCluster": {Verb: "Get", Resource: "Cluster", OutputListKey: "", OutputItemKey: "cluster", Method: "GET", URI: "/clusters/{name}"}, + "DescribeClusterVersions": {Verb: "Get", Resource: "ClusterVersion", OutputListKey: "clusterVersions", OutputItemKey: "", Method: "GET", URI: "/cluster-versions"}, + "DescribeEksAnywhereSubscription": {Verb: "Get", Resource: "EksAnywhereSubscription", OutputListKey: "", OutputItemKey: "subscription", Method: "GET", URI: "/eks-anywhere-subscriptions/{id}"}, + "DescribeFargateProfile": {Verb: "Get", Resource: "FargateProfile", OutputListKey: "", OutputItemKey: "fargateProfile", Method: "GET", URI: "/clusters/{clusterName}/fargate-profiles/{fargateProfileName}"}, + "DescribeIdentityProviderConfig": {Verb: "Get", Resource: "IdentityProviderConfig", OutputListKey: "", OutputItemKey: "identityProviderConfig", Method: "POST", URI: "/clusters/{clusterName}/identity-provider-configs/describe"}, + "DescribeInsight": {Verb: "Get", Resource: "Insight", OutputListKey: "", OutputItemKey: "insight", Method: "GET", URI: "/clusters/{clusterName}/insights/{id}"}, + "DescribeInsightsRefresh": {Verb: "Get", Resource: "InsightsRefresh", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/insights-refresh"}, + "DescribeNodegroup": {Verb: "Get", Resource: "Nodegroup", OutputListKey: "", OutputItemKey: "nodegroup", Method: "GET", URI: "/clusters/{clusterName}/node-groups/{nodegroupName}"}, + "DescribePodIdentityAssociation": {Verb: "Get", Resource: "PodIdentityAssociation", OutputListKey: "", OutputItemKey: "association", Method: "GET", URI: "/clusters/{clusterName}/pod-identity-associations/{associationId}"}, + "DescribeUpdate": {Verb: "Get", Resource: "Update", OutputListKey: "", OutputItemKey: "update", Method: "GET", URI: "/clusters/{name}/updates/{updateId}"}, + "ListAccessEntries": {Verb: "List", Resource: "AccessEntry", OutputListKey: "accessEntries", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/access-entries"}, + "ListAccessPolicies": {Verb: "List", Resource: "AccessPolicy", OutputListKey: "accessPolicies", OutputItemKey: "", Method: "GET", URI: "/access-policies"}, + "ListAddons": {Verb: "List", Resource: "Addon", OutputListKey: "addons", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/addons"}, + "ListAssociatedAccessPolicies": {Verb: "List", Resource: "AssociatedAccessPolicy", OutputListKey: "associatedAccessPolicies", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/access-entries/{principalArn}/access-policies"}, + "ListCapabilities": {Verb: "List", Resource: "Capability", OutputListKey: "capabilities", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/capabilities"}, + "ListClusters": {Verb: "List", Resource: "Cluster", OutputListKey: "clusters", OutputItemKey: "", Method: "GET", URI: "/clusters"}, + "ListEksAnywhereSubscriptions": {Verb: "List", Resource: "EksAnywhereSubscription", OutputListKey: "subscriptions", OutputItemKey: "", Method: "GET", URI: "/eks-anywhere-subscriptions"}, + "ListFargateProfiles": {Verb: "List", Resource: "FargateProfile", OutputListKey: "fargateProfileNames", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/fargate-profiles"}, + "ListIdentityProviderConfigs": {Verb: "List", Resource: "IdentityProviderConfig", OutputListKey: "identityProviderConfigs", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/identity-provider-configs"}, + "ListInsights": {Verb: "List", Resource: "Insight", OutputListKey: "insights", OutputItemKey: "", Method: "POST", URI: "/clusters/{clusterName}/insights"}, + "ListNodegroups": {Verb: "List", Resource: "Nodegroup", OutputListKey: "nodegroups", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/node-groups"}, + "ListPodIdentityAssociations": {Verb: "List", Resource: "PodIdentityAssociation", OutputListKey: "associations", OutputItemKey: "", Method: "GET", URI: "/clusters/{clusterName}/pod-identity-associations"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "ListUpdates": {Verb: "List", Resource: "Update", OutputListKey: "updateIds", OutputItemKey: "", Method: "GET", URI: "/clusters/{name}/updates"}, + "RegisterCluster": {Verb: "Create", Resource: "Cluster", OutputListKey: "", OutputItemKey: "cluster", Method: "POST", URI: "/cluster-registrations"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateAccessEntry": {Verb: "Update", Resource: "AccessEntry", OutputListKey: "", OutputItemKey: "accessEntry", Method: "POST", URI: "/clusters/{clusterName}/access-entries/{principalArn}"}, + "UpdateAddon": {Verb: "Update", Resource: "Addon", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{clusterName}/addons/{addonName}/update"}, + "UpdateCapability": {Verb: "Update", Resource: "Capability", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{clusterName}/capabilities/{capabilityName}"}, + "UpdateClusterConfig": {Verb: "Update", Resource: "ClusterConfig", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{name}/update-config"}, + "UpdateClusterVersion": {Verb: "Update", Resource: "ClusterVersion", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{name}/updates"}, + "UpdateEksAnywhereSubscription": {Verb: "Update", Resource: "EksAnywhereSubscription", OutputListKey: "", OutputItemKey: "subscription", Method: "POST", URI: "/eks-anywhere-subscriptions/{id}"}, + "UpdateNodegroupConfig": {Verb: "Update", Resource: "NodegroupConfig", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{clusterName}/node-groups/{nodegroupName}/update-config"}, + "UpdateNodegroupVersion": {Verb: "Update", Resource: "NodegroupVersion", OutputListKey: "", OutputItemKey: "update", Method: "POST", URI: "/clusters/{clusterName}/node-groups/{nodegroupName}/update-version"}, + "UpdatePodIdentityAssociation": {Verb: "Update", Resource: "PodIdentityAssociation", OutputListKey: "", OutputItemKey: "association", Method: "POST", URI: "/clusters/{clusterName}/pod-identity-associations/{associationId}"}, + }) + crud.Register("elasticsearchservice", map[string]crud.OpMeta{ + "CreateElasticsearchDomain": {Verb: "Create", Resource: "ElasticsearchDomain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "POST", URI: "/2015-01-01/es/domain"}, + "CreateOutboundCrossClusterSearchConnection": {Verb: "Create", Resource: "OutboundCrossClusterSearchConnection", OutputListKey: "", OutputItemKey: "ConnectionStatus", Method: "POST", URI: "/2015-01-01/es/ccs/outboundConnection"}, + "CreatePackage": {Verb: "Create", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "POST", URI: "/2015-01-01/packages"}, + "CreateVpcEndpoint": {Verb: "Create", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpoint", Method: "POST", URI: "/2015-01-01/es/vpcEndpoints"}, + "DeleteElasticsearchDomain": {Verb: "Delete", Resource: "ElasticsearchDomain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "DELETE", URI: "/2015-01-01/es/domain/{DomainName}"}, + "DeleteElasticsearchServiceRole": {Verb: "Delete", Resource: "ElasticsearchServiceRole", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-01-01/es/role"}, + "DeleteInboundCrossClusterSearchConnection": {Verb: "Delete", Resource: "InboundCrossClusterSearchConnection", OutputListKey: "", OutputItemKey: "CrossClusterSearchConnection", Method: "DELETE", URI: "/2015-01-01/es/ccs/inboundConnection/{CrossClusterSearchConnectionId}"}, + "DeleteOutboundCrossClusterSearchConnection": {Verb: "Delete", Resource: "OutboundCrossClusterSearchConnection", OutputListKey: "", OutputItemKey: "CrossClusterSearchConnection", Method: "DELETE", URI: "/2015-01-01/es/ccs/outboundConnection/{CrossClusterSearchConnectionId}"}, + "DeletePackage": {Verb: "Delete", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "DELETE", URI: "/2015-01-01/packages/{PackageID}"}, + "DeleteVpcEndpoint": {Verb: "Delete", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpointSummary", Method: "DELETE", URI: "/2015-01-01/es/vpcEndpoints/{VpcEndpointId}"}, + "DescribeDomainAutoTunes": {Verb: "Get", Resource: "DomainAutoTune", OutputListKey: "AutoTunes", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}/autoTunes"}, + "DescribeDomainChangeProgress": {Verb: "Get", Resource: "DomainChangeProgress", OutputListKey: "", OutputItemKey: "ChangeProgressStatus", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}/progress"}, + "DescribeElasticsearchDomain": {Verb: "Get", Resource: "ElasticsearchDomain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}"}, + "DescribeElasticsearchDomainConfig": {Verb: "Get", Resource: "ElasticsearchDomainConfig", OutputListKey: "", OutputItemKey: "DomainConfig", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}/config"}, + "DescribeElasticsearchDomains": {Verb: "Get", Resource: "ElasticsearchDomain", OutputListKey: "DomainStatusList", OutputItemKey: "", Method: "POST", URI: "/2015-01-01/es/domain-info"}, + "DescribeElasticsearchInstanceTypeLimits": {Verb: "Get", Resource: "ElasticsearchInstanceTypeLimit", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/instanceTypeLimits/{ElasticsearchVersion}/{InstanceType}"}, + "DescribeInboundCrossClusterSearchConnections": {Verb: "Get", Resource: "InboundCrossClusterSearchConnection", OutputListKey: "CrossClusterSearchConnections", OutputItemKey: "", Method: "POST", URI: "/2015-01-01/es/ccs/inboundConnection/search"}, + "DescribeOutboundCrossClusterSearchConnections": {Verb: "Get", Resource: "OutboundCrossClusterSearchConnection", OutputListKey: "CrossClusterSearchConnections", OutputItemKey: "", Method: "POST", URI: "/2015-01-01/es/ccs/outboundConnection/search"}, + "DescribePackages": {Verb: "Get", Resource: "Package", OutputListKey: "PackageDetailsList", OutputItemKey: "", Method: "POST", URI: "/2015-01-01/packages/describe"}, + "DescribeReservedElasticsearchInstanceOfferings": {Verb: "Get", Resource: "ReservedElasticsearchInstanceOffering", OutputListKey: "ReservedElasticsearchInstanceOfferings", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/reservedInstanceOfferings"}, + "DescribeReservedElasticsearchInstances": {Verb: "Get", Resource: "ReservedElasticsearchInstance", OutputListKey: "ReservedElasticsearchInstances", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/reservedInstances"}, + "DescribeVpcEndpoints": {Verb: "Get", Resource: "VpcEndpoint", OutputListKey: "VpcEndpointErrors", OutputItemKey: "", Method: "POST", URI: "/2015-01-01/es/vpcEndpoints/describe"}, + "GetCompatibleElasticsearchVersions": {Verb: "Get", Resource: "CompatibleElasticsearchVersion", OutputListKey: "CompatibleElasticsearchVersions", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/compatibleVersions"}, + "GetPackageVersionHistory": {Verb: "Get", Resource: "PackageVersionHistory", OutputListKey: "PackageVersionHistoryList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/packages/{PackageID}/history"}, + "GetUpgradeHistory": {Verb: "Get", Resource: "UpgradeHistory", OutputListKey: "UpgradeHistories", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/upgradeDomain/{DomainName}/history"}, + "GetUpgradeStatus": {Verb: "Get", Resource: "UpgradeStatu", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/upgradeDomain/{DomainName}/status"}, + "ListDomainNames": {Verb: "List", Resource: "DomainName", OutputListKey: "DomainNames", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/domain"}, + "ListDomainsForPackage": {Verb: "List", Resource: "DomainsForPackage", OutputListKey: "DomainPackageDetailsList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/packages/{PackageID}/domains"}, + "ListElasticsearchInstanceTypes": {Verb: "List", Resource: "ElasticsearchInstanceType", OutputListKey: "ElasticsearchInstanceTypes", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/instanceTypes/{ElasticsearchVersion}"}, + "ListElasticsearchVersions": {Verb: "List", Resource: "ElasticsearchVersion", OutputListKey: "ElasticsearchVersions", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/versions"}, + "ListPackagesForDomain": {Verb: "List", Resource: "PackagesForDomain", OutputListKey: "DomainPackageDetailsList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/domain/{DomainName}/packages"}, + "ListTags": {Verb: "List", Resource: "Tag", OutputListKey: "TagList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/tags"}, + "ListVpcEndpointAccess": {Verb: "List", Resource: "VpcEndpointAccess", OutputListKey: "AuthorizedPrincipalList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}/listVpcEndpointAccess"}, + "ListVpcEndpoints": {Verb: "List", Resource: "VpcEndpoint", OutputListKey: "VpcEndpointSummaryList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/vpcEndpoints"}, + "ListVpcEndpointsForDomain": {Verb: "List", Resource: "VpcEndpointsForDomain", OutputListKey: "VpcEndpointSummaryList", OutputItemKey: "", Method: "GET", URI: "/2015-01-01/es/domain/{DomainName}/vpcEndpoints"}, + "UpdateElasticsearchDomainConfig": {Verb: "Update", Resource: "ElasticsearchDomainConfig", OutputListKey: "", OutputItemKey: "DomainConfig", Method: "POST", URI: "/2015-01-01/es/domain/{DomainName}/config"}, + "UpdatePackage": {Verb: "Update", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "POST", URI: "/2015-01-01/packages/update"}, + "UpdateVpcEndpoint": {Verb: "Update", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpoint", Method: "POST", URI: "/2015-01-01/es/vpcEndpoints/update"}, + }) crud.Register("emr", map[string]crud.OpMeta{ "CreatePersistentAppUI": {Verb: "Create", Resource: "PersistentAppUI", OutputListKey: "", OutputItemKey: ""}, "CreateSecurityConfiguration": {Verb: "Create", Resource: "SecurityConfiguration", OutputListKey: "", OutputItemKey: ""}, @@ -1006,6 +2072,41 @@ func init() { "UpdateStudio": {Verb: "Update", Resource: "Studio", OutputListKey: "", OutputItemKey: ""}, "UpdateStudioSessionMapping": {Verb: "Update", Resource: "StudioSessionMapping", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("entityresolution", map[string]crud.OpMeta{ + "CreateIdMappingWorkflow": {Verb: "Create", Resource: "IdMappingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "idMappingTechniques", Method: "POST", URI: "/idmappingworkflows"}, + "CreateIdNamespace": {Verb: "Create", Resource: "IdNamespace", OutputListKey: "idMappingWorkflowProperties", OutputItemKey: "", Method: "POST", URI: "/idnamespaces"}, + "CreateMatchingWorkflow": {Verb: "Create", Resource: "MatchingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "incrementalRunConfig", Method: "POST", URI: "/matchingworkflows"}, + "CreateSchemaMapping": {Verb: "Create", Resource: "SchemaMapping", OutputListKey: "mappedInputFields", OutputItemKey: "", Method: "POST", URI: "/schemas"}, + "DeleteIdMappingWorkflow": {Verb: "Delete", Resource: "IdMappingWorkflow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/idmappingworkflows/{workflowName}"}, + "DeleteIdNamespace": {Verb: "Delete", Resource: "IdNamespace", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/idnamespaces/{idNamespaceName}"}, + "DeleteMatchingWorkflow": {Verb: "Delete", Resource: "MatchingWorkflow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/matchingworkflows/{workflowName}"}, + "DeletePolicyStatement": {Verb: "Delete", Resource: "PolicyStatement", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/policies/{arn}/{statementId}"}, + "DeleteSchemaMapping": {Verb: "Delete", Resource: "SchemaMapping", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/schemas/{schemaName}"}, + "GetIdMappingJob": {Verb: "Get", Resource: "IdMappingJob", OutputListKey: "outputSourceConfig", OutputItemKey: "errorDetails", Method: "GET", URI: "/idmappingworkflows/{workflowName}/jobs/{jobId}"}, + "GetIdMappingWorkflow": {Verb: "Get", Resource: "IdMappingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "idMappingTechniques", Method: "GET", URI: "/idmappingworkflows/{workflowName}"}, + "GetIdNamespace": {Verb: "Get", Resource: "IdNamespace", OutputListKey: "idMappingWorkflowProperties", OutputItemKey: "", Method: "GET", URI: "/idnamespaces/{idNamespaceName}"}, + "GetMatchId": {Verb: "Get", Resource: "MatchId", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/matchingworkflows/{workflowName}/matches"}, + "GetMatchingJob": {Verb: "Get", Resource: "MatchingJob", OutputListKey: "outputSourceConfig", OutputItemKey: "errorDetails", Method: "GET", URI: "/matchingworkflows/{workflowName}/jobs/{jobId}"}, + "GetMatchingWorkflow": {Verb: "Get", Resource: "MatchingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "incrementalRunConfig", Method: "GET", URI: "/matchingworkflows/{workflowName}"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policies/{arn}"}, + "GetProviderService": {Verb: "Get", Resource: "ProviderService", OutputListKey: "", OutputItemKey: "providerComponentSchema", Method: "GET", URI: "/providerservices/{providerName}/{providerServiceName}"}, + "GetSchemaMapping": {Verb: "Get", Resource: "SchemaMapping", OutputListKey: "mappedInputFields", OutputItemKey: "", Method: "GET", URI: "/schemas/{schemaName}"}, + "ListIdMappingJobs": {Verb: "List", Resource: "IdMappingJob", OutputListKey: "jobs", OutputItemKey: "", Method: "GET", URI: "/idmappingworkflows/{workflowName}/jobs"}, + "ListIdMappingWorkflows": {Verb: "List", Resource: "IdMappingWorkflow", OutputListKey: "workflowSummaries", OutputItemKey: "", Method: "GET", URI: "/idmappingworkflows"}, + "ListIdNamespaces": {Verb: "List", Resource: "IdNamespace", OutputListKey: "idNamespaceSummaries", OutputItemKey: "", Method: "GET", URI: "/idnamespaces"}, + "ListMatchingJobs": {Verb: "List", Resource: "MatchingJob", OutputListKey: "jobs", OutputItemKey: "", Method: "GET", URI: "/matchingworkflows/{workflowName}/jobs"}, + "ListMatchingWorkflows": {Verb: "List", Resource: "MatchingWorkflow", OutputListKey: "workflowSummaries", OutputItemKey: "", Method: "GET", URI: "/matchingworkflows"}, + "ListProviderServices": {Verb: "List", Resource: "ProviderService", OutputListKey: "providerServiceSummaries", OutputItemKey: "", Method: "GET", URI: "/providerservices"}, + "ListSchemaMappings": {Verb: "List", Resource: "SchemaMapping", OutputListKey: "schemaList", OutputItemKey: "", Method: "GET", URI: "/schemas"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutPolicy": {Verb: "Update", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/policies/{arn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateIdMappingWorkflow": {Verb: "Update", Resource: "IdMappingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "idMappingTechniques", Method: "PUT", URI: "/idmappingworkflows/{workflowName}"}, + "UpdateIdNamespace": {Verb: "Update", Resource: "IdNamespace", OutputListKey: "idMappingWorkflowProperties", OutputItemKey: "", Method: "PUT", URI: "/idnamespaces/{idNamespaceName}"}, + "UpdateMatchingWorkflow": {Verb: "Update", Resource: "MatchingWorkflow", OutputListKey: "inputSourceConfig", OutputItemKey: "incrementalRunConfig", Method: "PUT", URI: "/matchingworkflows/{workflowName}"}, + "UpdateSchemaMapping": {Verb: "Update", Resource: "SchemaMapping", OutputListKey: "mappedInputFields", OutputItemKey: "", Method: "PUT", URI: "/schemas/{schemaName}"}, + }) crud.Register("eventbridge", map[string]crud.OpMeta{ "CreateApiDestination": {Verb: "Create", Resource: "ApiDestination", OutputListKey: "", OutputItemKey: ""}, "CreateArchive": {Verb: "Create", Resource: "Archive", OutputListKey: "", OutputItemKey: ""}, @@ -1067,6 +2168,32 @@ func init() { "UntagDeliveryStream": {Verb: "Untag", Resource: "DeliveryStream", OutputListKey: "", OutputItemKey: ""}, "UpdateDestination": {Verb: "Update", Resource: "Destination", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("fis", map[string]crud.OpMeta{ + "CreateExperimentTemplate": {Verb: "Create", Resource: "ExperimentTemplate", OutputListKey: "", OutputItemKey: "experimentTemplate", Method: "POST", URI: "/experimentTemplates"}, + "CreateTargetAccountConfiguration": {Verb: "Create", Resource: "TargetAccountConfiguration", OutputListKey: "", OutputItemKey: "targetAccountConfiguration", Method: "POST", URI: "/experimentTemplates/{experimentTemplateId}/targetAccountConfigurations/{accountId}"}, + "DeleteExperimentTemplate": {Verb: "Delete", Resource: "ExperimentTemplate", OutputListKey: "", OutputItemKey: "experimentTemplate", Method: "DELETE", URI: "/experimentTemplates/{id}"}, + "DeleteTargetAccountConfiguration": {Verb: "Delete", Resource: "TargetAccountConfiguration", OutputListKey: "", OutputItemKey: "targetAccountConfiguration", Method: "DELETE", URI: "/experimentTemplates/{experimentTemplateId}/targetAccountConfigurations/{accountId}"}, + "GetAction": {Verb: "Get", Resource: "Action", OutputListKey: "", OutputItemKey: "action", Method: "GET", URI: "/actions/{id}"}, + "GetExperiment": {Verb: "Get", Resource: "Experiment", OutputListKey: "", OutputItemKey: "experiment", Method: "GET", URI: "/experiments/{id}"}, + "GetExperimentTargetAccountConfiguration": {Verb: "Get", Resource: "ExperimentTargetAccountConfiguration", OutputListKey: "", OutputItemKey: "targetAccountConfiguration", Method: "GET", URI: "/experiments/{experimentId}/targetAccountConfigurations/{accountId}"}, + "GetExperimentTemplate": {Verb: "Get", Resource: "ExperimentTemplate", OutputListKey: "", OutputItemKey: "experimentTemplate", Method: "GET", URI: "/experimentTemplates/{id}"}, + "GetSafetyLever": {Verb: "Get", Resource: "SafetyLever", OutputListKey: "", OutputItemKey: "safetyLever", Method: "GET", URI: "/safetyLevers/{id}"}, + "GetTargetAccountConfiguration": {Verb: "Get", Resource: "TargetAccountConfiguration", OutputListKey: "", OutputItemKey: "targetAccountConfiguration", Method: "GET", URI: "/experimentTemplates/{experimentTemplateId}/targetAccountConfigurations/{accountId}"}, + "GetTargetResourceType": {Verb: "Get", Resource: "TargetResourceType", OutputListKey: "", OutputItemKey: "targetResourceType", Method: "GET", URI: "/targetResourceTypes/{resourceType}"}, + "ListActions": {Verb: "List", Resource: "Action", OutputListKey: "actions", OutputItemKey: "", Method: "GET", URI: "/actions"}, + "ListExperimentResolvedTargets": {Verb: "List", Resource: "ExperimentResolvedTarget", OutputListKey: "resolvedTargets", OutputItemKey: "", Method: "GET", URI: "/experiments/{experimentId}/resolvedTargets"}, + "ListExperimentTargetAccountConfigurations": {Verb: "List", Resource: "ExperimentTargetAccountConfiguration", OutputListKey: "targetAccountConfigurations", OutputItemKey: "", Method: "GET", URI: "/experiments/{experimentId}/targetAccountConfigurations"}, + "ListExperimentTemplates": {Verb: "List", Resource: "ExperimentTemplate", OutputListKey: "experimentTemplates", OutputItemKey: "", Method: "GET", URI: "/experimentTemplates"}, + "ListExperiments": {Verb: "List", Resource: "Experiment", OutputListKey: "experiments", OutputItemKey: "", Method: "GET", URI: "/experiments"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "ListTargetAccountConfigurations": {Verb: "List", Resource: "TargetAccountConfiguration", OutputListKey: "targetAccountConfigurations", OutputItemKey: "", Method: "GET", URI: "/experimentTemplates/{experimentTemplateId}/targetAccountConfigurations"}, + "ListTargetResourceTypes": {Verb: "List", Resource: "TargetResourceType", OutputListKey: "targetResourceTypes", OutputItemKey: "", Method: "GET", URI: "/targetResourceTypes"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateExperimentTemplate": {Verb: "Update", Resource: "ExperimentTemplate", OutputListKey: "", OutputItemKey: "experimentTemplate", Method: "PATCH", URI: "/experimentTemplates/{id}"}, + "UpdateSafetyLeverState": {Verb: "Update", Resource: "SafetyLeverState", OutputListKey: "", OutputItemKey: "safetyLever", Method: "PATCH", URI: "/safetyLevers/{id}/state"}, + "UpdateTargetAccountConfiguration": {Verb: "Update", Resource: "TargetAccountConfiguration", OutputListKey: "", OutputItemKey: "targetAccountConfiguration", Method: "PATCH", URI: "/experimentTemplates/{experimentTemplateId}/targetAccountConfigurations/{accountId}"}, + }) crud.Register("forecast", map[string]crud.OpMeta{ "CreateAutoPredictor": {Verb: "Create", Resource: "AutoPredictor", OutputListKey: "", OutputItemKey: ""}, "CreateDataset": {Verb: "Create", Resource: "Dataset", OutputListKey: "", OutputItemKey: ""}, @@ -1201,6 +2328,26 @@ func init() { "UpdateRuleVersion": {Verb: "Update", Resource: "RuleVersion", OutputListKey: "", OutputItemKey: "rule"}, "UpdateVariable": {Verb: "Update", Resource: "Variable", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("glacier", map[string]crud.OpMeta{ + "CreateVault": {Verb: "Create", Resource: "Vault", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/{accountId}/vaults/{vaultName}"}, + "DeleteArchive": {Verb: "Delete", Resource: "Archive", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/{accountId}/vaults/{vaultName}/archives/{archiveId}"}, + "DeleteVault": {Verb: "Delete", Resource: "Vault", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/{accountId}/vaults/{vaultName}"}, + "DeleteVaultAccessPolicy": {Verb: "Delete", Resource: "VaultAccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/{accountId}/vaults/{vaultName}/access-policy"}, + "DeleteVaultNotifications": {Verb: "Delete", Resource: "VaultNotification", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/{accountId}/vaults/{vaultName}/notification-configuration"}, + "DescribeJob": {Verb: "Get", Resource: "Job", OutputListKey: "", OutputItemKey: "InventoryRetrievalParameters", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/jobs/{jobId}"}, + "DescribeVault": {Verb: "Get", Resource: "Vault", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}"}, + "GetDataRetrievalPolicy": {Verb: "Get", Resource: "DataRetrievalPolicy", OutputListKey: "", OutputItemKey: "Policy", Method: "GET", URI: "/{accountId}/policies/data-retrieval"}, + "GetJobOutput": {Verb: "Get", Resource: "JobOutput", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/jobs/{jobId}/output"}, + "GetVaultAccessPolicy": {Verb: "Get", Resource: "VaultAccessPolicy", OutputListKey: "", OutputItemKey: "policy", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/access-policy"}, + "GetVaultLock": {Verb: "Get", Resource: "VaultLock", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/lock-policy"}, + "GetVaultNotifications": {Verb: "Get", Resource: "VaultNotification", OutputListKey: "", OutputItemKey: "vaultNotificationConfig", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/notification-configuration"}, + "ListJobs": {Verb: "List", Resource: "Job", OutputListKey: "JobList", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/jobs"}, + "ListMultipartUploads": {Verb: "List", Resource: "MultipartUpload", OutputListKey: "UploadsList", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/multipart-uploads"}, + "ListParts": {Verb: "List", Resource: "Part", OutputListKey: "Parts", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/multipart-uploads/{uploadId}"}, + "ListProvisionedCapacity": {Verb: "List", Resource: "ProvisionedCapacity", OutputListKey: "ProvisionedCapacityList", OutputItemKey: "", Method: "GET", URI: "/{accountId}/provisioned-capacity"}, + "ListTagsForVault": {Verb: "List", Resource: "TagsForVault", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults/{vaultName}/tags"}, + "ListVaults": {Verb: "List", Resource: "Vault", OutputListKey: "VaultList", OutputItemKey: "", Method: "GET", URI: "/{accountId}/vaults"}, + }) crud.Register("glue", map[string]crud.OpMeta{ "BatchGetBlueprints": {Verb: "List", Resource: "Blueprint", OutputListKey: "Blueprints", OutputItemKey: ""}, "BatchGetCrawlers": {Verb: "List", Resource: "Crawler", OutputListKey: "Crawlers", OutputItemKey: ""}, @@ -1425,27 +2572,411 @@ func init() { "UpdateWorkflow": {Verb: "Update", Resource: "Workflow", OutputListKey: "", OutputItemKey: ""}, }) crud.Register("healthlake", map[string]crud.OpMeta{ - "CreateDataTransformationProfile": {Verb: "Create", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: ""}, + "CreateDataTransformationProfile": {Verb: "Create", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/data-transformation-profile"}, "CreateFHIRDatastore": {Verb: "Create", Resource: "FHIRDatastore", OutputListKey: "", OutputItemKey: ""}, - "DeleteDataTransformationProfile": {Verb: "Delete", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: ""}, + "DeleteDataTransformationProfile": {Verb: "Delete", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/data-transformation-profile/{ProfileId}"}, "DeleteFHIRDatastore": {Verb: "Delete", Resource: "FHIRDatastore", OutputListKey: "", OutputItemKey: ""}, - "DescribeDataTransformationJob": {Verb: "Get", Resource: "DataTransformationJob", OutputListKey: "", OutputItemKey: "TransformationJobProperties"}, + "DescribeDataTransformationJob": {Verb: "Get", Resource: "DataTransformationJob", OutputListKey: "", OutputItemKey: "TransformationJobProperties", Method: "GET", URI: "/data-transformation-job/{JobId}"}, "DescribeFHIRDatastore": {Verb: "Get", Resource: "FHIRDatastore", OutputListKey: "", OutputItemKey: "DatastoreProperties"}, "DescribeFHIRExportJob": {Verb: "Get", Resource: "FHIRExportJob", OutputListKey: "", OutputItemKey: "ExportJobProperties"}, "DescribeFHIRImportJob": {Verb: "Get", Resource: "FHIRImportJob", OutputListKey: "", OutputItemKey: "ImportJobProperties"}, - "GetDataTransformationProfile": {Verb: "Get", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: ""}, - "ListDataTransformationJobs": {Verb: "List", Resource: "DataTransformationJob", OutputListKey: "Items", OutputItemKey: ""}, - "ListDataTransformationProfileVersions": {Verb: "List", Resource: "DataTransformationProfileVersion", OutputListKey: "Items", OutputItemKey: ""}, - "ListDataTransformationProfiles": {Verb: "List", Resource: "DataTransformationProfile", OutputListKey: "Items", OutputItemKey: ""}, + "GetDataTransformationProfile": {Verb: "Get", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/data-transformation-profile/{ProfileId}"}, + "ListDataTransformationJobs": {Verb: "List", Resource: "DataTransformationJob", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/data-transformation-jobs"}, + "ListDataTransformationProfileVersions": {Verb: "List", Resource: "DataTransformationProfileVersion", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/data-transformation-profile/{ProfileId}/versions"}, + "ListDataTransformationProfiles": {Verb: "List", Resource: "DataTransformationProfile", OutputListKey: "Items", OutputItemKey: "", Method: "GET", URI: "/data-transformation-profile"}, "ListFHIRDatastores": {Verb: "List", Resource: "FHIRDatastore", OutputListKey: "DatastorePropertiesList", OutputItemKey: ""}, "ListFHIRExportJobs": {Verb: "List", Resource: "FHIRExportJob", OutputListKey: "ExportJobPropertiesList", OutputItemKey: ""}, "ListFHIRImportJobs": {Verb: "List", Resource: "FHIRImportJob", OutputListKey: "ImportJobPropertiesList", OutputItemKey: ""}, "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: ""}, "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, - "UpdateDataTransformationProfile": {Verb: "Update", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: ""}, + "UpdateDataTransformationProfile": {Verb: "Update", Resource: "DataTransformationProfile", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/data-transformation-profile/{ProfileId}"}, "UpdateFHIRDatastore": {Verb: "Update", Resource: "FHIRDatastore", OutputListKey: "", OutputItemKey: "DatastoreProperties"}, - "UpdateProfileWithAgent": {Verb: "Update", Resource: "ProfileWithAgent", OutputListKey: "", OutputItemKey: "AgentResponse"}, + "UpdateProfileWithAgent": {Verb: "Update", Resource: "ProfileWithAgent", OutputListKey: "", OutputItemKey: "AgentResponse", Method: "POST", URI: "/update-profile-with-agent"}, + }) + crud.Register("iot", map[string]crud.OpMeta{ + "CreateAuditSuppression": {Verb: "Create", Resource: "AuditSuppression", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/audit/suppressions/create"}, + "CreateAuthorizer": {Verb: "Create", Resource: "Authorizer", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/authorizer/{authorizerName}"}, + "CreateBillingGroup": {Verb: "Create", Resource: "BillingGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/billing-groups/{billingGroupName}"}, + "CreateCertificateFromCsr": {Verb: "Create", Resource: "CertificateFromCsr", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/certificates"}, + "CreateCertificateProvider": {Verb: "Create", Resource: "CertificateProvider", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/certificate-providers/{certificateProviderName}"}, + "CreateCommand": {Verb: "Create", Resource: "Command", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/commands/{commandId}"}, + "CreateCustomMetric": {Verb: "Create", Resource: "CustomMetric", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/custom-metric/{metricName}"}, + "CreateDimension": {Verb: "Create", Resource: "Dimension", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/dimensions/{name}"}, + "CreateDomainConfiguration": {Verb: "Create", Resource: "DomainConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/domainConfigurations/{domainConfigurationName}"}, + "CreateDynamicThingGroup": {Verb: "Create", Resource: "DynamicThingGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/dynamic-thing-groups/{thingGroupName}"}, + "CreateFleetMetric": {Verb: "Create", Resource: "FleetMetric", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/fleet-metric/{metricName}"}, + "CreateJob": {Verb: "Create", Resource: "Job", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/jobs/{jobId}"}, + "CreateJobTemplate": {Verb: "Create", Resource: "JobTemplate", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/job-templates/{jobTemplateId}"}, + "CreateKeysAndCertificate": {Verb: "Create", Resource: "KeysAndCertificate", OutputListKey: "", OutputItemKey: "keyPair", Method: "POST", URI: "/keys-and-certificate"}, + "CreateMitigationAction": {Verb: "Create", Resource: "MitigationAction", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/mitigationactions/actions/{actionName}"}, + "CreateOTAUpdate": {Verb: "Create", Resource: "OTAUpdate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/otaUpdates/{otaUpdateId}"}, + "CreatePackage": {Verb: "Create", Resource: "Package", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/packages/{packageName}"}, + "CreatePackageVersion": {Verb: "Create", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/packages/{packageName}/versions/{versionName}"}, + "CreatePolicy": {Verb: "Create", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/policies/{policyName}"}, + "CreatePolicyVersion": {Verb: "Create", Resource: "PolicyVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/policies/{policyName}/version"}, + "CreateProvisioningClaim": {Verb: "Create", Resource: "ProvisioningClaim", OutputListKey: "", OutputItemKey: "keyPair", Method: "POST", URI: "/provisioning-templates/{templateName}/provisioning-claim"}, + "CreateProvisioningTemplate": {Verb: "Create", Resource: "ProvisioningTemplate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/provisioning-templates"}, + "CreateProvisioningTemplateVersion": {Verb: "Create", Resource: "ProvisioningTemplateVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/provisioning-templates/{templateName}/versions"}, + "CreateRoleAlias": {Verb: "Create", Resource: "RoleAlia", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/role-aliases/{roleAlias}"}, + "CreateScheduledAudit": {Verb: "Create", Resource: "ScheduledAudit", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/audit/scheduledaudits/{scheduledAuditName}"}, + "CreateSecurityProfile": {Verb: "Create", Resource: "SecurityProfile", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/security-profiles/{securityProfileName}"}, + "CreateStream": {Verb: "Create", Resource: "Stream", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/streams/{streamId}"}, + "CreateThing": {Verb: "Create", Resource: "Thing", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/things/{thingName}"}, + "CreateThingGroup": {Verb: "Create", Resource: "ThingGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/thing-groups/{thingGroupName}"}, + "CreateThingType": {Verb: "Create", Resource: "ThingType", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/thing-types/{thingTypeName}"}, + "CreateTopicRule": {Verb: "Create", Resource: "TopicRule", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/rules/{ruleName}"}, + "CreateTopicRuleDestination": {Verb: "Create", Resource: "TopicRuleDestination", OutputListKey: "", OutputItemKey: "topicRuleDestination", Method: "POST", URI: "/destinations"}, + "DeleteAccountAuditConfiguration": {Verb: "Delete", Resource: "AccountAuditConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/audit/configuration"}, + "DeleteAuditSuppression": {Verb: "Delete", Resource: "AuditSuppression", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/audit/suppressions/delete"}, + "DeleteAuthorizer": {Verb: "Delete", Resource: "Authorizer", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/authorizer/{authorizerName}"}, + "DeleteBillingGroup": {Verb: "Delete", Resource: "BillingGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/billing-groups/{billingGroupName}"}, + "DeleteCACertificate": {Verb: "Delete", Resource: "CACertificate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/cacertificate/{certificateId}"}, + "DeleteCertificate": {Verb: "Delete", Resource: "Certificate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/certificates/{certificateId}"}, + "DeleteCertificateProvider": {Verb: "Delete", Resource: "CertificateProvider", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/certificate-providers/{certificateProviderName}"}, + "DeleteCommand": {Verb: "Delete", Resource: "Command", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/commands/{commandId}"}, + "DeleteCommandExecution": {Verb: "Delete", Resource: "CommandExecution", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/command-executions/{executionId}"}, + "DeleteCustomMetric": {Verb: "Delete", Resource: "CustomMetric", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/custom-metric/{metricName}"}, + "DeleteDimension": {Verb: "Delete", Resource: "Dimension", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/dimensions/{name}"}, + "DeleteDomainConfiguration": {Verb: "Delete", Resource: "DomainConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/domainConfigurations/{domainConfigurationName}"}, + "DeleteDynamicThingGroup": {Verb: "Delete", Resource: "DynamicThingGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/dynamic-thing-groups/{thingGroupName}"}, + "DeleteFleetMetric": {Verb: "Delete", Resource: "FleetMetric", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/fleet-metric/{metricName}"}, + "DeleteJob": {Verb: "Delete", Resource: "Job", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/jobs/{jobId}"}, + "DeleteJobExecution": {Verb: "Delete", Resource: "JobExecution", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/things/{thingName}/jobs/{jobId}/executionNumber/{executionNumber}"}, + "DeleteJobTemplate": {Verb: "Delete", Resource: "JobTemplate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/job-templates/{jobTemplateId}"}, + "DeleteMitigationAction": {Verb: "Delete", Resource: "MitigationAction", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/mitigationactions/actions/{actionName}"}, + "DeleteOTAUpdate": {Verb: "Delete", Resource: "OTAUpdate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/otaUpdates/{otaUpdateId}"}, + "DeletePackage": {Verb: "Delete", Resource: "Package", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/packages/{packageName}"}, + "DeletePackageVersion": {Verb: "Delete", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/packages/{packageName}/versions/{versionName}"}, + "DeletePolicy": {Verb: "Delete", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/policies/{policyName}"}, + "DeletePolicyVersion": {Verb: "Delete", Resource: "PolicyVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/policies/{policyName}/version/{policyVersionId}"}, + "DeleteProvisioningTemplate": {Verb: "Delete", Resource: "ProvisioningTemplate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/provisioning-templates/{templateName}"}, + "DeleteProvisioningTemplateVersion": {Verb: "Delete", Resource: "ProvisioningTemplateVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/provisioning-templates/{templateName}/versions/{versionId}"}, + "DeleteRegistrationCode": {Verb: "Delete", Resource: "RegistrationCode", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/registrationcode"}, + "DeleteRoleAlias": {Verb: "Delete", Resource: "RoleAlia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/role-aliases/{roleAlias}"}, + "DeleteScheduledAudit": {Verb: "Delete", Resource: "ScheduledAudit", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/audit/scheduledaudits/{scheduledAuditName}"}, + "DeleteSecurityProfile": {Verb: "Delete", Resource: "SecurityProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/security-profiles/{securityProfileName}"}, + "DeleteStream": {Verb: "Delete", Resource: "Stream", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/streams/{streamId}"}, + "DeleteThing": {Verb: "Delete", Resource: "Thing", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/things/{thingName}"}, + "DeleteThingGroup": {Verb: "Delete", Resource: "ThingGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/thing-groups/{thingGroupName}"}, + "DeleteThingType": {Verb: "Delete", Resource: "ThingType", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/thing-types/{thingTypeName}"}, + "DeleteTopicRule": {Verb: "Delete", Resource: "TopicRule", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/rules/{ruleName}"}, + "DeleteTopicRuleDestination": {Verb: "Delete", Resource: "TopicRuleDestination", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/destinations/{arn+}"}, + "DeleteV2LoggingLevel": {Verb: "Delete", Resource: "V2LoggingLevel", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2LoggingLevel"}, + "DescribeAccountAuditConfiguration": {Verb: "Get", Resource: "AccountAuditConfiguration", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/audit/configuration"}, + "DescribeAuditFinding": {Verb: "Get", Resource: "AuditFinding", OutputListKey: "", OutputItemKey: "finding", Method: "GET", URI: "/audit/findings/{findingId}"}, + "DescribeAuditMitigationActionsTask": {Verb: "Get", Resource: "AuditMitigationActionsTask", OutputListKey: "actionsDefinition", OutputItemKey: "target", Method: "GET", URI: "/audit/mitigationactions/tasks/{taskId}"}, + "DescribeAuditSuppression": {Verb: "Get", Resource: "AuditSuppression", OutputListKey: "", OutputItemKey: "resourceIdentifier", Method: "POST", URI: "/audit/suppressions/describe"}, + "DescribeAuditTask": {Verb: "Get", Resource: "AuditTask", OutputListKey: "", OutputItemKey: "taskStatistics", Method: "GET", URI: "/audit/tasks/{taskId}"}, + "DescribeAuthorizer": {Verb: "Get", Resource: "Authorizer", OutputListKey: "", OutputItemKey: "authorizerDescription", Method: "GET", URI: "/authorizer/{authorizerName}"}, + "DescribeBillingGroup": {Verb: "Get", Resource: "BillingGroup", OutputListKey: "", OutputItemKey: "billingGroupMetadata", Method: "GET", URI: "/billing-groups/{billingGroupName}"}, + "DescribeCACertificate": {Verb: "Get", Resource: "CACertificate", OutputListKey: "", OutputItemKey: "certificateDescription", Method: "GET", URI: "/cacertificate/{certificateId}"}, + "DescribeCertificate": {Verb: "Get", Resource: "Certificate", OutputListKey: "", OutputItemKey: "certificateDescription", Method: "GET", URI: "/certificates/{certificateId}"}, + "DescribeCertificateProvider": {Verb: "Get", Resource: "CertificateProvider", OutputListKey: "accountDefaultForOperations", OutputItemKey: "", Method: "GET", URI: "/certificate-providers/{certificateProviderName}"}, + "DescribeCustomMetric": {Verb: "Get", Resource: "CustomMetric", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/custom-metric/{metricName}"}, + "DescribeDefaultAuthorizer": {Verb: "Get", Resource: "DefaultAuthorizer", OutputListKey: "", OutputItemKey: "authorizerDescription", Method: "GET", URI: "/default-authorizer"}, + "DescribeDetectMitigationActionsTask": {Verb: "Get", Resource: "DetectMitigationActionsTask", OutputListKey: "", OutputItemKey: "taskSummary", Method: "GET", URI: "/detect/mitigationactions/tasks/{taskId}"}, + "DescribeDimension": {Verb: "Get", Resource: "Dimension", OutputListKey: "stringValues", OutputItemKey: "", Method: "GET", URI: "/dimensions/{name}"}, + "DescribeDomainConfiguration": {Verb: "Get", Resource: "DomainConfiguration", OutputListKey: "serverCertificates", OutputItemKey: "authorizerConfig", Method: "GET", URI: "/domainConfigurations/{domainConfigurationName}"}, + "DescribeEncryptionConfiguration": {Verb: "Get", Resource: "EncryptionConfiguration", OutputListKey: "", OutputItemKey: "configurationDetails", Method: "GET", URI: "/encryption-configuration"}, + "DescribeEndpoint": {Verb: "Get", Resource: "Endpoint", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/endpoint"}, + "DescribeEventConfigurations": {Verb: "Get", Resource: "EventConfiguration", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/event-configurations"}, + "DescribeFleetMetric": {Verb: "Get", Resource: "FleetMetric", OutputListKey: "", OutputItemKey: "aggregationType", Method: "GET", URI: "/fleet-metric/{metricName}"}, + "DescribeIndex": {Verb: "Get", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/indices/{indexName}"}, + "DescribeJob": {Verb: "Get", Resource: "Job", OutputListKey: "", OutputItemKey: "job", Method: "GET", URI: "/jobs/{jobId}"}, + "DescribeJobExecution": {Verb: "Get", Resource: "JobExecution", OutputListKey: "", OutputItemKey: "execution", Method: "GET", URI: "/things/{thingName}/jobs/{jobId}"}, + "DescribeJobTemplate": {Verb: "Get", Resource: "JobTemplate", OutputListKey: "destinationPackageVersions", OutputItemKey: "abortConfig", Method: "GET", URI: "/job-templates/{jobTemplateId}"}, + "DescribeManagedJobTemplate": {Verb: "Get", Resource: "ManagedJobTemplate", OutputListKey: "documentParameters", OutputItemKey: "", Method: "GET", URI: "/managed-job-templates/{templateName}"}, + "DescribeMitigationAction": {Verb: "Get", Resource: "MitigationAction", OutputListKey: "", OutputItemKey: "actionParams", Method: "GET", URI: "/mitigationactions/actions/{actionName}"}, + "DescribeProvisioningTemplate": {Verb: "Get", Resource: "ProvisioningTemplate", OutputListKey: "", OutputItemKey: "preProvisioningHook", Method: "GET", URI: "/provisioning-templates/{templateName}"}, + "DescribeProvisioningTemplateVersion": {Verb: "Get", Resource: "ProvisioningTemplateVersion", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/provisioning-templates/{templateName}/versions/{versionId}"}, + "DescribeRoleAlias": {Verb: "Get", Resource: "RoleAlia", OutputListKey: "", OutputItemKey: "roleAliasDescription", Method: "GET", URI: "/role-aliases/{roleAlias}"}, + "DescribeScheduledAudit": {Verb: "Get", Resource: "ScheduledAudit", OutputListKey: "targetCheckNames", OutputItemKey: "", Method: "GET", URI: "/audit/scheduledaudits/{scheduledAuditName}"}, + "DescribeSecurityProfile": {Verb: "Get", Resource: "SecurityProfile", OutputListKey: "additionalMetricsToRetain", OutputItemKey: "metricsExportConfig", Method: "GET", URI: "/security-profiles/{securityProfileName}"}, + "DescribeStream": {Verb: "Get", Resource: "Stream", OutputListKey: "", OutputItemKey: "streamInfo", Method: "GET", URI: "/streams/{streamId}"}, + "DescribeThing": {Verb: "Get", Resource: "Thing", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}"}, + "DescribeThingGroup": {Verb: "Get", Resource: "ThingGroup", OutputListKey: "", OutputItemKey: "thingGroupMetadata", Method: "GET", URI: "/thing-groups/{thingGroupName}"}, + "DescribeThingRegistrationTask": {Verb: "Get", Resource: "ThingRegistrationTask", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/thing-registration-tasks/{taskId}"}, + "DescribeThingType": {Verb: "Get", Resource: "ThingType", OutputListKey: "", OutputItemKey: "thingTypeMetadata", Method: "GET", URI: "/thing-types/{thingTypeName}"}, + "GetBehaviorModelTrainingSummaries": {Verb: "Get", Resource: "BehaviorModelTrainingSummary", OutputListKey: "summaries", OutputItemKey: "", Method: "GET", URI: "/behavior-model-training/summaries"}, + "GetBucketsAggregation": {Verb: "Get", Resource: "BucketsAggregation", OutputListKey: "buckets", OutputItemKey: "", Method: "POST", URI: "/indices/buckets"}, + "GetCardinality": {Verb: "Get", Resource: "Cardinality", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/indices/cardinality"}, + "GetCommand": {Verb: "Get", Resource: "Command", OutputListKey: "mandatoryParameters", OutputItemKey: "payload", Method: "GET", URI: "/commands/{commandId}"}, + "GetCommandExecution": {Verb: "Get", Resource: "CommandExecution", OutputListKey: "", OutputItemKey: "statusReason", Method: "GET", URI: "/command-executions/{executionId}"}, + "GetEffectivePolicies": {Verb: "Get", Resource: "EffectivePolicy", OutputListKey: "effectivePolicies", OutputItemKey: "", Method: "POST", URI: "/effective-policies"}, + "GetIndexingConfiguration": {Verb: "Get", Resource: "IndexingConfiguration", OutputListKey: "", OutputItemKey: "thingGroupIndexingConfiguration", Method: "GET", URI: "/indexing/config"}, + "GetJobDocument": {Verb: "Get", Resource: "JobDocument", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/jobs/{jobId}/job-document"}, + "GetLoggingOptions": {Verb: "Get", Resource: "LoggingOption", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/loggingOptions"}, + "GetOTAUpdate": {Verb: "Get", Resource: "OTAUpdate", OutputListKey: "", OutputItemKey: "otaUpdateInfo", Method: "GET", URI: "/otaUpdates/{otaUpdateId}"}, + "GetPackage": {Verb: "Get", Resource: "Package", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/packages/{packageName}"}, + "GetPackageConfiguration": {Verb: "Get", Resource: "PackageConfiguration", OutputListKey: "", OutputItemKey: "versionUpdateByJobsConfig", Method: "GET", URI: "/package-configuration"}, + "GetPackageVersion": {Verb: "Get", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "artifact", Method: "GET", URI: "/packages/{packageName}/versions/{versionName}"}, + "GetPercentiles": {Verb: "Get", Resource: "Percentile", OutputListKey: "percentiles", OutputItemKey: "", Method: "POST", URI: "/indices/percentiles"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policies/{policyName}"}, + "GetPolicyVersion": {Verb: "Get", Resource: "PolicyVersion", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policies/{policyName}/version/{policyVersionId}"}, + "GetRegistrationCode": {Verb: "Get", Resource: "RegistrationCode", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/registrationcode"}, + "GetStatistics": {Verb: "Get", Resource: "Statistic", OutputListKey: "", OutputItemKey: "statistics", Method: "POST", URI: "/indices/statistics"}, + "GetThingConnectivityData": {Verb: "Get", Resource: "ThingConnectivityData", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/things/{thingName}/connectivity-data"}, + "GetTopicRule": {Verb: "Get", Resource: "TopicRule", OutputListKey: "", OutputItemKey: "rule", Method: "GET", URI: "/rules/{ruleName}"}, + "GetTopicRuleDestination": {Verb: "Get", Resource: "TopicRuleDestination", OutputListKey: "", OutputItemKey: "topicRuleDestination", Method: "GET", URI: "/destinations/{arn+}"}, + "GetV2LoggingOptions": {Verb: "Get", Resource: "V2LoggingOption", OutputListKey: "eventConfigurations", OutputItemKey: "", Method: "GET", URI: "/v2LoggingOptions"}, + "ListActiveViolations": {Verb: "List", Resource: "ActiveViolation", OutputListKey: "activeViolations", OutputItemKey: "", Method: "GET", URI: "/active-violations"}, + "ListAttachedPolicies": {Verb: "List", Resource: "AttachedPolicy", OutputListKey: "policies", OutputItemKey: "", Method: "POST", URI: "/attached-policies/{target}"}, + "ListAuditFindings": {Verb: "List", Resource: "AuditFinding", OutputListKey: "findings", OutputItemKey: "", Method: "POST", URI: "/audit/findings"}, + "ListAuditMitigationActionsExecutions": {Verb: "List", Resource: "AuditMitigationActionsExecution", OutputListKey: "actionsExecutions", OutputItemKey: "", Method: "GET", URI: "/audit/mitigationactions/executions"}, + "ListAuditMitigationActionsTasks": {Verb: "List", Resource: "AuditMitigationActionsTask", OutputListKey: "tasks", OutputItemKey: "", Method: "GET", URI: "/audit/mitigationactions/tasks"}, + "ListAuditSuppressions": {Verb: "List", Resource: "AuditSuppression", OutputListKey: "suppressions", OutputItemKey: "", Method: "POST", URI: "/audit/suppressions/list"}, + "ListAuditTasks": {Verb: "List", Resource: "AuditTask", OutputListKey: "tasks", OutputItemKey: "", Method: "GET", URI: "/audit/tasks"}, + "ListAuthorizers": {Verb: "List", Resource: "Authorizer", OutputListKey: "authorizers", OutputItemKey: "", Method: "GET", URI: "/authorizers"}, + "ListBillingGroups": {Verb: "List", Resource: "BillingGroup", OutputListKey: "billingGroups", OutputItemKey: "", Method: "GET", URI: "/billing-groups"}, + "ListCACertificates": {Verb: "List", Resource: "CACertificate", OutputListKey: "certificates", OutputItemKey: "", Method: "GET", URI: "/cacertificates"}, + "ListCertificateProviders": {Verb: "List", Resource: "CertificateProvider", OutputListKey: "certificateProviders", OutputItemKey: "", Method: "GET", URI: "/certificate-providers"}, + "ListCertificates": {Verb: "List", Resource: "Certificate", OutputListKey: "certificates", OutputItemKey: "", Method: "GET", URI: "/certificates"}, + "ListCertificatesByCA": {Verb: "List", Resource: "CertificatesByCA", OutputListKey: "certificates", OutputItemKey: "", Method: "GET", URI: "/certificates-by-ca/{caCertificateId}"}, + "ListCommandExecutions": {Verb: "List", Resource: "CommandExecution", OutputListKey: "commandExecutions", OutputItemKey: "", Method: "POST", URI: "/command-executions"}, + "ListCommands": {Verb: "List", Resource: "Command", OutputListKey: "commands", OutputItemKey: "", Method: "GET", URI: "/commands"}, + "ListCustomMetrics": {Verb: "List", Resource: "CustomMetric", OutputListKey: "metricNames", OutputItemKey: "", Method: "GET", URI: "/custom-metrics"}, + "ListDetectMitigationActionsExecutions": {Verb: "List", Resource: "DetectMitigationActionsExecution", OutputListKey: "actionsExecutions", OutputItemKey: "", Method: "GET", URI: "/detect/mitigationactions/executions"}, + "ListDetectMitigationActionsTasks": {Verb: "List", Resource: "DetectMitigationActionsTask", OutputListKey: "tasks", OutputItemKey: "", Method: "GET", URI: "/detect/mitigationactions/tasks"}, + "ListDimensions": {Verb: "List", Resource: "Dimension", OutputListKey: "dimensionNames", OutputItemKey: "", Method: "GET", URI: "/dimensions"}, + "ListDomainConfigurations": {Verb: "List", Resource: "DomainConfiguration", OutputListKey: "domainConfigurations", OutputItemKey: "", Method: "GET", URI: "/domainConfigurations"}, + "ListFleetMetrics": {Verb: "List", Resource: "FleetMetric", OutputListKey: "fleetMetrics", OutputItemKey: "", Method: "GET", URI: "/fleet-metrics"}, + "ListIndices": {Verb: "List", Resource: "Indice", OutputListKey: "indexNames", OutputItemKey: "", Method: "GET", URI: "/indices"}, + "ListJobExecutionsForJob": {Verb: "List", Resource: "JobExecutionsForJob", OutputListKey: "executionSummaries", OutputItemKey: "", Method: "GET", URI: "/jobs/{jobId}/things"}, + "ListJobExecutionsForThing": {Verb: "List", Resource: "JobExecutionsForThing", OutputListKey: "executionSummaries", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}/jobs"}, + "ListJobTemplates": {Verb: "List", Resource: "JobTemplate", OutputListKey: "jobTemplates", OutputItemKey: "", Method: "GET", URI: "/job-templates"}, + "ListJobs": {Verb: "List", Resource: "Job", OutputListKey: "jobs", OutputItemKey: "", Method: "GET", URI: "/jobs"}, + "ListManagedJobTemplates": {Verb: "List", Resource: "ManagedJobTemplate", OutputListKey: "managedJobTemplates", OutputItemKey: "", Method: "GET", URI: "/managed-job-templates"}, + "ListMetricValues": {Verb: "List", Resource: "MetricValue", OutputListKey: "metricDatumList", OutputItemKey: "", Method: "GET", URI: "/metric-values"}, + "ListMitigationActions": {Verb: "List", Resource: "MitigationAction", OutputListKey: "actionIdentifiers", OutputItemKey: "", Method: "GET", URI: "/mitigationactions/actions"}, + "ListOTAUpdates": {Verb: "List", Resource: "OTAUpdate", OutputListKey: "otaUpdates", OutputItemKey: "", Method: "GET", URI: "/otaUpdates"}, + "ListOutgoingCertificates": {Verb: "List", Resource: "OutgoingCertificate", OutputListKey: "outgoingCertificates", OutputItemKey: "", Method: "GET", URI: "/certificates-out-going"}, + "ListPackageVersions": {Verb: "List", Resource: "PackageVersion", OutputListKey: "packageVersionSummaries", OutputItemKey: "", Method: "GET", URI: "/packages/{packageName}/versions"}, + "ListPackages": {Verb: "List", Resource: "Package", OutputListKey: "packageSummaries", OutputItemKey: "", Method: "GET", URI: "/packages"}, + "ListPolicies": {Verb: "List", Resource: "Policy", OutputListKey: "policies", OutputItemKey: "", Method: "GET", URI: "/policies"}, + "ListPolicyPrincipals": {Verb: "List", Resource: "PolicyPrincipal", OutputListKey: "principals", OutputItemKey: "", Method: "GET", URI: "/policy-principals"}, + "ListPolicyVersions": {Verb: "List", Resource: "PolicyVersion", OutputListKey: "policyVersions", OutputItemKey: "", Method: "GET", URI: "/policies/{policyName}/version"}, + "ListPrincipalPolicies": {Verb: "List", Resource: "PrincipalPolicy", OutputListKey: "policies", OutputItemKey: "", Method: "GET", URI: "/principal-policies"}, + "ListPrincipalThings": {Verb: "List", Resource: "PrincipalThing", OutputListKey: "things", OutputItemKey: "", Method: "GET", URI: "/principals/things"}, + "ListPrincipalThingsV2": {Verb: "List", Resource: "PrincipalThingsV2", OutputListKey: "principalThingObjects", OutputItemKey: "", Method: "GET", URI: "/principals/things-v2"}, + "ListProvisioningTemplateVersions": {Verb: "List", Resource: "ProvisioningTemplateVersion", OutputListKey: "versions", OutputItemKey: "", Method: "GET", URI: "/provisioning-templates/{templateName}/versions"}, + "ListProvisioningTemplates": {Verb: "List", Resource: "ProvisioningTemplate", OutputListKey: "templates", OutputItemKey: "", Method: "GET", URI: "/provisioning-templates"}, + "ListRelatedResourcesForAuditFinding": {Verb: "List", Resource: "RelatedResourcesForAuditFinding", OutputListKey: "relatedResources", OutputItemKey: "", Method: "GET", URI: "/audit/relatedResources"}, + "ListRoleAliases": {Verb: "List", Resource: "RoleAliase", OutputListKey: "roleAliases", OutputItemKey: "", Method: "GET", URI: "/role-aliases"}, + "ListSbomValidationResults": {Verb: "List", Resource: "SbomValidationResult", OutputListKey: "validationResultSummaries", OutputItemKey: "", Method: "GET", URI: "/packages/{packageName}/versions/{versionName}/sbom-validation-results"}, + "ListScheduledAudits": {Verb: "List", Resource: "ScheduledAudit", OutputListKey: "scheduledAudits", OutputItemKey: "", Method: "GET", URI: "/audit/scheduledaudits"}, + "ListSecurityProfiles": {Verb: "List", Resource: "SecurityProfile", OutputListKey: "securityProfileIdentifiers", OutputItemKey: "", Method: "GET", URI: "/security-profiles"}, + "ListSecurityProfilesForTarget": {Verb: "List", Resource: "SecurityProfilesForTarget", OutputListKey: "securityProfileTargetMappings", OutputItemKey: "", Method: "GET", URI: "/security-profiles-for-target"}, + "ListStreams": {Verb: "List", Resource: "Stream", OutputListKey: "streams", OutputItemKey: "", Method: "GET", URI: "/streams"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "GET", URI: "/tags"}, + "ListTargetsForPolicy": {Verb: "List", Resource: "TargetsForPolicy", OutputListKey: "targets", OutputItemKey: "", Method: "POST", URI: "/policy-targets/{policyName}"}, + "ListTargetsForSecurityProfile": {Verb: "List", Resource: "TargetsForSecurityProfile", OutputListKey: "securityProfileTargets", OutputItemKey: "", Method: "GET", URI: "/security-profiles/{securityProfileName}/targets"}, + "ListThingGroups": {Verb: "List", Resource: "ThingGroup", OutputListKey: "thingGroups", OutputItemKey: "", Method: "GET", URI: "/thing-groups"}, + "ListThingGroupsForThing": {Verb: "List", Resource: "ThingGroupsForThing", OutputListKey: "thingGroups", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}/thing-groups"}, + "ListThingPrincipals": {Verb: "List", Resource: "ThingPrincipal", OutputListKey: "principals", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}/principals"}, + "ListThingPrincipalsV2": {Verb: "List", Resource: "ThingPrincipalsV2", OutputListKey: "thingPrincipalObjects", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}/principals-v2"}, + "ListThingRegistrationTaskReports": {Verb: "List", Resource: "ThingRegistrationTaskReport", OutputListKey: "resourceLinks", OutputItemKey: "", Method: "GET", URI: "/thing-registration-tasks/{taskId}/reports"}, + "ListThingRegistrationTasks": {Verb: "List", Resource: "ThingRegistrationTask", OutputListKey: "taskIds", OutputItemKey: "", Method: "GET", URI: "/thing-registration-tasks"}, + "ListThingTypes": {Verb: "List", Resource: "ThingType", OutputListKey: "thingTypes", OutputItemKey: "", Method: "GET", URI: "/thing-types"}, + "ListThings": {Verb: "List", Resource: "Thing", OutputListKey: "things", OutputItemKey: "", Method: "GET", URI: "/things"}, + "ListThingsInBillingGroup": {Verb: "List", Resource: "ThingsInBillingGroup", OutputListKey: "things", OutputItemKey: "", Method: "GET", URI: "/billing-groups/{billingGroupName}/things"}, + "ListThingsInThingGroup": {Verb: "List", Resource: "ThingsInThingGroup", OutputListKey: "things", OutputItemKey: "", Method: "GET", URI: "/thing-groups/{thingGroupName}/things"}, + "ListTopicRuleDestinations": {Verb: "List", Resource: "TopicRuleDestination", OutputListKey: "destinationSummaries", OutputItemKey: "", Method: "GET", URI: "/destinations"}, + "ListTopicRules": {Verb: "List", Resource: "TopicRule", OutputListKey: "rules", OutputItemKey: "", Method: "GET", URI: "/rules"}, + "ListV2LoggingLevels": {Verb: "List", Resource: "V2LoggingLevel", OutputListKey: "logTargetConfigurations", OutputItemKey: "", Method: "GET", URI: "/v2LoggingLevel"}, + "ListViolationEvents": {Verb: "List", Resource: "ViolationEvent", OutputListKey: "violationEvents", OutputItemKey: "", Method: "GET", URI: "/violation-events"}, + "PutVerificationStateOnViolation": {Verb: "Update", Resource: "VerificationStateOnViolation", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/violations/verification-state/{violationId}"}, + "RegisterCACertificate": {Verb: "Create", Resource: "CACertificate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/cacertificate"}, + "RegisterCertificate": {Verb: "Create", Resource: "Certificate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/certificate/register"}, + "RegisterCertificateWithoutCA": {Verb: "Create", Resource: "CertificateWithoutCA", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/certificate/register-no-ca"}, + "RegisterThing": {Verb: "Create", Resource: "Thing", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/things"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/untag"}, + "UpdateAccountAuditConfiguration": {Verb: "Update", Resource: "AccountAuditConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/audit/configuration"}, + "UpdateAuditSuppression": {Verb: "Update", Resource: "AuditSuppression", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/audit/suppressions/update"}, + "UpdateAuthorizer": {Verb: "Update", Resource: "Authorizer", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/authorizer/{authorizerName}"}, + "UpdateBillingGroup": {Verb: "Update", Resource: "BillingGroup", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/billing-groups/{billingGroupName}"}, + "UpdateCACertificate": {Verb: "Update", Resource: "CACertificate", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/cacertificate/{certificateId}"}, + "UpdateCertificate": {Verb: "Update", Resource: "Certificate", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/certificates/{certificateId}"}, + "UpdateCertificateProvider": {Verb: "Update", Resource: "CertificateProvider", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/certificate-providers/{certificateProviderName}"}, + "UpdateCommand": {Verb: "Update", Resource: "Command", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/commands/{commandId}"}, + "UpdateCustomMetric": {Verb: "Update", Resource: "CustomMetric", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/custom-metric/{metricName}"}, + "UpdateDimension": {Verb: "Update", Resource: "Dimension", OutputListKey: "stringValues", OutputItemKey: "", Method: "PATCH", URI: "/dimensions/{name}"}, + "UpdateDomainConfiguration": {Verb: "Update", Resource: "DomainConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/domainConfigurations/{domainConfigurationName}"}, + "UpdateDynamicThingGroup": {Verb: "Update", Resource: "DynamicThingGroup", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/dynamic-thing-groups/{thingGroupName}"}, + "UpdateEncryptionConfiguration": {Verb: "Update", Resource: "EncryptionConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/encryption-configuration"}, + "UpdateEventConfigurations": {Verb: "Update", Resource: "EventConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/event-configurations"}, + "UpdateFleetMetric": {Verb: "Update", Resource: "FleetMetric", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/fleet-metric/{metricName}"}, + "UpdateIndexingConfiguration": {Verb: "Update", Resource: "IndexingConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/indexing/config"}, + "UpdateJob": {Verb: "Update", Resource: "Job", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/jobs/{jobId}"}, + "UpdateMitigationAction": {Verb: "Update", Resource: "MitigationAction", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/mitigationactions/actions/{actionName}"}, + "UpdatePackage": {Verb: "Update", Resource: "Package", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/packages/{packageName}"}, + "UpdatePackageConfiguration": {Verb: "Update", Resource: "PackageConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/package-configuration"}, + "UpdatePackageVersion": {Verb: "Update", Resource: "PackageVersion", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/packages/{packageName}/versions/{versionName}"}, + "UpdateProvisioningTemplate": {Verb: "Update", Resource: "ProvisioningTemplate", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/provisioning-templates/{templateName}"}, + "UpdateRoleAlias": {Verb: "Update", Resource: "RoleAlia", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/role-aliases/{roleAlias}"}, + "UpdateScheduledAudit": {Verb: "Update", Resource: "ScheduledAudit", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/audit/scheduledaudits/{scheduledAuditName}"}, + "UpdateSecurityProfile": {Verb: "Update", Resource: "SecurityProfile", OutputListKey: "additionalMetricsToRetain", OutputItemKey: "metricsExportConfig", Method: "PATCH", URI: "/security-profiles/{securityProfileName}"}, + "UpdateStream": {Verb: "Update", Resource: "Stream", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/streams/{streamId}"}, + "UpdateThing": {Verb: "Update", Resource: "Thing", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/things/{thingName}"}, + "UpdateThingGroup": {Verb: "Update", Resource: "ThingGroup", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/thing-groups/{thingGroupName}"}, + "UpdateThingGroupsForThing": {Verb: "Update", Resource: "ThingGroupsForThing", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/thing-groups/updateThingGroupsForThing"}, + "UpdateThingType": {Verb: "Update", Resource: "ThingType", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/thing-types/{thingTypeName}"}, + "UpdateTopicRuleDestination": {Verb: "Update", Resource: "TopicRuleDestination", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/destinations"}, + }) + crud.Register("iotdataplane", map[string]crud.OpMeta{ + "DeleteConnection": {Verb: "Delete", Resource: "Connection", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/connections/{clientId}"}, + "DeleteThingShadow": {Verb: "Delete", Resource: "ThingShadow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/things/{thingName}/shadow"}, + "GetRetainedMessage": {Verb: "Get", Resource: "RetainedMessage", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/retainedMessage/{topic}"}, + "GetThingShadow": {Verb: "Get", Resource: "ThingShadow", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/things/{thingName}/shadow"}, + "ListNamedShadowsForThing": {Verb: "List", Resource: "NamedShadowsForThing", OutputListKey: "results", OutputItemKey: "", Method: "GET", URI: "/api/things/shadow/ListNamedShadowsForThing/{thingName}"}, + "ListRetainedMessages": {Verb: "List", Resource: "RetainedMessage", OutputListKey: "retainedTopics", OutputItemKey: "", Method: "GET", URI: "/retainedMessage"}, + "UpdateThingShadow": {Verb: "Update", Resource: "ThingShadow", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/things/{thingName}/shadow"}, + }) + crud.Register("iotwireless", map[string]crud.OpMeta{ + "CreateDestination": {Verb: "Create", Resource: "Destination", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/destinations"}, + "CreateDeviceProfile": {Verb: "Create", Resource: "DeviceProfile", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/device-profiles"}, + "CreateFuotaTask": {Verb: "Create", Resource: "FuotaTask", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/fuota-tasks"}, + "CreateMulticastGroup": {Verb: "Create", Resource: "MulticastGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/multicast-groups"}, + "CreateNetworkAnalyzerConfiguration": {Verb: "Create", Resource: "NetworkAnalyzerConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/network-analyzer-configurations"}, + "CreateServiceProfile": {Verb: "Create", Resource: "ServiceProfile", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/service-profiles"}, + "CreateWirelessDevice": {Verb: "Create", Resource: "WirelessDevice", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/wireless-devices"}, + "CreateWirelessGateway": {Verb: "Create", Resource: "WirelessGateway", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/wireless-gateways"}, + "CreateWirelessGatewayTask": {Verb: "Create", Resource: "WirelessGatewayTask", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/wireless-gateways/{Id}/tasks"}, + "CreateWirelessGatewayTaskDefinition": {Verb: "Create", Resource: "WirelessGatewayTaskDefinition", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/wireless-gateway-task-definitions"}, + "DeleteDestination": {Verb: "Delete", Resource: "Destination", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/destinations/{Name}"}, + "DeleteDeviceProfile": {Verb: "Delete", Resource: "DeviceProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/device-profiles/{Id}"}, + "DeleteFuotaTask": {Verb: "Delete", Resource: "FuotaTask", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/fuota-tasks/{Id}"}, + "DeleteMulticastGroup": {Verb: "Delete", Resource: "MulticastGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/multicast-groups/{Id}"}, + "DeleteNetworkAnalyzerConfiguration": {Verb: "Delete", Resource: "NetworkAnalyzerConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/network-analyzer-configurations/{ConfigurationName}"}, + "DeleteQueuedMessages": {Verb: "Delete", Resource: "QueuedMessage", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless-devices/{Id}/data"}, + "DeleteServiceProfile": {Verb: "Delete", Resource: "ServiceProfile", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/service-profiles/{Id}"}, + "DeleteWirelessDevice": {Verb: "Delete", Resource: "WirelessDevice", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless-devices/{Id}"}, + "DeleteWirelessDeviceImportTask": {Verb: "Delete", Resource: "WirelessDeviceImportTask", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless_device_import_task/{Id}"}, + "DeleteWirelessGateway": {Verb: "Delete", Resource: "WirelessGateway", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless-gateways/{Id}"}, + "DeleteWirelessGatewayTask": {Verb: "Delete", Resource: "WirelessGatewayTask", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless-gateways/{Id}/tasks"}, + "DeleteWirelessGatewayTaskDefinition": {Verb: "Delete", Resource: "WirelessGatewayTaskDefinition", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/wireless-gateway-task-definitions/{Id}"}, + "DeregisterWirelessDevice": {Verb: "Delete", Resource: "WirelessDevice", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/wireless-devices/{Identifier}/deregister"}, + "GetDestination": {Verb: "Get", Resource: "Destination", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/destinations/{Name}"}, + "GetDeviceProfile": {Verb: "Get", Resource: "DeviceProfile", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/device-profiles/{Id}"}, + "GetEventConfigurationByResourceTypes": {Verb: "Get", Resource: "EventConfigurationByResourceType", OutputListKey: "", OutputItemKey: "ConnectionStatus", Method: "GET", URI: "/event-configurations-resource-types"}, + "GetFuotaTask": {Verb: "Get", Resource: "FuotaTask", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/fuota-tasks/{Id}"}, + "GetLogLevelsByResourceTypes": {Verb: "Get", Resource: "LogLevelsByResourceType", OutputListKey: "FuotaTaskLogOptions", OutputItemKey: "", Method: "GET", URI: "/log-levels"}, + "GetMetricConfiguration": {Verb: "Get", Resource: "MetricConfiguration", OutputListKey: "", OutputItemKey: "SummaryMetric", Method: "GET", URI: "/metric-configuration"}, + "GetMetrics": {Verb: "Get", Resource: "Metric", OutputListKey: "SummaryMetricQueryResults", OutputItemKey: "", Method: "POST", URI: "/metrics"}, + "GetMulticastGroup": {Verb: "Get", Resource: "MulticastGroup", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/multicast-groups/{Id}"}, + "GetMulticastGroupSession": {Verb: "Get", Resource: "MulticastGroupSession", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/multicast-groups/{Id}/session"}, + "GetNetworkAnalyzerConfiguration": {Verb: "Get", Resource: "NetworkAnalyzerConfiguration", OutputListKey: "MulticastGroups", OutputItemKey: "TraceContent", Method: "GET", URI: "/network-analyzer-configurations/{ConfigurationName}"}, + "GetPartnerAccount": {Verb: "Get", Resource: "PartnerAccount", OutputListKey: "", OutputItemKey: "Sidewalk", Method: "GET", URI: "/partner-accounts/{PartnerAccountId}"}, + "GetPosition": {Verb: "Get", Resource: "Position", OutputListKey: "Position", OutputItemKey: "Accuracy", Method: "GET", URI: "/positions/{ResourceIdentifier}"}, + "GetPositionConfiguration": {Verb: "Get", Resource: "PositionConfiguration", OutputListKey: "", OutputItemKey: "Solvers", Method: "GET", URI: "/position-configurations/{ResourceIdentifier}"}, + "GetPositionEstimate": {Verb: "Get", Resource: "PositionEstimate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/position-estimate"}, + "GetResourceEventConfiguration": {Verb: "Get", Resource: "ResourceEventConfiguration", OutputListKey: "", OutputItemKey: "ConnectionStatus", Method: "GET", URI: "/event-configurations/{Identifier}"}, + "GetResourceLogLevel": {Verb: "Get", Resource: "ResourceLogLevel", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/log-levels/{ResourceIdentifier}"}, + "GetResourcePosition": {Verb: "Get", Resource: "ResourcePosition", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resource-positions/{ResourceIdentifier}"}, + "GetServiceEndpoint": {Verb: "Get", Resource: "ServiceEndpoint", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/service-endpoint"}, + "GetServiceProfile": {Verb: "Get", Resource: "ServiceProfile", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/service-profiles/{Id}"}, + "GetWirelessDevice": {Verb: "Get", Resource: "WirelessDevice", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/wireless-devices/{Identifier}"}, + "GetWirelessDeviceImportTask": {Verb: "Get", Resource: "WirelessDeviceImportTask", OutputListKey: "", OutputItemKey: "Sidewalk", Method: "GET", URI: "/wireless_device_import_task/{Id}"}, + "GetWirelessDeviceStatistics": {Verb: "Get", Resource: "WirelessDeviceStatistic", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/wireless-devices/{WirelessDeviceId}/statistics"}, + "GetWirelessGateway": {Verb: "Get", Resource: "WirelessGateway", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/wireless-gateways/{Identifier}"}, + "GetWirelessGatewayCertificate": {Verb: "Get", Resource: "WirelessGatewayCertificate", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/wireless-gateways/{Id}/certificate"}, + "GetWirelessGatewayFirmwareInformation": {Verb: "Get", Resource: "WirelessGatewayFirmwareInformation", OutputListKey: "", OutputItemKey: "LoRaWAN", Method: "GET", URI: "/wireless-gateways/{Id}/firmware-information"}, + "GetWirelessGatewayStatistics": {Verb: "Get", Resource: "WirelessGatewayStatistic", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/wireless-gateways/{WirelessGatewayId}/statistics"}, + "GetWirelessGatewayTask": {Verb: "Get", Resource: "WirelessGatewayTask", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/wireless-gateways/{Id}/tasks"}, + "GetWirelessGatewayTaskDefinition": {Verb: "Get", Resource: "WirelessGatewayTaskDefinition", OutputListKey: "", OutputItemKey: "Update", Method: "GET", URI: "/wireless-gateway-task-definitions/{Id}"}, + "ListDestinations": {Verb: "List", Resource: "Destination", OutputListKey: "DestinationList", OutputItemKey: "", Method: "GET", URI: "/destinations"}, + "ListDeviceProfiles": {Verb: "List", Resource: "DeviceProfile", OutputListKey: "DeviceProfileList", OutputItemKey: "", Method: "GET", URI: "/device-profiles"}, + "ListDevicesForWirelessDeviceImportTask": {Verb: "List", Resource: "DevicesForWirelessDeviceImportTask", OutputListKey: "ImportedWirelessDeviceList", OutputItemKey: "Sidewalk", Method: "GET", URI: "/wireless_device_import_task"}, + "ListEventConfigurations": {Verb: "List", Resource: "EventConfiguration", OutputListKey: "EventConfigurationsList", OutputItemKey: "", Method: "GET", URI: "/event-configurations"}, + "ListFuotaTasks": {Verb: "List", Resource: "FuotaTask", OutputListKey: "FuotaTaskList", OutputItemKey: "", Method: "GET", URI: "/fuota-tasks"}, + "ListMulticastGroups": {Verb: "List", Resource: "MulticastGroup", OutputListKey: "MulticastGroupList", OutputItemKey: "", Method: "GET", URI: "/multicast-groups"}, + "ListMulticastGroupsByFuotaTask": {Verb: "List", Resource: "MulticastGroupsByFuotaTask", OutputListKey: "MulticastGroupList", OutputItemKey: "", Method: "GET", URI: "/fuota-tasks/{Id}/multicast-groups"}, + "ListNetworkAnalyzerConfigurations": {Verb: "List", Resource: "NetworkAnalyzerConfiguration", OutputListKey: "NetworkAnalyzerConfigurationList", OutputItemKey: "", Method: "GET", URI: "/network-analyzer-configurations"}, + "ListPartnerAccounts": {Verb: "List", Resource: "PartnerAccount", OutputListKey: "Sidewalk", OutputItemKey: "", Method: "GET", URI: "/partner-accounts"}, + "ListPositionConfigurations": {Verb: "List", Resource: "PositionConfiguration", OutputListKey: "PositionConfigurationList", OutputItemKey: "", Method: "GET", URI: "/position-configurations"}, + "ListQueuedMessages": {Verb: "List", Resource: "QueuedMessage", OutputListKey: "DownlinkQueueMessagesList", OutputItemKey: "", Method: "GET", URI: "/wireless-devices/{Id}/data"}, + "ListServiceProfiles": {Verb: "List", Resource: "ServiceProfile", OutputListKey: "ServiceProfileList", OutputItemKey: "", Method: "GET", URI: "/service-profiles"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/tags"}, + "ListWirelessDeviceImportTasks": {Verb: "List", Resource: "WirelessDeviceImportTask", OutputListKey: "WirelessDeviceImportTaskList", OutputItemKey: "", Method: "GET", URI: "/wireless_device_import_tasks"}, + "ListWirelessDevices": {Verb: "List", Resource: "WirelessDevice", OutputListKey: "WirelessDeviceList", OutputItemKey: "", Method: "GET", URI: "/wireless-devices"}, + "ListWirelessGatewayTaskDefinitions": {Verb: "List", Resource: "WirelessGatewayTaskDefinition", OutputListKey: "TaskDefinitions", OutputItemKey: "", Method: "GET", URI: "/wireless-gateway-task-definitions"}, + "ListWirelessGateways": {Verb: "List", Resource: "WirelessGateway", OutputListKey: "WirelessGatewayList", OutputItemKey: "", Method: "GET", URI: "/wireless-gateways"}, + "PutPositionConfiguration": {Verb: "Update", Resource: "PositionConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/position-configurations/{ResourceIdentifier}"}, + "PutResourceLogLevel": {Verb: "Update", Resource: "ResourceLogLevel", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/log-levels/{ResourceIdentifier}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags"}, + "UpdateDestination": {Verb: "Update", Resource: "Destination", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/destinations/{Name}"}, + "UpdateEventConfigurationByResourceTypes": {Verb: "Update", Resource: "EventConfigurationByResourceType", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/event-configurations-resource-types"}, + "UpdateFuotaTask": {Verb: "Update", Resource: "FuotaTask", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/fuota-tasks/{Id}"}, + "UpdateLogLevelsByResourceTypes": {Verb: "Update", Resource: "LogLevelsByResourceType", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/log-levels"}, + "UpdateMetricConfiguration": {Verb: "Update", Resource: "MetricConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/metric-configuration"}, + "UpdateMulticastGroup": {Verb: "Update", Resource: "MulticastGroup", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/multicast-groups/{Id}"}, + "UpdateNetworkAnalyzerConfiguration": {Verb: "Update", Resource: "NetworkAnalyzerConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/network-analyzer-configurations/{ConfigurationName}"}, + "UpdatePartnerAccount": {Verb: "Update", Resource: "PartnerAccount", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/partner-accounts/{PartnerAccountId}"}, + "UpdatePosition": {Verb: "Update", Resource: "Position", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/positions/{ResourceIdentifier}"}, + "UpdateResourceEventConfiguration": {Verb: "Update", Resource: "ResourceEventConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/event-configurations/{Identifier}"}, + "UpdateResourcePosition": {Verb: "Update", Resource: "ResourcePosition", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/resource-positions/{ResourceIdentifier}"}, + "UpdateWirelessDevice": {Verb: "Update", Resource: "WirelessDevice", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/wireless-devices/{Id}"}, + "UpdateWirelessDeviceImportTask": {Verb: "Update", Resource: "WirelessDeviceImportTask", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/wireless_device_import_task/{Id}"}, + "UpdateWirelessGateway": {Verb: "Update", Resource: "WirelessGateway", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/wireless-gateways/{Id}"}, + }) + crud.Register("kafka", map[string]crud.OpMeta{ + "CreateCluster": {Verb: "Create", Resource: "Cluster", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/clusters"}, + "CreateClusterV2": {Verb: "Create", Resource: "ClusterV2", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/api/v2/clusters"}, + "CreateConfiguration": {Verb: "Create", Resource: "Configuration", OutputListKey: "", OutputItemKey: "LatestRevision", Method: "POST", URI: "/v1/configurations"}, + "CreateReplicator": {Verb: "Create", Resource: "Replicator", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/replication/v1/replicators"}, + "CreateTopic": {Verb: "Create", Resource: "Topic", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/clusters/{ClusterArn}/topics"}, + "CreateVpcConnection": {Verb: "Create", Resource: "VpcConnection", OutputListKey: "ClientSubnets", OutputItemKey: "", Method: "POST", URI: "/v1/vpc-connection"}, + "DeleteCluster": {Verb: "Delete", Resource: "Cluster", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/clusters/{ClusterArn}"}, + "DeleteClusterPolicy": {Verb: "Delete", Resource: "ClusterPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/clusters/{ClusterArn}/policy"}, + "DeleteConfiguration": {Verb: "Delete", Resource: "Configuration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/configurations/{Arn}"}, + "DeleteReplicator": {Verb: "Delete", Resource: "Replicator", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/replication/v1/replicators/{ReplicatorArn}"}, + "DeleteTopic": {Verb: "Delete", Resource: "Topic", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/clusters/{ClusterArn}/topics/{TopicName}"}, + "DeleteVpcConnection": {Verb: "Delete", Resource: "VpcConnection", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/vpc-connection/{Arn}"}, + "DescribeCluster": {Verb: "Get", Resource: "Cluster", OutputListKey: "", OutputItemKey: "ClusterInfo", Method: "GET", URI: "/v1/clusters/{ClusterArn}"}, + "DescribeClusterOperation": {Verb: "Get", Resource: "ClusterOperation", OutputListKey: "", OutputItemKey: "ClusterOperationInfo", Method: "GET", URI: "/v1/operations/{ClusterOperationArn}"}, + "DescribeClusterOperationV2": {Verb: "Get", Resource: "ClusterOperationV2", OutputListKey: "", OutputItemKey: "ClusterOperationInfo", Method: "GET", URI: "/api/v2/operations/{ClusterOperationArn}"}, + "DescribeClusterV2": {Verb: "Get", Resource: "ClusterV2", OutputListKey: "", OutputItemKey: "ClusterInfo", Method: "GET", URI: "/api/v2/clusters/{ClusterArn}"}, + "DescribeConfiguration": {Verb: "Get", Resource: "Configuration", OutputListKey: "KafkaVersions", OutputItemKey: "LatestRevision", Method: "GET", URI: "/v1/configurations/{Arn}"}, + "DescribeConfigurationRevision": {Verb: "Get", Resource: "ConfigurationRevision", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/configurations/{Arn}/revisions/{Revision}"}, + "DescribeReplicator": {Verb: "Get", Resource: "Replicator", OutputListKey: "KafkaClusters", OutputItemKey: "StateInfo", Method: "GET", URI: "/replication/v1/replicators/{ReplicatorArn}"}, + "DescribeTopic": {Verb: "Get", Resource: "Topic", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/topics/{TopicName}"}, + "DescribeTopicPartitions": {Verb: "Get", Resource: "TopicPartition", OutputListKey: "Partitions", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/topics/{TopicName}/partitions"}, + "DescribeVpcConnection": {Verb: "Get", Resource: "VpcConnection", OutputListKey: "SecurityGroups", OutputItemKey: "", Method: "GET", URI: "/v1/vpc-connection/{Arn}"}, + "GetBootstrapBrokers": {Verb: "Get", Resource: "BootstrapBroker", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/bootstrap-brokers"}, + "GetClusterPolicy": {Verb: "Get", Resource: "ClusterPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/policy"}, + "GetCompatibleKafkaVersions": {Verb: "Get", Resource: "CompatibleKafkaVersion", OutputListKey: "CompatibleKafkaVersions", OutputItemKey: "", Method: "GET", URI: "/v1/compatible-kafka-versions"}, + "ListClientVpcConnections": {Verb: "List", Resource: "ClientVpcConnection", OutputListKey: "ClientVpcConnections", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/client-vpc-connections"}, + "ListClusterOperations": {Verb: "List", Resource: "ClusterOperation", OutputListKey: "ClusterOperationInfoList", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/operations"}, + "ListClusterOperationsV2": {Verb: "List", Resource: "ClusterOperationsV2", OutputListKey: "ClusterOperationInfoList", OutputItemKey: "", Method: "GET", URI: "/api/v2/clusters/{ClusterArn}/operations"}, + "ListClusters": {Verb: "List", Resource: "Cluster", OutputListKey: "ClusterInfoList", OutputItemKey: "", Method: "GET", URI: "/v1/clusters"}, + "ListClustersV2": {Verb: "List", Resource: "ClustersV2", OutputListKey: "ClusterInfoList", OutputItemKey: "", Method: "GET", URI: "/api/v2/clusters"}, + "ListConfigurationRevisions": {Verb: "List", Resource: "ConfigurationRevision", OutputListKey: "Revisions", OutputItemKey: "", Method: "GET", URI: "/v1/configurations/{Arn}/revisions"}, + "ListConfigurations": {Verb: "List", Resource: "Configuration", OutputListKey: "Configurations", OutputItemKey: "", Method: "GET", URI: "/v1/configurations"}, + "ListKafkaVersions": {Verb: "List", Resource: "KafkaVersion", OutputListKey: "KafkaVersions", OutputItemKey: "", Method: "GET", URI: "/v1/kafka-versions"}, + "ListNodes": {Verb: "List", Resource: "Node", OutputListKey: "NodeInfoList", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/nodes"}, + "ListReplicators": {Verb: "List", Resource: "Replicator", OutputListKey: "Replicators", OutputItemKey: "", Method: "GET", URI: "/replication/v1/replicators"}, + "ListScramSecrets": {Verb: "List", Resource: "ScramSecret", OutputListKey: "SecretArnList", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/scram-secrets"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/tags/{ResourceArn}"}, + "ListTopics": {Verb: "List", Resource: "Topic", OutputListKey: "Topics", OutputItemKey: "", Method: "GET", URI: "/v1/clusters/{ClusterArn}/topics"}, + "ListVpcConnections": {Verb: "List", Resource: "VpcConnection", OutputListKey: "VpcConnections", OutputItemKey: "", Method: "GET", URI: "/v1/vpc-connections"}, + "PutClusterPolicy": {Verb: "Update", Resource: "ClusterPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/policy"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{ResourceArn}"}, + "UpdateBrokerCount": {Verb: "Update", Resource: "BrokerCount", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/nodes/count"}, + "UpdateBrokerStorage": {Verb: "Update", Resource: "BrokerStorage", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/nodes/storage"}, + "UpdateBrokerType": {Verb: "Update", Resource: "BrokerType", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/nodes/type"}, + "UpdateClusterConfiguration": {Verb: "Update", Resource: "ClusterConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/configuration"}, + "UpdateClusterKafkaVersion": {Verb: "Update", Resource: "ClusterKafkaVersion", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/version"}, + "UpdateConfiguration": {Verb: "Update", Resource: "Configuration", OutputListKey: "", OutputItemKey: "LatestRevision", Method: "PUT", URI: "/v1/configurations/{Arn}"}, + "UpdateConnectivity": {Verb: "Update", Resource: "Connectivity", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/connectivity"}, + "UpdateMonitoring": {Verb: "Update", Resource: "Monitoring", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/monitoring"}, + "UpdateRebalancing": {Verb: "Update", Resource: "Rebalancing", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/rebalancing"}, + "UpdateReplicationInfo": {Verb: "Update", Resource: "ReplicationInfo", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/replication/v1/replicators/{ReplicatorArn}/replication-info"}, + "UpdateSecurity": {Verb: "Update", Resource: "Security", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/v1/clusters/{ClusterArn}/security"}, + "UpdateStorage": {Verb: "Update", Resource: "Storage", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/storage"}, + "UpdateTopic": {Verb: "Update", Resource: "Topic", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/clusters/{ClusterArn}/topics/{TopicName}"}, }) crud.Register("kendra", map[string]crud.OpMeta{ "BatchGetDocumentStatus": {Verb: "List", Resource: "DocumentStatu", OutputListKey: "DocumentStatusList", OutputItemKey: ""}, @@ -1503,14 +3034,14 @@ func init() { "UpdateThesaurus": {Verb: "Update", Resource: "Thesauru", OutputListKey: "", OutputItemKey: ""}, }) crud.Register("kendraranking", map[string]crud.OpMeta{ - "CreateRescoreExecutionPlan": {Verb: "Create", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: ""}, - "DeleteRescoreExecutionPlan": {Verb: "Delete", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: ""}, - "DescribeRescoreExecutionPlan": {Verb: "Get", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: "CapacityUnits"}, - "ListRescoreExecutionPlans": {Verb: "List", Resource: "RescoreExecutionPlan", OutputListKey: "SummaryItems", OutputItemKey: ""}, + "CreateRescoreExecutionPlan": {Verb: "Create", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/rescore-execution-plans"}, + "DeleteRescoreExecutionPlan": {Verb: "Delete", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/rescore-execution-plans/{Id}"}, + "DescribeRescoreExecutionPlan": {Verb: "Get", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: "CapacityUnits", Method: "GET", URI: "/rescore-execution-plans/{Id}"}, + "ListRescoreExecutionPlans": {Verb: "List", Resource: "RescoreExecutionPlan", OutputListKey: "SummaryItems", OutputItemKey: "", Method: "GET", URI: "/rescore-execution-plans"}, "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: ""}, "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, - "UpdateRescoreExecutionPlan": {Verb: "Update", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: ""}, + "UpdateRescoreExecutionPlan": {Verb: "Update", Resource: "RescoreExecutionPlan", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/rescore-execution-plans/{Id}"}, }) crud.Register("kinesis", map[string]crud.OpMeta{ "CreateStream": {Verb: "Create", Resource: "Stream", OutputListKey: "", OutputItemKey: ""}, @@ -1596,6 +3127,275 @@ func init() { "UpdateKeyDescription": {Verb: "Update", Resource: "KeyDescription", OutputListKey: "", OutputItemKey: ""}, "UpdatePrimaryRegion": {Verb: "Update", Resource: "PrimaryRegion", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("lakeformation", map[string]crud.OpMeta{ + "CreateDataCellsFilter": {Verb: "Create", Resource: "DataCellsFilter", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/CreateDataCellsFilter"}, + "CreateLFTag": {Verb: "Create", Resource: "LFTag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/CreateLFTag"}, + "CreateLFTagExpression": {Verb: "Create", Resource: "LFTagExpression", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/CreateLFTagExpression"}, + "CreateLakeFormationIdentityCenterConfiguration": {Verb: "Create", Resource: "LakeFormationIdentityCenterConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/CreateLakeFormationIdentityCenterConfiguration"}, + "CreateLakeFormationOptIn": {Verb: "Create", Resource: "LakeFormationOptIn", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/CreateLakeFormationOptIn"}, + "DeleteDataCellsFilter": {Verb: "Delete", Resource: "DataCellsFilter", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteDataCellsFilter"}, + "DeleteLFTag": {Verb: "Delete", Resource: "LFTag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteLFTag"}, + "DeleteLFTagExpression": {Verb: "Delete", Resource: "LFTagExpression", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteLFTagExpression"}, + "DeleteLakeFormationIdentityCenterConfiguration": {Verb: "Delete", Resource: "LakeFormationIdentityCenterConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteLakeFormationIdentityCenterConfiguration"}, + "DeleteLakeFormationOptIn": {Verb: "Delete", Resource: "LakeFormationOptIn", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteLakeFormationOptIn"}, + "DeleteObjectsOnCancel": {Verb: "Delete", Resource: "ObjectsOnCancel", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteObjectsOnCancel"}, + "DeregisterResource": {Verb: "Delete", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeregisterResource"}, + "DescribeLakeFormationIdentityCenterConfiguration": {Verb: "Get", Resource: "LakeFormationIdentityCenterConfiguration", OutputListKey: "ServiceIntegrations", OutputItemKey: "ExternalFiltering", Method: "POST", URI: "/DescribeLakeFormationIdentityCenterConfiguration"}, + "DescribeResource": {Verb: "Get", Resource: "Resource", OutputListKey: "", OutputItemKey: "ResourceInfo", Method: "POST", URI: "/DescribeResource"}, + "DescribeTransaction": {Verb: "Get", Resource: "Transaction", OutputListKey: "", OutputItemKey: "TransactionDescription", Method: "POST", URI: "/DescribeTransaction"}, + "GetDataCellsFilter": {Verb: "Get", Resource: "DataCellsFilter", OutputListKey: "", OutputItemKey: "DataCellsFilter", Method: "POST", URI: "/GetDataCellsFilter"}, + "GetDataLakePrincipal": {Verb: "Get", Resource: "DataLakePrincipal", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetDataLakePrincipal"}, + "GetDataLakeSettings": {Verb: "Get", Resource: "DataLakeSetting", OutputListKey: "", OutputItemKey: "DataLakeSettings", Method: "POST", URI: "/GetDataLakeSettings"}, + "GetEffectivePermissionsForPath": {Verb: "Get", Resource: "EffectivePermissionsForPath", OutputListKey: "Permissions", OutputItemKey: "", Method: "POST", URI: "/GetEffectivePermissionsForPath"}, + "GetLFTag": {Verb: "Get", Resource: "LFTag", OutputListKey: "TagValues", OutputItemKey: "", Method: "POST", URI: "/GetLFTag"}, + "GetLFTagExpression": {Verb: "Get", Resource: "LFTagExpression", OutputListKey: "Expression", OutputItemKey: "", Method: "POST", URI: "/GetLFTagExpression"}, + "GetQueryState": {Verb: "Get", Resource: "QueryState", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetQueryState"}, + "GetQueryStatistics": {Verb: "Get", Resource: "QueryStatistic", OutputListKey: "", OutputItemKey: "ExecutionStatistics", Method: "POST", URI: "/GetQueryStatistics"}, + "GetResourceLFTags": {Verb: "Get", Resource: "ResourceLFTag", OutputListKey: "LFTagOnDatabase", OutputItemKey: "", Method: "POST", URI: "/GetResourceLFTags"}, + "GetTableObjects": {Verb: "Get", Resource: "TableObject", OutputListKey: "Objects", OutputItemKey: "", Method: "POST", URI: "/GetTableObjects"}, + "GetTemporaryDataLocationCredentials": {Verb: "Get", Resource: "TemporaryDataLocationCredential", OutputListKey: "AccessibleDataLocations", OutputItemKey: "Credentials", Method: "POST", URI: "/GetTemporaryDataLocationCredentials"}, + "GetTemporaryGluePartitionCredentials": {Verb: "Get", Resource: "TemporaryGluePartitionCredential", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetTemporaryGluePartitionCredentials"}, + "GetTemporaryGlueTableCredentials": {Verb: "Get", Resource: "TemporaryGlueTableCredential", OutputListKey: "VendedS3Path", OutputItemKey: "", Method: "POST", URI: "/GetTemporaryGlueTableCredentials"}, + "GetWorkUnitResults": {Verb: "Get", Resource: "WorkUnitResult", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetWorkUnitResults"}, + "GetWorkUnits": {Verb: "Get", Resource: "WorkUnit", OutputListKey: "WorkUnitRanges", OutputItemKey: "", Method: "POST", URI: "/GetWorkUnits"}, + "ListDataCellsFilter": {Verb: "List", Resource: "DataCellsFilter", OutputListKey: "DataCellsFilters", OutputItemKey: "", Method: "POST", URI: "/ListDataCellsFilter"}, + "ListLFTagExpressions": {Verb: "List", Resource: "LFTagExpression", OutputListKey: "LFTagExpressions", OutputItemKey: "", Method: "POST", URI: "/ListLFTagExpressions"}, + "ListLFTags": {Verb: "List", Resource: "LFTag", OutputListKey: "LFTags", OutputItemKey: "", Method: "POST", URI: "/ListLFTags"}, + "ListLakeFormationOptIns": {Verb: "List", Resource: "LakeFormationOptIn", OutputListKey: "LakeFormationOptInsInfoList", OutputItemKey: "", Method: "POST", URI: "/ListLakeFormationOptIns"}, + "ListPermissions": {Verb: "List", Resource: "Permission", OutputListKey: "PrincipalResourcePermissions", OutputItemKey: "", Method: "POST", URI: "/ListPermissions"}, + "ListResources": {Verb: "List", Resource: "Resource", OutputListKey: "ResourceInfoList", OutputItemKey: "", Method: "POST", URI: "/ListResources"}, + "ListTableStorageOptimizers": {Verb: "List", Resource: "TableStorageOptimizer", OutputListKey: "StorageOptimizerList", OutputItemKey: "", Method: "POST", URI: "/ListTableStorageOptimizers"}, + "ListTransactions": {Verb: "List", Resource: "Transaction", OutputListKey: "Transactions", OutputItemKey: "", Method: "POST", URI: "/ListTransactions"}, + "PutDataLakeSettings": {Verb: "Update", Resource: "DataLakeSetting", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/PutDataLakeSettings"}, + "RegisterResource": {Verb: "Create", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/RegisterResource"}, + "UpdateDataCellsFilter": {Verb: "Update", Resource: "DataCellsFilter", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateDataCellsFilter"}, + "UpdateLFTag": {Verb: "Update", Resource: "LFTag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateLFTag"}, + "UpdateLFTagExpression": {Verb: "Update", Resource: "LFTagExpression", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateLFTagExpression"}, + "UpdateLakeFormationIdentityCenterConfiguration": {Verb: "Update", Resource: "LakeFormationIdentityCenterConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateLakeFormationIdentityCenterConfiguration"}, + "UpdateResource": {Verb: "Update", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateResource"}, + "UpdateTableObjects": {Verb: "Update", Resource: "TableObject", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateTableObjects"}, + "UpdateTableStorageOptimizer": {Verb: "Update", Resource: "TableStorageOptimizer", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateTableStorageOptimizer"}, + }) + crud.Register("lambda", map[string]crud.OpMeta{ + "CreateAlias": {Verb: "Create", Resource: "Alia", OutputListKey: "", OutputItemKey: "RoutingConfig", Method: "POST", URI: "/2015-03-31/functions/{FunctionName}/aliases"}, + "CreateCapacityProvider": {Verb: "Create", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "CapacityProvider", Method: "POST", URI: "/2025-11-30/capacity-providers"}, + "CreateCodeSigningConfig": {Verb: "Create", Resource: "CodeSigningConfig", OutputListKey: "", OutputItemKey: "CodeSigningConfig", Method: "POST", URI: "/2020-04-22/code-signing-configs"}, + "CreateEventSourceMapping": {Verb: "Create", Resource: "EventSourceMapping", OutputListKey: "FunctionResponseTypes", OutputItemKey: "AmazonManagedKafkaEventSourceConfig", Method: "POST", URI: "/2015-03-31/event-source-mappings"}, + "CreateFunction": {Verb: "Create", Resource: "Function", OutputListKey: "Architectures", OutputItemKey: "CapacityProviderConfig", Method: "POST", URI: "/2015-03-31/functions"}, + "CreateFunctionUrlConfig": {Verb: "Create", Resource: "FunctionUrlConfig", OutputListKey: "", OutputItemKey: "Cors", Method: "POST", URI: "/2021-10-31/functions/{FunctionName}/url"}, + "DeleteAlias": {Verb: "Delete", Resource: "Alia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-03-31/functions/{FunctionName}/aliases/{Name}"}, + "DeleteCapacityProvider": {Verb: "Delete", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "CapacityProvider", Method: "DELETE", URI: "/2025-11-30/capacity-providers/{CapacityProviderName}"}, + "DeleteCodeSigningConfig": {Verb: "Delete", Resource: "CodeSigningConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2020-04-22/code-signing-configs/{CodeSigningConfigArn}"}, + "DeleteEventSourceMapping": {Verb: "Delete", Resource: "EventSourceMapping", OutputListKey: "FunctionResponseTypes", OutputItemKey: "AmazonManagedKafkaEventSourceConfig", Method: "DELETE", URI: "/2015-03-31/event-source-mappings/{UUID}"}, + "DeleteFunction": {Verb: "Delete", Resource: "Function", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2015-03-31/functions/{FunctionName}"}, + "DeleteFunctionCodeSigningConfig": {Verb: "Delete", Resource: "FunctionCodeSigningConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2020-06-30/functions/{FunctionName}/code-signing-config"}, + "DeleteFunctionConcurrency": {Verb: "Delete", Resource: "FunctionConcurrency", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2017-10-31/functions/{FunctionName}/concurrency"}, + "DeleteFunctionEventInvokeConfig": {Verb: "Delete", Resource: "FunctionEventInvokeConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2019-09-25/functions/{FunctionName}/event-invoke-config"}, + "DeleteFunctionUrlConfig": {Verb: "Delete", Resource: "FunctionUrlConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-10-31/functions/{FunctionName}/url"}, + "DeleteLayerVersion": {Verb: "Delete", Resource: "LayerVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2018-10-31/layers/{LayerName}/versions/{VersionNumber}"}, + "DeleteProvisionedConcurrencyConfig": {Verb: "Delete", Resource: "ProvisionedConcurrencyConfig", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2019-09-30/functions/{FunctionName}/provisioned-concurrency"}, + "GetAccountSettings": {Verb: "Get", Resource: "AccountSetting", OutputListKey: "", OutputItemKey: "AccountLimit", Method: "GET", URI: "/2016-08-19/account-settings"}, + "GetAlias": {Verb: "Get", Resource: "Alia", OutputListKey: "", OutputItemKey: "RoutingConfig", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}/aliases/{Name}"}, + "GetCapacityProvider": {Verb: "Get", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "CapacityProvider", Method: "GET", URI: "/2025-11-30/capacity-providers/{CapacityProviderName}"}, + "GetCodeSigningConfig": {Verb: "Get", Resource: "CodeSigningConfig", OutputListKey: "", OutputItemKey: "CodeSigningConfig", Method: "GET", URI: "/2020-04-22/code-signing-configs/{CodeSigningConfigArn}"}, + "GetDurableExecution": {Verb: "Get", Resource: "DurableExecution", OutputListKey: "", OutputItemKey: "Error", Method: "GET", URI: "/2025-12-01/durable-executions/{DurableExecutionArn}"}, + "GetDurableExecutionHistory": {Verb: "Get", Resource: "DurableExecutionHistory", OutputListKey: "Events", OutputItemKey: "", Method: "GET", URI: "/2025-12-01/durable-executions/{DurableExecutionArn}/history"}, + "GetDurableExecutionState": {Verb: "Get", Resource: "DurableExecutionState", OutputListKey: "Operations", OutputItemKey: "", Method: "GET", URI: "/2025-12-01/durable-executions/{DurableExecutionArn}/state"}, + "GetEventSourceMapping": {Verb: "Get", Resource: "EventSourceMapping", OutputListKey: "FunctionResponseTypes", OutputItemKey: "AmazonManagedKafkaEventSourceConfig", Method: "GET", URI: "/2015-03-31/event-source-mappings/{UUID}"}, + "GetFunction": {Verb: "Get", Resource: "Function", OutputListKey: "", OutputItemKey: "Code", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}"}, + "GetFunctionCodeSigningConfig": {Verb: "Get", Resource: "FunctionCodeSigningConfig", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2020-06-30/functions/{FunctionName}/code-signing-config"}, + "GetFunctionConcurrency": {Verb: "Get", Resource: "FunctionConcurrency", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2019-09-30/functions/{FunctionName}/concurrency"}, + "GetFunctionConfiguration": {Verb: "Get", Resource: "FunctionConfiguration", OutputListKey: "Architectures", OutputItemKey: "CapacityProviderConfig", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}/configuration"}, + "GetFunctionEventInvokeConfig": {Verb: "Get", Resource: "FunctionEventInvokeConfig", OutputListKey: "", OutputItemKey: "DestinationConfig", Method: "GET", URI: "/2019-09-25/functions/{FunctionName}/event-invoke-config"}, + "GetFunctionRecursionConfig": {Verb: "Get", Resource: "FunctionRecursionConfig", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2024-08-31/functions/{FunctionName}/recursion-config"}, + "GetFunctionScalingConfig": {Verb: "Get", Resource: "FunctionScalingConfig", OutputListKey: "", OutputItemKey: "AppliedFunctionScalingConfig", Method: "GET", URI: "/2025-11-30/functions/{FunctionName}/function-scaling-config"}, + "GetFunctionUrlConfig": {Verb: "Get", Resource: "FunctionUrlConfig", OutputListKey: "", OutputItemKey: "Cors", Method: "GET", URI: "/2021-10-31/functions/{FunctionName}/url"}, + "GetLayerVersion": {Verb: "Get", Resource: "LayerVersion", OutputListKey: "CompatibleArchitectures", OutputItemKey: "Content", Method: "GET", URI: "/2018-10-31/layers/{LayerName}/versions/{VersionNumber}"}, + "GetLayerVersionByArn": {Verb: "Get", Resource: "LayerVersionByArn", OutputListKey: "CompatibleArchitectures", OutputItemKey: "Content", Method: "GET", URI: "/2018-10-31/layers?find=LayerVersion"}, + "GetLayerVersionPolicy": {Verb: "Get", Resource: "LayerVersionPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2018-10-31/layers/{LayerName}/versions/{VersionNumber}/policy"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}/policy"}, + "GetProvisionedConcurrencyConfig": {Verb: "Get", Resource: "ProvisionedConcurrencyConfig", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2019-09-30/functions/{FunctionName}/provisioned-concurrency"}, + "GetRuntimeManagementConfig": {Verb: "Get", Resource: "RuntimeManagementConfig", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-07-20/functions/{FunctionName}/runtime-management-config"}, + "ListAliases": {Verb: "List", Resource: "Aliase", OutputListKey: "Aliases", OutputItemKey: "", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}/aliases"}, + "ListCapacityProviders": {Verb: "List", Resource: "CapacityProvider", OutputListKey: "CapacityProviders", OutputItemKey: "", Method: "GET", URI: "/2025-11-30/capacity-providers"}, + "ListCodeSigningConfigs": {Verb: "List", Resource: "CodeSigningConfig", OutputListKey: "CodeSigningConfigs", OutputItemKey: "", Method: "GET", URI: "/2020-04-22/code-signing-configs"}, + "ListDurableExecutionsByFunction": {Verb: "List", Resource: "DurableExecutionsByFunction", OutputListKey: "DurableExecutions", OutputItemKey: "", Method: "GET", URI: "/2025-12-01/functions/{FunctionName}/durable-executions"}, + "ListEventSourceMappings": {Verb: "List", Resource: "EventSourceMapping", OutputListKey: "EventSourceMappings", OutputItemKey: "", Method: "GET", URI: "/2015-03-31/event-source-mappings"}, + "ListFunctionEventInvokeConfigs": {Verb: "List", Resource: "FunctionEventInvokeConfig", OutputListKey: "FunctionEventInvokeConfigs", OutputItemKey: "", Method: "GET", URI: "/2019-09-25/functions/{FunctionName}/event-invoke-config/list"}, + "ListFunctionUrlConfigs": {Verb: "List", Resource: "FunctionUrlConfig", OutputListKey: "FunctionUrlConfigs", OutputItemKey: "", Method: "GET", URI: "/2021-10-31/functions/{FunctionName}/urls"}, + "ListFunctionVersionsByCapacityProvider": {Verb: "List", Resource: "FunctionVersionsByCapacityProvider", OutputListKey: "FunctionVersions", OutputItemKey: "", Method: "GET", URI: "/2025-11-30/capacity-providers/{CapacityProviderName}/function-versions"}, + "ListFunctions": {Verb: "List", Resource: "Function", OutputListKey: "Functions", OutputItemKey: "", Method: "GET", URI: "/2015-03-31/functions"}, + "ListFunctionsByCodeSigningConfig": {Verb: "List", Resource: "FunctionsByCodeSigningConfig", OutputListKey: "FunctionArns", OutputItemKey: "", Method: "GET", URI: "/2020-04-22/code-signing-configs/{CodeSigningConfigArn}/functions"}, + "ListLayerVersions": {Verb: "List", Resource: "LayerVersion", OutputListKey: "LayerVersions", OutputItemKey: "", Method: "GET", URI: "/2018-10-31/layers/{LayerName}/versions"}, + "ListLayers": {Verb: "List", Resource: "Layer", OutputListKey: "Layers", OutputItemKey: "", Method: "GET", URI: "/2018-10-31/layers"}, + "ListProvisionedConcurrencyConfigs": {Verb: "List", Resource: "ProvisionedConcurrencyConfig", OutputListKey: "ProvisionedConcurrencyConfigs", OutputItemKey: "", Method: "GET", URI: "/2019-09-30/functions/{FunctionName}/provisioned-concurrency?List=ALL"}, + "ListTags": {Verb: "List", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2017-03-31/tags/{Resource}"}, + "ListVersionsByFunction": {Verb: "List", Resource: "VersionsByFunction", OutputListKey: "Versions", OutputItemKey: "", Method: "GET", URI: "/2015-03-31/functions/{FunctionName}/versions"}, + "PutFunctionCodeSigningConfig": {Verb: "Update", Resource: "FunctionCodeSigningConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2020-06-30/functions/{FunctionName}/code-signing-config"}, + "PutFunctionConcurrency": {Verb: "Update", Resource: "FunctionConcurrency", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2017-10-31/functions/{FunctionName}/concurrency"}, + "PutFunctionEventInvokeConfig": {Verb: "Update", Resource: "FunctionEventInvokeConfig", OutputListKey: "", OutputItemKey: "DestinationConfig", Method: "PUT", URI: "/2019-09-25/functions/{FunctionName}/event-invoke-config"}, + "PutFunctionRecursionConfig": {Verb: "Update", Resource: "FunctionRecursionConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2024-08-31/functions/{FunctionName}/recursion-config"}, + "PutFunctionScalingConfig": {Verb: "Update", Resource: "FunctionScalingConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2025-11-30/functions/{FunctionName}/function-scaling-config"}, + "PutProvisionedConcurrencyConfig": {Verb: "Update", Resource: "ProvisionedConcurrencyConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2019-09-30/functions/{FunctionName}/provisioned-concurrency"}, + "PutRuntimeManagementConfig": {Verb: "Update", Resource: "RuntimeManagementConfig", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2021-07-20/functions/{FunctionName}/runtime-management-config"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2017-03-31/tags/{Resource}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2017-03-31/tags/{Resource}"}, + "UpdateAlias": {Verb: "Update", Resource: "Alia", OutputListKey: "", OutputItemKey: "RoutingConfig", Method: "PUT", URI: "/2015-03-31/functions/{FunctionName}/aliases/{Name}"}, + "UpdateCapacityProvider": {Verb: "Update", Resource: "CapacityProvider", OutputListKey: "", OutputItemKey: "CapacityProvider", Method: "PUT", URI: "/2025-11-30/capacity-providers/{CapacityProviderName}"}, + "UpdateCodeSigningConfig": {Verb: "Update", Resource: "CodeSigningConfig", OutputListKey: "", OutputItemKey: "CodeSigningConfig", Method: "PUT", URI: "/2020-04-22/code-signing-configs/{CodeSigningConfigArn}"}, + "UpdateEventSourceMapping": {Verb: "Update", Resource: "EventSourceMapping", OutputListKey: "FunctionResponseTypes", OutputItemKey: "AmazonManagedKafkaEventSourceConfig", Method: "PUT", URI: "/2015-03-31/event-source-mappings/{UUID}"}, + "UpdateFunctionCode": {Verb: "Update", Resource: "FunctionCode", OutputListKey: "Architectures", OutputItemKey: "CapacityProviderConfig", Method: "PUT", URI: "/2015-03-31/functions/{FunctionName}/code"}, + "UpdateFunctionConfiguration": {Verb: "Update", Resource: "FunctionConfiguration", OutputListKey: "Architectures", OutputItemKey: "CapacityProviderConfig", Method: "PUT", URI: "/2015-03-31/functions/{FunctionName}/configuration"}, + "UpdateFunctionEventInvokeConfig": {Verb: "Update", Resource: "FunctionEventInvokeConfig", OutputListKey: "", OutputItemKey: "DestinationConfig", Method: "POST", URI: "/2019-09-25/functions/{FunctionName}/event-invoke-config"}, + "UpdateFunctionUrlConfig": {Verb: "Update", Resource: "FunctionUrlConfig", OutputListKey: "", OutputItemKey: "Cors", Method: "PUT", URI: "/2021-10-31/functions/{FunctionName}/url"}, + }) + crud.Register("lexmodelbuildingservice", map[string]crud.OpMeta{ + "CreateBotVersion": {Verb: "Create", Resource: "BotVersion", OutputListKey: "intents", OutputItemKey: "abortStatement", Method: "POST", URI: "/bots/{name}/versions"}, + "CreateIntentVersion": {Verb: "Create", Resource: "IntentVersion", OutputListKey: "inputContexts", OutputItemKey: "conclusionStatement", Method: "POST", URI: "/intents/{name}/versions"}, + "CreateSlotTypeVersion": {Verb: "Create", Resource: "SlotTypeVersion", OutputListKey: "enumerationValues", OutputItemKey: "", Method: "POST", URI: "/slottypes/{name}/versions"}, + "DeleteBot": {Verb: "Delete", Resource: "Bot", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{name}"}, + "DeleteBotAlias": {Verb: "Delete", Resource: "BotAlia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botName}/aliases/{name}"}, + "DeleteBotChannelAssociation": {Verb: "Delete", Resource: "BotChannelAssociation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botName}/aliases/{botAlias}/channels/{name}"}, + "DeleteBotVersion": {Verb: "Delete", Resource: "BotVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{name}/versions/{version}"}, + "DeleteIntent": {Verb: "Delete", Resource: "Intent", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/intents/{name}"}, + "DeleteIntentVersion": {Verb: "Delete", Resource: "IntentVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/intents/{name}/versions/{version}"}, + "DeleteSlotType": {Verb: "Delete", Resource: "SlotType", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/slottypes/{name}"}, + "DeleteSlotTypeVersion": {Verb: "Delete", Resource: "SlotTypeVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/slottypes/{name}/version/{version}"}, + "DeleteUtterances": {Verb: "Delete", Resource: "Utterance", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botName}/utterances/{userId}"}, + "GetBot": {Verb: "Get", Resource: "Bot", OutputListKey: "intents", OutputItemKey: "abortStatement", Method: "GET", URI: "/bots/{name}/versions/{versionOrAlias}"}, + "GetBotAlias": {Verb: "Get", Resource: "BotAlia", OutputListKey: "", OutputItemKey: "conversationLogs", Method: "GET", URI: "/bots/{botName}/aliases/{name}"}, + "GetBotAliases": {Verb: "Get", Resource: "BotAliase", OutputListKey: "BotAliases", OutputItemKey: "", Method: "GET", URI: "/bots/{botName}/aliases"}, + "GetBotChannelAssociation": {Verb: "Get", Resource: "BotChannelAssociation", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/bots/{botName}/aliases/{botAlias}/channels/{name}"}, + "GetBotChannelAssociations": {Verb: "Get", Resource: "BotChannelAssociation", OutputListKey: "botChannelAssociations", OutputItemKey: "", Method: "GET", URI: "/bots/{botName}/aliases/{botAlias}/channels"}, + "GetBotVersions": {Verb: "Get", Resource: "BotVersion", OutputListKey: "bots", OutputItemKey: "", Method: "GET", URI: "/bots/{name}/versions"}, + "GetBots": {Verb: "Get", Resource: "Bot", OutputListKey: "bots", OutputItemKey: "", Method: "GET", URI: "/bots"}, + "GetBuiltinIntent": {Verb: "Get", Resource: "BuiltinIntent", OutputListKey: "slots", OutputItemKey: "", Method: "GET", URI: "/builtins/intents/{signature}"}, + "GetBuiltinIntents": {Verb: "Get", Resource: "BuiltinIntent", OutputListKey: "intents", OutputItemKey: "", Method: "GET", URI: "/builtins/intents"}, + "GetBuiltinSlotTypes": {Verb: "Get", Resource: "BuiltinSlotType", OutputListKey: "slotTypes", OutputItemKey: "", Method: "GET", URI: "/builtins/slottypes"}, + "GetExport": {Verb: "Get", Resource: "Export", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/exports"}, + "GetImport": {Verb: "Get", Resource: "Import", OutputListKey: "failureReason", OutputItemKey: "", Method: "GET", URI: "/imports/{importId}"}, + "GetIntent": {Verb: "Get", Resource: "Intent", OutputListKey: "inputContexts", OutputItemKey: "conclusionStatement", Method: "GET", URI: "/intents/{name}/versions/{version}"}, + "GetIntentVersions": {Verb: "Get", Resource: "IntentVersion", OutputListKey: "intents", OutputItemKey: "", Method: "GET", URI: "/intents/{name}/versions"}, + "GetIntents": {Verb: "Get", Resource: "Intent", OutputListKey: "intents", OutputItemKey: "", Method: "GET", URI: "/intents"}, + "GetMigration": {Verb: "Get", Resource: "Migration", OutputListKey: "alerts", OutputItemKey: "", Method: "GET", URI: "/migrations/{migrationId}"}, + "GetMigrations": {Verb: "Get", Resource: "Migration", OutputListKey: "migrationSummaries", OutputItemKey: "", Method: "GET", URI: "/migrations"}, + "GetSlotType": {Verb: "Get", Resource: "SlotType", OutputListKey: "enumerationValues", OutputItemKey: "", Method: "GET", URI: "/slottypes/{name}/versions/{version}"}, + "GetSlotTypeVersions": {Verb: "Get", Resource: "SlotTypeVersion", OutputListKey: "slotTypes", OutputItemKey: "", Method: "GET", URI: "/slottypes/{name}/versions"}, + "GetSlotTypes": {Verb: "Get", Resource: "SlotType", OutputListKey: "slotTypes", OutputItemKey: "", Method: "GET", URI: "/slottypes"}, + "GetUtterancesView": {Verb: "Get", Resource: "UtterancesView", OutputListKey: "utterances", OutputItemKey: "", Method: "GET", URI: "/bots/{botName}/utterances?view=aggregation"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "PutBot": {Verb: "Update", Resource: "Bot", OutputListKey: "intents", OutputItemKey: "abortStatement", Method: "PUT", URI: "/bots/{name}/versions/$LATEST"}, + "PutBotAlias": {Verb: "Update", Resource: "BotAlia", OutputListKey: "tags", OutputItemKey: "conversationLogs", Method: "PUT", URI: "/bots/{botName}/aliases/{name}"}, + "PutIntent": {Verb: "Update", Resource: "Intent", OutputListKey: "inputContexts", OutputItemKey: "conclusionStatement", Method: "PUT", URI: "/intents/{name}/versions/$LATEST"}, + "PutSlotType": {Verb: "Update", Resource: "SlotType", OutputListKey: "enumerationValues", OutputItemKey: "", Method: "PUT", URI: "/slottypes/{name}/versions/$LATEST"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + }) + crud.Register("lexmodelsv2", map[string]crud.OpMeta{ + "CreateBot": {Verb: "Create", Resource: "Bot", OutputListKey: "botMembers", OutputItemKey: "dataPrivacy", Method: "PUT", URI: "/bots"}, + "CreateBotAlias": {Verb: "Create", Resource: "BotAlia", OutputListKey: "", OutputItemKey: "conversationLogSettings", Method: "PUT", URI: "/bots/{botId}/botaliases"}, + "CreateBotLocale": {Verb: "Create", Resource: "BotLocale", OutputListKey: "", OutputItemKey: "audioFillerSettings", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales"}, + "CreateBotReplica": {Verb: "Create", Resource: "BotReplica", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/bots/{botId}/replicas"}, + "CreateBotVersion": {Verb: "Create", Resource: "BotVersion", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/bots/{botId}/botversions"}, + "CreateExport": {Verb: "Create", Resource: "Export", OutputListKey: "", OutputItemKey: "resourceSpecification", Method: "PUT", URI: "/exports"}, + "CreateIntent": {Verb: "Create", Resource: "Intent", OutputListKey: "inputContexts", OutputItemKey: "dialogCodeHook", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents"}, + "CreateResourcePolicy": {Verb: "Create", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/policy/{resourceArn}"}, + "CreateResourcePolicyStatement": {Verb: "Create", Resource: "ResourcePolicyStatement", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/policy/{resourceArn}/statements"}, + "CreateSlot": {Verb: "Create", Resource: "Slot", OutputListKey: "", OutputItemKey: "multipleValuesSetting", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}/slots"}, + "CreateSlotType": {Verb: "Create", Resource: "SlotType", OutputListKey: "slotTypeValues", OutputItemKey: "compositeSlotTypeSetting", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/slottypes"}, + "CreateTestSetDiscrepancyReport": {Verb: "Create", Resource: "TestSetDiscrepancyReport", OutputListKey: "", OutputItemKey: "target", Method: "POST", URI: "/testsets/{testSetId}/testsetdiscrepancy"}, + "CreateUploadUrl": {Verb: "Create", Resource: "UploadUrl", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/createuploadurl"}, + "DeleteBot": {Verb: "Delete", Resource: "Bot", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}"}, + "DeleteBotAlias": {Verb: "Delete", Resource: "BotAlia", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botaliases/{botAliasId}"}, + "DeleteBotAnalyzerRecommendation": {Verb: "Delete", Resource: "BotAnalyzerRecommendation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botanalyzer/{botAnalyzerRequestId}"}, + "DeleteBotLocale": {Verb: "Delete", Resource: "BotLocale", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}"}, + "DeleteBotReplica": {Verb: "Delete", Resource: "BotReplica", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/replicas/{replicaRegion}"}, + "DeleteBotVersion": {Verb: "Delete", Resource: "BotVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}"}, + "DeleteCustomVocabulary": {Verb: "Delete", Resource: "CustomVocabulary", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/customvocabulary"}, + "DeleteExport": {Verb: "Delete", Resource: "Export", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/exports/{exportId}"}, + "DeleteImport": {Verb: "Delete", Resource: "Import", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/imports/{importId}"}, + "DeleteIntent": {Verb: "Delete", Resource: "Intent", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}"}, + "DeleteResourcePolicy": {Verb: "Delete", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/policy/{resourceArn}"}, + "DeleteResourcePolicyStatement": {Verb: "Delete", Resource: "ResourcePolicyStatement", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/policy/{resourceArn}/statements/{statementId}"}, + "DeleteSlot": {Verb: "Delete", Resource: "Slot", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}/slots/{slotId}"}, + "DeleteSlotType": {Verb: "Delete", Resource: "SlotType", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/slottypes/{slotTypeId}"}, + "DeleteTestSet": {Verb: "Delete", Resource: "TestSet", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/testsets/{testSetId}"}, + "DeleteUtterances": {Verb: "Delete", Resource: "Utterance", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/utterances"}, + "DescribeBot": {Verb: "Get", Resource: "Bot", OutputListKey: "botMembers", OutputItemKey: "dataPrivacy", Method: "GET", URI: "/bots/{botId}"}, + "DescribeBotAlias": {Verb: "Get", Resource: "BotAlia", OutputListKey: "botAliasHistoryEvents", OutputItemKey: "conversationLogSettings", Method: "GET", URI: "/bots/{botId}/botaliases/{botAliasId}"}, + "DescribeBotAnalyzerRecommendation": {Verb: "Get", Resource: "BotAnalyzerRecommendation", OutputListKey: "botAnalyzerRecommendationList", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botanalyzer/describe/{botAnalyzerRequestId}"}, + "DescribeBotLocale": {Verb: "Get", Resource: "BotLocale", OutputListKey: "botLocaleHistoryEvents", OutputItemKey: "audioFillerSettings", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}"}, + "DescribeBotRecommendation": {Verb: "Get", Resource: "BotRecommendation", OutputListKey: "failureReasons", OutputItemKey: "botRecommendationResults", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/botrecommendations/{botRecommendationId}"}, + "DescribeBotReplica": {Verb: "Get", Resource: "BotReplica", OutputListKey: "failureReasons", OutputItemKey: "", Method: "GET", URI: "/bots/{botId}/replicas/{replicaRegion}"}, + "DescribeBotResourceGeneration": {Verb: "Get", Resource: "BotResourceGeneration", OutputListKey: "failureReasons", OutputItemKey: "", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/generations/{generationId}"}, + "DescribeBotVersion": {Verb: "Get", Resource: "BotVersion", OutputListKey: "botMembers", OutputItemKey: "dataPrivacy", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}"}, + "DescribeCustomVocabularyMetadata": {Verb: "Get", Resource: "CustomVocabularyMetadata", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/customvocabulary/DEFAULT/metadata"}, + "DescribeExport": {Verb: "Get", Resource: "Export", OutputListKey: "failureReasons", OutputItemKey: "resourceSpecification", Method: "GET", URI: "/exports/{exportId}"}, + "DescribeImport": {Verb: "Get", Resource: "Import", OutputListKey: "failureReasons", OutputItemKey: "resourceSpecification", Method: "GET", URI: "/imports/{importId}"}, + "DescribeIntent": {Verb: "Get", Resource: "Intent", OutputListKey: "inputContexts", OutputItemKey: "dialogCodeHook", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}"}, + "DescribeResourcePolicy": {Verb: "Get", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/policy/{resourceArn}"}, + "DescribeSlot": {Verb: "Get", Resource: "Slot", OutputListKey: "", OutputItemKey: "multipleValuesSetting", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}/slots/{slotId}"}, + "DescribeSlotType": {Verb: "Get", Resource: "SlotType", OutputListKey: "slotTypeValues", OutputItemKey: "compositeSlotTypeSetting", Method: "GET", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/slottypes/{slotTypeId}"}, + "DescribeTestExecution": {Verb: "Get", Resource: "TestExecution", OutputListKey: "failureReasons", OutputItemKey: "target", Method: "GET", URI: "/testexecutions/{testExecutionId}"}, + "DescribeTestSet": {Verb: "Get", Resource: "TestSet", OutputListKey: "", OutputItemKey: "storageLocation", Method: "GET", URI: "/testsets/{testSetId}"}, + "DescribeTestSetDiscrepancyReport": {Verb: "Get", Resource: "TestSetDiscrepancyReport", OutputListKey: "failureReasons", OutputItemKey: "target", Method: "GET", URI: "/testsetdiscrepancy/{testSetDiscrepancyReportId}"}, + "DescribeTestSetGeneration": {Verb: "Get", Resource: "TestSetGeneration", OutputListKey: "failureReasons", OutputItemKey: "generationDataSource", Method: "GET", URI: "/testsetgenerations/{testSetGenerationId}"}, + "GetTestExecutionArtifactsUrl": {Verb: "Get", Resource: "TestExecutionArtifactsUrl", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/testexecutions/{testExecutionId}/artifacturl"}, + "ListAggregatedUtterances": {Verb: "List", Resource: "AggregatedUtterance", OutputListKey: "aggregatedUtterancesSummaries", OutputItemKey: "aggregationDuration", Method: "POST", URI: "/bots/{botId}/aggregatedutterances"}, + "ListBotAliasReplicas": {Verb: "List", Resource: "BotAliasReplica", OutputListKey: "botAliasReplicaSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/replicas/{replicaRegion}/botaliases"}, + "ListBotAliases": {Verb: "List", Resource: "BotAliase", OutputListKey: "botAliasSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botaliases"}, + "ListBotAnalyzerHistory": {Verb: "List", Resource: "BotAnalyzerHistory", OutputListKey: "botAnalyzerHistoryList", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botanalyzer/history"}, + "ListBotLocales": {Verb: "List", Resource: "BotLocale", OutputListKey: "botLocaleSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales"}, + "ListBotRecommendations": {Verb: "List", Resource: "BotRecommendation", OutputListKey: "botRecommendationSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/botrecommendations"}, + "ListBotReplicas": {Verb: "List", Resource: "BotReplica", OutputListKey: "botReplicaSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/replicas"}, + "ListBotResourceGenerations": {Verb: "List", Resource: "BotResourceGeneration", OutputListKey: "generationSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/generations"}, + "ListBotVersionReplicas": {Verb: "List", Resource: "BotVersionReplica", OutputListKey: "botVersionReplicaSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/replicas/{replicaRegion}/botversions"}, + "ListBotVersions": {Verb: "List", Resource: "BotVersion", OutputListKey: "botVersionSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions"}, + "ListBots": {Verb: "List", Resource: "Bot", OutputListKey: "botSummaries", OutputItemKey: "", Method: "POST", URI: "/bots"}, + "ListBuiltInIntents": {Verb: "List", Resource: "BuiltInIntent", OutputListKey: "builtInIntentSummaries", OutputItemKey: "", Method: "POST", URI: "/builtins/locales/{localeId}/intents"}, + "ListBuiltInSlotTypes": {Verb: "List", Resource: "BuiltInSlotType", OutputListKey: "builtInSlotTypeSummaries", OutputItemKey: "", Method: "POST", URI: "/builtins/locales/{localeId}/slottypes"}, + "ListCustomVocabularyItems": {Verb: "List", Resource: "CustomVocabularyItem", OutputListKey: "customVocabularyItems", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/customvocabulary/DEFAULT/list"}, + "ListExports": {Verb: "List", Resource: "Export", OutputListKey: "exportSummaries", OutputItemKey: "", Method: "POST", URI: "/exports"}, + "ListImports": {Verb: "List", Resource: "Import", OutputListKey: "importSummaries", OutputItemKey: "", Method: "POST", URI: "/imports"}, + "ListIntentMetrics": {Verb: "List", Resource: "IntentMetric", OutputListKey: "results", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/intentmetrics"}, + "ListIntentPaths": {Verb: "List", Resource: "IntentPath", OutputListKey: "nodeSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/intentpaths"}, + "ListIntentStageMetrics": {Verb: "List", Resource: "IntentStageMetric", OutputListKey: "results", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/intentstagemetrics"}, + "ListIntents": {Verb: "List", Resource: "Intent", OutputListKey: "intentSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents"}, + "ListRecommendedIntents": {Verb: "List", Resource: "RecommendedIntent", OutputListKey: "summaryList", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/botrecommendations/{botRecommendationId}/intents"}, + "ListSessionAnalyticsData": {Verb: "List", Resource: "SessionAnalyticsData", OutputListKey: "sessions", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/sessions"}, + "ListSessionMetrics": {Verb: "List", Resource: "SessionMetric", OutputListKey: "results", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/sessionmetrics"}, + "ListSlotTypes": {Verb: "List", Resource: "SlotType", OutputListKey: "slotTypeSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/slottypes"}, + "ListSlots": {Verb: "List", Resource: "Slot", OutputListKey: "slotSummaries", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}/slots"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceARN}"}, + "ListTestExecutionResultItems": {Verb: "List", Resource: "TestExecutionResultItem", OutputListKey: "", OutputItemKey: "testExecutionResults", Method: "POST", URI: "/testexecutions/{testExecutionId}/results"}, + "ListTestExecutions": {Verb: "List", Resource: "TestExecution", OutputListKey: "testExecutions", OutputItemKey: "", Method: "POST", URI: "/testexecutions"}, + "ListTestSetRecords": {Verb: "List", Resource: "TestSetRecord", OutputListKey: "testSetRecords", OutputItemKey: "", Method: "POST", URI: "/testsets/{testSetId}/records"}, + "ListTestSets": {Verb: "List", Resource: "TestSet", OutputListKey: "testSets", OutputItemKey: "", Method: "POST", URI: "/testsets"}, + "ListUtteranceAnalyticsData": {Verb: "List", Resource: "UtteranceAnalyticsData", OutputListKey: "utterances", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/utterances"}, + "ListUtteranceMetrics": {Verb: "List", Resource: "UtteranceMetric", OutputListKey: "results", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/analytics/utterancemetrics"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceARN}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceARN}"}, + "UpdateBot": {Verb: "Update", Resource: "Bot", OutputListKey: "botMembers", OutputItemKey: "dataPrivacy", Method: "PUT", URI: "/bots/{botId}"}, + "UpdateBotAlias": {Verb: "Update", Resource: "BotAlia", OutputListKey: "", OutputItemKey: "conversationLogSettings", Method: "PUT", URI: "/bots/{botId}/botaliases/{botAliasId}"}, + "UpdateBotLocale": {Verb: "Update", Resource: "BotLocale", OutputListKey: "failureReasons", OutputItemKey: "audioFillerSettings", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}"}, + "UpdateBotRecommendation": {Verb: "Update", Resource: "BotRecommendation", OutputListKey: "", OutputItemKey: "encryptionSetting", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/botrecommendations/{botRecommendationId}"}, + "UpdateExport": {Verb: "Update", Resource: "Export", OutputListKey: "", OutputItemKey: "resourceSpecification", Method: "PUT", URI: "/exports/{exportId}"}, + "UpdateIntent": {Verb: "Update", Resource: "Intent", OutputListKey: "inputContexts", OutputItemKey: "dialogCodeHook", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}"}, + "UpdateResourcePolicy": {Verb: "Update", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/policy/{resourceArn}"}, + "UpdateSlot": {Verb: "Update", Resource: "Slot", OutputListKey: "", OutputItemKey: "multipleValuesSetting", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/intents/{intentId}/slots/{slotId}"}, + "UpdateSlotType": {Verb: "Update", Resource: "SlotType", OutputListKey: "slotTypeValues", OutputItemKey: "compositeSlotTypeSetting", Method: "PUT", URI: "/bots/{botId}/botversions/{botVersion}/botlocales/{localeId}/slottypes/{slotTypeId}"}, + "UpdateTestSet": {Verb: "Update", Resource: "TestSet", OutputListKey: "", OutputItemKey: "storageLocation", Method: "PUT", URI: "/testsets/{testSetId}"}, + }) + crud.Register("lexruntimeservice", map[string]crud.OpMeta{ + "DeleteSession": {Verb: "Delete", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bot/{botName}/alias/{botAlias}/user/{userId}/session"}, + "GetSession": {Verb: "Get", Resource: "Session", OutputListKey: "activeContexts", OutputItemKey: "dialogAction", Method: "GET", URI: "/bot/{botName}/alias/{botAlias}/user/{userId}/session"}, + "PutSession": {Verb: "Update", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/bot/{botName}/alias/{botAlias}/user/{userId}/session"}, + }) + crud.Register("lexruntimev2", map[string]crud.OpMeta{ + "DeleteSession": {Verb: "Delete", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/bots/{botId}/botAliases/{botAliasId}/botLocales/{localeId}/sessions/{sessionId}"}, + "GetSession": {Verb: "Get", Resource: "Session", OutputListKey: "interpretations", OutputItemKey: "sessionState", Method: "GET", URI: "/bots/{botId}/botAliases/{botAliasId}/botLocales/{localeId}/sessions/{sessionId}"}, + "PutSession": {Verb: "Update", Resource: "Session", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/bots/{botId}/botAliases/{botAliasId}/botLocales/{localeId}/sessions/{sessionId}"}, + }) crud.Register("lookoutequipment", map[string]crud.OpMeta{ "CreateDataset": {Verb: "Create", Resource: "Dataset", OutputListKey: "", OutputItemKey: ""}, "CreateInferenceScheduler": {Verb: "Create", Resource: "InferenceScheduler", OutputListKey: "", OutputItemKey: ""}, @@ -1640,6 +3440,33 @@ func init() { "UpdateModel": {Verb: "Update", Resource: "Model", OutputListKey: "", OutputItemKey: ""}, "UpdateRetrainingScheduler": {Verb: "Update", Resource: "RetrainingScheduler", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("managedblockchain", map[string]crud.OpMeta{ + "CreateAccessor": {Verb: "Create", Resource: "Accessor", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/accessors"}, + "CreateMember": {Verb: "Create", Resource: "Member", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/networks/{NetworkId}/members"}, + "CreateNetwork": {Verb: "Create", Resource: "Network", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/networks"}, + "CreateNode": {Verb: "Create", Resource: "Node", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/networks/{NetworkId}/nodes"}, + "CreateProposal": {Verb: "Create", Resource: "Proposal", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/networks/{NetworkId}/proposals"}, + "DeleteAccessor": {Verb: "Delete", Resource: "Accessor", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/accessors/{AccessorId}"}, + "DeleteMember": {Verb: "Delete", Resource: "Member", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/networks/{NetworkId}/members/{MemberId}"}, + "DeleteNode": {Verb: "Delete", Resource: "Node", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/networks/{NetworkId}/nodes/{NodeId}"}, + "GetAccessor": {Verb: "Get", Resource: "Accessor", OutputListKey: "", OutputItemKey: "Accessor", Method: "GET", URI: "/accessors/{AccessorId}"}, + "GetMember": {Verb: "Get", Resource: "Member", OutputListKey: "", OutputItemKey: "Member", Method: "GET", URI: "/networks/{NetworkId}/members/{MemberId}"}, + "GetNetwork": {Verb: "Get", Resource: "Network", OutputListKey: "", OutputItemKey: "Network", Method: "GET", URI: "/networks/{NetworkId}"}, + "GetNode": {Verb: "Get", Resource: "Node", OutputListKey: "", OutputItemKey: "Node", Method: "GET", URI: "/networks/{NetworkId}/nodes/{NodeId}"}, + "GetProposal": {Verb: "Get", Resource: "Proposal", OutputListKey: "", OutputItemKey: "Proposal", Method: "GET", URI: "/networks/{NetworkId}/proposals/{ProposalId}"}, + "ListAccessors": {Verb: "List", Resource: "Accessor", OutputListKey: "Accessors", OutputItemKey: "", Method: "GET", URI: "/accessors"}, + "ListInvitations": {Verb: "List", Resource: "Invitation", OutputListKey: "Invitations", OutputItemKey: "", Method: "GET", URI: "/invitations"}, + "ListMembers": {Verb: "List", Resource: "Member", OutputListKey: "Members", OutputItemKey: "", Method: "GET", URI: "/networks/{NetworkId}/members"}, + "ListNetworks": {Verb: "List", Resource: "Network", OutputListKey: "Networks", OutputItemKey: "", Method: "GET", URI: "/networks"}, + "ListNodes": {Verb: "List", Resource: "Node", OutputListKey: "Nodes", OutputItemKey: "", Method: "GET", URI: "/networks/{NetworkId}/nodes"}, + "ListProposalVotes": {Verb: "List", Resource: "ProposalVote", OutputListKey: "ProposalVotes", OutputItemKey: "", Method: "GET", URI: "/networks/{NetworkId}/proposals/{ProposalId}/votes"}, + "ListProposals": {Verb: "List", Resource: "Proposal", OutputListKey: "Proposals", OutputItemKey: "", Method: "GET", URI: "/networks/{NetworkId}/proposals"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{ResourceArn}"}, + "UpdateMember": {Verb: "Update", Resource: "Member", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/networks/{NetworkId}/members/{MemberId}"}, + "UpdateNode": {Verb: "Update", Resource: "Node", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/networks/{NetworkId}/nodes/{NodeId}"}, + }) crud.Register("memorydb", map[string]crud.OpMeta{ "CreateACL": {Verb: "Create", Resource: "ACL", OutputListKey: "", OutputItemKey: "ACL"}, "CreateCluster": {Verb: "Create", Resource: "Cluster", OutputListKey: "", OutputItemKey: "Cluster"}, @@ -1682,6 +3509,205 @@ func init() { "UpdateSubnetGroup": {Verb: "Update", Resource: "SubnetGroup", OutputListKey: "", OutputItemKey: "SubnetGroup"}, "UpdateUser": {Verb: "Update", Resource: "User", OutputListKey: "", OutputItemKey: "User"}, }) + crud.Register("mq", map[string]crud.OpMeta{ + "CreateBroker": {Verb: "Create", Resource: "Broker", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/brokers"}, + "CreateConfiguration": {Verb: "Create", Resource: "Configuration", OutputListKey: "", OutputItemKey: "LatestRevision", Method: "POST", URI: "/v1/configurations"}, + "CreateTags": {Verb: "Create", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{ResourceArn}"}, + "CreateUser": {Verb: "Create", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/brokers/{BrokerId}/users/{Username}"}, + "DeleteBroker": {Verb: "Delete", Resource: "Broker", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/brokers/{BrokerId}"}, + "DeleteConfiguration": {Verb: "Delete", Resource: "Configuration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/configurations/{ConfigurationId}"}, + "DeleteTags": {Verb: "Delete", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{ResourceArn}"}, + "DeleteUser": {Verb: "Delete", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/brokers/{BrokerId}/users/{Username}"}, + "DescribeBroker": {Verb: "Get", Resource: "Broker", OutputListKey: "ActionsRequired", OutputItemKey: "Configurations", Method: "GET", URI: "/v1/brokers/{BrokerId}"}, + "DescribeBrokerEngineTypes": {Verb: "Get", Resource: "BrokerEngineType", OutputListKey: "BrokerEngineTypes", OutputItemKey: "", Method: "GET", URI: "/v1/broker-engine-types"}, + "DescribeBrokerInstanceOptions": {Verb: "Get", Resource: "BrokerInstanceOption", OutputListKey: "BrokerInstanceOptions", OutputItemKey: "", Method: "GET", URI: "/v1/broker-instance-options"}, + "DescribeConfiguration": {Verb: "Get", Resource: "Configuration", OutputListKey: "", OutputItemKey: "LatestRevision", Method: "GET", URI: "/v1/configurations/{ConfigurationId}"}, + "DescribeConfigurationRevision": {Verb: "Get", Resource: "ConfigurationRevision", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/configurations/{ConfigurationId}/revisions/{ConfigurationRevision}"}, + "DescribeUser": {Verb: "Get", Resource: "User", OutputListKey: "Groups", OutputItemKey: "Pending", Method: "GET", URI: "/v1/brokers/{BrokerId}/users/{Username}"}, + "ListBrokers": {Verb: "List", Resource: "Broker", OutputListKey: "BrokerSummaries", OutputItemKey: "", Method: "GET", URI: "/v1/brokers"}, + "ListConfigurationRevisions": {Verb: "List", Resource: "ConfigurationRevision", OutputListKey: "Revisions", OutputItemKey: "", Method: "GET", URI: "/v1/configurations/{ConfigurationId}/revisions"}, + "ListConfigurations": {Verb: "List", Resource: "Configuration", OutputListKey: "Configurations", OutputItemKey: "", Method: "GET", URI: "/v1/configurations"}, + "ListTags": {Verb: "List", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v1/tags/{ResourceArn}"}, + "ListUsers": {Verb: "List", Resource: "User", OutputListKey: "Users", OutputItemKey: "", Method: "GET", URI: "/v1/brokers/{BrokerId}/users"}, + "UpdateBroker": {Verb: "Update", Resource: "Broker", OutputListKey: "SecurityGroups", OutputItemKey: "Configuration", Method: "PUT", URI: "/v1/brokers/{BrokerId}"}, + "UpdateConfiguration": {Verb: "Update", Resource: "Configuration", OutputListKey: "Warnings", OutputItemKey: "LatestRevision", Method: "PUT", URI: "/v1/configurations/{ConfigurationId}"}, + "UpdateUser": {Verb: "Update", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/brokers/{BrokerId}/users/{Username}"}, + }) + crud.Register("mwaa", map[string]crud.OpMeta{ + "CreateCliToken": {Verb: "Create", Resource: "CliToken", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/clitoken/{Name}"}, + "CreateEnvironment": {Verb: "Create", Resource: "Environment", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/environments/{Name}"}, + "CreateWebLoginToken": {Verb: "Create", Resource: "WebLoginToken", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/webtoken/{Name}"}, + "DeleteEnvironment": {Verb: "Delete", Resource: "Environment", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/environments/{Name}"}, + "GetEnvironment": {Verb: "Get", Resource: "Environment", OutputListKey: "", OutputItemKey: "Environment", Method: "GET", URI: "/environments/{Name}"}, + "ListEnvironments": {Verb: "List", Resource: "Environment", OutputListKey: "Environments", OutputItemKey: "", Method: "GET", URI: "/environments"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{ResourceArn}"}, + "UpdateEnvironment": {Verb: "Update", Resource: "Environment", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/environments/{Name}"}, + }) + crud.Register("omics", map[string]crud.OpMeta{ + "CreateAnnotationStore": {Verb: "Create", Resource: "AnnotationStore", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/annotationStore"}, + "CreateAnnotationStoreVersion": {Verb: "Create", Resource: "AnnotationStoreVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/annotationStore/{name}/version"}, + "CreateConfiguration": {Verb: "Create", Resource: "Configuration", OutputListKey: "", OutputItemKey: "runConfigurations", Method: "POST", URI: "/configuration"}, + "CreateMultipartReadSetUpload": {Verb: "Create", Resource: "MultipartReadSetUpload", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/upload"}, + "CreateReferenceStore": {Verb: "Create", Resource: "ReferenceStore", OutputListKey: "", OutputItemKey: "sseConfig", Method: "POST", URI: "/referencestore"}, + "CreateRunCache": {Verb: "Create", Resource: "RunCache", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runCache"}, + "CreateRunGroup": {Verb: "Create", Resource: "RunGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runGroup"}, + "CreateSequenceStore": {Verb: "Create", Resource: "SequenceStore", OutputListKey: "propagatedSetLevelTags", OutputItemKey: "s3Access", Method: "POST", URI: "/sequencestore"}, + "CreateShare": {Verb: "Create", Resource: "Share", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/share"}, + "CreateVariantStore": {Verb: "Create", Resource: "VariantStore", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/variantStore"}, + "CreateWorkflow": {Verb: "Create", Resource: "Workflow", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/workflow"}, + "CreateWorkflowVersion": {Verb: "Create", Resource: "WorkflowVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/workflow/{workflowId}/version"}, + "DeleteAnnotationStore": {Verb: "Delete", Resource: "AnnotationStore", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/annotationStore/{name}"}, + "DeleteAnnotationStoreVersions": {Verb: "Delete", Resource: "AnnotationStoreVersion", OutputListKey: "errors", OutputItemKey: "", Method: "POST", URI: "/annotationStore/{name}/versions/delete"}, + "DeleteBatch": {Verb: "Delete", Resource: "Batch", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/runBatch/{batchId}"}, + "DeleteConfiguration": {Verb: "Delete", Resource: "Configuration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/configuration/{name}"}, + "DeleteReference": {Verb: "Delete", Resource: "Reference", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/referencestore/{referenceStoreId}/reference/{id}"}, + "DeleteReferenceStore": {Verb: "Delete", Resource: "ReferenceStore", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/referencestore/{id}"}, + "DeleteRun": {Verb: "Delete", Resource: "Run", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/run/{id}"}, + "DeleteRunBatch": {Verb: "Delete", Resource: "RunBatch", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runBatch/delete"}, + "DeleteRunCache": {Verb: "Delete", Resource: "RunCache", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/runCache/{id}"}, + "DeleteRunGroup": {Verb: "Delete", Resource: "RunGroup", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/runGroup/{id}"}, + "DeleteS3AccessPolicy": {Verb: "Delete", Resource: "S3AccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/s3accesspolicy/{s3AccessPointArn}"}, + "DeleteSequenceStore": {Verb: "Delete", Resource: "SequenceStore", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/sequencestore/{id}"}, + "DeleteShare": {Verb: "Delete", Resource: "Share", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/share/{shareId}"}, + "DeleteVariantStore": {Verb: "Delete", Resource: "VariantStore", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/variantStore/{name}"}, + "DeleteWorkflow": {Verb: "Delete", Resource: "Workflow", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/workflow/{id}"}, + "DeleteWorkflowVersion": {Verb: "Delete", Resource: "WorkflowVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/workflow/{workflowId}/version/{versionName}"}, + "GetAnnotationImportJob": {Verb: "Get", Resource: "AnnotationImportJob", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/import/annotation/{jobId}"}, + "GetAnnotationStore": {Verb: "Get", Resource: "AnnotationStore", OutputListKey: "", OutputItemKey: "sseConfig", Method: "GET", URI: "/annotationStore/{name}"}, + "GetAnnotationStoreVersion": {Verb: "Get", Resource: "AnnotationStoreVersion", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/annotationStore/{name}/version/{versionName}"}, + "GetBatch": {Verb: "Get", Resource: "Batch", OutputListKey: "", OutputItemKey: "defaultRunSetting", Method: "GET", URI: "/runBatch/{batchId}"}, + "GetConfiguration": {Verb: "Get", Resource: "Configuration", OutputListKey: "", OutputItemKey: "runConfigurations", Method: "GET", URI: "/configuration/{name}"}, + "GetReadSet": {Verb: "Get", Resource: "ReadSet", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/sequencestore/{sequenceStoreId}/readset/{id}"}, + "GetReadSetActivationJob": {Verb: "Get", Resource: "ReadSetActivationJob", OutputListKey: "sources", OutputItemKey: "", Method: "GET", URI: "/sequencestore/{sequenceStoreId}/activationjob/{id}"}, + "GetReadSetExportJob": {Verb: "Get", Resource: "ReadSetExportJob", OutputListKey: "readSets", OutputItemKey: "", Method: "GET", URI: "/sequencestore/{sequenceStoreId}/exportjob/{id}"}, + "GetReadSetImportJob": {Verb: "Get", Resource: "ReadSetImportJob", OutputListKey: "sources", OutputItemKey: "", Method: "GET", URI: "/sequencestore/{sequenceStoreId}/importjob/{id}"}, + "GetReadSetMetadata": {Verb: "Get", Resource: "ReadSetMetadata", OutputListKey: "", OutputItemKey: "etag", Method: "GET", URI: "/sequencestore/{sequenceStoreId}/readset/{id}/metadata"}, + "GetReference": {Verb: "Get", Resource: "Reference", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/referencestore/{referenceStoreId}/reference/{id}"}, + "GetReferenceImportJob": {Verb: "Get", Resource: "ReferenceImportJob", OutputListKey: "sources", OutputItemKey: "", Method: "GET", URI: "/referencestore/{referenceStoreId}/importjob/{id}"}, + "GetReferenceMetadata": {Verb: "Get", Resource: "ReferenceMetadata", OutputListKey: "", OutputItemKey: "files", Method: "GET", URI: "/referencestore/{referenceStoreId}/reference/{id}/metadata"}, + "GetReferenceStore": {Verb: "Get", Resource: "ReferenceStore", OutputListKey: "", OutputItemKey: "sseConfig", Method: "GET", URI: "/referencestore/{id}"}, + "GetRun": {Verb: "Get", Resource: "Run", OutputListKey: "", OutputItemKey: "configuration", Method: "GET", URI: "/run/{id}"}, + "GetRunCache": {Verb: "Get", Resource: "RunCache", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/runCache/{id}"}, + "GetRunGroup": {Verb: "Get", Resource: "RunGroup", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/runGroup/{id}"}, + "GetRunTask": {Verb: "Get", Resource: "RunTask", OutputListKey: "", OutputItemKey: "imageDetails", Method: "GET", URI: "/run/{id}/task/{taskId}"}, + "GetS3AccessPolicy": {Verb: "Get", Resource: "S3AccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/s3accesspolicy/{s3AccessPointArn}"}, + "GetSequenceStore": {Verb: "Get", Resource: "SequenceStore", OutputListKey: "propagatedSetLevelTags", OutputItemKey: "s3Access", Method: "GET", URI: "/sequencestore/{id}"}, + "GetShare": {Verb: "Get", Resource: "Share", OutputListKey: "", OutputItemKey: "share", Method: "GET", URI: "/share/{shareId}"}, + "GetVariantImportJob": {Verb: "Get", Resource: "VariantImportJob", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/import/variant/{jobId}"}, + "GetVariantStore": {Verb: "Get", Resource: "VariantStore", OutputListKey: "", OutputItemKey: "sseConfig", Method: "GET", URI: "/variantStore/{name}"}, + "GetWorkflow": {Verb: "Get", Resource: "Workflow", OutputListKey: "profiles", OutputItemKey: "containerRegistryMap", Method: "GET", URI: "/workflow/{id}"}, + "GetWorkflowVersion": {Verb: "Get", Resource: "WorkflowVersion", OutputListKey: "profiles", OutputItemKey: "containerRegistryMap", Method: "GET", URI: "/workflow/{workflowId}/version/{versionName}"}, + "ListAnnotationImportJobs": {Verb: "List", Resource: "AnnotationImportJob", OutputListKey: "annotationImportJobs", OutputItemKey: "", Method: "POST", URI: "/import/annotations"}, + "ListAnnotationStoreVersions": {Verb: "List", Resource: "AnnotationStoreVersion", OutputListKey: "annotationStoreVersions", OutputItemKey: "", Method: "POST", URI: "/annotationStore/{name}/versions"}, + "ListAnnotationStores": {Verb: "List", Resource: "AnnotationStore", OutputListKey: "annotationStores", OutputItemKey: "", Method: "POST", URI: "/annotationStores"}, + "ListBatch": {Verb: "List", Resource: "Batch", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/runBatch"}, + "ListConfigurations": {Verb: "List", Resource: "Configuration", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/configuration"}, + "ListMultipartReadSetUploads": {Verb: "List", Resource: "MultipartReadSetUpload", OutputListKey: "uploads", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/uploads"}, + "ListReadSetActivationJobs": {Verb: "List", Resource: "ReadSetActivationJob", OutputListKey: "activationJobs", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/activationjobs"}, + "ListReadSetExportJobs": {Verb: "List", Resource: "ReadSetExportJob", OutputListKey: "exportJobs", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/exportjobs"}, + "ListReadSetImportJobs": {Verb: "List", Resource: "ReadSetImportJob", OutputListKey: "importJobs", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/importjobs"}, + "ListReadSetUploadParts": {Verb: "List", Resource: "ReadSetUploadPart", OutputListKey: "parts", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/upload/{uploadId}/parts"}, + "ListReadSets": {Verb: "List", Resource: "ReadSet", OutputListKey: "readSets", OutputItemKey: "", Method: "POST", URI: "/sequencestore/{sequenceStoreId}/readsets"}, + "ListReferenceImportJobs": {Verb: "List", Resource: "ReferenceImportJob", OutputListKey: "importJobs", OutputItemKey: "", Method: "POST", URI: "/referencestore/{referenceStoreId}/importjobs"}, + "ListReferenceStores": {Verb: "List", Resource: "ReferenceStore", OutputListKey: "referenceStores", OutputItemKey: "", Method: "POST", URI: "/referencestores"}, + "ListReferences": {Verb: "List", Resource: "Reference", OutputListKey: "references", OutputItemKey: "", Method: "POST", URI: "/referencestore/{referenceStoreId}/references"}, + "ListRunCaches": {Verb: "List", Resource: "RunCache", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/runCache"}, + "ListRunGroups": {Verb: "List", Resource: "RunGroup", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/runGroup"}, + "ListRunTasks": {Verb: "List", Resource: "RunTask", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/run/{id}/task"}, + "ListRuns": {Verb: "List", Resource: "Run", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/run"}, + "ListRunsInBatch": {Verb: "List", Resource: "RunsInBatch", OutputListKey: "runs", OutputItemKey: "", Method: "GET", URI: "/runBatch/{batchId}/run"}, + "ListSequenceStores": {Verb: "List", Resource: "SequenceStore", OutputListKey: "sequenceStores", OutputItemKey: "", Method: "POST", URI: "/sequencestores"}, + "ListShares": {Verb: "List", Resource: "Share", OutputListKey: "shares", OutputItemKey: "", Method: "POST", URI: "/shares"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceArn}"}, + "ListVariantImportJobs": {Verb: "List", Resource: "VariantImportJob", OutputListKey: "variantImportJobs", OutputItemKey: "", Method: "POST", URI: "/import/variants"}, + "ListVariantStores": {Verb: "List", Resource: "VariantStore", OutputListKey: "variantStores", OutputItemKey: "", Method: "POST", URI: "/variantStores"}, + "ListWorkflowVersions": {Verb: "List", Resource: "WorkflowVersion", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/workflow/{workflowId}/version"}, + "ListWorkflows": {Verb: "List", Resource: "Workflow", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/workflow"}, + "PutS3AccessPolicy": {Verb: "Update", Resource: "S3AccessPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/s3accesspolicy/{s3AccessPointArn}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceArn}"}, + "UpdateAnnotationStore": {Verb: "Update", Resource: "AnnotationStore", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/annotationStore/{name}"}, + "UpdateAnnotationStoreVersion": {Verb: "Update", Resource: "AnnotationStoreVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/annotationStore/{name}/version/{versionName}"}, + "UpdateRunCache": {Verb: "Update", Resource: "RunCache", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runCache/{id}"}, + "UpdateRunGroup": {Verb: "Update", Resource: "RunGroup", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runGroup/{id}"}, + "UpdateSequenceStore": {Verb: "Update", Resource: "SequenceStore", OutputListKey: "propagatedSetLevelTags", OutputItemKey: "s3Access", Method: "PATCH", URI: "/sequencestore/{id}"}, + "UpdateVariantStore": {Verb: "Update", Resource: "VariantStore", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/variantStore/{name}"}, + "UpdateWorkflow": {Verb: "Update", Resource: "Workflow", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/workflow/{id}"}, + "UpdateWorkflowVersion": {Verb: "Update", Resource: "WorkflowVersion", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/workflow/{workflowId}/version/{versionName}"}, + }) + crud.Register("opensearch", map[string]crud.OpMeta{ + "CreateApplication": {Verb: "Create", Resource: "Application", OutputListKey: "appConfigs", OutputItemKey: "iamIdentityCenterOptions", Method: "POST", URI: "/2021-01-01/opensearch/application"}, + "CreateDomain": {Verb: "Create", Resource: "Domain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "POST", URI: "/2021-01-01/opensearch/domain"}, + "CreateIndex": {Verb: "Create", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/domain/{DomainName}/index"}, + "CreateOutboundConnection": {Verb: "Create", Resource: "OutboundConnection", OutputListKey: "", OutputItemKey: "ConnectionProperties", Method: "POST", URI: "/2021-01-01/opensearch/cc/outboundConnection"}, + "CreatePackage": {Verb: "Create", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "POST", URI: "/2021-01-01/packages"}, + "CreateVpcEndpoint": {Verb: "Create", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpoint", Method: "POST", URI: "/2021-01-01/opensearch/vpcEndpoints"}, + "DeleteApplication": {Verb: "Delete", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-01-01/opensearch/application/{id}"}, + "DeleteDataSource": {Verb: "Delete", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-01-01/opensearch/domain/{DomainName}/dataSource/{Name}"}, + "DeleteDirectQueryDataSource": {Verb: "Delete", Resource: "DirectQueryDataSource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-01-01/opensearch/directQueryDataSource/{DataSourceName}"}, + "DeleteDomain": {Verb: "Delete", Resource: "Domain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "DELETE", URI: "/2021-01-01/opensearch/domain/{DomainName}"}, + "DeleteInboundConnection": {Verb: "Delete", Resource: "InboundConnection", OutputListKey: "", OutputItemKey: "Connection", Method: "DELETE", URI: "/2021-01-01/opensearch/cc/inboundConnection/{ConnectionId}"}, + "DeleteIndex": {Verb: "Delete", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-01-01/opensearch/domain/{DomainName}/index/{IndexName}"}, + "DeleteOutboundConnection": {Verb: "Delete", Resource: "OutboundConnection", OutputListKey: "", OutputItemKey: "Connection", Method: "DELETE", URI: "/2021-01-01/opensearch/cc/outboundConnection/{ConnectionId}"}, + "DeletePackage": {Verb: "Delete", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "DELETE", URI: "/2021-01-01/packages/{PackageID}"}, + "DeleteVpcEndpoint": {Verb: "Delete", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpointSummary", Method: "DELETE", URI: "/2021-01-01/opensearch/vpcEndpoints/{VpcEndpointId}"}, + "DeregisterCapability": {Verb: "Delete", Resource: "Capability", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/2021-01-01/opensearch/application/{applicationId}/capability/deregister/{capabilityName}"}, + "DescribeDomain": {Verb: "Get", Resource: "Domain", OutputListKey: "", OutputItemKey: "DomainStatus", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}"}, + "DescribeDomainAutoTunes": {Verb: "Get", Resource: "DomainAutoTune", OutputListKey: "AutoTunes", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/autoTunes"}, + "DescribeDomainChangeProgress": {Verb: "Get", Resource: "DomainChangeProgress", OutputListKey: "", OutputItemKey: "ChangeProgressStatus", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/progress"}, + "DescribeDomainConfig": {Verb: "Get", Resource: "DomainConfig", OutputListKey: "", OutputItemKey: "DomainConfig", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/config"}, + "DescribeDomainHealth": {Verb: "Get", Resource: "DomainHealth", OutputListKey: "EnvironmentInformation", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/health"}, + "DescribeDomainNodes": {Verb: "Get", Resource: "DomainNode", OutputListKey: "DomainNodesStatusList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/nodes"}, + "DescribeDomains": {Verb: "Get", Resource: "Domain", OutputListKey: "DomainStatusList", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/domain-info"}, + "DescribeDryRunProgress": {Verb: "Get", Resource: "DryRunProgress", OutputListKey: "", OutputItemKey: "DryRunConfig", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/dryRun"}, + "DescribeInboundConnections": {Verb: "Get", Resource: "InboundConnection", OutputListKey: "Connections", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/cc/inboundConnection/search"}, + "DescribeInsightDetails": {Verb: "Get", Resource: "InsightDetail", OutputListKey: "Fields", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/insight-details"}, + "DescribeInstanceTypeLimits": {Verb: "Get", Resource: "InstanceTypeLimit", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/instanceTypeLimits/{EngineVersion}/{InstanceType}"}, + "DescribeOutboundConnections": {Verb: "Get", Resource: "OutboundConnection", OutputListKey: "Connections", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/cc/outboundConnection/search"}, + "DescribePackages": {Verb: "Get", Resource: "Package", OutputListKey: "PackageDetailsList", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/packages/describe"}, + "DescribeReservedInstanceOfferings": {Verb: "Get", Resource: "ReservedInstanceOffering", OutputListKey: "ReservedInstanceOfferings", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/reservedInstanceOfferings"}, + "DescribeReservedInstances": {Verb: "Get", Resource: "ReservedInstance", OutputListKey: "ReservedInstances", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/reservedInstances"}, + "DescribeVpcEndpoints": {Verb: "Get", Resource: "VpcEndpoint", OutputListKey: "VpcEndpointErrors", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/vpcEndpoints/describe"}, + "GetApplication": {Verb: "Get", Resource: "Application", OutputListKey: "appConfigs", OutputItemKey: "iamIdentityCenterOptions", Method: "GET", URI: "/2021-01-01/opensearch/application/{id}"}, + "GetCapability": {Verb: "Get", Resource: "Capability", OutputListKey: "failures", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/application/{applicationId}/capability/{capabilityName}"}, + "GetCompatibleVersions": {Verb: "Get", Resource: "CompatibleVersion", OutputListKey: "CompatibleVersions", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/compatibleVersions"}, + "GetDataSource": {Verb: "Get", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/dataSource/{Name}"}, + "GetDefaultApplicationSetting": {Verb: "Get", Resource: "DefaultApplicationSetting", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/defaultApplicationSetting"}, + "GetDirectQueryDataSource": {Verb: "Get", Resource: "DirectQueryDataSource", OutputListKey: "OpenSearchArns", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/directQueryDataSource/{DataSourceName}"}, + "GetDomainMaintenanceStatus": {Verb: "Get", Resource: "DomainMaintenanceStatu", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/domainMaintenance"}, + "GetIndex": {Verb: "Get", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/index/{IndexName}"}, + "GetPackageVersionHistory": {Verb: "Get", Resource: "PackageVersionHistory", OutputListKey: "PackageVersionHistoryList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/packages/{PackageID}/history"}, + "GetUpgradeHistory": {Verb: "Get", Resource: "UpgradeHistory", OutputListKey: "UpgradeHistories", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/upgradeDomain/{DomainName}/history"}, + "GetUpgradeStatus": {Verb: "Get", Resource: "UpgradeStatu", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/upgradeDomain/{DomainName}/status"}, + "ListApplications": {Verb: "List", Resource: "Application", OutputListKey: "ApplicationSummaries", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/list-applications"}, + "ListDataSources": {Verb: "List", Resource: "DataSource", OutputListKey: "DataSources", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/dataSource"}, + "ListDirectQueryDataSources": {Verb: "List", Resource: "DirectQueryDataSource", OutputListKey: "DirectQueryDataSources", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/directQueryDataSource"}, + "ListDomainMaintenances": {Verb: "List", Resource: "DomainMaintenance", OutputListKey: "DomainMaintenances", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/domainMaintenances"}, + "ListDomainNames": {Verb: "List", Resource: "DomainName", OutputListKey: "DomainNames", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/domain"}, + "ListDomainsForPackage": {Verb: "List", Resource: "DomainsForPackage", OutputListKey: "DomainPackageDetailsList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/packages/{PackageID}/domains"}, + "ListInsights": {Verb: "List", Resource: "Insight", OutputListKey: "Insights", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/insights"}, + "ListInstanceTypeDetails": {Verb: "List", Resource: "InstanceTypeDetail", OutputListKey: "InstanceTypeDetails", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/instanceTypeDetails/{EngineVersion}"}, + "ListPackagesForDomain": {Verb: "List", Resource: "PackagesForDomain", OutputListKey: "DomainPackageDetailsList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/domain/{DomainName}/packages"}, + "ListScheduledActions": {Verb: "List", Resource: "ScheduledAction", OutputListKey: "ScheduledActions", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/scheduledActions"}, + "ListTags": {Verb: "List", Resource: "Tag", OutputListKey: "TagList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/tags"}, + "ListVersions": {Verb: "List", Resource: "Version", OutputListKey: "Versions", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/versions"}, + "ListVpcEndpointAccess": {Verb: "List", Resource: "VpcEndpointAccess", OutputListKey: "AuthorizedPrincipalList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/listVpcEndpointAccess"}, + "ListVpcEndpoints": {Verb: "List", Resource: "VpcEndpoint", OutputListKey: "VpcEndpointSummaryList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/vpcEndpoints"}, + "ListVpcEndpointsForDomain": {Verb: "List", Resource: "VpcEndpointsForDomain", OutputListKey: "VpcEndpointSummaryList", OutputItemKey: "", Method: "GET", URI: "/2021-01-01/opensearch/domain/{DomainName}/vpcEndpoints"}, + "PutDefaultApplicationSetting": {Verb: "Update", Resource: "DefaultApplicationSetting", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2021-01-01/opensearch/defaultApplicationSetting"}, + "RegisterCapability": {Verb: "Create", Resource: "Capability", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/opensearch/application/{applicationId}/capability/register"}, + "UpdateApplication": {Verb: "Update", Resource: "Application", OutputListKey: "appConfigs", OutputItemKey: "iamIdentityCenterOptions", Method: "PUT", URI: "/2021-01-01/opensearch/application/{id}"}, + "UpdateDataSource": {Verb: "Update", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2021-01-01/opensearch/domain/{DomainName}/dataSource/{Name}"}, + "UpdateDirectQueryDataSource": {Verb: "Update", Resource: "DirectQueryDataSource", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2021-01-01/opensearch/directQueryDataSource/{DataSourceName}"}, + "UpdateDomainConfig": {Verb: "Update", Resource: "DomainConfig", OutputListKey: "", OutputItemKey: "DomainConfig", Method: "POST", URI: "/2021-01-01/opensearch/domain/{DomainName}/config"}, + "UpdateIndex": {Verb: "Update", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/2021-01-01/opensearch/domain/{DomainName}/index/{IndexName}"}, + "UpdatePackage": {Verb: "Update", Resource: "Package", OutputListKey: "", OutputItemKey: "PackageDetails", Method: "POST", URI: "/2021-01-01/packages/update"}, + "UpdatePackageScope": {Verb: "Update", Resource: "PackageScope", OutputListKey: "PackageUserList", OutputItemKey: "", Method: "POST", URI: "/2021-01-01/packages/updateScope"}, + "UpdateScheduledAction": {Verb: "Update", Resource: "ScheduledAction", OutputListKey: "", OutputItemKey: "ScheduledAction", Method: "PUT", URI: "/2021-01-01/opensearch/domain/{DomainName}/scheduledAction/update"}, + "UpdateVpcEndpoint": {Verb: "Update", Resource: "VpcEndpoint", OutputListKey: "", OutputItemKey: "VpcEndpoint", Method: "POST", URI: "/2021-01-01/opensearch/vpcEndpoints/update"}, + }) crud.Register("organizations", map[string]crud.OpMeta{ "CreateAccount": {Verb: "Create", Resource: "Account", OutputListKey: "", OutputItemKey: "CreateAccountStatus"}, "CreateGovCloudAccount": {Verb: "Create", Resource: "GovCloudAccount", OutputListKey: "", OutputItemKey: "CreateAccountStatus"}, @@ -1800,6 +3826,270 @@ func init() { "UpdateRecommender": {Verb: "Update", Resource: "Recommender", OutputListKey: "", OutputItemKey: ""}, "UpdateSolution": {Verb: "Update", Resource: "Solution", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("personalizeevents", map[string]crud.OpMeta{ + "PutActionInteractions": {Verb: "Update", Resource: "ActionInteraction", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/action-interactions"}, + "PutActions": {Verb: "Update", Resource: "Action", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/actions"}, + "PutEvents": {Verb: "Update", Resource: "Event", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/events"}, + "PutItems": {Verb: "Update", Resource: "Item", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/items"}, + "PutUsers": {Verb: "Update", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/users"}, + }) + crud.Register("personalizeruntime", map[string]crud.OpMeta{ + "GetActionRecommendations": {Verb: "Get", Resource: "ActionRecommendation", OutputListKey: "actionList", OutputItemKey: "", Method: "POST", URI: "/action-recommendations"}, + "GetPersonalizedRanking": {Verb: "Get", Resource: "PersonalizedRanking", OutputListKey: "personalizedRanking", OutputItemKey: "", Method: "POST", URI: "/personalize-ranking"}, + "GetRecommendations": {Verb: "Get", Resource: "Recommendation", OutputListKey: "itemList", OutputItemKey: "", Method: "POST", URI: "/recommendations"}, + }) + crud.Register("pinpoint", map[string]crud.OpMeta{ + "CreateApp": {Verb: "Create", Resource: "App", OutputListKey: "", OutputItemKey: "ApplicationResponse", Method: "POST", URI: "/v1/apps"}, + "CreateCampaign": {Verb: "Create", Resource: "Campaign", OutputListKey: "", OutputItemKey: "CampaignResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/campaigns"}, + "CreateEmailTemplate": {Verb: "Create", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "CreateTemplateMessageBody", Method: "POST", URI: "/v1/templates/{TemplateName}/email"}, + "CreateExportJob": {Verb: "Create", Resource: "ExportJob", OutputListKey: "", OutputItemKey: "ExportJobResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/jobs/export"}, + "CreateImportJob": {Verb: "Create", Resource: "ImportJob", OutputListKey: "", OutputItemKey: "ImportJobResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/jobs/import"}, + "CreateInAppTemplate": {Verb: "Create", Resource: "InAppTemplate", OutputListKey: "", OutputItemKey: "TemplateCreateMessageBody", Method: "POST", URI: "/v1/templates/{TemplateName}/inapp"}, + "CreateJourney": {Verb: "Create", Resource: "Journey", OutputListKey: "", OutputItemKey: "JourneyResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/journeys"}, + "CreatePushTemplate": {Verb: "Create", Resource: "PushTemplate", OutputListKey: "", OutputItemKey: "CreateTemplateMessageBody", Method: "POST", URI: "/v1/templates/{TemplateName}/push"}, + "CreateRecommenderConfiguration": {Verb: "Create", Resource: "RecommenderConfiguration", OutputListKey: "", OutputItemKey: "RecommenderConfigurationResponse", Method: "POST", URI: "/v1/recommenders"}, + "CreateSegment": {Verb: "Create", Resource: "Segment", OutputListKey: "", OutputItemKey: "SegmentResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/segments"}, + "CreateSmsTemplate": {Verb: "Create", Resource: "SmsTemplate", OutputListKey: "", OutputItemKey: "CreateTemplateMessageBody", Method: "POST", URI: "/v1/templates/{TemplateName}/sms"}, + "CreateVoiceTemplate": {Verb: "Create", Resource: "VoiceTemplate", OutputListKey: "", OutputItemKey: "CreateTemplateMessageBody", Method: "POST", URI: "/v1/templates/{TemplateName}/voice"}, + "DeleteAdmChannel": {Verb: "Delete", Resource: "AdmChannel", OutputListKey: "", OutputItemKey: "ADMChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/adm"}, + "DeleteApnsChannel": {Verb: "Delete", Resource: "ApnsChannel", OutputListKey: "", OutputItemKey: "APNSChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/apns"}, + "DeleteApnsSandboxChannel": {Verb: "Delete", Resource: "ApnsSandboxChannel", OutputListKey: "", OutputItemKey: "APNSSandboxChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/apns_sandbox"}, + "DeleteApnsVoipChannel": {Verb: "Delete", Resource: "ApnsVoipChannel", OutputListKey: "", OutputItemKey: "APNSVoipChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/apns_voip"}, + "DeleteApnsVoipSandboxChannel": {Verb: "Delete", Resource: "ApnsVoipSandboxChannel", OutputListKey: "", OutputItemKey: "APNSVoipSandboxChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/apns_voip_sandbox"}, + "DeleteApp": {Verb: "Delete", Resource: "App", OutputListKey: "", OutputItemKey: "ApplicationResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}"}, + "DeleteBaiduChannel": {Verb: "Delete", Resource: "BaiduChannel", OutputListKey: "", OutputItemKey: "BaiduChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/baidu"}, + "DeleteCampaign": {Verb: "Delete", Resource: "Campaign", OutputListKey: "", OutputItemKey: "CampaignResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}"}, + "DeleteEmailChannel": {Verb: "Delete", Resource: "EmailChannel", OutputListKey: "", OutputItemKey: "EmailChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/email"}, + "DeleteEmailTemplate": {Verb: "Delete", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "DELETE", URI: "/v1/templates/{TemplateName}/email"}, + "DeleteEndpoint": {Verb: "Delete", Resource: "Endpoint", OutputListKey: "", OutputItemKey: "EndpointResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/endpoints/{EndpointId}"}, + "DeleteEventStream": {Verb: "Delete", Resource: "EventStream", OutputListKey: "", OutputItemKey: "EventStream", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/eventstream"}, + "DeleteGcmChannel": {Verb: "Delete", Resource: "GcmChannel", OutputListKey: "", OutputItemKey: "GCMChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/gcm"}, + "DeleteInAppTemplate": {Verb: "Delete", Resource: "InAppTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "DELETE", URI: "/v1/templates/{TemplateName}/inapp"}, + "DeleteJourney": {Verb: "Delete", Resource: "Journey", OutputListKey: "", OutputItemKey: "JourneyResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}"}, + "DeletePushTemplate": {Verb: "Delete", Resource: "PushTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "DELETE", URI: "/v1/templates/{TemplateName}/push"}, + "DeleteRecommenderConfiguration": {Verb: "Delete", Resource: "RecommenderConfiguration", OutputListKey: "", OutputItemKey: "RecommenderConfigurationResponse", Method: "DELETE", URI: "/v1/recommenders/{RecommenderId}"}, + "DeleteSegment": {Verb: "Delete", Resource: "Segment", OutputListKey: "", OutputItemKey: "SegmentResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}"}, + "DeleteSmsChannel": {Verb: "Delete", Resource: "SmsChannel", OutputListKey: "", OutputItemKey: "SMSChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/sms"}, + "DeleteSmsTemplate": {Verb: "Delete", Resource: "SmsTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "DELETE", URI: "/v1/templates/{TemplateName}/sms"}, + "DeleteUserEndpoints": {Verb: "Delete", Resource: "UserEndpoint", OutputListKey: "", OutputItemKey: "EndpointsResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/users/{UserId}"}, + "DeleteVoiceChannel": {Verb: "Delete", Resource: "VoiceChannel", OutputListKey: "", OutputItemKey: "VoiceChannelResponse", Method: "DELETE", URI: "/v1/apps/{ApplicationId}/channels/voice"}, + "DeleteVoiceTemplate": {Verb: "Delete", Resource: "VoiceTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "DELETE", URI: "/v1/templates/{TemplateName}/voice"}, + "GetAdmChannel": {Verb: "Get", Resource: "AdmChannel", OutputListKey: "", OutputItemKey: "ADMChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/adm"}, + "GetApnsChannel": {Verb: "Get", Resource: "ApnsChannel", OutputListKey: "", OutputItemKey: "APNSChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/apns"}, + "GetApnsSandboxChannel": {Verb: "Get", Resource: "ApnsSandboxChannel", OutputListKey: "", OutputItemKey: "APNSSandboxChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/apns_sandbox"}, + "GetApnsVoipChannel": {Verb: "Get", Resource: "ApnsVoipChannel", OutputListKey: "", OutputItemKey: "APNSVoipChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/apns_voip"}, + "GetApnsVoipSandboxChannel": {Verb: "Get", Resource: "ApnsVoipSandboxChannel", OutputListKey: "", OutputItemKey: "APNSVoipSandboxChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/apns_voip_sandbox"}, + "GetApp": {Verb: "Get", Resource: "App", OutputListKey: "", OutputItemKey: "ApplicationResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}"}, + "GetApplicationDateRangeKpi": {Verb: "Get", Resource: "ApplicationDateRangeKpi", OutputListKey: "", OutputItemKey: "ApplicationDateRangeKpiResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/kpis/daterange/{KpiName}"}, + "GetApplicationSettings": {Verb: "Get", Resource: "ApplicationSetting", OutputListKey: "", OutputItemKey: "ApplicationSettingsResource", Method: "GET", URI: "/v1/apps/{ApplicationId}/settings"}, + "GetApps": {Verb: "Get", Resource: "App", OutputListKey: "", OutputItemKey: "ApplicationsResponse", Method: "GET", URI: "/v1/apps"}, + "GetBaiduChannel": {Verb: "Get", Resource: "BaiduChannel", OutputListKey: "", OutputItemKey: "BaiduChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/baidu"}, + "GetCampaign": {Verb: "Get", Resource: "Campaign", OutputListKey: "", OutputItemKey: "CampaignResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}"}, + "GetCampaignActivities": {Verb: "Get", Resource: "CampaignActivity", OutputListKey: "", OutputItemKey: "ActivitiesResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}/activities"}, + "GetCampaignDateRangeKpi": {Verb: "Get", Resource: "CampaignDateRangeKpi", OutputListKey: "", OutputItemKey: "CampaignDateRangeKpiResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}/kpis/daterange/{KpiName}"}, + "GetCampaignVersion": {Verb: "Get", Resource: "CampaignVersion", OutputListKey: "", OutputItemKey: "CampaignResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}/versions/{Version}"}, + "GetCampaignVersions": {Verb: "Get", Resource: "CampaignVersion", OutputListKey: "", OutputItemKey: "CampaignsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}/versions"}, + "GetCampaigns": {Verb: "Get", Resource: "Campaign", OutputListKey: "", OutputItemKey: "CampaignsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/campaigns"}, + "GetChannels": {Verb: "Get", Resource: "Channel", OutputListKey: "", OutputItemKey: "ChannelsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels"}, + "GetEmailChannel": {Verb: "Get", Resource: "EmailChannel", OutputListKey: "", OutputItemKey: "EmailChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/email"}, + "GetEmailTemplate": {Verb: "Get", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "EmailTemplateResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/email"}, + "GetEndpoint": {Verb: "Get", Resource: "Endpoint", OutputListKey: "", OutputItemKey: "EndpointResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/endpoints/{EndpointId}"}, + "GetEventStream": {Verb: "Get", Resource: "EventStream", OutputListKey: "", OutputItemKey: "EventStream", Method: "GET", URI: "/v1/apps/{ApplicationId}/eventstream"}, + "GetExportJob": {Verb: "Get", Resource: "ExportJob", OutputListKey: "", OutputItemKey: "ExportJobResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/jobs/export/{JobId}"}, + "GetExportJobs": {Verb: "Get", Resource: "ExportJob", OutputListKey: "", OutputItemKey: "ExportJobsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/jobs/export"}, + "GetGcmChannel": {Verb: "Get", Resource: "GcmChannel", OutputListKey: "", OutputItemKey: "GCMChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/gcm"}, + "GetImportJob": {Verb: "Get", Resource: "ImportJob", OutputListKey: "", OutputItemKey: "ImportJobResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/jobs/import/{JobId}"}, + "GetImportJobs": {Verb: "Get", Resource: "ImportJob", OutputListKey: "", OutputItemKey: "ImportJobsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/jobs/import"}, + "GetInAppMessages": {Verb: "Get", Resource: "InAppMessage", OutputListKey: "", OutputItemKey: "InAppMessagesResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/endpoints/{EndpointId}/inappmessages"}, + "GetInAppTemplate": {Verb: "Get", Resource: "InAppTemplate", OutputListKey: "", OutputItemKey: "InAppTemplateResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/inapp"}, + "GetJourney": {Verb: "Get", Resource: "Journey", OutputListKey: "", OutputItemKey: "JourneyResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}"}, + "GetJourneyDateRangeKpi": {Verb: "Get", Resource: "JourneyDateRangeKpi", OutputListKey: "", OutputItemKey: "JourneyDateRangeKpiResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/kpis/daterange/{KpiName}"}, + "GetJourneyExecutionActivityMetrics": {Verb: "Get", Resource: "JourneyExecutionActivityMetric", OutputListKey: "", OutputItemKey: "JourneyExecutionActivityMetricsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/activities/{JourneyActivityId}/execution-metrics"}, + "GetJourneyExecutionMetrics": {Verb: "Get", Resource: "JourneyExecutionMetric", OutputListKey: "", OutputItemKey: "JourneyExecutionMetricsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/execution-metrics"}, + "GetJourneyRunExecutionActivityMetrics": {Verb: "Get", Resource: "JourneyRunExecutionActivityMetric", OutputListKey: "", OutputItemKey: "JourneyRunExecutionActivityMetricsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/runs/{RunId}/activities/{JourneyActivityId}/execution-metrics"}, + "GetJourneyRunExecutionMetrics": {Verb: "Get", Resource: "JourneyRunExecutionMetric", OutputListKey: "", OutputItemKey: "JourneyRunExecutionMetricsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/runs/{RunId}/execution-metrics"}, + "GetJourneyRuns": {Verb: "Get", Resource: "JourneyRun", OutputListKey: "", OutputItemKey: "JourneyRunsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/runs"}, + "GetPushTemplate": {Verb: "Get", Resource: "PushTemplate", OutputListKey: "", OutputItemKey: "PushNotificationTemplateResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/push"}, + "GetRecommenderConfiguration": {Verb: "Get", Resource: "RecommenderConfiguration", OutputListKey: "", OutputItemKey: "RecommenderConfigurationResponse", Method: "GET", URI: "/v1/recommenders/{RecommenderId}"}, + "GetRecommenderConfigurations": {Verb: "Get", Resource: "RecommenderConfiguration", OutputListKey: "", OutputItemKey: "ListRecommenderConfigurationsResponse", Method: "GET", URI: "/v1/recommenders"}, + "GetSegment": {Verb: "Get", Resource: "Segment", OutputListKey: "", OutputItemKey: "SegmentResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}"}, + "GetSegmentExportJobs": {Verb: "Get", Resource: "SegmentExportJob", OutputListKey: "", OutputItemKey: "ExportJobsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}/jobs/export"}, + "GetSegmentImportJobs": {Verb: "Get", Resource: "SegmentImportJob", OutputListKey: "", OutputItemKey: "ImportJobsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}/jobs/import"}, + "GetSegmentVersion": {Verb: "Get", Resource: "SegmentVersion", OutputListKey: "", OutputItemKey: "SegmentResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}/versions/{Version}"}, + "GetSegmentVersions": {Verb: "Get", Resource: "SegmentVersion", OutputListKey: "", OutputItemKey: "SegmentsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}/versions"}, + "GetSegments": {Verb: "Get", Resource: "Segment", OutputListKey: "", OutputItemKey: "SegmentsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/segments"}, + "GetSmsChannel": {Verb: "Get", Resource: "SmsChannel", OutputListKey: "", OutputItemKey: "SMSChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/sms"}, + "GetSmsTemplate": {Verb: "Get", Resource: "SmsTemplate", OutputListKey: "", OutputItemKey: "SMSTemplateResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/sms"}, + "GetUserEndpoints": {Verb: "Get", Resource: "UserEndpoint", OutputListKey: "", OutputItemKey: "EndpointsResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/users/{UserId}"}, + "GetVoiceChannel": {Verb: "Get", Resource: "VoiceChannel", OutputListKey: "", OutputItemKey: "VoiceChannelResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/channels/voice"}, + "GetVoiceTemplate": {Verb: "Get", Resource: "VoiceTemplate", OutputListKey: "", OutputItemKey: "VoiceTemplateResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/voice"}, + "ListJourneys": {Verb: "List", Resource: "Journey", OutputListKey: "", OutputItemKey: "JourneysResponse", Method: "GET", URI: "/v1/apps/{ApplicationId}/journeys"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "TagsModel", Method: "GET", URI: "/v1/tags/{ResourceArn}"}, + "ListTemplateVersions": {Verb: "List", Resource: "TemplateVersion", OutputListKey: "", OutputItemKey: "TemplateVersionsResponse", Method: "GET", URI: "/v1/templates/{TemplateName}/{TemplateType}/versions"}, + "ListTemplates": {Verb: "List", Resource: "Template", OutputListKey: "", OutputItemKey: "TemplatesResponse", Method: "GET", URI: "/v1/templates"}, + "PutEventStream": {Verb: "Update", Resource: "EventStream", OutputListKey: "", OutputItemKey: "EventStream", Method: "POST", URI: "/v1/apps/{ApplicationId}/eventstream"}, + "PutEvents": {Verb: "Update", Resource: "Event", OutputListKey: "", OutputItemKey: "EventsResponse", Method: "POST", URI: "/v1/apps/{ApplicationId}/events"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{ResourceArn}"}, + "UpdateAdmChannel": {Verb: "Update", Resource: "AdmChannel", OutputListKey: "", OutputItemKey: "ADMChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/adm"}, + "UpdateApnsChannel": {Verb: "Update", Resource: "ApnsChannel", OutputListKey: "", OutputItemKey: "APNSChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/apns"}, + "UpdateApnsSandboxChannel": {Verb: "Update", Resource: "ApnsSandboxChannel", OutputListKey: "", OutputItemKey: "APNSSandboxChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/apns_sandbox"}, + "UpdateApnsVoipChannel": {Verb: "Update", Resource: "ApnsVoipChannel", OutputListKey: "", OutputItemKey: "APNSVoipChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/apns_voip"}, + "UpdateApnsVoipSandboxChannel": {Verb: "Update", Resource: "ApnsVoipSandboxChannel", OutputListKey: "", OutputItemKey: "APNSVoipSandboxChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/apns_voip_sandbox"}, + "UpdateApplicationSettings": {Verb: "Update", Resource: "ApplicationSetting", OutputListKey: "", OutputItemKey: "ApplicationSettingsResource", Method: "PUT", URI: "/v1/apps/{ApplicationId}/settings"}, + "UpdateBaiduChannel": {Verb: "Update", Resource: "BaiduChannel", OutputListKey: "", OutputItemKey: "BaiduChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/baidu"}, + "UpdateCampaign": {Verb: "Update", Resource: "Campaign", OutputListKey: "", OutputItemKey: "CampaignResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/campaigns/{CampaignId}"}, + "UpdateEmailChannel": {Verb: "Update", Resource: "EmailChannel", OutputListKey: "", OutputItemKey: "EmailChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/email"}, + "UpdateEmailTemplate": {Verb: "Update", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/email"}, + "UpdateEndpoint": {Verb: "Update", Resource: "Endpoint", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/apps/{ApplicationId}/endpoints/{EndpointId}"}, + "UpdateEndpointsBatch": {Verb: "Update", Resource: "EndpointsBatch", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/apps/{ApplicationId}/endpoints"}, + "UpdateGcmChannel": {Verb: "Update", Resource: "GcmChannel", OutputListKey: "", OutputItemKey: "GCMChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/gcm"}, + "UpdateInAppTemplate": {Verb: "Update", Resource: "InAppTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/inapp"}, + "UpdateJourney": {Verb: "Update", Resource: "Journey", OutputListKey: "", OutputItemKey: "JourneyResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}"}, + "UpdateJourneyState": {Verb: "Update", Resource: "JourneyState", OutputListKey: "", OutputItemKey: "JourneyResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/journeys/{JourneyId}/state"}, + "UpdatePushTemplate": {Verb: "Update", Resource: "PushTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/push"}, + "UpdateRecommenderConfiguration": {Verb: "Update", Resource: "RecommenderConfiguration", OutputListKey: "", OutputItemKey: "RecommenderConfigurationResponse", Method: "PUT", URI: "/v1/recommenders/{RecommenderId}"}, + "UpdateSegment": {Verb: "Update", Resource: "Segment", OutputListKey: "", OutputItemKey: "SegmentResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/segments/{SegmentId}"}, + "UpdateSmsChannel": {Verb: "Update", Resource: "SmsChannel", OutputListKey: "", OutputItemKey: "SMSChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/sms"}, + "UpdateSmsTemplate": {Verb: "Update", Resource: "SmsTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/sms"}, + "UpdateTemplateActiveVersion": {Verb: "Update", Resource: "TemplateActiveVersion", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/{TemplateType}/active-version"}, + "UpdateVoiceChannel": {Verb: "Update", Resource: "VoiceChannel", OutputListKey: "", OutputItemKey: "VoiceChannelResponse", Method: "PUT", URI: "/v1/apps/{ApplicationId}/channels/voice"}, + "UpdateVoiceTemplate": {Verb: "Update", Resource: "VoiceTemplate", OutputListKey: "", OutputItemKey: "MessageBody", Method: "PUT", URI: "/v1/templates/{TemplateName}/voice"}, + }) + crud.Register("polly", map[string]crud.OpMeta{ + "DeleteLexicon": {Verb: "Delete", Resource: "Lexicon", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/lexicons/{Name}"}, + "DescribeVoices": {Verb: "Get", Resource: "Voice", OutputListKey: "Voices", OutputItemKey: "", Method: "GET", URI: "/v1/voices"}, + "GetLexicon": {Verb: "Get", Resource: "Lexicon", OutputListKey: "", OutputItemKey: "Lexicon", Method: "GET", URI: "/v1/lexicons/{Name}"}, + "GetSpeechSynthesisTask": {Verb: "Get", Resource: "SpeechSynthesisTask", OutputListKey: "", OutputItemKey: "SynthesisTask", Method: "GET", URI: "/v1/synthesisTasks/{TaskId}"}, + "ListLexicons": {Verb: "List", Resource: "Lexicon", OutputListKey: "Lexicons", OutputItemKey: "", Method: "GET", URI: "/v1/lexicons"}, + "ListSpeechSynthesisTasks": {Verb: "List", Resource: "SpeechSynthesisTask", OutputListKey: "SynthesisTasks", OutputItemKey: "", Method: "GET", URI: "/v1/synthesisTasks"}, + "PutLexicon": {Verb: "Update", Resource: "Lexicon", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v1/lexicons/{Name}"}, + }) + crud.Register("qapps", map[string]crud.OpMeta{ + "CreateLibraryItem": {Verb: "Create", Resource: "LibraryItem", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/catalog.createItem"}, + "CreatePresignedUrl": {Verb: "Create", Resource: "PresignedUrl", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/apps.createPresignedUrl"}, + "CreateQApp": {Verb: "Create", Resource: "QApp", OutputListKey: "requiredCapabilities", OutputItemKey: "", Method: "POST", URI: "/apps.create"}, + "DeleteLibraryItem": {Verb: "Delete", Resource: "LibraryItem", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/catalog.deleteItem"}, + "DeleteQApp": {Verb: "Delete", Resource: "QApp", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/apps.delete"}, + "DescribeQAppPermissions": {Verb: "Get", Resource: "QAppPermission", OutputListKey: "permissions", OutputItemKey: "", Method: "GET", URI: "/apps.describeQAppPermissions"}, + "GetLibraryItem": {Verb: "Get", Resource: "LibraryItem", OutputListKey: "categories", OutputItemKey: "", Method: "GET", URI: "/catalog.getItem"}, + "GetQApp": {Verb: "Get", Resource: "QApp", OutputListKey: "requiredCapabilities", OutputItemKey: "appDefinition", Method: "GET", URI: "/apps.get"}, + "GetQAppSession": {Verb: "Get", Resource: "QAppSession", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/runtime.getQAppSession"}, + "GetQAppSessionMetadata": {Verb: "Get", Resource: "QAppSessionMetadata", OutputListKey: "", OutputItemKey: "sharingConfiguration", Method: "GET", URI: "/runtime.getQAppSessionMetadata"}, + "ListCategories": {Verb: "List", Resource: "Category", OutputListKey: "categories", OutputItemKey: "", Method: "GET", URI: "/catalog.listCategories"}, + "ListLibraryItems": {Verb: "List", Resource: "LibraryItem", OutputListKey: "libraryItems", OutputItemKey: "", Method: "GET", URI: "/catalog.list"}, + "ListQAppSessionData": {Verb: "List", Resource: "QAppSessionData", OutputListKey: "sessionData", OutputItemKey: "", Method: "GET", URI: "/runtime.listQAppSessionData"}, + "ListQApps": {Verb: "List", Resource: "QApp", OutputListKey: "apps", OutputItemKey: "", Method: "GET", URI: "/apps.list"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{resourceARN}"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tags/{resourceARN}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{resourceARN}"}, + "UpdateLibraryItem": {Verb: "Update", Resource: "LibraryItem", OutputListKey: "categories", OutputItemKey: "", Method: "POST", URI: "/catalog.updateItem"}, + "UpdateLibraryItemMetadata": {Verb: "Update", Resource: "LibraryItemMetadata", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/catalog.updateItemMetadata"}, + "UpdateQApp": {Verb: "Update", Resource: "QApp", OutputListKey: "requiredCapabilities", OutputItemKey: "", Method: "POST", URI: "/apps.update"}, + "UpdateQAppPermissions": {Verb: "Update", Resource: "QAppPermission", OutputListKey: "permissions", OutputItemKey: "", Method: "POST", URI: "/apps.updateQAppPermissions"}, + "UpdateQAppSession": {Verb: "Update", Resource: "QAppSession", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/runtime.updateQAppSession"}, + "UpdateQAppSessionMetadata": {Verb: "Update", Resource: "QAppSessionMetadata", OutputListKey: "", OutputItemKey: "sharingConfiguration", Method: "POST", URI: "/runtime.updateQAppSessionMetadata"}, + }) + crud.Register("qbusiness", map[string]crud.OpMeta{ + "CreateAnonymousWebExperienceUrl": {Verb: "Create", Resource: "AnonymousWebExperienceUrl", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/experiences/{webExperienceId}/anonymous-url"}, + "CreateApplication": {Verb: "Create", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications"}, + "CreateChatResponseConfiguration": {Verb: "Create", Resource: "ChatResponseConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/chatresponseconfigurations"}, + "CreateDataAccessor": {Verb: "Create", Resource: "DataAccessor", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/dataaccessors"}, + "CreateDataSource": {Verb: "Create", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/indices/{indexId}/datasources"}, + "CreateIndex": {Verb: "Create", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/indices"}, + "CreatePlugin": {Verb: "Create", Resource: "Plugin", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/plugins"}, + "CreateRetriever": {Verb: "Create", Resource: "Retriever", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/retrievers"}, + "CreateSubscription": {Verb: "Create", Resource: "Subscription", OutputListKey: "", OutputItemKey: "currentSubscription", Method: "POST", URI: "/applications/{applicationId}/subscriptions"}, + "CreateUser": {Verb: "Create", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/users"}, + "CreateWebExperience": {Verb: "Create", Resource: "WebExperience", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/experiences"}, + "DeleteApplication": {Verb: "Delete", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}"}, + "DeleteAttachment": {Verb: "Delete", Resource: "Attachment", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/conversations/{conversationId}/attachments/{attachmentId}"}, + "DeleteChatControlsConfiguration": {Verb: "Delete", Resource: "ChatControlsConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/chatcontrols"}, + "DeleteChatResponseConfiguration": {Verb: "Delete", Resource: "ChatResponseConfiguration", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/chatresponseconfigurations/{chatResponseConfigurationId}"}, + "DeleteConversation": {Verb: "Delete", Resource: "Conversation", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/conversations/{conversationId}"}, + "DeleteDataAccessor": {Verb: "Delete", Resource: "DataAccessor", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/dataaccessors/{dataAccessorId}"}, + "DeleteDataSource": {Verb: "Delete", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/indices/{indexId}/datasources/{dataSourceId}"}, + "DeleteGroup": {Verb: "Delete", Resource: "Group", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/indices/{indexId}/groups/{groupName}"}, + "DeleteIndex": {Verb: "Delete", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/indices/{indexId}"}, + "DeletePlugin": {Verb: "Delete", Resource: "Plugin", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/plugins/{pluginId}"}, + "DeleteRetriever": {Verb: "Delete", Resource: "Retriever", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/retrievers/{retrieverId}"}, + "DeleteUser": {Verb: "Delete", Resource: "User", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/users/{userId}"}, + "DeleteWebExperience": {Verb: "Delete", Resource: "WebExperience", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/applications/{applicationId}/experiences/{webExperienceId}"}, + "GetApplication": {Verb: "Get", Resource: "Application", OutputListKey: "clientIdsForOIDC", OutputItemKey: "attachmentsConfiguration", Method: "GET", URI: "/applications/{applicationId}"}, + "GetChatControlsConfiguration": {Verb: "Get", Resource: "ChatControlsConfiguration", OutputListKey: "topicConfigurations", OutputItemKey: "blockedPhrases", Method: "GET", URI: "/applications/{applicationId}/chatcontrols"}, + "GetChatResponseConfiguration": {Verb: "Get", Resource: "ChatResponseConfiguration", OutputListKey: "", OutputItemKey: "inUseConfiguration", Method: "GET", URI: "/applications/{applicationId}/chatresponseconfigurations/{chatResponseConfigurationId}"}, + "GetDataAccessor": {Verb: "Get", Resource: "DataAccessor", OutputListKey: "actionConfigurations", OutputItemKey: "authenticationDetail", Method: "GET", URI: "/applications/{applicationId}/dataaccessors/{dataAccessorId}"}, + "GetDataSource": {Verb: "Get", Resource: "DataSource", OutputListKey: "", OutputItemKey: "documentEnrichmentConfiguration", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}/datasources/{dataSourceId}"}, + "GetDocumentContent": {Verb: "Get", Resource: "DocumentContent", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/index/{indexId}/documents/{documentId}/content"}, + "GetGroup": {Verb: "Get", Resource: "Group", OutputListKey: "statusHistory", OutputItemKey: "status", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}/groups/{groupName}"}, + "GetIndex": {Verb: "Get", Resource: "Index", OutputListKey: "documentAttributeConfigurations", OutputItemKey: "capacityConfiguration", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}"}, + "GetMedia": {Verb: "Get", Resource: "Media", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/conversations/{conversationId}/messages/{messageId}/media/{mediaId}"}, + "GetPlugin": {Verb: "Get", Resource: "Plugin", OutputListKey: "", OutputItemKey: "customPluginConfiguration", Method: "GET", URI: "/applications/{applicationId}/plugins/{pluginId}"}, + "GetPolicy": {Verb: "Get", Resource: "Policy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/policy"}, + "GetRetriever": {Verb: "Get", Resource: "Retriever", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/retrievers/{retrieverId}"}, + "GetUser": {Verb: "Get", Resource: "User", OutputListKey: "userAliases", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/users/{userId}"}, + "GetWebExperience": {Verb: "Get", Resource: "WebExperience", OutputListKey: "origins", OutputItemKey: "browserExtensionConfiguration", Method: "GET", URI: "/applications/{applicationId}/experiences/{webExperienceId}"}, + "ListApplications": {Verb: "List", Resource: "Application", OutputListKey: "applications", OutputItemKey: "", Method: "GET", URI: "/applications"}, + "ListAttachments": {Verb: "List", Resource: "Attachment", OutputListKey: "attachments", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/attachments"}, + "ListChatResponseConfigurations": {Verb: "List", Resource: "ChatResponseConfiguration", OutputListKey: "chatResponseConfigurations", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/chatresponseconfigurations"}, + "ListConversations": {Verb: "List", Resource: "Conversation", OutputListKey: "conversations", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/conversations"}, + "ListDataAccessors": {Verb: "List", Resource: "DataAccessor", OutputListKey: "dataAccessors", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/dataaccessors"}, + "ListDataSourceSyncJobs": {Verb: "List", Resource: "DataSourceSyncJob", OutputListKey: "history", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}/datasources/{dataSourceId}/syncjobs"}, + "ListDataSources": {Verb: "List", Resource: "DataSource", OutputListKey: "dataSources", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}/datasources"}, + "ListDocuments": {Verb: "List", Resource: "Document", OutputListKey: "documentDetailList", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/index/{indexId}/documents"}, + "ListGroups": {Verb: "List", Resource: "Group", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/indices/{indexId}/groups"}, + "ListIndices": {Verb: "List", Resource: "Indice", OutputListKey: "indices", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/indices"}, + "ListMessages": {Verb: "List", Resource: "Message", OutputListKey: "messages", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/conversations/{conversationId}"}, + "ListPluginActions": {Verb: "List", Resource: "PluginAction", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/plugins/{pluginId}/actions"}, + "ListPluginTypeActions": {Verb: "List", Resource: "PluginTypeAction", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/pluginTypes/{pluginType}/actions"}, + "ListPluginTypeMetadata": {Verb: "List", Resource: "PluginTypeMetadata", OutputListKey: "items", OutputItemKey: "", Method: "GET", URI: "/pluginTypeMetadata"}, + "ListPlugins": {Verb: "List", Resource: "Plugin", OutputListKey: "plugins", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/plugins"}, + "ListRetrievers": {Verb: "List", Resource: "Retriever", OutputListKey: "retrievers", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/retrievers"}, + "ListSubscriptions": {Verb: "List", Resource: "Subscription", OutputListKey: "subscriptions", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/subscriptions"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "tags", OutputItemKey: "", Method: "GET", URI: "/v1/tags/{resourceARN}"}, + "ListWebExperiences": {Verb: "List", Resource: "WebExperience", OutputListKey: "webExperiences", OutputItemKey: "", Method: "GET", URI: "/applications/{applicationId}/experiences"}, + "PutFeedback": {Verb: "Update", Resource: "Feedback", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/applications/{applicationId}/conversations/{conversationId}/messages/{messageId}/feedback"}, + "PutGroup": {Verb: "Update", Resource: "Group", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/indices/{indexId}/groups"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v1/tags/{resourceARN}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v1/tags/{resourceARN}"}, + "UpdateApplication": {Verb: "Update", Resource: "Application", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}"}, + "UpdateChatControlsConfiguration": {Verb: "Update", Resource: "ChatControlsConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/applications/{applicationId}/chatcontrols"}, + "UpdateChatResponseConfiguration": {Verb: "Update", Resource: "ChatResponseConfiguration", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/chatresponseconfigurations/{chatResponseConfigurationId}"}, + "UpdateDataAccessor": {Verb: "Update", Resource: "DataAccessor", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/dataaccessors/{dataAccessorId}"}, + "UpdateDataSource": {Verb: "Update", Resource: "DataSource", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/indices/{indexId}/datasources/{dataSourceId}"}, + "UpdateIndex": {Verb: "Update", Resource: "Index", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/indices/{indexId}"}, + "UpdatePlugin": {Verb: "Update", Resource: "Plugin", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/plugins/{pluginId}"}, + "UpdateRetriever": {Verb: "Update", Resource: "Retriever", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/retrievers/{retrieverId}"}, + "UpdateSubscription": {Verb: "Update", Resource: "Subscription", OutputListKey: "", OutputItemKey: "currentSubscription", Method: "PUT", URI: "/applications/{applicationId}/subscriptions/{subscriptionId}"}, + "UpdateUser": {Verb: "Update", Resource: "User", OutputListKey: "userAliasesAdded", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/users/{userId}"}, + "UpdateWebExperience": {Verb: "Update", Resource: "WebExperience", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/applications/{applicationId}/experiences/{webExperienceId}"}, + }) + crud.Register("ram", map[string]crud.OpMeta{ + "CreatePermission": {Verb: "Create", Resource: "Permission", OutputListKey: "", OutputItemKey: "permission", Method: "POST", URI: "/createpermission"}, + "CreatePermissionVersion": {Verb: "Create", Resource: "PermissionVersion", OutputListKey: "", OutputItemKey: "permission", Method: "POST", URI: "/createpermissionversion"}, + "CreateResourceShare": {Verb: "Create", Resource: "ResourceShare", OutputListKey: "", OutputItemKey: "resourceShare", Method: "POST", URI: "/createresourceshare"}, + "DeletePermission": {Verb: "Delete", Resource: "Permission", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/deletepermission"}, + "DeletePermissionVersion": {Verb: "Delete", Resource: "PermissionVersion", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/deletepermissionversion"}, + "DeleteResourceShare": {Verb: "Delete", Resource: "ResourceShare", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/deleteresourceshare"}, + "GetPermission": {Verb: "Get", Resource: "Permission", OutputListKey: "", OutputItemKey: "permission", Method: "POST", URI: "/getpermission"}, + "GetResourcePolicies": {Verb: "Get", Resource: "ResourcePolicy", OutputListKey: "policies", OutputItemKey: "", Method: "POST", URI: "/getresourcepolicies"}, + "GetResourceShareAssociations": {Verb: "Get", Resource: "ResourceShareAssociation", OutputListKey: "resourceShareAssociations", OutputItemKey: "", Method: "POST", URI: "/getresourceshareassociations"}, + "GetResourceShareInvitations": {Verb: "Get", Resource: "ResourceShareInvitation", OutputListKey: "resourceShareInvitations", OutputItemKey: "", Method: "POST", URI: "/getresourceshareinvitations"}, + "GetResourceShares": {Verb: "Get", Resource: "ResourceShare", OutputListKey: "resourceShares", OutputItemKey: "", Method: "POST", URI: "/getresourceshares"}, + "ListPendingInvitationResources": {Verb: "List", Resource: "PendingInvitationResource", OutputListKey: "resources", OutputItemKey: "", Method: "POST", URI: "/listpendinginvitationresources"}, + "ListPermissionAssociations": {Verb: "List", Resource: "PermissionAssociation", OutputListKey: "permissions", OutputItemKey: "", Method: "POST", URI: "/listpermissionassociations"}, + "ListPermissionVersions": {Verb: "List", Resource: "PermissionVersion", OutputListKey: "permissions", OutputItemKey: "", Method: "POST", URI: "/listpermissionversions"}, + "ListPermissions": {Verb: "List", Resource: "Permission", OutputListKey: "permissions", OutputItemKey: "", Method: "POST", URI: "/listpermissions"}, + "ListPrincipals": {Verb: "List", Resource: "Principal", OutputListKey: "principals", OutputItemKey: "", Method: "POST", URI: "/listprincipals"}, + "ListReplacePermissionAssociationsWork": {Verb: "List", Resource: "ReplacePermissionAssociationsWork", OutputListKey: "replacePermissionAssociationsWorks", OutputItemKey: "", Method: "POST", URI: "/listreplacepermissionassociationswork"}, + "ListResourceSharePermissions": {Verb: "List", Resource: "ResourceSharePermission", OutputListKey: "permissions", OutputItemKey: "", Method: "POST", URI: "/listresourcesharepermissions"}, + "ListResourceTypes": {Verb: "List", Resource: "ResourceType", OutputListKey: "resourceTypes", OutputItemKey: "", Method: "POST", URI: "/listresourcetypes"}, + "ListResources": {Verb: "List", Resource: "Resource", OutputListKey: "resources", OutputItemKey: "", Method: "POST", URI: "/listresources"}, + "ListSourceAssociations": {Verb: "List", Resource: "SourceAssociation", OutputListKey: "sourceAssociations", OutputItemKey: "", Method: "POST", URI: "/listsourceassociations"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/tagresource"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/untagresource"}, + "UpdateResourceShare": {Verb: "Update", Resource: "ResourceShare", OutputListKey: "", OutputItemKey: "resourceShare", Method: "POST", URI: "/updateresourceshare"}, + }) crud.Register("rekognition", map[string]crud.OpMeta{ "CreateCollection": {Verb: "Create", Resource: "Collection", OutputListKey: "", OutputItemKey: ""}, "CreateDataset": {Verb: "Create", Resource: "Dataset", OutputListKey: "", OutputItemKey: ""}, @@ -1847,15 +4137,33 @@ func init() { "UpdateDatasetEntries": {Verb: "Update", Resource: "DatasetEntry", OutputListKey: "", OutputItemKey: ""}, "UpdateStreamProcessor": {Verb: "Update", Resource: "StreamProcessor", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("resourcegroups", map[string]crud.OpMeta{ + "CreateGroup": {Verb: "Create", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/groups"}, + "DeleteGroup": {Verb: "Delete", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/delete-group"}, + "GetAccountSettings": {Verb: "Get", Resource: "AccountSetting", OutputListKey: "", OutputItemKey: "AccountSettings", Method: "POST", URI: "/get-account-settings"}, + "GetGroup": {Verb: "Get", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/get-group"}, + "GetGroupConfiguration": {Verb: "Get", Resource: "GroupConfiguration", OutputListKey: "", OutputItemKey: "GroupConfiguration", Method: "POST", URI: "/get-group-configuration"}, + "GetGroupQuery": {Verb: "Get", Resource: "GroupQuery", OutputListKey: "", OutputItemKey: "GroupQuery", Method: "POST", URI: "/get-group-query"}, + "GetTagSyncTask": {Verb: "Get", Resource: "TagSyncTask", OutputListKey: "", OutputItemKey: "ResourceQuery", Method: "POST", URI: "/get-tag-sync-task"}, + "GetTags": {Verb: "Get", Resource: "Tag", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/resources/{Arn}/tags"}, + "ListGroupResources": {Verb: "List", Resource: "GroupResource", OutputListKey: "QueryErrors", OutputItemKey: "", Method: "POST", URI: "/list-group-resources"}, + "ListGroupingStatuses": {Verb: "List", Resource: "GroupingStatuse", OutputListKey: "GroupingStatuses", OutputItemKey: "", Method: "POST", URI: "/list-grouping-statuses"}, + "ListGroups": {Verb: "List", Resource: "Group", OutputListKey: "GroupIdentifiers", OutputItemKey: "", Method: "POST", URI: "/groups-list"}, + "ListTagSyncTasks": {Verb: "List", Resource: "TagSyncTask", OutputListKey: "TagSyncTasks", OutputItemKey: "", Method: "POST", URI: "/list-tag-sync-tasks"}, + "PutGroupConfiguration": {Verb: "Update", Resource: "GroupConfiguration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/put-group-configuration"}, + "UpdateAccountSettings": {Verb: "Update", Resource: "AccountSetting", OutputListKey: "", OutputItemKey: "AccountSettings", Method: "POST", URI: "/update-account-settings"}, + "UpdateGroup": {Verb: "Update", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/update-group"}, + "UpdateGroupQuery": {Verb: "Update", Resource: "GroupQuery", OutputListKey: "", OutputItemKey: "GroupQuery", Method: "POST", URI: "/update-group-query"}, + }) crud.Register("resourcegroupstaggingapi", map[string]crud.OpMeta{ - "DescribeReportCreation": {Verb: "Get", Resource: "ReportCreation", OutputListKey: "", OutputItemKey: ""}, - "GetComplianceSummary": {Verb: "Get", Resource: "ComplianceSummary", OutputListKey: "SummaryList", OutputItemKey: ""}, - "GetResources": {Verb: "Get", Resource: "Resource", OutputListKey: "ResourceTagMappingList", OutputItemKey: ""}, - "GetTagKeys": {Verb: "Get", Resource: "TagKey", OutputListKey: "TagKeys", OutputItemKey: ""}, - "GetTagValues": {Verb: "Get", Resource: "TagValue", OutputListKey: "TagValues", OutputItemKey: ""}, - "ListRequiredTags": {Verb: "List", Resource: "RequiredTag", OutputListKey: "RequiredTags", OutputItemKey: ""}, - "TagResources": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, - "UntagResources": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, + "DescribeReportCreation": {Verb: "Get", Resource: "ReportCreation", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DescribeReportCreation"}, + "GetComplianceSummary": {Verb: "Get", Resource: "ComplianceSummary", OutputListKey: "SummaryList", OutputItemKey: "", Method: "POST", URI: "/GetComplianceSummary"}, + "GetResources": {Verb: "Get", Resource: "Resource", OutputListKey: "ResourceTagMappingList", OutputItemKey: "", Method: "POST", URI: "/GetResources"}, + "GetTagKeys": {Verb: "Get", Resource: "TagKey", OutputListKey: "TagKeys", OutputItemKey: "", Method: "POST", URI: "/GetTagKeys"}, + "GetTagValues": {Verb: "Get", Resource: "TagValue", OutputListKey: "TagValues", OutputItemKey: "", Method: "POST", URI: "/GetTagValues"}, + "ListRequiredTags": {Verb: "List", Resource: "RequiredTag", OutputListKey: "RequiredTags", OutputItemKey: "", Method: "POST", URI: "/ListRequiredTags"}, + "TagResources": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/TagResources"}, + "UntagResources": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UntagResources"}, }) crud.Register("route53resolver", map[string]crud.OpMeta{ "CreateFirewallDomainList": {Verb: "Create", Resource: "FirewallDomainList", OutputListKey: "", OutputItemKey: "FirewallDomainList"}, @@ -2256,6 +4564,43 @@ func init() { "UpdateWorkforce": {Verb: "Update", Resource: "Workforce", OutputListKey: "", OutputItemKey: "Workforce"}, "UpdateWorkteam": {Verb: "Update", Resource: "Workteam", OutputListKey: "", OutputItemKey: "Workteam"}, }) + crud.Register("sagemakera2iruntime", map[string]crud.OpMeta{ + "DeleteHumanLoop": {Verb: "Delete", Resource: "HumanLoop", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/human-loops/{HumanLoopName}"}, + "DescribeHumanLoop": {Verb: "Get", Resource: "HumanLoop", OutputListKey: "", OutputItemKey: "HumanLoopOutput", Method: "GET", URI: "/human-loops/{HumanLoopName}"}, + "ListHumanLoops": {Verb: "List", Resource: "HumanLoop", OutputListKey: "HumanLoopSummaries", OutputItemKey: "", Method: "GET", URI: "/human-loops"}, + }) + crud.Register("sagemakeredge", map[string]crud.OpMeta{ + "GetDeployments": {Verb: "Get", Resource: "Deployment", OutputListKey: "Deployments", OutputItemKey: "", Method: "POST", URI: "/GetDeployments"}, + "GetDeviceRegistration": {Verb: "Get", Resource: "DeviceRegistration", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetDeviceRegistration"}, + }) + crud.Register("sagemakerfeaturestoreruntime", map[string]crud.OpMeta{ + "BatchGetRecord": {Verb: "List", Resource: "Record", OutputListKey: "Errors", OutputItemKey: "", Method: "POST", URI: "/BatchGetRecord"}, + "DeleteRecord": {Verb: "Delete", Resource: "Record", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/FeatureGroup/{FeatureGroupName}"}, + "GetRecord": {Verb: "Get", Resource: "Record", OutputListKey: "Record", OutputItemKey: "", Method: "GET", URI: "/FeatureGroup/{FeatureGroupName}"}, + "ListRecords": {Verb: "List", Resource: "Record", OutputListKey: "RecordIdentifiers", OutputItemKey: "", Method: "POST", URI: "/FeatureGroup/{FeatureGroupName}/ListRecords"}, + "PutRecord": {Verb: "Update", Resource: "Record", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/FeatureGroup/{FeatureGroupName}"}, + "UpdateRecord": {Verb: "Update", Resource: "Record", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/FeatureGroup/{FeatureGroupName}/Record"}, + }) + crud.Register("sagemakergeospatial", map[string]crud.OpMeta{ + "DeleteEarthObservationJob": {Verb: "Delete", Resource: "EarthObservationJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/earth-observation-jobs/{Arn}"}, + "DeleteVectorEnrichmentJob": {Verb: "Delete", Resource: "VectorEnrichmentJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/vector-enrichment-jobs/{Arn}"}, + "GetEarthObservationJob": {Verb: "Get", Resource: "EarthObservationJob", OutputListKey: "OutputBands", OutputItemKey: "ErrorDetails", Method: "GET", URI: "/earth-observation-jobs/{Arn}"}, + "GetRasterDataCollection": {Verb: "Get", Resource: "RasterDataCollection", OutputListKey: "ImageSourceBands", OutputItemKey: "", Method: "GET", URI: "/raster-data-collection/{Arn}"}, + "GetTile": {Verb: "Get", Resource: "Tile", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tile/{z}/{x}/{y}"}, + "GetVectorEnrichmentJob": {Verb: "Get", Resource: "VectorEnrichmentJob", OutputListKey: "", OutputItemKey: "ErrorDetails", Method: "GET", URI: "/vector-enrichment-jobs/{Arn}"}, + "ListEarthObservationJobs": {Verb: "List", Resource: "EarthObservationJob", OutputListKey: "EarthObservationJobSummaries", OutputItemKey: "", Method: "POST", URI: "/list-earth-observation-jobs"}, + "ListRasterDataCollections": {Verb: "List", Resource: "RasterDataCollection", OutputListKey: "RasterDataCollectionSummaries", OutputItemKey: "", Method: "GET", URI: "/raster-data-collections"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "ListVectorEnrichmentJobs": {Verb: "List", Resource: "VectorEnrichmentJob", OutputListKey: "VectorEnrichmentJobSummaries", OutputItemKey: "", Method: "POST", URI: "/list-vector-enrichment-jobs"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{ResourceArn}"}, + }) + crud.Register("sagemakerjobruntime", map[string]crud.OpMeta{ + "UpdateReward": {Verb: "Update", Resource: "Reward", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/update-reward"}, + }) + crud.Register("sagemakermetrics", map[string]crud.OpMeta{ + "BatchGetMetrics": {Verb: "List", Resource: "Metric", OutputListKey: "MetricQueryResults", OutputItemKey: "", Method: "POST", URI: "/BatchGetMetrics"}, + }) crud.Register("secretsmanager", map[string]crud.OpMeta{ "BatchGetSecretValue": {Verb: "List", Resource: "SecretValue", OutputListKey: "Errors", OutputItemKey: ""}, "CreateSecret": {Verb: "Create", Resource: "Secret", OutputListKey: "ReplicationStatus", OutputItemKey: ""}, @@ -2304,6 +4649,113 @@ func init() { "UpdateService": {Verb: "Update", Resource: "Service", OutputListKey: "", OutputItemKey: ""}, "UpdateServiceAttributes": {Verb: "Update", Resource: "ServiceAttribute", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("sesv2", map[string]crud.OpMeta{ + "BatchGetMetricData": {Verb: "List", Resource: "MetricData", OutputListKey: "Errors", OutputItemKey: "", Method: "POST", URI: "/v2/email/metrics/batch"}, + "CreateConfigurationSet": {Verb: "Create", Resource: "ConfigurationSet", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/configuration-sets"}, + "CreateConfigurationSetEventDestination": {Verb: "Create", Resource: "ConfigurationSetEventDestination", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/event-destinations"}, + "CreateContact": {Verb: "Create", Resource: "Contact", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/contact-lists/{ContactListName}/contacts"}, + "CreateContactList": {Verb: "Create", Resource: "ContactList", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/contact-lists"}, + "CreateCustomVerificationEmailTemplate": {Verb: "Create", Resource: "CustomVerificationEmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/custom-verification-email-templates"}, + "CreateDedicatedIpPool": {Verb: "Create", Resource: "DedicatedIpPool", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/dedicated-ip-pools"}, + "CreateDeliverabilityTestReport": {Verb: "Create", Resource: "DeliverabilityTestReport", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/deliverability-dashboard/test"}, + "CreateEmailIdentity": {Verb: "Create", Resource: "EmailIdentity", OutputListKey: "", OutputItemKey: "DkimAttributes", Method: "POST", URI: "/v2/email/identities"}, + "CreateEmailIdentityPolicy": {Verb: "Create", Resource: "EmailIdentityPolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/identities/{EmailIdentity}/policies/{PolicyName}"}, + "CreateEmailTemplate": {Verb: "Create", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/templates"}, + "CreateExportJob": {Verb: "Create", Resource: "ExportJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/export-jobs"}, + "CreateImportJob": {Verb: "Create", Resource: "ImportJob", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/import-jobs"}, + "CreateMultiRegionEndpoint": {Verb: "Create", Resource: "MultiRegionEndpoint", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/multi-region-endpoints"}, + "CreateTenant": {Verb: "Create", Resource: "Tenant", OutputListKey: "Tags", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants"}, + "CreateTenantResourceAssociation": {Verb: "Create", Resource: "TenantResourceAssociation", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants/resources"}, + "DeleteConfigurationSet": {Verb: "Delete", Resource: "ConfigurationSet", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/configuration-sets/{ConfigurationSetName}"}, + "DeleteConfigurationSetEventDestination": {Verb: "Delete", Resource: "ConfigurationSetEventDestination", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/event-destinations/{EventDestinationName}"}, + "DeleteContact": {Verb: "Delete", Resource: "Contact", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/contact-lists/{ContactListName}/contacts/{EmailAddress}"}, + "DeleteContactList": {Verb: "Delete", Resource: "ContactList", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/contact-lists/{ContactListName}"}, + "DeleteCustomVerificationEmailTemplate": {Verb: "Delete", Resource: "CustomVerificationEmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/custom-verification-email-templates/{TemplateName}"}, + "DeleteDedicatedIpPool": {Verb: "Delete", Resource: "DedicatedIpPool", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/dedicated-ip-pools/{PoolName}"}, + "DeleteEmailIdentity": {Verb: "Delete", Resource: "EmailIdentity", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/identities/{EmailIdentity}"}, + "DeleteEmailIdentityPolicy": {Verb: "Delete", Resource: "EmailIdentityPolicy", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/identities/{EmailIdentity}/policies/{PolicyName}"}, + "DeleteEmailTemplate": {Verb: "Delete", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/templates/{TemplateName}"}, + "DeleteMultiRegionEndpoint": {Verb: "Delete", Resource: "MultiRegionEndpoint", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/multi-region-endpoints/{EndpointName}"}, + "DeleteSuppressedDestination": {Verb: "Delete", Resource: "SuppressedDestination", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/suppression/addresses/{EmailAddress}"}, + "DeleteTenant": {Verb: "Delete", Resource: "Tenant", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants/delete"}, + "DeleteTenantResourceAssociation": {Verb: "Delete", Resource: "TenantResourceAssociation", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants/resources/delete"}, + "GetAccount": {Verb: "Get", Resource: "Account", OutputListKey: "", OutputItemKey: "Details", Method: "GET", URI: "/v2/email/account"}, + "GetBlacklistReports": {Verb: "Get", Resource: "BlacklistReport", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/email/deliverability-dashboard/blacklist-report"}, + "GetConfigurationSet": {Verb: "Get", Resource: "ConfigurationSet", OutputListKey: "Tags", OutputItemKey: "ArchivingOptions", Method: "GET", URI: "/v2/email/configuration-sets/{ConfigurationSetName}"}, + "GetConfigurationSetEventDestinations": {Verb: "Get", Resource: "ConfigurationSetEventDestination", OutputListKey: "EventDestinations", OutputItemKey: "", Method: "GET", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/event-destinations"}, + "GetContact": {Verb: "Get", Resource: "Contact", OutputListKey: "TopicDefaultPreferences", OutputItemKey: "", Method: "GET", URI: "/v2/email/contact-lists/{ContactListName}/contacts/{EmailAddress}"}, + "GetContactList": {Verb: "Get", Resource: "ContactList", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/v2/email/contact-lists/{ContactListName}"}, + "GetCustomVerificationEmailTemplate": {Verb: "Get", Resource: "CustomVerificationEmailTemplate", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/v2/email/custom-verification-email-templates/{TemplateName}"}, + "GetDedicatedIp": {Verb: "Get", Resource: "DedicatedIp", OutputListKey: "", OutputItemKey: "DedicatedIp", Method: "GET", URI: "/v2/email/dedicated-ips/{Ip}"}, + "GetDedicatedIpPool": {Verb: "Get", Resource: "DedicatedIpPool", OutputListKey: "", OutputItemKey: "DedicatedIpPool", Method: "GET", URI: "/v2/email/dedicated-ip-pools/{PoolName}"}, + "GetDedicatedIps": {Verb: "Get", Resource: "DedicatedIp", OutputListKey: "DedicatedIps", OutputItemKey: "", Method: "GET", URI: "/v2/email/dedicated-ips"}, + "GetDeliverabilityDashboardOptions": {Verb: "Get", Resource: "DeliverabilityDashboardOption", OutputListKey: "ActiveSubscribedDomains", OutputItemKey: "", Method: "GET", URI: "/v2/email/deliverability-dashboard"}, + "GetDeliverabilityTestReport": {Verb: "Get", Resource: "DeliverabilityTestReport", OutputListKey: "IspPlacements", OutputItemKey: "DeliverabilityTestReport", Method: "GET", URI: "/v2/email/deliverability-dashboard/test-reports/{ReportId}"}, + "GetDomainDeliverabilityCampaign": {Verb: "Get", Resource: "DomainDeliverabilityCampaign", OutputListKey: "", OutputItemKey: "DomainDeliverabilityCampaign", Method: "GET", URI: "/v2/email/deliverability-dashboard/campaigns/{CampaignId}"}, + "GetDomainStatisticsReport": {Verb: "Get", Resource: "DomainStatisticsReport", OutputListKey: "DailyVolumes", OutputItemKey: "OverallVolume", Method: "GET", URI: "/v2/email/deliverability-dashboard/statistics-report/{Domain}"}, + "GetEmailAddressInsights": {Verb: "Get", Resource: "EmailAddressInsight", OutputListKey: "", OutputItemKey: "MailboxValidation", Method: "POST", URI: "/v2/email/email-address-insights"}, + "GetEmailIdentity": {Verb: "Get", Resource: "EmailIdentity", OutputListKey: "Tags", OutputItemKey: "DkimAttributes", Method: "GET", URI: "/v2/email/identities/{EmailIdentity}"}, + "GetEmailIdentityPolicies": {Verb: "Get", Resource: "EmailIdentityPolicy", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/v2/email/identities/{EmailIdentity}/policies"}, + "GetEmailTemplate": {Verb: "Get", Resource: "EmailTemplate", OutputListKey: "Tags", OutputItemKey: "TemplateContent", Method: "GET", URI: "/v2/email/templates/{TemplateName}"}, + "GetExportJob": {Verb: "Get", Resource: "ExportJob", OutputListKey: "", OutputItemKey: "ExportDataSource", Method: "GET", URI: "/v2/email/export-jobs/{JobId}"}, + "GetImportJob": {Verb: "Get", Resource: "ImportJob", OutputListKey: "", OutputItemKey: "FailureInfo", Method: "GET", URI: "/v2/email/import-jobs/{JobId}"}, + "GetMessageInsights": {Verb: "Get", Resource: "MessageInsight", OutputListKey: "EmailTags", OutputItemKey: "", Method: "GET", URI: "/v2/email/insights/{MessageId}"}, + "GetMultiRegionEndpoint": {Verb: "Get", Resource: "MultiRegionEndpoint", OutputListKey: "Routes", OutputItemKey: "", Method: "GET", URI: "/v2/email/multi-region-endpoints/{EndpointName}"}, + "GetReputationEntity": {Verb: "Get", Resource: "ReputationEntity", OutputListKey: "", OutputItemKey: "ReputationEntity", Method: "GET", URI: "/v2/email/reputation/entities/{ReputationEntityType}/{ReputationEntityReference}"}, + "GetSuppressedDestination": {Verb: "Get", Resource: "SuppressedDestination", OutputListKey: "", OutputItemKey: "SuppressedDestination", Method: "GET", URI: "/v2/email/suppression/addresses/{EmailAddress}"}, + "GetTenant": {Verb: "Get", Resource: "Tenant", OutputListKey: "", OutputItemKey: "Tenant", Method: "POST", URI: "/v2/email/tenants/get"}, + "ListConfigurationSets": {Verb: "List", Resource: "ConfigurationSet", OutputListKey: "ConfigurationSets", OutputItemKey: "", Method: "GET", URI: "/v2/email/configuration-sets"}, + "ListContactLists": {Verb: "List", Resource: "ContactList", OutputListKey: "ContactLists", OutputItemKey: "", Method: "GET", URI: "/v2/email/contact-lists"}, + "ListContacts": {Verb: "List", Resource: "Contact", OutputListKey: "Contacts", OutputItemKey: "", Method: "POST", URI: "/v2/email/contact-lists/{ContactListName}/contacts/list"}, + "ListCustomVerificationEmailTemplates": {Verb: "List", Resource: "CustomVerificationEmailTemplate", OutputListKey: "CustomVerificationEmailTemplates", OutputItemKey: "", Method: "GET", URI: "/v2/email/custom-verification-email-templates"}, + "ListDedicatedIpPools": {Verb: "List", Resource: "DedicatedIpPool", OutputListKey: "DedicatedIpPools", OutputItemKey: "", Method: "GET", URI: "/v2/email/dedicated-ip-pools"}, + "ListDeliverabilityTestReports": {Verb: "List", Resource: "DeliverabilityTestReport", OutputListKey: "DeliverabilityTestReports", OutputItemKey: "", Method: "GET", URI: "/v2/email/deliverability-dashboard/test-reports"}, + "ListDomainDeliverabilityCampaigns": {Verb: "List", Resource: "DomainDeliverabilityCampaign", OutputListKey: "DomainDeliverabilityCampaigns", OutputItemKey: "", Method: "GET", URI: "/v2/email/deliverability-dashboard/domains/{SubscribedDomain}/campaigns"}, + "ListEmailIdentities": {Verb: "List", Resource: "EmailIdentity", OutputListKey: "EmailIdentities", OutputItemKey: "", Method: "GET", URI: "/v2/email/identities"}, + "ListEmailTemplates": {Verb: "List", Resource: "EmailTemplate", OutputListKey: "TemplatesMetadata", OutputItemKey: "", Method: "GET", URI: "/v2/email/templates"}, + "ListExportJobs": {Verb: "List", Resource: "ExportJob", OutputListKey: "ExportJobs", OutputItemKey: "", Method: "POST", URI: "/v2/email/list-export-jobs"}, + "ListImportJobs": {Verb: "List", Resource: "ImportJob", OutputListKey: "ImportJobs", OutputItemKey: "", Method: "POST", URI: "/v2/email/import-jobs/list"}, + "ListMultiRegionEndpoints": {Verb: "List", Resource: "MultiRegionEndpoint", OutputListKey: "MultiRegionEndpoints", OutputItemKey: "", Method: "GET", URI: "/v2/email/multi-region-endpoints"}, + "ListRecommendations": {Verb: "List", Resource: "Recommendation", OutputListKey: "Recommendations", OutputItemKey: "", Method: "POST", URI: "/v2/email/vdm/recommendations"}, + "ListReputationEntities": {Verb: "List", Resource: "ReputationEntity", OutputListKey: "ReputationEntities", OutputItemKey: "", Method: "POST", URI: "/v2/email/reputation/entities"}, + "ListResourceTenants": {Verb: "List", Resource: "ResourceTenant", OutputListKey: "ResourceTenants", OutputItemKey: "", Method: "POST", URI: "/v2/email/resources/tenants/list"}, + "ListSuppressedDestinations": {Verb: "List", Resource: "SuppressedDestination", OutputListKey: "SuppressedDestinationSummaries", OutputItemKey: "", Method: "GET", URI: "/v2/email/suppression/addresses"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/v2/email/tags"}, + "ListTenantResources": {Verb: "List", Resource: "TenantResource", OutputListKey: "TenantResources", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants/resources/list"}, + "ListTenants": {Verb: "List", Resource: "Tenant", OutputListKey: "Tenants", OutputItemKey: "", Method: "POST", URI: "/v2/email/tenants/list"}, + "PutAccountDedicatedIpWarmupAttributes": {Verb: "Update", Resource: "AccountDedicatedIpWarmupAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/account/dedicated-ips/warmup"}, + "PutAccountDetails": {Verb: "Update", Resource: "AccountDetail", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/account/details"}, + "PutAccountSendingAttributes": {Verb: "Update", Resource: "AccountSendingAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/account/sending"}, + "PutAccountSuppressionAttributes": {Verb: "Update", Resource: "AccountSuppressionAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/account/suppression"}, + "PutAccountVdmAttributes": {Verb: "Update", Resource: "AccountVdmAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/account/vdm"}, + "PutConfigurationSetArchivingOptions": {Verb: "Update", Resource: "ConfigurationSetArchivingOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/archiving-options"}, + "PutConfigurationSetDeliveryOptions": {Verb: "Update", Resource: "ConfigurationSetDeliveryOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/delivery-options"}, + "PutConfigurationSetReputationOptions": {Verb: "Update", Resource: "ConfigurationSetReputationOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/reputation-options"}, + "PutConfigurationSetSendingOptions": {Verb: "Update", Resource: "ConfigurationSetSendingOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/sending"}, + "PutConfigurationSetSuppressionOptions": {Verb: "Update", Resource: "ConfigurationSetSuppressionOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/suppression-options"}, + "PutConfigurationSetTrackingOptions": {Verb: "Update", Resource: "ConfigurationSetTrackingOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/tracking-options"}, + "PutConfigurationSetVdmOptions": {Verb: "Update", Resource: "ConfigurationSetVdmOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/vdm-options"}, + "PutDedicatedIpInPool": {Verb: "Update", Resource: "DedicatedIpInPool", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/dedicated-ips/{Ip}/pool"}, + "PutDedicatedIpPoolScalingAttributes": {Verb: "Update", Resource: "DedicatedIpPoolScalingAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/dedicated-ip-pools/{PoolName}/scaling"}, + "PutDedicatedIpWarmupAttributes": {Verb: "Update", Resource: "DedicatedIpWarmupAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/dedicated-ips/{Ip}/warmup"}, + "PutDeliverabilityDashboardOption": {Verb: "Update", Resource: "DeliverabilityDashboardOption", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/deliverability-dashboard"}, + "PutEmailIdentityConfigurationSetAttributes": {Verb: "Update", Resource: "EmailIdentityConfigurationSetAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/configuration-set"}, + "PutEmailIdentityDkimAttributes": {Verb: "Update", Resource: "EmailIdentityDkimAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/dkim"}, + "PutEmailIdentityDkimSigningAttributes": {Verb: "Update", Resource: "EmailIdentityDkimSigningAttribute", OutputListKey: "DkimTokens", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/dkim/signing"}, + "PutEmailIdentityFeedbackAttributes": {Verb: "Update", Resource: "EmailIdentityFeedbackAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/feedback"}, + "PutEmailIdentityMailFromAttributes": {Verb: "Update", Resource: "EmailIdentityMailFromAttribute", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/mail-from"}, + "PutSuppressedDestination": {Verb: "Update", Resource: "SuppressedDestination", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/suppression/addresses"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/v2/email/tags"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/v2/email/tags"}, + "UpdateConfigurationSetEventDestination": {Verb: "Update", Resource: "ConfigurationSetEventDestination", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/configuration-sets/{ConfigurationSetName}/event-destinations/{EventDestinationName}"}, + "UpdateContact": {Verb: "Update", Resource: "Contact", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/contact-lists/{ContactListName}/contacts/{EmailAddress}"}, + "UpdateContactList": {Verb: "Update", Resource: "ContactList", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/contact-lists/{ContactListName}"}, + "UpdateCustomVerificationEmailTemplate": {Verb: "Update", Resource: "CustomVerificationEmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/custom-verification-email-templates/{TemplateName}"}, + "UpdateEmailIdentityPolicy": {Verb: "Update", Resource: "EmailIdentityPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/identities/{EmailIdentity}/policies/{PolicyName}"}, + "UpdateEmailTemplate": {Verb: "Update", Resource: "EmailTemplate", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/templates/{TemplateName}"}, + "UpdateReputationEntityCustomerManagedStatus": {Verb: "Update", Resource: "ReputationEntityCustomerManagedStatu", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/reputation/entities/{ReputationEntityType}/{ReputationEntityReference}/customer-managed-status"}, + "UpdateReputationEntityPolicy": {Verb: "Update", Resource: "ReputationEntityPolicy", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/v2/email/reputation/entities/{ReputationEntityType}/{ReputationEntityReference}/policy"}, + }) crud.Register("sfn", map[string]crud.OpMeta{ "CreateActivity": {Verb: "Create", Resource: "Activity", OutputListKey: "", OutputItemKey: ""}, "CreateStateMachine": {Verb: "Create", Resource: "StateMachine", OutputListKey: "", OutputItemKey: ""}, @@ -2649,45 +5101,48 @@ func init() { "UpdateTable": {Verb: "Update", Resource: "Table", OutputListKey: "", OutputItemKey: "Table"}, }) crud.Register("transcribe", map[string]crud.OpMeta{ - "CreateCallAnalyticsCategory": {Verb: "Create", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties"}, - "CreateLanguageModel": {Verb: "Create", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: "InputDataConfig"}, - "CreateMedicalVocabulary": {Verb: "Create", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: ""}, - "CreateVocabulary": {Verb: "Create", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: ""}, - "CreateVocabularyFilter": {Verb: "Create", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: ""}, - "DeleteCallAnalyticsCategory": {Verb: "Delete", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: ""}, - "DeleteCallAnalyticsJob": {Verb: "Delete", Resource: "CallAnalyticsJob", OutputListKey: "", OutputItemKey: ""}, - "DeleteLanguageModel": {Verb: "Delete", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: ""}, - "DeleteMedicalScribeJob": {Verb: "Delete", Resource: "MedicalScribeJob", OutputListKey: "", OutputItemKey: ""}, - "DeleteMedicalTranscriptionJob": {Verb: "Delete", Resource: "MedicalTranscriptionJob", OutputListKey: "", OutputItemKey: ""}, - "DeleteMedicalVocabulary": {Verb: "Delete", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: ""}, - "DeleteTranscriptionJob": {Verb: "Delete", Resource: "TranscriptionJob", OutputListKey: "", OutputItemKey: ""}, - "DeleteVocabulary": {Verb: "Delete", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: ""}, - "DeleteVocabularyFilter": {Verb: "Delete", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: ""}, - "DescribeLanguageModel": {Verb: "Get", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: "LanguageModel"}, - "GetCallAnalyticsCategory": {Verb: "Get", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties"}, - "GetCallAnalyticsJob": {Verb: "Get", Resource: "CallAnalyticsJob", OutputListKey: "", OutputItemKey: "CallAnalyticsJob"}, - "GetMedicalScribeJob": {Verb: "Get", Resource: "MedicalScribeJob", OutputListKey: "", OutputItemKey: "MedicalScribeJob"}, - "GetMedicalTranscriptionJob": {Verb: "Get", Resource: "MedicalTranscriptionJob", OutputListKey: "", OutputItemKey: "MedicalTranscriptionJob"}, - "GetMedicalVocabulary": {Verb: "Get", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: ""}, - "GetTranscriptionJob": {Verb: "Get", Resource: "TranscriptionJob", OutputListKey: "", OutputItemKey: "TranscriptionJob"}, - "GetVocabulary": {Verb: "Get", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: ""}, - "GetVocabularyFilter": {Verb: "Get", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: ""}, - "ListCallAnalyticsCategories": {Verb: "List", Resource: "CallAnalyticsCategory", OutputListKey: "Categories", OutputItemKey: ""}, - "ListCallAnalyticsJobs": {Verb: "List", Resource: "CallAnalyticsJob", OutputListKey: "CallAnalyticsJobSummaries", OutputItemKey: ""}, - "ListLanguageModels": {Verb: "List", Resource: "LanguageModel", OutputListKey: "Models", OutputItemKey: ""}, - "ListMedicalScribeJobs": {Verb: "List", Resource: "MedicalScribeJob", OutputListKey: "MedicalScribeJobSummaries", OutputItemKey: ""}, - "ListMedicalTranscriptionJobs": {Verb: "List", Resource: "MedicalTranscriptionJob", OutputListKey: "MedicalTranscriptionJobSummaries", OutputItemKey: ""}, - "ListMedicalVocabularies": {Verb: "List", Resource: "MedicalVocabulary", OutputListKey: "Vocabularies", OutputItemKey: ""}, - "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: ""}, - "ListTranscriptionJobs": {Verb: "List", Resource: "TranscriptionJob", OutputListKey: "TranscriptionJobSummaries", OutputItemKey: ""}, - "ListVocabularies": {Verb: "List", Resource: "Vocabulary", OutputListKey: "Vocabularies", OutputItemKey: ""}, - "ListVocabularyFilters": {Verb: "List", Resource: "VocabularyFilter", OutputListKey: "VocabularyFilters", OutputItemKey: ""}, - "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, - "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, - "UpdateCallAnalyticsCategory": {Verb: "Update", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties"}, - "UpdateMedicalVocabulary": {Verb: "Update", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: ""}, - "UpdateVocabulary": {Verb: "Update", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: ""}, - "UpdateVocabularyFilter": {Verb: "Update", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: ""}, + "CreateCallAnalyticsCategory": {Verb: "Create", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties", Method: "PUT", URI: "/callanalyticscategories/{CategoryName}"}, + "CreateLanguageModel": {Verb: "Create", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: "InputDataConfig", Method: "PUT", URI: "/languagemodels/{ModelName}"}, + "CreateMedicalVocabulary": {Verb: "Create", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/medicalvocabularies/{VocabularyName}"}, + "CreateVocabulary": {Verb: "Create", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/vocabularies/{VocabularyName}"}, + "CreateVocabularyFilter": {Verb: "Create", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/vocabularyFilters/{VocabularyFilterName}"}, + "DeleteCallAnalyticsCategory": {Verb: "Delete", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/callanalyticscategories/{CategoryName}"}, + "DeleteCallAnalyticsJob": {Verb: "Delete", Resource: "CallAnalyticsJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/callanalyticsjobs/{CallAnalyticsJobName}"}, + "DeleteLanguageModel": {Verb: "Delete", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/languagemodels/{ModelName}"}, + "DeleteMedicalScribeJob": {Verb: "Delete", Resource: "MedicalScribeJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/medicalscribejobs/{MedicalScribeJobName}"}, + "DeleteMedicalTranscriptionJob": {Verb: "Delete", Resource: "MedicalTranscriptionJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/medicaltranscriptionjobs/{MedicalTranscriptionJobName}"}, + "DeleteMedicalVocabulary": {Verb: "Delete", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/medicalvocabularies/{VocabularyName}"}, + "DeleteTranscriptionJob": {Verb: "Delete", Resource: "TranscriptionJob", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/transcriptionjobs/{TranscriptionJobName}"}, + "DeleteVocabulary": {Verb: "Delete", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/vocabularies/{VocabularyName}"}, + "DeleteVocabularyFilter": {Verb: "Delete", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/vocabularyFilters/{VocabularyFilterName}"}, + "DescribeLanguageModel": {Verb: "Get", Resource: "LanguageModel", OutputListKey: "", OutputItemKey: "LanguageModel", Method: "GET", URI: "/languagemodels/{ModelName}"}, + "GetCallAnalyticsCategory": {Verb: "Get", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties", Method: "GET", URI: "/callanalyticscategories/{CategoryName}"}, + "GetCallAnalyticsJob": {Verb: "Get", Resource: "CallAnalyticsJob", OutputListKey: "", OutputItemKey: "CallAnalyticsJob", Method: "GET", URI: "/callanalyticsjobs/{CallAnalyticsJobName}"}, + "GetMedicalScribeJob": {Verb: "Get", Resource: "MedicalScribeJob", OutputListKey: "", OutputItemKey: "MedicalScribeJob", Method: "GET", URI: "/medicalscribejobs/{MedicalScribeJobName}"}, + "GetMedicalTranscriptionJob": {Verb: "Get", Resource: "MedicalTranscriptionJob", OutputListKey: "", OutputItemKey: "MedicalTranscriptionJob", Method: "GET", URI: "/medicaltranscriptionjobs/{MedicalTranscriptionJobName}"}, + "GetMedicalVocabulary": {Verb: "Get", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/medicalvocabularies/{VocabularyName}"}, + "GetTranscriptionJob": {Verb: "Get", Resource: "TranscriptionJob", OutputListKey: "", OutputItemKey: "TranscriptionJob", Method: "GET", URI: "/transcriptionjobs/{TranscriptionJobName}"}, + "GetVocabulary": {Verb: "Get", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/vocabularies/{VocabularyName}"}, + "GetVocabularyFilter": {Verb: "Get", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: "", Method: "GET", URI: "/vocabularyFilters/{VocabularyFilterName}"}, + "ListCallAnalyticsCategories": {Verb: "List", Resource: "CallAnalyticsCategory", OutputListKey: "Categories", OutputItemKey: "", Method: "GET", URI: "/callanalyticscategories"}, + "ListCallAnalyticsJobs": {Verb: "List", Resource: "CallAnalyticsJob", OutputListKey: "CallAnalyticsJobSummaries", OutputItemKey: "", Method: "GET", URI: "/callanalyticsjobs"}, + "ListLanguageModels": {Verb: "List", Resource: "LanguageModel", OutputListKey: "Models", OutputItemKey: "", Method: "GET", URI: "/languagemodels"}, + "ListMedicalScribeJobs": {Verb: "List", Resource: "MedicalScribeJob", OutputListKey: "MedicalScribeJobSummaries", OutputItemKey: "", Method: "GET", URI: "/medicalscribejobs"}, + "ListMedicalTranscriptionJobs": {Verb: "List", Resource: "MedicalTranscriptionJob", OutputListKey: "MedicalTranscriptionJobSummaries", OutputItemKey: "", Method: "GET", URI: "/medicaltranscriptionjobs"}, + "ListMedicalVocabularies": {Verb: "List", Resource: "MedicalVocabulary", OutputListKey: "Vocabularies", OutputItemKey: "", Method: "GET", URI: "/medicalvocabularies"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: "", Method: "GET", URI: "/tags/{ResourceArn}"}, + "ListTranscriptionJobs": {Verb: "List", Resource: "TranscriptionJob", OutputListKey: "TranscriptionJobSummaries", OutputItemKey: "", Method: "GET", URI: "/transcriptionjobs"}, + "ListVocabularies": {Verb: "List", Resource: "Vocabulary", OutputListKey: "Vocabularies", OutputItemKey: "", Method: "GET", URI: "/vocabularies"}, + "ListVocabularyFilters": {Verb: "List", Resource: "VocabularyFilter", OutputListKey: "VocabularyFilters", OutputItemKey: "", Method: "GET", URI: "/vocabularyFilters"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/tags/{ResourceArn}"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "DELETE", URI: "/tags/{ResourceArn}"}, + "UpdateCallAnalyticsCategory": {Verb: "Update", Resource: "CallAnalyticsCategory", OutputListKey: "", OutputItemKey: "CategoryProperties", Method: "PATCH", URI: "/callanalyticscategories/{CategoryName}"}, + "UpdateMedicalVocabulary": {Verb: "Update", Resource: "MedicalVocabulary", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/medicalvocabularies/{VocabularyName}"}, + "UpdateVocabulary": {Verb: "Update", Resource: "Vocabulary", OutputListKey: "", OutputItemKey: "", Method: "PATCH", URI: "/vocabularies/{VocabularyName}"}, + "UpdateVocabularyFilter": {Verb: "Update", Resource: "VocabularyFilter", OutputListKey: "", OutputItemKey: "", Method: "PUT", URI: "/vocabularyFilters/{VocabularyFilterName}"}, + }) + crud.Register("transcribestreaming", map[string]crud.OpMeta{ + "GetMedicalScribeStream": {Verb: "Get", Resource: "MedicalScribeStream", OutputListKey: "", OutputItemKey: "MedicalScribeStreamDetails", Method: "GET", URI: "/medical-scribe-stream/{SessionId}"}, }) crud.Register("transfer", map[string]crud.OpMeta{ "CreateAccess": {Verb: "Create", Resource: "Access", OutputListKey: "", OutputItemKey: ""}, @@ -2696,7 +5151,7 @@ func init() { "CreateProfile": {Verb: "Create", Resource: "Profile", OutputListKey: "", OutputItemKey: ""}, "CreateServer": {Verb: "Create", Resource: "Server", OutputListKey: "", OutputItemKey: ""}, "CreateUser": {Verb: "Create", Resource: "User", OutputListKey: "", OutputItemKey: ""}, - "CreateWebApp": {Verb: "Create", Resource: "WebApp", OutputListKey: "", OutputItemKey: ""}, + "CreateWebApp": {Verb: "Create", Resource: "WebApp", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/createWebApp"}, "CreateWorkflow": {Verb: "Create", Resource: "Workflow", OutputListKey: "", OutputItemKey: ""}, "DeleteAccess": {Verb: "Delete", Resource: "Access", OutputListKey: "", OutputItemKey: ""}, "DeleteAgreement": {Verb: "Delete", Resource: "Agreement", OutputListKey: "", OutputItemKey: ""}, @@ -2707,8 +5162,8 @@ func init() { "DeleteServer": {Verb: "Delete", Resource: "Server", OutputListKey: "", OutputItemKey: ""}, "DeleteSshPublicKey": {Verb: "Delete", Resource: "SshPublicKey", OutputListKey: "", OutputItemKey: ""}, "DeleteUser": {Verb: "Delete", Resource: "User", OutputListKey: "", OutputItemKey: ""}, - "DeleteWebApp": {Verb: "Delete", Resource: "WebApp", OutputListKey: "", OutputItemKey: ""}, - "DeleteWebAppCustomization": {Verb: "Delete", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: ""}, + "DeleteWebApp": {Verb: "Delete", Resource: "WebApp", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/deleteWebApp"}, + "DeleteWebAppCustomization": {Verb: "Delete", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/deleteWebAppCustomization"}, "DeleteWorkflow": {Verb: "Delete", Resource: "Workflow", OutputListKey: "", OutputItemKey: ""}, "DescribeAccess": {Verb: "Get", Resource: "Access", OutputListKey: "", OutputItemKey: "Access"}, "DescribeAgreement": {Verb: "Get", Resource: "Agreement", OutputListKey: "", OutputItemKey: "Agreement"}, @@ -2720,22 +5175,22 @@ func init() { "DescribeSecurityPolicy": {Verb: "Get", Resource: "SecurityPolicy", OutputListKey: "", OutputItemKey: "SecurityPolicy"}, "DescribeServer": {Verb: "Get", Resource: "Server", OutputListKey: "", OutputItemKey: "Server"}, "DescribeUser": {Verb: "Get", Resource: "User", OutputListKey: "", OutputItemKey: "User"}, - "DescribeWebApp": {Verb: "Get", Resource: "WebApp", OutputListKey: "", OutputItemKey: "WebApp"}, - "DescribeWebAppCustomization": {Verb: "Get", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: "WebAppCustomization"}, + "DescribeWebApp": {Verb: "Get", Resource: "WebApp", OutputListKey: "", OutputItemKey: "WebApp", Method: "POST", URI: "/describeWebApp"}, + "DescribeWebAppCustomization": {Verb: "Get", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: "WebAppCustomization", Method: "POST", URI: "/describeWebAppCustomization"}, "DescribeWorkflow": {Verb: "Get", Resource: "Workflow", OutputListKey: "", OutputItemKey: "Workflow"}, "ListAccesses": {Verb: "List", Resource: "Access", OutputListKey: "Accesses", OutputItemKey: ""}, "ListAgreements": {Verb: "List", Resource: "Agreement", OutputListKey: "Agreements", OutputItemKey: ""}, "ListCertificates": {Verb: "List", Resource: "Certificate", OutputListKey: "Certificates", OutputItemKey: ""}, "ListConnectors": {Verb: "List", Resource: "Connector", OutputListKey: "Connectors", OutputItemKey: ""}, "ListExecutions": {Verb: "List", Resource: "Execution", OutputListKey: "Executions", OutputItemKey: ""}, - "ListFileTransferResults": {Verb: "List", Resource: "FileTransferResult", OutputListKey: "FileTransferResults", OutputItemKey: ""}, + "ListFileTransferResults": {Verb: "List", Resource: "FileTransferResult", OutputListKey: "FileTransferResults", OutputItemKey: "", Method: "POST", URI: "/listFileTransferResults"}, "ListHostKeys": {Verb: "List", Resource: "HostKey", OutputListKey: "HostKeys", OutputItemKey: ""}, "ListProfiles": {Verb: "List", Resource: "Profile", OutputListKey: "Profiles", OutputItemKey: ""}, "ListSecurityPolicies": {Verb: "List", Resource: "SecurityPolicy", OutputListKey: "SecurityPolicyNames", OutputItemKey: ""}, "ListServers": {Verb: "List", Resource: "Server", OutputListKey: "Servers", OutputItemKey: ""}, "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: ""}, "ListUsers": {Verb: "List", Resource: "User", OutputListKey: "Users", OutputItemKey: ""}, - "ListWebApps": {Verb: "List", Resource: "WebApp", OutputListKey: "WebApps", OutputItemKey: ""}, + "ListWebApps": {Verb: "List", Resource: "WebApp", OutputListKey: "WebApps", OutputItemKey: "", Method: "POST", URI: "/listWebApps"}, "ListWorkflows": {Verb: "List", Resource: "Workflow", OutputListKey: "Workflows", OutputItemKey: ""}, "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: ""}, @@ -2747,8 +5202,8 @@ func init() { "UpdateProfile": {Verb: "Update", Resource: "Profile", OutputListKey: "", OutputItemKey: ""}, "UpdateServer": {Verb: "Update", Resource: "Server", OutputListKey: "", OutputItemKey: ""}, "UpdateUser": {Verb: "Update", Resource: "User", OutputListKey: "", OutputItemKey: ""}, - "UpdateWebApp": {Verb: "Update", Resource: "WebApp", OutputListKey: "", OutputItemKey: ""}, - "UpdateWebAppCustomization": {Verb: "Update", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: ""}, + "UpdateWebApp": {Verb: "Update", Resource: "WebApp", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/updateWebApp"}, + "UpdateWebAppCustomization": {Verb: "Update", Resource: "WebAppCustomization", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/updateWebAppCustomization"}, }) crud.Register("translate", map[string]crud.OpMeta{ "CreateParallelData": {Verb: "Create", Resource: "ParallelData", OutputListKey: "", OutputItemKey: ""}, @@ -2923,4 +5378,42 @@ func init() { "UpdateRuleGroup": {Verb: "Update", Resource: "RuleGroup", OutputListKey: "", OutputItemKey: ""}, "UpdateWebACL": {Verb: "Update", Resource: "WebACL", OutputListKey: "", OutputItemKey: ""}, }) + crud.Register("xray", map[string]crud.OpMeta{ + "BatchGetTraces": {Verb: "List", Resource: "Trace", OutputListKey: "Traces", OutputItemKey: "", Method: "POST", URI: "/Traces"}, + "CreateGroup": {Verb: "Create", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/CreateGroup"}, + "CreateSamplingRule": {Verb: "Create", Resource: "SamplingRule", OutputListKey: "", OutputItemKey: "SamplingRuleRecord", Method: "POST", URI: "/CreateSamplingRule"}, + "DeleteGroup": {Verb: "Delete", Resource: "Group", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteGroup"}, + "DeleteResourcePolicy": {Verb: "Delete", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/DeleteResourcePolicy"}, + "DeleteSamplingRule": {Verb: "Delete", Resource: "SamplingRule", OutputListKey: "", OutputItemKey: "SamplingRuleRecord", Method: "POST", URI: "/DeleteSamplingRule"}, + "GetEncryptionConfig": {Verb: "Get", Resource: "EncryptionConfig", OutputListKey: "", OutputItemKey: "EncryptionConfig", Method: "POST", URI: "/EncryptionConfig"}, + "GetGroup": {Verb: "Get", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/GetGroup"}, + "GetGroups": {Verb: "Get", Resource: "Group", OutputListKey: "Groups", OutputItemKey: "", Method: "POST", URI: "/Groups"}, + "GetIndexingRules": {Verb: "Get", Resource: "IndexingRule", OutputListKey: "IndexingRules", OutputItemKey: "", Method: "POST", URI: "/GetIndexingRules"}, + "GetInsight": {Verb: "Get", Resource: "Insight", OutputListKey: "", OutputItemKey: "Insight", Method: "POST", URI: "/Insight"}, + "GetInsightEvents": {Verb: "Get", Resource: "InsightEvent", OutputListKey: "InsightEvents", OutputItemKey: "", Method: "POST", URI: "/InsightEvents"}, + "GetInsightImpactGraph": {Verb: "Get", Resource: "InsightImpactGraph", OutputListKey: "Services", OutputItemKey: "", Method: "POST", URI: "/InsightImpactGraph"}, + "GetInsightSummaries": {Verb: "Get", Resource: "InsightSummary", OutputListKey: "InsightSummaries", OutputItemKey: "", Method: "POST", URI: "/InsightSummaries"}, + "GetRetrievedTracesGraph": {Verb: "Get", Resource: "RetrievedTracesGraph", OutputListKey: "Services", OutputItemKey: "", Method: "POST", URI: "/GetRetrievedTracesGraph"}, + "GetSamplingRules": {Verb: "Get", Resource: "SamplingRule", OutputListKey: "SamplingRuleRecords", OutputItemKey: "", Method: "POST", URI: "/GetSamplingRules"}, + "GetSamplingStatisticSummaries": {Verb: "Get", Resource: "SamplingStatisticSummary", OutputListKey: "SamplingStatisticSummaries", OutputItemKey: "", Method: "POST", URI: "/SamplingStatisticSummaries"}, + "GetSamplingTargets": {Verb: "Get", Resource: "SamplingTarget", OutputListKey: "SamplingTargetDocuments", OutputItemKey: "", Method: "POST", URI: "/SamplingTargets"}, + "GetServiceGraph": {Verb: "Get", Resource: "ServiceGraph", OutputListKey: "Services", OutputItemKey: "", Method: "POST", URI: "/ServiceGraph"}, + "GetTimeSeriesServiceStatistics": {Verb: "Get", Resource: "TimeSeriesServiceStatistic", OutputListKey: "TimeSeriesServiceStatistics", OutputItemKey: "", Method: "POST", URI: "/TimeSeriesServiceStatistics"}, + "GetTraceGraph": {Verb: "Get", Resource: "TraceGraph", OutputListKey: "Services", OutputItemKey: "", Method: "POST", URI: "/TraceGraph"}, + "GetTraceSegmentDestination": {Verb: "Get", Resource: "TraceSegmentDestination", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/GetTraceSegmentDestination"}, + "GetTraceSummaries": {Verb: "Get", Resource: "TraceSummary", OutputListKey: "TraceSummaries", OutputItemKey: "", Method: "POST", URI: "/TraceSummaries"}, + "ListResourcePolicies": {Verb: "List", Resource: "ResourcePolicy", OutputListKey: "ResourcePolicies", OutputItemKey: "", Method: "POST", URI: "/ListResourcePolicies"}, + "ListRetrievedTraces": {Verb: "List", Resource: "RetrievedTrace", OutputListKey: "Traces", OutputItemKey: "", Method: "POST", URI: "/ListRetrievedTraces"}, + "ListTagsForResource": {Verb: "List", Resource: "TagsForResource", OutputListKey: "Tags", OutputItemKey: "", Method: "POST", URI: "/ListTagsForResource"}, + "PutEncryptionConfig": {Verb: "Update", Resource: "EncryptionConfig", OutputListKey: "", OutputItemKey: "EncryptionConfig", Method: "POST", URI: "/PutEncryptionConfig"}, + "PutResourcePolicy": {Verb: "Update", Resource: "ResourcePolicy", OutputListKey: "", OutputItemKey: "ResourcePolicy", Method: "POST", URI: "/PutResourcePolicy"}, + "PutTelemetryRecords": {Verb: "Update", Resource: "TelemetryRecord", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/TelemetryRecords"}, + "PutTraceSegments": {Verb: "Update", Resource: "TraceSegment", OutputListKey: "UnprocessedTraceSegments", OutputItemKey: "", Method: "POST", URI: "/TraceSegments"}, + "TagResource": {Verb: "Tag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/TagResource"}, + "UntagResource": {Verb: "Untag", Resource: "Resource", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UntagResource"}, + "UpdateGroup": {Verb: "Update", Resource: "Group", OutputListKey: "", OutputItemKey: "Group", Method: "POST", URI: "/UpdateGroup"}, + "UpdateIndexingRule": {Verb: "Update", Resource: "IndexingRule", OutputListKey: "", OutputItemKey: "IndexingRule", Method: "POST", URI: "/UpdateIndexingRule"}, + "UpdateSamplingRule": {Verb: "Update", Resource: "SamplingRule", OutputListKey: "", OutputItemKey: "SamplingRuleRecord", Method: "POST", URI: "/UpdateSamplingRule"}, + "UpdateTraceSegmentDestination": {Verb: "Update", Resource: "TraceSegmentDestination", OutputListKey: "", OutputItemKey: "", Method: "POST", URI: "/UpdateTraceSegmentDestination"}, + }) } diff --git a/internal/generated/fidelity/manifest_gen.go b/internal/generated/fidelity/manifest_gen.go index 7cfa18cf..c853a686 100644 --- a/internal/generated/fidelity/manifest_gen.go +++ b/internal/generated/fidelity/manifest_gen.go @@ -46,12 +46,22 @@ type Service struct { // service's API. When false the unimplemented tail is not knowable, so the // manifest lists only what DevCloud serves. ModelBacked bool + // EngineWired reports whether the provider hands the operations it does not + // implement to the generic CRUD engine, by returning plugin.ErrUnhandledOp. + // + // It is the difference between an operation being *classifiable* and being + // *reachable*. The CRUD registry is built from the model, so it holds + // entries for services whose hand-written provider refuses unknown + // operations itself and never routes to the engine — for those, a + // registered operation is genuinely unimplemented, and only this field says + // so without guessing. + EngineWired bool Operations map[string]Tier } // Services maps a registered service ID to its operations. var Services = map[string]Service{ - "account": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "account": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "AcceptPrimaryEmailUpdate": TierHandVerified, "DeleteAlternateContact": TierHandVerified, "DeleteContactInformation": TierHandVerified, @@ -68,7 +78,7 @@ var Services = map[string]Service{ "PutContactInformation": TierHandVerified, "StartPrimaryEmailUpdate": TierHandVerified, }}, - "acm": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "acm": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToCertificate": TierHandVerified, "CancelCertificateIssuance": TierHandVerified, "CreatePermission": TierHandVerified, @@ -108,7 +118,7 @@ var Services = map[string]Service{ "UpdateCertificateOptions": TierHandVerified, "WaitForValidation": TierHandVerified, }}, - "acmpca": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "acmpca": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateCertificateAuthority": TierHandVerified, "CreateCertificateAuthorityAuditReport": TierHandVerified, "CreatePermission": TierHandVerified, @@ -133,7 +143,7 @@ var Services = map[string]Service{ "UntagCertificateAuthority": TierHandVerified, "UpdateCertificateAuthority": TierHandVerified, }}, - "amplify": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "amplify": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateApp": TierHandVerified, "CreateBackendEnvironment": TierHandVerified, "CreateBranch": TierHandVerified, @@ -172,7 +182,7 @@ var Services = map[string]Service{ "UpdateDomainAssociation": TierHandVerified, "UpdateWebhook": TierHandVerified, }}, - "apigatewayv2": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "apigatewayv2": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateApi": TierHandVerified, "CreateApiMapping": TierHandVerified, "CreateAuthorizer": TierHandVerified, @@ -277,7 +287,7 @@ var Services = map[string]Service{ "UpdateStage": TierHandVerified, "UpdateVpcLink": TierHandVerified, }}, - "appconfig": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "appconfig": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateApplication": TierHandVerified, "CreateConfigurationProfile": TierHandVerified, "CreateDeploymentStrategy": TierHandVerified, @@ -324,7 +334,7 @@ var Services = map[string]Service{ "UpdateExtensionAssociation": TierHandVerified, "ValidateConfiguration": TierHandVerified, }}, - "applicationautoscaling": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "applicationautoscaling": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchDeleteScalingPolicy": TierHandVerified, "BatchDeleteScheduledAction": TierHandVerified, "BatchDeregisterScalableTarget": TierHandVerified, @@ -366,7 +376,7 @@ var Services = map[string]Service{ "UpdateScalingPolicy": TierHandVerified, "UpdateScheduledAction": TierHandVerified, }}, - "appsync": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "appsync": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateApi": TierHandVerified, "AssociateMergedGraphqlApi": TierHandVerified, "AssociateSourceGraphqlApi": TierHandVerified, @@ -446,7 +456,7 @@ var Services = map[string]Service{ "UpdateSourceApiAssociation": TierHandVerified, "UpdateType": TierHandVerified, }}, - "athena": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "athena": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchGetNamedQuery": TierHandVerified, "BatchGetPreparedStatement": TierHandVerified, "BatchGetQueryExecution": TierHandVerified, @@ -518,7 +528,7 @@ var Services = map[string]Service{ "UpdatePreparedStatement": TierHandVerified, "UpdateWorkGroup": TierHandVerified, }}, - "autoscaling": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "autoscaling": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AttachInstances": TierHandVerified, "AttachLoadBalancerTargetGroups": TierHandVerified, "AttachLoadBalancers": TierHandVerified, @@ -586,7 +596,7 @@ var Services = map[string]Service{ "TerminateInstanceInAutoScalingGroup": TierHandVerified, "UpdateAutoScalingGroup": TierHandVerified, }}, - "backup": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "backup": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateBackupVaultMpaApprovalTeam": TierUnimplemented, "CancelLegalHold": TierUnimplemented, "CreateBackupPlan": TierHandVerified, @@ -696,7 +706,7 @@ var Services = map[string]Service{ "UpdateRestoreTestingSelection": TierHandVerified, "UpdateTieringConfiguration": TierUnimplemented, }}, - "batch": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "batch": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CancelJob": TierHandVerified, "CreateComputeEnvironment": TierHandVerified, "CreateConsumableResource": TierHandVerified, @@ -743,7 +753,7 @@ var Services = map[string]Service{ "UpdateServiceEnvironment": TierHandVerified, "UpdateServiceJob": TierHandVerified, }}, - "bedrock": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrock": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "BatchDeleteEvaluationJob": TierUnimplemented, "CancelAutomatedReasoningPolicyBuildWorkflow": TierUnimplemented, "CreateAutomatedReasoningPolicy": TierUnimplemented, @@ -848,136 +858,136 @@ var Services = map[string]Service{ "UpdateMarketplaceModelEndpoint": TierUnimplemented, "UpdateProvisionedModelThroughput": TierUnimplemented, }}, - "bedrockagent": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrockagent": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateAgentCollaborator": TierUnimplemented, "AssociateAgentKnowledgeBase": TierUnimplemented, - "CreateAgent": TierUnimplemented, - "CreateAgentActionGroup": TierUnimplemented, - "CreateAgentAlias": TierUnimplemented, - "CreateDataSource": TierUnimplemented, - "CreateFlow": TierUnimplemented, - "CreateFlowAlias": TierUnimplemented, - "CreateFlowVersion": TierUnimplemented, - "CreateKnowledgeBase": TierUnimplemented, - "CreatePrompt": TierUnimplemented, - "CreatePromptVersion": TierUnimplemented, - "DeleteAgent": TierUnimplemented, - "DeleteAgentActionGroup": TierUnimplemented, - "DeleteAgentAlias": TierUnimplemented, - "DeleteAgentVersion": TierUnimplemented, - "DeleteDataSource": TierUnimplemented, - "DeleteFlow": TierUnimplemented, - "DeleteFlowAlias": TierUnimplemented, - "DeleteFlowVersion": TierUnimplemented, - "DeleteKnowledgeBase": TierUnimplemented, - "DeleteKnowledgeBaseDocuments": TierUnimplemented, - "DeletePrompt": TierUnimplemented, - "DeleteResourcePolicy": TierUnimplemented, + "CreateAgent": TierAutoCRUD, + "CreateAgentActionGroup": TierAutoCRUD, + "CreateAgentAlias": TierAutoCRUD, + "CreateDataSource": TierAutoCRUD, + "CreateFlow": TierAutoCRUD, + "CreateFlowAlias": TierAutoCRUD, + "CreateFlowVersion": TierAutoCRUD, + "CreateKnowledgeBase": TierAutoCRUD, + "CreatePrompt": TierAutoCRUD, + "CreatePromptVersion": TierAutoCRUD, + "DeleteAgent": TierAutoCRUD, + "DeleteAgentActionGroup": TierAutoCRUD, + "DeleteAgentAlias": TierAutoCRUD, + "DeleteAgentVersion": TierAutoCRUD, + "DeleteDataSource": TierAutoCRUD, + "DeleteFlow": TierAutoCRUD, + "DeleteFlowAlias": TierAutoCRUD, + "DeleteFlowVersion": TierAutoCRUD, + "DeleteKnowledgeBase": TierAutoCRUD, + "DeleteKnowledgeBaseDocuments": TierAutoCRUD, + "DeletePrompt": TierAutoCRUD, + "DeleteResourcePolicy": TierAutoCRUD, "DisassociateAgentCollaborator": TierUnimplemented, "DisassociateAgentKnowledgeBase": TierUnimplemented, - "GetAgent": TierUnimplemented, - "GetAgentActionGroup": TierUnimplemented, - "GetAgentAlias": TierUnimplemented, - "GetAgentCollaborator": TierUnimplemented, - "GetAgentKnowledgeBase": TierUnimplemented, - "GetAgentVersion": TierUnimplemented, - "GetDataSource": TierUnimplemented, - "GetFlow": TierUnimplemented, - "GetFlowAlias": TierUnimplemented, - "GetFlowVersion": TierUnimplemented, - "GetIngestionJob": TierUnimplemented, - "GetKnowledgeBase": TierUnimplemented, - "GetKnowledgeBaseDocuments": TierUnimplemented, - "GetPrompt": TierUnimplemented, - "GetResourcePolicy": TierUnimplemented, + "GetAgent": TierAutoCRUD, + "GetAgentActionGroup": TierAutoCRUD, + "GetAgentAlias": TierAutoCRUD, + "GetAgentCollaborator": TierAutoCRUD, + "GetAgentKnowledgeBase": TierAutoCRUD, + "GetAgentVersion": TierAutoCRUD, + "GetDataSource": TierAutoCRUD, + "GetFlow": TierAutoCRUD, + "GetFlowAlias": TierAutoCRUD, + "GetFlowVersion": TierAutoCRUD, + "GetIngestionJob": TierAutoCRUD, + "GetKnowledgeBase": TierAutoCRUD, + "GetKnowledgeBaseDocuments": TierAutoCRUD, + "GetPrompt": TierAutoCRUD, + "GetResourcePolicy": TierAutoCRUD, "IngestKnowledgeBaseDocuments": TierUnimplemented, - "ListAgentActionGroups": TierUnimplemented, - "ListAgentAliases": TierUnimplemented, - "ListAgentCollaborators": TierUnimplemented, - "ListAgentKnowledgeBases": TierUnimplemented, - "ListAgentVersions": TierUnimplemented, - "ListAgents": TierUnimplemented, - "ListDataSources": TierUnimplemented, - "ListFlowAliases": TierUnimplemented, - "ListFlowVersions": TierUnimplemented, - "ListFlows": TierUnimplemented, - "ListIngestionJobs": TierUnimplemented, - "ListKnowledgeBaseDocuments": TierUnimplemented, - "ListKnowledgeBases": TierUnimplemented, - "ListPrompts": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, + "ListAgentActionGroups": TierAutoCRUD, + "ListAgentAliases": TierAutoCRUD, + "ListAgentCollaborators": TierAutoCRUD, + "ListAgentKnowledgeBases": TierAutoCRUD, + "ListAgentVersions": TierAutoCRUD, + "ListAgents": TierAutoCRUD, + "ListDataSources": TierAutoCRUD, + "ListFlowAliases": TierAutoCRUD, + "ListFlowVersions": TierAutoCRUD, + "ListFlows": TierAutoCRUD, + "ListIngestionJobs": TierAutoCRUD, + "ListKnowledgeBaseDocuments": TierAutoCRUD, + "ListKnowledgeBases": TierAutoCRUD, + "ListPrompts": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, "PrepareAgent": TierUnimplemented, "PrepareFlow": TierUnimplemented, - "PutResourcePolicy": TierUnimplemented, + "PutResourcePolicy": TierAutoCRUD, "StartIngestionJob": TierUnimplemented, "StopIngestionJob": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateAgent": TierUnimplemented, - "UpdateAgentActionGroup": TierUnimplemented, - "UpdateAgentAlias": TierUnimplemented, - "UpdateAgentCollaborator": TierUnimplemented, - "UpdateAgentKnowledgeBase": TierUnimplemented, - "UpdateDataSource": TierUnimplemented, - "UpdateFlow": TierUnimplemented, - "UpdateFlowAlias": TierUnimplemented, - "UpdateKnowledgeBase": TierUnimplemented, - "UpdatePrompt": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateAgent": TierAutoCRUD, + "UpdateAgentActionGroup": TierAutoCRUD, + "UpdateAgentAlias": TierAutoCRUD, + "UpdateAgentCollaborator": TierAutoCRUD, + "UpdateAgentKnowledgeBase": TierAutoCRUD, + "UpdateDataSource": TierAutoCRUD, + "UpdateFlow": TierAutoCRUD, + "UpdateFlowAlias": TierAutoCRUD, + "UpdateKnowledgeBase": TierAutoCRUD, + "UpdatePrompt": TierAutoCRUD, "ValidateFlowDefinition": TierUnimplemented, }}, - "bedrockagentcore": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrockagentcore": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchCreateMemoryRecords": TierUnimplemented, "BatchDeleteMemoryRecords": TierUnimplemented, "BatchUpdateMemoryRecords": TierUnimplemented, "CompleteResourceTokenAuth": TierUnimplemented, - "CreateABTest": TierUnimplemented, - "CreateEvent": TierUnimplemented, - "CreatePaymentInstrument": TierUnimplemented, - "CreatePaymentSession": TierUnimplemented, - "DeleteABTest": TierUnimplemented, - "DeleteBatchEvaluation": TierUnimplemented, - "DeleteCapacityProviderSession": TierUnimplemented, - "DeleteEvent": TierUnimplemented, - "DeleteMemoryRecord": TierUnimplemented, - "DeletePaymentInstrument": TierUnimplemented, - "DeletePaymentSession": TierUnimplemented, - "DeleteRecommendation": TierUnimplemented, + "CreateABTest": TierAutoCRUD, + "CreateEvent": TierAutoCRUD, + "CreatePaymentInstrument": TierAutoCRUD, + "CreatePaymentSession": TierAutoCRUD, + "DeleteABTest": TierAutoCRUD, + "DeleteBatchEvaluation": TierAutoCRUD, + "DeleteCapacityProviderSession": TierAutoCRUD, + "DeleteEvent": TierAutoCRUD, + "DeleteMemoryRecord": TierAutoCRUD, + "DeletePaymentInstrument": TierAutoCRUD, + "DeletePaymentSession": TierAutoCRUD, + "DeleteRecommendation": TierAutoCRUD, "Evaluate": TierUnimplemented, - "GetABTest": TierUnimplemented, - "GetAgentCard": TierUnimplemented, - "GetBatchEvaluation": TierUnimplemented, - "GetBrowserSession": TierUnimplemented, - "GetCodeInterpreterSession": TierUnimplemented, - "GetEvent": TierUnimplemented, - "GetMemoryRecord": TierUnimplemented, - "GetPaymentInstrument": TierUnimplemented, - "GetPaymentInstrumentBalance": TierUnimplemented, - "GetPaymentSession": TierUnimplemented, - "GetRecommendation": TierUnimplemented, - "GetResourceApiKey": TierUnimplemented, - "GetResourceOauth2Token": TierUnimplemented, - "GetResourcePaymentToken": TierUnimplemented, - "GetWorkloadAccessToken": TierUnimplemented, - "GetWorkloadAccessTokenForJWT": TierUnimplemented, - "GetWorkloadAccessTokenForUserId": TierUnimplemented, + "GetABTest": TierAutoCRUD, + "GetAgentCard": TierAutoCRUD, + "GetBatchEvaluation": TierAutoCRUD, + "GetBrowserSession": TierAutoCRUD, + "GetCodeInterpreterSession": TierAutoCRUD, + "GetEvent": TierAutoCRUD, + "GetMemoryRecord": TierAutoCRUD, + "GetPaymentInstrument": TierAutoCRUD, + "GetPaymentInstrumentBalance": TierAutoCRUD, + "GetPaymentSession": TierAutoCRUD, + "GetRecommendation": TierAutoCRUD, + "GetResourceApiKey": TierAutoCRUD, + "GetResourceOauth2Token": TierAutoCRUD, + "GetResourcePaymentToken": TierAutoCRUD, + "GetWorkloadAccessToken": TierAutoCRUD, + "GetWorkloadAccessTokenForJWT": TierAutoCRUD, + "GetWorkloadAccessTokenForUserId": TierAutoCRUD, "IngestData": TierUnimplemented, "InvokeAgentRuntime": TierUnimplemented, "InvokeAgentRuntimeCommand": TierUnimplemented, "InvokeBrowser": TierUnimplemented, "InvokeCodeInterpreter": TierUnimplemented, "InvokeHarness": TierUnimplemented, - "ListABTests": TierUnimplemented, - "ListActors": TierUnimplemented, - "ListBatchEvaluations": TierUnimplemented, - "ListBrowserSessions": TierUnimplemented, - "ListCodeInterpreterSessions": TierUnimplemented, - "ListEvents": TierUnimplemented, - "ListMemoryExtractionJobs": TierUnimplemented, - "ListMemoryRecords": TierUnimplemented, - "ListPaymentInstruments": TierUnimplemented, - "ListPaymentSessions": TierUnimplemented, - "ListRecommendations": TierUnimplemented, - "ListSessions": TierUnimplemented, + "ListABTests": TierAutoCRUD, + "ListActors": TierAutoCRUD, + "ListBatchEvaluations": TierAutoCRUD, + "ListBrowserSessions": TierAutoCRUD, + "ListCodeInterpreterSessions": TierAutoCRUD, + "ListEvents": TierAutoCRUD, + "ListMemoryExtractionJobs": TierAutoCRUD, + "ListMemoryRecords": TierAutoCRUD, + "ListPaymentInstruments": TierAutoCRUD, + "ListPaymentSessions": TierAutoCRUD, + "ListRecommendations": TierAutoCRUD, + "ListSessions": TierAutoCRUD, "ProcessPayment": TierUnimplemented, "RetrieveMemoryRecords": TierUnimplemented, "SaveBrowserSessionProfile": TierUnimplemented, @@ -991,248 +1001,248 @@ var Services = map[string]Service{ "StopBrowserSession": TierUnimplemented, "StopCodeInterpreterSession": TierUnimplemented, "StopRuntimeSession": TierUnimplemented, - "UpdateABTest": TierUnimplemented, - "UpdateBrowserStream": TierUnimplemented, + "UpdateABTest": TierAutoCRUD, + "UpdateBrowserStream": TierAutoCRUD, }}, - "bedrockagentcorecontrol": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrockagentcorecontrol": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddDatasetExamples": TierUnimplemented, "BatchPutGatewayRateLimits": TierUnimplemented, - "CreateAgentRuntime": TierUnimplemented, - "CreateAgentRuntimeEndpoint": TierUnimplemented, - "CreateApiKeyCredentialProvider": TierUnimplemented, - "CreateBrowser": TierUnimplemented, - "CreateBrowserProfile": TierUnimplemented, - "CreateCapacityProvider": TierUnimplemented, - "CreateCodeInterpreter": TierUnimplemented, - "CreateConfigurationBundle": TierUnimplemented, - "CreateConsentPortal": TierUnimplemented, - "CreateDataset": TierUnimplemented, - "CreateDatasetVersion": TierUnimplemented, - "CreateEvaluator": TierUnimplemented, - "CreateGateway": TierUnimplemented, - "CreateGatewayRateLimit": TierUnimplemented, - "CreateGatewayRule": TierUnimplemented, - "CreateGatewayTarget": TierUnimplemented, - "CreateHarness": TierUnimplemented, - "CreateHarnessEndpoint": TierUnimplemented, - "CreateMemory": TierUnimplemented, - "CreateOauth2CredentialProvider": TierUnimplemented, - "CreateOnlineEvaluationConfig": TierUnimplemented, - "CreatePaymentConnector": TierUnimplemented, - "CreatePaymentCredentialProvider": TierUnimplemented, - "CreatePaymentManager": TierUnimplemented, - "CreatePolicy": TierUnimplemented, - "CreatePolicyEngine": TierUnimplemented, - "CreateRegistry": TierUnimplemented, - "CreateRegistryRecord": TierUnimplemented, - "CreateWorkloadIdentity": TierUnimplemented, - "DeleteAgentRuntime": TierUnimplemented, - "DeleteAgentRuntimeEndpoint": TierUnimplemented, - "DeleteApiKeyCredentialProvider": TierUnimplemented, - "DeleteBrowser": TierUnimplemented, - "DeleteBrowserProfile": TierUnimplemented, - "DeleteCapacityProvider": TierUnimplemented, - "DeleteCodeInterpreter": TierUnimplemented, - "DeleteConfigurationBundle": TierUnimplemented, - "DeleteConsentPortal": TierUnimplemented, - "DeleteDataset": TierUnimplemented, - "DeleteDatasetExamples": TierUnimplemented, - "DeleteEvaluator": TierUnimplemented, - "DeleteGateway": TierUnimplemented, - "DeleteGatewayRateLimit": TierUnimplemented, - "DeleteGatewayRule": TierUnimplemented, - "DeleteGatewayTarget": TierUnimplemented, - "DeleteHarness": TierUnimplemented, - "DeleteHarnessEndpoint": TierUnimplemented, - "DeleteMemory": TierUnimplemented, - "DeleteOauth2CredentialProvider": TierUnimplemented, - "DeleteOnlineEvaluationConfig": TierUnimplemented, - "DeletePaymentConnector": TierUnimplemented, - "DeletePaymentCredentialProvider": TierUnimplemented, - "DeletePaymentManager": TierUnimplemented, - "DeletePolicy": TierUnimplemented, - "DeletePolicyEngine": TierUnimplemented, - "DeleteRegistry": TierUnimplemented, - "DeleteRegistryRecord": TierUnimplemented, - "DeleteResourcePolicy": TierUnimplemented, - "DeleteWorkloadIdentity": TierUnimplemented, - "GetAgentRuntime": TierUnimplemented, - "GetAgentRuntimeEndpoint": TierUnimplemented, - "GetApiKeyCredentialProvider": TierUnimplemented, - "GetBrowser": TierUnimplemented, - "GetBrowserProfile": TierUnimplemented, - "GetCapacityProvider": TierUnimplemented, - "GetCodeInterpreter": TierUnimplemented, - "GetConfigurationBundle": TierUnimplemented, - "GetConfigurationBundleVersion": TierUnimplemented, - "GetConsentPortal": TierUnimplemented, - "GetDataset": TierUnimplemented, - "GetEvaluator": TierUnimplemented, - "GetGateway": TierUnimplemented, - "GetGatewayRateLimit": TierUnimplemented, - "GetGatewayRule": TierUnimplemented, - "GetGatewayTarget": TierUnimplemented, - "GetHarness": TierUnimplemented, - "GetHarnessEndpoint": TierUnimplemented, - "GetMemory": TierUnimplemented, - "GetOauth2CredentialProvider": TierUnimplemented, - "GetOnlineEvaluationConfig": TierUnimplemented, - "GetPaymentConnector": TierUnimplemented, - "GetPaymentCredentialProvider": TierUnimplemented, - "GetPaymentManager": TierUnimplemented, - "GetPolicy": TierUnimplemented, - "GetPolicyEngine": TierUnimplemented, - "GetPolicyEngineSummary": TierUnimplemented, - "GetPolicyGeneration": TierUnimplemented, - "GetPolicyGenerationSummary": TierUnimplemented, - "GetPolicySummary": TierUnimplemented, - "GetRegistry": TierUnimplemented, - "GetRegistryRecord": TierUnimplemented, - "GetResourcePolicy": TierUnimplemented, - "GetTokenVault": TierUnimplemented, - "GetWorkloadIdentity": TierUnimplemented, - "ListAgentRuntimeEndpoints": TierUnimplemented, - "ListAgentRuntimeVersions": TierUnimplemented, - "ListAgentRuntimeVersionsByCapacityProvider": TierUnimplemented, - "ListAgentRuntimes": TierUnimplemented, - "ListApiKeyCredentialProviders": TierUnimplemented, - "ListBrowserProfiles": TierUnimplemented, - "ListBrowsers": TierUnimplemented, - "ListCapacityProviders": TierUnimplemented, - "ListCodeInterpreters": TierUnimplemented, - "ListConfigurationBundleVersions": TierUnimplemented, - "ListConfigurationBundles": TierUnimplemented, - "ListConsentPortals": TierUnimplemented, - "ListDatasetExamples": TierUnimplemented, - "ListDatasetVersions": TierUnimplemented, - "ListDatasets": TierUnimplemented, - "ListEvaluators": TierUnimplemented, - "ListGatewayRateLimits": TierUnimplemented, - "ListGatewayRules": TierUnimplemented, - "ListGatewayTargets": TierUnimplemented, - "ListGateways": TierUnimplemented, - "ListHarnessEndpoints": TierUnimplemented, - "ListHarnessVersions": TierUnimplemented, - "ListHarnesses": TierUnimplemented, - "ListMemories": TierUnimplemented, - "ListOauth2CredentialProviders": TierUnimplemented, - "ListOnlineEvaluationConfigs": TierUnimplemented, - "ListPaymentConnectors": TierUnimplemented, - "ListPaymentCredentialProviders": TierUnimplemented, - "ListPaymentManagers": TierUnimplemented, - "ListPolicies": TierUnimplemented, - "ListPolicyEngineSummaries": TierUnimplemented, - "ListPolicyEngines": TierUnimplemented, - "ListPolicyGenerationAssets": TierUnimplemented, - "ListPolicyGenerationSummaries": TierUnimplemented, - "ListPolicyGenerations": TierUnimplemented, - "ListPolicySummaries": TierUnimplemented, - "ListRegistries": TierUnimplemented, - "ListRegistryRecords": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "ListWorkloadIdentities": TierUnimplemented, - "PutResourcePolicy": TierUnimplemented, + "CreateAgentRuntime": TierAutoCRUD, + "CreateAgentRuntimeEndpoint": TierAutoCRUD, + "CreateApiKeyCredentialProvider": TierAutoCRUD, + "CreateBrowser": TierAutoCRUD, + "CreateBrowserProfile": TierAutoCRUD, + "CreateCapacityProvider": TierAutoCRUD, + "CreateCodeInterpreter": TierAutoCRUD, + "CreateConfigurationBundle": TierAutoCRUD, + "CreateConsentPortal": TierAutoCRUD, + "CreateDataset": TierAutoCRUD, + "CreateDatasetVersion": TierAutoCRUD, + "CreateEvaluator": TierAutoCRUD, + "CreateGateway": TierAutoCRUD, + "CreateGatewayRateLimit": TierAutoCRUD, + "CreateGatewayRule": TierAutoCRUD, + "CreateGatewayTarget": TierAutoCRUD, + "CreateHarness": TierAutoCRUD, + "CreateHarnessEndpoint": TierAutoCRUD, + "CreateMemory": TierAutoCRUD, + "CreateOauth2CredentialProvider": TierAutoCRUD, + "CreateOnlineEvaluationConfig": TierAutoCRUD, + "CreatePaymentConnector": TierAutoCRUD, + "CreatePaymentCredentialProvider": TierAutoCRUD, + "CreatePaymentManager": TierAutoCRUD, + "CreatePolicy": TierAutoCRUD, + "CreatePolicyEngine": TierAutoCRUD, + "CreateRegistry": TierAutoCRUD, + "CreateRegistryRecord": TierAutoCRUD, + "CreateWorkloadIdentity": TierAutoCRUD, + "DeleteAgentRuntime": TierAutoCRUD, + "DeleteAgentRuntimeEndpoint": TierAutoCRUD, + "DeleteApiKeyCredentialProvider": TierAutoCRUD, + "DeleteBrowser": TierAutoCRUD, + "DeleteBrowserProfile": TierAutoCRUD, + "DeleteCapacityProvider": TierAutoCRUD, + "DeleteCodeInterpreter": TierAutoCRUD, + "DeleteConfigurationBundle": TierAutoCRUD, + "DeleteConsentPortal": TierAutoCRUD, + "DeleteDataset": TierAutoCRUD, + "DeleteDatasetExamples": TierAutoCRUD, + "DeleteEvaluator": TierAutoCRUD, + "DeleteGateway": TierAutoCRUD, + "DeleteGatewayRateLimit": TierAutoCRUD, + "DeleteGatewayRule": TierAutoCRUD, + "DeleteGatewayTarget": TierAutoCRUD, + "DeleteHarness": TierAutoCRUD, + "DeleteHarnessEndpoint": TierAutoCRUD, + "DeleteMemory": TierAutoCRUD, + "DeleteOauth2CredentialProvider": TierAutoCRUD, + "DeleteOnlineEvaluationConfig": TierAutoCRUD, + "DeletePaymentConnector": TierAutoCRUD, + "DeletePaymentCredentialProvider": TierAutoCRUD, + "DeletePaymentManager": TierAutoCRUD, + "DeletePolicy": TierAutoCRUD, + "DeletePolicyEngine": TierAutoCRUD, + "DeleteRegistry": TierAutoCRUD, + "DeleteRegistryRecord": TierAutoCRUD, + "DeleteResourcePolicy": TierAutoCRUD, + "DeleteWorkloadIdentity": TierAutoCRUD, + "GetAgentRuntime": TierAutoCRUD, + "GetAgentRuntimeEndpoint": TierAutoCRUD, + "GetApiKeyCredentialProvider": TierAutoCRUD, + "GetBrowser": TierAutoCRUD, + "GetBrowserProfile": TierAutoCRUD, + "GetCapacityProvider": TierAutoCRUD, + "GetCodeInterpreter": TierAutoCRUD, + "GetConfigurationBundle": TierAutoCRUD, + "GetConfigurationBundleVersion": TierAutoCRUD, + "GetConsentPortal": TierAutoCRUD, + "GetDataset": TierAutoCRUD, + "GetEvaluator": TierAutoCRUD, + "GetGateway": TierAutoCRUD, + "GetGatewayRateLimit": TierAutoCRUD, + "GetGatewayRule": TierAutoCRUD, + "GetGatewayTarget": TierAutoCRUD, + "GetHarness": TierAutoCRUD, + "GetHarnessEndpoint": TierAutoCRUD, + "GetMemory": TierAutoCRUD, + "GetOauth2CredentialProvider": TierAutoCRUD, + "GetOnlineEvaluationConfig": TierAutoCRUD, + "GetPaymentConnector": TierAutoCRUD, + "GetPaymentCredentialProvider": TierAutoCRUD, + "GetPaymentManager": TierAutoCRUD, + "GetPolicy": TierAutoCRUD, + "GetPolicyEngine": TierAutoCRUD, + "GetPolicyEngineSummary": TierAutoCRUD, + "GetPolicyGeneration": TierAutoCRUD, + "GetPolicyGenerationSummary": TierAutoCRUD, + "GetPolicySummary": TierAutoCRUD, + "GetRegistry": TierAutoCRUD, + "GetRegistryRecord": TierAutoCRUD, + "GetResourcePolicy": TierAutoCRUD, + "GetTokenVault": TierAutoCRUD, + "GetWorkloadIdentity": TierAutoCRUD, + "ListAgentRuntimeEndpoints": TierAutoCRUD, + "ListAgentRuntimeVersions": TierAutoCRUD, + "ListAgentRuntimeVersionsByCapacityProvider": TierAutoCRUD, + "ListAgentRuntimes": TierAutoCRUD, + "ListApiKeyCredentialProviders": TierAutoCRUD, + "ListBrowserProfiles": TierAutoCRUD, + "ListBrowsers": TierAutoCRUD, + "ListCapacityProviders": TierAutoCRUD, + "ListCodeInterpreters": TierAutoCRUD, + "ListConfigurationBundleVersions": TierAutoCRUD, + "ListConfigurationBundles": TierAutoCRUD, + "ListConsentPortals": TierAutoCRUD, + "ListDatasetExamples": TierAutoCRUD, + "ListDatasetVersions": TierAutoCRUD, + "ListDatasets": TierAutoCRUD, + "ListEvaluators": TierAutoCRUD, + "ListGatewayRateLimits": TierAutoCRUD, + "ListGatewayRules": TierAutoCRUD, + "ListGatewayTargets": TierAutoCRUD, + "ListGateways": TierAutoCRUD, + "ListHarnessEndpoints": TierAutoCRUD, + "ListHarnessVersions": TierAutoCRUD, + "ListHarnesses": TierAutoCRUD, + "ListMemories": TierAutoCRUD, + "ListOauth2CredentialProviders": TierAutoCRUD, + "ListOnlineEvaluationConfigs": TierAutoCRUD, + "ListPaymentConnectors": TierAutoCRUD, + "ListPaymentCredentialProviders": TierAutoCRUD, + "ListPaymentManagers": TierAutoCRUD, + "ListPolicies": TierAutoCRUD, + "ListPolicyEngineSummaries": TierAutoCRUD, + "ListPolicyEngines": TierAutoCRUD, + "ListPolicyGenerationAssets": TierAutoCRUD, + "ListPolicyGenerationSummaries": TierAutoCRUD, + "ListPolicyGenerations": TierAutoCRUD, + "ListPolicySummaries": TierAutoCRUD, + "ListRegistries": TierAutoCRUD, + "ListRegistryRecords": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "ListWorkloadIdentities": TierAutoCRUD, + "PutResourcePolicy": TierAutoCRUD, "SetTokenVaultCMK": TierUnimplemented, "StartPolicyGeneration": TierUnimplemented, "SubmitRegistryRecordForApproval": TierUnimplemented, "SynchronizeGatewayTargets": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateAgentRuntime": TierUnimplemented, - "UpdateAgentRuntimeEndpoint": TierUnimplemented, - "UpdateApiKeyCredentialProvider": TierUnimplemented, - "UpdateCapacityProvider": TierUnimplemented, - "UpdateConfigurationBundle": TierUnimplemented, - "UpdateConsentPortal": TierUnimplemented, - "UpdateDataset": TierUnimplemented, - "UpdateDatasetExamples": TierUnimplemented, - "UpdateEvaluator": TierUnimplemented, - "UpdateGateway": TierUnimplemented, - "UpdateGatewayRateLimit": TierUnimplemented, - "UpdateGatewayRule": TierUnimplemented, - "UpdateGatewayTarget": TierUnimplemented, - "UpdateHarness": TierUnimplemented, - "UpdateHarnessEndpoint": TierUnimplemented, - "UpdateMemory": TierUnimplemented, - "UpdateOauth2CredentialProvider": TierUnimplemented, - "UpdateOnlineEvaluationConfig": TierUnimplemented, - "UpdatePaymentConnector": TierUnimplemented, - "UpdatePaymentCredentialProvider": TierUnimplemented, - "UpdatePaymentManager": TierUnimplemented, - "UpdatePolicy": TierUnimplemented, - "UpdatePolicyEngine": TierUnimplemented, - "UpdateRegistry": TierUnimplemented, - "UpdateRegistryRecord": TierUnimplemented, - "UpdateRegistryRecordStatus": TierUnimplemented, - "UpdateWorkloadIdentity": TierUnimplemented, - }}, - "bedrockagentruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateAgentRuntime": TierAutoCRUD, + "UpdateAgentRuntimeEndpoint": TierAutoCRUD, + "UpdateApiKeyCredentialProvider": TierAutoCRUD, + "UpdateCapacityProvider": TierAutoCRUD, + "UpdateConfigurationBundle": TierAutoCRUD, + "UpdateConsentPortal": TierAutoCRUD, + "UpdateDataset": TierAutoCRUD, + "UpdateDatasetExamples": TierAutoCRUD, + "UpdateEvaluator": TierAutoCRUD, + "UpdateGateway": TierAutoCRUD, + "UpdateGatewayRateLimit": TierAutoCRUD, + "UpdateGatewayRule": TierAutoCRUD, + "UpdateGatewayTarget": TierAutoCRUD, + "UpdateHarness": TierAutoCRUD, + "UpdateHarnessEndpoint": TierAutoCRUD, + "UpdateMemory": TierAutoCRUD, + "UpdateOauth2CredentialProvider": TierAutoCRUD, + "UpdateOnlineEvaluationConfig": TierAutoCRUD, + "UpdatePaymentConnector": TierAutoCRUD, + "UpdatePaymentCredentialProvider": TierAutoCRUD, + "UpdatePaymentManager": TierAutoCRUD, + "UpdatePolicy": TierAutoCRUD, + "UpdatePolicyEngine": TierAutoCRUD, + "UpdateRegistry": TierAutoCRUD, + "UpdateRegistryRecord": TierAutoCRUD, + "UpdateRegistryRecordStatus": TierAutoCRUD, + "UpdateWorkloadIdentity": TierAutoCRUD, + }}, + "bedrockagentruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AgenticRetrieveStream": TierUnimplemented, "CheckIngestedDocumentAcl": TierUnimplemented, - "CreateInvocation": TierUnimplemented, - "CreateSession": TierUnimplemented, - "DeleteAgentMemory": TierUnimplemented, - "DeleteSession": TierUnimplemented, + "CreateInvocation": TierAutoCRUD, + "CreateSession": TierAutoCRUD, + "DeleteAgentMemory": TierAutoCRUD, + "DeleteSession": TierAutoCRUD, "EndSession": TierUnimplemented, "GenerateQuery": TierUnimplemented, - "GetAgentMemory": TierUnimplemented, - "GetDocumentContent": TierUnimplemented, - "GetExecutionFlowSnapshot": TierUnimplemented, - "GetFlowExecution": TierUnimplemented, - "GetIngestedDocumentAcl": TierUnimplemented, - "GetInvocationStep": TierUnimplemented, - "GetSession": TierUnimplemented, + "GetAgentMemory": TierAutoCRUD, + "GetDocumentContent": TierAutoCRUD, + "GetExecutionFlowSnapshot": TierAutoCRUD, + "GetFlowExecution": TierAutoCRUD, + "GetIngestedDocumentAcl": TierAutoCRUD, + "GetInvocationStep": TierAutoCRUD, + "GetSession": TierAutoCRUD, "InvokeAgent": TierUnimplemented, "InvokeFlow": TierUnimplemented, "InvokeInlineAgent": TierUnimplemented, - "ListFlowExecutionEvents": TierUnimplemented, - "ListFlowExecutions": TierUnimplemented, - "ListInvocationSteps": TierUnimplemented, - "ListInvocations": TierUnimplemented, - "ListSessions": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, + "ListFlowExecutionEvents": TierAutoCRUD, + "ListFlowExecutions": TierAutoCRUD, + "ListInvocationSteps": TierAutoCRUD, + "ListInvocations": TierAutoCRUD, + "ListSessions": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, "OptimizePrompt": TierUnimplemented, - "PutInvocationStep": TierUnimplemented, + "PutInvocationStep": TierAutoCRUD, "Rerank": TierUnimplemented, "Retrieve": TierUnimplemented, "RetrieveAndGenerate": TierUnimplemented, "RetrieveAndGenerateStream": TierUnimplemented, "StartFlowExecution": TierUnimplemented, "StopFlowExecution": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateSession": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateSession": TierAutoCRUD, }}, - "bedrockdataautomation": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrockdataautomation": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CopyBlueprintStage": TierUnimplemented, - "CreateBlueprint": TierUnimplemented, - "CreateBlueprintVersion": TierUnimplemented, - "CreateDataAutomationLibrary": TierUnimplemented, - "CreateDataAutomationProject": TierUnimplemented, - "DeleteBlueprint": TierUnimplemented, - "DeleteDataAutomationLibrary": TierUnimplemented, - "DeleteDataAutomationProject": TierUnimplemented, - "GetBlueprint": TierUnimplemented, - "GetBlueprintOptimizationStatus": TierUnimplemented, - "GetDataAutomationLibrary": TierUnimplemented, - "GetDataAutomationLibraryEntity": TierUnimplemented, - "GetDataAutomationLibraryIngestionJob": TierUnimplemented, - "GetDataAutomationProject": TierUnimplemented, + "CreateBlueprint": TierAutoCRUD, + "CreateBlueprintVersion": TierAutoCRUD, + "CreateDataAutomationLibrary": TierAutoCRUD, + "CreateDataAutomationProject": TierAutoCRUD, + "DeleteBlueprint": TierAutoCRUD, + "DeleteDataAutomationLibrary": TierAutoCRUD, + "DeleteDataAutomationProject": TierAutoCRUD, + "GetBlueprint": TierAutoCRUD, + "GetBlueprintOptimizationStatus": TierAutoCRUD, + "GetDataAutomationLibrary": TierAutoCRUD, + "GetDataAutomationLibraryEntity": TierAutoCRUD, + "GetDataAutomationLibraryIngestionJob": TierAutoCRUD, + "GetDataAutomationProject": TierAutoCRUD, "InvokeBlueprintOptimizationAsync": TierUnimplemented, "InvokeDataAutomationLibraryIngestionJob": TierUnimplemented, - "ListBlueprints": TierUnimplemented, - "ListDataAutomationLibraries": TierUnimplemented, - "ListDataAutomationLibraryEntities": TierUnimplemented, - "ListDataAutomationLibraryIngestionJobs": TierUnimplemented, - "ListDataAutomationProjects": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateBlueprint": TierUnimplemented, - "UpdateDataAutomationLibrary": TierUnimplemented, - "UpdateDataAutomationProject": TierUnimplemented, - }}, - "bedrockdataautomationruntime": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ListBlueprints": TierAutoCRUD, + "ListDataAutomationLibraries": TierAutoCRUD, + "ListDataAutomationLibraryEntities": TierAutoCRUD, + "ListDataAutomationLibraryIngestionJobs": TierAutoCRUD, + "ListDataAutomationProjects": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateBlueprint": TierAutoCRUD, + "UpdateDataAutomationLibrary": TierAutoCRUD, + "UpdateDataAutomationProject": TierAutoCRUD, + }}, + "bedrockdataautomationruntime": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "GetDataAutomationStatus": TierAutoCRUD, "InvokeDataAutomation": TierUnimplemented, "InvokeDataAutomationAsync": TierUnimplemented, @@ -1240,20 +1250,20 @@ var Services = map[string]Service{ "TagResource": TierAutoCRUD, "UntagResource": TierAutoCRUD, }}, - "bedrockruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "bedrockruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "ApplyGuardrail": TierUnimplemented, "Converse": TierUnimplemented, "ConverseStream": TierUnimplemented, "CountTokens": TierUnimplemented, - "GetAsyncInvoke": TierUnimplemented, + "GetAsyncInvoke": TierAutoCRUD, "InvokeGuardrailChecks": TierUnimplemented, "InvokeModel": TierUnimplemented, "InvokeModelWithBidirectionalStream": TierUnimplemented, "InvokeModelWithResponseStream": TierUnimplemented, - "ListAsyncInvokes": TierUnimplemented, + "ListAsyncInvokes": TierAutoCRUD, "StartAsyncInvoke": TierUnimplemented, }}, - "cloudcontrol": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "cloudcontrol": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "BatchGetResources": TierHandVerified, "CancelResourceRequest": TierHandVerified, "CloneResource": TierHandVerified, @@ -1281,7 +1291,7 @@ var Services = map[string]Service{ "ValidateResource": TierHandVerified, "WaitForResource": TierHandVerified, }}, - "cloudformation": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "cloudformation": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "ActivateOrganizationsAccess": TierUnimplemented, "ActivateType": TierHandVerified, "BatchDescribeTypeConfigurations": TierHandVerified, @@ -1373,7 +1383,7 @@ var Services = map[string]Service{ "UpdateTerminationProtection": TierHandVerified, "ValidateTemplate": TierHandVerified, }}, - "cloudfront": {Protocol: "rest-xml", ModelBacked: true, Operations: map[string]Tier{ + "cloudfront": {Protocol: "rest-xml", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateAlias": TierUnimplemented, "AssociateDistributionTenantWebACL": TierUnimplemented, "AssociateDistributionWebACL": TierUnimplemented, @@ -1542,7 +1552,7 @@ var Services = map[string]Service{ "UpdateVpcOrigin": TierUnimplemented, "VerifyDnsConfiguration": TierUnimplemented, }}, - "cloudsearch": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "cloudsearch": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "BuildSuggesters": TierHandVerified, "CreateDomain": TierHandVerified, "DefineAnalysisScheme": TierHandVerified, @@ -1570,7 +1580,7 @@ var Services = map[string]Service{ "UpdateScalingParameters": TierHandVerified, "UpdateServiceAccessPolicies": TierHandVerified, }}, - "cloudtrail": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "cloudtrail": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTags": TierHandVerified, "CancelQuery": TierHandVerified, "CreateChannel": TierHandVerified, @@ -1632,7 +1642,7 @@ var Services = map[string]Service{ "UpdateEventDataStore": TierHandVerified, "UpdateTrail": TierHandVerified, }}, - "cloudwatch": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "cloudwatch": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "DeleteAlarmMuteRule": TierAutoCRUD, "DeleteAlarms": TierHandVerified, "DeleteAnomalyDetector": TierHandVerified, @@ -1680,7 +1690,7 @@ var Services = map[string]Service{ "TagResource": TierHandVerified, "UntagResource": TierHandVerified, }}, - "cloudwatchlogs": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "cloudwatchlogs": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateKmsKey": TierUnimplemented, "AssociateSourceToS3TableIntegration": TierUnimplemented, "CancelExportTask": TierUnimplemented, @@ -1795,7 +1805,7 @@ var Services = map[string]Service{ "UpdateLookupTable": TierAutoCRUD, "UpdateScheduledQuery": TierAutoCRUD, }}, - "codeartifact": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "codeartifact": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateExternalConnection": TierHandVerified, "CopyPackageVersions": TierHandVerified, "CreateDomain": TierHandVerified, @@ -1845,7 +1855,7 @@ var Services = map[string]Service{ "UpdatePackageVersionsStatus": TierHandVerified, "UpdateRepository": TierHandVerified, }}, - "codebuild": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "codebuild": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchDeleteBuilds": TierHandVerified, "BatchGetBuildBatches": TierAutoCRUD, "BatchGetBuilds": TierHandVerified, @@ -1909,7 +1919,7 @@ var Services = map[string]Service{ "UpdateReportGroup": TierHandVerified, "UpdateWebhook": TierAutoCRUD, }}, - "codecommit": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "codecommit": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateApprovalRuleTemplateWithRepository": TierHandVerified, "BatchAssociateApprovalRuleTemplateWithRepositories": TierHandVerified, "BatchDescribeMergeConflicts": TierHandVerified, @@ -1990,7 +2000,7 @@ var Services = map[string]Service{ "UpdateRepositoryEncryptionKey": TierHandVerified, "UpdateRepositoryName": TierHandVerified, }}, - "codeconnections": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "codeconnections": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "CreateConnection": TierHandVerified, "CreateHost": TierHandVerified, "CreateRepositoryLink": TierHandVerified, @@ -2027,7 +2037,7 @@ var Services = map[string]Service{ "UpdateSyncBlocker": TierHandVerified, "UpdateSyncConfiguration": TierHandVerified, }}, - "codedeploy": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "codedeploy": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToOnPremisesInstances": TierUnimplemented, "BatchGetApplicationRevisions": TierAutoCRUD, "BatchGetApplications": TierHandVerified, @@ -2076,63 +2086,63 @@ var Services = map[string]Service{ "UpdateApplication": TierHandVerified, "UpdateDeploymentGroup": TierHandVerified, }}, - "codeguruprofiler": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "codeguruprofiler": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddNotificationChannels": TierUnimplemented, - "BatchGetFrameMetricData": TierUnimplemented, + "BatchGetFrameMetricData": TierAutoCRUD, "ConfigureAgent": TierUnimplemented, - "CreateProfilingGroup": TierUnimplemented, - "DeleteProfilingGroup": TierUnimplemented, - "DescribeProfilingGroup": TierUnimplemented, - "GetFindingsReportAccountSummary": TierUnimplemented, - "GetNotificationConfiguration": TierUnimplemented, - "GetPolicy": TierUnimplemented, - "GetProfile": TierUnimplemented, - "GetRecommendations": TierUnimplemented, - "ListFindingsReports": TierUnimplemented, - "ListProfileTimes": TierUnimplemented, - "ListProfilingGroups": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, + "CreateProfilingGroup": TierAutoCRUD, + "DeleteProfilingGroup": TierAutoCRUD, + "DescribeProfilingGroup": TierAutoCRUD, + "GetFindingsReportAccountSummary": TierAutoCRUD, + "GetNotificationConfiguration": TierAutoCRUD, + "GetPolicy": TierAutoCRUD, + "GetProfile": TierAutoCRUD, + "GetRecommendations": TierAutoCRUD, + "ListFindingsReports": TierAutoCRUD, + "ListProfileTimes": TierAutoCRUD, + "ListProfilingGroups": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, "PostAgentProfile": TierUnimplemented, - "PutPermission": TierUnimplemented, + "PutPermission": TierAutoCRUD, "RemoveNotificationChannel": TierUnimplemented, "RemovePermission": TierUnimplemented, "SubmitFeedback": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateProfilingGroup": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateProfilingGroup": TierAutoCRUD, }}, - "codegurureviewer": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "codegurureviewer": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateRepository": TierUnimplemented, - "CreateCodeReview": TierUnimplemented, - "DescribeCodeReview": TierUnimplemented, - "DescribeRecommendationFeedback": TierUnimplemented, - "DescribeRepositoryAssociation": TierUnimplemented, + "CreateCodeReview": TierAutoCRUD, + "DescribeCodeReview": TierAutoCRUD, + "DescribeRecommendationFeedback": TierAutoCRUD, + "DescribeRepositoryAssociation": TierAutoCRUD, "DisassociateRepository": TierUnimplemented, - "ListCodeReviews": TierUnimplemented, - "ListRecommendationFeedback": TierUnimplemented, - "ListRecommendations": TierUnimplemented, - "ListRepositoryAssociations": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "PutRecommendationFeedback": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - }}, - "codegurusecurity": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "BatchGetFindings": TierUnimplemented, - "CreateScan": TierUnimplemented, - "CreateUploadUrl": TierUnimplemented, - "GetAccountConfiguration": TierUnimplemented, - "GetFindings": TierUnimplemented, - "GetMetricsSummary": TierUnimplemented, - "GetScan": TierUnimplemented, - "ListFindingsMetrics": TierUnimplemented, - "ListScans": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateAccountConfiguration": TierUnimplemented, - }}, - "codepipeline": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ListCodeReviews": TierAutoCRUD, + "ListRecommendationFeedback": TierAutoCRUD, + "ListRecommendations": TierAutoCRUD, + "ListRepositoryAssociations": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "PutRecommendationFeedback": TierAutoCRUD, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + }}, + "codegurusecurity": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "BatchGetFindings": TierAutoCRUD, + "CreateScan": TierAutoCRUD, + "CreateUploadUrl": TierAutoCRUD, + "GetAccountConfiguration": TierAutoCRUD, + "GetFindings": TierAutoCRUD, + "GetMetricsSummary": TierAutoCRUD, + "GetScan": TierAutoCRUD, + "ListFindingsMetrics": TierAutoCRUD, + "ListScans": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateAccountConfiguration": TierAutoCRUD, + }}, + "codepipeline": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AcknowledgeJob": TierHandVerified, "AcknowledgeThirdPartyJob": TierHandVerified, "CreateCustomActionType": TierHandVerified, @@ -2181,7 +2191,7 @@ var Services = map[string]Service{ "UpdatePipeline": TierHandVerified, "UpdatePipelineSettings": TierHandVerified, }}, - "cognitoidentity": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "cognitoidentity": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateIdentityPool": TierHandVerified, "DeleteIdentities": TierHandVerified, "DeleteIdentityPool": TierHandVerified, @@ -2206,7 +2216,7 @@ var Services = map[string]Service{ "UntagResource": TierHandVerified, "UpdateIdentityPool": TierHandVerified, }}, - "cognitoidentityprovider": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "cognitoidentityprovider": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddCustomAttributes": TierUnimplemented, "AddUserPoolClientSecret": TierUnimplemented, "AdminAddUserToGroup": TierHandVerified, @@ -2330,7 +2340,7 @@ var Services = map[string]Service{ "VerifySoftwareToken": TierUnimplemented, "VerifyUserAttribute": TierUnimplemented, }}, - "comprehend": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "comprehend": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchDetectDominantLanguage": TierUnimplemented, "BatchDetectEntities": TierUnimplemented, "BatchDetectKeyPhrases": TierUnimplemented, @@ -2417,7 +2427,7 @@ var Services = map[string]Service{ "UpdateEndpoint": TierAutoCRUD, "UpdateFlywheel": TierAutoCRUD, }}, - "comprehendmedical": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "comprehendmedical": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "DescribeEntitiesDetectionV2Job": TierAutoCRUD, "DescribeICD10CMInferenceJob": TierAutoCRUD, "DescribePHIDetectionJob": TierAutoCRUD, @@ -2445,7 +2455,7 @@ var Services = map[string]Service{ "StopRxNormInferenceJob": TierUnimplemented, "StopSNOMEDCTInferenceJob": TierUnimplemented, }}, - "configservice": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "configservice": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateResourceTypes": TierUnimplemented, "BatchGetAggregateResourceConfig": TierAutoCRUD, "BatchGetResourceConfig": TierAutoCRUD, @@ -2544,7 +2554,7 @@ var Services = map[string]Service{ "TagResource": TierHandVerified, "UntagResource": TierHandVerified, }}, - "costexplorer": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "costexplorer": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateAnomalyMonitor": TierHandVerified, "CreateAnomalySubscription": TierHandVerified, "CreateCostCategoryDefinition": TierHandVerified, @@ -2593,40 +2603,40 @@ var Services = map[string]Service{ "UpdateCostAllocationTagsStatus": TierHandVerified, "UpdateCostCategoryDefinition": TierHandVerified, }}, - "devopsguru": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "devopsguru": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddNotificationChannel": TierUnimplemented, - "DeleteInsight": TierUnimplemented, - "DescribeAccountHealth": TierUnimplemented, - "DescribeAccountOverview": TierUnimplemented, - "DescribeAnomaly": TierUnimplemented, - "DescribeEventSourcesConfig": TierUnimplemented, - "DescribeFeedback": TierUnimplemented, - "DescribeInsight": TierUnimplemented, - "DescribeOrganizationHealth": TierUnimplemented, - "DescribeOrganizationOverview": TierUnimplemented, - "DescribeOrganizationResourceCollectionHealth": TierUnimplemented, - "DescribeResourceCollectionHealth": TierUnimplemented, - "DescribeServiceIntegration": TierUnimplemented, - "GetCostEstimation": TierUnimplemented, - "GetResourceCollection": TierUnimplemented, - "ListAnomaliesForInsight": TierUnimplemented, - "ListAnomalousLogGroups": TierUnimplemented, - "ListEvents": TierUnimplemented, - "ListInsights": TierUnimplemented, - "ListMonitoredResources": TierUnimplemented, - "ListNotificationChannels": TierUnimplemented, - "ListOrganizationInsights": TierUnimplemented, - "ListRecommendations": TierUnimplemented, - "PutFeedback": TierUnimplemented, + "DeleteInsight": TierAutoCRUD, + "DescribeAccountHealth": TierAutoCRUD, + "DescribeAccountOverview": TierAutoCRUD, + "DescribeAnomaly": TierAutoCRUD, + "DescribeEventSourcesConfig": TierAutoCRUD, + "DescribeFeedback": TierAutoCRUD, + "DescribeInsight": TierAutoCRUD, + "DescribeOrganizationHealth": TierAutoCRUD, + "DescribeOrganizationOverview": TierAutoCRUD, + "DescribeOrganizationResourceCollectionHealth": TierAutoCRUD, + "DescribeResourceCollectionHealth": TierAutoCRUD, + "DescribeServiceIntegration": TierAutoCRUD, + "GetCostEstimation": TierAutoCRUD, + "GetResourceCollection": TierAutoCRUD, + "ListAnomaliesForInsight": TierAutoCRUD, + "ListAnomalousLogGroups": TierAutoCRUD, + "ListEvents": TierAutoCRUD, + "ListInsights": TierAutoCRUD, + "ListMonitoredResources": TierAutoCRUD, + "ListNotificationChannels": TierAutoCRUD, + "ListOrganizationInsights": TierAutoCRUD, + "ListRecommendations": TierAutoCRUD, + "PutFeedback": TierAutoCRUD, "RemoveNotificationChannel": TierUnimplemented, "SearchInsights": TierUnimplemented, "SearchOrganizationInsights": TierUnimplemented, "StartCostEstimation": TierUnimplemented, - "UpdateEventSourcesConfig": TierUnimplemented, - "UpdateResourceCollection": TierUnimplemented, - "UpdateServiceIntegration": TierUnimplemented, + "UpdateEventSourcesConfig": TierAutoCRUD, + "UpdateResourceCollection": TierAutoCRUD, + "UpdateServiceIntegration": TierAutoCRUD, }}, - "dms": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "dms": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "AddTagsToResource": TierHandVerified, "CreateEndpoint": TierHandVerified, "CreateEventSubscription": TierHandVerified, @@ -2661,7 +2671,7 @@ var Services = map[string]Service{ "StopReplicationTask": TierHandVerified, "TestConnection": TierHandVerified, }}, - "docdb": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "docdb": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddSourceIdentifierToSubscription": TierHandVerified, "AddTagsToResource": TierHandVerified, "ApplyPendingMaintenanceAction": TierHandVerified, @@ -2718,7 +2728,7 @@ var Services = map[string]Service{ "StopDBCluster": TierHandVerified, "SwitchoverGlobalCluster": TierHandVerified, }}, - "dynamodb": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "dynamodb": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchExecuteStatement": TierUnimplemented, "BatchGetItem": TierHandVerified, "BatchWriteItem": TierHandVerified, @@ -2777,7 +2787,7 @@ var Services = map[string]Service{ "UpdateTableReplicaAutoScaling": TierAutoCRUD, "UpdateTimeToLive": TierHandVerified, }}, - "dynamodbstreams": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "dynamodbstreams": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToStream": TierHandVerified, "DescribeContinuousBackups": TierHandVerified, "DescribeLimits": TierHandVerified, @@ -2801,7 +2811,7 @@ var Services = map[string]Service{ "SplitShard": TierHandVerified, "UpdateStream": TierHandVerified, }}, - "ebs": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "ebs": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CompleteSnapshot": TierHandVerified, "CopySnapshot": TierHandVerified, "DescribeVolumesModifications": TierHandVerified, @@ -2815,7 +2825,7 @@ var Services = map[string]Service{ "RestoreSnapshotTier": TierHandVerified, "StartSnapshot": TierHandVerified, }}, - "ec2": {Protocol: "", ModelBacked: true, Operations: map[string]Tier{ + "ec2": {Protocol: "", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptAddressTransfer": TierUnimplemented, "AcceptCapacityReservationBillingOwnership": TierUnimplemented, "AcceptReservedInstancesExchangeQuote": TierUnimplemented, @@ -3573,7 +3583,7 @@ var Services = map[string]Service{ "UpdateSecurityGroupRuleDescriptionsIngress": TierUnimplemented, "WithdrawByoipCidr": TierUnimplemented, }}, - "ecr": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ecr": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchCheckLayerAvailability": TierHandVerified, "BatchDeleteImage": TierHandVerified, "BatchGetImage": TierHandVerified, @@ -3633,7 +3643,7 @@ var Services = map[string]Service{ "UploadLayerPart": TierHandVerified, "ValidatePullThroughCacheRule": TierUnimplemented, }}, - "ecs": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ecs": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateCapacityProvider": TierHandVerified, "CreateCluster": TierHandVerified, "CreateDaemon": TierAutoCRUD, @@ -3717,7 +3727,7 @@ var Services = map[string]Service{ "UpdateTaskProtection": TierHandVerified, "UpdateTaskSet": TierHandVerified, }}, - "efs": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "efs": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateAccessPoint": TierHandVerified, "CreateFileSystem": TierHandVerified, "CreateMountTarget": TierHandVerified, @@ -3750,7 +3760,7 @@ var Services = map[string]Service{ "UpdateFileSystem": TierHandVerified, "UpdateFileSystemProtection": TierUnimplemented, }}, - "eks": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "eks": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateAccessPolicy": TierHandVerified, "AssociateEncryptionConfig": TierHandVerified, "AssociateIdentityProviderConfig": TierHandVerified, @@ -3816,7 +3826,7 @@ var Services = map[string]Service{ "UpdateNodegroupVersion": TierHandVerified, "UpdatePodIdentityAssociation": TierHandVerified, }}, - "elasticache": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "elasticache": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddTagsToResource": TierHandVerified, "AuthorizeCacheSecurityGroupIngress": TierHandVerified, "BatchApplyUpdateAction": TierUnimplemented, @@ -3893,7 +3903,7 @@ var Services = map[string]Service{ "TestFailover": TierHandVerified, "TestMigration": TierUnimplemented, }}, - "elasticbeanstalk": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "elasticbeanstalk": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AbortEnvironmentUpdate": TierHandVerified, "ApplyEnvironmentManagedAction": TierHandVerified, "AssociateEnvironmentOperationsRole": TierHandVerified, @@ -3942,7 +3952,7 @@ var Services = map[string]Service{ "UpdateTagsForResource": TierHandVerified, "ValidateConfigurationSettings": TierHandVerified, }}, - "elasticloadbalancingv2": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "elasticloadbalancingv2": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddListenerCertificates": TierHandVerified, "AddTags": TierHandVerified, "AddTrustStoreRevocations": TierUnimplemented, @@ -3995,7 +4005,7 @@ var Services = map[string]Service{ "SetSecurityGroups": TierHandVerified, "SetSubnets": TierHandVerified, }}, - "elasticsearchservice": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "elasticsearchservice": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptInboundCrossClusterSearchConnection": TierHandVerified, "AddTags": TierHandVerified, "AssociatePackage": TierHandVerified, @@ -4048,7 +4058,7 @@ var Services = map[string]Service{ "UpdateVpcEndpoint": TierHandVerified, "UpgradeElasticsearchDomain": TierHandVerified, }}, - "emr": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "emr": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddInstanceFleet": TierHandVerified, "AddInstanceGroups": TierHandVerified, "AddJobFlowSteps": TierHandVerified, @@ -4110,47 +4120,47 @@ var Services = map[string]Service{ "UpdateStudio": TierHandVerified, "UpdateStudioSessionMapping": TierHandVerified, }}, - "entityresolution": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "entityresolution": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddPolicyStatement": TierUnimplemented, "BatchDeleteUniqueId": TierUnimplemented, - "CreateIdMappingWorkflow": TierUnimplemented, - "CreateIdNamespace": TierUnimplemented, - "CreateMatchingWorkflow": TierUnimplemented, - "CreateSchemaMapping": TierUnimplemented, - "DeleteIdMappingWorkflow": TierUnimplemented, - "DeleteIdNamespace": TierUnimplemented, - "DeleteMatchingWorkflow": TierUnimplemented, - "DeletePolicyStatement": TierUnimplemented, - "DeleteSchemaMapping": TierUnimplemented, + "CreateIdMappingWorkflow": TierAutoCRUD, + "CreateIdNamespace": TierAutoCRUD, + "CreateMatchingWorkflow": TierAutoCRUD, + "CreateSchemaMapping": TierAutoCRUD, + "DeleteIdMappingWorkflow": TierAutoCRUD, + "DeleteIdNamespace": TierAutoCRUD, + "DeleteMatchingWorkflow": TierAutoCRUD, + "DeletePolicyStatement": TierAutoCRUD, + "DeleteSchemaMapping": TierAutoCRUD, "GenerateMatchId": TierUnimplemented, - "GetIdMappingJob": TierUnimplemented, - "GetIdMappingWorkflow": TierUnimplemented, - "GetIdNamespace": TierUnimplemented, - "GetMatchId": TierUnimplemented, - "GetMatchingJob": TierUnimplemented, - "GetMatchingWorkflow": TierUnimplemented, - "GetPolicy": TierUnimplemented, - "GetProviderService": TierUnimplemented, - "GetSchemaMapping": TierUnimplemented, - "ListIdMappingJobs": TierUnimplemented, - "ListIdMappingWorkflows": TierUnimplemented, - "ListIdNamespaces": TierUnimplemented, - "ListMatchingJobs": TierUnimplemented, - "ListMatchingWorkflows": TierUnimplemented, - "ListProviderServices": TierUnimplemented, - "ListSchemaMappings": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "PutPolicy": TierUnimplemented, + "GetIdMappingJob": TierAutoCRUD, + "GetIdMappingWorkflow": TierAutoCRUD, + "GetIdNamespace": TierAutoCRUD, + "GetMatchId": TierAutoCRUD, + "GetMatchingJob": TierAutoCRUD, + "GetMatchingWorkflow": TierAutoCRUD, + "GetPolicy": TierAutoCRUD, + "GetProviderService": TierAutoCRUD, + "GetSchemaMapping": TierAutoCRUD, + "ListIdMappingJobs": TierAutoCRUD, + "ListIdMappingWorkflows": TierAutoCRUD, + "ListIdNamespaces": TierAutoCRUD, + "ListMatchingJobs": TierAutoCRUD, + "ListMatchingWorkflows": TierAutoCRUD, + "ListProviderServices": TierAutoCRUD, + "ListSchemaMappings": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "PutPolicy": TierAutoCRUD, "StartIdMappingJob": TierUnimplemented, "StartMatchingJob": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateIdMappingWorkflow": TierUnimplemented, - "UpdateIdNamespace": TierUnimplemented, - "UpdateMatchingWorkflow": TierUnimplemented, - "UpdateSchemaMapping": TierUnimplemented, - }}, - "eventbridge": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateIdMappingWorkflow": TierAutoCRUD, + "UpdateIdNamespace": TierAutoCRUD, + "UpdateMatchingWorkflow": TierAutoCRUD, + "UpdateSchemaMapping": TierAutoCRUD, + }}, + "eventbridge": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "ActivateEventSource": TierUnimplemented, "CancelReplay": TierHandVerified, "CreateApiDestination": TierAutoCRUD, @@ -4209,7 +4219,7 @@ var Services = map[string]Service{ "UpdateEndpoint": TierAutoCRUD, "UpdateEventBus": TierAutoCRUD, }}, - "firehose": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "firehose": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddKinesisSource": TierHandVerified, "CreateDeliveryStream": TierHandVerified, "DeleteDeliveryStream": TierHandVerified, @@ -4251,7 +4261,7 @@ var Services = map[string]Service{ "UpdateS3Destination": TierHandVerified, "UpdateSplunkDestination": TierHandVerified, }}, - "fis": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "fis": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CancelExperiment": TierHandVerified, "CloneExperimentTemplate": TierHandVerified, "CreateExperimentTemplate": TierHandVerified, @@ -4286,7 +4296,7 @@ var Services = map[string]Service{ "UpdateTargetAccountConfiguration": TierHandVerified, "ValidateExperimentTemplate": TierHandVerified, }}, - "forecast": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "forecast": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateAutoPredictor": TierAutoCRUD, "CreateDataset": TierAutoCRUD, "CreateDatasetGroup": TierAutoCRUD, @@ -4351,11 +4361,11 @@ var Services = map[string]Service{ "UntagResource": TierAutoCRUD, "UpdateDatasetGroup": TierAutoCRUD, }}, - "forecastquery": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "forecastquery": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "QueryForecast": TierUnimplemented, "QueryWhatIfForecast": TierUnimplemented, }}, - "frauddetector": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "frauddetector": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchCreateVariable": TierUnimplemented, "BatchGetVariable": TierAutoCRUD, "CancelBatchImportJob": TierUnimplemented, @@ -4430,7 +4440,7 @@ var Services = map[string]Service{ "UpdateRuleVersion": TierAutoCRUD, "UpdateVariable": TierAutoCRUD, }}, - "glacier": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "glacier": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AbortMultipartUpload": TierHandVerified, "AbortVaultLock": TierHandVerified, "AddTagsToVault": TierHandVerified, @@ -4465,7 +4475,7 @@ var Services = map[string]Service{ "UploadArchive": TierHandVerified, "UploadMultipartPart": TierHandVerified, }}, - "glue": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "glue": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchCreatePartition": TierHandVerified, "BatchDeleteConnection": TierHandVerified, "BatchDeletePartition": TierHandVerified, @@ -4732,7 +4742,7 @@ var Services = map[string]Service{ "UpdateUserDefinedFunction": TierAutoCRUD, "UpdateWorkflow": TierAutoCRUD, }}, - "healthlake": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "healthlake": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateDataTransformationProfile": TierAutoCRUD, "CreateFHIRDatastore": TierAutoCRUD, "DeleteDataTransformationProfile": TierAutoCRUD, @@ -4760,7 +4770,7 @@ var Services = map[string]Service{ "UpdateFHIRDatastore": TierAutoCRUD, "UpdateProfileWithAgent": TierAutoCRUD, }}, - "iam": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "iam": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptDelegationRequest": TierUnimplemented, "AddClientIDToOpenIDConnectProvider": TierUnimplemented, "AddRoleToInstanceProfile": TierHandVerified, @@ -4938,7 +4948,7 @@ var Services = map[string]Service{ "UploadServerCertificate": TierUnimplemented, "UploadSigningCertificate": TierUnimplemented, }}, - "identitystore": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "identitystore": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "ActivateUser": TierHandVerified, "BatchCreateGroups": TierHandVerified, "BatchCreateUsers": TierHandVerified, @@ -4977,7 +4987,7 @@ var Services = map[string]Service{ "UpdateGroup": TierHandVerified, "UpdateUser": TierHandVerified, }}, - "iot": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "iot": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptCertificateTransfer": TierUnimplemented, "AddThingToBillingGroup": TierUnimplemented, "AddThingToThingGroup": TierHandVerified, @@ -5251,7 +5261,7 @@ var Services = map[string]Service{ "UpdateTopicRuleDestination": TierUnimplemented, "ValidateSecurityProfileBehaviors": TierUnimplemented, }}, - "iotdataplane": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "iotdataplane": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "DeleteConnection": TierHandVerified, "DeleteThingShadow": TierHandVerified, "GetRetainedMessage": TierHandVerified, @@ -5261,7 +5271,7 @@ var Services = map[string]Service{ "Publish": TierHandVerified, "UpdateThingShadow": TierHandVerified, }}, - "iotwireless": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "iotwireless": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssociateAwsAccountWithPartnerAccount": TierUnimplemented, "AssociateMulticastGroupWithFuotaTask": TierUnimplemented, "AssociateWirelessDeviceWithFuotaTask": TierUnimplemented, @@ -5375,7 +5385,7 @@ var Services = map[string]Service{ "UpdateWirelessDeviceImportTask": TierUnimplemented, "UpdateWirelessGateway": TierHandVerified, }}, - "kafka": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "kafka": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "BatchAssociateScramSecret": TierHandVerified, "BatchDisassociateScramSecret": TierHandVerified, "CreateCluster": TierHandVerified, @@ -5436,7 +5446,7 @@ var Services = map[string]Service{ "UpdateStorage": TierHandVerified, "UpdateTopic": TierHandVerified, }}, - "kendra": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "kendra": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateEntitiesToExperience": TierUnimplemented, "AssociatePersonasToEntities": TierUnimplemented, "BatchDeleteDocument": TierUnimplemented, @@ -5504,7 +5514,7 @@ var Services = map[string]Service{ "UpdateQuerySuggestionsConfig": TierAutoCRUD, "UpdateThesaurus": TierAutoCRUD, }}, - "kendraranking": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "kendraranking": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateRescoreExecutionPlan": TierAutoCRUD, "DeleteRescoreExecutionPlan": TierAutoCRUD, "DescribeRescoreExecutionPlan": TierAutoCRUD, @@ -5515,7 +5525,7 @@ var Services = map[string]Service{ "UntagResource": TierAutoCRUD, "UpdateRescoreExecutionPlan": TierAutoCRUD, }}, - "kinesis": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "kinesis": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToStream": TierHandVerified, "CreateStream": TierHandVerified, "DecreaseStreamRetentionPeriod": TierHandVerified, @@ -5556,7 +5566,7 @@ var Services = map[string]Service{ "UpdateStreamMode": TierHandVerified, "UpdateStreamWarmThroughput": TierHandVerified, }}, - "kinesisanalyticsv2": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "kinesisanalyticsv2": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddApplicationCloudWatchLoggingOption": TierHandVerified, "AddApplicationInput": TierHandVerified, "AddApplicationInputProcessingConfiguration": TierHandVerified, @@ -5591,7 +5601,7 @@ var Services = map[string]Service{ "UpdateApplication": TierHandVerified, "UpdateApplicationMaintenanceConfiguration": TierHandVerified, }}, - "kms": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "kms": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CancelKeyDeletion": TierHandVerified, "ConnectCustomKeyStore": TierUnimplemented, "CreateAlias": TierHandVerified, @@ -5646,7 +5656,7 @@ var Services = map[string]Service{ "Verify": TierHandVerified, "VerifyMac": TierUnimplemented, }}, - "lakeformation": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "lakeformation": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddLFTagsToResource": TierHandVerified, "AssumeDecoratedRoleWithSAML": TierHandVerified, "BatchGrantPermissions": TierHandVerified, @@ -5709,7 +5719,7 @@ var Services = map[string]Service{ "UpdateTableObjects": TierHandVerified, "UpdateTableStorageOptimizer": TierHandVerified, }}, - "lambda": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "lambda": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddLayerVersionPermission": TierUnimplemented, "AddPermission": TierHandVerified, "CheckpointDurableExecution": TierUnimplemented, @@ -5796,137 +5806,137 @@ var Services = map[string]Service{ "UpdateFunctionEventInvokeConfig": TierUnimplemented, "UpdateFunctionUrlConfig": TierUnimplemented, }}, - "lexmodelbuildingservice": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "CreateBotVersion": TierUnimplemented, - "CreateIntentVersion": TierUnimplemented, - "CreateSlotTypeVersion": TierUnimplemented, - "DeleteBot": TierUnimplemented, - "DeleteBotAlias": TierUnimplemented, - "DeleteBotChannelAssociation": TierUnimplemented, - "DeleteBotVersion": TierUnimplemented, - "DeleteIntent": TierUnimplemented, - "DeleteIntentVersion": TierUnimplemented, - "DeleteSlotType": TierUnimplemented, - "DeleteSlotTypeVersion": TierUnimplemented, - "DeleteUtterances": TierUnimplemented, - "GetBot": TierUnimplemented, - "GetBotAlias": TierUnimplemented, - "GetBotAliases": TierUnimplemented, - "GetBotChannelAssociation": TierUnimplemented, - "GetBotChannelAssociations": TierUnimplemented, - "GetBotVersions": TierUnimplemented, - "GetBots": TierUnimplemented, - "GetBuiltinIntent": TierUnimplemented, - "GetBuiltinIntents": TierUnimplemented, - "GetBuiltinSlotTypes": TierUnimplemented, - "GetExport": TierUnimplemented, - "GetImport": TierUnimplemented, - "GetIntent": TierUnimplemented, - "GetIntentVersions": TierUnimplemented, - "GetIntents": TierUnimplemented, - "GetMigration": TierUnimplemented, - "GetMigrations": TierUnimplemented, - "GetSlotType": TierUnimplemented, - "GetSlotTypeVersions": TierUnimplemented, - "GetSlotTypes": TierUnimplemented, - "GetUtterancesView": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "PutBot": TierUnimplemented, - "PutBotAlias": TierUnimplemented, - "PutIntent": TierUnimplemented, - "PutSlotType": TierUnimplemented, + "lexmodelbuildingservice": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "CreateBotVersion": TierAutoCRUD, + "CreateIntentVersion": TierAutoCRUD, + "CreateSlotTypeVersion": TierAutoCRUD, + "DeleteBot": TierAutoCRUD, + "DeleteBotAlias": TierAutoCRUD, + "DeleteBotChannelAssociation": TierAutoCRUD, + "DeleteBotVersion": TierAutoCRUD, + "DeleteIntent": TierAutoCRUD, + "DeleteIntentVersion": TierAutoCRUD, + "DeleteSlotType": TierAutoCRUD, + "DeleteSlotTypeVersion": TierAutoCRUD, + "DeleteUtterances": TierAutoCRUD, + "GetBot": TierAutoCRUD, + "GetBotAlias": TierAutoCRUD, + "GetBotAliases": TierAutoCRUD, + "GetBotChannelAssociation": TierAutoCRUD, + "GetBotChannelAssociations": TierAutoCRUD, + "GetBotVersions": TierAutoCRUD, + "GetBots": TierAutoCRUD, + "GetBuiltinIntent": TierAutoCRUD, + "GetBuiltinIntents": TierAutoCRUD, + "GetBuiltinSlotTypes": TierAutoCRUD, + "GetExport": TierAutoCRUD, + "GetImport": TierAutoCRUD, + "GetIntent": TierAutoCRUD, + "GetIntentVersions": TierAutoCRUD, + "GetIntents": TierAutoCRUD, + "GetMigration": TierAutoCRUD, + "GetMigrations": TierAutoCRUD, + "GetSlotType": TierAutoCRUD, + "GetSlotTypeVersions": TierAutoCRUD, + "GetSlotTypes": TierAutoCRUD, + "GetUtterancesView": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "PutBot": TierAutoCRUD, + "PutBotAlias": TierAutoCRUD, + "PutIntent": TierAutoCRUD, + "PutSlotType": TierAutoCRUD, "StartImport": TierUnimplemented, "StartMigration": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, }}, - "lexmodelsv2": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "lexmodelsv2": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchCreateCustomVocabularyItem": TierUnimplemented, "BatchDeleteCustomVocabularyItem": TierUnimplemented, "BatchUpdateCustomVocabularyItem": TierUnimplemented, "BuildBotLocale": TierUnimplemented, - "CreateBot": TierUnimplemented, - "CreateBotAlias": TierUnimplemented, - "CreateBotLocale": TierUnimplemented, - "CreateBotReplica": TierUnimplemented, - "CreateBotVersion": TierUnimplemented, - "CreateExport": TierUnimplemented, - "CreateIntent": TierUnimplemented, - "CreateResourcePolicy": TierUnimplemented, - "CreateResourcePolicyStatement": TierUnimplemented, - "CreateSlot": TierUnimplemented, - "CreateSlotType": TierUnimplemented, - "CreateTestSetDiscrepancyReport": TierUnimplemented, - "CreateUploadUrl": TierUnimplemented, - "DeleteBot": TierUnimplemented, - "DeleteBotAlias": TierUnimplemented, - "DeleteBotAnalyzerRecommendation": TierUnimplemented, - "DeleteBotLocale": TierUnimplemented, - "DeleteBotReplica": TierUnimplemented, - "DeleteBotVersion": TierUnimplemented, - "DeleteCustomVocabulary": TierUnimplemented, - "DeleteExport": TierUnimplemented, - "DeleteImport": TierUnimplemented, - "DeleteIntent": TierUnimplemented, - "DeleteResourcePolicy": TierUnimplemented, - "DeleteResourcePolicyStatement": TierUnimplemented, - "DeleteSlot": TierUnimplemented, - "DeleteSlotType": TierUnimplemented, - "DeleteTestSet": TierUnimplemented, - "DeleteUtterances": TierUnimplemented, - "DescribeBot": TierUnimplemented, - "DescribeBotAlias": TierUnimplemented, - "DescribeBotAnalyzerRecommendation": TierUnimplemented, - "DescribeBotLocale": TierUnimplemented, - "DescribeBotRecommendation": TierUnimplemented, - "DescribeBotReplica": TierUnimplemented, - "DescribeBotResourceGeneration": TierUnimplemented, - "DescribeBotVersion": TierUnimplemented, - "DescribeCustomVocabularyMetadata": TierUnimplemented, - "DescribeExport": TierUnimplemented, - "DescribeImport": TierUnimplemented, - "DescribeIntent": TierUnimplemented, - "DescribeResourcePolicy": TierUnimplemented, - "DescribeSlot": TierUnimplemented, - "DescribeSlotType": TierUnimplemented, - "DescribeTestExecution": TierUnimplemented, - "DescribeTestSet": TierUnimplemented, - "DescribeTestSetDiscrepancyReport": TierUnimplemented, - "DescribeTestSetGeneration": TierUnimplemented, + "CreateBot": TierAutoCRUD, + "CreateBotAlias": TierAutoCRUD, + "CreateBotLocale": TierAutoCRUD, + "CreateBotReplica": TierAutoCRUD, + "CreateBotVersion": TierAutoCRUD, + "CreateExport": TierAutoCRUD, + "CreateIntent": TierAutoCRUD, + "CreateResourcePolicy": TierAutoCRUD, + "CreateResourcePolicyStatement": TierAutoCRUD, + "CreateSlot": TierAutoCRUD, + "CreateSlotType": TierAutoCRUD, + "CreateTestSetDiscrepancyReport": TierAutoCRUD, + "CreateUploadUrl": TierAutoCRUD, + "DeleteBot": TierAutoCRUD, + "DeleteBotAlias": TierAutoCRUD, + "DeleteBotAnalyzerRecommendation": TierAutoCRUD, + "DeleteBotLocale": TierAutoCRUD, + "DeleteBotReplica": TierAutoCRUD, + "DeleteBotVersion": TierAutoCRUD, + "DeleteCustomVocabulary": TierAutoCRUD, + "DeleteExport": TierAutoCRUD, + "DeleteImport": TierAutoCRUD, + "DeleteIntent": TierAutoCRUD, + "DeleteResourcePolicy": TierAutoCRUD, + "DeleteResourcePolicyStatement": TierAutoCRUD, + "DeleteSlot": TierAutoCRUD, + "DeleteSlotType": TierAutoCRUD, + "DeleteTestSet": TierAutoCRUD, + "DeleteUtterances": TierAutoCRUD, + "DescribeBot": TierAutoCRUD, + "DescribeBotAlias": TierAutoCRUD, + "DescribeBotAnalyzerRecommendation": TierAutoCRUD, + "DescribeBotLocale": TierAutoCRUD, + "DescribeBotRecommendation": TierAutoCRUD, + "DescribeBotReplica": TierAutoCRUD, + "DescribeBotResourceGeneration": TierAutoCRUD, + "DescribeBotVersion": TierAutoCRUD, + "DescribeCustomVocabularyMetadata": TierAutoCRUD, + "DescribeExport": TierAutoCRUD, + "DescribeImport": TierAutoCRUD, + "DescribeIntent": TierAutoCRUD, + "DescribeResourcePolicy": TierAutoCRUD, + "DescribeSlot": TierAutoCRUD, + "DescribeSlotType": TierAutoCRUD, + "DescribeTestExecution": TierAutoCRUD, + "DescribeTestSet": TierAutoCRUD, + "DescribeTestSetDiscrepancyReport": TierAutoCRUD, + "DescribeTestSetGeneration": TierAutoCRUD, "GenerateBotElement": TierUnimplemented, - "GetTestExecutionArtifactsUrl": TierUnimplemented, - "ListAggregatedUtterances": TierUnimplemented, - "ListBotAliasReplicas": TierUnimplemented, - "ListBotAliases": TierUnimplemented, - "ListBotAnalyzerHistory": TierUnimplemented, - "ListBotLocales": TierUnimplemented, - "ListBotRecommendations": TierUnimplemented, - "ListBotReplicas": TierUnimplemented, - "ListBotResourceGenerations": TierUnimplemented, - "ListBotVersionReplicas": TierUnimplemented, - "ListBotVersions": TierUnimplemented, - "ListBots": TierUnimplemented, - "ListBuiltInIntents": TierUnimplemented, - "ListBuiltInSlotTypes": TierUnimplemented, - "ListCustomVocabularyItems": TierUnimplemented, - "ListExports": TierUnimplemented, - "ListImports": TierUnimplemented, - "ListIntentMetrics": TierUnimplemented, - "ListIntentPaths": TierUnimplemented, - "ListIntentStageMetrics": TierUnimplemented, - "ListIntents": TierUnimplemented, - "ListRecommendedIntents": TierUnimplemented, - "ListSessionAnalyticsData": TierUnimplemented, - "ListSessionMetrics": TierUnimplemented, - "ListSlotTypes": TierUnimplemented, - "ListSlots": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "ListTestExecutionResultItems": TierUnimplemented, - "ListTestExecutions": TierUnimplemented, - "ListTestSetRecords": TierUnimplemented, - "ListTestSets": TierUnimplemented, - "ListUtteranceAnalyticsData": TierUnimplemented, - "ListUtteranceMetrics": TierUnimplemented, + "GetTestExecutionArtifactsUrl": TierAutoCRUD, + "ListAggregatedUtterances": TierAutoCRUD, + "ListBotAliasReplicas": TierAutoCRUD, + "ListBotAliases": TierAutoCRUD, + "ListBotAnalyzerHistory": TierAutoCRUD, + "ListBotLocales": TierAutoCRUD, + "ListBotRecommendations": TierAutoCRUD, + "ListBotReplicas": TierAutoCRUD, + "ListBotResourceGenerations": TierAutoCRUD, + "ListBotVersionReplicas": TierAutoCRUD, + "ListBotVersions": TierAutoCRUD, + "ListBots": TierAutoCRUD, + "ListBuiltInIntents": TierAutoCRUD, + "ListBuiltInSlotTypes": TierAutoCRUD, + "ListCustomVocabularyItems": TierAutoCRUD, + "ListExports": TierAutoCRUD, + "ListImports": TierAutoCRUD, + "ListIntentMetrics": TierAutoCRUD, + "ListIntentPaths": TierAutoCRUD, + "ListIntentStageMetrics": TierAutoCRUD, + "ListIntents": TierAutoCRUD, + "ListRecommendedIntents": TierAutoCRUD, + "ListSessionAnalyticsData": TierAutoCRUD, + "ListSessionMetrics": TierAutoCRUD, + "ListSlotTypes": TierAutoCRUD, + "ListSlots": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "ListTestExecutionResultItems": TierAutoCRUD, + "ListTestExecutions": TierAutoCRUD, + "ListTestSetRecords": TierAutoCRUD, + "ListTestSets": TierAutoCRUD, + "ListUtteranceAnalyticsData": TierAutoCRUD, + "ListUtteranceMetrics": TierAutoCRUD, "SearchAssociatedTranscripts": TierUnimplemented, "StartBotAnalyzer": TierUnimplemented, "StartBotRecommendation": TierUnimplemented, @@ -5936,35 +5946,35 @@ var Services = map[string]Service{ "StartTestSetGeneration": TierUnimplemented, "StopBotAnalyzer": TierUnimplemented, "StopBotRecommendation": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateBot": TierUnimplemented, - "UpdateBotAlias": TierUnimplemented, - "UpdateBotLocale": TierUnimplemented, - "UpdateBotRecommendation": TierUnimplemented, - "UpdateExport": TierUnimplemented, - "UpdateIntent": TierUnimplemented, - "UpdateResourcePolicy": TierUnimplemented, - "UpdateSlot": TierUnimplemented, - "UpdateSlotType": TierUnimplemented, - "UpdateTestSet": TierUnimplemented, - }}, - "lexruntimeservice": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "DeleteSession": TierUnimplemented, - "GetSession": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateBot": TierAutoCRUD, + "UpdateBotAlias": TierAutoCRUD, + "UpdateBotLocale": TierAutoCRUD, + "UpdateBotRecommendation": TierAutoCRUD, + "UpdateExport": TierAutoCRUD, + "UpdateIntent": TierAutoCRUD, + "UpdateResourcePolicy": TierAutoCRUD, + "UpdateSlot": TierAutoCRUD, + "UpdateSlotType": TierAutoCRUD, + "UpdateTestSet": TierAutoCRUD, + }}, + "lexruntimeservice": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "DeleteSession": TierAutoCRUD, + "GetSession": TierAutoCRUD, "PostContent": TierUnimplemented, "PostText": TierUnimplemented, - "PutSession": TierUnimplemented, + "PutSession": TierAutoCRUD, }}, - "lexruntimev2": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "DeleteSession": TierUnimplemented, - "GetSession": TierUnimplemented, - "PutSession": TierUnimplemented, + "lexruntimev2": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "DeleteSession": TierAutoCRUD, + "GetSession": TierAutoCRUD, + "PutSession": TierAutoCRUD, "RecognizeText": TierUnimplemented, "RecognizeUtterance": TierUnimplemented, "StartConversation": TierUnimplemented, }}, - "lookoutequipment": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "lookoutequipment": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateDataset": TierAutoCRUD, "CreateInferenceScheduler": TierAutoCRUD, "CreateLabel": TierAutoCRUD, @@ -6015,7 +6025,7 @@ var Services = map[string]Service{ "UpdateModel": TierAutoCRUD, "UpdateRetrainingScheduler": TierAutoCRUD, }}, - "managedblockchain": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "managedblockchain": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateAccessor": TierHandVerified, "CreateMember": TierHandVerified, "CreateNetwork": TierHandVerified, @@ -6045,7 +6055,7 @@ var Services = map[string]Service{ "UpdateNode": TierHandVerified, "VoteOnProposal": TierHandVerified, }}, - "mediaconvert": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "mediaconvert": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "AssociateCertificate": TierHandVerified, "CancelJob": TierHandVerified, "CreateJob": TierHandVerified, @@ -6082,7 +6092,7 @@ var Services = map[string]Service{ "UpdatePreset": TierHandVerified, "UpdateQueue": TierHandVerified, }}, - "memorydb": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "memorydb": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchUpdateCluster": TierHandVerified, "CopySnapshot": TierHandVerified, "CreateACL": TierHandVerified, @@ -6129,7 +6139,7 @@ var Services = map[string]Service{ "UpdateSubnetGroup": TierHandVerified, "UpdateUser": TierHandVerified, }}, - "mq": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "mq": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateBroker": TierHandVerified, "CreateConfiguration": TierHandVerified, "CreateTags": TierHandVerified, @@ -6155,7 +6165,7 @@ var Services = map[string]Service{ "UpdateConfiguration": TierHandVerified, "UpdateUser": TierHandVerified, }}, - "mwaa": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "mwaa": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateCliToken": TierHandVerified, "CreateDag": TierHandVerified, "CreateDagRun": TierHandVerified, @@ -6190,7 +6200,7 @@ var Services = map[string]Service{ "UpdateEnvironment": TierHandVerified, "UpdateVariables": TierHandVerified, }}, - "neptune": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "neptune": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddRoleToDBCluster": TierHandVerified, "AddSourceIdentifierToSubscription": TierHandVerified, "AddTagsToResource": TierHandVerified, @@ -6263,7 +6273,7 @@ var Services = map[string]Service{ "StopDBCluster": TierHandVerified, "SwitchoverGlobalCluster": TierHandVerified, }}, - "omics": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "omics": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AbortMultipartReadSetUpload": TierUnimplemented, "AcceptShare": TierUnimplemented, "BatchDeleteReadSet": TierUnimplemented, @@ -6272,86 +6282,86 @@ var Services = map[string]Service{ "CancelRunBatch": TierUnimplemented, "CancelVariantImportJob": TierUnimplemented, "CompleteMultipartReadSetUpload": TierUnimplemented, - "CreateAnnotationStore": TierUnimplemented, - "CreateAnnotationStoreVersion": TierUnimplemented, - "CreateConfiguration": TierUnimplemented, - "CreateMultipartReadSetUpload": TierUnimplemented, - "CreateReferenceStore": TierUnimplemented, - "CreateRunCache": TierUnimplemented, - "CreateRunGroup": TierUnimplemented, - "CreateSequenceStore": TierUnimplemented, - "CreateShare": TierUnimplemented, - "CreateVariantStore": TierUnimplemented, - "CreateWorkflow": TierUnimplemented, - "CreateWorkflowVersion": TierUnimplemented, - "DeleteAnnotationStore": TierUnimplemented, - "DeleteAnnotationStoreVersions": TierUnimplemented, - "DeleteBatch": TierUnimplemented, - "DeleteConfiguration": TierUnimplemented, - "DeleteReference": TierUnimplemented, - "DeleteReferenceStore": TierUnimplemented, - "DeleteRun": TierUnimplemented, - "DeleteRunBatch": TierUnimplemented, - "DeleteRunCache": TierUnimplemented, - "DeleteRunGroup": TierUnimplemented, - "DeleteS3AccessPolicy": TierUnimplemented, - "DeleteSequenceStore": TierUnimplemented, - "DeleteShare": TierUnimplemented, - "DeleteVariantStore": TierUnimplemented, - "DeleteWorkflow": TierUnimplemented, - "DeleteWorkflowVersion": TierUnimplemented, - "GetAnnotationImportJob": TierUnimplemented, - "GetAnnotationStore": TierUnimplemented, - "GetAnnotationStoreVersion": TierUnimplemented, - "GetBatch": TierUnimplemented, - "GetConfiguration": TierUnimplemented, - "GetReadSet": TierUnimplemented, - "GetReadSetActivationJob": TierUnimplemented, - "GetReadSetExportJob": TierUnimplemented, - "GetReadSetImportJob": TierUnimplemented, - "GetReadSetMetadata": TierUnimplemented, - "GetReference": TierUnimplemented, - "GetReferenceImportJob": TierUnimplemented, - "GetReferenceMetadata": TierUnimplemented, - "GetReferenceStore": TierUnimplemented, - "GetRun": TierUnimplemented, - "GetRunCache": TierUnimplemented, - "GetRunGroup": TierUnimplemented, - "GetRunTask": TierUnimplemented, - "GetS3AccessPolicy": TierUnimplemented, - "GetSequenceStore": TierUnimplemented, - "GetShare": TierUnimplemented, - "GetVariantImportJob": TierUnimplemented, - "GetVariantStore": TierUnimplemented, - "GetWorkflow": TierUnimplemented, - "GetWorkflowVersion": TierUnimplemented, - "ListAnnotationImportJobs": TierUnimplemented, - "ListAnnotationStoreVersions": TierUnimplemented, - "ListAnnotationStores": TierUnimplemented, - "ListBatch": TierUnimplemented, - "ListConfigurations": TierUnimplemented, - "ListMultipartReadSetUploads": TierUnimplemented, - "ListReadSetActivationJobs": TierUnimplemented, - "ListReadSetExportJobs": TierUnimplemented, - "ListReadSetImportJobs": TierUnimplemented, - "ListReadSetUploadParts": TierUnimplemented, - "ListReadSets": TierUnimplemented, - "ListReferenceImportJobs": TierUnimplemented, - "ListReferenceStores": TierUnimplemented, - "ListReferences": TierUnimplemented, - "ListRunCaches": TierUnimplemented, - "ListRunGroups": TierUnimplemented, - "ListRunTasks": TierUnimplemented, - "ListRuns": TierUnimplemented, - "ListRunsInBatch": TierUnimplemented, - "ListSequenceStores": TierUnimplemented, - "ListShares": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "ListVariantImportJobs": TierUnimplemented, - "ListVariantStores": TierUnimplemented, - "ListWorkflowVersions": TierUnimplemented, - "ListWorkflows": TierUnimplemented, - "PutS3AccessPolicy": TierUnimplemented, + "CreateAnnotationStore": TierAutoCRUD, + "CreateAnnotationStoreVersion": TierAutoCRUD, + "CreateConfiguration": TierAutoCRUD, + "CreateMultipartReadSetUpload": TierAutoCRUD, + "CreateReferenceStore": TierAutoCRUD, + "CreateRunCache": TierAutoCRUD, + "CreateRunGroup": TierAutoCRUD, + "CreateSequenceStore": TierAutoCRUD, + "CreateShare": TierAutoCRUD, + "CreateVariantStore": TierAutoCRUD, + "CreateWorkflow": TierAutoCRUD, + "CreateWorkflowVersion": TierAutoCRUD, + "DeleteAnnotationStore": TierAutoCRUD, + "DeleteAnnotationStoreVersions": TierAutoCRUD, + "DeleteBatch": TierAutoCRUD, + "DeleteConfiguration": TierAutoCRUD, + "DeleteReference": TierAutoCRUD, + "DeleteReferenceStore": TierAutoCRUD, + "DeleteRun": TierAutoCRUD, + "DeleteRunBatch": TierAutoCRUD, + "DeleteRunCache": TierAutoCRUD, + "DeleteRunGroup": TierAutoCRUD, + "DeleteS3AccessPolicy": TierAutoCRUD, + "DeleteSequenceStore": TierAutoCRUD, + "DeleteShare": TierAutoCRUD, + "DeleteVariantStore": TierAutoCRUD, + "DeleteWorkflow": TierAutoCRUD, + "DeleteWorkflowVersion": TierAutoCRUD, + "GetAnnotationImportJob": TierAutoCRUD, + "GetAnnotationStore": TierAutoCRUD, + "GetAnnotationStoreVersion": TierAutoCRUD, + "GetBatch": TierAutoCRUD, + "GetConfiguration": TierAutoCRUD, + "GetReadSet": TierAutoCRUD, + "GetReadSetActivationJob": TierAutoCRUD, + "GetReadSetExportJob": TierAutoCRUD, + "GetReadSetImportJob": TierAutoCRUD, + "GetReadSetMetadata": TierAutoCRUD, + "GetReference": TierAutoCRUD, + "GetReferenceImportJob": TierAutoCRUD, + "GetReferenceMetadata": TierAutoCRUD, + "GetReferenceStore": TierAutoCRUD, + "GetRun": TierAutoCRUD, + "GetRunCache": TierAutoCRUD, + "GetRunGroup": TierAutoCRUD, + "GetRunTask": TierAutoCRUD, + "GetS3AccessPolicy": TierAutoCRUD, + "GetSequenceStore": TierAutoCRUD, + "GetShare": TierAutoCRUD, + "GetVariantImportJob": TierAutoCRUD, + "GetVariantStore": TierAutoCRUD, + "GetWorkflow": TierAutoCRUD, + "GetWorkflowVersion": TierAutoCRUD, + "ListAnnotationImportJobs": TierAutoCRUD, + "ListAnnotationStoreVersions": TierAutoCRUD, + "ListAnnotationStores": TierAutoCRUD, + "ListBatch": TierAutoCRUD, + "ListConfigurations": TierAutoCRUD, + "ListMultipartReadSetUploads": TierAutoCRUD, + "ListReadSetActivationJobs": TierAutoCRUD, + "ListReadSetExportJobs": TierAutoCRUD, + "ListReadSetImportJobs": TierAutoCRUD, + "ListReadSetUploadParts": TierAutoCRUD, + "ListReadSets": TierAutoCRUD, + "ListReferenceImportJobs": TierAutoCRUD, + "ListReferenceStores": TierAutoCRUD, + "ListReferences": TierAutoCRUD, + "ListRunCaches": TierAutoCRUD, + "ListRunGroups": TierAutoCRUD, + "ListRunTasks": TierAutoCRUD, + "ListRuns": TierAutoCRUD, + "ListRunsInBatch": TierAutoCRUD, + "ListSequenceStores": TierAutoCRUD, + "ListShares": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "ListVariantImportJobs": TierAutoCRUD, + "ListVariantStores": TierAutoCRUD, + "ListWorkflowVersions": TierAutoCRUD, + "ListWorkflows": TierAutoCRUD, + "PutS3AccessPolicy": TierAutoCRUD, "StartAnnotationImportJob": TierUnimplemented, "StartReadSetActivationJob": TierUnimplemented, "StartReadSetExportJob": TierUnimplemented, @@ -6360,19 +6370,19 @@ var Services = map[string]Service{ "StartRun": TierUnimplemented, "StartRunBatch": TierUnimplemented, "StartVariantImportJob": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateAnnotationStore": TierUnimplemented, - "UpdateAnnotationStoreVersion": TierUnimplemented, - "UpdateRunCache": TierUnimplemented, - "UpdateRunGroup": TierUnimplemented, - "UpdateSequenceStore": TierUnimplemented, - "UpdateVariantStore": TierUnimplemented, - "UpdateWorkflow": TierUnimplemented, - "UpdateWorkflowVersion": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateAnnotationStore": TierAutoCRUD, + "UpdateAnnotationStoreVersion": TierAutoCRUD, + "UpdateRunCache": TierAutoCRUD, + "UpdateRunGroup": TierAutoCRUD, + "UpdateSequenceStore": TierAutoCRUD, + "UpdateVariantStore": TierAutoCRUD, + "UpdateWorkflow": TierAutoCRUD, + "UpdateWorkflowVersion": TierAutoCRUD, "UploadReadSetPart": TierUnimplemented, }}, - "opensearch": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "opensearch": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptInboundConnection": TierHandVerified, "AddDataSource": TierHandVerified, "AddDirectQueryDataSource": TierHandVerified, @@ -6461,7 +6471,7 @@ var Services = map[string]Service{ "UpdateVpcEndpoint": TierHandVerified, "UpgradeDomain": TierHandVerified, }}, - "organizations": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "organizations": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AcceptHandshake": TierHandVerified, "AttachPolicy": TierHandVerified, "CancelHandshake": TierHandVerified, @@ -6526,7 +6536,7 @@ var Services = map[string]Service{ "UpdatePolicy": TierHandVerified, "UpdateResponsibilityTransfer": TierAutoCRUD, }}, - "personalize": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "personalize": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateBatchInferenceJob": TierAutoCRUD, "CreateBatchSegmentJob": TierAutoCRUD, "CreateCampaign": TierAutoCRUD, @@ -6599,19 +6609,19 @@ var Services = map[string]Service{ "UpdateRecommender": TierAutoCRUD, "UpdateSolution": TierAutoCRUD, }}, - "personalizeevents": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "PutActionInteractions": TierUnimplemented, - "PutActions": TierUnimplemented, - "PutEvents": TierUnimplemented, - "PutItems": TierUnimplemented, - "PutUsers": TierUnimplemented, + "personalizeevents": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "PutActionInteractions": TierAutoCRUD, + "PutActions": TierAutoCRUD, + "PutEvents": TierAutoCRUD, + "PutItems": TierAutoCRUD, + "PutUsers": TierAutoCRUD, }}, - "personalizeruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "GetActionRecommendations": TierUnimplemented, - "GetPersonalizedRanking": TierUnimplemented, - "GetRecommendations": TierUnimplemented, + "personalizeruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "GetActionRecommendations": TierAutoCRUD, + "GetPersonalizedRanking": TierAutoCRUD, + "GetRecommendations": TierAutoCRUD, }}, - "pinpoint": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "pinpoint": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CreateApp": TierHandVerified, "CreateCampaign": TierHandVerified, "CreateEmailTemplate": TierHandVerified, @@ -6735,7 +6745,7 @@ var Services = map[string]Service{ "UpdateVoiceTemplate": TierHandVerified, "VerifyOTPMessage": TierHandVerified, }}, - "pipes": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "pipes": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "CreatePipe": TierHandVerified, "DeletePipe": TierHandVerified, "DescribePipe": TierHandVerified, @@ -6760,56 +6770,56 @@ var Services = map[string]Service{ "UpdatePipe": TierHandVerified, "ValidatePipeParameters": TierHandVerified, }}, - "polly": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "DeleteLexicon": TierUnimplemented, - "DescribeVoices": TierUnimplemented, - "GetLexicon": TierUnimplemented, - "GetSpeechSynthesisTask": TierUnimplemented, - "ListLexicons": TierUnimplemented, - "ListSpeechSynthesisTasks": TierUnimplemented, - "PutLexicon": TierUnimplemented, + "polly": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "DeleteLexicon": TierAutoCRUD, + "DescribeVoices": TierAutoCRUD, + "GetLexicon": TierAutoCRUD, + "GetSpeechSynthesisTask": TierAutoCRUD, + "ListLexicons": TierAutoCRUD, + "ListSpeechSynthesisTasks": TierAutoCRUD, + "PutLexicon": TierAutoCRUD, "StartSpeechSynthesisStream": TierUnimplemented, "StartSpeechSynthesisTask": TierUnimplemented, "SynthesizeSpeech": TierUnimplemented, }}, - "qapps": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "qapps": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateLibraryItemReview": TierUnimplemented, "AssociateQAppWithUser": TierUnimplemented, "BatchCreateCategory": TierUnimplemented, "BatchDeleteCategory": TierUnimplemented, "BatchUpdateCategory": TierUnimplemented, - "CreateLibraryItem": TierUnimplemented, - "CreatePresignedUrl": TierUnimplemented, - "CreateQApp": TierUnimplemented, - "DeleteLibraryItem": TierUnimplemented, - "DeleteQApp": TierUnimplemented, - "DescribeQAppPermissions": TierUnimplemented, + "CreateLibraryItem": TierAutoCRUD, + "CreatePresignedUrl": TierAutoCRUD, + "CreateQApp": TierAutoCRUD, + "DeleteLibraryItem": TierAutoCRUD, + "DeleteQApp": TierAutoCRUD, + "DescribeQAppPermissions": TierAutoCRUD, "DisassociateLibraryItemReview": TierUnimplemented, "DisassociateQAppFromUser": TierUnimplemented, "ExportQAppSessionData": TierUnimplemented, - "GetLibraryItem": TierUnimplemented, - "GetQApp": TierUnimplemented, - "GetQAppSession": TierUnimplemented, - "GetQAppSessionMetadata": TierUnimplemented, + "GetLibraryItem": TierAutoCRUD, + "GetQApp": TierAutoCRUD, + "GetQAppSession": TierAutoCRUD, + "GetQAppSessionMetadata": TierAutoCRUD, "ImportDocument": TierUnimplemented, - "ListCategories": TierUnimplemented, - "ListLibraryItems": TierUnimplemented, - "ListQAppSessionData": TierUnimplemented, - "ListQApps": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, + "ListCategories": TierAutoCRUD, + "ListLibraryItems": TierAutoCRUD, + "ListQAppSessionData": TierAutoCRUD, + "ListQApps": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, "PredictQApp": TierUnimplemented, "StartQAppSession": TierUnimplemented, "StopQAppSession": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateLibraryItem": TierUnimplemented, - "UpdateLibraryItemMetadata": TierUnimplemented, - "UpdateQApp": TierUnimplemented, - "UpdateQAppPermissions": TierUnimplemented, - "UpdateQAppSession": TierUnimplemented, - "UpdateQAppSessionMetadata": TierUnimplemented, - }}, - "qbusiness": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateLibraryItem": TierAutoCRUD, + "UpdateLibraryItemMetadata": TierAutoCRUD, + "UpdateQApp": TierAutoCRUD, + "UpdateQAppPermissions": TierAutoCRUD, + "UpdateQAppSession": TierAutoCRUD, + "UpdateQAppSessionMetadata": TierAutoCRUD, + }}, + "qbusiness": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociatePermission": TierUnimplemented, "BatchDeleteDocument": TierUnimplemented, "BatchPutDocument": TierUnimplemented, @@ -6817,84 +6827,84 @@ var Services = map[string]Service{ "Chat": TierUnimplemented, "ChatSync": TierUnimplemented, "CheckDocumentAccess": TierUnimplemented, - "CreateAnonymousWebExperienceUrl": TierUnimplemented, - "CreateApplication": TierUnimplemented, - "CreateChatResponseConfiguration": TierUnimplemented, - "CreateDataAccessor": TierUnimplemented, - "CreateDataSource": TierUnimplemented, - "CreateIndex": TierUnimplemented, - "CreatePlugin": TierUnimplemented, - "CreateRetriever": TierUnimplemented, - "CreateSubscription": TierUnimplemented, - "CreateUser": TierUnimplemented, - "CreateWebExperience": TierUnimplemented, - "DeleteApplication": TierUnimplemented, - "DeleteAttachment": TierUnimplemented, - "DeleteChatControlsConfiguration": TierUnimplemented, - "DeleteChatResponseConfiguration": TierUnimplemented, - "DeleteConversation": TierUnimplemented, - "DeleteDataAccessor": TierUnimplemented, - "DeleteDataSource": TierUnimplemented, - "DeleteGroup": TierUnimplemented, - "DeleteIndex": TierUnimplemented, - "DeletePlugin": TierUnimplemented, - "DeleteRetriever": TierUnimplemented, - "DeleteUser": TierUnimplemented, - "DeleteWebExperience": TierUnimplemented, + "CreateAnonymousWebExperienceUrl": TierAutoCRUD, + "CreateApplication": TierAutoCRUD, + "CreateChatResponseConfiguration": TierAutoCRUD, + "CreateDataAccessor": TierAutoCRUD, + "CreateDataSource": TierAutoCRUD, + "CreateIndex": TierAutoCRUD, + "CreatePlugin": TierAutoCRUD, + "CreateRetriever": TierAutoCRUD, + "CreateSubscription": TierAutoCRUD, + "CreateUser": TierAutoCRUD, + "CreateWebExperience": TierAutoCRUD, + "DeleteApplication": TierAutoCRUD, + "DeleteAttachment": TierAutoCRUD, + "DeleteChatControlsConfiguration": TierAutoCRUD, + "DeleteChatResponseConfiguration": TierAutoCRUD, + "DeleteConversation": TierAutoCRUD, + "DeleteDataAccessor": TierAutoCRUD, + "DeleteDataSource": TierAutoCRUD, + "DeleteGroup": TierAutoCRUD, + "DeleteIndex": TierAutoCRUD, + "DeletePlugin": TierAutoCRUD, + "DeleteRetriever": TierAutoCRUD, + "DeleteUser": TierAutoCRUD, + "DeleteWebExperience": TierAutoCRUD, "DisassociatePermission": TierUnimplemented, - "GetApplication": TierUnimplemented, - "GetChatControlsConfiguration": TierUnimplemented, - "GetChatResponseConfiguration": TierUnimplemented, - "GetDataAccessor": TierUnimplemented, - "GetDataSource": TierUnimplemented, - "GetDocumentContent": TierUnimplemented, - "GetGroup": TierUnimplemented, - "GetIndex": TierUnimplemented, - "GetMedia": TierUnimplemented, - "GetPlugin": TierUnimplemented, - "GetPolicy": TierUnimplemented, - "GetRetriever": TierUnimplemented, - "GetUser": TierUnimplemented, - "GetWebExperience": TierUnimplemented, - "ListApplications": TierUnimplemented, - "ListAttachments": TierUnimplemented, - "ListChatResponseConfigurations": TierUnimplemented, - "ListConversations": TierUnimplemented, - "ListDataAccessors": TierUnimplemented, - "ListDataSourceSyncJobs": TierUnimplemented, - "ListDataSources": TierUnimplemented, - "ListDocuments": TierUnimplemented, - "ListGroups": TierUnimplemented, - "ListIndices": TierUnimplemented, - "ListMessages": TierUnimplemented, - "ListPluginActions": TierUnimplemented, - "ListPluginTypeActions": TierUnimplemented, - "ListPluginTypeMetadata": TierUnimplemented, - "ListPlugins": TierUnimplemented, - "ListRetrievers": TierUnimplemented, - "ListSubscriptions": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "ListWebExperiences": TierUnimplemented, - "PutFeedback": TierUnimplemented, - "PutGroup": TierUnimplemented, + "GetApplication": TierAutoCRUD, + "GetChatControlsConfiguration": TierAutoCRUD, + "GetChatResponseConfiguration": TierAutoCRUD, + "GetDataAccessor": TierAutoCRUD, + "GetDataSource": TierAutoCRUD, + "GetDocumentContent": TierAutoCRUD, + "GetGroup": TierAutoCRUD, + "GetIndex": TierAutoCRUD, + "GetMedia": TierAutoCRUD, + "GetPlugin": TierAutoCRUD, + "GetPolicy": TierAutoCRUD, + "GetRetriever": TierAutoCRUD, + "GetUser": TierAutoCRUD, + "GetWebExperience": TierAutoCRUD, + "ListApplications": TierAutoCRUD, + "ListAttachments": TierAutoCRUD, + "ListChatResponseConfigurations": TierAutoCRUD, + "ListConversations": TierAutoCRUD, + "ListDataAccessors": TierAutoCRUD, + "ListDataSourceSyncJobs": TierAutoCRUD, + "ListDataSources": TierAutoCRUD, + "ListDocuments": TierAutoCRUD, + "ListGroups": TierAutoCRUD, + "ListIndices": TierAutoCRUD, + "ListMessages": TierAutoCRUD, + "ListPluginActions": TierAutoCRUD, + "ListPluginTypeActions": TierAutoCRUD, + "ListPluginTypeMetadata": TierAutoCRUD, + "ListPlugins": TierAutoCRUD, + "ListRetrievers": TierAutoCRUD, + "ListSubscriptions": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "ListWebExperiences": TierAutoCRUD, + "PutFeedback": TierAutoCRUD, + "PutGroup": TierAutoCRUD, "SearchRelevantContent": TierUnimplemented, "StartDataSourceSyncJob": TierUnimplemented, "StopDataSourceSyncJob": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, - "UpdateApplication": TierUnimplemented, - "UpdateChatControlsConfiguration": TierUnimplemented, - "UpdateChatResponseConfiguration": TierUnimplemented, - "UpdateDataAccessor": TierUnimplemented, - "UpdateDataSource": TierUnimplemented, - "UpdateIndex": TierUnimplemented, - "UpdatePlugin": TierUnimplemented, - "UpdateRetriever": TierUnimplemented, - "UpdateSubscription": TierUnimplemented, - "UpdateUser": TierUnimplemented, - "UpdateWebExperience": TierUnimplemented, - }}, - "ram": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, + "UpdateApplication": TierAutoCRUD, + "UpdateChatControlsConfiguration": TierAutoCRUD, + "UpdateChatResponseConfiguration": TierAutoCRUD, + "UpdateDataAccessor": TierAutoCRUD, + "UpdateDataSource": TierAutoCRUD, + "UpdateIndex": TierAutoCRUD, + "UpdatePlugin": TierAutoCRUD, + "UpdateRetriever": TierAutoCRUD, + "UpdateSubscription": TierAutoCRUD, + "UpdateUser": TierAutoCRUD, + "UpdateWebExperience": TierAutoCRUD, + }}, + "ram": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptResourceShareInvitation": TierHandVerified, "AssociateResourceShare": TierHandVerified, "AssociateResourceSharePermission": TierHandVerified, @@ -6931,7 +6941,7 @@ var Services = map[string]Service{ "UntagResource": TierHandVerified, "UpdateResourceShare": TierHandVerified, }}, - "rds": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "rds": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddRoleToDBCluster": TierUnimplemented, "AddRoleToDBInstance": TierUnimplemented, "AddSourceIdentifierToSubscription": TierUnimplemented, @@ -7096,7 +7106,7 @@ var Services = map[string]Service{ "SwitchoverGlobalCluster": TierUnimplemented, "SwitchoverReadReplica": TierUnimplemented, }}, - "redshift": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "redshift": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AcceptReservedNodeExchange": TierUnimplemented, "AddPartner": TierUnimplemented, "AssociateDataShareConsumer": TierUnimplemented, @@ -7239,7 +7249,7 @@ var Services = map[string]Service{ "RotateEncryptionKey": TierUnimplemented, "UpdatePartnerStatus": TierUnimplemented, }}, - "rekognition": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "rekognition": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateFaces": TierUnimplemented, "CompareFaces": TierUnimplemented, "CopyProjectVersion": TierUnimplemented, @@ -7316,7 +7326,7 @@ var Services = map[string]Service{ "UpdateDatasetEntries": TierAutoCRUD, "UpdateStreamProcessor": TierAutoCRUD, }}, - "resourcegroups": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "resourcegroups": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CancelTagSyncTask": TierHandVerified, "CreateGroup": TierHandVerified, "DeleteGroup": TierHandVerified, @@ -7341,7 +7351,7 @@ var Services = map[string]Service{ "UpdateGroup": TierHandVerified, "UpdateGroupQuery": TierHandVerified, }}, - "resourcegroupstaggingapi": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "resourcegroupstaggingapi": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateTags": TierHandVerified, "CreateTagOption": TierHandVerified, "DeleteTagOption": TierHandVerified, @@ -7365,7 +7375,7 @@ var Services = map[string]Service{ "UntagResources": TierHandVerified, "UpdateTagOption": TierHandVerified, }}, - "route53": {Protocol: "rest-xml", ModelBacked: true, Operations: map[string]Tier{ + "route53": {Protocol: "rest-xml", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "ActivateKeySigningKey": TierHandVerified, "AssociateVPCWithHostedZone": TierHandVerified, "ChangeCidrCollection": TierHandVerified, @@ -7439,7 +7449,7 @@ var Services = map[string]Service{ "UpdateTrafficPolicyComment": TierUnimplemented, "UpdateTrafficPolicyInstance": TierHandVerified, }}, - "route53resolver": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "route53resolver": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateFirewallRuleGroup": TierHandVerified, "AssociateResolverEndpointIpAddress": TierHandVerified, "AssociateResolverQueryLogConfig": TierHandVerified, @@ -7509,7 +7519,7 @@ var Services = map[string]Service{ "UpdateResolverEndpoint": TierHandVerified, "UpdateResolverRule": TierHandVerified, }}, - "s3": {Protocol: "rest-xml", ModelBacked: true, Operations: map[string]Tier{ + "s3": {Protocol: "rest-xml", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AbortMultipartUpload": TierHandVerified, "CompleteMultipartUpload": TierHandVerified, "CopyObject": TierHandVerified, @@ -7618,7 +7628,7 @@ var Services = map[string]Service{ "UploadPartCopy": TierUnimplemented, "WriteGetObjectResponse": TierUnimplemented, }}, - "s3tables": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "s3tables": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "CreateNamespace": TierHandVerified, "CreateTable": TierHandVerified, "CreateTableBucket": TierHandVerified, @@ -7653,7 +7663,7 @@ var Services = map[string]Service{ "RenameTable": TierHandVerified, "UpdateTableMetadataLocation": TierHandVerified, }}, - "sagemaker": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "sagemaker": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddAssociation": TierUnimplemented, "AddTags": TierHandVerified, "AssociateTrialComponent": TierUnimplemented, @@ -8036,67 +8046,67 @@ var Services = map[string]Service{ "UpdateWorkforce": TierAutoCRUD, "UpdateWorkteam": TierAutoCRUD, }}, - "sagemakera2iruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "DeleteHumanLoop": TierUnimplemented, - "DescribeHumanLoop": TierUnimplemented, - "ListHumanLoops": TierUnimplemented, + "sagemakera2iruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "DeleteHumanLoop": TierAutoCRUD, + "DescribeHumanLoop": TierAutoCRUD, + "ListHumanLoops": TierAutoCRUD, "StartHumanLoop": TierUnimplemented, "StopHumanLoop": TierUnimplemented, }}, - "sagemakeredge": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "GetDeployments": TierUnimplemented, - "GetDeviceRegistration": TierUnimplemented, + "sagemakeredge": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "GetDeployments": TierAutoCRUD, + "GetDeviceRegistration": TierAutoCRUD, "SendHeartbeat": TierUnimplemented, }}, - "sagemakerfeaturestoreruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "BatchGetRecord": TierUnimplemented, + "sagemakerfeaturestoreruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "BatchGetRecord": TierAutoCRUD, "BatchWriteRecord": TierUnimplemented, - "DeleteRecord": TierUnimplemented, - "GetRecord": TierUnimplemented, - "ListRecords": TierUnimplemented, - "PutRecord": TierUnimplemented, - "UpdateRecord": TierUnimplemented, - }}, - "sagemakergeospatial": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "DeleteEarthObservationJob": TierUnimplemented, - "DeleteVectorEnrichmentJob": TierUnimplemented, + "DeleteRecord": TierAutoCRUD, + "GetRecord": TierAutoCRUD, + "ListRecords": TierAutoCRUD, + "PutRecord": TierAutoCRUD, + "UpdateRecord": TierAutoCRUD, + }}, + "sagemakergeospatial": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "DeleteEarthObservationJob": TierAutoCRUD, + "DeleteVectorEnrichmentJob": TierAutoCRUD, "ExportEarthObservationJob": TierUnimplemented, "ExportVectorEnrichmentJob": TierUnimplemented, - "GetEarthObservationJob": TierUnimplemented, - "GetRasterDataCollection": TierUnimplemented, - "GetTile": TierUnimplemented, - "GetVectorEnrichmentJob": TierUnimplemented, - "ListEarthObservationJobs": TierUnimplemented, - "ListRasterDataCollections": TierUnimplemented, - "ListTagsForResource": TierUnimplemented, - "ListVectorEnrichmentJobs": TierUnimplemented, + "GetEarthObservationJob": TierAutoCRUD, + "GetRasterDataCollection": TierAutoCRUD, + "GetTile": TierAutoCRUD, + "GetVectorEnrichmentJob": TierAutoCRUD, + "ListEarthObservationJobs": TierAutoCRUD, + "ListRasterDataCollections": TierAutoCRUD, + "ListTagsForResource": TierAutoCRUD, + "ListVectorEnrichmentJobs": TierAutoCRUD, "SearchRasterDataCollection": TierUnimplemented, "StartEarthObservationJob": TierUnimplemented, "StartVectorEnrichmentJob": TierUnimplemented, "StopEarthObservationJob": TierUnimplemented, "StopVectorEnrichmentJob": TierUnimplemented, - "TagResource": TierUnimplemented, - "UntagResource": TierUnimplemented, + "TagResource": TierAutoCRUD, + "UntagResource": TierAutoCRUD, }}, - "sagemakerjobruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "sagemakerjobruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CompleteRollout": TierUnimplemented, "Sample": TierUnimplemented, "SampleWithResponseStream": TierUnimplemented, - "UpdateReward": TierUnimplemented, + "UpdateReward": TierAutoCRUD, }}, - "sagemakermetrics": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "BatchGetMetrics": TierUnimplemented, + "sagemakermetrics": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "BatchGetMetrics": TierAutoCRUD, "BatchPutMetrics": TierUnimplemented, }}, - "sagemakerruntime": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "sagemakerruntime": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "InvokeEndpoint": TierUnimplemented, "InvokeEndpointAsync": TierUnimplemented, "InvokeEndpointWithResponseStream": TierUnimplemented, }}, - "sagemakerruntimehttp2": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "sagemakerruntimehttp2": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "InvokeEndpointWithBidirectionalStream": TierUnimplemented, }}, - "scheduler": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "scheduler": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "BatchCheckMaxRateLimits": TierHandVerified, "BatchCreateSchedules": TierHandVerified, "BatchDeleteSchedules": TierHandVerified, @@ -8135,7 +8145,7 @@ var Services = map[string]Service{ "UpdateScheduleGroup": TierHandVerified, "ValidateScheduleExpression": TierHandVerified, }}, - "secretsmanager": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "secretsmanager": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "BatchGetSecretValue": TierHandVerified, "CancelRotateSecret": TierHandVerified, "ClearSecretValue": TierHandVerified, @@ -8177,7 +8187,7 @@ var Services = map[string]Service{ "ValidateResourcePolicy": TierHandVerified, "ValidateSecret": TierHandVerified, }}, - "serverlessrepo": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "serverlessrepo": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "AddApplicationDependency": TierHandVerified, "CancelCloudFormationChangeSet": TierHandVerified, "CreateApplication": TierHandVerified, @@ -8220,7 +8230,7 @@ var Services = map[string]Service{ "UpdateApplication": TierHandVerified, "UpdateApplicationVersion": TierHandVerified, }}, - "servicediscovery": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "servicediscovery": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateHttpNamespace": TierHandVerified, "CreatePrivateDnsNamespace": TierHandVerified, "CreatePublicDnsNamespace": TierHandVerified, @@ -8252,7 +8262,7 @@ var Services = map[string]Service{ "UpdateService": TierHandVerified, "UpdateServiceAttributes": TierHandVerified, }}, - "ses": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "ses": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "CloneReceiptRuleSet": TierHandVerified, "CreateConfigurationSet": TierHandVerified, "CreateConfigurationSetEventDestination": TierHandVerified, @@ -8330,7 +8340,7 @@ var Services = map[string]Service{ "VerifyEmailAddress": TierHandVerified, "VerifyEmailIdentity": TierHandVerified, }}, - "sesv2": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "sesv2": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "BatchGetMetricData": TierHandVerified, "CancelExportJob": TierHandVerified, "CreateConfigurationSet": TierHandVerified, @@ -8442,7 +8452,7 @@ var Services = map[string]Service{ "UpdateReputationEntityCustomerManagedStatus": TierHandVerified, "UpdateReputationEntityPolicy": TierHandVerified, }}, - "sfn": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "sfn": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateActivity": TierHandVerified, "CreateStateMachine": TierHandVerified, "CreateStateMachineAlias": TierHandVerified, @@ -8481,7 +8491,7 @@ var Services = map[string]Service{ "UpdateStateMachineAlias": TierHandVerified, "ValidateStateMachineDefinition": TierHandVerified, }}, - "shield": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "shield": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateDRTLogBucket": TierHandVerified, "AssociateDRTRole": TierHandVerified, "AssociateHealthCheck": TierHandVerified, @@ -8519,7 +8529,7 @@ var Services = map[string]Service{ "UpdateProtectionGroup": TierHandVerified, "UpdateSubscription": TierHandVerified, }}, - "sns": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "sns": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AddPermission": TierHandVerified, "CheckIfPhoneNumberIsOptedOut": TierHandVerified, "ConfirmSubscription": TierHandVerified, @@ -8563,7 +8573,7 @@ var Services = map[string]Service{ "UntagResource": TierHandVerified, "VerifySMSSandboxPhoneNumber": TierUnimplemented, }}, - "sqs": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "sqs": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddPermission": TierHandVerified, "CancelMessageMoveTask": TierHandVerified, "ChangeMessageVisibility": TierHandVerified, @@ -8588,7 +8598,7 @@ var Services = map[string]Service{ "TagQueue": TierHandVerified, "UntagQueue": TierHandVerified, }}, - "ssm": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ssm": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddTagsToResource": TierHandVerified, "AssociateOpsItemRelatedItem": TierUnimplemented, "CancelCommand": TierUnimplemented, @@ -8736,7 +8746,7 @@ var Services = map[string]Service{ "UpdateResourceDataSync": TierAutoCRUD, "UpdateServiceSetting": TierAutoCRUD, }}, - "ssoadmin": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "ssoadmin": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddRegion": TierHandVerified, "AttachCustomerManagedPolicyReferenceToPermissionSet": TierHandVerified, "AttachManagedPolicyToPermissionSet": TierHandVerified, @@ -8817,7 +8827,7 @@ var Services = map[string]Service{ "UpdatePermissionSet": TierHandVerified, "UpdateTrustedTokenIssuer": TierHandVerified, }}, - "sts": {Protocol: "query", ModelBacked: true, Operations: map[string]Tier{ + "sts": {Protocol: "query", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "AssumeRole": TierHandVerified, "AssumeRoleWithSAML": TierUnimplemented, "AssumeRoleWithWebIdentity": TierUnimplemented, @@ -8830,7 +8840,7 @@ var Services = map[string]Service{ "GetSessionToken": TierHandVerified, "GetWebIdentityToken": TierUnimplemented, }}, - "support": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "support": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AddAttachmentsToSet": TierHandVerified, "AddCommunicationToCase": TierHandVerified, "CreateCase": TierHandVerified, @@ -8875,7 +8885,7 @@ var Services = map[string]Service{ "UpdateCaseAttributes": TierHandVerified, "UpdateSupportPlan": TierHandVerified, }}, - "swf": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "swf": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CountClosedWorkflowExecutions": TierHandVerified, "CountOpenWorkflowExecutions": TierHandVerified, "CountPendingActivityTasks": TierHandVerified, @@ -8916,7 +8926,7 @@ var Services = map[string]Service{ "UndeprecateWorkflowType": TierHandVerified, "UntagResource": TierHandVerified, }}, - "textract": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "textract": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AnalyzeDocument": TierHandVerified, "AnalyzeExpense": TierHandVerified, "AnalyzeID": TierHandVerified, @@ -8964,7 +8974,7 @@ var Services = map[string]Service{ "UntagResource": TierHandVerified, "UpdateAdapter": TierHandVerified, }}, - "timestreamwrite": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "timestreamwrite": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateBatchLoadTask": TierHandVerified, "CreateDatabase": TierHandVerified, "CreateTable": TierHandVerified, @@ -8985,7 +8995,7 @@ var Services = map[string]Service{ "UpdateTable": TierHandVerified, "WriteRecords": TierHandVerified, }}, - "transcribe": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "transcribe": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateCallAnalyticsCategory": TierHandVerified, "CreateLanguageModel": TierHandVerified, "CreateMedicalVocabulary": TierHandVerified, @@ -9030,14 +9040,14 @@ var Services = map[string]Service{ "UpdateVocabulary": TierHandVerified, "UpdateVocabularyFilter": TierHandVerified, }}, - "transcribestreaming": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ - "GetMedicalScribeStream": TierUnimplemented, + "transcribestreaming": {Protocol: "rest-json", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ + "GetMedicalScribeStream": TierAutoCRUD, "StartCallAnalyticsStreamTranscription": TierUnimplemented, "StartMedicalScribeStream": TierUnimplemented, "StartMedicalStreamTranscription": TierUnimplemented, "StartStreamTranscription": TierUnimplemented, }}, - "transfer": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "transfer": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateAccess": TierHandVerified, "CreateAgreement": TierAutoCRUD, "CreateConnector": TierAutoCRUD, @@ -9110,7 +9120,7 @@ var Services = map[string]Service{ "UpdateWebApp": TierAutoCRUD, "UpdateWebAppCustomization": TierAutoCRUD, }}, - "translate": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "translate": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateParallelData": TierAutoCRUD, "DeleteParallelData": TierAutoCRUD, "DeleteTerminology": TierAutoCRUD, @@ -9131,7 +9141,7 @@ var Services = map[string]Service{ "UntagResource": TierAutoCRUD, "UpdateParallelData": TierAutoCRUD, }}, - "verifiedpermissions": {Protocol: "", ModelBacked: false, Operations: map[string]Tier{ + "verifiedpermissions": {Protocol: "", ModelBacked: false, EngineWired: false, Operations: map[string]Tier{ "BatchEvaluatePermissions": TierHandVerified, "BatchGetEntityRelationship": TierHandVerified, "CreateEntityRelationship": TierHandVerified, @@ -9169,7 +9179,7 @@ var Services = map[string]Service{ "PutPolicyTemplate": TierHandVerified, "PutSchema": TierHandVerified, }}, - "voiceid": {Protocol: "json-1.0", ModelBacked: true, Operations: map[string]Tier{ + "voiceid": {Protocol: "json-1.0", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateFraudster": TierUnimplemented, "CreateDomain": TierAutoCRUD, "CreateWatchlist": TierAutoCRUD, @@ -9200,7 +9210,7 @@ var Services = map[string]Service{ "UpdateDomain": TierAutoCRUD, "UpdateWatchlist": TierAutoCRUD, }}, - "waf": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "waf": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "CreateByteMatchSet": TierHandVerified, "CreateGeoMatchSet": TierHandVerified, "CreateIPSet": TierHandVerified, @@ -9279,7 +9289,7 @@ var Services = map[string]Service{ "UpdateWebACL": TierHandVerified, "UpdateXssMatchSet": TierHandVerified, }}, - "wafv2": {Protocol: "json-1.1", ModelBacked: true, Operations: map[string]Tier{ + "wafv2": {Protocol: "json-1.1", ModelBacked: true, EngineWired: true, Operations: map[string]Tier{ "AssociateWebACL": TierHandVerified, "CheckCapacity": TierHandVerified, "CreateAPIKey": TierHandVerified, @@ -9336,7 +9346,7 @@ var Services = map[string]Service{ "UpdateRuleGroup": TierHandVerified, "UpdateWebACL": TierHandVerified, }}, - "xray": {Protocol: "rest-json", ModelBacked: true, Operations: map[string]Tier{ + "xray": {Protocol: "rest-json", ModelBacked: true, EngineWired: false, Operations: map[string]Tier{ "BatchGetTraces": TierHandVerified, "CancelTraceRetrieval": TierUnimplemented, "CreateGroup": TierHandVerified, diff --git a/internal/shared/crud/crud.go b/internal/shared/crud/crud.go index df47d8f7..c0887795 100644 --- a/internal/shared/crud/crud.go +++ b/internal/shared/crud/crud.go @@ -17,9 +17,13 @@ import ( "encoding/json" "errors" "maps" + "net/url" + "sort" "strings" "sync" "time" + + "github.com/skyoo2003/devcloud/internal/shared/httproute" ) // ErrUnclassified means the engine has no CRUD handling for this operation; the @@ -33,6 +37,26 @@ type OpMeta struct { Resource string // singular resource key, e.g. "Database" OutputListKey string // output member holding the collection (List ops) OutputItemKey string // output member wrapping a single resource ("" = flat echo) + + // Method and URI are the operation's REST binding, empty for a service + // whose protocol has none. They are what lets the engine serve rest-json: + // that protocol puts the operation in the method and path instead of in an + // X-Amz-Target header, so without them there is nothing to classify. + Method string // e.g. "GET" + URI string // e.g. "/v1/graphs/{GraphName}" +} + +// Call is one request the engine may be asked to serve, in protocol-neutral +// terms. The JSON protocols name the operation in a header, so they set Op; the +// REST protocols put it in the method and path, so they set Method and URI and +// leave Op empty. +type Call struct { + Service string + Protocol string + Op string + Method string + URI string + Body []byte } // Result is a protocol-agnostic response the caller maps onto its transport. @@ -42,11 +66,18 @@ type Result struct { ContentType string } -const jsonContentType = "application/x-amz-json-1.1" +const ( + jsonContentType = "application/x-amz-json-1.1" + restJSONType = "application/json" + + protocolJSON10 = "json-1.0" + protocolRESTJSON = "rest-json" +) var ( mu sync.RWMutex registry = map[string]map[string]OpMeta{} // service -> op -> meta + routes = map[string][]httproute.Route{} // service -> REST routes, sorted by operation store = map[string]map[string]map[string]any{} // "service|resource" -> id -> doc ) @@ -56,6 +87,21 @@ func Register(service string, ops map[string]OpMeta) { mu.Lock() defer mu.Unlock() registry[service] = ops + + // Build the REST route table alongside the op map. Sorted by operation + // name because Go map iteration is randomised, and httproute.Match takes + // the first route that fits within a specificity pass — an unsorted table + // would make routing differ between runs of the same binary. The order + // mirrors what codegen emits for the generated per-service routers. + rs := make([]httproute.Route, 0, len(ops)) + for op, m := range ops { + if m.URI == "" { + continue + } + rs = append(rs, httproute.Route{Method: m.Method, Pattern: m.URI, Operation: op}) + } + sort.Slice(rs, func(i, j int) bool { return rs[i].Operation < rs[j].Operation }) + routes[service] = rs } // RegisteredOps returns the operation metadata registered for a service. @@ -65,46 +111,116 @@ func RegisteredOps(service string) map[string]OpMeta { return registry[service] } -// JSONProtocol reports whether the engine can serve requests for a protocol. -// Only the X-Amz-Target JSON protocols carry an operation name at the router, -// which the engine needs to classify. +// JSONProtocol reports whether a protocol carries the operation name in an +// X-Amz-Target header. It says nothing about whether the engine can serve the +// protocol — use Servable for that. func JSONProtocol(protocol string) bool { return strings.HasPrefix(protocol, "json") } -// Handle attempts to serve op for service from its request body. It returns -// ErrUnclassified when the operation is unknown or not CRUD-shaped. -func Handle(service, op, protocol string, body []byte) (*Result, error) { - if !JSONProtocol(protocol) { +// Servable reports whether the engine can serve requests for a protocol. +// +// The JSON protocols carry the operation name in a header. rest-json does not, +// but its model binds every operation to a method and URI template, which the +// route table turns back into an operation name. query and rest-xml have +// neither, so a request for one of them cannot be classified at all and is +// declined rather than guessed at. +func Servable(protocol string) bool { + return JSONProtocol(protocol) || protocol == protocolRESTJSON +} + +// Handle attempts to serve a call from the service's registered operations. It +// returns ErrUnclassified when the operation is unknown, not CRUD-shaped, or +// carried by a protocol the engine cannot read — never a fabricated success. +func Handle(c Call) (*Result, error) { + op := c.Op + var labels httproute.Params + rest := false + + switch { + case JSONProtocol(c.Protocol): + // The operation name arrived in X-Amz-Target; nothing to resolve. + case c.Protocol == protocolRESTJSON: + rest = true + mu.RLock() + rs := routes[c.Service] + mu.RUnlock() + // A miss here is any of: unregistered service, an operation codegen + // refused to classify, or a path this service does not model. All + // three must decline — see docs/coverage.md on why a registered + // service must never fabricate a success. + if op, labels = httproute.Match(rs, c.Method, c.URI); op == "" { + return nil, ErrUnclassified + } + default: return nil, ErrUnclassified } + mu.RLock() - m, ok := registry[service][op] + m, ok := registry[c.Service][op] mu.RUnlock() if !ok || m.Verb == "" { return nil, ErrUnclassified } - var params map[string]any - if len(body) > 0 { - if err := json.Unmarshal(body, ¶ms); err != nil { + params := map[string]any{} + // Three sources, least authoritative first: httpQuery values, then the + // JSON body, then the path labels — the URI is what addresses the + // resource, so it wins. A restJson1 model never binds one member to two of + // these, so real SDK traffic never exercises the precedence; it is here so + // a hand-rolled request cannot redirect a lookup from the body. + if rest { + maps.Copy(params, queryParams(c.URI)) + } + if len(c.Body) > 0 { + var body map[string]any + if err := json.Unmarshal(c.Body, &body); err != nil { // Malformed body: real services reject with SerializationException // rather than fabricating a success from empty params. - return withContentType(serializationError(), protocol), nil + return withContentType(serializationError(), c.Protocol), nil } + maps.Copy(params, body) + } + for k, v := range labels { + params[k] = v + } + + res, err := dispatch(c.Service, m, params) + return withContentType(res, c.Protocol), err +} + +// queryParams reads the request URI's query string as engine parameters. A +// repeated key keeps its first value: the engine has no list-valued parameter, +// and dropping the key entirely would lose a resource identifier. +func queryParams(uri string) map[string]any { + _, query, found := strings.Cut(uri, "?") + if !found || query == "" { + return nil } - if params == nil { - params = map[string]any{} + // ParseQuery returns what it could parse alongside any error, so a + // malformed tail cannot discard the terms before it. + values, _ := url.ParseQuery(query) + out := make(map[string]any, len(values)) + for k, vs := range values { + if len(vs) > 0 { + out[k] = vs[0] + } } - res, err := dispatch(service, m, params) - return withContentType(res, protocol), err + return out } -// withContentType stamps the protocol-appropriate amz-json version so a json-1.0 -// service is not served a 1.1 content type. dispatch/okJSON default to 1.1. +// withContentType stamps the protocol-appropriate content type so a json-1.0 +// service is not served a 1.1 one, and a rest-json service is not served an +// X-Amz-Target type it never uses. dispatch/okJSON default to amz-json 1.1. func withContentType(res *Result, protocol string) *Result { - if res != nil && protocol == "json-1.0" { + if res == nil { + return res + } + switch protocol { + case protocolJSON10: res.ContentType = "application/x-amz-json-1.0" + case protocolRESTJSON: + res.ContentType = restJSONType } return res } diff --git a/internal/shared/crud/crud_test.go b/internal/shared/crud/crud_test.go index 9a4a5d1b..f90d5429 100644 --- a/internal/shared/crud/crud_test.go +++ b/internal/shared/crud/crud_test.go @@ -11,7 +11,7 @@ import ( func handleJSON(t *testing.T, service, op string, params map[string]any) (*Result, error) { t.Helper() body, _ := json.Marshal(params) - return Handle(service, op, "json-1.1", body) + return Handle(Call{Service: service, Protocol: "json-1.1", Op: op, Body: body}) } func decode(t *testing.T, r *Result) map[string]any { @@ -86,7 +86,7 @@ func TestEngineUnclassified(t *testing.T) { if _, err := handleJSON(t, svc, "SomeCustomOp", nil); err != ErrUnclassified { t.Fatalf("unknown op: want ErrUnclassified, got %v", err) } - if _, err := Handle(svc, "CreateWidget", "query", []byte("{}")); err != ErrUnclassified { + if _, err := Handle(Call{Service: svc, Protocol: "query", Op: "CreateWidget", Body: []byte("{}")}); err != ErrUnclassified { t.Fatalf("non-json protocol: want ErrUnclassified, got %v", err) } if _, err := handleJSON(t, "unregistered", "CreateThing", nil); err != ErrUnclassified { @@ -110,7 +110,7 @@ func TestEngineConcurrentAccess(t *testing.T) { do := func(op string, params map[string]any) { body, _ := json.Marshal(params) - if _, err := Handle(svc, op, "json-1.1", body); err != nil { + if _, err := Handle(Call{Service: svc, Protocol: "json-1.1", Op: op, Body: body}); err != nil { t.Errorf("%s: %v", op, err) } } @@ -125,6 +125,193 @@ func TestEngineConcurrentAccess(t *testing.T) { wg.Wait() } +// --- rest-json --- + +func handleREST(t *testing.T, service, method, uri string, params map[string]any) (*Result, error) { + t.Helper() + var body []byte + if params != nil { + body, _ = json.Marshal(params) + } + return Handle(Call{Service: service, Protocol: "rest-json", Method: method, URI: uri, Body: body}) +} + +// TestEngineRESTJSONRoundTrip is the whole point of teaching the engine +// rest-json: the operation name is not in a header, so it has to come from the +// method and path, and the resource identifier has to come from the path label +// rather than the body. +func TestEngineRESTJSONRoundTrip(t *testing.T) { + const svc = "restsvc" + Register(svc, map[string]OpMeta{ + "CreateGraph": {Verb: "Create", Resource: "Graph", OutputItemKey: "Graph", + Method: "POST", URI: "/v1/graphs"}, + "GetGraph": {Verb: "Get", Resource: "Graph", OutputItemKey: "Graph", + Method: "GET", URI: "/v1/graphs/{GraphName}"}, + "ListGraphs": {Verb: "List", Resource: "Graph", OutputListKey: "Graphs", + Method: "GET", URI: "/v1/graphs"}, + "DeleteGraph": {Verb: "Delete", Resource: "Graph", + Method: "DELETE", URI: "/v1/graphs/{GraphName}"}, + }) + + // An empty store lists cleanly rather than erroring — the parameterless + // read every compat smoke test performs. + r, err := handleREST(t, svc, "GET", "/v1/graphs", nil) + if err != nil || r.Status != 200 { + t.Fatalf("list on empty store: status=%d err=%v", statusOf(r), err) + } + if got := decode(t, r)["Graphs"].([]any); len(got) != 0 { + t.Fatalf("empty store listed %d graphs", len(got)) + } + + // Create takes its parameters from the body. + r, err = handleREST(t, svc, "POST", "/v1/graphs", map[string]any{"GraphName": "g1", "Tier": "small"}) + if err != nil || r.Status != 200 { + t.Fatalf("create: status=%d err=%v", statusOf(r), err) + } + graph := decode(t, r)["Graph"].(map[string]any) + if graph["GraphName"] != "g1" || graph["Tier"] != "small" { + t.Fatalf("create echo wrong: %v", graph) + } + + // Get takes its identifier from the path label, with no body at all. This + // is the case a JSON-only engine could never serve. + r, err = handleREST(t, svc, "GET", "/v1/graphs/g1", nil) + if err != nil || r.Status != 200 { + t.Fatalf("get by path label: status=%d err=%v", statusOf(r), err) + } + if got := decode(t, r)["Graph"].(map[string]any); got["Tier"] != "small" { + t.Fatalf("get returned the wrong resource: %v", got) + } + + // Delete, also addressed by path label, and the list goes back to empty. + if _, err := handleREST(t, svc, "DELETE", "/v1/graphs/g1", nil); err != nil { + t.Fatalf("delete: %v", err) + } + r, _ = handleREST(t, svc, "GET", "/v1/graphs", nil) + if got := decode(t, r)["Graphs"].([]any); len(got) != 0 { + t.Fatalf("after delete, list returned %d graphs", len(got)) + } +} + +// TestEngineRESTJSONContentType guards against serving a rest-json caller the +// X-Amz-Target content type. botocore parses the body by the modelled protocol, +// but an amz-json content type on a REST response is wrong on the wire and +// misleads anyone reading a capture. +func TestEngineRESTJSONContentType(t *testing.T) { + const svc = "ctsvc" + Register(svc, map[string]OpMeta{ + "ListThings": {Verb: "List", Resource: "CtThing", OutputListKey: "Things", + Method: "GET", URI: "/things"}, + }) + + r, err := handleREST(t, svc, "GET", "/things", nil) + if err != nil { + t.Fatalf("list: %v", err) + } + if r.ContentType != "application/json" { + t.Errorf("ContentType = %q, want application/json", r.ContentType) + } +} + +// TestEngineRESTJSONPathLabelWinsOverBody pins which source of a parameter is +// authoritative. A restJson1 model never binds one member to both the URI and +// the body, so real SDK traffic cannot hit this — but the URI is what addresses +// the resource, so a request that does carry both must not be able to redirect +// the lookup from the body. +func TestEngineRESTJSONPathLabelWinsOverBody(t *testing.T) { + const svc = "authsvc" + Register(svc, map[string]OpMeta{ + "CreateItem": {Verb: "Create", Resource: "AItem", OutputItemKey: "Item", + Method: "POST", URI: "/items"}, + "UpdateItem": {Verb: "Update", Resource: "AItem", OutputItemKey: "Item", + Method: "PUT", URI: "/items/{AItemName}"}, + }) + + if _, err := handleREST(t, svc, "POST", "/items", map[string]any{"AItemName": "real"}); err != nil { + t.Fatalf("create: %v", err) + } + + r, err := handleREST(t, svc, "PUT", "/items/real", + map[string]any{"AItemName": "spoofed", "Colour": "blue"}) + if err != nil { + t.Fatalf("update: %v", err) + } + if got := decode(t, r)["Item"].(map[string]any); got["AItemName"] != "real" { + t.Errorf("body overrode the path label: AItemName = %v, want real", got["AItemName"]) + } +} + +// TestEngineRESTJSONQueryParams covers the third parameter source: values the +// model binds with httpQuery rather than into the body. +func TestEngineRESTJSONQueryParams(t *testing.T) { + const svc = "qsvc" + Register(svc, map[string]OpMeta{ + "CreateQThing": {Verb: "Create", Resource: "QThing", OutputItemKey: "Thing", + Method: "POST", URI: "/qthings"}, + }) + + r, err := handleREST(t, svc, "POST", "/qthings?QThingName=fromquery", nil) + if err != nil { + t.Fatalf("create: %v", err) + } + if got := decode(t, r)["Thing"].(map[string]any); got["QThingName"] != "fromquery" { + t.Errorf("query parameter ignored: %v", got) + } +} + +// TestEngineRESTJSONUnmatchedPathIsUnclassified is the guarantee the whole +// coverage claim rests on. A path the route table does not know must decline, +// never fabricate an empty success — see docs/coverage.md. +func TestEngineRESTJSONUnmatchedPathIsUnclassified(t *testing.T) { + const svc = "misssvc" + Register(svc, map[string]OpMeta{ + "ListThings": {Verb: "List", Resource: "MThing", OutputListKey: "Things", + Method: "GET", URI: "/things"}, + }) + + if _, err := handleREST(t, svc, "GET", "/not/a/known/path", nil); err != ErrUnclassified { + t.Errorf("unknown path: want ErrUnclassified, got %v", err) + } + if _, err := handleREST(t, svc, "POST", "/things", nil); err != ErrUnclassified { + t.Errorf("known path, wrong method: want ErrUnclassified, got %v", err) + } + if _, err := handleREST(t, "unregistered", "GET", "/things", nil); err != ErrUnclassified { + t.Errorf("unregistered service: want ErrUnclassified, got %v", err) + } +} + +// TestEngineRESTJSONUnroutedOperationIsUnclassified covers the operation that is +// reachable by path but not CRUD-shaped. codegen omits it from the registry, so +// it has no route, and the caller must get a clean error. +func TestEngineRESTJSONUnroutedOperationIsUnclassified(t *testing.T) { + const svc = "execsvc" + // Modelled on rds-data: every operation is a verb the classifier refuses, + // so nothing registers and nothing routes. + Register(svc, map[string]OpMeta{}) + + if _, err := handleREST(t, svc, "POST", "/Execute", nil); err != ErrUnclassified { + t.Errorf("want ErrUnclassified, got %v", err) + } +} + +// TestEngineRESTXMLStillDeclines pins the boundary. rest-xml and query carry no +// route table into the engine, and admitting them would serve S3 traffic from +// the generic store. +func TestEngineRESTXMLStillDeclines(t *testing.T) { + const svc = "xmlsvc" + Register(svc, map[string]OpMeta{ + "ListThings": {Verb: "List", Resource: "XThing", OutputListKey: "Things", + Method: "GET", URI: "/things"}, + }) + + for _, proto := range []string{"rest-xml", "query"} { + _, err := Handle(Call{Service: svc, Protocol: proto, Method: "GET", URI: "/things"}) + if err != ErrUnclassified { + t.Errorf("%s: want ErrUnclassified, got %v", proto, err) + } + } +} + func statusOf(r *Result) int { if r == nil { return 0 diff --git a/tests/compatibility/test_service_smoke.py b/tests/compatibility/test_service_smoke.py index c77bde01..af517749 100644 --- a/tests/compatibility/test_service_smoke.py +++ b/tests/compatibility/test_service_smoke.py @@ -19,11 +19,19 @@ # name is the point: the test asserts what a user typing it actually gets. # # Services whose coverage comes from the generic CRUD engine rather than a -# hand-written provider. The engine only serves the awsJson1_0 / awsJson1_1 -# protocols, which carry the operation name in X-Amz-Target; a rest-json, -# query, or rest-xml service cannot be listed here and be served. +# hand-written provider. The engine serves the awsJson1_0 / awsJson1_1 +# protocols, which carry the operation name in X-Amz-Target, and rest-json, +# whose operation is recovered from the request method and path via the model's +# route table. A query or rest-xml service cannot be listed here and be served. ENGINE_SERVED_SERVICES = [ "comprehend", + # rest-json, and the proof the engine reaches that protocol at all. All + # three sat in REGISTERED_ONLY_SERVICES until the engine learned to resolve + # an operation from the method and path; nothing about these three services + # changed, only what the engine can read. + "polly", + "qbusiness", + "codeguru-reviewer", # rekognition could not be onboarded at all before the alias table was # derived from the models: its X-Amz-Target prefix is RekognitionService, # which no hand-written gateway clause covered, so every call came back @@ -55,12 +63,19 @@ # never a fabricated success, and never an unrouted UnknownService, which would # send a caller back to real AWS. They are deliberately NOT counted as covered; # see docs/coverage.md. +# rest-json, so the engine can now read its requests — and still served by +# nothing, because it has no CRUD-shaped operation to classify. InvokeEndpoint, +# InvokeEndpointAsync and InvokeEndpointWithResponseStream are not +# Create/Get/List/Delete/Update, so codegen registers nothing and there is no +# route to match. Same case as forecastquery; see docs/coverage.md. +# +# personalize-runtime left this list when the engine gained rest-json: +# GetRecommendations classifies as a Get, so it is served now. It is not in +# ENGINE_SERVED_SERVICES either, because both its operations take required +# parameters and this harness has no parameterless read to prove it with — the +# fidelity manifest is its record, as for bedrock-data-automation-runtime. REGISTERED_ONLY_SERVICES = [ - "polly", - "qbusiness", "sagemaker-runtime", - "personalize-runtime", - "codeguru-reviewer", ]