Skip to content

Commit

Permalink
feat: add API endpoint to generate CoMapeo config from zip
Browse files Browse the repository at this point in the history
  • Loading branch information
luandro committed Oct 21, 2024
1 parent 1cdfe73 commit cf246fc
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@headlessui/react": "^1.7.17",
"adm-zip": "^0.5.16",
"date-fns": "^2.30.0",
"formidable": "2.x",
"mapeo-config-deconstructor": "^2.0.6",
Expand Down
94 changes: 94 additions & 0 deletions pages/api/generateFromZip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import type { NextApiRequest, NextApiResponse } from "next";
import path from 'path';
import fs from 'fs';
import { promisify } from 'util';
import { exec } from 'child_process';
import { parseForm } from "../../lib/parse-form";
import AdmZip from 'adm-zip';
import crypto from 'crypto';

const execAsync = promisify(exec);

async function runShellCommand(command: string) {
try {
const { stdout, stderr } = await execAsync(command);
if (stderr) {
console.error(`Error: ${stderr}`);
}
return stdout;
} catch (error) {
console.error(`Execution failed: ${error}`);
throw error;
}
}

const handler = async (
req: NextApiRequest,
res: NextApiResponse<{
data: { file: string | null };
error: string | null;
}>
) => {
if (req.method !== "POST") {
res.setHeader("Allow", "POST");
res.status(405).json({
data: { file: null },
error: "Method Not Allowed",
});
return;
}

try {
const { files } = await parseForm(req);
const zipFile = files.file;
const zipFilePath = Array.isArray(zipFile) ? zipFile[0]?.filepath : zipFile?.filepath;

if (!zipFilePath) {
res.status(400).json({
data: { file: null },
error: "No zip file uploaded",
});
return;
}

const uuid = crypto.randomBytes(16).toString('hex');
const tmpDir = path.join(process.cwd(), 'tmp', uuid);
const outputFile = path.join(tmpDir, 'output.mapeosettings');

// Create tmp directory
fs.mkdirSync(tmpDir, { recursive: true });

// Unzip the file
const zip = new AdmZip(zipFilePath);
zip.extractAllTo(tmpDir, true);

// Run mapeo-settings-builder
await runShellCommand(`cd ${tmpDir} && mapeo-settings-builder build --output ${outputFile}`);

// Read the output file
const outputData = fs.readFileSync(outputFile);

// Clean up
fs.rmSync(tmpDir, { recursive: true, force: true });

// Send the file
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Disposition', 'attachment; filename=output.mapeosettings');
res.status(200).send(outputData);

} catch (error) {
console.error(error);
res.status(500).json({
data: { file: null },
error: "Internal Server Error",
});
}
};

export const config = {
api: {
bodyParser: false,
},
};

export default handler;
36 changes: 33 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2821,6 +2821,11 @@ adjust-sourcemap-loader@^4.0.0:
loader-utils "^2.0.0"
regex-parser "^2.2.11"

adm-zip@^0.5.16:
version "0.5.16"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.16.tgz#0b5e4c779f07dedea5805cdccb1147071d94a909"
integrity sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==

agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
Expand Down Expand Up @@ -10494,7 +10499,16 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==

"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -10581,7 +10595,14 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -11898,7 +11919,7 @@ [email protected]:
"@types/trusted-types" "^2.0.2"
workbox-core "6.6.1"

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -11916,6 +11937,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

0 comments on commit cf246fc

Please sign in to comment.