← back to Cli Printing Press
fix(parser): check OpenAPI before GraphQL to prevent false positives
9c4349a3b4471a13e4527e646d1c3d77b87c98e6 · 2026-03-27 14:54:54 -0700 · Matt Van Horn
- Swap detection order: OpenAPI first, then GraphQL SDL
- Fixes false positive where "scalar" in OpenAPI descriptions triggered GraphQL parser
- Fix camelToKebab to handle acronyms (PR->pr, SQL->sql, not p-r-triage)
- Wire verify command into CLI root
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Files touched
M internal/cli/root.goM internal/pipeline/verify.go
Diff
commit 9c4349a3b4471a13e4527e646d1c3d77b87c98e6
Author: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date: Fri Mar 27 14:54:54 2026 -0700
fix(parser): check OpenAPI before GraphQL to prevent false positives
- Swap detection order: OpenAPI first, then GraphQL SDL
- Fixes false positive where "scalar" in OpenAPI descriptions triggered GraphQL parser
- Fix camelToKebab to handle acronyms (PR->pr, SQL->sql, not p-r-triage)
- Wire verify command into CLI root
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
internal/cli/root.go | 7 ++++---
internal/pipeline/verify.go | 19 +++++++++++++++++--
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/internal/cli/root.go b/internal/cli/root.go
index 49abdd70..3f12aeb6 100644
--- a/internal/cli/root.go
+++ b/internal/cli/root.go
@@ -39,6 +39,7 @@ func Execute() error {
rootCmd.AddCommand(newGenerateCmd())
rootCmd.AddCommand(newScorecardCmd())
rootCmd.AddCommand(newDogfoodCmd())
+ rootCmd.AddCommand(newVerifyCmd())
rootCmd.AddCommand(newVisionCmd())
rootCmd.AddCommand(newVersionCmd())
rootCmd.AddCommand(newPrintCmd())
@@ -180,14 +181,14 @@ func newGenerateCmd() *cobra.Command {
}
var apiSpec *spec.APISpec
- if graphql.IsGraphQLSDL(data) {
- apiSpec, err = graphql.ParseSDLBytes(specFile, data)
- } else if openapi.IsOpenAPI(data) {
+ if openapi.IsOpenAPI(data) {
if lenient {
apiSpec, err = openapi.ParseLenient(data)
} else {
apiSpec, err = openapi.Parse(data)
}
+ } else if graphql.IsGraphQLSDL(data) {
+ apiSpec, err = graphql.ParseSDLBytes(specFile, data)
} else {
apiSpec, err = spec.ParseBytes(data)
}
diff --git a/internal/pipeline/verify.go b/internal/pipeline/verify.go
index 3738ac15..c506de84 100644
--- a/internal/pipeline/verify.go
+++ b/internal/pipeline/verify.go
@@ -527,10 +527,25 @@ func countTableColumns(storeSrc, tableName string) int {
func camelToKebab(s string) string {
var b strings.Builder
- for i, r := range s {
+ runes := []rune(s)
+ for i, r := range runes {
if unicode.IsUpper(r) {
+ // Don't insert hyphen if:
+ // - first character
+ // - previous char was also uppercase AND next char is uppercase or end (acronym interior)
if i > 0 {
- b.WriteByte('-')
+ prevUpper := unicode.IsUpper(runes[i-1])
+ nextUpper := i+1 < len(runes) && unicode.IsUpper(runes[i+1])
+ nextEnd := i+1 >= len(runes)
+ if prevUpper && (nextUpper || nextEnd) {
+ // Inside or at end of acronym - no hyphen
+ } else if !prevUpper {
+ // Start of new word after lowercase
+ b.WriteByte('-')
+ } else {
+ // prevUpper && next is lowercase = start of new word after acronym (e.g., PRTriage -> pr-triage)
+ b.WriteByte('-')
+ }
}
b.WriteRune(unicode.ToLower(r))
} else {
← 4f93e79f feat(verify): add runtime verification command with mock ser
·
back to Cli Printing Press
·
feat(skill): add product thesis, market research, naming pas ad4812f3 →