Skip to content

Commit f8561b1

Browse files
authored
feat: add cache option to fetch (#817)
1 parent 36387ff commit f8561b1

File tree

5 files changed

+205
-4
lines changed

5 files changed

+205
-4
lines changed

packages/next-drupal/src/next-drupal.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export class NextDrupal extends NextDrupalBase {
8989
async createResource<T extends JsonApiResource>(
9090
type: string,
9191
body: JsonApiCreateResourceBody,
92-
options?: JsonApiOptions
92+
options?: JsonApiOptions & JsonApiWithNextFetchOptions
9393
): Promise<T> {
9494
options = {
9595
deserialize: true,
@@ -115,6 +115,7 @@ export class NextDrupal extends NextDrupalBase {
115115
method: "POST",
116116
body: JSON.stringify(body),
117117
withAuth: options.withAuth,
118+
cache: options.cache,
118119
})
119120

120121
await this.throwIfJsonErrors(response, "Error while creating resource: ")
@@ -129,7 +130,7 @@ export class NextDrupal extends NextDrupalBase {
129130
async createFileResource<T = DrupalFile>(
130131
type: string,
131132
body: JsonApiCreateFileResourceBody,
132-
options?: JsonApiOptions
133+
options?: JsonApiOptions & JsonApiWithNextFetchOptions
133134
): Promise<T> {
134135
options = {
135136
deserialize: true,
@@ -158,6 +159,7 @@ export class NextDrupal extends NextDrupalBase {
158159
},
159160
body: body.data.attributes.file,
160161
withAuth: options.withAuth,
162+
cache: options.cache,
161163
})
162164

163165
await this.throwIfJsonErrors(
@@ -174,7 +176,7 @@ export class NextDrupal extends NextDrupalBase {
174176
type: string,
175177
uuid: string,
176178
body: JsonApiUpdateResourceBody,
177-
options?: JsonApiOptions
179+
options?: JsonApiOptions & JsonApiWithNextFetchOptions
178180
): Promise<T> {
179181
options = {
180182
deserialize: true,
@@ -202,6 +204,7 @@ export class NextDrupal extends NextDrupalBase {
202204
method: "PATCH",
203205
body: JSON.stringify(body),
204206
withAuth: options.withAuth,
207+
cache: options.cache,
205208
})
206209

207210
await this.throwIfJsonErrors(response, "Error while updating resource: ")
@@ -216,7 +219,7 @@ export class NextDrupal extends NextDrupalBase {
216219
async deleteResource(
217220
type: string,
218221
uuid: string,
219-
options?: JsonApiOptions
222+
options?: JsonApiOptions & JsonApiWithNextFetchOptions
220223
): Promise<boolean> {
221224
options = {
222225
withAuth: true,
@@ -239,6 +242,7 @@ export class NextDrupal extends NextDrupalBase {
239242
const response = await this.fetch(endpoint, {
240243
method: "DELETE",
241244
withAuth: options.withAuth,
245+
cache: options.cache,
242246
})
243247

244248
await this.throwIfJsonErrors(response, "Error while deleting resource: ")
@@ -287,6 +291,7 @@ export class NextDrupal extends NextDrupalBase {
287291
const response = await this.fetch(endpoint, {
288292
withAuth: options.withAuth,
289293
next: options.next,
294+
cache: options.cache,
290295
})
291296

292297
await this.throwIfJsonErrors(response, "Error while fetching resource: ")
@@ -376,6 +381,7 @@ export class NextDrupal extends NextDrupalBase {
376381
body: JSON.stringify(payload),
377382
withAuth: options.withAuth,
378383
next: options.next,
384+
cache: options.cache,
379385
})
380386

381387
const errorMessagePrefix = "Error while fetching resource by path:"
@@ -435,6 +441,7 @@ export class NextDrupal extends NextDrupalBase {
435441
const response = await this.fetch(endpoint, {
436442
withAuth: options.withAuth,
437443
next: options.next,
444+
cache: options.cache,
438445
})
439446

440447
await this.throwIfJsonErrors(
@@ -500,6 +507,7 @@ export class NextDrupal extends NextDrupalBase {
500507
params,
501508
withAuth: options.withAuth,
502509
next: options.next,
510+
cache: options.cache,
503511
}
504512
if (locale) {
505513
opts = {
@@ -573,6 +581,7 @@ export class NextDrupal extends NextDrupalBase {
573581
const response = await this.fetch(endpoint, {
574582
withAuth: options.withAuth,
575583
next: options.next,
584+
cache: options.cache,
576585
})
577586

578587
if (response.status === 404) {
@@ -600,6 +609,7 @@ export class NextDrupal extends NextDrupalBase {
600609
// As per https://www.drupal.org/node/2984034 /jsonapi is public.
601610
withAuth: false,
602611
next: options?.next,
612+
cache: options?.cache,
603613
})
604614

605615
await this.throwIfJsonErrors(
@@ -710,6 +720,7 @@ export class NextDrupal extends NextDrupalBase {
710720
const response = await this.fetch(endpoint, {
711721
withAuth: options.withAuth,
712722
next: options.next,
723+
cache: options.cache,
713724
})
714725

715726
await this.throwIfJsonErrors(response, "Error while fetching menu items: ")
@@ -760,6 +771,7 @@ export class NextDrupal extends NextDrupalBase {
760771
const response = await this.fetch(endpoint, {
761772
withAuth: options.withAuth,
762773
next: options.next,
774+
cache: options.cache,
763775
})
764776

765777
await this.throwIfJsonErrors(response, "Error while fetching view: ")
@@ -798,6 +810,7 @@ export class NextDrupal extends NextDrupalBase {
798810
const response = await this.fetch(endpoint, {
799811
withAuth: options.withAuth,
800812
next: options.next,
813+
cache: options.cache,
801814
})
802815

803816
await this.throwIfJsonErrors(

packages/next-drupal/src/types/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type JsonApiWithCacheOptions = {
3636

3737
export type JsonApiWithNextFetchOptions = {
3838
next?: NextFetchRequestConfig
39+
cache?: RequestCache
3940
}
4041
// TODO: Properly type this.
4142
/* eslint-disable @typescript-eslint/no-explicit-any */

packages/next-drupal/tests/NextDrupal/resource-methods.test.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,25 @@ describe("getMenu()", () => {
281281
})
282282
)
283283
})
284+
285+
test("makes request with cache option", async () => {
286+
const drupal = new NextDrupal(BASE_URL)
287+
const mockInit = {
288+
cache: "no-store",
289+
} as FetchOptions
290+
291+
const fetchSpy = spyOnFetch()
292+
293+
await drupal.getMenu("main", mockInit)
294+
295+
expect(fetchSpy).toBeCalledTimes(1)
296+
expect(fetchSpy).toBeCalledWith(
297+
expect.anything(),
298+
expect.objectContaining({
299+
...mockInit,
300+
})
301+
)
302+
})
284303
})
285304

286305
describe("getResource()", () => {
@@ -512,6 +531,29 @@ describe("getResource()", () => {
512531
})
513532
)
514533
})
534+
535+
test("makes request with cache option", async () => {
536+
const drupal = new NextDrupal(BASE_URL)
537+
const mockInit = {
538+
cache: "no-store",
539+
} as FetchOptions
540+
541+
const fetchSpy = spyOnFetch()
542+
543+
await drupal.getResource(
544+
"node--recipe",
545+
"71e04ead-4cc7-416c-b9ca-60b635fdc50f",
546+
mockInit
547+
)
548+
549+
expect(fetchSpy).toBeCalledTimes(1)
550+
expect(fetchSpy).toBeCalledWith(
551+
expect.anything(),
552+
expect.objectContaining({
553+
...mockInit,
554+
})
555+
)
556+
})
515557
})
516558

517559
describe("getResourceByPath()", () => {
@@ -830,6 +872,32 @@ describe("getResourceByPath()", () => {
830872
})
831873
)
832874
})
875+
876+
test("makes request with cache option", async () => {
877+
const drupal = new NextDrupal(BASE_URL)
878+
const mockInit = {
879+
cache: "no-store",
880+
} as FetchOptions
881+
882+
const fetchSpy = spyOnFetch({
883+
status: 207,
884+
statusText: "Multi-Status",
885+
responseBody: mocks.resources.subRequests.ok,
886+
})
887+
888+
await drupal.getResourceByPath<DrupalNode>(
889+
"/recipes/deep-mediterranean-quiche",
890+
mockInit
891+
)
892+
893+
expect(fetchSpy).toBeCalledTimes(1)
894+
expect(fetchSpy).toBeCalledWith(
895+
expect.anything(),
896+
expect.objectContaining({
897+
...mockInit,
898+
})
899+
)
900+
})
833901
})
834902

835903
describe("getResourceCollection()", () => {
@@ -957,6 +1025,25 @@ describe("getResourceCollection()", () => {
9571025
})
9581026
)
9591027
})
1028+
1029+
test("makes request with cache option", async () => {
1030+
const drupal = new NextDrupal(BASE_URL)
1031+
const mockInit = {
1032+
cache: "no-store",
1033+
} as FetchOptions
1034+
1035+
const fetchSpy = spyOnFetch()
1036+
1037+
await drupal.getResourceCollection("node--recipe", mockInit)
1038+
1039+
expect(fetchSpy).toBeCalledTimes(1)
1040+
expect(fetchSpy).toBeCalledWith(
1041+
expect.anything(),
1042+
expect.objectContaining({
1043+
...mockInit,
1044+
})
1045+
)
1046+
})
9601047
})
9611048

9621049
describe("getResourceCollectionPathSegments()", () => {
@@ -1116,6 +1203,27 @@ describe("getResourceCollectionPathSegments()", () => {
11161203
})
11171204
)
11181205
})
1206+
1207+
test("makes request with cache option", async () => {
1208+
const drupal = new NextDrupal(BASE_URL)
1209+
const mockInit = {
1210+
cache: "no-store",
1211+
} as FetchOptions
1212+
1213+
const fetchSpy = spyOnFetch({
1214+
responseBody: { data: [] },
1215+
})
1216+
1217+
await drupal.getResourceCollectionPathSegments("node--article", mockInit)
1218+
1219+
expect(fetchSpy).toBeCalledTimes(1)
1220+
expect(fetchSpy).toBeCalledWith(
1221+
expect.anything(),
1222+
expect.objectContaining({
1223+
...mockInit,
1224+
})
1225+
)
1226+
})
11191227
})
11201228

11211229
describe("getSearchIndex()", () => {
@@ -1246,6 +1354,25 @@ describe("getSearchIndex()", () => {
12461354
})
12471355
)
12481356
})
1357+
1358+
test("makes request with cache option", async () => {
1359+
const drupal = new NextDrupal(BASE_URL)
1360+
const mockInit = {
1361+
cache: "no-store",
1362+
} as FetchOptions
1363+
1364+
const fetchSpy = spyOnFetch()
1365+
1366+
await drupal.getSearchIndex("recipes", mockInit)
1367+
1368+
expect(fetchSpy).toBeCalledTimes(1)
1369+
expect(fetchSpy).toBeCalledWith(
1370+
expect.anything(),
1371+
expect.objectContaining({
1372+
...mockInit,
1373+
})
1374+
)
1375+
})
12491376
})
12501377

12511378
describe("getView()", () => {
@@ -1369,6 +1496,25 @@ describe("getView()", () => {
13691496
})
13701497
)
13711498
})
1499+
1500+
test("makes request with cache option", async () => {
1501+
const drupal = new NextDrupal(BASE_URL)
1502+
const mockInit = {
1503+
cache: "no-store",
1504+
} as FetchOptions
1505+
1506+
const fetchSpy = spyOnFetch()
1507+
1508+
await drupal.getView("featured_articles--page_1", mockInit)
1509+
1510+
expect(fetchSpy).toBeCalledTimes(1)
1511+
expect(fetchSpy).toBeCalledWith(
1512+
expect.anything(),
1513+
expect.objectContaining({
1514+
...mockInit,
1515+
})
1516+
)
1517+
})
13721518
})
13731519

13741520
describe("translatePath()", () => {
@@ -1478,4 +1624,23 @@ describe("translatePath()", () => {
14781624
})
14791625
)
14801626
})
1627+
1628+
test("makes request with cache option", async () => {
1629+
const drupal = new NextDrupal(BASE_URL)
1630+
const mockInit = {
1631+
cache: "no-store",
1632+
} as FetchOptions
1633+
1634+
const fetchSpy = spyOnFetch()
1635+
1636+
await drupal.translatePath("recipes/deep-mediterranean-quiche", mockInit)
1637+
1638+
expect(fetchSpy).toBeCalledTimes(1)
1639+
expect(fetchSpy).toBeCalledWith(
1640+
expect.anything(),
1641+
expect.objectContaining({
1642+
...mockInit,
1643+
})
1644+
)
1645+
})
14811646
})

packages/next-drupal/tests/NextDrupalBase/fetch-methods.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,27 @@ describe("fetch()", () => {
200200
})
201201
)
202202
})
203+
204+
test("optionally adds cache option", async () => {
205+
const drupal = new NextDrupalBase(BASE_URL)
206+
const mockUrl = "/mock-url"
207+
const mockInit = {
208+
cache: "no-store",
209+
} as FetchOptions
210+
211+
const fetchSpy = spyOnFetch()
212+
213+
await drupal.fetch(mockUrl, mockInit)
214+
215+
expect(fetchSpy).toBeCalledTimes(1)
216+
expect(fetchSpy).toBeCalledWith(
217+
`${BASE_URL}${mockUrl}`,
218+
expect.objectContaining({
219+
...defaultInit,
220+
...mockInit,
221+
})
222+
)
223+
})
203224
})
204225

205226
describe("getAccessToken()", () => {

0 commit comments

Comments
 (0)