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. |
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.