fix(oas:sync): resolve path-item $refs so sync stops deleting pages - #47
fix(oas:sync): resolve path-item $refs so sync stops deleting pages#47cursor[bot] wants to merge 2 commits into
Conversation
extractOperations walked the raw spec and treated a path-level $ref (OAS 3.1 components.pathItems, or a pointer to another path) as having zero operations. oas:sync and lint --fix then deleted every matching reference page. Resolve internal JSON Pointer $refs before collecting operations, and skip the delete pass when a $ref still cannot be inlined (e.g. a split spec that points at ./paths/*.yaml). Co-authored-by: Jon Ursenbach <erunion@users.noreply.github.com>
|
- Walk JSON Pointers with Object.hasOwn so #/__proto__ cannot escape into Object.prototype and empty the operation set. - Treat a $ref as unresolved only after following the full chain, so a pointer that lands on an external, cyclic, or broken $ref still skips the delete pass. - Overlay OAS 3.1 path-item siblings onto the resolved target instead of dropping them (local keys win). Co-authored-by: Jon Ursenbach <erunion@users.noreply.github.com>
| if (target == null) return obj; | ||
| const resolved = resolveRefObject(root, target, seen); | ||
| if (!hasSiblings) return resolved; | ||
| if (!resolved || typeof resolved !== 'object' || Array.isArray(resolved)) return resolved; |
There was a problem hiding this comment.
Non-object targets discard siblings
When a path item has a sibling HTTP operation beside an internal $ref whose target is an array or scalar, resolveRefObject returns only that target and discards the sibling. The reference is then treated as resolved, so extraction omits the sibling operation while deletion remains enabled, causing synchronization to delete its existing page and validation to report it as missing.
oas:sync/lint --fixdeleted valid reference pages when the spec used path-item$refs🪄 Changes
extractOperationswalked the raw OpenAPI document and only counted HTTP methods sitting directly on each path item. A path-level$ref— including the OAS 3.1components.pathItemsform — therefore contributed zero operations.syncOneOasthen treated every existing page for that spec as orphaned and deleted it. Same path forreadme lint --fix(via theoas-referencevalidator).Concrete trigger: a repo with
reference/openapi.jsonlike:and a page
reference/.../listPets.mdwith custom body. Onereadme oas:syncorreadme lint --fixpermanently deletes that page.Fix:
$refs (#/components/pathItems/…,#/paths/~1pets, operation-level pointers) before collecting operations.$refstill cannot be inlined (e.g. a split spec pointing at./paths/pets.yaml), so "we couldn't see the operation" is not treated as "the operation was removed".No change to add/skip-on-collision behavior, path sanitization, or webhook handling (still covered by #43).
🧬 QA & Testing
pathItemsspec on unmodifiedmain(page gone;changes.deleted = ['Pets/Other/listPets.md']).oas-referencevalidator no longer reportsOperation not found.test/oas-sync.test.js(resolution, no-deletion for internal and external$refs) andtest/oas-reference.test.js(no false missing-operation).npm test).