-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathload-entries.ts
More file actions
121 lines (106 loc) · 3.74 KB
/
Copy pathload-entries.ts
File metadata and controls
121 lines (106 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import type { LoaderContext } from "astro/loaders";
import type { PocketBaseLoaderOptions } from "../types/pocketbase-loader-options.type";
import { parseEntry } from "./parse-entry";
/**
* Load (modified) entries from a PocketBase collection.
*
* @param options Options for the loader.
* @param context Context of the loader.
* @param superuserToken Superuser token to access all resources.
* @param lastModified Date of the last fetch to only update changed entries.
*
* @returns `true` if the collection has an updated column, `false` otherwise.
*/
export async function loadEntries(
options: PocketBaseLoaderOptions,
context: LoaderContext,
superuserToken: string | undefined,
lastModified: string | undefined
): Promise<void> {
// Build the URL for the collections endpoint
const collectionUrl = new URL(
`api/collections/${options.collectionName}/records`,
options.url
).href;
// Create the headers for the request to append the superuser token (if available)
const collectionHeaders = new Headers();
if (superuserToken) {
collectionHeaders.set("Authorization", superuserToken);
}
// Log the fetching of the entries
context.logger.info(
`Fetching${lastModified ? " modified" : ""} data${
lastModified ? ` starting at ${lastModified}` : ""
}${superuserToken ? " as superuser" : ""}`
);
// Prepare pagination variables
let page = 0;
let totalPages = 0;
let entries = 0;
// Fetch all (modified) entries
do {
// Build search parameters
const searchParams = new URLSearchParams({
page: `${++page}`,
perPage: "100"
});
const filters = [];
if (lastModified && options.updatedField) {
// If `lastModified` is set, only fetch entries that have been modified since the last fetch
filters.push(`(${options.updatedField}>"${lastModified}")`);
// Sort by the updated field and id
searchParams.set("sort", `-${options.updatedField},id`);
}
if (options.filter) {
filters.push(`(${options.filter})`);
}
// Add filters to search parameters
if (filters.length > 0) {
searchParams.set("filter", filters.join("&&"));
}
// Add filters to search parameters
if (options.expand) {
searchParams.set("expand", options.expand.join(","));
}
// Fetch entries from the collection
const collectionRequest = await fetch(
`${collectionUrl}?${searchParams.toString()}`,
{
headers: collectionHeaders
}
);
// If the request was not successful, print the error message and return
if (!collectionRequest.ok) {
// If the collection is locked, an superuser token is required
if (collectionRequest.status === 403) {
throw new Error(
`The collection is not accessible without superuser rights. Please provide superuser credentials in the config.`
);
}
// Get the reason for the error
const reason = await collectionRequest
.json()
.then((data) => data.message);
const errorMessage = `Fetching data failed with status code ${collectionRequest.status}.\nReason: ${reason}`;
throw new Error(errorMessage);
}
// Get the data from the response
const response = await collectionRequest.json();
// Parse and store the entries
for (const entry of response.items) {
await parseEntry(entry, context, options);
}
// Update the page and total pages
page = response.page;
totalPages = response.totalPages;
entries += response.items.length;
} while (page < totalPages);
// Log the number of fetched entries
if (lastModified) {
context.logger.info(
`Updated ${entries}/${context.store.keys().length} entries.`
);
} else {
context.logger.info(`Fetched ${entries} entries.`);
}
}