From 4db64f1f6781c8c7f4947663f95b1d06fd50dec7 Mon Sep 17 00:00:00 2001 From: Pete Steyert-Woods Date: Wed, 7 Jan 2026 13:38:53 +0000 Subject: [PATCH] Support references starting with numeric character --- bundler/bundler_test.go | 3 ++ index/find_component.go | 12 +++++++- .../components/responses/4xxClientErrors.yaml | 20 +++++++++++++ test_specs/nested_files/openapi-bundled.yaml | 30 +++++++++++++++++++ .../nested_files/paths/v1_Accounts.yaml | 7 ++++- utils/utils.go | 12 ++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 test_specs/nested_files/components/responses/4xxClientErrors.yaml diff --git a/bundler/bundler_test.go b/bundler/bundler_test.go index b58b4c05..4469f2c6 100644 --- a/bundler/bundler_test.go +++ b/bundler/bundler_test.go @@ -560,6 +560,9 @@ func TestBundleDocument_BundleBytesComposed_NestedFiles(t *testing.T) { AllowFileReferences: true, BasePath: "../test_specs/nested_files", ExtractRefsSequentially: true, + Logger: slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelDebug, + })), } bundledBytes, e := BundleBytesComposed(specBytes, config, nil) diff --git a/index/find_component.go b/index/find_component.go index 06855dc9..b34108a3 100644 --- a/index/find_component.go +++ b/index/find_component.go @@ -80,7 +80,17 @@ func FindComponent(_ context.Context, root *yaml.Node, componentId, absoluteFile friendlySearch = "$" } path, err := jsonpath.NewPath(friendlySearch, jsonpathconfig.WithPropertyNameExtension()) - if path == nil || err != nil || root == nil { + if err != nil { + index.logger.Warn("[FindComponent] error creating JSON path", + "absoluteFilePath", absoluteFilePath, + "componentId", componentId, + "name", name, + "friendlySearch", friendlySearch, + "error", err.Error(), + ) + return nil + } + if path == nil || root == nil { return nil // no component found } res := path.Query(root) diff --git a/test_specs/nested_files/components/responses/4xxClientErrors.yaml b/test_specs/nested_files/components/responses/4xxClientErrors.yaml new file mode 100644 index 00000000..3538e754 --- /dev/null +++ b/test_specs/nested_files/components/responses/4xxClientErrors.yaml @@ -0,0 +1,20 @@ +400_unexpected_request_body: + description: Unexpected request body provided. + content: + application/json: + schema: + additionalProperties: false + properties: + message: + type: string + default: Unexpected request body provided. +403_permission_denied: + description: None or insufficient credentials provided. + content: + application/json: + schema: + additionalProperties: false + properties: + message: + type: string + default: Permission denied. diff --git a/test_specs/nested_files/openapi-bundled.yaml b/test_specs/nested_files/openapi-bundled.yaml index c5f88f5f..f83bc891 100644 --- a/test_specs/nested_files/openapi-bundled.yaml +++ b/test_specs/nested_files/openapi-bundled.yaml @@ -153,6 +153,16 @@ components: responses: "200": $ref: '#/components/responses/Unspecified200' + "403": + description: None or insufficient credentials provided. + content: + application/json: + schema: + additionalProperties: false + properties: + message: + type: string + default: Permission denied. put: summary: TODO description: TODO @@ -166,3 +176,23 @@ components: responses: "200": $ref: '#/components/responses/Unspecified200' + "400": + description: Unexpected request body provided. + content: + application/json: + schema: + additionalProperties: false + properties: + message: + type: string + default: Unexpected request body provided. + "403": + description: None or insufficient credentials provided. + content: + application/json: + schema: + additionalProperties: false + properties: + message: + type: string + default: Permission denied. diff --git a/test_specs/nested_files/paths/v1_Accounts.yaml b/test_specs/nested_files/paths/v1_Accounts.yaml index dc5c396b..d3b785e4 100644 --- a/test_specs/nested_files/paths/v1_Accounts.yaml +++ b/test_specs/nested_files/paths/v1_Accounts.yaml @@ -26,7 +26,8 @@ post: responses: "200": $ref: ../components/responses/Unspecified200.yaml - + "403": + $ref: '../components/responses/4xxClientErrors.yaml#/403_permission_denied' put: summary: TODO description: TODO @@ -40,3 +41,7 @@ put: responses: "200": $ref: ../components/responses/Unspecified200.yaml + "400": + $ref: '../components/responses/4xxClientErrors.yaml#/400_unexpected_request_body' + "403": + $ref: '../components/responses/4xxClientErrors.yaml#/403_permission_denied' diff --git a/utils/utils.go b/utils/utils.go index 4492912a..b56a1a96 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -830,6 +830,18 @@ func ConvertComponentIdIntoFriendlyPathSearch(id string) (string, string) { continue } + // If segment starts with a number + if len(segs[i]) > 0 && segs[i][0] >= '0' && segs[i][0] <= '9' { + var pluralBuilder strings.Builder + pluralBuilder.Grow(len(segs[i]) + 4) + pluralBuilder.WriteString("['") + pluralBuilder.WriteString(segs[i]) + pluralBuilder.WriteString("']") + segs[i] = pluralBuilder.String() + cleaned = append(cleaned, segs[i]) + continue + } + // if we have a plural parent, wrap it in quotes. if i > 0 && segs[i-1] != "" && segs[i-1][len(segs[i-1])-1] == 's' { if i == 2 { // ignore first segment.