From 0d0eeb4268fe6922f0a542b4ef966c3e4bd27659 Mon Sep 17 00:00:00 2001 From: Spencer Ellinor Date: Tue, 23 Jul 2019 13:50:48 -0700 Subject: [PATCH] Add extraFetchOptions fluent API to allow for custom per-call Fetch Options --- src/model.ts | 7 +++++++ src/scope.ts | 24 +++++++++++++++++++++--- test/integration/finders.test.ts | 13 +++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/model.ts b/src/model.ts index 54d5fda..09c3116 100644 --- a/src/model.ts +++ b/src/model.ts @@ -826,6 +826,13 @@ export class SpraypaintBase { return this.scope().extraParams(clause) } + static extraFetchOptions( + this: I, + options: RequestInit + ) { + return this.scope().extraFetchOptions(options) + } + static order( this: I, clause: SortScope | string diff --git a/src/scope.ts b/src/scope.ts index 3665eac..4e13f02 100644 --- a/src/scope.ts +++ b/src/scope.ts @@ -51,6 +51,7 @@ export class Scope { private _include: IncludeScopeHash = {} private _stats: StatsScope = {} private _extraParams: any = {} + private _extraFetchOptions: RequestInit = {} constructor(model: Constructor | typeof SpraypaintBase) { this.model = (model as any) as typeof SpraypaintBase @@ -205,6 +206,18 @@ export class Scope { return copy } + extraFetchOptions(options: RequestInit): Scope { + const copy = this.copy() + + for (const key in options) { + if (options.hasOwnProperty(key)) { + copy._extraFetchOptions[key] = options[key] + } + } + + return copy + } + // The `Model` class has a `scope()` method to return the scope for it. // This method makes it possible for methods to expect either a model or // a scope and reliably cast them to a scope for use via `scope()` @@ -240,6 +253,13 @@ export class Scope { } } + fetchOptions(): RequestInit { + return { + ...this.model.fetchOptions(), + ...this._extraFetchOptions + } + } + copy(): Scope { const newScope = cloneDeep(this) @@ -310,9 +330,7 @@ export class Scope { url = `${url}?${qp}` } const request = new Request(this.model.middlewareStack, this.model.logger) - const fetchOpts = this.model.fetchOptions() - - const response = await request.get(url, fetchOpts) + const response = await request.get(url, this.fetchOptions()) refreshJWT(this.model, response) return response.jsonPayload } diff --git a/test/integration/finders.test.ts b/test/integration/finders.test.ts index 9ee6e6a..7ea5891 100644 --- a/test/integration/finders.test.ts +++ b/test/integration/finders.test.ts @@ -20,6 +20,19 @@ describe("Model finders", () => { }) }) + it("allows for overridable fetch options", async () => { + const dummyHeaders = { Test: "hi" } + const { data } = await Person.extraFetchOptions({ + headers: dummyHeaders + }).find(1) + + const defaultFetchOptions = Person.fetchOptions + + const lastOptions = fetchMock.lastOptions() + + expect(lastOptions.headers).to.deep.eq(dummyHeaders) + }) + it("returns a promise that resolves the correct instance", async () => { const { data } = await Person.find(1) expect(data)