feat(cmd/api): expose cache and i18n spec flags
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
5c067b3dae
commit
814c1b6233
4 changed files with 206 additions and 20 deletions
|
|
@ -39,6 +39,12 @@ func addSDKCommand(parent *cli.Command) {
|
|||
wsPath string
|
||||
pprofEnabled bool
|
||||
expvarEnabled bool
|
||||
cacheEnabled bool
|
||||
cacheTTL string
|
||||
cacheMaxEntries int
|
||||
cacheMaxBytes int
|
||||
i18nDefaultLocale string
|
||||
i18nSupportedLocales string
|
||||
termsURL string
|
||||
contactName string
|
||||
contactURL string
|
||||
|
|
@ -84,6 +90,12 @@ func addSDKCommand(parent *cli.Command) {
|
|||
wsPath: wsPath,
|
||||
pprofEnabled: pprofEnabled,
|
||||
expvarEnabled: expvarEnabled,
|
||||
cacheEnabled: cacheEnabled,
|
||||
cacheTTL: cacheTTL,
|
||||
cacheMaxEntries: cacheMaxEntries,
|
||||
cacheMaxBytes: cacheMaxBytes,
|
||||
i18nDefaultLocale: i18nDefaultLocale,
|
||||
i18nSupportedLocales: i18nSupportedLocales,
|
||||
termsURL: termsURL,
|
||||
contactName: contactName,
|
||||
contactURL: contactURL,
|
||||
|
|
@ -146,6 +158,12 @@ func addSDKCommand(parent *cli.Command) {
|
|||
cli.StringFlag(cmd, &wsPath, "ws-path", "", "", "WebSocket endpoint path in generated spec")
|
||||
cli.BoolFlag(cmd, &pprofEnabled, "pprof", "", false, "Include pprof endpoints in generated spec")
|
||||
cli.BoolFlag(cmd, &expvarEnabled, "expvar", "", false, "Include expvar endpoint in generated spec")
|
||||
cli.BoolFlag(cmd, &cacheEnabled, "cache", "", false, "Include cache metadata in generated spec")
|
||||
cli.StringFlag(cmd, &cacheTTL, "cache-ttl", "", "", "Cache TTL in generated spec")
|
||||
cli.IntFlag(cmd, &cacheMaxEntries, "cache-max-entries", "", 0, "Cache max entries in generated spec")
|
||||
cli.IntFlag(cmd, &cacheMaxBytes, "cache-max-bytes", "", 0, "Cache max bytes in generated spec")
|
||||
cli.StringFlag(cmd, &i18nDefaultLocale, "i18n-default-locale", "", "", "Default locale in generated spec")
|
||||
cli.StringFlag(cmd, &i18nSupportedLocales, "i18n-supported-locales", "", "", "Comma-separated supported locales in generated spec")
|
||||
cli.StringFlag(cmd, &termsURL, "terms-of-service", "", "", "OpenAPI terms of service URL in generated spec")
|
||||
cli.StringFlag(cmd, &contactName, "contact-name", "", "", "OpenAPI contact name in generated spec")
|
||||
cli.StringFlag(cmd, &contactURL, "contact-url", "", "", "OpenAPI contact URL in generated spec")
|
||||
|
|
@ -173,6 +191,12 @@ func sdkSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) {
|
|||
wsPath: cfg.wsPath,
|
||||
pprofEnabled: cfg.pprofEnabled,
|
||||
expvarEnabled: cfg.expvarEnabled,
|
||||
cacheEnabled: cfg.cacheEnabled,
|
||||
cacheTTL: cfg.cacheTTL,
|
||||
cacheMaxEntries: cfg.cacheMaxEntries,
|
||||
cacheMaxBytes: cfg.cacheMaxBytes,
|
||||
i18nDefaultLocale: cfg.i18nDefaultLocale,
|
||||
i18nSupportedLocales: cfg.i18nSupportedLocales,
|
||||
termsURL: cfg.termsURL,
|
||||
contactName: cfg.contactName,
|
||||
contactURL: cfg.contactURL,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ func addSpecCommand(parent *cli.Command) {
|
|||
wsPath string
|
||||
pprofEnabled bool
|
||||
expvarEnabled bool
|
||||
cacheEnabled bool
|
||||
cacheTTL string
|
||||
cacheMaxEntries int
|
||||
cacheMaxBytes int
|
||||
i18nDefaultLocale string
|
||||
i18nSupportedLocales string
|
||||
termsURL string
|
||||
contactName string
|
||||
contactURL string
|
||||
|
|
@ -54,6 +60,12 @@ func addSpecCommand(parent *cli.Command) {
|
|||
wsPath: wsPath,
|
||||
pprofEnabled: pprofEnabled,
|
||||
expvarEnabled: expvarEnabled,
|
||||
cacheEnabled: cacheEnabled,
|
||||
cacheTTL: cacheTTL,
|
||||
cacheMaxEntries: cacheMaxEntries,
|
||||
cacheMaxBytes: cacheMaxBytes,
|
||||
i18nDefaultLocale: i18nDefaultLocale,
|
||||
i18nSupportedLocales: i18nSupportedLocales,
|
||||
termsURL: termsURL,
|
||||
contactName: contactName,
|
||||
contactURL: contactURL,
|
||||
|
|
@ -96,6 +108,12 @@ func addSpecCommand(parent *cli.Command) {
|
|||
cli.StringFlag(cmd, &wsPath, "ws-path", "", "", "WebSocket endpoint path in generated spec")
|
||||
cli.BoolFlag(cmd, &pprofEnabled, "pprof", "", false, "Include pprof endpoints in generated spec")
|
||||
cli.BoolFlag(cmd, &expvarEnabled, "expvar", "", false, "Include expvar endpoint in generated spec")
|
||||
cli.BoolFlag(cmd, &cacheEnabled, "cache", "", false, "Include cache metadata in generated spec")
|
||||
cli.StringFlag(cmd, &cacheTTL, "cache-ttl", "", "", "Cache TTL in generated spec")
|
||||
cli.IntFlag(cmd, &cacheMaxEntries, "cache-max-entries", "", 0, "Cache max entries in generated spec")
|
||||
cli.IntFlag(cmd, &cacheMaxBytes, "cache-max-bytes", "", 0, "Cache max bytes in generated spec")
|
||||
cli.StringFlag(cmd, &i18nDefaultLocale, "i18n-default-locale", "", "", "Default locale in generated spec")
|
||||
cli.StringFlag(cmd, &i18nSupportedLocales, "i18n-supported-locales", "", "", "Comma-separated supported locales in generated spec")
|
||||
cli.StringFlag(cmd, &termsURL, "terms-of-service", "", "", "OpenAPI terms of service URL in spec")
|
||||
cli.StringFlag(cmd, &contactName, "contact-name", "", "", "OpenAPI contact name in spec")
|
||||
cli.StringFlag(cmd, &contactURL, "contact-url", "", "", "OpenAPI contact URL in spec")
|
||||
|
|
|
|||
|
|
@ -115,6 +115,24 @@ func TestAPISpecCmd_Good_JSON(t *testing.T) {
|
|||
if specCmd.Flag("expvar") == nil {
|
||||
t.Fatal("expected --expvar flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("cache") == nil {
|
||||
t.Fatal("expected --cache flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("cache-ttl") == nil {
|
||||
t.Fatal("expected --cache-ttl flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("cache-max-entries") == nil {
|
||||
t.Fatal("expected --cache-max-entries flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("cache-max-bytes") == nil {
|
||||
t.Fatal("expected --cache-max-bytes flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("i18n-default-locale") == nil {
|
||||
t.Fatal("expected --i18n-default-locale flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("i18n-supported-locales") == nil {
|
||||
t.Fatal("expected --i18n-supported-locales flag on spec command")
|
||||
}
|
||||
if specCmd.Flag("terms-of-service") == nil {
|
||||
t.Fatal("expected --terms-of-service flag on spec command")
|
||||
}
|
||||
|
|
@ -216,6 +234,61 @@ func TestAPISpecCmd_Good_SummaryPopulatesSpecInfo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAPISpecCmd_Good_CacheAndI18nFlagsPopulateSpec(t *testing.T) {
|
||||
root := &cli.Command{Use: "root"}
|
||||
AddAPICommands(root)
|
||||
|
||||
outputFile := t.TempDir() + "/spec.json"
|
||||
root.SetArgs([]string{
|
||||
"api", "spec",
|
||||
"--cache",
|
||||
"--cache-ttl", "5m0s",
|
||||
"--cache-max-entries", "42",
|
||||
"--cache-max-bytes", "8192",
|
||||
"--i18n-default-locale", "en-GB",
|
||||
"--i18n-supported-locales", "en-GB,fr,en-GB",
|
||||
"--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-cache-enabled"]; got != true {
|
||||
t.Fatalf("expected x-cache-enabled=true, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-ttl"]; got != "5m0s" {
|
||||
t.Fatalf("expected x-cache-ttl=5m0s, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-max-entries"]; got != float64(42) {
|
||||
t.Fatalf("expected x-cache-max-entries=42, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-max-bytes"]; got != float64(8192) {
|
||||
t.Fatalf("expected x-cache-max-bytes=8192, got %v", got)
|
||||
}
|
||||
if got := spec["x-i18n-default-locale"]; got != "en-GB" {
|
||||
t.Fatalf("expected x-i18n-default-locale=en-GB, got %v", got)
|
||||
}
|
||||
locales, ok := spec["x-i18n-supported-locales"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("expected x-i18n-supported-locales array, got %T", spec["x-i18n-supported-locales"])
|
||||
}
|
||||
if len(locales) != 2 || locales[0] != "en-GB" || locales[1] != "fr" {
|
||||
t.Fatalf("expected supported locales [en-GB fr], got %v", locales)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPISpecCmd_Good_GraphQLPlaygroundFlagPopulatesSpecPaths(t *testing.T) {
|
||||
root := &cli.Command{Use: "root"}
|
||||
AddAPICommands(root)
|
||||
|
|
@ -758,6 +831,24 @@ func TestAPISDKCmd_Good_ValidatesLanguage(t *testing.T) {
|
|||
if sdkCmd.Flag("expvar") == nil {
|
||||
t.Fatal("expected --expvar flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("cache") == nil {
|
||||
t.Fatal("expected --cache flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("cache-ttl") == nil {
|
||||
t.Fatal("expected --cache-ttl flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("cache-max-entries") == nil {
|
||||
t.Fatal("expected --cache-max-entries flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("cache-max-bytes") == nil {
|
||||
t.Fatal("expected --cache-max-bytes flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("i18n-default-locale") == nil {
|
||||
t.Fatal("expected --i18n-default-locale flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("i18n-supported-locales") == nil {
|
||||
t.Fatal("expected --i18n-supported-locales flag on sdk command")
|
||||
}
|
||||
if sdkCmd.Flag("terms-of-service") == nil {
|
||||
t.Fatal("expected --terms-of-service flag on sdk command")
|
||||
}
|
||||
|
|
@ -795,25 +886,31 @@ func TestAPISDKCmd_Good_TempSpecUsesMetadataFlags(t *testing.T) {
|
|||
api.RegisterSpecGroups(specCmdStubGroup{})
|
||||
|
||||
builder, err := sdkSpecBuilder(specBuilderConfig{
|
||||
title: "Custom SDK API",
|
||||
summary: "Custom SDK overview",
|
||||
description: "Custom SDK description",
|
||||
version: "9.9.9",
|
||||
swaggerPath: "/docs",
|
||||
graphqlPath: "/gql",
|
||||
graphqlPlayground: true,
|
||||
ssePath: "/events",
|
||||
wsPath: "/ws",
|
||||
pprofEnabled: true,
|
||||
expvarEnabled: true,
|
||||
termsURL: "https://example.com/terms",
|
||||
contactName: "SDK Support",
|
||||
contactURL: "https://example.com/support",
|
||||
contactEmail: "support@example.com",
|
||||
licenseName: "EUPL-1.2",
|
||||
licenseURL: "https://eupl.eu/1.2/en/",
|
||||
servers: "https://api.example.com, /, https://api.example.com",
|
||||
securitySchemes: `{"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}}`,
|
||||
title: "Custom SDK API",
|
||||
summary: "Custom SDK overview",
|
||||
description: "Custom SDK description",
|
||||
version: "9.9.9",
|
||||
swaggerPath: "/docs",
|
||||
graphqlPath: "/gql",
|
||||
graphqlPlayground: true,
|
||||
ssePath: "/events",
|
||||
wsPath: "/ws",
|
||||
pprofEnabled: true,
|
||||
expvarEnabled: true,
|
||||
cacheEnabled: true,
|
||||
cacheTTL: "5m0s",
|
||||
cacheMaxEntries: 42,
|
||||
cacheMaxBytes: 8192,
|
||||
i18nDefaultLocale: "en-GB",
|
||||
i18nSupportedLocales: "en-GB,fr,en-GB",
|
||||
termsURL: "https://example.com/terms",
|
||||
contactName: "SDK Support",
|
||||
contactURL: "https://example.com/support",
|
||||
contactEmail: "support@example.com",
|
||||
licenseName: "EUPL-1.2",
|
||||
licenseURL: "https://eupl.eu/1.2/en/",
|
||||
servers: "https://api.example.com, /, https://api.example.com",
|
||||
securitySchemes: `{"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}}`,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error building sdk spec: %v", err)
|
||||
|
|
@ -878,6 +975,29 @@ func TestAPISDKCmd_Good_TempSpecUsesMetadataFlags(t *testing.T) {
|
|||
t.Fatal("expected expvar path to be included in generated spec")
|
||||
}
|
||||
|
||||
if got := spec["x-cache-enabled"]; got != true {
|
||||
t.Fatalf("expected x-cache-enabled=true, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-ttl"]; got != "5m0s" {
|
||||
t.Fatalf("expected x-cache-ttl=5m0s, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-max-entries"]; got != float64(42) {
|
||||
t.Fatalf("expected x-cache-max-entries=42, got %v", got)
|
||||
}
|
||||
if got := spec["x-cache-max-bytes"]; got != float64(8192) {
|
||||
t.Fatalf("expected x-cache-max-bytes=8192, got %v", got)
|
||||
}
|
||||
if got := spec["x-i18n-default-locale"]; got != "en-GB" {
|
||||
t.Fatalf("expected x-i18n-default-locale=en-GB, got %v", got)
|
||||
}
|
||||
locales, ok := spec["x-i18n-supported-locales"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("expected x-i18n-supported-locales array, got %T", spec["x-i18n-supported-locales"])
|
||||
}
|
||||
if len(locales) != 2 || locales[0] != "en-GB" || locales[1] != "fr" {
|
||||
t.Fatalf("expected supported locales [en-GB fr], got %v", locales)
|
||||
}
|
||||
|
||||
if info["termsOfService"] != "https://example.com/terms" {
|
||||
t.Fatalf("expected termsOfService to be preserved, got %v", info["termsOfService"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
package api
|
||||
|
||||
import goapi "dappco.re/go/core/api"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
goapi "dappco.re/go/core/api"
|
||||
)
|
||||
|
||||
type specBuilderConfig struct {
|
||||
title string
|
||||
|
|
@ -16,6 +20,12 @@ type specBuilderConfig struct {
|
|||
wsPath string
|
||||
pprofEnabled bool
|
||||
expvarEnabled bool
|
||||
cacheEnabled bool
|
||||
cacheTTL string
|
||||
cacheMaxEntries int
|
||||
cacheMaxBytes int
|
||||
i18nDefaultLocale string
|
||||
i18nSupportedLocales string
|
||||
termsURL string
|
||||
contactName string
|
||||
contactURL string
|
||||
|
|
@ -41,6 +51,11 @@ func newSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) {
|
|||
WSPath: cfg.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),
|
||||
CacheMaxEntries: cfg.cacheMaxEntries,
|
||||
CacheMaxBytes: cfg.cacheMaxBytes,
|
||||
I18nDefaultLocale: strings.TrimSpace(cfg.i18nDefaultLocale),
|
||||
TermsOfService: cfg.termsURL,
|
||||
ContactName: cfg.contactName,
|
||||
ContactURL: cfg.contactURL,
|
||||
|
|
@ -52,6 +67,11 @@ func newSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) {
|
|||
ExternalDocsURL: cfg.externalDocsURL,
|
||||
}
|
||||
|
||||
builder.I18nSupportedLocales = parseLocales(cfg.i18nSupportedLocales)
|
||||
if builder.I18nDefaultLocale == "" && len(builder.I18nSupportedLocales) > 0 {
|
||||
builder.I18nDefaultLocale = "en"
|
||||
}
|
||||
|
||||
if cfg.securitySchemes != "" {
|
||||
schemes, err := parseSecuritySchemes(cfg.securitySchemes)
|
||||
if err != nil {
|
||||
|
|
@ -62,3 +82,7 @@ func newSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) {
|
|||
|
||||
return builder, nil
|
||||
}
|
||||
|
||||
func parseLocales(raw string) []string {
|
||||
return splitUniqueCSV(raw)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue