fix(typescript,mcp): validate usageSDKInitImports and advancedFlags in gen.yaml
Why
Two config fields declare their gen.yaml checks as a ValidationFunc on the field definition in config.ts:
typescriptv2usageSDKInitImports: must be an array of objects with a non-emptypackageandimport, and an optionaltypeoftypeImport,packageImport, oraliasImport.mcp-typescriptadvancedFlags: must be an array of alphanumeric strings.
Nothing reads ValidationFunc. GetLanguageConfigFields decodes the field definitions into sdk-gen-config's SDKGenConfigField, which has no such field, so the key is dropped and neither check has ever run. Malformed values are accepted silently: a usageSDKInitImports entry without import passes an undefined import name to addUsageImport, and an advancedFlags entry such as dry-run can never match a flag name, because gatherMCPFlags compares entries against sanitizeFieldName(flag.Name).
What changed
templates/templates/typescriptv2/config.ts,templates/templates/mcp-typescript/config.ts: each check moves into a target-levelvalidateConfig(cfg). This is the hookGenerator.validateConfig(pkg/generate/configuration.go) already runs on gen.yaml for the cli, go, javav2, php, pythonv2, and ruby targets; a non-empty message fails generation withgen.yaml validation error for <target>: <message>. TheValidationFunckeys are removed.- The
usageSDKInitImportscheck resolvespackage || Package,import || Import, andtype || Typebefore validating, matchingtemplateUsageSDKInit, so entries using the capitalized keys keep generating. - Absent and
nullvalues are skipped. Templating already treats both as empty (templateUsageSDKInitchecksArray.isArray,gatherMCPFlagschecks truthiness), and an emptyusageSDKInitImports:oradvancedFlags:key in gen.yaml decodes tonull, which the old function would have rejected. pkg/generate/typescript_config_validation_test.go: error and success cases for both fields, including capitalized and mixed-case import keys, every import type, empty and non-string values, and empty flag names, throughGenerator.validateConfig, in the same style ascli_config_validation_test.go. That file'snewCLITestConfighelper becomesnewLanguageTestConfig(target, cfg)so both test files share it.- Changeset:
core/typescriptv2,mcp-typescriptpatch.
Behaviour change: a gen.yaml with a malformed value for either field now fails validation instead of generating. Import types other than typeImport, packageImport, or aliasImport now fail validation. Previously, unrecognized values silently rendered as typeImport. Generated output for valid configurations does not change, so no review SDKs are regenerated; the existing review and test configurations (advancedFlags: [loneQueryParam], usageSDKInitImports: []) pass.
Testing
go test ./pkg/generate -run TestValidateConfigTypeScript -count=1: passes. With the template changes reverted, all 15 error cases fail.go test ./pkg/generate -count=1: passes.cmd/generateagainst a one-operation spec, with gen.yaml leavingtemplateVersionunset:typescriptwithusageSDKInitImports: [{package: "@acme/sdk"}]fails withgen.yaml validation error for typescript: usageSDKInitImports[0].import must be a non-empty string; addingimport: Acmegenerates.mcp-typescriptwithadvancedFlags: [dry-run]fails withgen.yaml validation error for mcp-typescript: advancedFlags[0] must contain only letters or numbers;dryRungenerates.
make check-template-typescriptv2,make check-template-mcp-typescript,make lint: pass.
Public-safety check
- This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
- Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (
.claude/skills/public-repo-communication/SKILL.md). - Generated fixtures and review SDK changes are public-safe.
- I reviewed
git diff --check.