gatsby-source-cloudbase-cms
Version:
Gatsby source plugin for building websites using CloudBase CMS as a data source
150 lines (124 loc) • 4.73 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _lodash = _interopRequireWildcard(require("lodash"));
var _fetch = _interopRequireDefault(require("./fetch"));
var _nodes = require("./nodes");
var _normalize = _interopRequireDefault(require("./normalize"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const toTypeInfo = type => {
if (typeof type === 'object') {
return {
endpoint: type.endpoint || type.name,
name: type.name,
api: type.api
};
}
return {
endpoint: type,
name: type
};
};
const contentTypeToTypeInfo = toTypeInfo;
const singleTypeToTypeInfo = singleType => toTypeInfo(singleType, {
single: true
});
const fetchEntities = async (entityDefinition, ctx) => {
const entities = await (0, _fetch.default)(entityDefinition, ctx);
await _normalize.default.downloadMediaFiles(entities, ctx);
return entities;
};
const addDynamicZoneFieldsToSchema = ({
type,
items,
actions,
schema
}) => {
const {
createTypes
} = actions; // Search for dynamic zones in all items
const dynamicZoneFields = {};
items.forEach(item => {
_lodash.default.forEach(item, (value, field) => {
if (_normalize.default.isDynamicZone(value)) {
dynamicZoneFields[field] = 'JSON';
}
});
}); // Cast dynamic zone fields to JSON
if (!_lodash.default.isEmpty(dynamicZoneFields)) {
const typeDef = schema.buildObjectType({
name: `CloudBase${(0, _lodash.upperFirst)((0, _lodash.camelCase)(type))}`,
fields: dynamicZoneFields,
interfaces: ['Node']
});
createTypes([typeDef]);
}
};
exports.sourceNodes = async ({
store,
actions,
cache,
reporter,
getNode,
getNodes,
createNodeId,
createContentDigest,
schema
}, {
apiURL,
apiToken,
fetchOptions,
queryLimit = 100,
...options
}) => {
const {
createNode,
deleteNode,
touchNode
} = actions;
const ctx = {
store,
cache,
getNode,
createNode,
createNodeId,
queryLimit,
apiURL,
apiToken,
fetchOptions,
reporter,
touchNode,
createContentDigest,
schema
}; // Start activity, CloudBase CMS data fetching
const fetchActivity = reporter.activityTimer(`Fetched CloudBase CMS Data`);
fetchActivity.start();
const collectionTypes = (options.collectionTypes || []).map(contentTypeToTypeInfo);
const singleTypes = (options.singleTypes || []).map(singleTypeToTypeInfo);
const types = [...collectionTypes, ...singleTypes]; // Execute the promises
const entities = await Promise.all(types.map(type => fetchEntities(type, ctx))); // new created nodes
const newNodes = []; // Fetch existing cloudbase nodes
const existingNodes = getNodes().filter(n => n.internal.owner === `gatsby-source-cloudbase-cms`); // Touch each one of them
existingNodes.forEach(node => touchNode(node)); // Merge single and collection types and retrieve create nodes
types.forEach(({
name
}, i) => {
const items = entities[i];
addDynamicZoneFieldsToSchema({
type: name,
items,
actions,
schema
});
items.forEach(item => {
const node = (0, _nodes.Node)((0, _lodash.capitalize)(name), item); // Adding new created nodes in an Array
newNodes.push(node); // Create nodes
createNode(node);
});
}); // Make a diff array between existing nodes and new ones
const diff = existingNodes.filter(existingNode => {
return !newNodes.some(newNode => newNode.id === existingNode.id);
}); // Delete diff nodes
diff.forEach(node => deleteNode(getNode(node.id)));
fetchActivity.end();
};