feat(mcp): add web.allowedorigins-removed rule; document v1.3.0 CORS migration

This commit is contained in:
2026-08-08 10:51:38 -06:00
parent 03a8d8a641
commit 3961ae7175
7 changed files with 118 additions and 9 deletions
+11 -7
View File
@@ -49,10 +49,10 @@ func synthIndex() *index.Index {
{Kind: "type", Name: "Config", SubPackage: "server", Fields: []index.Field{
{Name: "Host", Type: "string", Tag: `env:"EINHERJAR_SERVER_HOST" envDefault:"0.0.0.0"`},
{Name: "Port", Type: "int", Tag: `env:"EINHERJAR_SERVER_PORT" envDefault:"8080"`},
{Name: "CORSOrigins", Type: "[]string", Tag: `env:"EINHERJAR_SERVER_CORS_ORIGINS" envSeparator:","`},
}},
{Kind: "type", Name: "Config", SubPackage: "", Fields: []index.Field{
{Name: "Server", Type: "server.Config"}, // nested, no env tag
{Name: "AllowedOrigins", Type: "[]string", Tag: `env:"EINHERJAR_SERVER_CORS_ORIGINS" envSeparator:","`},
{Name: "Server", Type: "server.Config"}, // nested, no env tag; root has no own env vars
}},
},
},
@@ -73,7 +73,7 @@ func synthIndex() *index.Index {
func TestForModule(t *testing.T) {
idx := synthIndex()
got := ForModule(idx, "web")
if len(got) != 3 { // 2 server + 1 CORS; the nested Server field is not a leaf
if len(got) != 3 { // Host + Port + CORSOrigins, all on server.Config; the nested Server field is not a leaf and the root has no own env vars
t.Fatalf("ForModule(web) = %d vars, want 3: %+v", len(got), got)
}
names := map[string]bool{}
@@ -93,15 +93,19 @@ func TestForModule(t *testing.T) {
func TestFindStruct(t *testing.T) {
idx := synthIndex()
server := FindStruct(idx, "web", "server", "Config")
if len(server) != 2 {
t.Fatalf("FindStruct(web/server/Config) = %d, want 2", len(server))
if len(server) != 3 {
t.Fatalf("FindStruct(web/server/Config) = %d, want 3", len(server))
}
// The root web.Config must NOT be returned for the server selector.
// CORS now lives on server.Config, so the server selector MUST include it.
corsOnServer := false
for _, v := range server {
if v.Name == "EINHERJAR_SERVER_CORS_ORIGINS" {
t.Error("server selector leaked the root web.Config CORS var")
corsOnServer = true
}
}
if !corsOnServer {
t.Error("server selector should include EINHERJAR_SERVER_CORS_ORIGINS (it lives on server.Config)")
}
pg := FindStruct(idx, "db-postgres", "", "Config")
if len(pg) != 3 {
t.Fatalf("FindStruct(db-postgres//Config) = %d, want 3", len(pg))