fix: apply excludedPathMatcher during external resolution - #430
Conversation
|
Thanks for working on this — the direction makes sense, but I don't think this is ready to merge yet. I found two blocking issues. 1. The resolver matcher receives a different path formatAt Bundle and dereference pass a root-relative JSON pointer instead: I reproduced an exact matcher such as: const matcher = (path: string) => path === "#/example";working for bundle/dereference but failing during resolution, so the supposedly excluded external reference is still fetched. The inverse can also happen: a matcher such as When an external document is crawled, the matcher path is also reset to that document's URL at I think resolution needs to carry a separate logical/root-relative 2. This introduces a public TypeScript regressionThe callable arm added to the index signature at
Additional edge casePruning a source subtree during resolution can leave external references unloaded when that same value is later reached through a nonexcluded internal {
embedded: { child: { $ref: "child.virtual" } },
use: { $ref: "#/embedded" }
}If The canonical options documentation should also document ValidationThe existing implementation is otherwise clean: GitHub's cross-platform matrix is green, and locally build, typecheck, lint, formatting, 523 Node tests, and 484 browser tests all passed. The new tests use unanchored path matching, which masks the path-format issue above. |
|
@jonluca Thanks for the detailed review. I have addressed each point:
For the additional edge case, I chose operation-wide, value-based semantics. Matching a path marks that value and its descendants as literal data for the rest of the operation. It does not only skip processing at that one occurrence. An internal alias can still resolve to the excluded value or access a literal property within it, but any I added coverage for internal aliases, excluded descendants, valid and missing literal properties, parser reuse, and circular input values. |
Closes #429
Summary
External references are resolved before the existing bundle and dereference exclusion matchers run. As a result, a literal
$refbelow an excluded path can still be downloaded or throw a resolution error.This adds
resolve.excludedPathMatcherso callers can stop traversal before external references are fetched.The matcher now also receives the value at the current path:
The value is useful when a document contains both intentional internal references and literal external
$refproperties in the same section. Callers can preserve the literal value without excluding every reference below that path.Bundling now checks direct child values as well as containers. This ensures a matching
$refis skipped before it enters the bundle inventory.Existing path-only matchers remain compatible because the second argument is optional.
Testing
$refand its sibling properties.