Skip to content

Commit

Permalink
Fix formidable upload issue, fix error handling, do structural refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexeyNikipelau committed Jul 15, 2024
1 parent bf444bf commit c5099cc
Show file tree
Hide file tree
Showing 39 changed files with 177 additions and 130 deletions.
16 changes: 11 additions & 5 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
'use strict';

const config = require('./config');

const cors = require('cors');
const express = require('express');
const cors = require('cors');

const app = express();

const config = require('./config');

const {version} = require('./package.json');
const {debug} = require('./src/handlers');
const {errorHandler} = require('./src/handlers/errors');

const pdfRouter = require('./src/pdf/router');
const pdfRouter = require('./src/router');
const debugScopes = require('./src/debug-scopes');

app.use(cors());

app.use(debug(debugScopes.DEFAULT));

app.get('/version', async (__req, res) => {
res.send({version});
});

app.use('/pdf', pdfRouter);

app.use(errorHandler);

app.listen(config.port, () => {
// eslint-disable-next-line no-console
console.log(`PDF Libs listening on port: ${config.port}`);
Expand Down
9 changes: 9 additions & 0 deletions src/debug-scopes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

const debugScopes = {
DEFAULT: 'pdfLibs.default',
CONVERT_TO_HTML: 'pdfLibs.html',
FORMFIELDS: 'pdfLibs.formfields'
};

module.exports = debugScopes;
5 changes: 5 additions & 0 deletions src/errors/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
...require('./validation-error')
};
16 changes: 16 additions & 0 deletions src/errors/validation-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

class ValidationError extends Error {
constructor (message, errors) {
super(message);
this.errors = errors;
this.statusCode = 400;
}

withStatus (statusCode) {
this.statusCode = statusCode;
return this;
}
}

module.exports = {ValidationError};
5 changes: 4 additions & 1 deletion src/pdf/middleware/cleanup.js → src/handlers/cleanup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

const fs = require('fs/promises');
const _ = require('lodash');
module.exports = (req, res, next) => {

const cleanup = (req, res, next) => {
res.on('finish', () => {
if (!req.cleanup || !req.cleanup.length) {
return;
Expand All @@ -20,3 +21,5 @@ module.exports = (req, res, next) => {
});
return next();
};

module.exports = {cleanup};
15 changes: 15 additions & 0 deletions src/handlers/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

const logDebug = require('debug');

const debug = (namespace) => {
const log = logDebug(namespace);
return (req, __res, next) => {
req.debug = (msg) => {
log(`${msg}`);
};
next();
};
};

module.exports = {debug};
13 changes: 13 additions & 0 deletions src/handlers/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict';

const {ValidationError} = require('../errors');

const errorHandler = (err, req, res, __next) => {
req.debug?.(`Error: ${err.message || err}`);
if (err instanceof ValidationError) {
return res.status(err.statusCode).send(err.message);
}
res.status(500).send(err.message ?? err);
};

module.exports = {errorHandler};
22 changes: 22 additions & 0 deletions src/handlers/get-file-from-formdata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const formidable = require('formidable');
const {ValidationError} = require('../errors');

const getFileFromFormData = (req, __res, next) => {
const form = new formidable.IncomingForm();
req.cleanup = [];
form.parse(req, async (err, __, files) => {
if (err) {
return next(new ValidationError(err?.message ?? err));
}
if (!files.pdf) {
return next(new ValidationError('No files were uploaded'));
}
req.filePath = files.pdf[0].filepath;
req.cleanup.push(req.file);
next();
});
};

module.exports = {getFileFromFormData};
8 changes: 8 additions & 0 deletions src/handlers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

module.exports = {
...require('./pdf'),
...require('./get-file-from-formdata'),
...require('./cleanup'),
...require('./debug'),
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const path = require('path');
const {v4: uuid} = require('uuid');
const tmpdir = require('os').tmpdir();

const {generateHtml} = require('../services/convert-to-html');
const {generateHtml} = require('../../services/pdf/convert-to-html');
const {htmlGenerationTimeoutConfig} = require('../../../config');

const convertToHtml = async (req, res, next) => {
Expand All @@ -27,7 +27,7 @@ const convertToHtml = async (req, res, next) => {
}
catch (err) {
return req.optimizedPdf
? res.status(500).send(err)
? next(err)
: next();
}
return res.sendFile(outputPath, (err) => {
Expand All @@ -37,4 +37,4 @@ const convertToHtml = async (req, res, next) => {
});
};

module.exports = convertToHtml;
module.exports = {convertToHtml};
15 changes: 15 additions & 0 deletions src/handlers/pdf/get-formfields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

const {extractFormfields} = require('../../services/pdf/formfields');

const getFormfields = async (req, res, next) => {
try {
const jsonOutput = await extractFormfields(req.filePath);
res.json(jsonOutput);
}
catch (err) {
return next(err);
}
};

module.exports = {getFormfields};
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use strict';

const config = require('../../../config');
const {exec} = require('../utils');
const path = require('path');
const os = require('os');
const {v4: uuid} = require('uuid');

const config = require('../../../config');
const {exec} = require('../../utils');

const hideFormfields = async (req, __res, next) => {
const outputPath = path.join(os.tmpdir(), `${uuid()}.pdf`);
req.cleanup.push(outputPath);
Expand All @@ -15,4 +16,4 @@ const hideFormfields = async (req, __res, next) => {
next();
};

module.exports = hideFormfields;
module.exports = {hideFormfields};
8 changes: 8 additions & 0 deletions src/handlers/pdf/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

module.exports = {
...require('./get-formfields'),
...require('./optimize-pdf'),
...require('./hide-formfields'),
...require('./convert-to-html'),
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
const os = require('os');
const path = require('path');
const {v4: uuid} = require('uuid');
const {psToPdf} = require('../services/convert-to-html');
const {psToPdf} = require('../../services/pdf/convert-to-html');

const optimizePdf = (req, res, next) => {
const optimizePdf = (req, __res, next) => {
req.debug('Optimizing PDF');
const outputPath = path.join(os.tmpdir(), `${uuid()}.pdf`);
req.cleanup.push(outputPath);
psToPdf(req.filePath, outputPath, (err, filePath) => {
if (err) {
res.status(500).send(err);
return next(err);
}
if (!filePath) {
res.status(500).send('Error when optimizing PDF file');
return next(new Error('Optimized PDF not found'));
}
req.filePath = filePath;
req.optimizedPdf = true;
next();
});
};

module.exports = optimizePdf;
module.exports = {optimizePdf};
13 changes: 0 additions & 13 deletions src/pdf/middleware/debug.js

This file was deleted.

23 changes: 0 additions & 23 deletions src/pdf/middleware/get-file-from-formdata.js

This file was deleted.

15 changes: 0 additions & 15 deletions src/pdf/middleware/get-formfields.js

This file was deleted.

19 changes: 0 additions & 19 deletions src/pdf/middleware/index.js

This file was deleted.

9 changes: 0 additions & 9 deletions src/pdf/services/convert-to-html/index.js

This file was deleted.

7 changes: 0 additions & 7 deletions src/pdf/services/formfields/index.js

This file was deleted.

4 changes: 0 additions & 4 deletions src/pdf/utils/exec.js

This file was deleted.

7 changes: 0 additions & 7 deletions src/pdf/utils/index.js

This file was deleted.

8 changes: 4 additions & 4 deletions src/pdf/router.js → src/router.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const r = require('express').Router();
const debugScopes = require('./debug-scopes');

const {
getFileFromFormData,
Expand All @@ -9,14 +10,13 @@ const {
getFormfields,
cleanup,
debug
} = require('./middleware');
} = require('./handlers');

r.use(debug('pdfLibs'));
r.use(cleanup);
r.use(getFileFromFormData);

r.post('/convertToHtml',
debug('pdfLibs.html'),
debug(debugScopes.CONVERT_TO_HTML),
// hideFormfields,
convertToHtml,
optimizePdf,
Expand All @@ -26,7 +26,7 @@ r.post('/getFormfields', debug('pdfLibs.formfields'), getFormfields);

// DEPRECATED PATHS
r.post('/pdf2html',
debug('pdfLibs.html'),
debug(debugScopes.FORMFIELDS),
// hideFormfields,
convertToHtml,
optimizePdf,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const {pdf2htmlexPath} = require('../../../../config');
const {exec} = require('../../utils');
const {exec} = require('../../../utils');

const generateHtml = async (filePath, toFile, params, commands, timeout) => {
const {zoom, dpi} = params;
Expand All @@ -24,4 +24,4 @@ const generateHtml = async (filePath, toFile, params, commands, timeout) => {
await exec(`${pdf2htmlexPath} ${args.join(' ')}`, {timeout});
};

module.exports = generateHtml;
module.exports = {generateHtml};
Loading

0 comments on commit c5099cc

Please sign in to comment.