Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task1 #33

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"singleQuote": true,
"trailingComma": "all",
"overrides": [
{
"files": ["**/.*rc", "**/*.json"],
"options": { "parser": "json" }
}
]
}
14 changes: 14 additions & 0 deletions JavaScript/9-logger/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
transport: 'ws', // ws | http
apiPort: 8001,
staticPort: 8000,
staticPath: './static',
logPath: './log',
db: {
host: '127.0.0.1',
port: 5432,
database: 'example',
user: 'marcus',
password: 'marcus',
},
};
12 changes: 3 additions & 9 deletions JavaScript/9-logger/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@

const pg = require('pg');

const pool = new pg.Pool({
host: '127.0.0.1',
port: 5432,
database: 'example',
user: 'marcus',
password: 'marcus',
});

module.exports = (table) => ({
const createDBCrud = (pool) => (table) => ({
async query(sql, args) {
return await pool.query(sql, args);
},
Expand Down Expand Up @@ -57,3 +49,5 @@ module.exports = (table) => ({
return await pool.query(sql, [id]);
},
});

module.exports = (poolOptions) => createDBCrud(new pg.Pool(poolOptions));
51 changes: 34 additions & 17 deletions JavaScript/9-logger/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,47 @@

const http = require('node:http');

const answerNotFound = (res, headers) => {
res.writeHead(404, headers);
res.end('Not found');
};

const receiveArgs = async (req) => {
const buffers = [];
for await (const chunk of req) buffers.push(chunk);
const data = Buffer.concat(buffers).toString();
return JSON.parse(data);
};

module.exports = (routing, port) => {
http.createServer(async (req, res) => {
const { url, socket } = req;
const [name, method, id] = url.substring(1).split('/');
const entity = routing[name];
if (!entity) return void res.end('Not found');
const handler = entity[method];
if (!handler) return void res.end('Not found');
const src = handler.toString();
const signature = src.substring(0, src.indexOf(')'));
const args = [];
if (signature.includes('(id')) args.push(id);
if (signature.includes('{')) args.push(await receiveArgs(req));
console.log(`${socket.remoteAddress} ${method} ${url}`);
const result = await handler(...args);
res.end(JSON.stringify(result.rows));
}).listen(port);
module.exports = (routing, port, console) => {
http
.createServer(async (req, res) => {
const headers = {
'Access-Control-Allow-Origin':
'*' /* @dev First, read about security */,
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Max-Age': 2592000, // 30 days
/** add other headers as per requirement */
};

const { url, socket } = req;
const [name, method, id] = url.substring(1).split('/');
const entity = routing[name];
if (!entity) return void answerNotFound(res, headers);
const handler = entity[method];
if (!handler) return void answerNotFound(res, headers);

res.writeHead(200, headers);
const src = handler.toString();
const signature = src.substring(0, src.indexOf(')'));
const args = [];
if (signature.includes('(id')) args.push(id);
args.push(...(await receiveArgs(req)));
console.log(`${socket.remoteAddress} ${req.method} ${url}`);
const result = await handler(...args);
res.end(JSON.stringify(result.rows));
})
.listen(port);

console.log(`API on port ${port}`);
};
2 changes: 1 addition & 1 deletion JavaScript/9-logger/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ class Logger {
}
}

module.exports = new Logger('./log');
module.exports = Logger;
14 changes: 9 additions & 5 deletions JavaScript/9-logger/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

const fsp = require('node:fs').promises;
const path = require('node:path');
const server = require('./ws.js');
const staticServer = require('./static.js');
const load = require('./load.js');
const db = require('./db.js');
const createDbQueryConstructor = require('./db.js');
const hash = require('./hash.js');
const logger = require('./logger.js');
const Logger = require('./logger.js');
const config = require('./config.js');
const server = require(`./${config.transport}.js`);

const logger = new Logger(config.logPath);
const db = createDbQueryConstructor(config.db);

const sandbox = {
console: Object.freeze(logger),
Expand All @@ -26,6 +30,6 @@ const routing = {};
routing[serviceName] = await load(filePath, sandbox);
}

staticServer('./static', 8000);
server(routing, 8001);
staticServer(config.staticPath, config.staticPort, logger);
server(routing, config.apiPort, logger);
})();
5 changes: 4 additions & 1 deletion JavaScript/9-logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
"private": true,
"main": "main.js",
"engines": {
"node": "14 || 16 || 18"
"node": "14 || 16 || 18 || 20"
},
"scripts": {
"start": "node --experimental-vm-modules main.js"
},
"dependencies": {
"pg": "^8.8.0",
Expand Down
26 changes: 14 additions & 12 deletions JavaScript/9-logger/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ const http = require('node:http');
const path = require('node:path');
const fs = require('node:fs');

module.exports = (root, port) => {
http.createServer(async (req, res) => {
const url = req.url === '/' ? '/index.html' : req.url;
const filePath = path.join(root, url);
try {
const data = await fs.promises.readFile(filePath);
res.end(data);
} catch (err) {
res.statusCode = 404;
res.end('"File is not found"');
}
}).listen(port);
module.exports = (root, port, console) => {
http
.createServer(async (req, res) => {
const url = req.url === '/' ? '/index.html' : req.url;
const filePath = path.join(root, url);
try {
const data = await fs.promises.readFile(filePath);
res.end(data);
} catch (err) {
res.statusCode = 404;
res.end('"File is not found"');
}
})
.listen(port);

console.log(`Static on port ${port}`);
};
74 changes: 58 additions & 16 deletions JavaScript/9-logger/static/client.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,86 @@
'use strict';

const socket = new WebSocket('ws://127.0.0.1:8001/');
const API_URL = 'ws://localhost:8001';

const scaffold = (structure) => {
const getTransport = (url) => {
let socket;
const protocol = url.split(':')[0];

const transports = {
ws: (name, method) => {
if (!socket) socket = new WebSocket(url);
return (...args) => {
return new Promise((resolve) => {
const packet = { name, method, args };
socket.send(JSON.stringify(packet));
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
resolve(data);
};
});
};
},

http:
(name, method, methodArgs) =>
(...args) => {
const urlParts = [url, name, method];
if (methodArgs[0] === 'id') urlParts.push(args.shift());

return fetch(urlParts.join('/'), {
method: 'POST',
body: JSON.stringify(args),
}).then((response) => response.json());
},
};

return transports[protocol];
};

const scaffold = (url, structure) => {
const transport = getTransport(url);
const api = {};
const services = Object.keys(structure);
for (const serviceName of services) {
api[serviceName] = {};
const service = structure[serviceName];
const methods = Object.keys(service);
for (const methodName of methods) {
api[serviceName][methodName] = (...args) => new Promise((resolve) => {
const packet = { name: serviceName, method: methodName, args };
socket.send(JSON.stringify(packet));
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
resolve(data);
};
});
api[serviceName][methodName] = transport(
serviceName,
methodName,
service[methodName],
);
}
}
return api;
};

const api = scaffold({
const api = scaffold(API_URL, {
user: {
create: ['record'],
read: ['id'],
update: ['id', 'record'],
delete: ['id'],
find: ['mask'],
},
city: {
read: ['id'],
create: ['record'],
update: ['id', 'record'],
delete: ['id'],
},
country: {
read: ['id'],
create: ['record'],
update: ['id', 'record'],
delete: ['id'],
find: ['mask'],
},
});

socket.addEventListener('open', async () => {
const data = await api.user.read(3);
console.dir({ data });
});
// socket.addEventListener('open', async () => {
// const data = await api.user.read(3);
// console.dir({ data });
// });

(async () => console.log(await api.user.read(3)))();
3 changes: 1 addition & 2 deletions JavaScript/9-logger/ws.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';

const console = require('./logger.js');
const { Server } = require('ws');

module.exports = (routing, port) => {
module.exports = (routing, port, console) => {
const ws = new Server({ port });

ws.on('connection', (connection, req) => {
Expand Down