cyberia 3.2.5 → 3.2.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/engine-cyberia.cd.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -2
- package/CHANGELOG.md +351 -1
- package/CLI-HELP.md +40 -13
- package/Dockerfile +0 -4
- package/README.md +242 -497
- package/bin/build.js +19 -5
- package/bin/cyberia.js +1149 -240
- package/bin/deploy.js +570 -1
- package/bin/file.js +6 -0
- package/bin/index.js +1149 -240
- package/bin/vs.js +1 -1
- package/conf.js +67 -89
- package/deployment.yaml +4 -222
- package/hardhat/package-lock.json +32 -32
- package/hardhat/package.json +3 -3
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -2
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +4 -222
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +10 -118
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +23 -14
- package/proxy.yaml +10 -118
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +18 -18
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +7 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +76 -21
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +13 -13
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +11 -11
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +16 -16
- package/src/api/cyberia-entity/cyberia-entity.controller.js +10 -10
- package/src/api/cyberia-entity/cyberia-entity.service.js +10 -10
- package/src/api/cyberia-instance/cyberia-fallback-world.js +19 -209
- package/src/api/cyberia-instance/cyberia-instance.controller.js +14 -14
- package/src/api/cyberia-instance/cyberia-instance.model.js +3 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +22 -57
- package/src/api/cyberia-instance/cyberia-portal-connector.js +20 -246
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +10 -10
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +216 -55
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +4 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +18 -14
- package/src/api/cyberia-map/cyberia-map.controller.js +10 -10
- package/src/api/cyberia-map/cyberia-map.service.js +10 -10
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +12 -12
- package/src/api/ipfs/ipfs.model.js +4 -13
- package/src/api/ipfs/ipfs.service.js +14 -28
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.service.js +12 -12
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +3 -20
- package/src/cli/cluster.js +61 -14
- package/src/cli/db.js +47 -2
- package/src/cli/deploy.js +67 -35
- package/src/cli/fs.js +79 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +26 -1
- package/src/cli/release.js +57 -1
- package/src/cli/repository.js +69 -31
- package/src/cli/run.js +415 -36
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Cryptokoyn.index.js +18 -21
- package/src/client/CyberiaPortal.index.js +19 -23
- package/src/client/Default.index.js +21 -33
- package/src/client/Itemledger.index.js +20 -26
- package/src/client/Underpost.index.js +19 -23
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +1 -1
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +42 -63
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +69 -91
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +25 -18
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +462 -178
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +57 -57
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cyberia/InstanceEngineCyberia.js +141 -60
- package/src/client/components/cyberia/MapEngineCyberia.js +691 -214
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1204 -94
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +196 -298
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +102 -102
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +305 -61
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +57 -57
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +6 -4
- package/src/client/components/itemledger/LogOutItemledger.js +6 -4
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +88 -88
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +6 -4
- package/src/client/components/underpost/LogOutUnderpost.js +6 -4
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +17 -49
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +10 -16
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +5 -5
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +10 -16
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +6 -6
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +12 -18
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +10 -16
- package/src/client/services/cyberia-map/cyberia-map.management.js +6 -6
- package/src/client/services/cyberia-map/cyberia-map.service.js +12 -18
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +5 -5
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +12 -18
- package/src/client/services/object-layer/object-layer.management.js +12 -12
- package/src/client/services/object-layer/object-layer.service.js +20 -26
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +5 -5
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +179 -67
- package/src/index.js +1 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +5 -4
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +22 -0
- package/src/server/ipfs-client.js +232 -91
- package/src/server/object-layer.js +1 -6
- package/src/server/process.js +13 -27
- package/src/server/semantic-layer-generator-floor.js +11 -51
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +41 -171
- package/src/server/semantic-layer-generator.js +122 -14
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +17 -3
- package/src/server/valkey.js +141 -235
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -68
- package/jsdoc.json +0 -68
- package/src/api/object-layer/README.md +0 -672
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -62
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/grpc/cyberia/OFF_CHAIN_ECONOMY.md +0 -305
- package/src/grpc/cyberia/README.md +0 -326
|
@@ -324,59 +324,56 @@ const buildApiDocs = async ({
|
|
|
324
324
|
};
|
|
325
325
|
|
|
326
326
|
/**
|
|
327
|
-
* Builds JSDoc
|
|
327
|
+
* Builds API documentation using TypeDoc (generates a modern static site from JSDoc-annotated JS).
|
|
328
|
+
* Config is read from the base typedoc JSON, merged with runtime values, written to a temporary
|
|
329
|
+
* file, and deleted after the build — the base config file is never mutated on disk.
|
|
328
330
|
* @function buildJsDocs
|
|
329
331
|
* @memberof clientBuildDocs
|
|
330
|
-
* @param {Object} options -
|
|
332
|
+
* @param {Object} options - TypeDoc build options
|
|
331
333
|
* @param {string} options.host - The hostname for the documentation
|
|
332
334
|
* @param {string} options.path - The base path for the documentation
|
|
333
335
|
* @param {Object} options.metadata - Metadata for the documentation
|
|
334
|
-
* @param {string} options.publicClientId - Client ID used to resolve the
|
|
336
|
+
* @param {string} options.publicClientId - Client ID used to resolve the references directory
|
|
335
337
|
* @param {Object} options.docs - Documentation config from server conf
|
|
336
|
-
* @param {string} options.docs.jsJsonPath - Path to the
|
|
338
|
+
* @param {string} options.docs.jsJsonPath - Path to the base typedoc JSON config file
|
|
339
|
+
* @param {string} options.docsDestination - Resolved output path for the generated docs
|
|
337
340
|
*/
|
|
338
|
-
const buildJsDocs = async ({ host, path, metadata = {}, publicClientId, docs }) => {
|
|
341
|
+
const buildJsDocs = async ({ host, path, metadata = {}, publicClientId, docs, docsDestination }) => {
|
|
339
342
|
const logger = loggerFactory(import.meta);
|
|
340
343
|
|
|
341
|
-
const
|
|
342
|
-
if (!fs.existsSync(
|
|
343
|
-
logger.warn('
|
|
344
|
+
const typedocConfigPath = docs.jsJsonPath;
|
|
345
|
+
if (!fs.existsSync(typedocConfigPath)) {
|
|
346
|
+
logger.warn('typedoc config not found, skipping', typedocConfigPath);
|
|
344
347
|
return;
|
|
345
348
|
}
|
|
346
|
-
const
|
|
347
|
-
logger.info('using
|
|
349
|
+
const baseConfig = JSON.parse(fs.readFileSync(typedocConfigPath, 'utf8'));
|
|
350
|
+
logger.info('using typedoc config', typedocConfigPath);
|
|
348
351
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
// Build runtime config in memory — never mutate the base config file
|
|
353
|
+
// tsconfig must be absolute so TypeDoc resolves it regardless of where the
|
|
354
|
+
// tmp config file is located on disk.
|
|
355
|
+
const runtimeConfig = {
|
|
356
|
+
...baseConfig,
|
|
357
|
+
tsconfig: fs.realpathSync(baseConfig.tsconfig || './tsconfig.docs.json'),
|
|
358
|
+
out: docsDestination,
|
|
359
|
+
name: metadata?.title || baseConfig.name,
|
|
360
|
+
favicon: `./public/${host}${path === '/' ? '/' : `${path}/`}favicon.ico`,
|
|
361
|
+
};
|
|
354
362
|
|
|
363
|
+
// Include extra reference documents as TypeDoc document pages
|
|
364
|
+
// TypeDoc 0.28+: option is `projectDocuments`, not `documents`
|
|
355
365
|
if (Array.isArray(docs.references) && docs.references.length > 0) {
|
|
356
|
-
|
|
357
|
-
|
|
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
|
-
}
|
|
363
|
-
}
|
|
366
|
+
runtimeConfig.projectDocuments = docs.references.filter((p) => fs.existsSync(p));
|
|
367
|
+
if (runtimeConfig.projectDocuments.length > 0) logger.info('typedoc documents', runtimeConfig.projectDocuments);
|
|
364
368
|
}
|
|
365
369
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
jsDocsConfig.opts.theme_opts.sections.push('Tutorials');
|
|
370
|
-
}
|
|
371
|
-
logger.info('build jsdoc tutorials', tutorialsPath);
|
|
372
|
-
} else {
|
|
373
|
-
delete jsDocsConfig.opts.tutorials;
|
|
374
|
-
}
|
|
370
|
+
const tmpConfigPath = `.typedoc.tmp.json`;
|
|
371
|
+
fs.writeFileSync(tmpConfigPath, JSON.stringify(runtimeConfig, null, 2), 'utf8');
|
|
372
|
+
logger.warn('build typedoc view', docsDestination);
|
|
375
373
|
|
|
376
|
-
|
|
377
|
-
logger.warn('build jsdoc view', jsDocsConfig.opts.destination);
|
|
374
|
+
shellExec(`node_modules/.bin/typedoc --options ${tmpConfigPath}`, { silent: true });
|
|
378
375
|
|
|
379
|
-
|
|
376
|
+
fs.removeSync(tmpConfigPath);
|
|
380
377
|
};
|
|
381
378
|
|
|
382
379
|
/**
|
|
@@ -384,17 +381,13 @@ const buildJsDocs = async ({ host, path, metadata = {}, publicClientId, docs })
|
|
|
384
381
|
* @function buildCoverage
|
|
385
382
|
* @memberof clientBuildDocs
|
|
386
383
|
* @param {Object} options - Coverage build options
|
|
387
|
-
* @param {string} options.host - The hostname for the coverage
|
|
388
|
-
* @param {string} options.path - The base path for the coverage
|
|
389
384
|
* @param {Object} options.docs - Documentation config from server conf
|
|
390
|
-
* @param {string} options.docs.coveragePath - Directory where
|
|
385
|
+
* @param {string} options.docs.coveragePath - Directory where coverage reports are generated
|
|
386
|
+
* @param {string} options.docsDestination - Resolved output path where docs were built
|
|
391
387
|
*/
|
|
392
|
-
const buildCoverage = async ({
|
|
388
|
+
const buildCoverage = async ({ docs, docsDestination }) => {
|
|
393
389
|
const logger = loggerFactory(import.meta);
|
|
394
|
-
const
|
|
395
|
-
const jsDocsConfig = JSON.parse(fs.readFileSync(jsDocSourcePath, 'utf8'));
|
|
396
|
-
const coveragePath = docs.coveragePath;
|
|
397
|
-
const coverageOutputDir = docs.coverageOutputDir || 'coverage';
|
|
390
|
+
const { coveragePath, coverageOutputDir = 'coverage' } = docs;
|
|
398
391
|
|
|
399
392
|
const coverageOutputPath = `${coveragePath}/coverage`;
|
|
400
393
|
if (!fs.existsSync(coverageOutputPath)) {
|
|
@@ -412,7 +405,7 @@ const buildCoverage = async ({ host, path, docs }) => {
|
|
|
412
405
|
}
|
|
413
406
|
|
|
414
407
|
if (fs.existsSync(coverageOutputPath) && fs.readdirSync(coverageOutputPath).length > 0) {
|
|
415
|
-
const coverageBuildPath = `${
|
|
408
|
+
const coverageBuildPath = `${docsDestination}${coverageOutputDir}`;
|
|
416
409
|
fs.mkdirSync(coverageBuildPath, { recursive: true });
|
|
417
410
|
// Hardhat 3 outputs HTML to coverage/html/; Hardhat 2 / c8 output directly to coverage/
|
|
418
411
|
const coverageHtmlSubdir = `${coverageOutputPath}/html`;
|
|
@@ -453,8 +446,14 @@ const buildDocs = async ({
|
|
|
453
446
|
packageData,
|
|
454
447
|
docs,
|
|
455
448
|
}) => {
|
|
456
|
-
|
|
457
|
-
|
|
449
|
+
const pathPrefix = path === '/' ? '/' : `${path}/`;
|
|
450
|
+
// TypeDoc output is versioned: served at /docs/engine/{version}/
|
|
451
|
+
const version = (packageData?.version || '').replace(/^v/, '');
|
|
452
|
+
const jsDocsDestination = `./public/${host}${pathPrefix}docs/engine/${version}/`;
|
|
453
|
+
// Coverage output at /docs/coverage/ (or /docs/{coverageOutputDir}/)
|
|
454
|
+
const coverageBaseDestination = `./public/${host}${pathPrefix}docs/`;
|
|
455
|
+
await buildJsDocs({ host, path, metadata, publicClientId, docs, docsDestination: jsDocsDestination });
|
|
456
|
+
await buildCoverage({ docs, docsDestination: coverageBaseDestination });
|
|
458
457
|
await buildApiDocs({
|
|
459
458
|
host,
|
|
460
459
|
path,
|
|
@@ -38,6 +38,8 @@ import { ssrFactory } from './ssr.js';
|
|
|
38
38
|
* @memberof clientBuild
|
|
39
39
|
*/
|
|
40
40
|
const copyNonExistingFiles = (src, dest) => {
|
|
41
|
+
if (dir.basename(src) === '.git') return;
|
|
42
|
+
|
|
41
43
|
// Ensure source exists
|
|
42
44
|
if (!fs.existsSync(src)) {
|
|
43
45
|
throw new Error(`Source directory does not exist: ${src}`);
|
|
@@ -74,6 +76,224 @@ const copyNonExistingFiles = (src, dest) => {
|
|
|
74
76
|
}
|
|
75
77
|
};
|
|
76
78
|
|
|
79
|
+
const splitFileByMb = ({ filePath, partSizeMb, logger }) => {
|
|
80
|
+
const partSizeBytes = Math.floor(Number(partSizeMb) * 1024 * 1024);
|
|
81
|
+
if (!Number.isFinite(partSizeBytes) || partSizeBytes <= 0) {
|
|
82
|
+
throw new Error(`Invalid --split value: ${partSizeMb}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Clean ALL stale part files (any naming variant) before writing new ones
|
|
86
|
+
const zipDir = dir.dirname(filePath);
|
|
87
|
+
const zipBase = dir.basename(filePath);
|
|
88
|
+
if (fs.existsSync(zipDir)) {
|
|
89
|
+
fs.readdirSync(zipDir)
|
|
90
|
+
.filter((name) => name.startsWith(`${zipBase}.part`) || name.startsWith(`${zipBase}-part`))
|
|
91
|
+
.forEach((name) => fs.removeSync(dir.join(zipDir, name)));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
95
|
+
const partPaths = [];
|
|
96
|
+
|
|
97
|
+
for (let offset = 0, partIndex = 0; offset < fileBuffer.length; offset += partSizeBytes, partIndex++) {
|
|
98
|
+
const partBuffer = fileBuffer.subarray(offset, offset + partSizeBytes);
|
|
99
|
+
const partPath = `${filePath}.part${String(partIndex + 1).padStart(3, '0')}`;
|
|
100
|
+
fs.writeFileSync(partPath, partBuffer);
|
|
101
|
+
partPaths.push(partPath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
logger.warn('split zip', {
|
|
105
|
+
filePath,
|
|
106
|
+
partSizeMb: Number(partSizeMb),
|
|
107
|
+
parts: partPaths.length,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return partPaths;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const getZipPartPaths = (zipPath) => {
|
|
114
|
+
const zipDir = dir.dirname(zipPath);
|
|
115
|
+
const zipBase = dir.basename(zipPath);
|
|
116
|
+
const partPrefixDot = `${zipBase}.part`;
|
|
117
|
+
const partPrefixDash = `${zipBase}-part`;
|
|
118
|
+
|
|
119
|
+
const parsePartIndex = (rawSuffix) => {
|
|
120
|
+
// Strip optional .zip suffix added by pull/download (e.g. '001.zip' → '001')
|
|
121
|
+
const digits = rawSuffix.replace(/\.zip$/i, '');
|
|
122
|
+
return /^\d+$/.test(digits) ? Number(digits) : NaN;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const getPartIndex = (name) => {
|
|
126
|
+
if (name.startsWith(partPrefixDot)) return parsePartIndex(name.slice(partPrefixDot.length));
|
|
127
|
+
if (name.startsWith(partPrefixDash)) return parsePartIndex(name.slice(partPrefixDash.length));
|
|
128
|
+
return NaN;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return fs
|
|
132
|
+
.readdirSync(zipDir)
|
|
133
|
+
.filter((name) => Number.isFinite(getPartIndex(name)))
|
|
134
|
+
.sort((a, b) => getPartIndex(a) - getPartIndex(b))
|
|
135
|
+
.map((name) => dir.join(zipDir, name));
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const resolveClientBuildZip = (buildPrefix) => {
|
|
139
|
+
const normalizedPrefix = buildPrefix.replace(/\.zip(?:[.-]part\d+|[.-]part\*)?$/, '').replace(/[.-]part\*$/, '');
|
|
140
|
+
const candidatePrefixes = uniqueArray([
|
|
141
|
+
normalizedPrefix,
|
|
142
|
+
normalizedPrefix.endsWith('-') ? normalizedPrefix : `${normalizedPrefix}-`,
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
for (const prefix of candidatePrefixes) {
|
|
146
|
+
const zipPath = `${prefix}.zip`;
|
|
147
|
+
if (fs.existsSync(zipPath)) {
|
|
148
|
+
return {
|
|
149
|
+
buildPrefix: prefix,
|
|
150
|
+
zipPath,
|
|
151
|
+
partPaths: [],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const partPaths = fs.existsSync(dir.dirname(zipPath)) ? getZipPartPaths(zipPath) : [];
|
|
156
|
+
if (partPaths.length > 0) {
|
|
157
|
+
return {
|
|
158
|
+
buildPrefix: prefix,
|
|
159
|
+
zipPath,
|
|
160
|
+
partPaths,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const searchDir = dir.dirname(normalizedPrefix);
|
|
166
|
+
const prefixBase = dir.basename(normalizedPrefix);
|
|
167
|
+
if (!fs.existsSync(searchDir)) {
|
|
168
|
+
throw new Error(`Build directory not found: ${searchDir}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const matches = uniqueArray(
|
|
172
|
+
fs
|
|
173
|
+
.readdirSync(searchDir)
|
|
174
|
+
.filter((name) => name.startsWith(prefixBase) && /\.zip(?:[.-]part\d+)?$/.test(name))
|
|
175
|
+
.map((name) => name.replace(/[.-]part\d+$/, '')),
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
if (matches.length === 1) {
|
|
179
|
+
const zipPath = dir.join(searchDir, matches[0]);
|
|
180
|
+
const partPaths = getZipPartPaths(zipPath);
|
|
181
|
+
return {
|
|
182
|
+
buildPrefix: zipPath.replace(/\.zip$/, ''),
|
|
183
|
+
zipPath,
|
|
184
|
+
partPaths,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (matches.length > 1) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`Multiple build zip matches found for '${buildPrefix}': ${matches.join(', ')}. Use a more specific --unzip path.`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
throw new Error(`No build zip or split parts found for: ${buildPrefix}`);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Merges split ZIP parts back into a single ZIP file.
|
|
199
|
+
* @param {object} options
|
|
200
|
+
* @param {string} options.buildPrefix - The build prefix path (e.g. build/underpost.net/underpost.net-).
|
|
201
|
+
* @param {object} options.logger - Logger instance.
|
|
202
|
+
* @returns {{ zipPath: string, partPaths: string[], mergedBytes: number }}
|
|
203
|
+
*/
|
|
204
|
+
const mergeClientBuildZip = ({ buildPrefix, logger }) => {
|
|
205
|
+
// Normalize to get the zip path, then look for parts directly (bypassing resolveClientBuildZip
|
|
206
|
+
// which prefers an existing monolithic zip over parts).
|
|
207
|
+
const normalizedPrefix = buildPrefix.replace(/\.zip(?:[.-]part\d+)?$/, '').replace(/[-.]$/, '') + '-';
|
|
208
|
+
const candidatePrefixes = uniqueArray([buildPrefix, buildPrefix.endsWith('-') ? buildPrefix : `${buildPrefix}-`]);
|
|
209
|
+
|
|
210
|
+
let zipPath;
|
|
211
|
+
let partPaths = [];
|
|
212
|
+
|
|
213
|
+
for (const prefix of candidatePrefixes) {
|
|
214
|
+
const candidate = prefix.endsWith('.zip') ? prefix : `${prefix}.zip`;
|
|
215
|
+
const parts = getZipPartPaths(candidate);
|
|
216
|
+
if (parts.length > 0) {
|
|
217
|
+
zipPath = candidate;
|
|
218
|
+
partPaths = parts;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (partPaths.length === 0) {
|
|
224
|
+
// Fall back to resolveClientBuildZip for the zipPath
|
|
225
|
+
const resolved = resolveClientBuildZip(buildPrefix);
|
|
226
|
+
zipPath = resolved.zipPath;
|
|
227
|
+
logger.warn('merge-zip: no split parts found, nothing to merge', { buildPrefix, zipPath });
|
|
228
|
+
return { zipPath, partPaths, mergedBytes: 0 };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// For each part, extract raw bytes: if the part file is a Cloudinary wrapper zip
|
|
232
|
+
// (downloaded via pull without --omit-unzip or with --omit-unzip keeping the .zip),
|
|
233
|
+
// extract the inner entry rather than using the wrapper bytes.
|
|
234
|
+
const readPartBytes = (partPath) => {
|
|
235
|
+
const rawBytes = fs.readFileSync(partPath);
|
|
236
|
+
// Check for ZIP magic bytes (PK\x03\x04)
|
|
237
|
+
if (rawBytes[0] === 0x50 && rawBytes[1] === 0x4b && rawBytes[2] === 0x03 && rawBytes[3] === 0x04) {
|
|
238
|
+
try {
|
|
239
|
+
const wrapperZip = new AdmZip(rawBytes);
|
|
240
|
+
const entries = wrapperZip.getEntries();
|
|
241
|
+
// The inner entry is the original part file (without the outer .zip wrapper)
|
|
242
|
+
const partBase = dir.basename(partPath).replace(/\.zip$/i, '');
|
|
243
|
+
const entry = entries.find((e) => e.entryName === partBase || e.entryName.endsWith('/' + partBase));
|
|
244
|
+
if (entry) {
|
|
245
|
+
return entry.getData();
|
|
246
|
+
}
|
|
247
|
+
// Fallback: single-entry archive
|
|
248
|
+
if (entries.length === 1) {
|
|
249
|
+
return entries[0].getData();
|
|
250
|
+
}
|
|
251
|
+
} catch (_) {
|
|
252
|
+
// Not a valid zip or extraction failed — use raw bytes
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return rawBytes;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const mergedBuffer = Buffer.concat(partPaths.map(readPartBytes));
|
|
259
|
+
fs.writeFileSync(zipPath, mergedBuffer);
|
|
260
|
+
|
|
261
|
+
logger.warn('merge-zip: merged split parts into zip', {
|
|
262
|
+
zipPath,
|
|
263
|
+
parts: partPaths.length,
|
|
264
|
+
mergedBytes: mergedBuffer.length,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return { zipPath, partPaths, mergedBytes: mergedBuffer.length };
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const unzipClientBuild = ({ buildPrefix, logger }) => {
|
|
271
|
+
const { zipPath, partPaths, buildPrefix: resolvedBuildPrefix } = resolveClientBuildZip(buildPrefix);
|
|
272
|
+
const outputPath = resolvedBuildPrefix.replace(/-$/, '');
|
|
273
|
+
|
|
274
|
+
fs.removeSync(outputPath);
|
|
275
|
+
fs.mkdirSync(outputPath, { recursive: true });
|
|
276
|
+
|
|
277
|
+
const zip =
|
|
278
|
+
partPaths.length > 0
|
|
279
|
+
? new AdmZip(Buffer.concat(partPaths.map((partPath) => fs.readFileSync(partPath))))
|
|
280
|
+
: new AdmZip(zipPath);
|
|
281
|
+
|
|
282
|
+
zip.extractAllTo(outputPath, true);
|
|
283
|
+
|
|
284
|
+
logger.warn('unzip build', {
|
|
285
|
+
source: partPaths.length > 0 ? partPaths : [zipPath],
|
|
286
|
+
outputPath,
|
|
287
|
+
splitParts: partPaths.length,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
outputPath,
|
|
292
|
+
zipPath,
|
|
293
|
+
partPaths,
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
|
|
77
297
|
/** @type {string} Default XSL sitemap template used when no `sitemap` source file exists in the public directory. */
|
|
78
298
|
const defaultSitemapXsl = `<?xml version="1.0" encoding="UTF-8"?>
|
|
79
299
|
<xsl:stylesheet version="1.0"
|
|
@@ -233,6 +453,7 @@ const defaultSitemapXsl = `<?xml version="1.0" encoding="UTF-8"?>
|
|
|
233
453
|
* @param {Array} options.liveClientBuildPaths - List of paths to build incrementally.
|
|
234
454
|
* @param {Array} options.instances - List of instances to build.
|
|
235
455
|
* @param {boolean} options.buildZip - Whether to create zip files of the builds.
|
|
456
|
+
* @param {string|number} options.split - Optional zip split size in MB.
|
|
236
457
|
* @param {boolean} options.fullBuild - Whether to perform a full build.
|
|
237
458
|
* @param {boolean} options.iconsBuild - Whether to build icons.
|
|
238
459
|
* @returns {Promise<void>} - Promise that resolves when the build is complete.
|
|
@@ -245,6 +466,7 @@ const buildClient = async (
|
|
|
245
466
|
liveClientBuildPaths: [],
|
|
246
467
|
instances: [],
|
|
247
468
|
buildZip: false,
|
|
469
|
+
split: '',
|
|
248
470
|
fullBuild: false,
|
|
249
471
|
iconsBuild: false,
|
|
250
472
|
},
|
|
@@ -311,35 +533,18 @@ const buildClient = async (
|
|
|
311
533
|
|
|
312
534
|
buildAcmeChallengePath(acmeChallengeFullPath);
|
|
313
535
|
|
|
314
|
-
if (publicClientId && publicClientId.startsWith('html-website-templates')) {
|
|
315
|
-
if (!fs.existsSync(`/home/dd/html-website-templates/`))
|
|
316
|
-
shellExec(`cd /home/dd && git clone https://github.com/designmodo/html-website-templates.git`);
|
|
317
|
-
if (!fs.existsSync(`${rootClientPath}/index.php`)) {
|
|
318
|
-
fs.copySync(`/home/dd/html-website-templates/${publicClientId.split('-publicClientId-')[1]}`, rootClientPath);
|
|
319
|
-
Underpost.repo.initLocalRepo({ path: rootClientPath });
|
|
320
|
-
shellExec(`cd ${rootClientPath} && git add . && git commit -m "Base template implementation"`);
|
|
321
|
-
// git remote add origin git@github.com:<username>/<repo>.git
|
|
322
|
-
fs.writeFileSync(`${rootClientPath}/.git/.htaccess`, `Deny from all`, 'utf8');
|
|
323
|
-
}
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
536
|
fs.removeSync(rootClientPath);
|
|
328
537
|
|
|
329
538
|
if (fs.existsSync(`./src/client/public/${publicClientId}`)) {
|
|
330
539
|
if (iconsBuild === true) await buildIcons({ publicClientId, metadata });
|
|
331
540
|
|
|
332
|
-
fs.copySync(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
filter: function (name) {
|
|
336
|
-
console.log(name);
|
|
337
|
-
return true;
|
|
338
|
-
},
|
|
339
|
-
} */,
|
|
340
|
-
);
|
|
541
|
+
fs.copySync(`./src/client/public/${publicClientId}`, rootClientPath, {
|
|
542
|
+
filter: (sourcePath) => !sourcePath.split(dir.sep).includes('.git'),
|
|
543
|
+
});
|
|
341
544
|
} else if (fs.existsSync(`./engine-private/src/client/public/${publicClientId}`)) {
|
|
342
|
-
fs.copySync(`./engine-private/src/client/public/${publicClientId}`, rootClientPath
|
|
545
|
+
fs.copySync(`./engine-private/src/client/public/${publicClientId}`, rootClientPath, {
|
|
546
|
+
filter: (sourcePath) => !sourcePath.split(dir.sep).includes('.git'),
|
|
547
|
+
});
|
|
343
548
|
}
|
|
344
549
|
if (dists)
|
|
345
550
|
for (const dist of dists) {
|
|
@@ -463,28 +668,18 @@ const buildClient = async (
|
|
|
463
668
|
for (const module of services) {
|
|
464
669
|
if (!fs.existsSync(`${rootClientPath}/services/${module}`))
|
|
465
670
|
fs.mkdirSync(`${rootClientPath}/services/${module}`, { recursive: true });
|
|
671
|
+
const moduleDir = `./src/client/services/${module}`;
|
|
672
|
+
if (!fs.existsSync(moduleDir)) continue;
|
|
466
673
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
674
|
+
const serviceFiles = fs
|
|
675
|
+
.readdirSync(moduleDir)
|
|
676
|
+
.filter((name) => name.endsWith('.service.js') || name.endsWith('.management.js'))
|
|
677
|
+
.sort();
|
|
471
678
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
basePath: 'services',
|
|
476
|
-
module,
|
|
477
|
-
baseHost,
|
|
478
|
-
minify: minifyBuild,
|
|
479
|
-
});
|
|
480
|
-
fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
|
|
481
|
-
}
|
|
482
|
-
}
|
|
679
|
+
for (const serviceFile of serviceFiles) {
|
|
680
|
+
const jsSrcPath = `${moduleDir}/${serviceFile}`;
|
|
681
|
+
const jsPublicPath = `${rootClientPath}/services/${module}/${serviceFile}`;
|
|
483
682
|
|
|
484
|
-
for (const module of services) {
|
|
485
|
-
if (fs.existsSync(`./src/client/services/${module}/${module}.management.js`)) {
|
|
486
|
-
const jsSrcPath = `./src/client/services/${module}/${module}.management.js`;
|
|
487
|
-
const jsPublicPath = `${rootClientPath}/services/${module}/${module}.management.js`;
|
|
488
683
|
if (enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath)) continue;
|
|
489
684
|
|
|
490
685
|
const jsSrc = await transformClientJs(jsSrcPath, {
|
|
@@ -497,6 +692,30 @@ const buildClient = async (
|
|
|
497
692
|
});
|
|
498
693
|
fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
|
|
499
694
|
}
|
|
695
|
+
|
|
696
|
+
// Auto-build guest module files when user module is processed
|
|
697
|
+
if (module === 'user') {
|
|
698
|
+
const guestModuleDir = './src/client/services/user';
|
|
699
|
+
const guestServicePath = `${guestModuleDir}/guest.service.js`;
|
|
700
|
+
if (fs.existsSync(guestServicePath)) {
|
|
701
|
+
if (!fs.existsSync(`${rootClientPath}/services/user`))
|
|
702
|
+
fs.mkdirSync(`${rootClientPath}/services/user`, { recursive: true });
|
|
703
|
+
|
|
704
|
+
const guestJsPublicPath = `${rootClientPath}/services/user/guest.service.js`;
|
|
705
|
+
|
|
706
|
+
if (!enableLiveRebuild || options.liveClientBuildPaths.find((p) => p.srcBuildPath === guestServicePath)) {
|
|
707
|
+
const guestJsSrc = await transformClientJs(guestServicePath, {
|
|
708
|
+
dists,
|
|
709
|
+
proxyPath: path,
|
|
710
|
+
basePath: 'services',
|
|
711
|
+
module: 'user',
|
|
712
|
+
baseHost,
|
|
713
|
+
minify: minifyBuild,
|
|
714
|
+
});
|
|
715
|
+
fs.writeFileSync(guestJsPublicPath, guestJsSrc, 'utf8');
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
500
719
|
}
|
|
501
720
|
}
|
|
502
721
|
|
|
@@ -506,14 +725,18 @@ const buildClient = async (
|
|
|
506
725
|
const Render = await ssrFactory();
|
|
507
726
|
|
|
508
727
|
if (views) {
|
|
509
|
-
const jsSrcPath =
|
|
510
|
-
? `./src/client/sw/${publicClientId}.sw.js`
|
|
511
|
-
: `./src/client/sw/default.sw.js`;
|
|
728
|
+
const jsSrcPath = `./src/client/sw/core.sw.js`;
|
|
512
729
|
|
|
513
730
|
const jsPublicPath = `${rootClientPath}/sw.js`;
|
|
514
731
|
|
|
515
732
|
if (!(enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === jsSrcPath))) {
|
|
516
|
-
const jsSrc = await transformClientJs(jsSrcPath, {
|
|
733
|
+
const jsSrc = await transformClientJs(jsSrcPath, {
|
|
734
|
+
dists,
|
|
735
|
+
proxyPath: path,
|
|
736
|
+
baseHost,
|
|
737
|
+
minify: minifyBuild,
|
|
738
|
+
externalizeBareImports: false,
|
|
739
|
+
});
|
|
517
740
|
|
|
518
741
|
fs.writeFileSync(jsPublicPath, jsSrc, 'utf8');
|
|
519
742
|
}
|
|
@@ -746,16 +969,18 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
|
|
|
746
969
|
if (client) {
|
|
747
970
|
let PRE_CACHED_RESOURCES = [];
|
|
748
971
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
972
|
+
const normalizePrecacheRoutePath = (candidatePath) => {
|
|
973
|
+
const routePath =
|
|
974
|
+
typeof candidatePath === 'string' && candidatePath.trim().length > 0 ? candidatePath.trim() : '/offline';
|
|
975
|
+
const withLeadingSlash = routePath.startsWith('/') ? routePath : `/${routePath}`;
|
|
976
|
+
const withoutTrailingSlash = withLeadingSlash.replace(/\/+$/, '');
|
|
977
|
+
return withoutTrailingSlash.length > 0 ? withoutTrailingSlash : '/';
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
const toPrecacheIndexUrl = (routePath) => {
|
|
981
|
+
const normalizedRoutePath = normalizePrecacheRoutePath(routePath);
|
|
982
|
+
return `${path === '/' ? '' : path}${normalizedRoutePath === '/' ? '' : normalizedRoutePath}/index.html`;
|
|
983
|
+
};
|
|
759
984
|
|
|
760
985
|
for (const pageType of ['offline', 'pages']) {
|
|
761
986
|
if (confSSR[getCapVariableName(client)] && confSSR[getCapVariableName(client)][pageType]) {
|
|
@@ -783,7 +1008,11 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
|
|
|
783
1008
|
rootClientPath[rootClientPath.length - 1] === '/' ? rootClientPath.slice(0, -1) : rootClientPath
|
|
784
1009
|
}${page.path === '/' ? page.path : `${page.path}/`}`;
|
|
785
1010
|
|
|
786
|
-
|
|
1011
|
+
// Install-time precache is intentionally restricted to SSR offline pages.
|
|
1012
|
+
// All other routes/assets are loaded lazily at runtime.
|
|
1013
|
+
if (pageType === 'offline') {
|
|
1014
|
+
PRE_CACHED_RESOURCES.push(toPrecacheIndexUrl(page.path));
|
|
1015
|
+
}
|
|
787
1016
|
|
|
788
1017
|
if (!fs.existsSync(buildPath)) fs.mkdirSync(buildPath, { recursive: true });
|
|
789
1018
|
|
|
@@ -809,13 +1038,47 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
|
|
|
809
1038
|
}
|
|
810
1039
|
|
|
811
1040
|
{
|
|
1041
|
+
const cacheScope = path === '/' ? 'root' : path.replaceAll('/', '_');
|
|
1042
|
+
const ssrClientConf = confSSR[getCapVariableName(client)] || {};
|
|
1043
|
+
const ssrOfflinePages = Array.isArray(ssrClientConf.offline) ? ssrClientConf.offline : [];
|
|
1044
|
+
const normalizeSsrRoutePath = (candidatePath, fallbackPath) => {
|
|
1045
|
+
const value =
|
|
1046
|
+
typeof candidatePath === 'string' && candidatePath.trim().length > 0
|
|
1047
|
+
? candidatePath.trim()
|
|
1048
|
+
: fallbackPath;
|
|
1049
|
+
const withLeadingSlash = value.startsWith('/') ? value : `/${value}`;
|
|
1050
|
+
const withoutTrailingSlash = withLeadingSlash.replace(/\/+$/, '');
|
|
1051
|
+
return withoutTrailingSlash.length > 0 ? withoutTrailingSlash : '/';
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
const offlineSsrPage =
|
|
1055
|
+
ssrOfflinePages.find(
|
|
1056
|
+
(page) =>
|
|
1057
|
+
page?.client === 'NoNetworkConnection' ||
|
|
1058
|
+
/no\s*network|offline/i.test(`${page?.title || ''} ${page?.client || ''} ${page?.path || ''}`),
|
|
1059
|
+
) || ssrOfflinePages[0];
|
|
1060
|
+
|
|
1061
|
+
const maintenanceSsrPage =
|
|
1062
|
+
ssrOfflinePages.find(
|
|
1063
|
+
(page) =>
|
|
1064
|
+
page?.client === 'Maintenance' ||
|
|
1065
|
+
/maintenance/i.test(`${page?.title || ''} ${page?.client || ''} ${page?.path || ''}`),
|
|
1066
|
+
) || ssrOfflinePages[1];
|
|
1067
|
+
|
|
1068
|
+
const offlinePath = normalizeSsrRoutePath(offlineSsrPage?.path, '/offline');
|
|
1069
|
+
const maintenancePath = normalizeSsrRoutePath(maintenanceSsrPage?.path, '/maintenance');
|
|
1070
|
+
|
|
812
1071
|
const renderPayload = {
|
|
813
1072
|
PRE_CACHED_RESOURCES: uniqueArray(PRE_CACHED_RESOURCES),
|
|
814
1073
|
PROXY_PATH: path,
|
|
1074
|
+
CACHE_PREFIX: `engine-core-v3-${cacheScope}`,
|
|
1075
|
+
OFFLINE_PATH: offlinePath,
|
|
1076
|
+
MAINTENANCE_PATH: maintenancePath,
|
|
815
1077
|
};
|
|
816
1078
|
fs.writeFileSync(
|
|
817
1079
|
`${rootClientPath}/sw.js`,
|
|
818
1080
|
`self.renderPayload = ${JSONweb(renderPayload)};
|
|
1081
|
+
self.__WB_DISABLE_DEV_LOGS = true;
|
|
819
1082
|
${fs.readFileSync(`${rootClientPath}/sw.js`, 'utf8')}`,
|
|
820
1083
|
'utf8',
|
|
821
1084
|
);
|
|
@@ -838,13 +1101,24 @@ ${fs.readFileSync(`${rootClientPath}/sw.js`, 'utf8')}`,
|
|
|
838
1101
|
}
|
|
839
1102
|
|
|
840
1103
|
const buildId = `${host}-${path.replaceAll('/', '')}`;
|
|
1104
|
+
const zipPath = `./build/${buildId}.zip`;
|
|
841
1105
|
|
|
842
|
-
logger.warn('write zip',
|
|
1106
|
+
logger.warn('write zip', zipPath);
|
|
843
1107
|
|
|
844
|
-
zip.writeZip(
|
|
1108
|
+
zip.writeZip(zipPath);
|
|
1109
|
+
|
|
1110
|
+
if (options.split) {
|
|
1111
|
+
splitFileByMb({
|
|
1112
|
+
filePath: zipPath,
|
|
1113
|
+
partSizeMb: options.split,
|
|
1114
|
+
logger,
|
|
1115
|
+
});
|
|
1116
|
+
fs.removeSync(zipPath);
|
|
1117
|
+
logger.warn('removed original zip after split', { zipPath });
|
|
1118
|
+
}
|
|
845
1119
|
}
|
|
846
1120
|
}
|
|
847
1121
|
}
|
|
848
1122
|
};
|
|
849
1123
|
|
|
850
|
-
export { buildClient, copyNonExistingFiles };
|
|
1124
|
+
export { buildClient, copyNonExistingFiles, unzipClientBuild, mergeClientBuildZip };
|