Skip to content

Commit 5612ec3

Browse files
authored
Merge pull request #69 from microcmsio/feat/get-all-contents
feat: getAllContents
2 parents d2873f1 + 29a3a05 commit 5612ec3

File tree

5 files changed

+148
-3
lines changed

5 files changed

+148
-3
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "microcms-js-sdk",
3-
"version": "2.6.1",
3+
"version": "2.7.0",
44
"description": "JavaScript SDK Client for microCMS.",
55
"main": "./dist/microcms-js-sdk.js",
66
"module": "./dist/esm/microcms-js-sdk.js",

src/createClient.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
DeleteRequest,
2121
GetAllContentIdsRequest,
2222
MicroCMSQueries,
23+
GetAllContentRequest,
2324
} from './types';
2425
import {
2526
API_VERSION,
@@ -278,6 +279,46 @@ export const createClient = ({
278279
return contentIds;
279280
};
280281

282+
/**
283+
* Get all content API data for microCMS
284+
*/
285+
const getAllContents = async <T = any>({
286+
endpoint,
287+
queries = {},
288+
customRequestInit,
289+
}: GetAllContentRequest): Promise<(T & MicroCMSListContent)[]> => {
290+
const limit = 100;
291+
292+
const { totalCount } = await makeRequest({
293+
endpoint,
294+
queries: { ...queries, limit: 0 },
295+
requestInit: customRequestInit,
296+
});
297+
298+
let contents: (T & MicroCMSListContent)[] = [];
299+
let offset = 0;
300+
301+
const sleep = (ms: number) =>
302+
new Promise((resolve) => setTimeout(resolve, ms));
303+
304+
while (contents.length < totalCount) {
305+
const { contents: _contents } = (await makeRequest({
306+
endpoint,
307+
queries: { ...queries, limit, offset },
308+
requestInit: customRequestInit,
309+
})) as MicroCMSListResponse<T>;
310+
311+
contents = contents.concat(_contents);
312+
313+
offset += limit;
314+
if (contents.length < totalCount) {
315+
await sleep(1000); // sleep for 1 second before the next request
316+
}
317+
}
318+
319+
return contents;
320+
};
321+
281322
/**
282323
* Create new content in the microCMS list API data
283324
*/
@@ -371,6 +412,7 @@ export const createClient = ({
371412
getListDetail,
372413
getObject,
373414
getAllContentIds,
415+
getAllContents,
374416
create,
375417
update,
376418
delete: _delete,

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ export interface GetAllContentIdsRequest {
129129
customRequestInit?: CustomRequestInit;
130130
}
131131

132+
export interface GetAllContentRequest {
133+
endpoint: string;
134+
queries?: Omit<MicroCMSQueries, 'limit' | 'offset' | 'ids'>;
135+
customRequestInit?: CustomRequestInit;
136+
}
137+
132138
export interface WriteApiRequestResult {
133139
id: string;
134140
}

tests/getAllContents.test.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { rest } from 'msw';
2+
import { createClient } from '../src/createClient';
3+
import { testBaseUrl } from './mocks/handlers';
4+
import { server } from './mocks/server';
5+
6+
const client = createClient({
7+
serviceDomain: 'serviceDomain',
8+
apiKey: 'apiKey',
9+
});
10+
11+
describe('getAllContents', () => {
12+
afterEach(() => {
13+
jest.resetAllMocks();
14+
});
15+
16+
test('should fetch all contents', async () => {
17+
server.use(
18+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
19+
return res.once(
20+
ctx.status(200),
21+
ctx.json({
22+
totalCount: 100,
23+
}),
24+
);
25+
}),
26+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
27+
return res.once(
28+
ctx.status(200),
29+
ctx.json({
30+
contents: Array(100)
31+
.fill(null)
32+
.map((_, index) => ({ id: `id${index}` })),
33+
}),
34+
);
35+
}),
36+
);
37+
38+
const result = await client.getAllContents({
39+
endpoint: 'getAllContents-list-type',
40+
});
41+
42+
expect(result).toHaveLength(100);
43+
expect(result).toContainEqual({ id: 'id0' });
44+
expect(result).toContainEqual({ id: 'id99' });
45+
});
46+
47+
test('should handle pagination and fetch more than limit', async () => {
48+
server.use(
49+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
50+
return res.once(
51+
ctx.status(200),
52+
ctx.json({
53+
totalCount: 250,
54+
}),
55+
);
56+
}),
57+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
58+
return res.once(
59+
ctx.status(200),
60+
ctx.json({
61+
contents: Array(100)
62+
.fill(null)
63+
.map((_, index) => ({ id: `id${index}` })),
64+
}),
65+
);
66+
}),
67+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
68+
return res.once(
69+
ctx.status(200),
70+
ctx.json({
71+
contents: Array(100)
72+
.fill(null)
73+
.map((_, index) => ({ id: `id${index + 100}` })),
74+
}),
75+
);
76+
}),
77+
rest.get(`${testBaseUrl}/getAllContents-list-type`, (_, res, ctx) => {
78+
return res.once(
79+
ctx.status(200),
80+
ctx.json({
81+
contents: Array(50)
82+
.fill(null)
83+
.map((_, index) => ({ id: `id${index + 200}` })),
84+
}),
85+
);
86+
}),
87+
);
88+
89+
const result = await client.getAllContents({
90+
endpoint: 'getAllContents-list-type',
91+
});
92+
93+
expect(result).toHaveLength(250);
94+
expect(result).toContainEqual({ id: 'id0' });
95+
expect(result).toContainEqual({ id: 'id249' });
96+
});
97+
});

0 commit comments

Comments
 (0)