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.
Files changed (35) hide show
  1. package/.github/workflows/{ghpkg.yml → ghpkg.ci.yml} +1 -1
  2. package/.github/workflows/{npmpkg.yml → npmpkg.ci.yml} +1 -1
  3. package/.github/workflows/{publish.yml → publish.ci.yml} +1 -1
  4. package/.github/workflows/{pwa-microservices-template.page.yml → pwa-microservices-template-page.cd.yml} +1 -1
  5. package/.github/workflows/{pwa-microservices-template.test.yml → pwa-microservices-template-test.ci.yml} +1 -1
  6. package/.vscode/settings.json +0 -1
  7. package/README.md +18 -2
  8. package/bin/build.js +8 -5
  9. package/bin/deploy.js +10 -69
  10. package/bin/file.js +15 -11
  11. package/cli.md +47 -43
  12. package/docker-compose.yml +1 -1
  13. package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
  14. package/manifests/maas/gpu-diag.sh +1 -1
  15. package/package.json +3 -5
  16. package/src/api/user/user.router.js +24 -1
  17. package/src/cli/cluster.js +19 -10
  18. package/src/cli/index.js +1 -0
  19. package/src/cli/run.js +21 -0
  20. package/src/client/components/core/Css.js +52 -2
  21. package/src/client/components/core/CssCore.js +0 -4
  22. package/src/client/components/core/Docs.js +10 -57
  23. package/src/client/components/core/DropDown.js +128 -82
  24. package/src/client/components/core/EventsUI.js +92 -5
  25. package/src/client/components/core/Modal.js +451 -120
  26. package/src/client/components/core/NotificationManager.js +2 -2
  27. package/src/client/components/core/Panel.js +2 -2
  28. package/src/client/components/core/PanelForm.js +12 -2
  29. package/src/client/components/core/Recover.js +1 -1
  30. package/src/client/components/core/Router.js +63 -2
  31. package/src/client/components/core/Translate.js +2 -2
  32. package/src/index.js +1 -1
  33. package/src/server/client-build-docs.js +205 -0
  34. package/src/server/client-build.js +11 -140
  35. 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: 5 !important;
18
+ z-index: 11 !important;
19
19
  }
20
20
  .notification-board-title {
21
- padding: 5px !important;
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
- if (lastCid === cid) return;
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
- htmls('title', html`${title} | ${NameApp}`);
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
- export { Router, setDocTitle, LoadRouter, RouterEvents, setQueryPath, listenQueryPathInstance };
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
@@ -34,7 +34,7 @@ class Underpost {
34
34
  * @type {String}
35
35
  * @memberof Underpost
36
36
  */
37
- static version = 'v2.8.843';
37
+ static version = 'v2.8.845';
38
38
  /**
39
39
  * Repository cli API
40
40
  * @static
@@ -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
- // https://www.pullrequest.com/blog/leveraging-jsdoc-for-better-code-documentation-in-javascript/
561
- // https://jsdoc.app/about-configuring-jsdoc
562
- // https://jsdoc.app/ Block tags
563
-
564
- const jsDocsConfig = JSON.parse(fs.readFileSync(`./jsdoc.json`, 'utf8'));
565
- jsDocsConfig.opts.destination = `./public/${host}${path === '/' ? path : `${path}/`}docs/`;
566
- jsDocsConfig.opts.theme_opts.title = metadata && metadata.title ? metadata.title : undefined;
567
- jsDocsConfig.opts.theme_opts.favicon = `./public/${host}${path === '/' ? path : `${path}/favicon.ico`}`;
568
- fs.writeFileSync(`./jsdoc.json`, JSON.stringify(jsDocsConfig, null, 4), 'utf8');
569
- logger.warn('build jsdoc view', jsDocsConfig.opts.destination);
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) {