underpost 2.7.7 → 2.7.9
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 +115 -0
- package/.github/workflows/publish.yml +20 -3
- package/.github/workflows/pwa-microservices-template.page.yml +54 -0
- package/.github/workflows/pwa-microservices-template.test.yml +30 -0
- package/.vscode/settings.json +6 -0
- package/CHANGELOG.md +64 -16
- package/bin/cron.js +47 -0
- package/bin/db.js +9 -1
- package/bin/deploy.js +207 -11
- package/bin/file.js +17 -1
- package/bin/index.js +1 -1
- package/bin/util.js +22 -0
- package/conf.js +18 -4
- package/docker-compose.yml +1 -1
- package/package.json +3 -3
- package/src/api/core/core.router.js +9 -9
- package/src/api/core/core.service.js +6 -4
- package/src/api/default/default.service.js +4 -4
- package/src/api/file/file.service.js +3 -3
- package/src/api/user/user.service.js +7 -7
- package/src/client/components/core/Css.js +0 -222
- package/src/client/components/core/CssCore.js +30 -3
- package/src/client/components/core/Docs.js +110 -10
- package/src/client/components/core/Modal.js +224 -22
- package/src/client/components/core/Panel.js +1 -1
- package/src/client/components/core/PanelForm.js +2 -1
- package/src/client/components/core/Responsive.js +15 -0
- package/src/client/components/core/RichText.js +4 -2
- package/src/client/components/core/Translate.js +6 -2
- package/src/client/components/core/WebComponent.js +44 -0
- package/src/client/components/core/Worker.js +12 -4
- package/src/client/public/default/plantuml/client-conf.svg +1 -1
- package/src/client/public/default/plantuml/client-schema.svg +1 -1
- package/src/client/public/default/plantuml/cron-conf.svg +1 -1
- package/src/client/public/default/plantuml/cron-schema.svg +1 -1
- package/src/client/public/default/plantuml/server-conf.svg +1 -1
- package/src/client/public/default/plantuml/server-schema.svg +1 -1
- package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
- package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
- package/src/client/public/default/site.webmanifest +69 -0
- package/src/client/services/default/default.management.js +118 -120
- package/src/client/ssr/Render.js +224 -3
- package/src/client/ssr/common/Alert.js +75 -0
- package/src/client/ssr/common/SsrCore.js +91 -0
- package/src/client/ssr/common/Translate.js +26 -0
- package/src/client/ssr/common/Worker.js +28 -0
- package/src/client/ssr/{body-components → components/body}/CacheControl.js +1 -1
- package/src/client/ssr/{body-components → components/body}/DefaultSplashScreen.js +15 -4
- package/src/client/ssr/components/head/Pwa.js +146 -0
- package/src/client/ssr/pages/404.js +12 -0
- package/src/client/ssr/pages/500.js +12 -0
- package/src/client/ssr/pages/maintenance.js +14 -0
- package/src/client/ssr/pages/offline.js +21 -0
- package/src/client/sw/default.sw.js +13 -9
- package/src/db/DataBaseProvider.js +12 -1
- package/src/db/mongo/MongooseDB.js +0 -1
- package/src/mailer/EmailRender.js +1 -1
- package/src/server/backup.js +82 -70
- package/src/server/client-build-live.js +6 -0
- package/src/server/client-build.js +76 -73
- package/src/server/client-formatted.js +11 -1
- package/src/server/client-icons.js +1 -1
- package/src/server/conf.js +60 -12
- package/src/server/crypto.js +91 -0
- package/src/server/dns.js +42 -13
- package/src/server/network.js +94 -7
- package/src/server/proxy.js +27 -27
- package/src/server/runtime.js +27 -8
- package/.github/workflows/test.yml +0 -80
- package/src/client/ssr/head-components/Microdata.js +0 -11
- package/src/cron.js +0 -30
- package/src/server/cron.js +0 -35
- /package/src/client/ssr/{email-components → components/email}/DefaultRecoverEmail.js +0 -0
- /package/src/client/ssr/{email-components → components/email}/DefaultVerifyEmail.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Css.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/DefaultScripts.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Production.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/PwaDefault.js +0 -0
- /package/src/client/ssr/{head-components → components/head}/Seo.js +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { htmls, loggerFactory } from '../common/SsrCore.js';
|
|
2
|
+
import { Alert } from '../common/Alert.js';
|
|
3
|
+
import { Translate } from '../common/Translate.js';
|
|
4
|
+
import { Worker } from '../common/Worker.js';
|
|
5
|
+
/*imports*/
|
|
6
|
+
|
|
7
|
+
const logger = loggerFactory({ url: location.toString() });
|
|
8
|
+
|
|
9
|
+
window.onload = () =>
|
|
10
|
+
Worker.instance({
|
|
11
|
+
render: async () => {
|
|
12
|
+
window.ononline = async () => {
|
|
13
|
+
location.href = location.pathname.split('/')[1] ? `/${location.pathname.split('/')[1].split('.')[0]}` : '/';
|
|
14
|
+
};
|
|
15
|
+
window.onoffline = async () => {
|
|
16
|
+
htmls(`.page-render`, html`${await Alert.noInternet({ Translate })}`);
|
|
17
|
+
};
|
|
18
|
+
if (navigator.onLine && !location.hostname.match('localhost')) window.ononline();
|
|
19
|
+
else window.onoffline();
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -37,6 +37,8 @@ even while offline, can asynchronously save files and many other things)
|
|
|
37
37
|
|
|
38
38
|
const logger = loggerFactory(import.meta);
|
|
39
39
|
|
|
40
|
+
const PROXY_PATH = '/';
|
|
41
|
+
|
|
40
42
|
self.addEventListener('install', (event) => {
|
|
41
43
|
// Activate right away
|
|
42
44
|
self.skipWaiting();
|
|
@@ -179,15 +181,17 @@ self.addEventListener('fetch', (event) => {
|
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
logger.error('Fetch failed; returning offline page instead.', { error, path });
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
try {
|
|
185
|
+
const cache = await caches.open(`${PROXY_PATH}offline.html`);
|
|
186
|
+
const cachedResponse = await cache.match(`${PROXY_PATH}offline.html`);
|
|
187
|
+
return cachedResponse;
|
|
188
|
+
} catch (error) {
|
|
189
|
+
logger.error('Error opening cache for offline page', { error, path });
|
|
190
|
+
const response = new Response(JSON.stringify({ status: 'error', message: 'offline test response' }));
|
|
191
|
+
// response.status = 200;
|
|
192
|
+
response.headers.set('Content-Type', 'application/json');
|
|
193
|
+
return response;
|
|
194
|
+
}
|
|
191
195
|
}
|
|
192
196
|
})(),
|
|
193
197
|
);
|
|
@@ -18,7 +18,18 @@ const DataBaseProvider = {
|
|
|
18
18
|
case 'mongoose':
|
|
19
19
|
{
|
|
20
20
|
const conn = await MongooseDB.connect(db.host, db.name);
|
|
21
|
-
this.instance[`${host}${path}`][db.provider] =
|
|
21
|
+
this.instance[`${host}${path}`][db.provider] = {
|
|
22
|
+
models: await MongooseDB.loadModels({ conn, apis }),
|
|
23
|
+
connection: conn,
|
|
24
|
+
close: async () => {
|
|
25
|
+
return await new Promise((resolve) => {
|
|
26
|
+
DataBaseProvider.instance[`${host}${path}`][db.provider].connection.close().then(() => {
|
|
27
|
+
// logger.info('Mongoose connection is disconnected', db);
|
|
28
|
+
return resolve();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
};
|
|
22
33
|
}
|
|
23
34
|
break;
|
|
24
35
|
default:
|
|
@@ -59,7 +59,7 @@ const EmailRender = {
|
|
|
59
59
|
for (const templateKey of Object.keys(options.templates)) {
|
|
60
60
|
const ssrEmailComponent = options.templates[templateKey];
|
|
61
61
|
let SrrComponent;
|
|
62
|
-
eval(await srcFormatted(fs.readFileSync(`./src/client/ssr/email
|
|
62
|
+
eval(await srcFormatted(fs.readFileSync(`./src/client/ssr/components/email/${ssrEmailComponent}.js`, 'utf8')));
|
|
63
63
|
templates[templateKey] = SrrComponent(this, options);
|
|
64
64
|
}
|
|
65
65
|
return templates;
|
package/src/server/backup.js
CHANGED
|
@@ -9,100 +9,112 @@ dotenv.config();
|
|
|
9
9
|
const logger = loggerFactory(import.meta);
|
|
10
10
|
|
|
11
11
|
const BackUpManagement = {
|
|
12
|
-
repoUrl: `https://${process.env.
|
|
13
|
-
Init: async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
Callback: async function () {
|
|
18
|
-
const privateCronConfPath = `./engine-private/conf/${process.argv[2]}/conf.cron.json`;
|
|
12
|
+
repoUrl: `https://${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_USERNAME}/${process.env.GITHUB_BACKUP_REPO}.git`,
|
|
13
|
+
Init: async function ({ deployId }) {
|
|
14
|
+
const Callback = async function () {
|
|
15
|
+
const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
const { backups } = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
if (!backups) return;
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
logger.info('init backups callback');
|
|
24
|
+
await logger.setUpInfo();
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
fs.mkdirSync('./engine-private/cron-backups', { recursive: true });
|
|
26
|
+
const currentDate = new Date().getTime();
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const dataDeploy = getDataDeploy({ deployGroupId });
|
|
28
|
+
if (!fs.existsSync('./engine-private/cron-backups'))
|
|
29
|
+
fs.mkdirSync('./engine-private/cron-backups', { recursive: true });
|
|
34
30
|
|
|
35
|
-
for (const
|
|
36
|
-
const {
|
|
31
|
+
for (const deployGroupData of backups) {
|
|
32
|
+
const { deployGroupId } = deployGroupData;
|
|
33
|
+
const dataDeploy = getDataDeploy({ deployGroupId });
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
for (const deployObj of dataDeploy) {
|
|
36
|
+
const { deployId, replicaHost } = deployObj;
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
|
|
42
|
-
? fs.readFileSync(`./engine-private/replica/${deployId}/conf.server.json`, 'utf8')
|
|
43
|
-
: fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
|
|
44
|
-
);
|
|
38
|
+
if (replicaHost) continue;
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
const confServer = JSON.parse(
|
|
41
|
+
fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
|
|
42
|
+
? fs.readFileSync(`./engine-private/replica/${deployId}/conf.server.json`, 'utf8')
|
|
43
|
+
: fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
|
|
44
|
+
);
|
|
50
45
|
|
|
51
|
-
|
|
46
|
+
for (const host of Object.keys(confServer))
|
|
47
|
+
for (const path of Object.keys(confServer[host])) {
|
|
48
|
+
// retention policy
|
|
49
|
+
let { db, backupFrequency, maxBackupRetention, singleReplica, wp, git, directory } =
|
|
50
|
+
confServer[host][path];
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
if (!maxBackupRetention) maxBackupRetention = 5;
|
|
52
|
+
if (!db || singleReplica) continue;
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// .isDirectory()
|
|
59
|
-
const files = await fs.readdir(backUpPath, { withFileTypes: true });
|
|
54
|
+
if (!backupFrequency) backupFrequency = 'daily';
|
|
55
|
+
if (!maxBackupRetention) maxBackupRetention = 5;
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
.
|
|
63
|
-
.
|
|
64
|
-
.
|
|
57
|
+
const backUpPath = `${process.cwd()}/engine-private/cron-backups/${getCronBackUpFolder(host, path)}`;
|
|
58
|
+
if (!fs.existsSync(backUpPath)) fs.mkdirSync(`${backUpPath}`, { recursive: true });
|
|
59
|
+
// .isDirectory()
|
|
60
|
+
const files = await fs.readdir(backUpPath, { withFileTypes: true });
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
const currentBackupsDirs = files
|
|
63
|
+
.map((fileObj) => parseInt(fileObj.name))
|
|
64
|
+
.sort((a, b) => a - b)
|
|
65
|
+
.reverse();
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
67
|
+
switch (backupFrequency) {
|
|
68
|
+
case 'daily':
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
default:
|
|
71
|
+
// if (currentBackupsDirs[0] && currentDate - currentBackupsDirs[0] < 1000 * 60 * 60 * 24) continue;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const retentionPath of currentBackupsDirs.filter((t, i) => i >= maxBackupRetention - 1)) {
|
|
76
|
+
const removePathRetention = `${backUpPath}/${retentionPath}`;
|
|
77
|
+
logger.info('Remove backup folder', removePathRetention);
|
|
78
|
+
fs.removeSync(removePathRetention);
|
|
79
|
+
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
fs.mkdirSync(`${backUpPath}/${currentDate}`, { recursive: true });
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
shellExec(`node bin/db ${host}${path} export ${deployId} ${backUpPath}/${currentDate}`);
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
if (wp) {
|
|
86
|
+
const repoUrl = `https://${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_USERNAME}/${git
|
|
87
|
+
.split('/')
|
|
88
|
+
.pop()}.git`;
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
shellExec(
|
|
91
|
+
`cd ${directory}` +
|
|
92
|
+
` && git pull ${repoUrl}` +
|
|
93
|
+
` && git add . && git commit -m "backup ${new Date().toLocaleDateString()}"` +
|
|
94
|
+
` && git push ${repoUrl}`,
|
|
95
|
+
{
|
|
96
|
+
disableLog: true,
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
}
|
|
95
100
|
}
|
|
96
|
-
|
|
101
|
+
}
|
|
97
102
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
shellExec(
|
|
104
|
+
`cd ./engine-private/cron-backups` +
|
|
105
|
+
` && git pull ${BackUpManagement.repoUrl}` +
|
|
106
|
+
` && git add . && git commit -m "backup ${new Date().toLocaleDateString()}"` +
|
|
107
|
+
` && git push ${BackUpManagement.repoUrl}`,
|
|
108
|
+
{
|
|
109
|
+
disableLog: true,
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
await Callback();
|
|
114
|
+
BackUpManagement.Callback = Callback;
|
|
115
|
+
return Callback;
|
|
105
116
|
},
|
|
117
|
+
Callback: async function (params) {},
|
|
106
118
|
};
|
|
107
119
|
|
|
108
120
|
export { BackUpManagement };
|
|
@@ -71,6 +71,12 @@ const clientLiveBuild = async () => {
|
|
|
71
71
|
} else if (srcPath.split('src')[1].startsWith(`\\client\\sw`)) {
|
|
72
72
|
const publicBuildPath = `./public/${baseHost}/sw.js`;
|
|
73
73
|
liveClientBuildPaths.push({ srcBuildPath, publicBuildPath });
|
|
74
|
+
} else if (
|
|
75
|
+
srcPath.split('src')[1].startsWith(`\\client\\offline`) &&
|
|
76
|
+
srcPath.split('src')[1].startsWith(`index.js`)
|
|
77
|
+
) {
|
|
78
|
+
const publicBuildPath = `./public/${baseHost}/offline.js`;
|
|
79
|
+
liveClientBuildPaths.push({ srcBuildPath, publicBuildPath });
|
|
74
80
|
} else if (srcPath.split('src')[1].startsWith(`\\client`) && srcPath.slice(-9) === '.index.js') {
|
|
75
81
|
for (const view of views) {
|
|
76
82
|
const publicBuildPath = `./public/${baseHost}${view.path === '/' ? '' : view.path}/${clientId}.index.js`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
|
-
import { srcFormatted, componentFormatted, viewFormatted } from './client-formatted.js';
|
|
4
|
+
import { srcFormatted, componentFormatted, viewFormatted, ssrFactory } from './client-formatted.js';
|
|
5
5
|
import { loggerFactory } from './logger.js';
|
|
6
6
|
import { cap, newInstance, orderArrayFromAttrInt, titleFormatted } from '../client/components/core/CommonJs.js';
|
|
7
7
|
import UglifyJS from 'uglify-js';
|
|
@@ -52,7 +52,7 @@ const fullBuild = async ({
|
|
|
52
52
|
if (!fs.existsSync(defaultBaseIconPath))
|
|
53
53
|
await buildTextImg(metadata.title, { debugFilename: defaultBaseIconPath });
|
|
54
54
|
|
|
55
|
-
if (
|
|
55
|
+
if (!fs.existsSync(`./src/client/public/${publicClientId}/site.webmanifest`))
|
|
56
56
|
await buildIcons({ publicClientId, metadata });
|
|
57
57
|
}
|
|
58
58
|
fs.copySync(
|
|
@@ -112,6 +112,16 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
112
112
|
const enableLiveRebuild =
|
|
113
113
|
options && options.liveClientBuildPaths && options.liveClientBuildPaths.length > 0 ? true : false;
|
|
114
114
|
|
|
115
|
+
// common ssr components
|
|
116
|
+
let jsSsrCommonComponents = '';
|
|
117
|
+
{
|
|
118
|
+
const files = await fs.readdir(`./src/client/ssr/common`);
|
|
119
|
+
for (const relativePath of files)
|
|
120
|
+
jsSsrCommonComponents += await srcFormatted(
|
|
121
|
+
fs.readFileSync(`./src/client/ssr/common/${relativePath}`, 'utf8').split('export')[0],
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
115
125
|
let currentPort = parseInt(process.env.PORT) + 1;
|
|
116
126
|
for (const host of Object.keys(confServer)) {
|
|
117
127
|
const paths = orderArrayFromAttrInt(Object.keys(confServer[host]), 'length', 'asc');
|
|
@@ -178,7 +188,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
178
188
|
iconsBuild,
|
|
179
189
|
metadata,
|
|
180
190
|
});
|
|
181
|
-
if (apis)
|
|
191
|
+
if (apis && false)
|
|
182
192
|
for (const apiBuildScript of apis) {
|
|
183
193
|
const scriptPath = `src/api/${apiBuildScript}/${apiBuildScript}.build.js`;
|
|
184
194
|
if (fs.existsSync(`./${scriptPath}`)) {
|
|
@@ -238,8 +248,13 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
238
248
|
'const getBaseHost = () => location.host;',
|
|
239
249
|
`const getBaseHost = () => '${apiBaseHost}';`,
|
|
240
250
|
);
|
|
241
|
-
if (apiBaseProxyPath)
|
|
251
|
+
if (apiBaseProxyPath) {
|
|
242
252
|
jsSrc = jsSrc.replace('${getProxyPath()}api/', `${apiBaseProxyPath}${process.env.BASE_API}/`);
|
|
253
|
+
jsSrc = jsSrc.replace(
|
|
254
|
+
"const getWsBasePath = () => (getProxyPath() !== '/' ? `${getProxyPath()}socket.io/` : undefined);",
|
|
255
|
+
`const getWsBasePath = () => '${apiBaseProxyPath}socket.io/';`,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
243
258
|
}
|
|
244
259
|
fs.writeFileSync(
|
|
245
260
|
jsPublicPath,
|
|
@@ -274,26 +289,61 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
274
289
|
|
|
275
290
|
const buildId = `${client}.index`;
|
|
276
291
|
const siteMapLinks = [];
|
|
292
|
+
let Render = () => '';
|
|
293
|
+
eval(await srcFormatted(fs.readFileSync(`./src/client/ssr/Render.js`, 'utf8')));
|
|
277
294
|
|
|
278
295
|
if (views) {
|
|
279
|
-
|
|
280
|
-
if (path === '/') {
|
|
281
|
-
const jsSrcPath = fs.existsSync(`./src/client/sw/${publicClientId}.sw.js`)
|
|
282
|
-
? `./src/client/sw/${publicClientId}.sw.js`
|
|
283
|
-
: `./src/client/sw/default.sw.js`;
|
|
284
|
-
|
|
285
|
-
const jsPublicPath = `${rootClientPath}/sw.js`;
|
|
286
|
-
|
|
296
|
+
const buildJsSrcPage = async (jsSrcPath, jsPublicPath, filter) => {
|
|
287
297
|
if (!(enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath))) {
|
|
288
|
-
|
|
289
|
-
|
|
298
|
+
let jsSrc = viewFormatted(await srcFormatted(fs.readFileSync(jsSrcPath, 'utf8')), dists, path, baseHost);
|
|
299
|
+
if (jsSrc.split('/*imports*/')[1]) jsSrc = jsSrc.split('/*imports*/')[1];
|
|
300
|
+
if (filter) jsSrc = await filter(jsSrc);
|
|
290
301
|
fs.writeFileSync(
|
|
291
302
|
jsPublicPath,
|
|
292
303
|
minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
|
|
293
304
|
'utf8',
|
|
294
305
|
);
|
|
295
306
|
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// service woker
|
|
310
|
+
await buildJsSrcPage(
|
|
311
|
+
fs.existsSync(`./src/client/sw/${publicClientId}.sw.js`)
|
|
312
|
+
? `./src/client/sw/${publicClientId}.sw.js`
|
|
313
|
+
: `./src/client/sw/default.sw.js`,
|
|
314
|
+
`${rootClientPath}/sw.js`,
|
|
315
|
+
path !== '/'
|
|
316
|
+
? (jsSrc) => jsSrc.replaceAll(`const PROXY_PATH = '/';`, `const PROXY_PATH = '${path}/';`)
|
|
317
|
+
: undefined,
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
// ssr pages
|
|
321
|
+
for (const page of await fs.readdir('./src/client/ssr/pages')) {
|
|
322
|
+
await buildJsSrcPage(`./src/client/ssr/pages/${page}`, `${rootClientPath}/${page}`);
|
|
323
|
+
|
|
324
|
+
const htmlSrc = Render({
|
|
325
|
+
title: metadata?.title ? metadata.title : cap(client),
|
|
326
|
+
ssrPath: '/',
|
|
327
|
+
ssrHeadComponents: '',
|
|
328
|
+
ssrBodyComponents: '',
|
|
329
|
+
baseSsrLib: jsSsrCommonComponents + fs.readFileSync(`${rootClientPath}/${page}`, 'utf8'),
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
fs.writeFileSync(
|
|
333
|
+
`${rootClientPath}/${page.slice(0, -3)}.html`,
|
|
334
|
+
minifyBuild || process.env.NODE_ENV === 'production'
|
|
335
|
+
? await minify(htmlSrc, {
|
|
336
|
+
minifyCSS: true,
|
|
337
|
+
minifyJS: true,
|
|
338
|
+
collapseBooleanAttributes: true,
|
|
339
|
+
collapseInlineTagWhitespace: true,
|
|
340
|
+
collapseWhitespace: true,
|
|
341
|
+
})
|
|
342
|
+
: htmlSrc,
|
|
343
|
+
'utf8',
|
|
344
|
+
);
|
|
296
345
|
}
|
|
346
|
+
|
|
297
347
|
if (
|
|
298
348
|
!(
|
|
299
349
|
enableLiveRebuild &&
|
|
@@ -345,11 +395,9 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
345
395
|
confSSR[view.ssr].head.unshift('Production');
|
|
346
396
|
|
|
347
397
|
for (const ssrHeadComponent of confSSR[view.ssr].head) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
fs.readFileSync(`./src/client/ssr/head-components/${ssrHeadComponent}.js`, 'utf8'),
|
|
352
|
-
),
|
|
398
|
+
const SrrComponent = await ssrFactory(
|
|
399
|
+
`./src/client/ssr/components/head/${ssrHeadComponent}.js`,
|
|
400
|
+
jsSsrCommonComponents,
|
|
353
401
|
);
|
|
354
402
|
|
|
355
403
|
switch (ssrHeadComponent) {
|
|
@@ -359,7 +407,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
359
407
|
fs.existsSync(`./src/client/public/${publicClientId}/browserconfig.xml`) &&
|
|
360
408
|
fs.existsSync(`./src/client/public/${publicClientId}/site.webmanifest`);
|
|
361
409
|
|
|
362
|
-
if (
|
|
410
|
+
if (validPwaBuild) {
|
|
363
411
|
// build webmanifest
|
|
364
412
|
const webmanifestJson = JSON.parse(
|
|
365
413
|
fs.readFileSync(`./src/client/public/${publicClientId}/site.webmanifest`, 'utf8'),
|
|
@@ -431,11 +479,9 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
431
479
|
}
|
|
432
480
|
|
|
433
481
|
for (const ssrBodyComponent of confSSR[view.ssr].body) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
fs.readFileSync(`./src/client/ssr/body-components/${ssrBodyComponent}.js`, 'utf8'),
|
|
438
|
-
),
|
|
482
|
+
const SrrComponent = await ssrFactory(
|
|
483
|
+
`./src/client/ssr/components/body/${ssrBodyComponent}.js`,
|
|
484
|
+
jsSsrCommonComponents,
|
|
439
485
|
);
|
|
440
486
|
switch (ssrBodyComponent) {
|
|
441
487
|
case 'UnderpostDefaultSplashScreen':
|
|
@@ -448,7 +494,10 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
448
494
|
.readFileSync(backgroundImage)
|
|
449
495
|
.toString('base64')}`,
|
|
450
496
|
});
|
|
497
|
+
break;
|
|
451
498
|
} else {
|
|
499
|
+
ssrHeadComponents += SrrComponent({ metadata });
|
|
500
|
+
break;
|
|
452
501
|
const bufferBackgroundImage = await getBufferPngText({
|
|
453
502
|
text: ' ',
|
|
454
503
|
textColor: metadata?.themeColor ? metadata.themeColor : '#ececec',
|
|
@@ -459,7 +508,6 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
459
508
|
base64BackgroundImage: `data:image/png;base64,${bufferBackgroundImage.toString('base64')}`,
|
|
460
509
|
});
|
|
461
510
|
}
|
|
462
|
-
break;
|
|
463
511
|
|
|
464
512
|
case 'CyberiaSplashScreenLore': {
|
|
465
513
|
ssrBodyComponents += SrrComponent({
|
|
@@ -467,48 +515,6 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
467
515
|
host,
|
|
468
516
|
path,
|
|
469
517
|
ttiLoadTimeLimit,
|
|
470
|
-
storage: {
|
|
471
|
-
// 'space-background': fs.readFileSync('./src/client/public/cyberia/space-background', 'utf8'),
|
|
472
|
-
lore0: `data:image/jpeg;base64,${fs
|
|
473
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore0.jpeg')
|
|
474
|
-
.toString('base64')}`,
|
|
475
|
-
lore1: `data:image/jpeg;base64,${fs
|
|
476
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore1.jpeg')
|
|
477
|
-
.toString('base64')}`,
|
|
478
|
-
lore2: `data:image/jpeg;base64,${fs
|
|
479
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore2.jpeg')
|
|
480
|
-
.toString('base64')}`,
|
|
481
|
-
lore3: `data:image/jpeg;base64,${fs
|
|
482
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore3.jpeg')
|
|
483
|
-
.toString('base64')}`,
|
|
484
|
-
lore4: `data:image/jpeg;base64,${fs
|
|
485
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore4.jpeg')
|
|
486
|
-
.toString('base64')}`,
|
|
487
|
-
lore5: `data:image/jpeg;base64,${fs
|
|
488
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore5.jpeg')
|
|
489
|
-
.toString('base64')}`,
|
|
490
|
-
lore6: `data:image/jpeg;base64,${fs
|
|
491
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore6.jpeg')
|
|
492
|
-
.toString('base64')}`,
|
|
493
|
-
lore7: `data:image/jpeg;base64,${fs
|
|
494
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore7.jpeg')
|
|
495
|
-
.toString('base64')}`,
|
|
496
|
-
lore8: `data:image/jpeg;base64,${fs
|
|
497
|
-
.readFileSync('./src/client/public/cyberia/assets/lore/lore8.jpeg')
|
|
498
|
-
.toString('base64')}`,
|
|
499
|
-
['arrow-left']: `data:image/png;base64,${fs
|
|
500
|
-
.readFileSync('./src/client/public/cyberia/assets/ui-icons/arrow-left.png')
|
|
501
|
-
.toString('base64')}`,
|
|
502
|
-
['arrow-right']: `data:image/png;base64,${fs
|
|
503
|
-
.readFileSync('./src/client/public/cyberia/assets/ui-icons/arrow-right.png')
|
|
504
|
-
.toString('base64')}`,
|
|
505
|
-
['fullscreen']: `data:image/png;base64,${fs
|
|
506
|
-
.readFileSync('./src/client/public/cyberia/assets/ui-icons/fullscreen.png')
|
|
507
|
-
.toString('base64')}`,
|
|
508
|
-
['cyberia-logo']: `data:image/png;base64,${fs
|
|
509
|
-
.readFileSync('./src/client/public/cyberia/assets/util/cyberia-retro-banner.png')
|
|
510
|
-
.toString('base64')}`,
|
|
511
|
-
},
|
|
512
518
|
});
|
|
513
519
|
break;
|
|
514
520
|
}
|
|
@@ -519,16 +525,13 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [] }
|
|
|
519
525
|
}
|
|
520
526
|
}
|
|
521
527
|
}
|
|
522
|
-
|
|
523
|
-
let Render = () => '';
|
|
524
|
-
eval(await srcFormatted(fs.readFileSync(`./src/client/ssr/Render.js`, 'utf8')));
|
|
525
|
-
|
|
526
528
|
const htmlSrc = Render({
|
|
527
529
|
title,
|
|
528
530
|
buildId,
|
|
529
531
|
ssrPath,
|
|
530
532
|
ssrHeadComponents,
|
|
531
533
|
ssrBodyComponents,
|
|
534
|
+
baseSsrLib: jsSsrCommonComponents,
|
|
532
535
|
});
|
|
533
536
|
|
|
534
537
|
/** @type {import('sitemap').SitemapItem} */
|
|
@@ -616,7 +619,7 @@ Sitemap: https://${host}${path === '/' ? '' : path}/sitemap.xml`,
|
|
|
616
619
|
fs.copySync(`./coverage`, coverageBuildPath);
|
|
617
620
|
|
|
618
621
|
// uml
|
|
619
|
-
shellExec(`node bin/deploy uml ${host} ${path}`);
|
|
622
|
+
// shellExec(`node bin/deploy uml ${host} ${path}`);
|
|
620
623
|
|
|
621
624
|
// https://swagger-autogen.github.io/docs/
|
|
622
625
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
|
|
3
5
|
const srcFormatted = (src) =>
|
|
4
6
|
src
|
|
5
7
|
.replaceAll(' html`', '`')
|
|
@@ -45,4 +47,12 @@ const viewFormatted = (src, dists, proxyPath, baseHost = '') => {
|
|
|
45
47
|
return src.replaceAll(`from './`, componentFromFormatted).replaceAll(`from '../`, componentFromFormatted);
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
const ssrFactory = async (componentPath = '', jsSsrCommonComponents) => {
|
|
51
|
+
let SrrComponent = () => {};
|
|
52
|
+
let render = await srcFormatted(fs.readFileSync(componentPath, 'utf8'));
|
|
53
|
+
if (render.split('/*imports*/')[1]) render = render.split('/*imports*/')[1];
|
|
54
|
+
eval(jsSsrCommonComponents + render);
|
|
55
|
+
return SrrComponent;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export { srcFormatted, JSONweb, componentFormatted, viewFormatted, ssrFactory };
|
|
@@ -140,7 +140,7 @@ const buildIcons = async ({
|
|
|
140
140
|
for (const file of response.files)
|
|
141
141
|
fs.writeFileSync(`./src/client/public/${publicClientId}/${file.name}`, file.contents, 'utf8');
|
|
142
142
|
|
|
143
|
-
const ssrPath = `./src/client/ssr/
|
|
143
|
+
const ssrPath = `./src/client/ssr/components/head/Pwa${getCapVariableName(publicClientId)}.js`;
|
|
144
144
|
if (!fs.existsSync(ssrPath))
|
|
145
145
|
fs.writeFileSync(ssrPath, 'SrrComponent = () => html`' + response.html.join(`\n`) + '`;', 'utf8');
|
|
146
146
|
} catch (error) {
|