UNPKG

astro-pocketbase-loader

Version:

A content loader for Astro that uses the PocketBase API

90 lines (77 loc) 3.44 kB
import type { Loader, LoaderContext } from "astro/loaders"; import packageJson from "./../package.json"; import { cleanupEntries } from "./cleanup-entries"; import { generateSchema } from "./generate-schema"; import { loadEntries } from "./load-entries"; import type { PocketBaseLoaderOptions } from "./types/pocketbase-loader-options.type"; import { getAdminToken } from "./utils/get-admin-token"; /** * Loader for collections stored in PocketBase. * * @param options Options for the loader. See {@link PocketBaseLoaderOptions} for more details. */ export function pocketbaseLoader(options: PocketBaseLoaderOptions): Loader { return { name: "pocketbase-loader", load: async (context: LoaderContext): Promise<void> => { // Check if the version has changed to force an update const lastVersion = context.meta.get("version"); if (lastVersion !== packageJson.version) { context.logger.info( `PocketBase loader was updated from ${lastVersion} to ${packageJson.version}. All entries will be loaded again.` ); options.forceUpdate = true; } // Get the date of the last fetch to only update changed entries. // If `forceUpdate` is set to `true`, this will be `undefined` to fetch all entries again. const lastModified = options.forceUpdate ? undefined : context.meta.get("last-modified"); // Get the `has-updated-column` meta to check if the collection has an updated column let hasUpdatedColumn = context.meta.get("has-updated-column") === "true"; // Clear the store if we want to fetch all entries again if (options.forceUpdate) { context.store.clear(); } // Try to get an admin token to access all resources. let token: string | undefined; if (options.adminEmail && options.adminPassword) { token = await getAdminToken( options.url, options.adminEmail, options.adminPassword, context.logger ); } if (context.store.keys().length > 0) { // Cleanup entries that are no longer in the collection await cleanupEntries(options, context, token); } // Load the (modified) entries try { hasUpdatedColumn = await loadEntries( options, context, token, // Only fetch entries that have been modified since the last fetch // If the collection does not have an updated column, all entries will be fetched hasUpdatedColumn ? lastModified : undefined ); } catch (error) { // Set the `has-updated-column` meta to `false` if an error occurred // This will force the loader to fetch all entries again in the next run context.meta.set("has-updated-column", `${false}`); throw error; } // Set the `has-updated-column` meta to `true` if the collection has an updated column context.meta.set("has-updated-column", `${hasUpdatedColumn}`); // Set the last modified date to the current date context.meta.set("last-modified", new Date().toISOString()); context.meta.set("version", packageJson.version); }, schema: async () => { // Generate the schema for the collection according to the API return await generateSchema(options); } }; }