diff --git a/src/createServer.js b/src/createServer.js
index 1cf1dda..4d610aa 100644
--- a/src/createServer.js
+++ b/src/createServer.js
@@ -1,10 +1,110 @@
'use strict';
+const http = require('node:http');
+const fs = require('node:fs');
+const path = require('node:path');
+const querystring = require('node:querystring');
+
+const dataPath = path.resolve(__dirname, '../db/expense.json');
+
function createServer() {
- /* Write your code here */
- // Return instance of http.Server class
+ return http.createServer((req, res) => {
+ /* ---------- GET FORM ---------- */
+ if (req.method === 'GET' && req.url === '/') {
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'text/html');
+
+ res.end(`
+
Add expense
+
+ `);
+
+ return;
+ }
+
+ /* ---------- ONLY POST /add-expense ---------- */
+ if (req.method !== 'POST' || req.url !== '/add-expense') {
+ res.statusCode = 404;
+ res.end('Not Found');
+
+ return;
+ }
+
+ const chunks = [];
+
+ req.on('data', (chunk) => chunks.push(chunk));
+
+ req.on('end', () => {
+ const body = Buffer.concat(chunks).toString('utf-8');
+
+ let expense;
+
+ try {
+ if (req.headers['content-type']?.includes('application/json')) {
+ expense = JSON.parse(body);
+ } else {
+ expense = querystring.parse(body);
+ }
+ } catch {
+ res.statusCode = 400;
+ res.end('Invalid data
');
+
+ return;
+ }
+
+ if (!expense.date || !expense.title || !expense.amount) {
+ res.statusCode = 400;
+ res.setHeader('Content-Type', 'text/html');
+ res.end('Missing required fields
');
+
+ return;
+ }
+
+ /* ---------- READ EXISTING FILE ---------- */
+ fs.readFile(dataPath, 'utf-8', (readErr, fileData) => {
+ let expenses = [];
+
+ if (!readErr && fileData) {
+ try {
+ expenses = JSON.parse(fileData);
+ } catch {
+ expenses = [];
+ }
+ }
+
+ if (!Array.isArray(expenses)) {
+ expenses = [];
+ }
+
+ expenses.push(expense);
+
+ /* ---------- WRITE UPDATED ARRAY ---------- */
+ fs.writeFile(
+ dataPath,
+ JSON.stringify(expenses, null, 2),
+ (writeErr) => {
+ if (writeErr) {
+ res.statusCode = 500;
+ res.end('Server error
');
+
+ return;
+ }
+
+ /* ---------- HTML RESPONSE ---------- */
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'text/html');
+
+ res.end(JSON.stringify(expense, null, 2));
+ },
+ );
+ });
+ });
+ });
}
-module.exports = {
- createServer,
-};
+module.exports = { createServer };
diff --git a/tests/formDataServer.test.js b/tests/formDataServer.test.js
index 0ee1766..30b95ff 100644
--- a/tests/formDataServer.test.js
+++ b/tests/formDataServer.test.js
@@ -53,7 +53,7 @@ describe('Form Data Server', () => {
const savedData = JSON.parse(fs.readFileSync(dataPath));
- expect(savedData).toStrictEqual(expense);
+ expect(savedData).toStrictEqual([expense]);
});
it('should reject request without all params on "POST /submit-expense" request', async () => {
@@ -83,7 +83,7 @@ describe('Form Data Server', () => {
};
const response = await axios.post(`${HOST}/add-expense`, expense);
- expect(response.headers['content-type']).toBe('application/json');
+ expect(response.headers['content-type']).toBe('text/html');
expect(response.data).toStrictEqual(expense);
});