From d592c71cb2bac3cf9f83c9eb5a69d66e28bfeddf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Mar 2026 11:07:26 +0000 Subject: [PATCH 1/4] chore(deps): update module github.com/oapi-codegen/runtime to v1.3.1 --- go.mod | 5 ++--- go.sum | 10 ++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 038eb22..81bcc05 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,9 @@ go 1.25.0 require ( github.com/JGLTechnologies/gin-rate-limit v1.5.6 github.com/emersion/go-smtp v0.24.0 - github.com/getkin/kin-openapi v0.133.0 github.com/gin-gonic/gin v1.12.0 github.com/google/uuid v1.6.0 - github.com/oapi-codegen/runtime v1.3.0 + github.com/oapi-codegen/runtime v1.3.1 golang.org/x/net v0.52.0 gorm.io/driver/postgres v1.6.0 gorm.io/driver/sqlite v1.6.0 @@ -16,7 +15,6 @@ require ( ) require ( - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect @@ -26,6 +24,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/gabriel-vasile/mimetype v1.4.12 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect diff --git a/go.sum b/go.sum index 10c9b72..073f0cf 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ github.com/JGLTechnologies/gin-rate-limit v1.5.6 h1:BrL2wXrF7SSqmB88YTGFVKMGVcjURMUeKqwQrlmzweI= github.com/JGLTechnologies/gin-rate-limit v1.5.6/go.mod h1:fwUuBegxLKm8+/4ST0zDFssRFTFaVZ7bH3ApK7iNZww= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -102,7 +98,6 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -132,8 +127,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= -github.com/oapi-codegen/runtime v1.3.0 h1:vyK1zc0gDWWXgk2xoQa4+X4RNNc5SL2RbTpJS/4vMYA= -github.com/oapi-codegen/runtime v1.3.0/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= +github.com/oapi-codegen/runtime v1.3.1 h1:RgDY6J4OGQLbRXhG/Xpt3vSVqYpHQS7hN4m85+5xB9g= +github.com/oapi-codegen/runtime v1.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -170,7 +165,6 @@ github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= From 7422f6ed0a5c1f4306d6656189683fbb03828d13 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 9 Apr 2026 17:46:08 +0700 Subject: [PATCH 2/4] Add paginated test history listing with disable option Add GET /tests endpoint returning lightweight test summaries (grade, score, domain, date) with pagination, using database-level JSON extraction to avoid loading full report blobs. The feature can be disabled with --disable-test-list flag. Frontend includes a new /tests/ page with table view and a conditional "History" navbar link. Fixes: https://github.com/happyDomain/happydeliver/issues/12 --- api/openapi.yaml | 93 ++++++++++ internal/api/handlers.go | 75 ++++++++ internal/config/cli.go | 1 + internal/config/config.go | 1 + internal/storage/storage.go | 51 ++++++ web/routes.go | 5 + web/src/lib/components/HistoryTable.svelte | 72 ++++++++ web/src/lib/components/index.ts | 1 + web/src/lib/stores/config.ts | 1 + web/src/routes/+layout.svelte | 12 +- web/src/routes/+page.svelte | 48 +++++- web/src/routes/history/+page.svelte | 189 +++++++++++++++++++++ 12 files changed, 546 insertions(+), 3 deletions(-) create mode 100644 web/src/lib/components/HistoryTable.svelte create mode 100644 web/src/routes/history/+page.svelte diff --git a/api/openapi.yaml b/api/openapi.yaml index 225e26c..ee56cff 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -76,6 +76,49 @@ paths: schema: $ref: '#/components/schemas/Error' + /tests: + get: + tags: + - tests + summary: List all tests + description: Returns a paginated list of test summaries with scores and grades. Can be disabled via server configuration. + operationId: listTests + parameters: + - name: offset + in: query + schema: + type: integer + minimum: 0 + default: 0 + description: Number of items to skip + - name: limit + in: query + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + description: Maximum number of items to return + responses: + '200': + description: List of test summaries + content: + application/json: + schema: + $ref: '#/components/schemas/TestListResponse' + '403': + description: Test listing is disabled + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /report/{id}: get: tags: @@ -1365,3 +1408,53 @@ components: items: $ref: '#/components/schemas/BlacklistCheck' description: List of DNS whitelist check results (informational only) + + TestSummary: + type: object + required: + - test_id + - score + - grade + - created_at + properties: + test_id: + type: string + pattern: '^[a-z0-9-]+$' + description: Test identifier (base32-encoded with hyphens) + score: + type: integer + minimum: 0 + maximum: 100 + description: Overall deliverability score (0-100) + grade: + type: string + enum: [A+, A, B, C, D, E, F] + description: Letter grade + from_domain: + type: string + description: Sender domain extracted from the report + created_at: + type: string + format: date-time + + TestListResponse: + type: object + required: + - tests + - total + - offset + - limit + properties: + tests: + type: array + items: + $ref: '#/components/schemas/TestSummary' + total: + type: integer + description: Total number of tests + offset: + type: integer + description: Current offset + limit: + type: integer + description: Current limit diff --git a/internal/api/handlers.go b/internal/api/handlers.go index 470136e..e524b40 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -381,3 +381,78 @@ func (h *APIHandler) CheckBlacklist(c *gin.Context) { c.JSON(http.StatusOK, response) } + +// ListTests returns a paginated list of test summaries +// (GET /tests) +func (h *APIHandler) ListTests(c *gin.Context, params ListTestsParams) { + if h.config.DisableTestList { + c.JSON(http.StatusForbidden, Error{ + Error: "feature_disabled", + Message: "Test listing is disabled on this instance", + }) + return + } + + offset := 0 + limit := 20 + if params.Offset != nil { + offset = *params.Offset + } + if params.Limit != nil { + limit = *params.Limit + if limit > 100 { + limit = 100 + } + } + + summaries, total, err := h.storage.ListReportSummaries(offset, limit) + if err != nil { + c.JSON(http.StatusInternalServerError, Error{ + Error: "internal_error", + Message: "Failed to list tests", + Details: stringPtr(err.Error()), + }) + return + } + + tests := make([]TestSummary, 0, len(summaries)) + for _, s := range summaries { + base32ID := utils.UUIDToBase32(s.TestID) + + var grade TestSummaryGrade + switch s.Grade { + case "A+": + grade = TestSummaryGradeA + case "A": + grade = TestSummaryGradeA1 + case "B": + grade = TestSummaryGradeB + case "C": + grade = TestSummaryGradeC + case "D": + grade = TestSummaryGradeD + case "E": + grade = TestSummaryGradeE + default: + grade = TestSummaryGradeF + } + + summary := TestSummary{ + TestId: base32ID, + Score: s.Score, + Grade: grade, + CreatedAt: s.CreatedAt, + } + if s.FromDomain != "" { + summary.FromDomain = stringPtr(s.FromDomain) + } + tests = append(tests, summary) + } + + c.JSON(http.StatusOK, TestListResponse{ + Tests: tests, + Total: int(total), + Offset: offset, + Limit: limit, + }) +} diff --git a/internal/config/cli.go b/internal/config/cli.go index 77108ca..fcc914f 100644 --- a/internal/config/cli.go +++ b/internal/config/cli.go @@ -44,6 +44,7 @@ func declareFlags(o *Config) { flag.UintVar(&o.RateLimit, "rate-limit", o.RateLimit, "API rate limit (requests per second per IP)") flag.Var(&URL{&o.SurveyURL}, "survey-url", "URL for user feedback survey") flag.StringVar(&o.CustomLogoURL, "custom-logo-url", o.CustomLogoURL, "URL for custom logo image in the web UI") + flag.BoolVar(&o.DisableTestList, "disable-test-list", o.DisableTestList, "Disable the public test listing endpoint") // Others flags are declared in some other files likes sources, storages, ... when they need specials configurations } diff --git a/internal/config/config.go b/internal/config/config.go index 9d803d0..b264994 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -50,6 +50,7 @@ type Config struct { RateLimit uint // API rate limit (requests per second per IP) SurveyURL url.URL // URL for user feedback survey CustomLogoURL string // URL for custom logo image in the web UI + DisableTestList bool // Disable the public test listing endpoint } // DatabaseConfig contains database connection settings diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 39b2eb6..1077e74 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -45,11 +45,21 @@ type Storage interface { ReportExists(testID uuid.UUID) (bool, error) UpdateReport(testID uuid.UUID, reportJSON []byte) error DeleteOldReports(olderThan time.Time) (int64, error) + ListReportSummaries(offset, limit int) ([]ReportSummary, int64, error) // Close closes the database connection Close() error } +// ReportSummary is a lightweight projection of Report for listing +type ReportSummary struct { + TestID uuid.UUID + Score int + Grade string + FromDomain string + CreatedAt time.Time +} + // DBStorage implements Storage using GORM type DBStorage struct { db *gorm.DB @@ -139,6 +149,47 @@ func (s *DBStorage) DeleteOldReports(olderThan time.Time) (int64, error) { return result.RowsAffected, nil } +// ListReportSummaries returns a paginated list of lightweight report summaries +func (s *DBStorage) ListReportSummaries(offset, limit int) ([]ReportSummary, int64, error) { + var total int64 + if err := s.db.Model(&Report{}).Count(&total).Error; err != nil { + return nil, 0, fmt.Errorf("failed to count reports: %w", err) + } + + if total == 0 { + return []ReportSummary{}, 0, nil + } + + var selectExpr string + switch s.db.Dialector.Name() { + case "postgres": + selectExpr = `test_id, ` + + `(convert_from(report_json, 'UTF8')::jsonb->>'score')::int as score, ` + + `convert_from(report_json, 'UTF8')::jsonb->>'grade' as grade, ` + + `convert_from(report_json, 'UTF8')::jsonb->'dns_results'->>'from_domain' as from_domain, ` + + `created_at` + default: // sqlite + selectExpr = `test_id, ` + + `json_extract(report_json, '$.score') as score, ` + + `json_extract(report_json, '$.grade') as grade, ` + + `json_extract(report_json, '$.dns_results.from_domain') as from_domain, ` + + `created_at` + } + + var summaries []ReportSummary + err := s.db.Model(&Report{}). + Select(selectExpr). + Order("created_at DESC"). + Offset(offset). + Limit(limit). + Scan(&summaries).Error + if err != nil { + return nil, 0, fmt.Errorf("failed to list report summaries: %w", err) + } + + return summaries, total, nil +} + // Close closes the database connection func (s *DBStorage) Close() error { sqlDB, err := s.db.DB() diff --git a/web/routes.go b/web/routes.go index 876954c..056115d 100644 --- a/web/routes.go +++ b/web/routes.go @@ -70,6 +70,10 @@ func DeclareRoutes(cfg *config.Config, router *gin.Engine) { appConfig["custom_logo_url"] = cfg.CustomLogoURL } + if !cfg.DisableTestList { + appConfig["test_list_enabled"] = true + } + if appcfg, err := json.MarshalIndent(appConfig, "", " "); err != nil { log.Println("Unable to generate JSON config to inject in web application") } else { @@ -95,6 +99,7 @@ func DeclareRoutes(cfg *config.Config, router *gin.Engine) { router.GET("/domain/:domain", serveOrReverse("/", cfg)) router.GET("/test/", serveOrReverse("/", cfg)) router.GET("/test/:testid", serveOrReverse("/", cfg)) + router.GET("/history/", serveOrReverse("/", cfg)) router.GET("/favicon.png", func(c *gin.Context) { c.Writer.Header().Set("Cache-Control", "public, max-age=604800, immutable") }, serveOrReverse("", cfg)) router.GET("/img/*path", serveOrReverse("", cfg)) diff --git a/web/src/lib/components/HistoryTable.svelte b/web/src/lib/components/HistoryTable.svelte new file mode 100644 index 0000000..737d025 --- /dev/null +++ b/web/src/lib/components/HistoryTable.svelte @@ -0,0 +1,72 @@ + + +
+ + + + + + + + + + + + {#each tests as test} + goto(`/test/${test.test_id}`)}> + + + + + + + {/each} + +
GradeScoreDomainDate
+ + + {test.score}% + + {#if test.from_domain} + {test.from_domain} + {:else} + - + {/if} + + {formatDate(test.created_at)} + + +
+
+ + diff --git a/web/src/lib/components/index.ts b/web/src/lib/components/index.ts index 8ed409c..a593801 100644 --- a/web/src/lib/components/index.ts +++ b/web/src/lib/components/index.ts @@ -23,5 +23,6 @@ export { default as RspamdCard } from "./RspamdCard.svelte"; export { default as SpamAssassinCard } from "./SpamAssassinCard.svelte"; export { default as SpfRecordsDisplay } from "./SpfRecordsDisplay.svelte"; export { default as SummaryCard } from "./SummaryCard.svelte"; +export { default as HistoryTable } from "./HistoryTable.svelte"; export { default as TinySurvey } from "./TinySurvey.svelte"; export { default as WhitelistCard } from "./WhitelistCard.svelte"; diff --git a/web/src/lib/stores/config.ts b/web/src/lib/stores/config.ts index c393dd2..962868c 100644 --- a/web/src/lib/stores/config.ts +++ b/web/src/lib/stores/config.ts @@ -26,6 +26,7 @@ interface AppConfig { survey_url?: string; custom_logo_url?: string; rbls?: string[]; + test_list_enabled?: boolean; } const defaultConfig: AppConfig = { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 077f340..92bb4db 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -40,7 +40,17 @@ {/if} -
+ {#if $appConfig.test_list_enabled} + + {/if} +
Open-Source Email Deliverability Tester diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 7c23d10..b9259fe 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1,12 +1,30 @@ + + + Test History - happyDeliver + + +
+
+
+
+

+ + Test History +

+ +
+ + {#if loading} +
+
+ Loading... +
+

Loading tests...

+
+ {:else if error} + + {:else if tests.length === 0} +
+ +

No tests yet

+

+ Send a test email to get your first deliverability + report. +

+ +
+ {:else} + + + + {#if totalPages > 1} + + {/if} + {/if} +
+
+
From 3eec5ce96655060eb94f28403daacb720e2c8115 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 9 Apr 2026 17:49:52 +0700 Subject: [PATCH 3/4] Remove unused xAlignedFrom prop from HeaderAnalysisCard --- web/src/lib/components/HeaderAnalysisCard.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/lib/components/HeaderAnalysisCard.svelte b/web/src/lib/components/HeaderAnalysisCard.svelte index b26b492..73c39e8 100644 --- a/web/src/lib/components/HeaderAnalysisCard.svelte +++ b/web/src/lib/components/HeaderAnalysisCard.svelte @@ -11,7 +11,7 @@ headerScore?: number; } - let { dmarcRecord, headerAnalysis, headerGrade, headerScore, xAlignedFrom }: Props = $props(); + let { dmarcRecord, headerAnalysis, headerGrade, headerScore }: Props = $props();
From 79e1c930f1ea9a356531d68b73dc2c460b3922d5 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 9 Apr 2026 11:10:34 +0000 Subject: [PATCH 4/4] chore(deps): update module github.com/oapi-codegen/runtime to v1.4.0 --- go.mod | 5 ++--- go.sum | 10 ++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 038eb22..2cb24a7 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,9 @@ go 1.25.0 require ( github.com/JGLTechnologies/gin-rate-limit v1.5.6 github.com/emersion/go-smtp v0.24.0 - github.com/getkin/kin-openapi v0.133.0 github.com/gin-gonic/gin v1.12.0 github.com/google/uuid v1.6.0 - github.com/oapi-codegen/runtime v1.3.0 + github.com/oapi-codegen/runtime v1.4.0 golang.org/x/net v0.52.0 gorm.io/driver/postgres v1.6.0 gorm.io/driver/sqlite v1.6.0 @@ -16,7 +15,6 @@ require ( ) require ( - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect @@ -26,6 +24,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/gabriel-vasile/mimetype v1.4.12 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/swag/jsonname v0.25.4 // indirect diff --git a/go.sum b/go.sum index 10c9b72..a79c0ba 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ github.com/JGLTechnologies/gin-rate-limit v1.5.6 h1:BrL2wXrF7SSqmB88YTGFVKMGVcjURMUeKqwQrlmzweI= github.com/JGLTechnologies/gin-rate-limit v1.5.6/go.mod h1:fwUuBegxLKm8+/4ST0zDFssRFTFaVZ7bH3ApK7iNZww= -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -102,7 +98,6 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -132,8 +127,8 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= -github.com/oapi-codegen/runtime v1.3.0 h1:vyK1zc0gDWWXgk2xoQa4+X4RNNc5SL2RbTpJS/4vMYA= -github.com/oapi-codegen/runtime v1.3.0/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY= +github.com/oapi-codegen/runtime v1.4.0 h1:KLOSFOp7UzkbS7Cs1ms6NBEKYr0WmH2wZG0KKbd2er4= +github.com/oapi-codegen/runtime v1.4.0/go.mod h1:5sw5fxCDmnOzKNYmkVNF8d34kyUeejJEY8HNT2WaPec= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -170,7 +165,6 @@ github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=