import { ErrorMergeResult } from './data'; import { Components31, OpenApiDocument } from './oas31'; import { DEDUPLICATED_COMPONENT_TYPES } from './paths-and-components'; /** * Cross-document `$ref` resolution (issues #104 and #10). * * A `$ref` that does not start with `#` names another document -- either one * of this merge's own inputs (`#/components/schemas/X` as seen from a * *different* input than the one containing the ref, qualified with that * input's `sourceIdentity`), or a document this merge never received as an * input at all, only as {@link import('./data').MergeOptions.externalDocuments}. * Both are resolved through the same entry point, {@link createCrossDocumentResolver}, * because from the referencing side they look identical: a `$ref` shaped * `#`. * * What differs is what "resolving" means once the identity is known: * - **A declared input**: the component is already being merged in as part * of that whole input. Resolving means looking up what it was renamed to * (if anything) in that input's own `referenceModification` map -- the * exact map its own bare in-document refs are rewritten with. * - **An external document**: nothing about it is being merged in * automatically. Resolving means reaching into that document, cloning out * *just* the referenced component, deduplicating it into the output like * any other component, and -- since that component may itself `$ref` * something, either locally within the same external document or another * external document entirely -- resolving those the same way, recursively. */ type ComponentBucket = typeof DEDUPLICATED_COMPONENT_TYPES[number]; export type ParsedComponentFragment = { bucket: ComponentBucket; name: string; }; /** * Parses a `#`-prefixed fragment like `#/components/schemas/ServerError` into * its bucket and name -- matching exactly the shape * {@link DEDUPLICATED_COMPONENT_TYPES} already deduplicates. * * Anything else is unsupported and returns `undefined`, left for the caller * to leave unresolved rather than guessed at: * - A nested path (`#/components/schemas/Foo/properties/bar`): this library * only ever tracks whole-component renames, never partial ones. * - `#/components/securitySchemes/X`: security schemes are addressed by name * in a security requirement object, never by `$ref`, so this shape is not * a reference-target OpenAPI itself defines (issue #33/#94's existing * carve-out for the same reason). * - Anything not shaped `#/components//` at all. */ export declare function parseComponentFragment(fragment: string): ParsedComponentFragment | undefined; /** Splits a cross-document `$ref` into its identity and (`#`-prefixed) fragment, or `undefined` for a bare same-document ref. */ export declare function splitCrossDocumentRef(ref: string): { identity: string; fragment: string | undefined; } | undefined; export type ReferenceModificationByIdentity = Record; export type ExternalReferenceResolution = { kind: 'resolved'; ref: string; } | { kind: 'error'; error: ErrorMergeResult; } | { kind: 'unresolved'; }; /** * Builds the resolver used by {@link import('./paths-and-components').mergePathsAndComponents}'s * cross-document pass. One resolver per merge call: it caches every * identity+fragment it has already placed, and grows `resultComponents` in * place as external components are pulled in. * * @param referenceModificationByIdentity Each declared input's own rename map * (built during that input's normal per-input processing), keyed by its * `sourceIdentity`. * @param ambiguousIdentities Identities claimed by more than one declared * input (issue #104 ยง5.2) -- treated as unmatched rather than guessed at, * since there is no principled way to pick which input a ref meant. * @param externalDocuments Documents that are not inputs, only a source of * components to pull in on demand (issue #10). * @param resultComponents The merge's own `components`, mutated in place as * external components are placed into it. * @param knownDocuments Every document a cross-document `$ref` *inside* a * pulled-in component might itself name -- declared inputs keyed by * `sourceIdentity`, plus `externalDocuments` -- so the dedup check below * (issue: PR #87 / proposal 45, Option C) can resolve one instead of * giving up on it. Built once by {@link import('./paths-and-components').mergePathsAndComponents} * via {@link import('./cross-document-lookup').buildKnownDocuments}, the * same map its own per-input dedup uses. */ export declare function createCrossDocumentResolver(referenceModificationByIdentity: ReferenceModificationByIdentity, ambiguousIdentities: ReadonlySet, externalDocuments: Record, resultComponents: Components31, knownDocuments: Readonly>): (identity: string, fragment: string) => ExternalReferenceResolution; export {}; //# sourceMappingURL=external-references.d.ts.map