@rmdes/indiekit-endpoint-github 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/github-graphql.js +57 -65
- package/package.json +1 -1
package/lib/github-graphql.js
CHANGED
|
@@ -46,15 +46,6 @@ const LISTS_QUERY = `
|
|
|
46
46
|
slug
|
|
47
47
|
description
|
|
48
48
|
isPrivate
|
|
49
|
-
items(first: 100) {
|
|
50
|
-
totalCount
|
|
51
|
-
nodes {
|
|
52
|
-
... on Repository {
|
|
53
|
-
nameWithOwner
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
pageInfo { endCursor hasNextPage }
|
|
57
|
-
}
|
|
58
49
|
}
|
|
59
50
|
pageInfo { endCursor hasNextPage }
|
|
60
51
|
}
|
|
@@ -183,11 +174,11 @@ export async function fetchAllLists(token) {
|
|
|
183
174
|
throw new Error("GitHub token is required for GraphQL API");
|
|
184
175
|
}
|
|
185
176
|
|
|
186
|
-
|
|
177
|
+
// Stage 1: Fetch list metadata only (no items — avoids timeout)
|
|
178
|
+
const listMeta = [];
|
|
187
179
|
let cursor = null;
|
|
188
180
|
let hasNextPage = true;
|
|
189
181
|
|
|
190
|
-
// Fetch all lists (outer pagination)
|
|
191
182
|
while (hasNextPage) {
|
|
192
183
|
const response = await fetch(GITHUB_GRAPHQL_URL, {
|
|
193
184
|
method: "POST",
|
|
@@ -214,73 +205,74 @@ export async function fetchAllLists(token) {
|
|
|
214
205
|
const listsData = body.data.viewer.lists;
|
|
215
206
|
|
|
216
207
|
for (const node of listsData.nodes) {
|
|
217
|
-
// Skip private lists
|
|
218
208
|
if (node.isPrivate) continue;
|
|
219
|
-
|
|
220
|
-
const repoFullNames = (node.items.nodes || [])
|
|
221
|
-
.map((n) => n.nameWithOwner)
|
|
222
|
-
.filter(Boolean);
|
|
223
|
-
|
|
224
|
-
const list = {
|
|
209
|
+
listMeta.push({
|
|
225
210
|
name: node.name,
|
|
226
211
|
slug: node.slug,
|
|
227
212
|
description: node.description || "",
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
// If this list has more items than the first page, paginate them
|
|
232
|
-
if (node.items.pageInfo.hasNextPage) {
|
|
233
|
-
let itemsCursor = node.items.pageInfo.endCursor;
|
|
234
|
-
let itemsHasNext = true;
|
|
235
|
-
|
|
236
|
-
while (itemsHasNext) {
|
|
237
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
238
|
-
|
|
239
|
-
const itemsResponse = await fetch(GITHUB_GRAPHQL_URL, {
|
|
240
|
-
method: "POST",
|
|
241
|
-
headers: {
|
|
242
|
-
Authorization: `Bearer ${token}`,
|
|
243
|
-
"Content-Type": "application/json",
|
|
244
|
-
},
|
|
245
|
-
body: JSON.stringify({
|
|
246
|
-
query: LIST_ITEMS_QUERY,
|
|
247
|
-
variables: { slug: node.slug, cursor: itemsCursor },
|
|
248
|
-
}),
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
if (!itemsResponse.ok) {
|
|
252
|
-
console.error(`[GitHub Lists] Failed to paginate items for list "${node.name}": ${itemsResponse.status}`);
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
255
215
|
|
|
256
|
-
|
|
216
|
+
cursor = listsData.pageInfo.endCursor;
|
|
217
|
+
hasNextPage = listsData.pageInfo.hasNextPage;
|
|
257
218
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
219
|
+
if (hasNextPage) {
|
|
220
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
262
223
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (itemNode.nameWithOwner) {
|
|
266
|
-
list.repoFullNames.push(itemNode.nameWithOwner);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
224
|
+
// Stage 2: Fetch items per list individually (avoids timeout from bulk query)
|
|
225
|
+
const allLists = [];
|
|
269
226
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
227
|
+
for (const meta of listMeta) {
|
|
228
|
+
const repoFullNames = [];
|
|
229
|
+
let itemsCursor = null;
|
|
230
|
+
let itemsHasNext = true;
|
|
231
|
+
|
|
232
|
+
while (itemsHasNext) {
|
|
233
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
234
|
+
|
|
235
|
+
const itemsResponse = await fetch(GITHUB_GRAPHQL_URL, {
|
|
236
|
+
method: "POST",
|
|
237
|
+
headers: {
|
|
238
|
+
Authorization: `Bearer ${token}`,
|
|
239
|
+
"Content-Type": "application/json",
|
|
240
|
+
},
|
|
241
|
+
body: JSON.stringify({
|
|
242
|
+
query: LIST_ITEMS_QUERY,
|
|
243
|
+
variables: { slug: meta.slug, cursor: itemsCursor },
|
|
244
|
+
}),
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (!itemsResponse.ok) {
|
|
248
|
+
console.error(`[GitHub Lists] Failed to fetch items for list "${meta.name}": ${itemsResponse.status}`);
|
|
249
|
+
break;
|
|
273
250
|
}
|
|
274
251
|
|
|
275
|
-
|
|
276
|
-
}
|
|
252
|
+
const itemsBody = await itemsResponse.json();
|
|
277
253
|
|
|
278
|
-
|
|
279
|
-
|
|
254
|
+
if (itemsBody.errors) {
|
|
255
|
+
console.error(`[GitHub Lists] GraphQL errors for list "${meta.name}": ${itemsBody.errors.map((e) => e.message).join(", ")}`);
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
280
258
|
|
|
281
|
-
|
|
282
|
-
|
|
259
|
+
const itemsData = itemsBody.data.viewer.list.items;
|
|
260
|
+
for (const itemNode of itemsData.nodes) {
|
|
261
|
+
if (itemNode.nameWithOwner) {
|
|
262
|
+
repoFullNames.push(itemNode.nameWithOwner);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
itemsCursor = itemsData.pageInfo.endCursor;
|
|
267
|
+
itemsHasNext = itemsData.pageInfo.hasNextPage;
|
|
283
268
|
}
|
|
269
|
+
|
|
270
|
+
allLists.push({
|
|
271
|
+
name: meta.name,
|
|
272
|
+
slug: meta.slug,
|
|
273
|
+
description: meta.description,
|
|
274
|
+
repoFullNames,
|
|
275
|
+
});
|
|
284
276
|
}
|
|
285
277
|
|
|
286
278
|
console.log(`[GitHub Lists] Fetched ${allLists.length} public lists`);
|
package/package.json
CHANGED