diff --git a/lib/index.ts b/lib/index.ts index e23d3e4a..c1f68e7d 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -94,14 +94,21 @@ export class $RefParser { */ public async bundle({ arrayBuffer, + fetch, pathOrUrlOrSchema, resolvedInput, }: { arrayBuffer?: ArrayBuffer; + fetch?: RequestInit; pathOrUrlOrSchema: JSONSchema | string | unknown; resolvedInput?: ResolvedInput; }): Promise { - await this.parse({ arrayBuffer, pathOrUrlOrSchema, resolvedInput }); + await this.parse({ + arrayBuffer, + fetch, + pathOrUrlOrSchema, + resolvedInput, + }); await resolveExternal(this, this.options); const errors = JSONParserErrorGroup.getParserErrors(this); if (errors.length > 0) { @@ -125,11 +132,16 @@ export class $RefParser { * @param pathOrUrlOrSchema A JSON Schema object, or the file path or URL of a JSON Schema file. */ public async dereference({ + fetch, pathOrUrlOrSchema, }: { + fetch?: RequestInit; pathOrUrlOrSchema: JSONSchema | string | unknown; }): Promise { - await this.parse({ pathOrUrlOrSchema }); + await this.parse({ + fetch, + pathOrUrlOrSchema, + }); await resolveExternal(this, this.options); const errors = JSONParserErrorGroup.getParserErrors(this); if (errors.length > 0) { @@ -153,10 +165,12 @@ export class $RefParser { */ public async parse({ arrayBuffer, + fetch, pathOrUrlOrSchema, resolvedInput: _resolvedInput, }: { arrayBuffer?: ArrayBuffer; + fetch?: RequestInit; pathOrUrlOrSchema: JSONSchema | string | unknown; resolvedInput?: ResolvedInput; }): Promise<{ schema: JSONSchema }> { @@ -182,7 +196,11 @@ export class $RefParser { $refAdded.pathType = type; try { const resolver = type === 'file' ? fileResolver : urlResolver; - await resolver.handler(file, arrayBuffer); + await resolver.handler({ + arrayBuffer, + fetch, + file, + }); const parseResult = await parseFile(file, this.options); $refAdded.value = parseResult.result; schema = parseResult.result; diff --git a/lib/resolve-external.ts b/lib/resolve-external.ts index 559c6a01..6adc4481 100644 --- a/lib/resolve-external.ts +++ b/lib/resolve-external.ts @@ -124,7 +124,7 @@ async function resolve$Ref( if (resolvedInput.type !== 'json') { const resolver = resolvedInput.type === 'file' ? fileResolver : urlResolver; - await resolver.handler(file); + await resolver.handler({ file }); const parseResult = await parseFile(file, options); $refAdded.value = parseResult.result; promises = crawl(parseResult.result, `${withoutHash}#`, $refs, options, new Set(), true); diff --git a/lib/resolvers/file.ts b/lib/resolvers/file.ts index 2c45cb91..25d4c223 100644 --- a/lib/resolvers/file.ts +++ b/lib/resolvers/file.ts @@ -5,7 +5,11 @@ import { ResolverError } from "../util/errors.js"; import type { FileInfo } from "../types/index.js"; export const fileResolver = { - handler: async (file: FileInfo): Promise => { + handler: async ({ + file, + }: { + file: FileInfo; + }): Promise => { let path: string | undefined; try { diff --git a/lib/resolvers/url.ts b/lib/resolvers/url.ts index cb452f11..a613d0d9 100644 --- a/lib/resolvers/url.ts +++ b/lib/resolvers/url.ts @@ -4,17 +4,17 @@ import { ResolverError } from "../util/errors.js"; import type { FileInfo } from "../types/index.js"; export const sendRequest = async ({ - init, + fetchOptions, redirects = [], timeout = 60_000, url, }: { - init?: RequestInit; + fetchOptions?: RequestInit; redirects?: string[]; timeout?: number; url: URL | string; }): Promise<{ - init?: RequestInit; + fetchOptions?: RequestInit; response: Response; }> => { url = new URL(url); @@ -26,7 +26,7 @@ export const sendRequest = async ({ }, timeout); const response = await fetch(url, { signal: controller.signal, - ...init, + ...fetchOptions, }); clearTimeout(timeoutId); @@ -45,32 +45,41 @@ export const sendRequest = async ({ } return sendRequest({ - init, + fetchOptions, redirects, timeout, url: resolve(url.href, response.headers.location as string), }); } - return { init, response }; + return { fetchOptions, response }; } export const urlResolver = { - handler: async (file: FileInfo, arrayBuffer?: ArrayBuffer): Promise => { + handler: async ({ + arrayBuffer, + fetch: _fetch, + file, + }: { + arrayBuffer?: ArrayBuffer; + fetch?: RequestInit; + file: FileInfo; + }): Promise => { let data = arrayBuffer; if (!data) { try { - const { init, response } = await sendRequest({ - init: { + const { fetchOptions, response } = await sendRequest({ + fetchOptions: { method: 'GET', + ..._fetch, }, url: file.url, }); if (response.status >= 400) { // gracefully handle HEAD method not allowed - if (response.status !== 405 || init?.method !== 'HEAD') { + if (response.status !== 405 || fetchOptions?.method !== 'HEAD') { throw ono({ status: response.status }, `HTTP ERROR ${response.status}`); }