From ede71e2b1f020b49257893fb3eeb5ff7c8505b0a Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 12:56:59 +0000 Subject: [PATCH] feat(cmd/api): infer spec transport enablement from flags Co-Authored-By: Virgil --- cmd/api/cmd_test.go | 43 +++++++++++++++++++++++++++++++++++++++++ cmd/api/spec_builder.go | 22 +++++++++++++++------ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/cmd/api/cmd_test.go b/cmd/api/cmd_test.go index 8fadd18..33e4a56 100644 --- a/cmd/api/cmd_test.go +++ b/cmd/api/cmd_test.go @@ -325,6 +325,49 @@ func TestAPISpecCmd_Good_GraphQLPlaygroundFlagPopulatesSpecPaths(t *testing.T) { } } +func TestAPISpecCmd_Good_EnabledExtensionsFollowProvidedPaths(t *testing.T) { + root := &cli.Command{Use: "root"} + AddAPICommands(root) + + outputFile := t.TempDir() + "/spec.json" + root.SetArgs([]string{ + "api", "spec", + "--swagger-path", "/docs", + "--graphql-path", "/graphql", + "--ws-path", "/socket", + "--sse-path", "/events", + "--output", outputFile, + }) + root.SetErr(new(bytes.Buffer)) + + if err := root.Execute(); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + data, err := os.ReadFile(outputFile) + if err != nil { + t.Fatalf("expected spec file to be written: %v", err) + } + + var spec map[string]any + if err := json.Unmarshal(data, &spec); err != nil { + t.Fatalf("expected valid JSON spec, got error: %v", err) + } + + if got := spec["x-swagger-enabled"]; got != true { + t.Fatalf("expected x-swagger-enabled=true, got %v", got) + } + if got := spec["x-graphql-enabled"]; got != true { + t.Fatalf("expected x-graphql-enabled=true, got %v", got) + } + if got := spec["x-ws-enabled"]; got != true { + t.Fatalf("expected x-ws-enabled=true, got %v", got) + } + if got := spec["x-sse-enabled"]; got != true { + t.Fatalf("expected x-sse-enabled=true, got %v", got) + } +} + func TestAPISpecCmd_Good_ContactFlagsPopulateSpecInfo(t *testing.T) { root := &cli.Command{Use: "root"} AddAPICommands(root) diff --git a/cmd/api/spec_builder.go b/cmd/api/spec_builder.go index 6134543..b8785d7 100644 --- a/cmd/api/spec_builder.go +++ b/cmd/api/spec_builder.go @@ -39,20 +39,30 @@ type specBuilderConfig struct { } func newSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) { + swaggerPath := strings.TrimSpace(cfg.swaggerPath) + graphqlPath := strings.TrimSpace(cfg.graphqlPath) + ssePath := strings.TrimSpace(cfg.ssePath) + wsPath := strings.TrimSpace(cfg.wsPath) + cacheTTL := strings.TrimSpace(cfg.cacheTTL) + builder := &goapi.SpecBuilder{ Title: cfg.title, Summary: cfg.summary, Description: cfg.description, Version: cfg.version, - SwaggerPath: cfg.swaggerPath, - GraphQLPath: cfg.graphqlPath, + SwaggerEnabled: swaggerPath != "", + SwaggerPath: swaggerPath, + GraphQLEnabled: graphqlPath != "" || cfg.graphqlPlayground, + GraphQLPath: graphqlPath, GraphQLPlayground: cfg.graphqlPlayground, - SSEPath: cfg.ssePath, - WSPath: cfg.wsPath, + SSEEnabled: ssePath != "", + SSEPath: ssePath, + WSEnabled: wsPath != "", + WSPath: wsPath, PprofEnabled: cfg.pprofEnabled, ExpvarEnabled: cfg.expvarEnabled, - CacheEnabled: cfg.cacheEnabled || strings.TrimSpace(cfg.cacheTTL) != "" || cfg.cacheMaxEntries > 0 || cfg.cacheMaxBytes > 0, - CacheTTL: strings.TrimSpace(cfg.cacheTTL), + CacheEnabled: cfg.cacheEnabled || cacheTTL != "" || cfg.cacheMaxEntries > 0 || cfg.cacheMaxBytes > 0, + CacheTTL: cacheTTL, CacheMaxEntries: cfg.cacheMaxEntries, CacheMaxBytes: cfg.cacheMaxBytes, I18nDefaultLocale: strings.TrimSpace(cfg.i18nDefaultLocale),