Skip to content

Instantly share code, notes, and snippets.

@rileybathurst
Created May 11, 2023 20:24
Show Gist options
  • Save rileybathurst/81ccfc5ef46e9c2b93f3105ffee3b58b to your computer and use it in GitHub Desktop.
Save rileybathurst/81ccfc5ef46e9c2b93f3105ffee3b58b to your computer and use it in GitHub Desktop.
I renamed a million things to try get the gatsby strapi to build, still needs a clean cache but it can run
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.downloadMediaFiles = exports.downloadFile = void 0;
var _commonmark = require("commonmark");
var _qs = _interopRequireDefault(require("qs"));
var _gatsbySourceFilesystem = require("gatsby-source-filesystem");
var _helpers = require("./helpers");
const reader = new _commonmark.Parser();
/**
* Retrieves all medias from the markdown
* @param {String} text
* @param {String} apiURL
* @returns {Object[]}
*/
const extractFiles = (text, apiURL) => {
const strapifiles = [];
// parse the markdown content
const parsed = reader.parse(text);
const walker = parsed.walker();
let event, node;
while (event = walker.next()) {
node = event.node;
// process image nodes
if (event.entering && node.type === "image") {
var _node$firstChild;
let destination;
const alternativeText = ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.literal) || "";
if (/^\//.test(node.destination)) {
destination = `${apiURL}${node.destination}`;
} else if (/^http/i.test(node.destination)) {
destination = node.destination;
}
if (destination) {
strapifiles.push({
url: destination,
src: node.destination,
alternativeText
});
}
}
}
return strapifiles.filter(Boolean);
};
/**
* Download file and create node
* @param {Object} strapifile
* @param {Object} ctx
* @returns {String} node Id
*/
const strapiDownloadFile = async (strapifile, context) => {
const {
actions: {
createNode,
touchNode
},
cache,
createNodeId,
getNode,
store,
strapiConfig
} = context;
const {
apiURL,
remoteFileHeaders
} = strapiConfig;
let strapiFileNodeID;
const mediaDataCacheKey = `strapi-media-${strapifile.id}`;
const cacheMediaData = await cache.get(mediaDataCacheKey);
// If we have cached media data and it wasn't modified, reuse
// previously created file node to not try to redownload
if (cacheMediaData && cacheMediaData.updatedAt === strapifile.updatedAt) {
strapiFileNodeID = cacheMediaData.starpiFileNodeID;
touchNode(getNode(strapiFileNodeID));
}
if (!strapiFileNodeID) {
try {
// full media url
const source_url = `${strapifile.url.startsWith("http") ? "" : apiURL}${strapifile.url}`;
const strapiFileNode = await (0, _gatsbySourceFilesystem.createRemoteFileNode)({
url: source_url,
store,
cache,
createNode,
createNodeId,
httpHeaders: remoteFileHeaders || {}
});
if (strapiFileNode) {
strapiFileNodeID = strapiFileNode.id;
await cache.set(mediaDataCacheKey, {
fileNodeID: strapiFileNodeID,
updatedAt: strapifile.updatedAt
});
}
} catch (error) {
// Ignore
console.log("err", error);
}
}
return strapiFileNodeID;
};
/**
* Extract images and create remote nodes for images in all fields.
* @param {Object} item the entity
* @param {Object} context gatsby function
* @param {String} uid the main schema uid
*/
exports.downloadFile = strapiDownloadFile;
const extractImages = async (item, context, uid) => {
const {
schemas,
strapiConfig,
axiosInstance
} = context;
const schema = (0, _helpers.getContentTypeSchema)(schemas, uid);
const {
apiURL
} = strapiConfig;
for (const attributeName of Object.keys(item)) {
const value = item[attributeName];
const attribute = schema.schema.attributes[attributeName];
const type = (attribute === null || attribute === void 0 ? void 0 : attribute.type) || undefined;
if (value && type) {
if (type === "richtext") {
const strapiExtractedFiles = extractFiles(value.data, apiURL);
const strapifiles = await Promise.all(strapiExtractedFiles.map(async ({
url
}) => {
const filters = _qs.default.stringify({
filters: {
url: url.replace(`${apiURL}`, "")
}
}, {
encode: false
});
const {
data
} = await axiosInstance.get(`/api/upload/strapi-files?${filters}`);
const strapifile = data[0];
if (!strapifile) {
return;
}
const strapiFileNodeID = await strapiDownloadFile(strapifile, context);
return {
strapiFileNodeID: strapiFileNodeID,
strapifile: strapifile
};
}));
const strapiFileNodes = strapifiles.filter(Boolean);
for (const [index, strapiFileNode] of strapiFileNodes.entries()) {
item[attributeName].medias.push({
alternativeText: strapiExtractedFiles[index].alternativeText,
url: strapiExtractedFiles[index].url,
src: strapiExtractedFiles[index].src,
strapiLocalFile___NODE: strapiFileNode.strapiFileNodeID,
strapifile: strapiFileNode.strapifile
});
}
}
if (type === "dynamiczone") {
for (const element of value) {
await extractImages(element, context, element.strapi_component);
}
}
if (type === "component") {
if (attribute.repeatable) {
for (const element of value) {
await extractImages(element, context, attribute.component);
}
} else {
await extractImages(value, context, attribute.component);
}
}
if (type === "relation") {
await extractImages(value, context, attribute.target);
}
if (type === "media") {
const isMultiple = attribute.multiple;
const imagesField = isMultiple ? value : [value];
// Dowload all files
const strapifiles = await Promise.all(imagesField.map(async strapifile => {
const strapiFileNodeID = await strapiDownloadFile(strapifile, context);
return strapiFileNodeID;
}));
const images = strapifiles.filter(Boolean);
if (images && images.length > 0) {
if (isMultiple) {
for (let index = 0; index < value.length; index++) {
item[attributeName][index][`localFile___NODE`] = images[index];
}
} else {
item[attributeName][`localFile___NODE`] = isMultiple ? images : images[0];
}
}
}
}
}
};
// console.log(file);
// Downloads media from image type fields
const downloadMediaFiles = async (entities, context, contentTypeUid) => Promise.all(entities.map(async entity => {
await extractImages(entity, context, contentTypeUid);
return entity;
}));
exports.downloadMediaFiles = downloadMediaFiles;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment