My code below copies the /template
directory into the /theme
directory after replacing some variables.
The /theme
directory is zipped and returned in an HTTP response.
This works locally, but fails once I push it up to Netlify. It fails because I don't have write privileges from within the function. I believe the solution is to write to a stream instead of to the disk, but I'm unsure of how to do that after reading through some docs.
const copy = require("copy-template-dir");
const path = require("path");
const fs = require("fs");
const JSZip = require("jszip");
const inDir = path.join(__dirname, "template");
const outDir = path.join(__dirname, "theme");
exports.handler = async (event, context) => {
// Searches /template, replaces the variables, and copies the files to /theme
function makeCopy() {
return new Promise(function (resolve, reject) {
//returning promise
// Theme Variables to Find and Replace
const vars = {
theme_name: "Theme Name",
theme_slug: "theme-slug",
author_name: "Author Name",
};
// Get vars from query string
if (event.queryStringParameters) {
vars.theme_name = event.queryStringParameters.name || vars.theme_name;
vars.theme_slug = event.queryStringParameters.name || vars.theme_slug;
vars.author_name = event.queryStringParameters.author || vars.author_name;
}
copy(inDir, outDir, vars, (err, createdFiles) => {
if (err) throw err;
resolve();
});
});
}
// Loops contents of the /theme directory and creates a zip file
const addFilesFromDirectoryToZip = (directoryPath = "", zip) => {
const directoryContents = fs.readdirSync(directoryPath, {
withFileTypes: true,
});
directoryContents.forEach(({ name }) => {
const path = `${directoryPath}/${name}`;
if (fs.statSync(path).isFile()) {
zip.file(path, fs.readFileSync(path, "utf-8"));
}
if (fs.statSync(path).isDirectory()) {
addFilesFromDirectoryToZip(path, zip);
}
});
};
// Zip the theme
async function makeZip() {
var zip = new JSZip();
addFilesFromDirectoryToZip("theme", zip);
const zipAsBase64 = await zip.generateAsync({ type: "base64" });
return zipAsBase64;
}
const myCopy = await makeCopy();
const zip = await makeZip();
// Return the zip
return {
statusCode: 200,
body: zip,
headers: {
"Content-Type": "application/zip",
"Content-Disposition": "attachment; filename=theme.zip",
},
};
};
The answer is not Node streams. Since this is a lambda function, I just needed to make use of the writable /tmp folder.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.