@alizadefaig/pos-server 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/app/config.js ADDED
@@ -0,0 +1,18 @@
1
+ let config = {
2
+ "isServer": true,
3
+ "apiUrl": "https://admin.cafepos.az",
4
+ "debug": false,
5
+ "port": 3005
6
+ }
7
+
8
+ const getConfig = () => {
9
+ return config;
10
+ }
11
+
12
+ const setConfig = (conf) => {
13
+ config = conf || {};
14
+ }
15
+ module.exports = {
16
+ getConfig,
17
+ setConfig
18
+ }
@@ -0,0 +1,24 @@
1
+ const {getConfig} = require("../config");
2
+
3
+ class Local {
4
+ constructor() {
5
+ this.path = getConfig().path;
6
+ }
7
+ log(data) {
8
+ console.log(data);
9
+ }
10
+
11
+ error(data) {
12
+ console.error(data);
13
+ }
14
+
15
+ info(data) {
16
+ console.info(data);
17
+ }
18
+
19
+ warning(data) {
20
+ console.warn(data);
21
+ }
22
+ }
23
+
24
+ module.exports = Local;
@@ -0,0 +1,25 @@
1
+ const Server = require("./Server");
2
+ const Local = require("./Local");
3
+ const {getConfig} = require("../config");
4
+
5
+ class Log {
6
+ loggers = {
7
+ 'server': Server,
8
+ 'local': Local,
9
+ }
10
+ static logger = null;
11
+ static getLogger() {
12
+ if (!Log.logger) {
13
+ Log.logger = new Log(getConfig().isServer ? "server" : 'local')
14
+ }
15
+
16
+ return Log.logger;
17
+ }
18
+ constructor(logger) {
19
+ if (!Log.logger) {
20
+ Log.logger = new this.loggers[logger];
21
+ }
22
+ return Log.logger
23
+ }
24
+ }
25
+ module.exports = Log;
@@ -0,0 +1,18 @@
1
+ class Server {
2
+ log(data) {
3
+ console.log(data);
4
+ }
5
+
6
+ error(data) {
7
+ console.error(data);
8
+ }
9
+
10
+ info(data) {
11
+ console.info(data);
12
+ }
13
+
14
+ warning(data) {
15
+ console.warn(data);
16
+ }
17
+ }
18
+ module.exports = Server;
package/app/proxy.js ADDED
@@ -0,0 +1,100 @@
1
+ const axios = require("../lib/axios");
2
+ const {getConfig} = require("./config");
3
+ const {getLogger} = require("./logger/Log");
4
+ const {createProxyMiddleware, fixRequestBody} = require("http-proxy-middleware");
5
+ const moment = require("moment");
6
+ const { v4: uuidv4 } = require('uuid');
7
+
8
+
9
+
10
+ function isLocalRoute(req, app) {
11
+ const path = req.path;
12
+ const method = req.method.toLowerCase();
13
+ console.log(app._router);
14
+ // Проверяем стек роутов Express
15
+ return app._router.stack.some((layer) => {
16
+ if (!layer.route) return false; // Это не роут
17
+ if (!layer.route.methods[method]) return false; // Метод не совпадает (GET, POST и т.д.)
18
+ return layer.route.path === path; // Путь совпадает
19
+ });
20
+ }
21
+
22
+ // const
23
+ const loadProxy = (app) => {
24
+ let appConfig = getConfig();
25
+ let PROXY_TARGET = appConfig.apiUrl;
26
+ const logger = getLogger();
27
+ const proxy = createProxyMiddleware({
28
+ target: PROXY_TARGET,
29
+ changeOrigin: true,
30
+ on: {
31
+ proxyReq: (proxyReq, req, res, options) => {
32
+ const traceId = uuidv4();
33
+ const timeStamp = moment.utc().unix();
34
+ proxyReq.setHeader('trace-id', traceId);
35
+ req.traceId = traceId;
36
+ logger.log({
37
+ traceId,
38
+ timeStamp,
39
+ request: {
40
+ headers: req.headers,
41
+ method: req.method,
42
+ url: req.url,
43
+ body: req.data,
44
+ params: req.params,
45
+ }
46
+ })
47
+ return fixRequestBody(proxyReq, req);
48
+ },
49
+ proxyRes: (proxyRes, req, res, options) => {
50
+ const traceId = req.traceId;
51
+ const timeStamp = moment.utc().unix();
52
+ // proxyRes.setHeader('Content-Type', 'application/json');
53
+
54
+
55
+ let body = Buffer.from('');
56
+
57
+ proxyRes.on('data', (chunk) => {
58
+ body = Buffer.concat([body, chunk]);
59
+ });
60
+
61
+ proxyRes.on('end', () => {
62
+ const responseBody = body.toString('utf8');
63
+
64
+ let response = responseBody;
65
+ try {
66
+ response = JSON.parse(responseBody);
67
+ } catch (e) {
68
+ response = responseBody;
69
+ }
70
+
71
+ logger.log({
72
+ traceId,
73
+ timeStamp,
74
+ response
75
+ })
76
+ });
77
+ },
78
+ error: (err, req, res, target) => {
79
+ const traceId = req.traceId;
80
+ const timeStamp = moment.utc().unix();
81
+ logger.error({
82
+ traceId,
83
+ timeStamp,
84
+ error: err
85
+ })
86
+
87
+ res.end(JSON.stringify({
88
+ error: 'Bad Gateway',
89
+ message: err.message,
90
+ traceId: req.traceId || null,
91
+ }));
92
+ }
93
+ },
94
+ selfHandleResponse: false
95
+ });
96
+ app.use(proxy);
97
+ }
98
+ module.exports = {
99
+ loadProxy
100
+ }
@@ -1,17 +1,19 @@
1
1
  const {io} = require("socket.io-client");
2
2
  const serverSocket = require('../socket/server')();
3
3
  let clientSocket = null;
4
- module.exports = (target, companyId) => {
4
+ module.exports = (target, companyId, terminalId) => {
5
5
  if (!clientSocket && companyId) {
6
6
  clientSocket = io(target, {
7
7
  query: {
8
- company_id: companyId
8
+ company_id: companyId,
9
+ terminal_id: terminalId,
10
+ is_proxy_server: true,
9
11
  }
10
12
  });
11
13
  }
12
14
 
13
15
  if (clientSocket) {
14
- clientSocket.onAny((companyId, eventName, ...args) => {
16
+ clientSocket.onAny((eventName, ...args) => {
15
17
  serverSocket.to(companyId).emit(eventName, ...args);
16
18
  })
17
19
  }
@@ -1,4 +1,8 @@
1
1
  const {Server} = require("socket.io");
2
+ const axios = require("axios");
3
+ const {getConfig} = require("../config");
4
+ const {getLogger} = require("../logger/Log");
5
+ const {socketSendByFilter} = require("../../utils");
2
6
  let serverSocket = null;
3
7
  module.exports = (server = null) => {
4
8
  if (server && !serverSocket) {
@@ -6,15 +10,76 @@ module.exports = (server = null) => {
6
10
  cors: {
7
11
  origin: '*'
8
12
  }
9
- })
13
+ });
14
+
15
+ const logger = getLogger();
16
+
10
17
 
11
18
  serverSocket.on('connection', (socket) => {
12
- socket.join(socket.handshake.query.company_id);
13
19
  const companyId = socket.handshake.query.company_id;
14
- const terminalId = socket.handshake.query.terminalId;
15
- socket.onAny((eventName, ...args) => {
16
- serverSocket.to(companyId).emit(eventName, terminalId, ...args);
17
- });
20
+ const terminalId = socket.handshake.query.terminal_id;
21
+ let userId = socket.handshake.query.user_id;
22
+ // const isProxy = socket.handshake.query.is_proxy_server ?? false;
23
+ const isProxy = false;
24
+ const PROXY_TARGET = getConfig().apiUrl;
25
+
26
+ socket.join(companyId);
27
+ socket.terminalId = terminalId;
28
+ socket.companyId = companyId;
29
+ socket.userId = userId;
30
+ socket.isProxy = isProxy;
31
+
32
+ if (!isProxy) {
33
+
34
+ axios.post(`${PROXY_TARGET}/api/socket/connection`, {
35
+ companyId,
36
+ terminalId,
37
+ userId,
38
+ }).catch(error => {
39
+ logger.error(error);
40
+ });
41
+
42
+ socket.on('setUserId', (id) => {
43
+ userId = id;
44
+
45
+ axios.post(`${PROXY_TARGET}/api/socket/setUserId`, {
46
+ companyId,
47
+ terminalId,
48
+ userId,
49
+ }).catch((err) => {
50
+ logger.error(err);
51
+ });
52
+
53
+
54
+ if (id) {
55
+ socket.userId = id;
56
+ }
57
+ });
58
+
59
+
60
+ socket.on('disconnect', () => {
61
+ axios.post(`${PROXY_TARGET}/api/socket/disconnect`, {
62
+ companyId,
63
+ terminalId,
64
+ userId,
65
+ }).catch((err) => {
66
+ logger.error(err);
67
+ });
68
+ });
69
+
70
+ // socket.on('broadcast', (data) => {
71
+ // console.log(companyId, data.eventName, data.data);
72
+ // })
73
+
74
+ socket.onAny((eventName, ...data) => {
75
+ // socketSendByFilter('company', companyId, eventName, {
76
+ // terminal: [terminalId],
77
+ // }, ...args);
78
+ socket.to(companyId).emit(eventName, ...data);
79
+ });
80
+ } else {
81
+ console.log('Proxy');
82
+ }
18
83
  });
19
84
  }
20
85
 
package/lib/axios.js CHANGED
@@ -1,7 +1,44 @@
1
1
  const axios = require("axios");
2
- const {appConfig} = require("../server");
2
+ const {getConfig} = require("../app/config");
3
+ const {streamToString} = require("../utils");
4
+ const {getLogger} = require("../app/logger/Log");
5
+ const {response} = require("express");
6
+ const logger = getLogger();
3
7
  const instance = axios.create({
4
- baseURL: appConfig.apiUrl
8
+ baseURL: getConfig().apiUrl
9
+ });
10
+ instance.interceptors.request.use((config) => {
11
+ const traceId = Date.now().toString();
12
+ config.headers['trace-id'] = traceId;
13
+ logger.log({
14
+ traceId,
15
+ request: {
16
+ headers: config.headers,
17
+ method: config.method,
18
+ url: config.url,
19
+ data: config.data,
20
+ }
21
+ })
22
+ return config;
23
+ })
24
+
25
+ instance.interceptors.response.use((response) => {
26
+ /**
27
+ * @var request:Cli
28
+ */
29
+ const traceId = response.request.getHeader('trace-id');
30
+ logger.log({
31
+ traceId,
32
+ response: response.data,
33
+ });
34
+ return response;
35
+ }, (error) => {
36
+ const traceId = error.request.getHeader('trace-id');
37
+ logger.error({
38
+ traceId,
39
+ error: error.response.data
40
+ });
41
+ throw error;
5
42
  })
6
43
 
7
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alizadefaig/pos-server",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Server in express js with Proxy to Main server if need and will work with Electron JS",
5
5
  "homepage": "https://gitlab.com/faigalizade/pos-server#readme",
6
6
  "bugs": {
@@ -18,10 +18,13 @@
18
18
  "escpos-network": "^3.0.0-alpha.5",
19
19
  "express": "^5.1.0",
20
20
  "form-data": "^4.0.2",
21
+ "http-proxy-middleware": "^3.0.5",
22
+ "moment": "^2.30.1",
21
23
  "multer": "^1.4.5-lts.2",
22
24
  "sequelize": "^6.37.7",
23
25
  "socket.io": "^4.8.1",
24
- "socket.io-client": "^4.8.1"
26
+ "socket.io-client": "^4.8.1",
27
+ "uuid": "^11.1.0"
25
28
  },
26
29
  "license": "ISC",
27
30
  "author": "faigalizade@newave.az",
@@ -0,0 +1,54 @@
1
+ const express = require('express');
2
+ const {socketSendByFilter} = require("../../utils");
3
+ const serverSocket = require("../../app/socket/server")();
4
+ const router = express.Router();
5
+
6
+
7
+ router.all('/socket', (req, res) => {
8
+ /**
9
+ * @var to [company|terminal|user]
10
+ */
11
+
12
+ const companyId = req.body?.company_id || req.query?.company_id;
13
+ const eventName = (req.body?.event || req.query?.event) ?? null;
14
+ const data = (req.body?.data || req.query?.data) ?? null;
15
+
16
+ if (!companyId || !data || !eventName) {
17
+ return res.json({
18
+ success: false,
19
+ message: 'Required fields is not set',
20
+ });
21
+ }
22
+
23
+ const to = (req.body?.to || req.query?.to) ?? null;
24
+ const excepts = (req.body?.excepts || req.query?.excepts) ?? null;
25
+ const toId = (req.body?.to_id || req.query?.to_id) ?? null;
26
+
27
+ if (to && ['terminal', 'user'].includes(to)) {
28
+ if (!toId) {
29
+ return res.json({
30
+ success: false,
31
+ message: 'To ID is missing',
32
+ })
33
+ }
34
+
35
+ return res.json({
36
+ success: false,
37
+ message: 'To is incorrect',
38
+ })
39
+ }
40
+
41
+ socketSendByFilter({
42
+ companyId,
43
+ eventName,
44
+ data,
45
+ to,
46
+ toId,
47
+ excepts
48
+ }, serverSocket);
49
+ res.send({
50
+ success: true,
51
+ });
52
+ });
53
+
54
+ module.exports = router;
@@ -6,7 +6,8 @@ const net = require('net');
6
6
  escpos.USB = require('@alizadefaig/cafetap-escpos-usb');
7
7
  escpos.Network = require('escpos-network');
8
8
  const axios = require('axios');
9
- const appConfig = require("../../../config.json");
9
+ const {getConfig} = require("../../../app/config");
10
+ const appConfig = getConfig();
10
11
 
11
12
  let PROXY_TARGET = appConfig.apiUrl || 'http://localhost:8000';
12
13
  const getUsbPrinters = async () => {
@@ -110,7 +111,7 @@ router.get('/printers.get', async (req, res) => {
110
111
  router.post('/printers.print', async (req, res) => {
111
112
  const device = getPrinterDevice(req.body.printer)
112
113
  if (!device) {
113
- res.send('bad').status(404);
114
+ return res.send('bad').status(404);
114
115
  }
115
116
  const imageContent = req.body.content.replace(/\r?\n|\r/g, '').replace(/^data:image\/\w+;base64,/, '');
116
117
  const printer = new escpos.Printer(device, {});
@@ -126,12 +127,15 @@ router.post('/printers.print', async (req, res) => {
126
127
 
127
128
  device.open((err) => {
128
129
  if (err) {
129
- console.error('Ошибка подключения к принтеру:', err);
130
- sent = true;
131
- res.json({
132
- success: false,
133
- error: err
134
- })
130
+ if (!sent) {
131
+ sent = true;
132
+ res.json({
133
+ success: false,
134
+ error: 'connection_error',
135
+ message: err
136
+ })
137
+ return;
138
+ }
135
139
  return;
136
140
  }
137
141
 
@@ -149,14 +153,17 @@ router.post('/printers.print', async (req, res) => {
149
153
  .cut()
150
154
  .close();
151
155
 
152
- sent = true;
153
- res.json({
154
- success: true
155
- })
156
+ if (!sent) {
157
+ sent = true;
158
+ res.json({
159
+ success: true,
160
+ })
161
+ }
156
162
  });
157
163
 
158
164
  setTimeout(() => {
159
165
  if (!sent) {
166
+ sent = true;
160
167
  res.json({
161
168
  success: false,
162
169
  error: 'timeout'
package/server.js CHANGED
@@ -3,108 +3,81 @@ const app = express();
3
3
  const http = require('http');
4
4
  const cors = require('cors')
5
5
  const server = http.createServer(app);
6
- const multer = require('multer');
7
6
  const {join} = require("node:path");
7
+ const {loadRoutes, streamToString, getIpAddress} = require("./utils");
8
+ const {getConfig, setConfig} = require("./app/config");
9
+ const {loadProxy} = require("./app/proxy");
10
+ const multer = require('multer');
11
+ const {getLogger} = require("./app/logger/Log");
12
+
13
+
14
+
15
+
8
16
  const upload = multer();
9
- const axios = require("axios");
10
- const {loadRoutes, streamToString} = require("./utils");
11
- const appConfig = require("./config.json");
12
- const FormData = require("form-data");
13
- app.use(express.json());
14
- app.use(express.urlencoded({extended: true})); // Для обработки form-urlencoded
15
- app.use(upload.any()); // Позволяет обрабатывать файлы
16
- app.use(cors());
17
+ app.use(express.json({limit: '500mb'}));
18
+ app.use(express.urlencoded({extended: true, limit: '500mb'}));
19
+ app.use(upload.any());
20
+ app.use(cors({
21
+ origin: "*",
22
+ }));
23
+
24
+
25
+
26
+
27
+
28
+ let isServer = true;
29
+ let serverSocket = null;
30
+ let clientSocket = null;
31
+
32
+
17
33
  const runExpress = (conf = null) => {
18
- const appConfig = conf || require('./config.json');
34
+ if (conf) {
35
+ setConfig(conf);
36
+ }
37
+ const appConfig = conf || getConfig();
19
38
  let PROXY_TARGET = appConfig.apiUrl;
20
39
  const port = appConfig.port;
21
- const isServer = appConfig.isServer;
22
- const serverSocket = require('./app/socket/server')(server);
23
- let clientSocket = null;
24
- app.get('/up', (req, res) => {
40
+ isServer = appConfig.isServer;
41
+ serverSocket = require('./app/socket/server')(server);
42
+
43
+
44
+
45
+ // ==== Server Health checker
46
+ app.get('/health', (req, res) => {
25
47
  res.send('ok');
26
48
  });
27
49
 
28
-
50
+ // ===== Init Platform
29
51
  app.get('/init', (req, res) => {
30
- if (!appConfig.isServer && clientSocket && req.header('company-id')) {
31
- clientSocket = require('./app/socket/client')(PROXY_TARGET, req.header('company-id'));
52
+ if (!clientSocket && !appConfig.isServer) {
53
+ if (req.header('company-id') && req.header('terminal-id')) {
54
+ clientSocket = require('./app/socket/client')(PROXY_TARGET, req.header('company-id'));
55
+ }
32
56
  }
33
57
  res.send('ok');
34
58
  });
35
59
 
36
60
 
61
+ // ==== Load Platform Based Routes ====
37
62
  loadRoutes(app, join(__dirname, ('routes/' + (appConfig.isServer ? 'server' : 'desktop'))));
38
- loadRoutes(app, join(__dirname, ('routes/common')));
39
- app.use(async (req, res, next) => {
40
- try {
41
- const targetUrl = PROXY_TARGET + req.originalUrl;
42
- const config = {
43
- method: req.method,
44
- url: targetUrl,
45
- headers: {...req.headers, host: new URL(PROXY_TARGET).host},
46
- responseType: 'stream'
47
- };
48
-
49
- if (req.body && Object.keys(req.body).length > 0) {
50
- config.data = req.body;
51
- }
52
-
53
- if (req.files && req.files.length > 0) {
54
- const FormData = require('form-data');
55
- const form = new FormData();
56
- req.files.forEach(file => {
57
- form.append(file.fieldname, file.buffer, file.originalname);
58
- });
59
-
60
- Object.entries(req.body).forEach(([key, value]) => {
61
- form.append(key, value);
62
- });
63
-
64
- config.data = form;
65
- config.headers = {...config.headers, ...form.getHeaders(), 'Accept': 'application/json'};
66
- }
67
63
 
68
- const response = await axios(config);
69
64
 
65
+ // ==== Load Common Routes ====
66
+ loadRoutes(app, join(__dirname, ('routes/common')));
70
67
 
71
- res.status(response.status);
72
- // Object.entries(response.headers).forEach(([key, value]) => {
73
- // res.setHeader(key, value);
74
- // });
75
-
76
- const responseData = await streamToString(response.data);
77
-
78
-
79
- if (typeof responseData === 'string' || Buffer.isBuffer(responseData)) {
80
- res.send(responseData);
81
- } else {
82
- res.json(responseData);
83
- }
84
-
85
- } catch (error) {
86
- if (error.response) {
87
- // Если сервер вернул ответ с ошибкой
88
- res.status(error.response.status);
89
-
90
-
91
- if (error.response.data && typeof error.response.data === 'object') {
92
- const details = await streamToString(error.response.data)
93
- res.json({error: 'Ошибка от проксируемого сервера', details});
94
- } else {
95
- res.send(error.response.data);
96
- }
97
- } else {
98
- // Внутренняя ошибка сервера (например, таймаут или потеря связи)
99
- res.status(500).json({error: 'Внутренняя ошибка прокси', details: error.message});
100
- }
68
+ // ==== Load Proxy ====
69
+ loadProxy(app);
101
70
 
102
71
 
103
- console.error('Ошибка при проксировании запроса:', error.message);
72
+ // ==== Start Listen ====
73
+ const hostname = appConfig.host || 'localhost';
74
+ server.listen(port, hostname, async () => {
75
+ if (hostname === 'localhost') {
76
+ console.log(`Server started on ${hostname} http://${hostname}:${port}`);
77
+ } else {
78
+ const host = await getIpAddress();
79
+ console.log(`Server started on ${hostname} http://${host}:${port}`);
104
80
  }
105
- });
106
- server.listen(port, appConfig.host || 'localhost', () => {
107
- console.log('Server started on: ' + port);
108
81
  })
109
82
  }
110
83
 
@@ -0,0 +1,20 @@
1
+ const escpos = require("escpos");
2
+ escpos.USB = require('@alizadefaig/cafetap-escpos-usb');
3
+ device = new escpos.USB(8137, 8214);
4
+ console.log(device);
5
+ // console.log(base64Str);
6
+
7
+ const printer = new escpos.Printer(device, {});
8
+
9
+
10
+
11
+
12
+ device.open((err) => {
13
+ console.log('asd')
14
+ if (err) {
15
+ console.log(err)
16
+ }
17
+ printer.text('Hello World!');
18
+
19
+ printer.newLine().newLine().cut().close();
20
+ });
package/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const {readdirSync, existsSync} = require("node:fs");
2
2
  const {extname, join} = require("node:path");
3
3
  const {networkInterfaces} = require("os");
4
+ const escpos = require("escpos");
4
5
 
5
6
  function loadRoutes(app, routesDir, prefix = '') {
6
7
  if (!existsSync(routesDir)) {
@@ -66,7 +67,7 @@ function getPrinterDevice(printer) {
66
67
  let device = null;
67
68
  try {
68
69
  if (printer.type === 'USB') {
69
- device = new escpos.USB(printer.vendor_id, printer.product_id);
70
+ device = new escpos.USB(+printer.vendor_id, +printer.product_id);
70
71
  } else {
71
72
  device = new escpos.Network(printer.ip_address);
72
73
  }
@@ -91,10 +92,21 @@ const streamToString = async (stream) => {
91
92
  }
92
93
  };
93
94
 
95
+ const socketSendByFilter = ({companyId, eventName, data, to, toId, excepts}, serverSocket = null) => {
96
+ if (!serverSocket) {
97
+ serverSocket = require('./app/socket/server')();
98
+ }
99
+
100
+ if (!to) {
101
+ serverSocket.to(companyId).emit(eventName, data);
102
+ }
103
+ }
104
+
94
105
  module.exports = {
95
106
  loadRoutes,
96
107
  getIpAddress,
97
108
  ipRange,
98
109
  getPrinterDevice,
99
- streamToString
110
+ streamToString,
111
+ socketSendByFilter
100
112
  }
package/config.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "isServer": true,
3
- "apiUrl": "https://admin.cafepos.az",
4
- "debug": false,
5
- "port": 3005
6
- }
@@ -1,19 +0,0 @@
1
- const express = require('express');
2
- const serverSocket = require("../../app/socket/server")();
3
- const router = express.Router();
4
-
5
-
6
- router.all('/socket', (req, res) => {
7
- const companyId = req.body?.company_id || req.query?.company_id;
8
- const eventName = req.body?.event || req.query?.event;
9
- const data = req.body?.data || req.query?.data;
10
- if (!companyId || !eventName || !data) {
11
- return res.send('ok');
12
- }
13
- serverSocket
14
- .to(companyId)
15
- .emit(eventName, data);
16
- res.send('ok');
17
- });
18
-
19
- module.exports = router;