underpost 2.8.843 → 2.8.845
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/.github/workflows/{ghpkg.yml → ghpkg.ci.yml} +1 -1
- package/.github/workflows/{npmpkg.yml → npmpkg.ci.yml} +1 -1
- package/.github/workflows/{publish.yml → publish.ci.yml} +1 -1
- package/.github/workflows/{pwa-microservices-template.page.yml → pwa-microservices-template-page.cd.yml} +1 -1
- package/.github/workflows/{pwa-microservices-template.test.yml → pwa-microservices-template-test.ci.yml} +1 -1
- package/.vscode/settings.json +0 -1
- package/README.md +18 -2
- package/bin/build.js +8 -5
- package/bin/deploy.js +10 -69
- package/bin/file.js +15 -11
- package/cli.md +47 -43
- package/docker-compose.yml +1 -1
- package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
- package/manifests/maas/gpu-diag.sh +1 -1
- package/package.json +3 -5
- package/src/api/user/user.router.js +24 -1
- package/src/cli/cluster.js +19 -10
- package/src/cli/index.js +1 -0
- package/src/cli/run.js +21 -0
- package/src/client/components/core/Css.js +52 -2
- package/src/client/components/core/CssCore.js +0 -4
- package/src/client/components/core/Docs.js +10 -57
- package/src/client/components/core/DropDown.js +128 -82
- package/src/client/components/core/EventsUI.js +92 -5
- package/src/client/components/core/Modal.js +451 -120
- package/src/client/components/core/NotificationManager.js +2 -2
- package/src/client/components/core/Panel.js +2 -2
- package/src/client/components/core/PanelForm.js +12 -2
- package/src/client/components/core/Recover.js +1 -1
- package/src/client/components/core/Router.js +63 -2
- package/src/client/components/core/Translate.js +2 -2
- package/src/index.js +1 -1
- package/src/server/client-build-docs.js +205 -0
- package/src/server/client-build.js +11 -140
- package/src/server/valkey.js +102 -41
|
@@ -15,10 +15,10 @@ const NotificationManager = {
|
|
|
15
15
|
right: 5px !important;
|
|
16
16
|
width: 300px !important;
|
|
17
17
|
bottom: ${5 + (options?.heightBottomBar ? options.heightBottomBar : 0)}px !important;
|
|
18
|
-
z-index:
|
|
18
|
+
z-index: 11 !important;
|
|
19
19
|
}
|
|
20
20
|
.notification-board-title {
|
|
21
|
-
padding:
|
|
21
|
+
padding: 11px !important;
|
|
22
22
|
}
|
|
23
23
|
.notification-manager-date {
|
|
24
24
|
font-size: 20px !important;
|
|
@@ -119,10 +119,11 @@ const Panel = {
|
|
|
119
119
|
});
|
|
120
120
|
s(`.a-${payload._id}`).onclick = async (e) => {
|
|
121
121
|
e.preventDefault();
|
|
122
|
+
if (options.onClick) await options.onClick({ payload });
|
|
122
123
|
};
|
|
123
124
|
s(`.container-${idPanel}-${id}`).onclick = async (e) => {
|
|
124
125
|
e.preventDefault();
|
|
125
|
-
if (options.onClick) await options.onClick({ payload });
|
|
126
|
+
// if (options.onClick) await options.onClick({ payload });
|
|
126
127
|
};
|
|
127
128
|
});
|
|
128
129
|
if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
|
|
@@ -540,7 +541,6 @@ const Panel = {
|
|
|
540
541
|
background: #f6f6f6;
|
|
541
542
|
color: black;
|
|
542
543
|
padding: 10px;
|
|
543
|
-
cursor: pointer;
|
|
544
544
|
min-height: 400px;
|
|
545
545
|
}
|
|
546
546
|
.${idPanel}:hover {
|
|
@@ -15,7 +15,7 @@ import { getSrcFromFileData } from './Input.js';
|
|
|
15
15
|
import { imageShimmer, renderCssAttr } from './Css.js';
|
|
16
16
|
import { Translate } from './Translate.js';
|
|
17
17
|
import { Modal } from './Modal.js';
|
|
18
|
-
import { listenQueryPathInstance, setQueryPath } from './Router.js';
|
|
18
|
+
import { closeModalRouteChangeEvents, listenQueryPathInstance, renderTitle, setQueryPath } from './Router.js';
|
|
19
19
|
|
|
20
20
|
const PanelForm = {
|
|
21
21
|
Data: {},
|
|
@@ -425,13 +425,22 @@ const PanelForm = {
|
|
|
425
425
|
});
|
|
426
426
|
let firsUpdateEvent = false;
|
|
427
427
|
let lastCid;
|
|
428
|
+
let lastUserId;
|
|
429
|
+
closeModalRouteChangeEvents[idPanel] = (newPath) => {
|
|
430
|
+
if (newPath.split('?')[0] === '/' && PanelForm.Data[idPanel].data && PanelForm.Data[idPanel].data.length === 0) {
|
|
431
|
+
this.Data[idPanel].updatePanel();
|
|
432
|
+
}
|
|
433
|
+
};
|
|
428
434
|
this.Data[idPanel].updatePanel = async () => {
|
|
429
435
|
const cid = getQueryParams().cid ? getQueryParams().cid : '';
|
|
430
|
-
|
|
436
|
+
const forceUpdate = lastUserId !== Elements.Data.user.main.model.user._id;
|
|
437
|
+
if (lastCid === cid && !forceUpdate) return;
|
|
438
|
+
lastUserId = newInstance(Elements.Data.user.main.model.user._id);
|
|
431
439
|
lastCid = cid;
|
|
432
440
|
if (options.route === 'home') Modal.homeCid = newInstance(cid);
|
|
433
441
|
htmls(`.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`, await renderSrrPanelData());
|
|
434
442
|
await getPanelData();
|
|
443
|
+
if (this.Data[idPanel].data.length === 1) renderTitle(this.Data[idPanel].data[0].title);
|
|
435
444
|
htmls(
|
|
436
445
|
`.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`,
|
|
437
446
|
await panelRender({ data: this.Data[idPanel].data }),
|
|
@@ -452,6 +461,7 @@ const PanelForm = {
|
|
|
452
461
|
if (!options.parentIdModal)
|
|
453
462
|
Modal.Data['modal-menu'].onHome[idPanel] = async () => {
|
|
454
463
|
lastCid = undefined;
|
|
464
|
+
lastUserId = undefined;
|
|
455
465
|
setQueryPath({ path: options.route, queryPath: '' });
|
|
456
466
|
await this.Data[idPanel].updatePanel();
|
|
457
467
|
};
|
|
@@ -62,7 +62,7 @@ const Recover = {
|
|
|
62
62
|
|
|
63
63
|
setTimeout(async () => {
|
|
64
64
|
if (user && user.email) {
|
|
65
|
-
s(`.recover-email`).value = user.email;
|
|
65
|
+
s(`.recover-email`).value = user.role === 'guest' ? '' : user.email;
|
|
66
66
|
if (user.emailConfirmed) s(`.recover-email`).setAttribute('disabled', '');
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { titleFormatted } from './CommonJs.js';
|
|
2
2
|
import { loggerFactory } from './Logger.js';
|
|
3
3
|
import { getProxyPath, getQueryParams, htmls, s, setPath } from './VanillaJs.js';
|
|
4
|
+
import { Modal } from './Modal.js';
|
|
5
|
+
import { Worker } from './Worker.js';
|
|
4
6
|
|
|
5
7
|
// Router
|
|
6
8
|
|
|
7
9
|
const logger = loggerFactory(import.meta);
|
|
8
10
|
|
|
11
|
+
const renderTitle = (title, nameApp) => htmls('title', html`${title} | ${nameApp ?? Worker.RouterInstance.NameApp}`);
|
|
12
|
+
|
|
9
13
|
const setDocTitle = (options = { Routes: () => {}, route: '', NameApp: '' }) => {
|
|
10
14
|
const { Routes, route, NameApp } = options;
|
|
11
15
|
let title = titleFormatted(Routes()[`/${route}`].title);
|
|
12
16
|
if (Routes()[`/${route}`].upperCase) title = title.toUpperCase();
|
|
13
|
-
|
|
17
|
+
renderTitle(title, NameApp);
|
|
14
18
|
{
|
|
15
19
|
const routeId = route === '' ? 'home' : route;
|
|
16
20
|
if (s(`.main-btn-${routeId}`)) {
|
|
@@ -75,4 +79,61 @@ const listenQueryPathInstance = ({ id, routeId, event }, queryKey = 'cid') => {
|
|
|
75
79
|
});
|
|
76
80
|
};
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
const closeModalRouteChangeEvents = {};
|
|
83
|
+
const triggerCloseModalRouteChangeEvents = (newPath) => {
|
|
84
|
+
console.warn('[closeModalRouteChangeEvent]', newPath);
|
|
85
|
+
for (const event of Object.keys(closeModalRouteChangeEvents)) closeModalRouteChangeEvents[event](newPath);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const closeModalRouteChangeEvent = (options = {}) => {
|
|
89
|
+
const { route, RouterInstance, homeCid } = options;
|
|
90
|
+
if (!route) return;
|
|
91
|
+
|
|
92
|
+
let path = window.location.pathname;
|
|
93
|
+
if (path[path.length - 1] !== '/') path = `${path}/`;
|
|
94
|
+
let newPath = `${getProxyPath()}`;
|
|
95
|
+
|
|
96
|
+
if (path !== newPath) {
|
|
97
|
+
for (const subIdModal of Object.keys(Modal.Data).reverse()) {
|
|
98
|
+
if (Modal.Data[subIdModal]?.options?.route) {
|
|
99
|
+
newPath = `${newPath}${Modal.Data[subIdModal].options.route}`;
|
|
100
|
+
triggerCloseModalRouteChangeEvents(newPath);
|
|
101
|
+
setPath(newPath);
|
|
102
|
+
Modal.setTopModalCallback(subIdModal);
|
|
103
|
+
return setDocTitle({ ...RouterInstance, route: Modal.Data[subIdModal].options.route });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
newPath = `${newPath}${homeCid ? `?cid=${homeCid}` : ''}`;
|
|
107
|
+
triggerCloseModalRouteChangeEvents(newPath);
|
|
108
|
+
setPath(newPath);
|
|
109
|
+
return setDocTitle({ ...RouterInstance, route: '' });
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handleModalViewRoute = (options = {}) => {
|
|
114
|
+
const { route, RouterInstance } = options;
|
|
115
|
+
if (!route) return;
|
|
116
|
+
|
|
117
|
+
let path = window.location.pathname;
|
|
118
|
+
if (path !== '/' && path[path.length - 1] === '/') path = path.slice(0, -1);
|
|
119
|
+
const proxyPath = getProxyPath();
|
|
120
|
+
const newPath = `${proxyPath}${route}`;
|
|
121
|
+
|
|
122
|
+
if (path !== newPath) {
|
|
123
|
+
setPath(newPath);
|
|
124
|
+
setDocTitle({ ...RouterInstance, route });
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
Router,
|
|
130
|
+
setDocTitle,
|
|
131
|
+
LoadRouter,
|
|
132
|
+
RouterEvents,
|
|
133
|
+
setQueryPath,
|
|
134
|
+
listenQueryPathInstance,
|
|
135
|
+
closeModalRouteChangeEvent,
|
|
136
|
+
handleModalViewRoute,
|
|
137
|
+
closeModalRouteChangeEvents,
|
|
138
|
+
renderTitle,
|
|
139
|
+
};
|
|
@@ -60,10 +60,10 @@ const Translate = {
|
|
|
60
60
|
this.Parse(language);
|
|
61
61
|
if (s(`.action-btn-lang-render`)) htmls(`.action-btn-lang-render`, s('html').lang);
|
|
62
62
|
},
|
|
63
|
-
RenderSetting: async function () {
|
|
63
|
+
RenderSetting: async function (id) {
|
|
64
64
|
return html` <div class="in section-mp">
|
|
65
65
|
${await DropDown.Render({
|
|
66
|
-
id: 'settings-lang',
|
|
66
|
+
id: id ?? 'settings-lang',
|
|
67
67
|
value: s('html').lang ? s('html').lang : 'en',
|
|
68
68
|
label: html`${Translate.Render('lang')}`,
|
|
69
69
|
data: ['en', 'es'].map((language) => {
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import swaggerAutoGen from 'swagger-autogen';
|
|
5
|
+
import { shellExec } from './process.js';
|
|
6
|
+
import { loggerFactory } from './logger.js';
|
|
7
|
+
import { JSONweb } from './client-formatted.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Builds API documentation using Swagger
|
|
11
|
+
* @param {Object} options - Documentation build options
|
|
12
|
+
* @param {string} options.host - The hostname for the API
|
|
13
|
+
* @param {string} options.path - The base path for the API
|
|
14
|
+
* @param {number} options.port - The port number for the API
|
|
15
|
+
* @param {Object} options.metadata - Metadata for the API documentation
|
|
16
|
+
* @param {Array<string>} options.apis - List of API modules to document
|
|
17
|
+
* @param {string} options.publicClientId - Client ID for the public documentation
|
|
18
|
+
* @param {string} options.rootClientPath - Root path for client files
|
|
19
|
+
* @param {Object} options.packageData - Package.json data
|
|
20
|
+
*/
|
|
21
|
+
const buildApiDocs = async ({
|
|
22
|
+
host,
|
|
23
|
+
path,
|
|
24
|
+
port,
|
|
25
|
+
metadata = {},
|
|
26
|
+
apis = [],
|
|
27
|
+
publicClientId,
|
|
28
|
+
rootClientPath,
|
|
29
|
+
packageData,
|
|
30
|
+
}) => {
|
|
31
|
+
const logger = loggerFactory(import.meta);
|
|
32
|
+
const basePath = path === '/' ? `${process.env.BASE_API}` : `/${process.env.BASE_API}`;
|
|
33
|
+
|
|
34
|
+
const doc = {
|
|
35
|
+
info: {
|
|
36
|
+
version: packageData.version,
|
|
37
|
+
title: metadata?.title ? `${metadata.title}` : 'REST API',
|
|
38
|
+
description: metadata?.description ? metadata.description : '',
|
|
39
|
+
},
|
|
40
|
+
servers: [
|
|
41
|
+
{
|
|
42
|
+
url:
|
|
43
|
+
process.env.NODE_ENV === 'development'
|
|
44
|
+
? `http://localhost:${port}${path}${basePath}`
|
|
45
|
+
: `https://${host}${path}${basePath}`,
|
|
46
|
+
description: `${process.env.NODE_ENV} server`,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
tags: [
|
|
50
|
+
{
|
|
51
|
+
name: 'user',
|
|
52
|
+
description: 'User API operations',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
components: {
|
|
56
|
+
schemas: {
|
|
57
|
+
userRequest: {
|
|
58
|
+
username: 'user123',
|
|
59
|
+
password: 'Password123',
|
|
60
|
+
email: 'user@example.com',
|
|
61
|
+
},
|
|
62
|
+
userResponse: {
|
|
63
|
+
status: 'success',
|
|
64
|
+
data: {
|
|
65
|
+
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Il9pZCI6IjY2YzM3N2Y1N2Y5OWU1OTY5YjgxZG...',
|
|
66
|
+
user: {
|
|
67
|
+
_id: '66c377f57f99e5969b81de89',
|
|
68
|
+
email: 'user@example.com',
|
|
69
|
+
emailConfirmed: false,
|
|
70
|
+
username: 'user123',
|
|
71
|
+
role: 'user',
|
|
72
|
+
profileImageId: '66c377f57f99e5969b81de87',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
userUpdateResponse: {
|
|
77
|
+
status: 'success',
|
|
78
|
+
data: {
|
|
79
|
+
_id: '66c377f57f99e5969b81de89',
|
|
80
|
+
email: 'user@example.com',
|
|
81
|
+
emailConfirmed: false,
|
|
82
|
+
username: 'user123222',
|
|
83
|
+
role: 'user',
|
|
84
|
+
profileImageId: '66c377f57f99e5969b81de87',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
userGetResponse: {
|
|
88
|
+
status: 'success',
|
|
89
|
+
data: {
|
|
90
|
+
_id: '66c377f57f99e5969b81de89',
|
|
91
|
+
email: 'user@example.com',
|
|
92
|
+
emailConfirmed: false,
|
|
93
|
+
username: 'user123222',
|
|
94
|
+
role: 'user',
|
|
95
|
+
profileImageId: '66c377f57f99e5969b81de87',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
userLogInRequest: {
|
|
99
|
+
email: 'user@example.com',
|
|
100
|
+
password: 'Password123',
|
|
101
|
+
},
|
|
102
|
+
userBadRequestResponse: {
|
|
103
|
+
status: 'error',
|
|
104
|
+
message: 'Bad request. Please check your inputs, and try again',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
securitySchemes: {
|
|
108
|
+
bearerAuth: {
|
|
109
|
+
type: 'http',
|
|
110
|
+
scheme: 'bearer',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
logger.warn('build swagger api docs', doc.info);
|
|
117
|
+
|
|
118
|
+
const outputFile = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
|
|
119
|
+
const routes = [];
|
|
120
|
+
for (const api of apis) {
|
|
121
|
+
if (['user'].includes(api)) routes.push(`./src/api/${api}/${api}.router.js`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await swaggerAutoGen({ openapi: '3.0.0' })(outputFile, routes, doc);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Builds JSDoc documentation
|
|
129
|
+
* @param {Object} options - JSDoc build options
|
|
130
|
+
* @param {string} options.host - The hostname for the documentation
|
|
131
|
+
* @param {string} options.path - The base path for the documentation
|
|
132
|
+
* @param {Object} options.metadata - Metadata for the documentation
|
|
133
|
+
*/
|
|
134
|
+
const buildJsDocs = async ({ host, path, metadata = {} }) => {
|
|
135
|
+
const logger = loggerFactory(import.meta);
|
|
136
|
+
const jsDocsConfig = JSON.parse(fs.readFileSync(`./jsdoc.json`, 'utf8'));
|
|
137
|
+
|
|
138
|
+
jsDocsConfig.opts.destination = `./public/${host}${path === '/' ? path : `${path}/`}docs/`;
|
|
139
|
+
jsDocsConfig.opts.theme_opts.title = metadata?.title ? metadata.title : undefined;
|
|
140
|
+
jsDocsConfig.opts.theme_opts.favicon = `./public/${host}${path === '/' ? path : `${path}/favicon.ico`}`;
|
|
141
|
+
|
|
142
|
+
fs.writeFileSync(`./jsdoc.json`, JSON.stringify(jsDocsConfig, null, 4), 'utf8');
|
|
143
|
+
logger.warn('build jsdoc view', jsDocsConfig.opts.destination);
|
|
144
|
+
|
|
145
|
+
shellExec(`npm run docs`, { silent: true });
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Builds test coverage documentation
|
|
150
|
+
* @param {Object} options - Coverage build options
|
|
151
|
+
* @param {string} options.host - The hostname for the coverage
|
|
152
|
+
* @param {string} options.path - The base path for the coverage
|
|
153
|
+
*/
|
|
154
|
+
const buildCoverage = async ({ host, path }) => {
|
|
155
|
+
const logger = loggerFactory(import.meta);
|
|
156
|
+
const jsDocsConfig = JSON.parse(fs.readFileSync(`./jsdoc.json`, 'utf8'));
|
|
157
|
+
|
|
158
|
+
if (!fs.existsSync(`./coverage`)) {
|
|
159
|
+
shellExec(`npm test`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const coverageBuildPath = `${jsDocsConfig.opts.destination}/coverage`;
|
|
163
|
+
fs.mkdirSync(coverageBuildPath, { recursive: true });
|
|
164
|
+
fs.copySync(`./coverage`, coverageBuildPath);
|
|
165
|
+
|
|
166
|
+
logger.warn('build coverage', coverageBuildPath);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Main function to build all documentation
|
|
171
|
+
* @param {Object} options - Documentation build options
|
|
172
|
+
* @param {string} options.host - The hostname
|
|
173
|
+
* @param {string} options.path - The base path
|
|
174
|
+
* @param {number} options.port - The port number
|
|
175
|
+
* @param {Object} options.metadata - Metadata for the documentation
|
|
176
|
+
* @param {Array<string>} options.apis - List of API modules to document
|
|
177
|
+
* @param {string} options.publicClientId - Client ID for the public documentation
|
|
178
|
+
* @param {string} options.rootClientPath - Root path for client files
|
|
179
|
+
* @param {Object} options.packageData - Package.json data
|
|
180
|
+
*/
|
|
181
|
+
const buildDocs = async ({
|
|
182
|
+
host,
|
|
183
|
+
path,
|
|
184
|
+
port,
|
|
185
|
+
metadata = {},
|
|
186
|
+
apis = [],
|
|
187
|
+
publicClientId,
|
|
188
|
+
rootClientPath,
|
|
189
|
+
packageData,
|
|
190
|
+
}) => {
|
|
191
|
+
await buildJsDocs({ host, path, metadata });
|
|
192
|
+
await buildCoverage({ host, path });
|
|
193
|
+
await buildApiDocs({
|
|
194
|
+
host,
|
|
195
|
+
path,
|
|
196
|
+
port,
|
|
197
|
+
metadata,
|
|
198
|
+
apis,
|
|
199
|
+
publicClientId,
|
|
200
|
+
rootClientPath,
|
|
201
|
+
packageData,
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export { buildDocs };
|
|
@@ -17,11 +17,11 @@ import dotenv from 'dotenv';
|
|
|
17
17
|
import AdmZip from 'adm-zip';
|
|
18
18
|
import * as dir from 'path';
|
|
19
19
|
import { shellExec } from './process.js';
|
|
20
|
-
import swaggerAutoGen from 'swagger-autogen';
|
|
21
20
|
import { SitemapStream, streamToPromise } from 'sitemap';
|
|
22
21
|
import { Readable } from 'stream';
|
|
23
22
|
import { buildIcons, buildTextImg, getBufferPngText } from './client-icons.js';
|
|
24
23
|
import Underpost from '../index.js';
|
|
24
|
+
import { buildDocs } from './client-build-docs.js';
|
|
25
25
|
|
|
26
26
|
dotenv.config();
|
|
27
27
|
|
|
@@ -557,145 +557,16 @@ Sitemap: https://${host}${path === '/' ? '' : path}/sitemap.xml`,
|
|
|
557
557
|
}
|
|
558
558
|
|
|
559
559
|
if (!enableLiveRebuild && !process.argv.includes('l') && !process.argv.includes('deploy') && docsBuild) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
shellExec(`npm run docs`, { silent: true });
|
|
571
|
-
|
|
572
|
-
// coverage
|
|
573
|
-
if (!fs.existsSync(`./coverage`)) {
|
|
574
|
-
shellExec(`npm test`);
|
|
575
|
-
}
|
|
576
|
-
const coverageBuildPath = `${jsDocsConfig.opts.destination}/coverage`;
|
|
577
|
-
fs.mkdirSync(coverageBuildPath, { recursive: true });
|
|
578
|
-
fs.copySync(`./coverage`, coverageBuildPath);
|
|
579
|
-
|
|
580
|
-
// uml
|
|
581
|
-
// shellExec(`node bin/deploy uml ${host} ${path}`);
|
|
582
|
-
|
|
583
|
-
// https://swagger-autogen.github.io/docs/
|
|
584
|
-
|
|
585
|
-
const basePath = path === '/' ? `${process.env.BASE_API}` : `/${process.env.BASE_API}`;
|
|
586
|
-
|
|
587
|
-
const doc = {
|
|
588
|
-
info: {
|
|
589
|
-
version: packageData.version, // by default: '1.0.0'
|
|
590
|
-
title: metadata?.title ? `${metadata.title}` : 'REST API', // by default: 'REST API'
|
|
591
|
-
description: metadata?.description ? metadata.description : '', // by default: ''
|
|
592
|
-
},
|
|
593
|
-
servers: [
|
|
594
|
-
{
|
|
595
|
-
url:
|
|
596
|
-
process.env.NODE_ENV === 'development'
|
|
597
|
-
? `http://localhost:${port}${path}${basePath}`
|
|
598
|
-
: `https://${host}${path}${basePath}`, // by default: 'http://localhost:3000'
|
|
599
|
-
description: `${process.env.NODE_ENV} server`, // by default: ''
|
|
600
|
-
},
|
|
601
|
-
],
|
|
602
|
-
tags: [
|
|
603
|
-
// by default: empty Array
|
|
604
|
-
{
|
|
605
|
-
name: 'user', // Tag name
|
|
606
|
-
description: 'User API operations', // Tag description
|
|
607
|
-
},
|
|
608
|
-
],
|
|
609
|
-
components: {
|
|
610
|
-
schemas: {
|
|
611
|
-
userRequest: {
|
|
612
|
-
username: 'user123',
|
|
613
|
-
password: 'Password123',
|
|
614
|
-
email: 'user@example.com',
|
|
615
|
-
},
|
|
616
|
-
userResponse: {
|
|
617
|
-
status: 'success',
|
|
618
|
-
data: {
|
|
619
|
-
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Il9pZCI6IjY2YzM3N2Y1N2Y5OWU1OTY5YjgxZG...',
|
|
620
|
-
user: {
|
|
621
|
-
_id: '66c377f57f99e5969b81de89',
|
|
622
|
-
email: 'user@example.com',
|
|
623
|
-
emailConfirmed: false,
|
|
624
|
-
username: 'user123',
|
|
625
|
-
role: 'user',
|
|
626
|
-
profileImageId: '66c377f57f99e5969b81de87',
|
|
627
|
-
},
|
|
628
|
-
},
|
|
629
|
-
},
|
|
630
|
-
userUpdateResponse: {
|
|
631
|
-
status: 'success',
|
|
632
|
-
data: {
|
|
633
|
-
_id: '66c377f57f99e5969b81de89',
|
|
634
|
-
email: 'user@example.com',
|
|
635
|
-
emailConfirmed: false,
|
|
636
|
-
username: 'user123222',
|
|
637
|
-
role: 'user',
|
|
638
|
-
profileImageId: '66c377f57f99e5969b81de87',
|
|
639
|
-
},
|
|
640
|
-
},
|
|
641
|
-
userGetResponse: {
|
|
642
|
-
status: 'success',
|
|
643
|
-
data: {
|
|
644
|
-
_id: '66c377f57f99e5969b81de89',
|
|
645
|
-
email: 'user@example.com',
|
|
646
|
-
emailConfirmed: false,
|
|
647
|
-
username: 'user123222',
|
|
648
|
-
role: 'user',
|
|
649
|
-
profileImageId: '66c377f57f99e5969b81de87',
|
|
650
|
-
},
|
|
651
|
-
},
|
|
652
|
-
userLogInRequest: {
|
|
653
|
-
email: 'user@example.com',
|
|
654
|
-
password: 'Password123',
|
|
655
|
-
},
|
|
656
|
-
userBadRequestResponse: {
|
|
657
|
-
status: 'error',
|
|
658
|
-
message: 'Bad request. Please check your inputs, and try again',
|
|
659
|
-
},
|
|
660
|
-
},
|
|
661
|
-
securitySchemes: {
|
|
662
|
-
bearerAuth: {
|
|
663
|
-
type: 'http',
|
|
664
|
-
scheme: 'bearer',
|
|
665
|
-
},
|
|
666
|
-
},
|
|
667
|
-
},
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
// plantuml
|
|
671
|
-
logger.info('copy plantuml', `${rootClientPath}/docs/plantuml`);
|
|
672
|
-
fs.copySync(`./src/client/public/default/plantuml`, `${rootClientPath}/docs/plantuml`);
|
|
673
|
-
|
|
674
|
-
logger.warn('build swagger api docs', doc.info);
|
|
675
|
-
|
|
676
|
-
const outputFile = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
|
|
677
|
-
const routes = [];
|
|
678
|
-
for (const api of apis) {
|
|
679
|
-
if (['user'].includes(api)) routes.push(`./src/api/${api}/${api}.router.js`);
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/* NOTE: If you are using the express Router, you must pass in the 'routes' only the
|
|
683
|
-
root file where the route starts, such as index.js, app.js, routes.js, etc ... */
|
|
684
|
-
|
|
685
|
-
await swaggerAutoGen({ openapi: '3.0.0' })(outputFile, routes, doc);
|
|
686
|
-
|
|
687
|
-
const htmlFiles = await fs.readdir(`./public/${host}/docs/engine/${Underpost.version.replace('v', '')}`);
|
|
688
|
-
for (const htmlFile of htmlFiles) {
|
|
689
|
-
if (htmlFile.match('.html')) {
|
|
690
|
-
fs.writeFileSync(
|
|
691
|
-
`./public/${host}/docs/engine/${Underpost.version.replace('v', '')}/${htmlFile}`,
|
|
692
|
-
fs
|
|
693
|
-
.readFileSync(`./public/${host}/docs/engine/${Underpost.version.replace('v', '')}/${htmlFile}`, 'utf8')
|
|
694
|
-
.replaceAll('Tutorials', 'References'),
|
|
695
|
-
'utf8',
|
|
696
|
-
);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
560
|
+
await buildDocs({
|
|
561
|
+
host,
|
|
562
|
+
path,
|
|
563
|
+
port,
|
|
564
|
+
metadata,
|
|
565
|
+
apis,
|
|
566
|
+
publicClientId,
|
|
567
|
+
rootClientPath,
|
|
568
|
+
packageData,
|
|
569
|
+
});
|
|
699
570
|
}
|
|
700
571
|
|
|
701
572
|
if (client) {
|