underpost 3.1.2 → 3.2.0

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 (98) hide show
  1. package/.env.example +0 -2
  2. package/.github/workflows/ghpkg.ci.yml +4 -4
  3. package/.github/workflows/npmpkg.ci.yml +38 -7
  4. package/.github/workflows/pwa-microservices-template-page.cd.yml +3 -4
  5. package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
  6. package/.github/workflows/release.cd.yml +4 -4
  7. package/CHANGELOG.md +365 -1
  8. package/CLI-HELP.md +55 -3
  9. package/README.md +7 -3
  10. package/bin/build.js +18 -12
  11. package/bin/deploy.js +205 -225
  12. package/bin/file.js +3 -0
  13. package/conf.js +4 -10
  14. package/jsdoc.json +1 -1
  15. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  16. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  17. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  18. package/manifests/deployment/dd-test-development/deployment.yaml +72 -50
  19. package/manifests/deployment/dd-test-development/proxy.yaml +13 -4
  20. package/manifests/deployment/playwright/deployment.yaml +1 -1
  21. package/nodemon.json +1 -1
  22. package/package.json +21 -14
  23. package/scripts/ports-ls.sh +2 -0
  24. package/scripts/rhel-grpc-setup.sh +56 -0
  25. package/src/api/file/file.ref.json +18 -0
  26. package/src/api/user/user.service.js +8 -7
  27. package/src/cli/cluster.js +7 -7
  28. package/src/cli/db.js +76 -242
  29. package/src/cli/deploy.js +104 -65
  30. package/src/cli/env.js +1 -0
  31. package/src/cli/fs.js +2 -1
  32. package/src/cli/index.js +50 -1
  33. package/src/cli/kubectl.js +211 -0
  34. package/src/cli/release.js +284 -0
  35. package/src/cli/repository.js +328 -112
  36. package/src/cli/run.js +283 -69
  37. package/src/cli/test.js +3 -3
  38. package/src/client/Default.index.js +3 -4
  39. package/src/client/components/core/Alert.js +2 -2
  40. package/src/client/components/core/AppStore.js +69 -0
  41. package/src/client/components/core/CalendarCore.js +2 -2
  42. package/src/client/components/core/Docs.js +9 -2
  43. package/src/client/components/core/DropDown.js +129 -17
  44. package/src/client/components/core/Keyboard.js +2 -2
  45. package/src/client/components/core/LogIn.js +2 -2
  46. package/src/client/components/core/LogOut.js +2 -2
  47. package/src/client/components/core/Modal.js +0 -1
  48. package/src/client/components/core/Panel.js +0 -1
  49. package/src/client/components/core/PanelForm.js +19 -19
  50. package/src/client/components/core/RichText.js +1 -2
  51. package/src/client/components/core/SocketIo.js +82 -29
  52. package/src/client/components/core/SocketIoHandler.js +75 -0
  53. package/src/client/components/core/Stream.js +143 -95
  54. package/src/client/components/core/Webhook.js +40 -7
  55. package/src/client/components/default/AppStoreDefault.js +5 -0
  56. package/src/client/components/default/LogInDefault.js +3 -3
  57. package/src/client/components/default/LogOutDefault.js +2 -2
  58. package/src/client/components/default/MenuDefault.js +5 -5
  59. package/src/client/components/default/SocketIoDefault.js +3 -51
  60. package/src/client/services/core/core.service.js +20 -8
  61. package/src/client/services/user/user.management.js +2 -2
  62. package/src/client/ssr/body/404.js +15 -11
  63. package/src/client/ssr/body/500.js +15 -11
  64. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  65. package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
  66. package/src/client/ssr/pages/Test.js +11 -10
  67. package/src/index.js +24 -1
  68. package/src/runtime/express/Express.js +26 -9
  69. package/src/runtime/lampp/Dockerfile +9 -2
  70. package/src/runtime/lampp/Lampp.js +4 -3
  71. package/src/runtime/wp/Dockerfile +64 -0
  72. package/src/runtime/wp/Wp.js +497 -0
  73. package/src/server/auth.js +30 -6
  74. package/src/server/backup.js +19 -1
  75. package/src/server/client-build-docs.js +51 -110
  76. package/src/server/client-build.js +55 -64
  77. package/src/server/client-formatted.js +109 -57
  78. package/src/server/conf.js +19 -15
  79. package/src/server/ipfs-client.js +24 -1
  80. package/src/server/peer.js +8 -0
  81. package/src/server/runtime.js +25 -1
  82. package/src/server/start.js +21 -8
  83. package/src/ws/IoInterface.js +1 -10
  84. package/src/ws/IoServer.js +14 -33
  85. package/src/ws/core/channels/core.ws.chat.js +65 -20
  86. package/src/ws/core/channels/core.ws.mailer.js +113 -32
  87. package/src/ws/core/channels/core.ws.stream.js +90 -31
  88. package/src/ws/core/core.ws.connection.js +12 -33
  89. package/src/ws/core/core.ws.emit.js +10 -26
  90. package/src/ws/core/core.ws.server.js +25 -58
  91. package/src/ws/default/channels/default.ws.main.js +53 -12
  92. package/src/ws/default/default.ws.connection.js +26 -13
  93. package/src/ws/default/default.ws.server.js +30 -12
  94. package/src/client/components/default/ElementsDefault.js +0 -38
  95. package/src/ws/core/management/core.ws.chat.js +0 -8
  96. package/src/ws/core/management/core.ws.mailer.js +0 -16
  97. package/src/ws/core/management/core.ws.stream.js +0 -8
  98. package/src/ws/default/management/default.ws.main.js +0 -8
@@ -332,56 +332,17 @@ const buildApiDocs = async ({
332
332
  * @param {string} options.path - The base path for the documentation
333
333
  * @param {Object} options.metadata - Metadata for the documentation
334
334
  * @param {string} options.publicClientId - Client ID used to resolve the tutorials/references directory
335
+ * @param {Object} options.docs - Documentation config from server conf
336
+ * @param {string} options.docs.jsJsonPath - Path to the JSDoc JSON config file
335
337
  */
336
- const buildJsDocs = async ({ host, path, metadata = {}, publicClientId }) => {
338
+ const buildJsDocs = async ({ host, path, metadata = {}, publicClientId, docs }) => {
337
339
  const logger = loggerFactory(import.meta);
338
340
 
339
- // Detect custom jsdoc.<deployId>.json by matching host against deploy server configs
340
- let customJsDocPath = '';
341
- const privateConfBase = `./engine-private/conf`;
342
- if (fs.existsSync(privateConfBase)) {
343
- for (const deployId of fs.readdirSync(privateConfBase)) {
344
- const candidatePath = `./jsdoc.${deployId}.json`;
345
- if (!fs.existsSync(candidatePath)) continue;
346
-
347
- // Check if this deployId's server config contains the current host
348
- const serverConfPath = `${privateConfBase}/${deployId}/conf.server.json`;
349
- if (fs.existsSync(serverConfPath)) {
350
- try {
351
- const serverConf = JSON.parse(fs.readFileSync(serverConfPath, 'utf8'));
352
- if (serverConf[host]) {
353
- customJsDocPath = candidatePath;
354
- logger.info('detected custom jsdoc config', { deployId, host, path: candidatePath });
355
- break;
356
- }
357
- } catch (e) {
358
- // skip invalid JSON
359
- }
360
- }
361
-
362
- // Fallback: also check dev server configs
363
- if (!customJsDocPath) {
364
- const devConfFiles = fs
365
- .readdirSync(`${privateConfBase}/${deployId}`)
366
- .filter((f) => f.match(/^conf\.server\.dev\..*\.json$/));
367
- for (const devFile of devConfFiles) {
368
- try {
369
- const devConf = JSON.parse(fs.readFileSync(`${privateConfBase}/${deployId}/${devFile}`, 'utf8'));
370
- if (devConf[host]) {
371
- customJsDocPath = candidatePath;
372
- logger.info('detected custom jsdoc config (dev)', { deployId, host, path: candidatePath });
373
- break;
374
- }
375
- } catch (e) {
376
- // skip invalid JSON
377
- }
378
- }
379
- }
380
- if (customJsDocPath) break;
381
- }
341
+ const jsDocSourcePath = docs.jsJsonPath;
342
+ if (!fs.existsSync(jsDocSourcePath)) {
343
+ logger.warn('jsdoc config not found, skipping', jsDocSourcePath);
344
+ return;
382
345
  }
383
-
384
- const jsDocSourcePath = customJsDocPath || `./jsdoc.json`;
385
346
  const jsDocsConfig = JSON.parse(fs.readFileSync(jsDocSourcePath, 'utf8'));
386
347
  logger.info('using jsdoc config', jsDocSourcePath);
387
348
 
@@ -391,22 +352,14 @@ const buildJsDocs = async ({ host, path, metadata = {}, publicClientId }) => {
391
352
 
392
353
  const tutorialsPath = `./src/client/public/${publicClientId}/docs/references`;
393
354
 
394
- // Auto-prepare hardhat references when jsdoc config includes hardhat source files
395
- const includesHardhat =
396
- jsDocsConfig.source &&
397
- Array.isArray(jsDocsConfig.source.include) &&
398
- jsDocsConfig.source.include.some((p) => p.includes('hardhat/'));
399
- if (includesHardhat && fs.existsSync(`./hardhat`)) {
355
+ if (Array.isArray(docs.references) && docs.references.length > 0) {
400
356
  fs.mkdirSync(tutorialsPath, { recursive: true });
401
- const hardhatReadmePath = `./hardhat/README.md`;
402
- const hardhatWhitePaperPath = `./hardhat/WHITE-PAPER.md`;
403
- if (fs.existsSync(hardhatReadmePath)) {
404
- fs.copySync(hardhatReadmePath, `${tutorialsPath}/Hardhat Module.md`);
405
- logger.info('copied hardhat README.md to tutorials references');
406
- }
407
- if (fs.existsSync(hardhatWhitePaperPath)) {
408
- fs.copySync(hardhatWhitePaperPath, `${tutorialsPath}/White Paper.md`);
409
- logger.info('copied hardhat WHITE-PAPER.md to tutorials references');
357
+ for (const refPath of docs.references) {
358
+ if (fs.existsSync(refPath)) {
359
+ const fileName = refPath.split('/').pop();
360
+ fs.copySync(refPath, `${tutorialsPath}/${fileName}`);
361
+ logger.info('copied reference to tutorials', refPath);
362
+ }
410
363
  }
411
364
  }
412
365
 
@@ -420,10 +373,10 @@ const buildJsDocs = async ({ host, path, metadata = {}, publicClientId }) => {
420
373
  delete jsDocsConfig.opts.tutorials;
421
374
  }
422
375
 
423
- fs.writeFileSync(`./jsdoc.json`, JSON.stringify(jsDocsConfig, null, 4), 'utf8');
376
+ fs.writeFileSync(jsDocSourcePath, JSON.stringify(jsDocsConfig, null, 4), 'utf8');
424
377
  logger.warn('build jsdoc view', jsDocsConfig.opts.destination);
425
378
 
426
- shellExec(`npm run docs`, { silent: true });
379
+ shellExec(`npx jsdoc -c ${jsDocSourcePath}`, { silent: true });
427
380
  };
428
381
 
429
382
  /**
@@ -433,58 +386,44 @@ const buildJsDocs = async ({ host, path, metadata = {}, publicClientId }) => {
433
386
  * @param {Object} options - Coverage build options
434
387
  * @param {string} options.host - The hostname for the coverage
435
388
  * @param {string} options.path - The base path for the coverage
389
+ * @param {Object} options.docs - Documentation config from server conf
390
+ * @param {string} options.docs.coveragePath - Directory where to run npm run coverage
436
391
  */
437
- const buildCoverage = async ({ host, path }) => {
392
+ const buildCoverage = async ({ host, path, docs }) => {
438
393
  const logger = loggerFactory(import.meta);
439
- const jsDocsConfig = JSON.parse(fs.readFileSync(`./jsdoc.json`, 'utf8'));
440
-
441
- if (!fs.existsSync(`./coverage`)) {
442
- shellExec(`npm test`);
443
- }
444
-
445
- const coverageBuildPath = `${jsDocsConfig.opts.destination}coverage`;
446
- fs.mkdirSync(coverageBuildPath, { recursive: true });
447
- fs.copySync(`./coverage`, coverageBuildPath);
448
-
449
- logger.warn('build coverage', coverageBuildPath);
394
+ const jsDocSourcePath = docs.jsJsonPath;
395
+ const jsDocsConfig = JSON.parse(fs.readFileSync(jsDocSourcePath, 'utf8'));
396
+ const coveragePath = docs.coveragePath;
397
+ const coverageOutputDir = docs.coverageOutputDir || 'coverage';
450
398
 
451
- // Include hardhat coverage for cyberia-related builds
452
- const hardhatCoveragePath = `./hardhat/coverage`;
453
- if (fs.existsSync(hardhatCoveragePath) && fs.readdirSync(hardhatCoveragePath).length > 0) {
454
- const hardhatCoverageBuildPath = `${jsDocsConfig.opts.destination}hardhat-coverage`;
455
- fs.mkdirSync(hardhatCoverageBuildPath, { recursive: true });
456
- fs.copySync(hardhatCoveragePath, hardhatCoverageBuildPath);
457
- logger.warn('build hardhat coverage', hardhatCoverageBuildPath);
458
- } else if (fs.existsSync(`./hardhat/package.json`)) {
459
- // Attempt to generate hardhat coverage if the hardhat project exists
460
- try {
461
- const hardhatPkg = JSON.parse(fs.readFileSync(`./hardhat/package.json`, 'utf8'));
462
- if (hardhatPkg.scripts && hardhatPkg.scripts.coverage) {
463
- logger.info('generating hardhat coverage report');
464
- shellExec(`cd ./hardhat && npx hardhat coverage`, { silent: true });
465
- if (fs.existsSync(hardhatCoveragePath) && fs.readdirSync(hardhatCoveragePath).length > 0) {
466
- const hardhatCoverageBuildPath = `${jsDocsConfig.opts.destination}hardhat-coverage`;
467
- fs.mkdirSync(hardhatCoverageBuildPath, { recursive: true });
468
- fs.copySync(hardhatCoveragePath, hardhatCoverageBuildPath);
469
- logger.warn('build hardhat coverage (generated)', hardhatCoverageBuildPath);
470
- }
399
+ const coverageOutputPath = `${coveragePath}/coverage`;
400
+ if (!fs.existsSync(coverageOutputPath)) {
401
+ const pkgPath = `${coveragePath}/package.json`;
402
+ if (fs.existsSync(pkgPath)) {
403
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
404
+ if (pkg.scripts && pkg.scripts.coverage) {
405
+ logger.info('generating coverage report', coveragePath);
406
+ shellExec(`cd ${coveragePath} && npm run coverage`, { silent: true });
407
+ } else if (pkg.scripts && pkg.scripts.test) {
408
+ logger.info('generating coverage via test', coveragePath);
409
+ shellExec(`cd ${coveragePath} && npm test`, { silent: true });
471
410
  }
472
- } catch (e) {
473
- logger.warn('hardhat coverage generation skipped', e.message);
474
411
  }
475
412
  }
476
413
 
477
- // Copy hardhat README and WHITE-PAPER as markdown docs
478
- const docsDestBase = jsDocsConfig.opts.destination;
479
- const hardhatReadmePath = `./hardhat/README.md`;
480
- const hardhatWhitePaperPath = `./hardhat/WHITE-PAPER.md`;
481
- if (fs.existsSync(hardhatReadmePath)) {
482
- fs.copySync(hardhatReadmePath, `${docsDestBase}hardhat-README.md`);
483
- logger.info('copied hardhat README.md to docs');
484
- }
485
- if (fs.existsSync(hardhatWhitePaperPath)) {
486
- fs.copySync(hardhatWhitePaperPath, `${docsDestBase}hardhat-WHITE-PAPER.md`);
487
- logger.info('copied hardhat WHITE-PAPER.md to docs');
414
+ if (fs.existsSync(coverageOutputPath) && fs.readdirSync(coverageOutputPath).length > 0) {
415
+ const coverageBuildPath = `${jsDocsConfig.opts.destination}${coverageOutputDir}`;
416
+ fs.mkdirSync(coverageBuildPath, { recursive: true });
417
+ // Hardhat 3 outputs HTML to coverage/html/; Hardhat 2 / c8 output directly to coverage/
418
+ const coverageHtmlSubdir = `${coverageOutputPath}/html`;
419
+ if (fs.existsSync(coverageHtmlSubdir) && fs.existsSync(`${coverageHtmlSubdir}/index.html`)) {
420
+ fs.copySync(coverageHtmlSubdir, coverageBuildPath);
421
+ } else {
422
+ fs.copySync(coverageOutputPath, coverageBuildPath);
423
+ }
424
+ logger.warn('build coverage', coverageBuildPath);
425
+ } else {
426
+ logger.warn('no coverage output found, skipping', coverageOutputPath);
488
427
  }
489
428
  };
490
429
 
@@ -501,6 +440,7 @@ const buildCoverage = async ({ host, path }) => {
501
440
  * @param {string} options.publicClientId - Client ID for the public documentation
502
441
  * @param {string} options.rootClientPath - Root path for client files
503
442
  * @param {Object} options.packageData - Package.json data
443
+ * @param {Object} options.docs - Documentation config from server conf
504
444
  */
505
445
  const buildDocs = async ({
506
446
  host,
@@ -511,9 +451,10 @@ const buildDocs = async ({
511
451
  publicClientId,
512
452
  rootClientPath,
513
453
  packageData,
454
+ docs,
514
455
  }) => {
515
- await buildJsDocs({ host, path, metadata, publicClientId });
516
- await buildCoverage({ host, path });
456
+ await buildJsDocs({ host, path, metadata, publicClientId, docs });
457
+ await buildCoverage({ host, path, docs });
517
458
  await buildApiDocs({
518
459
  host,
519
460
  path,
@@ -7,7 +7,7 @@
7
7
  'use strict';
8
8
 
9
9
  import fs from 'fs-extra';
10
- import { srcFormatted, componentFormatted, viewFormatted, JSONweb } from './client-formatted.js';
10
+ import { transformClientJs, JSONweb } from './client-formatted.js';
11
11
  import { loggerFactory } from './logger.js';
12
12
  import {
13
13
  getCapVariableName,
@@ -16,7 +16,6 @@ import {
16
16
  uniqueArray,
17
17
  } from '../client/components/core/CommonJs.js';
18
18
  import { readConfJson } from './conf.js';
19
- import UglifyJS from 'uglify-js';
20
19
  import { minify } from 'html-minifier-terser';
21
20
  import AdmZip from 'adm-zip';
22
21
  import * as dir from 'path';
@@ -230,16 +229,28 @@ const defaultSitemapXsl = `<?xml version="1.0" encoding="UTF-8"?>
230
229
  * @function buildClient
231
230
  * @memberof clientBuild
232
231
  * @param {Object} options - Options for the build process.
232
+ * @param {string} options.deployId - The deployment ID for which to build the client.
233
233
  * @param {Array} options.liveClientBuildPaths - List of paths to build incrementally.
234
234
  * @param {Array} options.instances - List of instances to build.
235
235
  * @param {boolean} options.buildZip - Whether to create zip files of the builds.
236
+ * @param {boolean} options.fullBuild - Whether to perform a full build.
237
+ * @param {boolean} options.iconsBuild - Whether to build icons.
236
238
  * @returns {Promise<void>} - Promise that resolves when the build is complete.
237
239
  * @throws {Error} - If the build fails.
238
240
  * @memberof clientBuild
239
241
  */
240
- const buildClient = async (options = { liveClientBuildPaths: [], instances: [], buildZip: false }) => {
242
+ const buildClient = async (
243
+ options = {
244
+ deployId: '',
245
+ liveClientBuildPaths: [],
246
+ instances: [],
247
+ buildZip: false,
248
+ fullBuild: false,
249
+ iconsBuild: false,
250
+ },
251
+ ) => {
241
252
  const logger = loggerFactory(import.meta);
242
- const deployId = process.env.DEPLOY_ID;
253
+ const deployId = options.deployId || process.env.DEPLOY_ID;
243
254
  const confClient = readConfJson(deployId, 'client');
244
255
  const confServer = readConfJson(deployId, 'server', { loadReplicas: true });
245
256
  const confSSR = readConfJson(deployId, 'ssr');
@@ -305,7 +316,8 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
305
316
  shellExec(`cd /home/dd && git clone https://github.com/designmodo/html-website-templates.git`);
306
317
  if (!fs.existsSync(`${rootClientPath}/index.php`)) {
307
318
  fs.copySync(`/home/dd/html-website-templates/${publicClientId.split('-publicClientId-')[1]}`, rootClientPath);
308
- shellExec(`cd ${rootClientPath} && git init && git add . && git commit -m "Base template implementation"`);
319
+ Underpost.repo.initLocalRepo({ path: rootClientPath });
320
+ shellExec(`cd ${rootClientPath} && git add . && git commit -m "Base template implementation"`);
309
321
  // git remote add origin git@github.com:<username>/<repo>.git
310
322
  fs.writeFileSync(`${rootClientPath}/.git/.htaccess`, `Deny from all`, 'utf8');
311
323
  }
@@ -373,17 +385,14 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
373
385
  client,
374
386
  directory,
375
387
  disabledRebuild,
376
- minifyBuild,
377
388
  db,
378
389
  redirect,
379
390
  apis,
380
- iconsBuild,
381
- docsBuild,
382
391
  apiBaseProxyPath,
383
392
  apiBaseHost,
384
393
  ttiLoadTimeLimit,
385
394
  singleReplica,
386
- offlineBuild,
395
+ docs,
387
396
  } = confServer[host][path];
388
397
  if (singleReplica) continue;
389
398
  if (!confClient[client]) confClient[client] = {};
@@ -397,9 +406,10 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
397
406
  const rootClientPath = directory ? directory : `${publicPath}/${host}${path}`;
398
407
  const port = newInstance(currentPort);
399
408
  const publicClientId = publicRef ? publicRef : client;
400
- const fullBuildEnabled = !confServer[host][path].liteBuild && !enableLiveRebuild;
409
+ const fullBuildEnabled = options.fullBuild && !enableLiveRebuild;
401
410
  // const baseHost = process.env.NODE_ENV === 'production' ? `https://${host}` : `http://localhost:${port}`;
402
411
  const baseHost = process.env.NODE_ENV === 'production' ? `https://${host}` : ``;
412
+ const minifyBuild = process.env.NODE_ENV === 'production';
403
413
  // ''; // process.env.NODE_ENV === 'production' ? `https://${host}` : ``;
404
414
  currentPort++;
405
415
 
@@ -421,7 +431,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
421
431
  rootClientPath,
422
432
  acmeChallengeFullPath,
423
433
  publicClientId,
424
- iconsBuild,
434
+ iconsBuild: options.iconsBuild,
425
435
  metadata,
426
436
  publicCopyNonExistingFiles,
427
437
  });
@@ -437,19 +447,15 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
437
447
 
438
448
  if (enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath)) continue;
439
449
 
440
- const jsSrc = componentFormatted(
441
- await srcFormatted(fs.readFileSync(jsSrcPath, 'utf8')),
442
- module,
450
+ const jsSrc = await transformClientJs(jsSrcPath, {
443
451
  dists,
444
- path,
445
- 'components',
452
+ proxyPath: path,
453
+ basePath: 'components',
454
+ module,
446
455
  baseHost,
447
- );
448
- fs.writeFileSync(
449
- jsPublicPath,
450
- minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
451
- 'utf8',
452
- );
456
+ minify: minifyBuild,
457
+ });
458
+ fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
453
459
  }
454
460
  }
455
461
 
@@ -463,19 +469,15 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
463
469
  const jsPublicPath = `${rootClientPath}/services/${module}/${module}.service.js`;
464
470
  if (enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath)) continue;
465
471
 
466
- let jsSrc = componentFormatted(
467
- await srcFormatted(fs.readFileSync(jsSrcPath, 'utf8')),
468
- module,
472
+ const jsSrc = await transformClientJs(jsSrcPath, {
469
473
  dists,
470
- path,
471
- 'services',
474
+ proxyPath: path,
475
+ basePath: 'services',
476
+ module,
472
477
  baseHost,
473
- );
474
- fs.writeFileSync(
475
- jsPublicPath,
476
- minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
477
- 'utf8',
478
- );
478
+ minify: minifyBuild,
479
+ });
480
+ fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
479
481
  }
480
482
  }
481
483
 
@@ -485,19 +487,15 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
485
487
  const jsPublicPath = `${rootClientPath}/services/${module}/${module}.management.js`;
486
488
  if (enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath)) continue;
487
489
 
488
- const jsSrc = componentFormatted(
489
- await srcFormatted(fs.readFileSync(jsSrcPath, 'utf8')),
490
- module,
490
+ const jsSrc = await transformClientJs(jsSrcPath, {
491
491
  dists,
492
- path,
493
- 'services',
492
+ proxyPath: path,
493
+ basePath: 'services',
494
+ module,
494
495
  baseHost,
495
- );
496
- fs.writeFileSync(
497
- jsPublicPath,
498
- minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
499
- 'utf8',
500
- );
496
+ minify: minifyBuild,
497
+ });
498
+ fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
501
499
  }
502
500
  }
503
501
  }
@@ -515,13 +513,9 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
515
513
  const jsPublicPath = `${rootClientPath}/sw.js`;
516
514
 
517
515
  if (!(enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath))) {
518
- const jsSrc = viewFormatted(await srcFormatted(fs.readFileSync(jsSrcPath, 'utf8')), dists, path, baseHost);
516
+ const jsSrc = await transformClientJs(jsSrcPath, { dists, proxyPath: path, baseHost, minify: minifyBuild });
519
517
 
520
- fs.writeFileSync(
521
- jsPublicPath,
522
- minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
523
- 'utf8',
524
- );
518
+ fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
525
519
  }
526
520
 
527
521
  if (
@@ -541,18 +535,14 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
541
535
 
542
536
  logger.info('View build', buildPath);
543
537
 
544
- const jsSrc = viewFormatted(
545
- await srcFormatted(fs.readFileSync(`./src/client/${view.client}.index.js`, 'utf8')),
538
+ const jsSrc = await transformClientJs(`./src/client/${view.client}.index.js`, {
546
539
  dists,
547
- path,
540
+ proxyPath: path,
548
541
  baseHost,
549
- );
542
+ minify: minifyBuild,
543
+ });
550
544
 
551
- fs.writeFileSync(
552
- `${buildPath}${buildId}.js`,
553
- minifyBuild || process.env.NODE_ENV === 'production' ? UglifyJS.minify(jsSrc).code : jsSrc,
554
- 'utf8',
555
- );
545
+ fs.writeFileSync(`${buildPath}${buildId}.js`, jsSrc, 'utf8');
556
546
  const title = metadata.title ? metadata.title : title;
557
547
 
558
548
  const canonicalURL = `https://${host}${path}${
@@ -689,7 +679,7 @@ const buildClient = async (options = { liveClientBuildPaths: [], instances: [],
689
679
 
690
680
  fs.writeFileSync(
691
681
  `${buildPath}index.html`,
692
- minifyBuild || process.env.NODE_ENV === 'production'
682
+ minifyBuild
693
683
  ? await minify(htmlSrc, {
694
684
  minifyCSS: true,
695
685
  minifyJS: true,
@@ -739,7 +729,7 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
739
729
  );
740
730
  }
741
731
 
742
- if (fullBuildEnabled && !enableLiveRebuild && docsBuild) {
732
+ if (fullBuildEnabled && docs) {
743
733
  await buildDocs({
744
734
  host,
745
735
  path,
@@ -749,13 +739,14 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
749
739
  publicClientId,
750
740
  rootClientPath,
751
741
  packageData,
742
+ docs,
752
743
  });
753
744
  }
754
745
 
755
746
  if (client) {
756
747
  let PRE_CACHED_RESOURCES = [];
757
748
 
758
- if (views && offlineBuild && fs.existsSync(`${rootClientPath}/sw.js`)) {
749
+ if (views && fs.existsSync(`${rootClientPath}/sw.js`)) {
759
750
  PRE_CACHED_RESOURCES = await fs.readdir(rootClientPath, { recursive: true });
760
751
  PRE_CACHED_RESOURCES = views
761
752
  .map((view) => `${path === '/' ? '' : path}${view.path}`)
@@ -774,7 +765,7 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
774
765
  const htmlSrc = Render({
775
766
  title: page.title,
776
767
  ssrPath,
777
- ssrHeadComponents: '',
768
+ ssrHeadComponents: '<base target="_top">',
778
769
  ssrBodyComponents: SsrComponent(),
779
770
  renderPayload: {
780
771
  apiBaseProxyPath,
@@ -802,7 +793,7 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
802
793
 
803
794
  fs.writeFileSync(
804
795
  buildHtmlPath,
805
- minifyBuild || process.env.NODE_ENV === 'production'
796
+ minifyBuild
806
797
  ? await minify(htmlSrc, {
807
798
  minifyCSS: true,
808
799
  minifyJS: true,