underpost 2.8.82 → 2.8.85

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 (115) hide show
  1. package/.env.development +1 -0
  2. package/.env.production +1 -0
  3. package/.env.test +1 -0
  4. package/.github/workflows/{ghpkg.yml → ghpkg.ci.yml} +5 -5
  5. package/.github/workflows/{npmpkg.yml → npmpkg.ci.yml} +5 -5
  6. package/.github/workflows/{publish.yml → publish.ci.yml} +1 -1
  7. package/.github/workflows/{pwa-microservices-template.page.yml → pwa-microservices-template-page.cd.yml} +1 -1
  8. package/.github/workflows/{pwa-microservices-template.test.yml → pwa-microservices-template-test.ci.yml} +1 -1
  9. package/.vscode/extensions.json +1 -1
  10. package/.vscode/settings.json +0 -44
  11. package/README.md +62 -2
  12. package/bin/build.js +15 -5
  13. package/bin/deploy.js +42 -92
  14. package/bin/file.js +33 -9
  15. package/bin/vs.js +12 -4
  16. package/cli.md +90 -42
  17. package/conf.js +1 -1
  18. package/docker-compose.yml +1 -1
  19. package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
  20. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +65 -0
  21. package/manifests/maas/device-scan.sh +3 -3
  22. package/manifests/maas/gpu-diag.sh +19 -0
  23. package/manifests/maas/maas-setup.sh +10 -10
  24. package/manifests/maas/snap-clean.sh +26 -0
  25. package/package.json +4 -6
  26. package/src/api/user/user.router.js +24 -1
  27. package/src/api/user/user.service.js +1 -4
  28. package/src/cli/baremetal.js +105 -73
  29. package/src/cli/cloud-init.js +21 -12
  30. package/src/cli/cluster.js +227 -133
  31. package/src/cli/deploy.js +34 -0
  32. package/src/cli/index.js +28 -1
  33. package/src/cli/monitor.js +8 -12
  34. package/src/cli/repository.js +7 -4
  35. package/src/cli/run.js +367 -0
  36. package/src/cli/ssh.js +32 -0
  37. package/src/cli/test.js +1 -1
  38. package/src/client/Default.index.js +7 -3
  39. package/src/client/components/core/Account.js +1 -1
  40. package/src/client/components/core/Chat.js +1 -1
  41. package/src/client/components/core/CommonJs.js +24 -22
  42. package/src/client/components/core/Content.js +1 -5
  43. package/src/client/components/core/Css.js +258 -18
  44. package/src/client/components/core/CssCore.js +8 -8
  45. package/src/client/components/core/Docs.js +14 -61
  46. package/src/client/components/core/DropDown.js +137 -82
  47. package/src/client/components/core/EventsUI.js +92 -5
  48. package/src/client/components/core/LoadingAnimation.js +8 -15
  49. package/src/client/components/core/Modal.js +597 -136
  50. package/src/client/components/core/NotificationManager.js +2 -2
  51. package/src/client/components/core/ObjectLayerEngine.js +638 -0
  52. package/src/client/components/core/Panel.js +158 -34
  53. package/src/client/components/core/PanelForm.js +12 -3
  54. package/src/client/components/core/Recover.js +1 -1
  55. package/src/client/components/core/Router.js +77 -17
  56. package/src/client/components/core/SocketIo.js +3 -3
  57. package/src/client/components/core/Translate.js +6 -2
  58. package/src/client/components/core/VanillaJs.js +0 -3
  59. package/src/client/components/core/Worker.js +3 -1
  60. package/src/client/components/default/CssDefault.js +17 -3
  61. package/src/client/components/default/MenuDefault.js +264 -45
  62. package/src/client/components/default/RoutesDefault.js +6 -12
  63. package/src/client/public/default/android-chrome-144x144.png +0 -0
  64. package/src/client/public/default/android-chrome-192x192.png +0 -0
  65. package/src/client/public/default/android-chrome-256x256.png +0 -0
  66. package/src/client/public/default/android-chrome-36x36.png +0 -0
  67. package/src/client/public/default/android-chrome-48x48.png +0 -0
  68. package/src/client/public/default/android-chrome-72x72.png +0 -0
  69. package/src/client/public/default/android-chrome-96x96.png +0 -0
  70. package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
  71. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  72. package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
  73. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  74. package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
  75. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  76. package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
  77. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  78. package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
  79. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  80. package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
  81. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  82. package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
  83. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  84. package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
  85. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  86. package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
  87. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  88. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  89. package/src/client/public/default/apple-touch-icon.png +0 -0
  90. package/src/client/public/default/assets/background/dark.jpg +0 -0
  91. package/src/client/public/default/assets/background/dark.svg +557 -0
  92. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  93. package/src/client/public/default/assets/logo/underpost.gif +0 -0
  94. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  95. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  96. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  97. package/src/client/public/default/favicon-16x16.png +0 -0
  98. package/src/client/public/default/favicon-32x32.png +0 -0
  99. package/src/client/public/default/favicon.ico +0 -0
  100. package/src/client/public/default/mstile-144x144.png +0 -0
  101. package/src/client/public/default/mstile-150x150.png +0 -0
  102. package/src/client/public/default/mstile-310x150.png +0 -0
  103. package/src/client/public/default/mstile-310x310.png +0 -0
  104. package/src/client/public/default/mstile-70x70.png +0 -0
  105. package/src/client/public/default/safari-pinned-tab.svg +24 -0
  106. package/src/client/ssr/body/DefaultSplashScreen.js +2 -2
  107. package/src/index.js +34 -17
  108. package/src/monitor.js +24 -0
  109. package/src/runtime/lampp/Dockerfile +30 -39
  110. package/src/runtime/lampp/Lampp.js +11 -2
  111. package/src/server/client-build-docs.js +205 -0
  112. package/src/server/client-build.js +16 -166
  113. package/src/server/conf.js +18 -8
  114. package/src/server/process.js +16 -19
  115. package/src/server/valkey.js +102 -41
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
3
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
4
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
5
+ width="269.000000pt" height="269.000000pt" viewBox="0 0 269.000000 269.000000"
6
+ preserveAspectRatio="xMidYMid meet">
7
+ <metadata>
8
+ Created by potrace 1.11, written by Peter Selinger 2001-2013
9
+ </metadata>
10
+ <g transform="translate(0.000000,269.000000) scale(0.100000,-0.100000)"
11
+ fill="#000000" stroke="none">
12
+ <path d="M980 2475 l0 -65 65 0 65 0 0 65 0 65 -65 0 -65 0 0 -65z"/>
13
+ <path d="M1700 2475 l0 -65 65 0 65 0 0 65 0 65 -65 0 -65 0 0 -65z"/>
14
+ <path d="M1110 2325 l0 -65 -85 0 -85 0 0 -140 0 -140 -60 0 -60 0 0 -160 0
15
+ -160 75 0 75 0 0 -100 0 -100 95 0 95 0 0 -40 0 -40 -240 0 -240 0 0 -445 0
16
+ -445 -65 0 -65 0 0 -135 0 -135 65 0 65 0 0 -55 0 -55 65 0 65 0 0 475 0 475
17
+ 85 0 85 0 0 -425 0 -425 425 0 425 0 0 425 0 425 85 0 85 0 0 -475 0 -475 65
18
+ 0 65 0 0 55 0 55 60 0 60 0 0 135 0 135 -60 0 -60 0 0 445 0 445 -240 0 -240
19
+ 0 0 35 0 35 95 0 95 0 0 105 0 105 75 0 75 0 0 160 0 160 -60 0 -60 0 0 140 0
20
+ 140 -85 0 -85 0 0 65 0 65 -75 0 -75 0 0 -65 0 -65 -145 0 -145 0 0 65 0 65
21
+ -75 0 -75 0 0 -65z m210 -505 l0 -110 -110 0 -110 0 0 110 0 110 110 0 110 0
22
+ 0 -110z m390 0 l0 -70 -70 0 -70 0 0 70 0 70 70 0 70 0 0 -70z"/>
23
+ </g>
24
+ </svg>
@@ -1,12 +1,12 @@
1
1
  SrrComponent = ({ backgroundImage, metadata }) => html`
2
2
  ${backgroundImage
3
- ? html`<style>
3
+ ? html`<style class="style-ssr-background-image">
4
4
  .ssr-background-image {
5
5
  background-image: url('${backgroundImage}');
6
6
  }
7
7
  </style>`
8
8
  : metadata?.themeColor
9
- ? html`<style>
9
+ ? html`<style class="style-ssr-background-image">
10
10
  .ssr-background-image {
11
11
  background: ${metadata.themeColor};
12
12
  }
package/src/index.js CHANGED
@@ -16,8 +16,10 @@ import UnderpostImage from './cli/image.js';
16
16
  import UnderpostLxd from './cli/lxd.js';
17
17
  import UnderpostMonitor from './cli/monitor.js';
18
18
  import UnderpostRepository from './cli/repository.js';
19
+ import UnderpostRun from './cli/run.js';
19
20
  import UnderpostScript from './cli/script.js';
20
21
  import UnderpostSecret from './cli/secrets.js';
22
+ import UnderpostSSH from './cli/ssh.js';
21
23
  import UnderpostTest from './cli/test.js';
22
24
  import UnderpostStartUp from './server/start.js';
23
25
 
@@ -33,102 +35,109 @@ class Underpost {
33
35
  * @type {String}
34
36
  * @memberof Underpost
35
37
  */
36
- static version = 'v2.8.82';
38
+ static version = 'v2.8.85';
37
39
  /**
38
40
  * Repository cli API
39
41
  * @static
40
- * @type {UnderpostRepository}
42
+ * @type {UnderpostRepository.API}
41
43
  * @memberof Underpost
42
44
  */
43
45
  static repo = UnderpostRepository.API;
44
46
  /**
45
47
  * Root Env cli API
46
48
  * @static
47
- * @type {UnderpostRootEnv}
49
+ * @type {UnderpostRootEnv.API}
48
50
  * @memberof Underpost
49
51
  */
50
52
  static env = UnderpostRootEnv.API;
51
53
  /**
52
54
  * Test cli API
53
55
  * @static
54
- * @type {UnderpostTest}
56
+ * @type {UnderpostTest.API}
55
57
  * @memberof Underpost
56
58
  */
57
59
  static test = UnderpostTest.API;
58
60
  /**
59
61
  * Underpost Start Up cli API
60
62
  * @static
61
- * @type {UnderpostStartUp}
63
+ * @type {UnderpostStartUp.API}
62
64
  * @memberof Underpost
63
65
  */
64
66
  static start = UnderpostStartUp.API;
65
67
  /**
66
68
  * Cluster cli API
67
69
  * @static
68
- * @type {UnderpostCluster}
70
+ * @type {UnderpostCluster.API}
69
71
  * @memberof Underpost
70
72
  */
71
73
  static cluster = UnderpostCluster.API;
72
74
  /**
73
75
  * Image cli API
74
76
  * @static
75
- * @type {UnderpostImage}
77
+ * @type {UnderpostImage.API}
76
78
  * @memberof Underpost
77
79
  */
78
80
  static image = UnderpostImage.API;
79
81
  /**
80
82
  * Secrets cli API
81
83
  * @static
82
- * @type {UnderpostSecret}
84
+ * @type {UnderpostSecret.API}
83
85
  * @memberof Underpost
84
86
  */
85
87
  static secret = UnderpostSecret.API;
86
88
  /**
87
89
  * Scripts cli API
88
90
  * @static
89
- * @type {UnderpostScript}
91
+ * @type {UnderpostScript.API}
90
92
  * @memberof Underpost
91
93
  */
92
94
  static script = UnderpostScript.API;
93
95
  /**
94
96
  * Database cli API
95
97
  * @static
96
- * @type {UnderpostDB}
98
+ * @type {UnderpostDB.API}
97
99
  * @memberof Underpost
98
100
  */
99
101
  static db = UnderpostDB.API;
100
102
  /**
101
103
  * Deployment cli API
102
104
  * @static
103
- * @type {UnderpostDeploy}
105
+ * @type {UnderpostDeploy.API}
104
106
  * @memberof Underpost
105
107
  */
106
108
  static deploy = UnderpostDeploy.API;
107
109
  /**
108
110
  * Cron cli API
109
111
  * @static
110
- * @type {UnderpostCron}
112
+ * @type {UnderpostCron.API}
111
113
  * @memberof Underpost
112
114
  */
113
115
  static cron = UnderpostCron.API;
114
116
  /**
115
117
  * File Storage cli API
116
118
  * @static
117
- * @type {UnderpostFileStorage}
119
+ * @type {UnderpostFileStorage.API}
118
120
  * @memberof Underpost
119
121
  */
120
122
  static fs = UnderpostFileStorage.API;
121
123
  /**
122
124
  * Monitor cli API
123
125
  * @static
124
- * @type {UnderpostMonitor}
126
+ * @type {UnderpostMonitor.API}
125
127
  * @memberof Underpost
126
128
  */
127
129
  static monitor = UnderpostMonitor.API;
130
+ /**
131
+ * SSH cli API
132
+ * @static
133
+ * @type {UnderpostSSH.API}
134
+ * @memberof Underpost
135
+ */
136
+ static ssh = UnderpostSSH.API;
128
137
  /**
129
138
  * LXD cli API
130
139
  * @static
131
- * @type {UnderpostLxd}
140
+ * @type {UnderpostLxd.API}
132
141
  * @memberof Underpost
133
142
  */
134
143
  static lxd = UnderpostLxd.API;
@@ -136,15 +145,23 @@ class Underpost {
136
145
  /**
137
146
  * Cloud Init cli API
138
147
  * @static
139
- * @type {UnderpostCloudInit}
148
+ * @type {UnderpostCloudInit.API}
140
149
  * @memberof Underpost
141
150
  */
142
151
  static cloudInit = UnderpostCloudInit.API;
143
152
 
153
+ /**
154
+ * Run cli API
155
+ * @static
156
+ * @type {UnderpostRun.API}
157
+ * @memberof Underpost
158
+ */
159
+ static run = UnderpostRun.API;
160
+
144
161
  /**
145
162
  * Baremetal cli API
146
163
  * @static
147
- * @type {UnderpostBaremetal}
164
+ * @type {UnderpostBaremetal.API}
148
165
  * @memberof Underpost
149
166
  */
150
167
  static baremetal = UnderpostBaremetal.API;
package/src/monitor.js ADDED
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ // https://nodejs.org/api
4
+ // https://expressjs.com/en/4x/api.html
5
+
6
+ import dotenv from 'dotenv';
7
+ import { loggerFactory } from './server/logger.js';
8
+ import { ProcessController } from './server/process.js';
9
+ import { getUnderpostRootPath } from './server/conf.js';
10
+ import fs from 'fs-extra';
11
+ import UnderpostMonitor from './cli/monitor.js';
12
+
13
+ const underpostRootPath = getUnderpostRootPath();
14
+ fs.existsSync(`${underpostRootPath}/.env`)
15
+ ? dotenv.config({ path: `${underpostRootPath}/.env`, override: true })
16
+ : dotenv.config();
17
+
18
+ const logger = loggerFactory(import.meta);
19
+
20
+ await logger.setUpInfo();
21
+
22
+ UnderpostMonitor.API.callback(process.argv[2], process.argv[3], { type: 'blue-green', sync: true });
23
+
24
+ ProcessController.init(logger);
@@ -1,43 +1,35 @@
1
1
  FROM rockylinux:9
2
2
 
3
- RUN dnf install -y --allowerasing bzip2
4
-
5
- RUN dnf update -y
6
- RUN dnf install -y epel-release
7
- RUN dnf install -y --allowerasing sudo
8
- RUN dnf install -y --allowerasing curl
9
- RUN dnf install -y --allowerasing net-tools
10
- RUN dnf install -y --allowerasing openssh-server
11
- RUN dnf install -y --allowerasing nano
12
- RUN dnf install -y --allowerasing vim-enhanced
13
- RUN dnf install -y --allowerasing less
14
- RUN dnf install -y --allowerasing openssl-devel
15
- RUN dnf install -y --allowerasing wget
16
- RUN dnf install -y --allowerasing git
17
- RUN dnf install -y --allowerasing gnupg2
18
- RUN dnf clean all
19
-
20
- # Install LAMPP (XAMPP)
21
- # Download the XAMPP installer for Linux
22
- RUN curl -Lo xampp-linux-installer.run https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.33/xampp-linux-x64-7.4.33-0-installer.run?from_af=true
23
- RUN chmod +x xampp-linux-installer.run
24
- # Run the XAMPP installer in silent mode
25
- RUN bash -c './xampp-linux-installer.run --mode unattended'
26
- # Create a symbolic link for easy access to lampp command
27
- RUN ln -sf /opt/lampp/lampp /usr/bin/lampp
28
-
29
- # Configure XAMPP
30
- # Enable XAMPP web interface (remove security checks)
31
- RUN sed -i.bak 's/Require local/Require all granted/g' /opt/lampp/etc/extra/httpd-xampp.conf
32
- # Enable error display in php
33
- RUN sed -i.bak 's/display_errors=Off/display_errors=On/g' /opt/lampp/etc/php.ini
34
- # Enable includes of several configuration files for Apache
35
- RUN mkdir -p /opt/lampp/apache2/conf.d
36
- RUN echo "IncludeOptional /opt/lampp/apache2/conf.d/*.conf" >>/opt/lampp/etc/httpd.conf
37
- # Create a /www folder and a symbolic link to it in /opt/lampp/htdocs
38
- # This is convenient because it doesn't interfere with xampp, phpmyadmin or other tools
39
- RUN mkdir /www
40
- RUN ln -s /www /opt/lampp/htdocs
3
+ # --- Update and install required packages
4
+ RUN dnf -y update && \
5
+ dnf -y install epel-release && \
6
+ dnf -y install --allowerasing \
7
+ bzip2 \
8
+ sudo \
9
+ curl \
10
+ net-tools \
11
+ openssh-server \
12
+ nano \
13
+ vim-enhanced \
14
+ less \
15
+ openssl-devel \
16
+ wget \
17
+ git \
18
+ gnupg2 \
19
+ libnsl \
20
+ perl && \
21
+ dnf clean all
22
+
23
+ # --- Download and install XAMPP
24
+ RUN curl -L -o /tmp/xampp-linux-installer.run "https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.33/xampp-linux-x64-7.4.33-0-installer.run" && \
25
+ chmod +x /tmp/xampp-linux-installer.run && \
26
+ bash -c "/tmp/xampp-linux-installer.run --mode unattended" && \
27
+ ln -sf /opt/lampp/lampp /usr/bin/lampp
28
+
29
+ # --- Create /xampp/htdocs (static root) and set permissions
30
+ RUN mkdir -p /opt/lampp/htdocs && \
31
+ chown -R root:root /opt/lampp/htdocs && \
32
+ chmod -R a+rX /opt/lampp/htdocs
41
33
 
42
34
  # Install Node.js
43
35
  RUN curl -fsSL https://rpm.nodesource.com/setup_23.x | bash -
@@ -51,7 +43,6 @@ RUN npm --version
51
43
  # Set working directory
52
44
  WORKDIR /home/dd
53
45
 
54
- # Expose necessary ports
55
46
  EXPOSE 22
56
47
  EXPOSE 80
57
48
  EXPOSE 443
@@ -10,7 +10,16 @@ const Lampp = {
10
10
  initService: async function (options = { daemon: false }) {
11
11
  let cmd;
12
12
  // linux
13
- fs.writeFileSync(`/opt/lampp/apache2/conf/httpd.conf`, this.router || '', 'utf8');
13
+ // /opt/lampp/apache2/conf/httpd.conf
14
+ fs.writeFileSync(`/opt/lampp/etc/extra/httpd-vhosts.conf`, this.router || '', 'utf8');
15
+ fs.writeFileSync(
16
+ `/opt/lampp/etc/httpd.conf`,
17
+ fs
18
+ .readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8')
19
+ .replace(`#Include etc/extra/httpd-vhosts.conf`, `Include etc/extra/httpd-vhosts.conf`),
20
+ 'utf8',
21
+ );
22
+
14
23
  cmd = `sudo /opt/lampp/lampp stop`;
15
24
  if (!fs.readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8').match(`# Listen 80`))
16
25
  fs.writeFileSync(
@@ -42,7 +51,7 @@ const Lampp = {
42
51
  if (this.router) fs.writeFileSync(`./tmp/lampp-router.conf`, this.router, 'utf-8');
43
52
  shellExec(cmd);
44
53
  },
45
- enabled: () => fs.existsSync(`/opt/lampp/apache2/conf/httpd.conf`),
54
+ enabled: () => fs.existsSync(`/opt/lampp/etc/httpd.conf`),
46
55
  appendRouter: function (render) {
47
56
  if (!this.router) {
48
57
  if (fs.existsSync(`./tmp/lampp-router.conf`))
@@ -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 };