underpost 2.8.882 → 2.8.884
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/README.md +10 -2
- package/bin/db.js +1 -4
- package/cli.md +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/manifests/maas/device-scan.sh +1 -1
- package/package.json +1 -1
- package/src/api/user/user.service.js +3 -10
- package/src/client/components/core/Docs.js +0 -1
- package/src/client/components/core/Modal.js +14 -8
- package/src/index.js +1 -1
- package/src/runtime/express/Express.js +262 -0
- package/src/runtime/lampp/Lampp.js +272 -128
- package/src/server/auth.js +74 -16
- package/src/server/runtime.js +54 -230
- package/src/runtime/nginx/Nginx.js +0 -3
- package/src/runtime/xampp/Xampp.js +0 -83
package/README.md
CHANGED
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
67
71
|
|
|
68
72
|
|
|
69
73
|
|
|
@@ -72,7 +76,7 @@
|
|
|
72
76
|
<!-- badges -->
|
|
73
77
|
|
|
74
78
|
|
|
75
|
-
[](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [](https://www.npmjs.com/package/underpost) [](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.yml) [](https://www.npmjs.com/package/underpost) [](https://socket.dev/npm/package/underpost/overview/2.8.884) [](https://coveralls.io/github/underpostnet/engine?branch=master) [](https://www.npmjs.org/package/underpost) [](https://www.npmjs.com/package/underpost)
|
|
76
80
|
|
|
77
81
|
|
|
78
82
|
<!-- end-badges -->
|
|
@@ -125,6 +129,10 @@
|
|
|
125
129
|
|
|
126
130
|
|
|
127
131
|
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
128
136
|
|
|
129
137
|
|
|
130
138
|
|
|
@@ -174,7 +182,7 @@ Run dev client server
|
|
|
174
182
|
npm run dev
|
|
175
183
|
```
|
|
176
184
|
<!-- -->
|
|
177
|
-
## underpost ci/cd cli v2.8.
|
|
185
|
+
## underpost ci/cd cli v2.8.884
|
|
178
186
|
|
|
179
187
|
### Usage: `underpost [options] [command]`
|
|
180
188
|
```
|
package/bin/db.js
CHANGED
|
@@ -2,7 +2,6 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import { shellExec } from '../src/server/process.js';
|
|
3
3
|
import { loggerFactory } from '../src/server/logger.js';
|
|
4
4
|
import { MariaDB } from '../src/db/mariadb/MariaDB.js';
|
|
5
|
-
import { Xampp } from '../src/runtime/xampp/Xampp.js';
|
|
6
5
|
import { Lampp } from '../src/runtime/lampp/Lampp.js';
|
|
7
6
|
import { getCapVariableName, loadConf, splitFileFactory } from '../src/server/conf.js';
|
|
8
7
|
import { DataBaseProvider } from '../src/db/DataBaseProvider.js';
|
|
@@ -105,9 +104,7 @@ try {
|
|
|
105
104
|
break;
|
|
106
105
|
case 'import':
|
|
107
106
|
break;
|
|
108
|
-
|
|
109
|
-
await Xampp.initService();
|
|
110
|
-
break;
|
|
107
|
+
|
|
111
108
|
case 'init-lampp-service':
|
|
112
109
|
await Lampp.initService();
|
|
113
110
|
break;
|
package/cli.md
CHANGED
|
@@ -17,7 +17,7 @@ spec:
|
|
|
17
17
|
spec:
|
|
18
18
|
containers:
|
|
19
19
|
- name: dd-default-development-blue
|
|
20
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
20
|
+
image: localhost/rockylinux9-underpost:v2.8.884
|
|
21
21
|
# resources:
|
|
22
22
|
# requests:
|
|
23
23
|
# memory: "124Ki"
|
|
@@ -100,7 +100,7 @@ spec:
|
|
|
100
100
|
spec:
|
|
101
101
|
containers:
|
|
102
102
|
- name: dd-default-development-green
|
|
103
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
103
|
+
image: localhost/rockylinux9-underpost:v2.8.884
|
|
104
104
|
# resources:
|
|
105
105
|
# requests:
|
|
106
106
|
# memory: "124Ki"
|
|
@@ -17,7 +17,7 @@ spec:
|
|
|
17
17
|
spec:
|
|
18
18
|
containers:
|
|
19
19
|
- name: dd-test-development-blue
|
|
20
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
20
|
+
image: localhost/rockylinux9-underpost:v2.8.884
|
|
21
21
|
# resources:
|
|
22
22
|
# requests:
|
|
23
23
|
# memory: "96294Ki"
|
|
@@ -104,7 +104,7 @@ spec:
|
|
|
104
104
|
spec:
|
|
105
105
|
containers:
|
|
106
106
|
- name: dd-test-development-green
|
|
107
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
107
|
+
image: localhost/rockylinux9-underpost:v2.8.884
|
|
108
108
|
# resources:
|
|
109
109
|
# requests:
|
|
110
110
|
# memory: "96294Ki"
|
|
@@ -20,7 +20,7 @@ for iface_path in /sys/class/net/*; do
|
|
|
20
20
|
if [ -f "$pci_dev/vendor" ] && [ -f "$pci_dev/device" ]; then
|
|
21
21
|
vendor_id=$(< "$pci_dev/vendor")
|
|
22
22
|
device_id=$(< "$pci_dev/device")
|
|
23
|
-
#
|
|
23
|
+
# parse 0x8086 to 8086, etc.
|
|
24
24
|
vendor_id=${vendor_id#0x}
|
|
25
25
|
device_id=${device_id#0x}
|
|
26
26
|
pci="${vendor_id}:${device_id}"
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createSessionAndUserToken,
|
|
7
7
|
createUserAndSession,
|
|
8
8
|
refreshSessionAndToken,
|
|
9
|
-
|
|
9
|
+
logoutSession,
|
|
10
10
|
jwtSign,
|
|
11
11
|
getBearerToken,
|
|
12
12
|
validatePasswordMiddleware,
|
|
@@ -382,15 +382,8 @@ const UserService = {
|
|
|
382
382
|
const User = DataBaseProvider.instance[`${options.host}${options.path}`].mongoose.models.User;
|
|
383
383
|
|
|
384
384
|
if (req.params.id === 'logout') {
|
|
385
|
-
const
|
|
386
|
-
if (
|
|
387
|
-
const hashedToken = hashToken(refreshToken);
|
|
388
|
-
await User.updateOne(
|
|
389
|
-
{ 'activeSessions.tokenHash': hashedToken },
|
|
390
|
-
{ $pull: { activeSessions: { tokenHash: hashedToken } } },
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
res.clearCookie('refreshToken');
|
|
385
|
+
const result = await logoutSession(User, req, res);
|
|
386
|
+
if (!result) throw new Error('Logout failed');
|
|
394
387
|
return { message: 'Logged out successfully' };
|
|
395
388
|
}
|
|
396
389
|
|
|
@@ -156,7 +156,6 @@ const Docs = {
|
|
|
156
156
|
id: options.idModal,
|
|
157
157
|
routeId: 'docs',
|
|
158
158
|
event: (path) => {
|
|
159
|
-
Modal.subMenuBtnClass['docs'].open = !Modal.subMenuBtnClass['docs'].open;
|
|
160
159
|
if (s(`.btn-docs-${path}`)) s(`.btn-docs-${path}`).click();
|
|
161
160
|
if (Modal.mobileModal()) {
|
|
162
161
|
setTimeout(() => {
|
|
@@ -2191,14 +2191,13 @@ const Modal = {
|
|
|
2191
2191
|
: { ...Modal.subMenuBtnClass, _: { btnSelector, labelSelector } };
|
|
2192
2192
|
|
|
2193
2193
|
for (const keyDataBtn of Object.keys(_data)) {
|
|
2194
|
-
const {
|
|
2194
|
+
const { labelSelector, top } = _data[keyDataBtn];
|
|
2195
2195
|
if (top)
|
|
2196
2196
|
setTimeout(() => {
|
|
2197
2197
|
top();
|
|
2198
2198
|
});
|
|
2199
|
-
if (open) continue;
|
|
2200
2199
|
sa(labelSelector).forEach((el) => {
|
|
2201
|
-
el.classList.add('hide');
|
|
2200
|
+
if (!el.classList.contains('hide')) el.classList.add('hide');
|
|
2202
2201
|
el.style.transition = null;
|
|
2203
2202
|
});
|
|
2204
2203
|
|
|
@@ -2413,6 +2412,10 @@ const buildBadgeToolTipMenuOption = (id, sideKey = 'left') => {
|
|
|
2413
2412
|
return option;
|
|
2414
2413
|
};
|
|
2415
2414
|
|
|
2415
|
+
const isSubMenuOpen = (subMenuId) => {
|
|
2416
|
+
return s(`.down-arrow-submenu-${subMenuId}`).style.rotate === '180deg';
|
|
2417
|
+
};
|
|
2418
|
+
|
|
2416
2419
|
const subMenuRender = async (subMenuId) => {
|
|
2417
2420
|
const _hBtn = 51;
|
|
2418
2421
|
const menuBtn = s(`.main-btn-${subMenuId}`);
|
|
@@ -2435,8 +2438,7 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2435
2438
|
menuBtn.style.transition = '.3s';
|
|
2436
2439
|
arrow.style.transition = '.3s';
|
|
2437
2440
|
|
|
2438
|
-
if (
|
|
2439
|
-
Modal.subMenuBtnClass[subMenuId].open = false;
|
|
2441
|
+
if (isSubMenuOpen(subMenuId)) {
|
|
2440
2442
|
// Close animation
|
|
2441
2443
|
menuContainer.style.overflow = 'hidden';
|
|
2442
2444
|
menuContainer.style.height = '0px';
|
|
@@ -2446,8 +2448,12 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2446
2448
|
arrow.style.rotate = '0deg';
|
|
2447
2449
|
});
|
|
2448
2450
|
} else {
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
+
sa(`.menu-label-text-${subMenuId}`).forEach((el) => {
|
|
2452
|
+
if (!el.classList.contains('hide')) el.classList.add('hide');
|
|
2453
|
+
});
|
|
2454
|
+
setTimeout(() => {
|
|
2455
|
+
Modal.menuTextLabelAnimation('modal-menu', subMenuId);
|
|
2456
|
+
});
|
|
2451
2457
|
// Open animation
|
|
2452
2458
|
setTimeout(top, 360);
|
|
2453
2459
|
menuContainer.style.width = '320px';
|
|
@@ -2466,4 +2472,4 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2466
2472
|
}, 500);
|
|
2467
2473
|
};
|
|
2468
2474
|
|
|
2469
|
-
export { Modal, renderMenuLabel, renderViewTitle, buildBadgeToolTipMenuOption, subMenuRender };
|
|
2475
|
+
export { Modal, renderMenuLabel, renderViewTitle, buildBadgeToolTipMenuOption, subMenuRender, isSubMenuOpen };
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A service dedicated to creating and configuring an Express.js application
|
|
3
|
+
* instance based on server configuration data.
|
|
4
|
+
* @module src/runtime/express/Express.js
|
|
5
|
+
* @namespace ExpressService
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs-extra';
|
|
9
|
+
import express from 'express';
|
|
10
|
+
import fileUpload from 'express-fileupload';
|
|
11
|
+
import swaggerUi from 'swagger-ui-express';
|
|
12
|
+
import compression from 'compression';
|
|
13
|
+
import { createServer } from 'http';
|
|
14
|
+
|
|
15
|
+
import UnderpostStartUp from '../../server/start.js';
|
|
16
|
+
import { loggerFactory, loggerMiddleware } from '../../server/logger.js';
|
|
17
|
+
import { getCapVariableName, newInstance } from '../../client/components/core/CommonJs.js';
|
|
18
|
+
import { MailerProvider } from '../../mailer/MailerProvider.js';
|
|
19
|
+
import { DataBaseProvider } from '../../db/DataBaseProvider.js';
|
|
20
|
+
import { createPeerServer } from '../../server/peer.js';
|
|
21
|
+
import { createValkeyConnection } from '../../server/valkey.js';
|
|
22
|
+
import { applySecurity, authMiddlewareFactory } from '../../server/auth.js';
|
|
23
|
+
import { ssrMiddlewareFactory } from '../../server/ssr.js';
|
|
24
|
+
|
|
25
|
+
const logger = loggerFactory(import.meta);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @class ExpressService
|
|
29
|
+
* @description A service dedicated to creating and configuring an Express.js application
|
|
30
|
+
* instance based on server configuration data.
|
|
31
|
+
* @memberof ExpressService
|
|
32
|
+
*/
|
|
33
|
+
class ExpressService {
|
|
34
|
+
/**
|
|
35
|
+
* Creates and configures a complete Express application instance for a specific host/path configuration.
|
|
36
|
+
*
|
|
37
|
+
* @method createApp
|
|
38
|
+
* @memberof ExpressService
|
|
39
|
+
* @param {string} config.host - The host name for the instance (e.g., 'www.example.com').
|
|
40
|
+
* @param {string} config.path - The URL path for the instance (e.g., '/', '/api/v1').
|
|
41
|
+
* @param {number} config.port - The primary listening port for the instance.
|
|
42
|
+
* @param {string} config.client - The client associated with the instance (used for SSR/Mailer configuration lookup).
|
|
43
|
+
* @param {string[]} [config.apis] - A list of API names to load and attach routers for.
|
|
44
|
+
* @param {string[]} config.origins - Allowed origins for CORS.
|
|
45
|
+
* @param {string} [config.directory] - The directory for static files (if overriding default).
|
|
46
|
+
* @param {string} [config.ws] - The WebSocket server name to use.
|
|
47
|
+
* @param {object} [config.mailer] - Mailer configuration.
|
|
48
|
+
* @param {object} [config.db] - Database configuration.
|
|
49
|
+
* @param {string} [config.redirect] - URL or flag to indicate an HTTP redirect should be configured.
|
|
50
|
+
* @param {boolean} [config.peer] - Whether to enable the peer server.
|
|
51
|
+
* @param {object} [config.valkey] - Valkey connection configuration.
|
|
52
|
+
* @param {string} [config.apiBaseHost] - Base host for the API (if running separate API).
|
|
53
|
+
* @param {number} [config.devApiPort] - The dynamically calculated development API port used for CORS in dev mode.
|
|
54
|
+
* @param {string} config.redirectTarget - The full target URL for redirection (used if `redirect` is true).
|
|
55
|
+
* @param {string} config.rootHostPath - The root path for public host assets (e.g., `/public/hostname`).
|
|
56
|
+
* @param {object} config.confSSR - The SSR configuration object, used to look up Mailer templates.
|
|
57
|
+
* @param {import('prom-client').Counter<string>} config.promRequestCounter - Prometheus request counter instance.
|
|
58
|
+
* @param {import('prom-client').Registry} config.promRegister - Prometheus register instance for metrics.
|
|
59
|
+
* @returns {Promise<{portsUsed: number}>} An object indicating how many additional ports were used (e.g., for PeerServer).
|
|
60
|
+
*/
|
|
61
|
+
async createApp({
|
|
62
|
+
host,
|
|
63
|
+
path,
|
|
64
|
+
port,
|
|
65
|
+
client,
|
|
66
|
+
apis,
|
|
67
|
+
origins,
|
|
68
|
+
directory,
|
|
69
|
+
ws,
|
|
70
|
+
mailer,
|
|
71
|
+
db,
|
|
72
|
+
redirect,
|
|
73
|
+
peer,
|
|
74
|
+
valkey,
|
|
75
|
+
apiBaseHost,
|
|
76
|
+
devApiPort, // New parameter for dev environment CORS
|
|
77
|
+
redirectTarget,
|
|
78
|
+
rootHostPath,
|
|
79
|
+
confSSR,
|
|
80
|
+
promRequestCounter,
|
|
81
|
+
promRegister,
|
|
82
|
+
}) {
|
|
83
|
+
let portsUsed = 0;
|
|
84
|
+
const runningData = {
|
|
85
|
+
host,
|
|
86
|
+
path,
|
|
87
|
+
runtime: 'nodejs',
|
|
88
|
+
client,
|
|
89
|
+
meta: import.meta,
|
|
90
|
+
apis,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const app = express();
|
|
94
|
+
|
|
95
|
+
if (process.env.NODE_ENV === 'production') app.set('trust proxy', true);
|
|
96
|
+
|
|
97
|
+
app.use((req, res, next) => {
|
|
98
|
+
res.on('finish', () => {
|
|
99
|
+
promRequestCounter.inc({
|
|
100
|
+
instance: `${host}:${port}${path}`,
|
|
101
|
+
method: req.method,
|
|
102
|
+
status_code: res.statusCode,
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
return next();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Metrics endpoint
|
|
109
|
+
app.get(`${path === '/' ? '' : path}/metrics`, async (req, res) => {
|
|
110
|
+
res.set('Content-Type', promRegister.contentType);
|
|
111
|
+
return res.end(await promRegister.metrics());
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Logging, Compression, and Body Parsers
|
|
115
|
+
app.use(loggerMiddleware(import.meta));
|
|
116
|
+
// Compression filter logic is correctly inlined here
|
|
117
|
+
app.use(compression({ filter: (req, res) => !req.headers['x-no-compression'] && compression.filter(req, res) }));
|
|
118
|
+
app.use(express.json({ limit: '100MB' }));
|
|
119
|
+
app.use(express.urlencoded({ extended: true, limit: '20MB' }));
|
|
120
|
+
app.use(fileUpload());
|
|
121
|
+
|
|
122
|
+
if (process.env.NODE_ENV === 'development') app.set('json spaces', 2);
|
|
123
|
+
|
|
124
|
+
// Language handling middleware
|
|
125
|
+
app.use((req, res, next) => {
|
|
126
|
+
const lang = req.headers['accept-language'] || 'en';
|
|
127
|
+
req.lang = typeof lang === 'string' && lang.toLowerCase().match('es') ? 'es' : 'en';
|
|
128
|
+
return next();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Static file serving
|
|
132
|
+
app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
|
|
133
|
+
|
|
134
|
+
// Swagger path definition
|
|
135
|
+
const swaggerJsonPath = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
|
|
136
|
+
const swaggerPath = `${path === '/' ? `/api-docs` : `${path}/api-docs`}`;
|
|
137
|
+
|
|
138
|
+
// Flag swagger requests before security middleware
|
|
139
|
+
if (fs.existsSync(swaggerJsonPath)) {
|
|
140
|
+
app.use(swaggerPath, (req, res, next) => {
|
|
141
|
+
res.locals.isSwagger = true;
|
|
142
|
+
next();
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Security and CORS
|
|
147
|
+
applySecurity(app, {
|
|
148
|
+
origin: (origin, callback) => {
|
|
149
|
+
// Use devApiPort if provided to calculate the allowed development CORS origin
|
|
150
|
+
const devOrigin =
|
|
151
|
+
apis && process.env.NODE_ENV === 'development' && devApiPort ? [`http://localhost:${devApiPort}`] : [];
|
|
152
|
+
|
|
153
|
+
const allowedOrigins = origins.concat(devOrigin);
|
|
154
|
+
|
|
155
|
+
if (!origin || allowedOrigins.includes(origin)) {
|
|
156
|
+
callback(null, true);
|
|
157
|
+
} else {
|
|
158
|
+
callback(new Error('Not allowed by CORS'));
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Handle redirection-only instances
|
|
164
|
+
if (redirect) {
|
|
165
|
+
app.use((req, res, next) => {
|
|
166
|
+
if (process.env.NODE_ENV === 'production' && !req.url.startsWith(`/.well-known/acme-challenge`)) {
|
|
167
|
+
return res.status(302).redirect(redirectTarget + req.url);
|
|
168
|
+
}
|
|
169
|
+
return next();
|
|
170
|
+
});
|
|
171
|
+
await UnderpostStartUp.API.listenPortController(app, port, runningData);
|
|
172
|
+
return { portsUsed };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Create HTTP server for regular instances (required for WebSockets)
|
|
176
|
+
const server = createServer({}, app);
|
|
177
|
+
if (peer) portsUsed++; // Peer server uses one additional port
|
|
178
|
+
|
|
179
|
+
if (!apiBaseHost) {
|
|
180
|
+
// Swagger UI setup
|
|
181
|
+
if (fs.existsSync(swaggerJsonPath)) {
|
|
182
|
+
const swaggerDoc = JSON.parse(fs.readFileSync(swaggerJsonPath, 'utf8'));
|
|
183
|
+
// Reusing swaggerPath defined outside, removing unnecessary redeclaration
|
|
184
|
+
app.use(swaggerPath, swaggerUi.serve, swaggerUi.setup(swaggerDoc));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Database and Valkey connections
|
|
188
|
+
if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
|
|
189
|
+
if (valkey) await createValkeyConnection({ host, path }, valkey);
|
|
190
|
+
|
|
191
|
+
// Mailer setup
|
|
192
|
+
if (mailer) {
|
|
193
|
+
const mailerSsrConf = confSSR[getCapVariableName(client)];
|
|
194
|
+
await MailerProvider.load({
|
|
195
|
+
id: `${host}${path}`,
|
|
196
|
+
meta: `mailer-${host}${path}`,
|
|
197
|
+
host,
|
|
198
|
+
path,
|
|
199
|
+
...mailer,
|
|
200
|
+
templates: mailerSsrConf ? mailerSsrConf.mailer : {},
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// API router loading
|
|
205
|
+
if (apis && apis.length > 0) {
|
|
206
|
+
const authMiddleware = authMiddlewareFactory({ host, path });
|
|
207
|
+
const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
|
|
208
|
+
for (const api of apis) {
|
|
209
|
+
logger.info(`Build api server`, `${host}${apiPath}/${api}`);
|
|
210
|
+
const { ApiRouter } = await import(`../../api/${api}/${api}.router.js`);
|
|
211
|
+
const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware, origins });
|
|
212
|
+
app.use(`${apiPath}/${api}`, router);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// WebSocket server setup
|
|
217
|
+
if (ws) {
|
|
218
|
+
const { createIoServer } = await import(`../../ws/${ws}/${ws}.ws.server.js`);
|
|
219
|
+
const { options, meta } = await createIoServer(server, { host, path, db, port, origins });
|
|
220
|
+
|
|
221
|
+
// Listen on the main port for the WS server
|
|
222
|
+
await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), port, {
|
|
223
|
+
runtime: 'nodejs',
|
|
224
|
+
client: null,
|
|
225
|
+
host,
|
|
226
|
+
path: options.path,
|
|
227
|
+
meta,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Peer server setup
|
|
232
|
+
if (peer) {
|
|
233
|
+
const peerPort = newInstance(port + portsUsed); // portsUsed is 1 here
|
|
234
|
+
const { options, meta, peerServer } = await createPeerServer({
|
|
235
|
+
port: peerPort,
|
|
236
|
+
devPort: port,
|
|
237
|
+
origins,
|
|
238
|
+
host,
|
|
239
|
+
path,
|
|
240
|
+
});
|
|
241
|
+
await UnderpostStartUp.API.listenPortController(peerServer, peerPort, {
|
|
242
|
+
runtime: 'nodejs',
|
|
243
|
+
client: null,
|
|
244
|
+
host,
|
|
245
|
+
path: options.path,
|
|
246
|
+
meta,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// SSR middleware loading
|
|
252
|
+
const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
|
|
253
|
+
for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
|
|
254
|
+
|
|
255
|
+
// Start listening on the main port
|
|
256
|
+
await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
257
|
+
|
|
258
|
+
return { portsUsed };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export default new ExpressService();
|