@sensinum/astro-strapi-loader
Version:
Astro loader for Strapi CMS
124 lines (123 loc) • 4.91 kB
JavaScript
import qs from "qs";
import { fetchContent } from "./strapi";
export function strapiLoader(contentType, options, query = {}) {
return ({
name: options.collectionName || "strapi-loader",
load: async (context) => {
const { store, logger, parseData, generateDigest } = context;
const collectionName = options.collectionName || contentType;
logger.info(`[${collectionName}] Loading data from Strapi...`);
const { url, token, idGenerator, locale, headers } = options;
store.clear();
// Determine which locales to fetch
const localesToFetch = locale
? Array.isArray(locale)
? locale
: [locale]
: undefined;
// If no locales specified, fetch with the original query
if (!localesToFetch) {
await fetchAndStoreData({ url, token, contentType, query, headers }, { store, logger, parseData, generateDigest, idGenerator, collectionName });
}
else {
// Fetch data for each locale separately
const localeDataMap = {};
for (const loc of localesToFetch) {
const localeQuery = { ...query, locale: loc };
const response = await fetchContent({
url,
token,
contentType,
queryParams: qs.stringify(localeQuery),
headers,
});
if (response.data && response.data.length > 0) {
localeDataMap[loc] = response.data;
}
else if (response.data && !Array.isArray(response.data)) {
localeDataMap[loc] = response.data;
}
}
if (Object.keys(localeDataMap).length === 0) {
logger.info(`[${collectionName}] No data found in Strapi`);
return;
}
// Store data with locale structure
await storeLocaleData(localeDataMap, { store, parseData, generateDigest, idGenerator });
}
logger.info(`[${collectionName}] Loading data from Strapi... DONE`);
},
});
}
async function fetchAndStoreData(fetchOptions, storeOptions) {
const { url, token, contentType, query, headers } = fetchOptions;
const { store, logger, parseData, generateDigest, idGenerator, collectionName } = storeOptions;
const response = await fetchContent({
url,
token,
contentType,
queryParams: query ? qs.stringify(query) : undefined,
headers,
});
if (response.data.length === 0) {
logger.info(`[${collectionName}] No data found in Strapi`);
return;
}
const getItemId = (item) => {
if (idGenerator) {
return idGenerator(item);
}
return item.documentId;
};
if (Array.isArray(response.data)) {
await Promise.all(response.data.map(async (item) => {
const itemId = getItemId(item);
const data = await parseData({
id: itemId,
data: item,
});
const digest = generateDigest(data);
store.set({ id: itemId, data, digest });
}));
}
else {
const itemId = getItemId(response.data);
const data = await parseData({
id: itemId,
data: response.data,
});
const digest = generateDigest(data);
store.set({ id: itemId, data, digest });
}
}
async function storeLocaleData(localeDataMap, storeOptions) {
const { store, parseData, generateDigest, idGenerator } = storeOptions;
const getItemId = (item, locale) => {
if (idGenerator) {
return `${locale}:${idGenerator(item)}`;
}
return `${locale}:${item.documentId}`;
};
for (const [locale, data] of Object.entries(localeDataMap)) {
if (Array.isArray(data)) {
await Promise.all(data.map(async (item) => {
const itemId = getItemId(item, locale);
const parsedData = await parseData({
id: itemId,
data: { ...item, _locale: locale },
});
const digest = generateDigest(parsedData);
store.set({ id: itemId, data: parsedData, digest });
}));
}
else {
const itemId = getItemId(data, locale);
const parsedData = await parseData({
id: itemId,
data: { ...data, _locale: locale },
});
const digest = generateDigest(parsedData);
store.set({ id: itemId, data: parsedData, digest });
}
}
}