gatsby-source-payload-cms
Version:
Source data from Payload CMS
205 lines (204 loc) • 11.1 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchEntities = exports.fetchEntity = void 0;
/**
* fetch entity (global) or entities (collection)
*
* Common functionality for both functions:
*
* * Add a `gatsbyNodeType` key to each entity.
* * If locales are defined for a global/collection, return all localized entities and add a `locale` key.
*/
const qs_1 = __importDefault(require("qs"));
const lodash_1 = require("lodash");
const format_entity_1 = require("./format-entity");
const utils_1 = require("./utils");
const fetchEntity = (query, context) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const { reporter, axiosInstance } = context;
const params = query.params || {};
/** @type AxiosRequestConfig */
const options = {
method: `GET`,
url: query.endpoint,
params: Object.assign(Object.assign({}, params), ((0, lodash_1.isNumber)(query.limit) && { limit: query.limit })),
// Source: https://github.com/axios/axios/issues/5058#issuecomment-1379970592
paramsSerializer: {
serialize: (parameters) => qs_1.default.stringify(parameters, { encodeValuesOnly: true }),
},
};
try {
reporter.info((0, utils_1.fetchDataMessage)(options.url, options.paramsSerializer.serialize(options.params)));
// Handle internationalization
const fallbackLocale = (_a = context.pluginOptions) === null || _a === void 0 ? void 0 : _a.fallbackLocale;
const locales = query.locales || [];
/**
* If locales are defined for a collection/global, return
* multiple nodes (rather than an obect keyed by locale, as
* stored in the Payload database). This is better for Gatsby
* as we can read `updatedAt` for timestamps, set a `type` on
* the data...etc.
*
* i.e. it is better to treat each translation as a node.
*/
if (locales.length > 0) {
const localizationsPromises = locales.map((locale) => __awaiter(void 0, void 0, void 0, function* () {
const localeString = (0, lodash_1.isString)(locale) ? locale : locale.locale;
const { data: localizationResponse } = yield axiosInstance(Object.assign(Object.assign({}, options), { params: Object.assign(Object.assign(Object.assign({}, params), { fallbackLocale, locale: localeString }), ((0, lodash_1.isObject)(locale) && locale.params)) }));
return (0, format_entity_1.formatEntity)({
data: localizationResponse,
locale: localeString,
gatsbyNodeType: query.type,
}, context);
}));
// Run queries in parallel
const localizationsData = yield Promise.all(localizationsPromises);
return localizationsData;
}
else {
// Fetch default entity based on request options
const { data } = yield axiosInstance(options);
return [
(0, format_entity_1.formatEntity)({
data,
gatsbyNodeType: query.type,
}, context),
];
}
}
catch (error) {
if (error.response.status !== 404) {
reporter.panic(`Failed to fetch data from Payload ${options.url} with ${JSON.stringify(options)}`, error);
}
return [];
}
});
exports.fetchEntity = fetchEntity;
const fetchEntities = (query, context) => __awaiter(void 0, void 0, void 0, function* () {
var _b;
const { reporter, axiosInstance } = context;
const params = query.params || {};
const skipPagination = (0, lodash_1.isNumber)(query.limit);
const repopulate = query.repopulate || false;
/** @type AxiosRequestConfig */
const options = {
method: `GET`,
url: query.endpoint,
params: Object.assign(Object.assign({}, params), (skipPagination && { limit: query.limit })),
paramsSerializer: {
serialize: (parameters) => qs_1.default.stringify(parameters, { encodeValuesOnly: true }),
},
};
try {
reporter.info((0, utils_1.fetchDataMessage)(options.url, options.paramsSerializer.serialize(options.params)));
/**
* Always get non-localized response to either:
*
* * return non-localized collection; or
* * determine pagination for localized collection.
*/
const { data: response } = yield axiosInstance(options);
const data = (response === null || response === void 0 ? void 0 : response.docs) || response;
const page = Number.parseInt(response.page || 1, 10);
const pageCount = Number.parseInt(response.totalPages || 1, 10);
let pagesToGet = Array.from({
length: pageCount - page,
}).map((_, index) => index + page + 1);
// Handle internationalization
// If locales are active, always fetch page 1 - we need to rerun the query to get localizations.
const locales = query.locales || [];
if (skipPagination) {
pagesToGet = [];
}
if (locales.length > 0) {
pagesToGet = [1, ...pagesToGet];
if (skipPagination) {
pagesToGet = [1];
}
}
const fallbackLocale = (_b = context.pluginOptions) === null || _b === void 0 ? void 0 : _b.fallbackLocale;
if (locales.length > 0) {
const localizationsPromises = locales.map((locale) => __awaiter(void 0, void 0, void 0, function* () {
const localeString = (0, lodash_1.isString)(locale) ? locale : locale.locale;
const fetchPagesPromises = pagesToGet.map((page) => {
return (() => __awaiter(void 0, void 0, void 0, function* () {
const fetchOptions = Object.assign(Object.assign({}, options), { params: Object.assign(Object.assign(Object.assign({}, options.params), { page,
fallbackLocale, locale: localeString }), ((0, lodash_1.isObject)(locale) && locale.params)) });
reporter.info((0, utils_1.fetchDataMessage)(fetchOptions.url, options.paramsSerializer.serialize(fetchOptions.params)));
try {
const data = yield axiosInstance(fetchOptions);
return data.data.docs;
}
catch (error) {
reporter.panic(`Failed to fetch data from Payload ${fetchOptions.url}`, error);
}
}))();
});
const results = yield Promise.all(fetchPagesPromises);
if (!repopulate) {
return (0, lodash_1.flattenDeep)(results)
.map((entry) => (0, format_entity_1.formatEntity)(Object.assign({ data: entry, gatsbyNodeType: query.type, locale: localeString }, (query.imageSize && { payloadImageSize: query.imageSize })), context))
.filter((entity) => !(0, lodash_1.isEmpty)(entity));
}
// repopulate results
const fetchOptions = Object.assign(Object.assign({}, options), { params: Object.assign(Object.assign(Object.assign({}, options.params), { fallbackLocale, locale: localeString }), ((0, lodash_1.isObject)(locale) && locale.params)) });
const articlePromises = (0, lodash_1.flattenDeep)(results).map((doc) => {
return (() => __awaiter(void 0, void 0, void 0, function* () {
const options = Object.assign(Object.assign({}, fetchOptions), { url: `${fetchOptions.url}/${doc.id}` });
try {
const data = yield axiosInstance(options);
return data.data;
}
catch (error) {
reporter.panic(`Failed to fetch data from Payload ${options.url}`, error);
}
}))();
});
const repopulatedResults = yield Promise.all(articlePromises);
return (0, lodash_1.flattenDeep)(repopulatedResults)
.map((entry) => (0, format_entity_1.formatEntity)(Object.assign({ data: entry, gatsbyNodeType: query.type, locale: localeString }, (query.imageSize && { payloadImageSize: query.imageSize })), context))
.filter((entity) => !(0, lodash_1.isEmpty)(entity));
}));
// Run queries in parallel
const localizationsData = yield Promise.all(localizationsPromises);
return (0, lodash_1.flattenDeep)(localizationsData);
}
else {
const fetchPagesPromises = pagesToGet.map((page) => {
return (() => __awaiter(void 0, void 0, void 0, function* () {
const fetchOptions = Object.assign(Object.assign({}, options), { params: Object.assign(Object.assign({}, options.params), { page }) });
reporter.info((0, utils_1.fetchDataMessage)(fetchOptions.url, options.paramsSerializer.serialize(fetchOptions.params)));
try {
const data = yield axiosInstance(fetchOptions);
return data.data.docs;
}
catch (error) {
reporter.panic(`Failed to fetch data from Payload ${fetchOptions.url}`, error);
}
}))();
});
const results = yield Promise.all(fetchPagesPromises);
const cleanedData = [...data, ...(0, lodash_1.flattenDeep)(results)]
.map((entry) => (0, format_entity_1.formatEntity)(Object.assign({ data: entry, gatsbyNodeType: query.type }, (query.imageSize && { payloadImageSize: query.imageSize })), context))
.filter((entity) => !(0, lodash_1.isEmpty)(entity));
return cleanedData;
}
}
catch (error) {
reporter.panic(`Failed to fetch data from Payload ${options.url}`, error);
return [];
}
});
exports.fetchEntities = fetchEntities;