@ecopages/core 0.2.0-alpha.4 → 0.2.0-alpha.6
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/README.md +213 -12
- package/package.json +100 -188
- package/src/adapters/README.md +39 -0
- package/src/adapters/bun/hmr-manager.test.ts +267 -0
- package/src/adapters/bun/hmr-manager.ts +181 -68
- package/src/adapters/bun/index.ts +1 -2
- package/src/adapters/bun/server-adapter.ts +41 -34
- package/src/adapters/bun/server-lifecycle.ts +40 -70
- package/src/adapters/index.ts +1 -1
- package/src/adapters/node/bootstrap-dependency-resolver.test.ts +282 -0
- package/src/adapters/node/bootstrap-dependency-resolver.ts +301 -0
- package/src/adapters/node/index.ts +7 -0
- package/src/adapters/node/node-client-bridge.test.ts +198 -0
- package/src/adapters/node/node-hmr-manager.test.ts +322 -0
- package/src/adapters/node/node-hmr-manager.ts +208 -116
- package/src/adapters/node/runtime-adapter.test.ts +868 -0
- package/src/adapters/node/runtime-adapter.ts +439 -0
- package/src/adapters/node/server-adapter.ts +31 -104
- package/src/adapters/node/static-content-server.test.ts +60 -0
- package/src/adapters/node/static-content-server.ts +36 -0
- package/src/adapters/node/write-runtime-manifest.ts +38 -0
- package/src/adapters/shared/api-response.test.ts +97 -0
- package/src/{define-api-handler.ts → adapters/shared/define-api-handler.ts} +1 -1
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +381 -0
- package/src/adapters/shared/explicit-static-route-matcher.ts +7 -1
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +90 -0
- package/src/adapters/shared/file-route-middleware-pipeline.ts +6 -2
- package/src/adapters/shared/fs-server-response-factory.test.ts +187 -0
- package/src/adapters/shared/fs-server-response-matcher.test.ts +286 -0
- package/src/adapters/shared/fs-server-response-matcher.ts +17 -10
- package/src/adapters/shared/hmr-entrypoint-registrar.ts +149 -0
- package/src/adapters/shared/hmr-html-response.ts +52 -0
- package/src/adapters/shared/hmr-manager.contract.test.ts +196 -0
- package/src/adapters/shared/hmr-manager.dispatch.test.ts +220 -0
- package/src/adapters/shared/render-context.test.ts +146 -0
- package/src/adapters/shared/render-context.ts +21 -6
- package/src/adapters/shared/runtime-bootstrap.ts +79 -0
- package/src/adapters/shared/server-adapter.test.ts +77 -0
- package/src/adapters/shared/server-adapter.ts +51 -4
- package/src/adapters/shared/server-route-handler.test.ts +110 -0
- package/src/adapters/shared/server-route-handler.ts +5 -18
- package/src/adapters/shared/server-static-builder.test.ts +316 -0
- package/src/adapters/shared/server-static-builder.ts +92 -8
- package/src/build/README.md +101 -0
- package/src/build/build-adapter-serialization.test.ts +268 -0
- package/src/build/build-adapter.test.ts +815 -0
- package/src/build/build-adapter.ts +235 -6
- package/src/build/build-manifest.ts +54 -0
- package/src/build/dev-build-coordinator.ts +221 -0
- package/src/build/esbuild-build-adapter.ts +132 -83
- package/src/build/runtime-build-executor.ts +34 -0
- package/src/build/runtime-specifier-alias-plugin.test.ts +43 -0
- package/src/build/runtime-specifier-alias-plugin.ts +58 -0
- package/src/config/README.md +33 -0
- package/src/config/config-builder.test.ts +410 -0
- package/src/config/config-builder.ts +281 -49
- package/src/constants.ts +15 -0
- package/src/declarations.d.ts +18 -13
- package/src/eco/README.md +70 -16
- package/src/eco/component-render-context.ts +39 -17
- package/src/eco/eco.test.ts +678 -0
- package/src/eco/eco.ts +29 -8
- package/src/eco/eco.types.ts +20 -1
- package/src/eco/eco.utils.test.ts +124 -0
- package/src/eco/global-injector-map.test.ts +42 -0
- package/src/eco/lazy-injector-map.test.ts +66 -0
- package/src/eco/module-dependencies.test.ts +30 -0
- package/src/errors/http-error.test.ts +134 -0
- package/src/global/utils.test.ts +12 -0
- package/src/hmr/README.md +26 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-have-HMR-script-injected-in-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
- package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
- package/src/hmr/client/hmr-runtime.ts +38 -7
- package/src/hmr/hmr-strategy.test.ts +124 -0
- package/src/hmr/hmr.postcss.test.e2e.ts +41 -0
- package/src/hmr/hmr.test.e2e.ts +29 -38
- package/src/hmr/strategies/js-hmr-strategy.test.ts +335 -0
- package/src/hmr/strategies/js-hmr-strategy.ts +115 -115
- package/src/index.ts +1 -1
- package/src/integrations/ghtml/ghtml-renderer.test.ts +63 -0
- package/src/integrations/ghtml/ghtml-renderer.ts +4 -1
- package/src/internal-types.ts +39 -19
- package/src/plugins/README.md +34 -0
- package/src/plugins/alias-resolver-plugin.test.ts +41 -0
- package/src/plugins/alias-resolver-plugin.ts +21 -3
- package/src/plugins/eco-component-meta-plugin.test.ts +380 -0
- package/src/plugins/eco-component-meta-plugin.ts +10 -3
- package/src/plugins/integration-plugin.test.ts +111 -0
- package/src/plugins/integration-plugin.ts +45 -3
- package/src/plugins/processor.test.ts +148 -0
- package/src/plugins/processor.ts +22 -2
- package/src/plugins/runtime-capability.ts +14 -0
- package/src/public-types.ts +73 -16
- package/src/route-renderer/GRAPH.md +16 -20
- package/src/route-renderer/README.md +8 -21
- package/src/route-renderer/component-graph/component-graph-executor.test.ts +41 -0
- package/src/route-renderer/component-graph/component-graph.test.ts +63 -0
- package/src/route-renderer/component-graph/component-marker.test.ts +73 -0
- package/src/route-renderer/component-graph/component-reference.ts +29 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +135 -0
- package/src/route-renderer/{marker-graph-resolver.ts → component-graph/marker-graph-resolver.ts} +11 -9
- package/src/route-renderer/orchestration/integration-renderer.test.ts +936 -0
- package/src/route-renderer/{integration-renderer.ts → orchestration/integration-renderer.ts} +113 -19
- package/src/route-renderer/orchestration/render-execution.service.test.ts +97 -0
- package/src/route-renderer/{render-execution.service.ts → orchestration/render-execution.service.ts} +109 -37
- package/src/route-renderer/orchestration/render-preparation.service.test.ts +235 -0
- package/src/route-renderer/{render-preparation.service.ts → orchestration/render-preparation.service.ts} +127 -9
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +345 -0
- package/src/route-renderer/{dependency-resolver.ts → page-loading/dependency-resolver.ts} +28 -12
- package/src/route-renderer/page-loading/page-module-loader.test.ts +96 -0
- package/src/route-renderer/{page-module-loader.ts → page-loading/page-module-loader.ts} +49 -21
- package/src/route-renderer/route-renderer.ts +36 -1
- package/src/router/README.md +26 -0
- package/src/router/client/link-intent.d.ts +53 -0
- package/src/router/client/link-intent.test.browser.ts +51 -0
- package/src/router/client/link-intent.ts +92 -0
- package/src/router/client/navigation-coordinator.test.ts +237 -0
- package/src/router/client/navigation-coordinator.ts +433 -0
- package/src/router/server/fs-router-scanner.test.ts +83 -0
- package/src/router/{fs-router-scanner.ts → server/fs-router-scanner.ts} +12 -10
- package/src/router/server/fs-router.test.ts +214 -0
- package/src/router/{fs-router.ts → server/fs-router.ts} +2 -2
- package/src/services/README.md +29 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +385 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset-processing.service.ts +101 -6
- package/src/services/assets/asset-processing-service/asset.factory.test.ts +63 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/asset.factory.ts +2 -2
- package/src/services/{asset-processing-service → assets/asset-processing-service}/assets.types.ts +2 -1
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +72 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.ts +95 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +67 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.ts +78 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/index.ts +2 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.interface.ts +1 -1
- package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +59 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-processor.ts +11 -5
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/base/base-script-processor.ts +17 -27
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +286 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/file-script.processor.ts +3 -3
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +227 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/node-module-script.processor.ts +5 -4
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +199 -0
- package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/file-stylesheet.processor.ts +4 -1
- package/src/services/assets/browser-bundle.service.test.ts +36 -0
- package/src/services/assets/browser-bundle.service.ts +53 -0
- package/src/services/cache/index.ts +3 -3
- package/src/services/cache/memory-cache-store.test.ts +225 -0
- package/src/services/cache/memory-cache-store.ts +1 -1
- package/src/services/cache/page-cache-service.test.ts +175 -0
- package/src/services/cache/page-cache-service.ts +3 -3
- package/src/services/cache/page-request-cache-coordinator.service.test.ts +79 -0
- package/src/services/{page-request-cache-coordinator.service.ts → cache/page-request-cache-coordinator.service.ts} +9 -6
- package/src/services/html/html-rewriter-provider.service.test.ts +183 -0
- package/src/services/html/html-rewriter-provider.service.ts +103 -0
- package/src/services/html/html-transformer.service.test.ts +378 -0
- package/src/services/html/html-transformer.service.ts +279 -0
- package/src/services/invalidation/development-invalidation.service.test.ts +77 -0
- package/src/services/invalidation/development-invalidation.service.ts +261 -0
- package/src/services/module-loading/app-server-module-transpiler.service.ts +52 -0
- package/src/services/module-loading/page-module-import.service.test.ts +253 -0
- package/src/services/module-loading/page-module-import.service.ts +200 -0
- package/src/services/module-loading/server-loader.service.test.ts +161 -0
- package/src/services/module-loading/server-loader.service.ts +130 -0
- package/src/services/module-loading/server-module-transpiler.service.test.ts +115 -0
- package/src/services/module-loading/server-module-transpiler.service.ts +105 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +95 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.ts +101 -0
- package/src/services/runtime-state/dev-graph.service.ts +217 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.ts +136 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.ts +96 -0
- package/src/services/runtime-state/server-invalidation-state.service.ts +68 -0
- package/src/services/validation/schema-validation-service.test.ts +223 -0
- package/src/services/{schema-validation-service.ts → validation/schema-validation-service.ts} +1 -1
- package/src/static-site-generator/README.md +26 -0
- package/src/static-site-generator/static-site-generator.test.ts +307 -0
- package/src/static-site-generator/static-site-generator.ts +109 -6
- package/src/utils/deep-merge.test.ts +114 -0
- package/src/utils/invariant.test.ts +22 -0
- package/src/utils/path-utils.test.ts +15 -0
- package/src/utils/resolve-work-dir.ts +45 -0
- package/src/utils/server-utils.test.ts +38 -0
- package/src/watchers/project-watcher.integration.test.ts +337 -0
- package/src/watchers/project-watcher.test-helpers.ts +1 -1
- package/src/watchers/project-watcher.test.ts +678 -0
- package/src/watchers/project-watcher.ts +130 -111
- package/CHANGELOG.md +0 -91
- package/src/adapters/abstract/application-adapter.d.ts +0 -168
- package/src/adapters/abstract/application-adapter.js +0 -109
- package/src/adapters/abstract/router-adapter.d.ts +0 -26
- package/src/adapters/abstract/router-adapter.js +0 -5
- package/src/adapters/abstract/server-adapter.d.ts +0 -69
- package/src/adapters/abstract/server-adapter.js +0 -15
- package/src/adapters/bun/client-bridge.d.ts +0 -34
- package/src/adapters/bun/client-bridge.js +0 -48
- package/src/adapters/bun/create-app.d.ts +0 -60
- package/src/adapters/bun/create-app.js +0 -117
- package/src/adapters/bun/define-api-handler.d.ts +0 -61
- package/src/adapters/bun/define-api-handler.js +0 -15
- package/src/adapters/bun/define-api-handler.ts +0 -114
- package/src/adapters/bun/hmr-manager.d.ts +0 -85
- package/src/adapters/bun/hmr-manager.js +0 -240
- package/src/adapters/bun/index.d.ts +0 -3
- package/src/adapters/bun/index.js +0 -8
- package/src/adapters/bun/server-adapter.d.ts +0 -155
- package/src/adapters/bun/server-adapter.js +0 -368
- package/src/adapters/bun/server-lifecycle.d.ts +0 -52
- package/src/adapters/bun/server-lifecycle.js +0 -120
- package/src/adapters/index.d.ts +0 -6
- package/src/adapters/index.js +0 -14
- package/src/adapters/node/create-app.d.ts +0 -21
- package/src/adapters/node/create-app.js +0 -143
- package/src/adapters/node/index.d.ts +0 -4
- package/src/adapters/node/index.js +0 -8
- package/src/adapters/node/node-client-bridge.d.ts +0 -26
- package/src/adapters/node/node-client-bridge.js +0 -66
- package/src/adapters/node/node-hmr-manager.d.ts +0 -63
- package/src/adapters/node/node-hmr-manager.js +0 -237
- package/src/adapters/node/server-adapter.d.ts +0 -190
- package/src/adapters/node/server-adapter.js +0 -420
- package/src/adapters/node/static-content-server.d.ts +0 -24
- package/src/adapters/node/static-content-server.js +0 -166
- package/src/adapters/shared/api-response.d.ts +0 -52
- package/src/adapters/shared/api-response.js +0 -96
- package/src/adapters/shared/application-adapter.d.ts +0 -18
- package/src/adapters/shared/application-adapter.js +0 -90
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +0 -38
- package/src/adapters/shared/explicit-static-route-matcher.js +0 -100
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +0 -65
- package/src/adapters/shared/file-route-middleware-pipeline.js +0 -98
- package/src/adapters/shared/fs-server-response-factory.d.ts +0 -19
- package/src/adapters/shared/fs-server-response-factory.js +0 -97
- package/src/adapters/shared/fs-server-response-matcher.d.ts +0 -71
- package/src/adapters/shared/fs-server-response-matcher.js +0 -155
- package/src/adapters/shared/render-context.d.ts +0 -14
- package/src/adapters/shared/render-context.js +0 -69
- package/src/adapters/shared/server-adapter.d.ts +0 -87
- package/src/adapters/shared/server-adapter.js +0 -353
- package/src/adapters/shared/server-route-handler.d.ts +0 -89
- package/src/adapters/shared/server-route-handler.js +0 -120
- package/src/adapters/shared/server-static-builder.d.ts +0 -38
- package/src/adapters/shared/server-static-builder.js +0 -46
- package/src/build/build-adapter.d.ts +0 -74
- package/src/build/build-adapter.js +0 -54
- package/src/build/build-types.d.ts +0 -57
- package/src/build/build-types.js +0 -0
- package/src/build/esbuild-build-adapter.d.ts +0 -69
- package/src/build/esbuild-build-adapter.js +0 -390
- package/src/config/config-builder.d.ts +0 -227
- package/src/config/config-builder.js +0 -392
- package/src/constants.d.ts +0 -32
- package/src/constants.js +0 -21
- package/src/create-app.d.ts +0 -17
- package/src/create-app.js +0 -66
- package/src/define-api-handler.d.ts +0 -25
- package/src/define-api-handler.js +0 -15
- package/src/dev/sc-server.d.ts +0 -30
- package/src/dev/sc-server.js +0 -111
- package/src/eco/component-render-context.d.ts +0 -105
- package/src/eco/component-render-context.js +0 -77
- package/src/eco/eco.d.ts +0 -9
- package/src/eco/eco.js +0 -110
- package/src/eco/eco.types.d.ts +0 -170
- package/src/eco/eco.types.js +0 -0
- package/src/eco/eco.utils.d.ts +0 -40
- package/src/eco/eco.utils.js +0 -40
- package/src/eco/global-injector-map.d.ts +0 -16
- package/src/eco/global-injector-map.js +0 -80
- package/src/eco/lazy-injector-map.d.ts +0 -8
- package/src/eco/lazy-injector-map.js +0 -70
- package/src/eco/module-dependencies.d.ts +0 -18
- package/src/eco/module-dependencies.js +0 -49
- package/src/errors/http-error.d.ts +0 -31
- package/src/errors/http-error.js +0 -50
- package/src/errors/index.d.ts +0 -2
- package/src/errors/index.js +0 -4
- package/src/errors/locals-access-error.d.ts +0 -4
- package/src/errors/locals-access-error.js +0 -9
- package/src/global/app-logger.d.ts +0 -2
- package/src/global/app-logger.js +0 -6
- package/src/hmr/client/hmr-runtime.d.ts +0 -10
- package/src/hmr/client/hmr-runtime.js +0 -86
- package/src/hmr/hmr-strategy.d.ts +0 -159
- package/src/hmr/hmr-strategy.js +0 -29
- package/src/hmr/hmr.test.e2e.d.ts +0 -1
- package/src/hmr/hmr.test.e2e.js +0 -50
- package/src/hmr/strategies/default-hmr-strategy.d.ts +0 -43
- package/src/hmr/strategies/default-hmr-strategy.js +0 -34
- package/src/hmr/strategies/js-hmr-strategy.d.ts +0 -136
- package/src/hmr/strategies/js-hmr-strategy.js +0 -188
- package/src/index.browser.d.ts +0 -3
- package/src/index.browser.js +0 -4
- package/src/index.d.ts +0 -5
- package/src/index.js +0 -10
- package/src/integrations/ghtml/ghtml-renderer.d.ts +0 -15
- package/src/integrations/ghtml/ghtml-renderer.js +0 -60
- package/src/integrations/ghtml/ghtml.plugin.d.ts +0 -20
- package/src/integrations/ghtml/ghtml.plugin.js +0 -21
- package/src/internal-types.d.ts +0 -200
- package/src/internal-types.js +0 -0
- package/src/plugins/alias-resolver-plugin.d.ts +0 -2
- package/src/plugins/alias-resolver-plugin.js +0 -39
- package/src/plugins/eco-component-meta-plugin.d.ts +0 -95
- package/src/plugins/eco-component-meta-plugin.js +0 -157
- package/src/plugins/integration-plugin.d.ts +0 -102
- package/src/plugins/integration-plugin.js +0 -100
- package/src/plugins/processor.d.ts +0 -82
- package/src/plugins/processor.js +0 -122
- package/src/public-types.d.ts +0 -1098
- package/src/public-types.js +0 -0
- package/src/route-renderer/component-graph-executor.d.ts +0 -32
- package/src/route-renderer/component-graph-executor.js +0 -31
- package/src/route-renderer/component-graph.d.ts +0 -42
- package/src/route-renderer/component-graph.js +0 -72
- package/src/route-renderer/component-marker.d.ts +0 -52
- package/src/route-renderer/component-marker.js +0 -46
- package/src/route-renderer/dependency-resolver.d.ts +0 -24
- package/src/route-renderer/dependency-resolver.js +0 -428
- package/src/route-renderer/html-post-processing.service.d.ts +0 -40
- package/src/route-renderer/html-post-processing.service.js +0 -86
- package/src/route-renderer/html-post-processing.service.ts +0 -103
- package/src/route-renderer/integration-renderer.d.ts +0 -339
- package/src/route-renderer/integration-renderer.js +0 -526
- package/src/route-renderer/marker-graph-resolver.d.ts +0 -76
- package/src/route-renderer/marker-graph-resolver.js +0 -93
- package/src/route-renderer/page-module-loader.d.ts +0 -61
- package/src/route-renderer/page-module-loader.js +0 -102
- package/src/route-renderer/render-execution.service.d.ts +0 -69
- package/src/route-renderer/render-execution.service.js +0 -91
- package/src/route-renderer/render-preparation.service.d.ts +0 -112
- package/src/route-renderer/render-preparation.service.js +0 -243
- package/src/route-renderer/route-renderer.d.ts +0 -26
- package/src/route-renderer/route-renderer.js +0 -68
- package/src/router/fs-router-scanner.d.ts +0 -41
- package/src/router/fs-router-scanner.js +0 -155
- package/src/router/fs-router.d.ts +0 -26
- package/src/router/fs-router.js +0 -100
- package/src/services/asset-processing-service/asset-processing.service.d.ts +0 -41
- package/src/services/asset-processing-service/asset-processing.service.js +0 -250
- package/src/services/asset-processing-service/asset.factory.d.ts +0 -17
- package/src/services/asset-processing-service/asset.factory.js +0 -82
- package/src/services/asset-processing-service/assets.types.d.ts +0 -88
- package/src/services/asset-processing-service/assets.types.js +0 -0
- package/src/services/asset-processing-service/index.d.ts +0 -3
- package/src/services/asset-processing-service/index.js +0 -3
- package/src/services/asset-processing-service/processor.interface.d.ts +0 -22
- package/src/services/asset-processing-service/processor.interface.js +0 -6
- package/src/services/asset-processing-service/processor.registry.d.ts +0 -8
- package/src/services/asset-processing-service/processor.registry.js +0 -15
- package/src/services/asset-processing-service/processors/base/base-processor.d.ts +0 -24
- package/src/services/asset-processing-service/processors/base/base-processor.js +0 -59
- package/src/services/asset-processing-service/processors/base/base-script-processor.d.ts +0 -16
- package/src/services/asset-processing-service/processors/base/base-script-processor.js +0 -80
- package/src/services/asset-processing-service/processors/index.d.ts +0 -5
- package/src/services/asset-processing-service/processors/index.js +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/script/content-script.processor.js +0 -57
- package/src/services/asset-processing-service/processors/script/file-script.processor.d.ts +0 -8
- package/src/services/asset-processing-service/processors/script/file-script.processor.js +0 -76
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.d.ts +0 -7
- package/src/services/asset-processing-service/processors/script/node-module-script.processor.js +0 -74
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +0 -5
- package/src/services/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +0 -25
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +0 -9
- package/src/services/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +0 -63
- package/src/services/cache/cache.types.d.ts +0 -107
- package/src/services/cache/cache.types.js +0 -0
- package/src/services/cache/index.d.ts +0 -7
- package/src/services/cache/index.js +0 -7
- package/src/services/cache/memory-cache-store.d.ts +0 -42
- package/src/services/cache/memory-cache-store.js +0 -98
- package/src/services/cache/page-cache-service.d.ts +0 -70
- package/src/services/cache/page-cache-service.js +0 -152
- package/src/services/html-transformer.service.d.ts +0 -50
- package/src/services/html-transformer.service.js +0 -163
- package/src/services/html-transformer.service.ts +0 -217
- package/src/services/page-module-import.service.d.ts +0 -37
- package/src/services/page-module-import.service.js +0 -88
- package/src/services/page-module-import.service.ts +0 -129
- package/src/services/page-request-cache-coordinator.service.d.ts +0 -75
- package/src/services/page-request-cache-coordinator.service.js +0 -107
- package/src/services/schema-validation-service.d.ts +0 -122
- package/src/services/schema-validation-service.js +0 -101
- package/src/services/validation/standard-schema.types.d.ts +0 -65
- package/src/services/validation/standard-schema.types.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +0 -57
- package/src/static-site-generator/static-site-generator.js +0 -272
- package/src/utils/css.d.ts +0 -1
- package/src/utils/css.js +0 -7
- package/src/utils/deep-merge.d.ts +0 -14
- package/src/utils/deep-merge.js +0 -32
- package/src/utils/hash.d.ts +0 -1
- package/src/utils/hash.js +0 -7
- package/src/utils/html.d.ts +0 -1
- package/src/utils/html.js +0 -4
- package/src/utils/invariant.d.ts +0 -5
- package/src/utils/invariant.js +0 -11
- package/src/utils/locals-utils.d.ts +0 -15
- package/src/utils/locals-utils.js +0 -24
- package/src/utils/parse-cli-args.d.ts +0 -24
- package/src/utils/parse-cli-args.js +0 -47
- package/src/utils/path-utils.module.d.ts +0 -5
- package/src/utils/path-utils.module.js +0 -14
- package/src/utils/runtime.d.ts +0 -11
- package/src/utils/runtime.js +0 -40
- package/src/utils/server-utils.module.d.ts +0 -19
- package/src/utils/server-utils.module.js +0 -56
- package/src/watchers/project-watcher.d.ts +0 -125
- package/src/watchers/project-watcher.js +0 -265
- package/src/watchers/project-watcher.test-helpers.d.ts +0 -4
- package/src/watchers/project-watcher.test-helpers.js +0 -52
- /package/src/route-renderer/{component-graph-executor.ts → component-graph/component-graph-executor.ts} +0 -0
- /package/src/route-renderer/{component-graph.ts → component-graph/component-graph.ts} +0 -0
- /package/src/route-renderer/{component-marker.ts → component-graph/component-marker.ts} +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processor.registry.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/index.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/script/content-script.processor.ts +0 -0
- /package/src/services/{asset-processing-service → assets/asset-processing-service}/processors/stylesheet/content-stylesheet.processor.ts +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import * as v from 'valibot';
|
|
4
|
+
import { type } from 'arktype';
|
|
5
|
+
import { SchemaValidationService } from './schema-validation-service.ts';
|
|
6
|
+
|
|
7
|
+
describe('SchemaValidationService', () => {
|
|
8
|
+
const service = new SchemaValidationService();
|
|
9
|
+
|
|
10
|
+
describe('Zod validation', () => {
|
|
11
|
+
test('validates body with Zod schema', async () => {
|
|
12
|
+
const schema = z.object({
|
|
13
|
+
title: z.string().min(1),
|
|
14
|
+
count: z.number(),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const result = await service.validateRequest(
|
|
18
|
+
{ body: { title: 'Hello', count: 42 } },
|
|
19
|
+
{ body: schema as unknown as Parameters<typeof service.validateRequest>[1]['body'] },
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
expect(result.success).toBe(true);
|
|
23
|
+
expect(result.data?.body).toEqual({ title: 'Hello', count: 42 });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('rejects invalid body with Zod schema', async () => {
|
|
27
|
+
const schema = z.object({
|
|
28
|
+
title: z.string().min(1),
|
|
29
|
+
count: z.number(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const result = await service.validateRequest(
|
|
33
|
+
{ body: { title: '', count: 'not-a-number' } },
|
|
34
|
+
{ body: schema as unknown as Parameters<typeof service.validateRequest>[1]['body'] },
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(result.success).toBe(false);
|
|
38
|
+
expect(result.errors).toBeDefined();
|
|
39
|
+
expect(result.errors!.length).toBeGreaterThan(0);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('Valibot validation', () => {
|
|
44
|
+
test('validates query with Valibot schema', async () => {
|
|
45
|
+
const schema = v.object({
|
|
46
|
+
page: v.string(),
|
|
47
|
+
limit: v.string(),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const result = await service.validateRequest(
|
|
51
|
+
{ query: { page: '1', limit: '10' } },
|
|
52
|
+
{ query: schema as unknown as Parameters<typeof service.validateRequest>[1]['query'] },
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
expect(result.success).toBe(true);
|
|
56
|
+
expect(result.data?.query).toEqual({ page: '1', limit: '10' });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('rejects invalid query with Valibot schema', async () => {
|
|
60
|
+
const schema = v.object({
|
|
61
|
+
page: v.pipe(v.string(), v.minLength(1)),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const result = await service.validateRequest(
|
|
65
|
+
{ query: { page: '' } },
|
|
66
|
+
{ query: schema as unknown as Parameters<typeof service.validateRequest>[1]['query'] },
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(result.success).toBe(false);
|
|
70
|
+
expect(result.errors).toBeDefined();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('ArkType validation', () => {
|
|
75
|
+
test('validates headers with ArkType schema', async () => {
|
|
76
|
+
const schema = type({
|
|
77
|
+
'content-type': 'string',
|
|
78
|
+
authorization: 'string',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const result = await service.validateRequest(
|
|
82
|
+
{
|
|
83
|
+
headers: {
|
|
84
|
+
'content-type': 'application/json',
|
|
85
|
+
authorization: 'Bearer token',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{ headers: schema as unknown as Parameters<typeof service.validateRequest>[1]['headers'] },
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
expect(result.success).toBe(true);
|
|
92
|
+
expect(result.data?.headers).toEqual({
|
|
93
|
+
'content-type': 'application/json',
|
|
94
|
+
authorization: 'Bearer token',
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('rejects invalid headers with ArkType schema', async () => {
|
|
99
|
+
const schema = type({
|
|
100
|
+
'content-type': 'string',
|
|
101
|
+
'x-custom': 'string>5',
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const result = await service.validateRequest(
|
|
105
|
+
{
|
|
106
|
+
headers: {
|
|
107
|
+
'content-type': 'application/json',
|
|
108
|
+
'x-custom': 'ab',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{ headers: schema as unknown as Parameters<typeof service.validateRequest>[1]['headers'] },
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
expect(result.success).toBe(false);
|
|
115
|
+
expect(result.errors).toBeDefined();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('Combined validation', () => {
|
|
120
|
+
test('validates multiple sources at once', async () => {
|
|
121
|
+
const bodySchema = z.object({
|
|
122
|
+
title: z.string(),
|
|
123
|
+
});
|
|
124
|
+
const querySchema = v.object({
|
|
125
|
+
format: v.string(),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const result = await service.validateRequest(
|
|
129
|
+
{
|
|
130
|
+
body: { title: 'Post Title' },
|
|
131
|
+
query: { format: 'json' },
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
body: bodySchema as unknown as Parameters<typeof service.validateRequest>[1]['body'],
|
|
135
|
+
query: querySchema as unknown as Parameters<typeof service.validateRequest>[1]['query'],
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
expect(result.success).toBe(true);
|
|
140
|
+
expect(result.data?.body).toEqual({ title: 'Post Title' });
|
|
141
|
+
expect(result.data?.query).toEqual({ format: 'json' });
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('validates route params with schema', async () => {
|
|
145
|
+
const paramsSchema = z.object({
|
|
146
|
+
id: z.coerce.number().int(),
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const result = await service.validateRequest(
|
|
150
|
+
{
|
|
151
|
+
params: { id: '42' },
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
params: paramsSchema as unknown as Parameters<typeof service.validateRequest>[1]['params'],
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
expect(result.success).toBe(true);
|
|
159
|
+
expect(result.data?.params).toEqual({ id: 42 });
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test('aggregates errors from multiple sources', async () => {
|
|
163
|
+
const bodySchema = z.object({
|
|
164
|
+
title: z.string().min(5),
|
|
165
|
+
});
|
|
166
|
+
const querySchema = v.object({
|
|
167
|
+
page: v.pipe(v.string(), v.regex(/^\d+$/)),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const result = await service.validateRequest(
|
|
171
|
+
{
|
|
172
|
+
body: { title: 'ab' },
|
|
173
|
+
query: { page: 'invalid' },
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
body: bodySchema as unknown as Parameters<typeof service.validateRequest>[1]['body'],
|
|
177
|
+
query: querySchema as unknown as Parameters<typeof service.validateRequest>[1]['query'],
|
|
178
|
+
},
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
expect(result.success).toBe(false);
|
|
182
|
+
expect(result.errors).toBeDefined();
|
|
183
|
+
expect(result.errors!.length).toBeGreaterThan(1);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('Edge cases', () => {
|
|
188
|
+
test('handles missing optional schemas', async () => {
|
|
189
|
+
const result = await service.validateRequest({ body: { data: 'test' } }, {});
|
|
190
|
+
|
|
191
|
+
expect(result.success).toBe(true);
|
|
192
|
+
expect(result.data).toEqual({});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('handles undefined source data', async () => {
|
|
196
|
+
const schema = z.object({ name: z.string() });
|
|
197
|
+
|
|
198
|
+
const result = await service.validateRequest(
|
|
199
|
+
{ body: undefined },
|
|
200
|
+
{ body: schema as unknown as Parameters<typeof service.validateRequest>[1]['body'] },
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
expect(result.success).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('catches validation exceptions', async () => {
|
|
207
|
+
const brokenSchema = {
|
|
208
|
+
'~standard': {
|
|
209
|
+
version: 1,
|
|
210
|
+
vendor: 'test',
|
|
211
|
+
validate: () => {
|
|
212
|
+
throw new Error('Validation crashed');
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
} as const;
|
|
216
|
+
|
|
217
|
+
const result = await service.validateRequest({ body: { test: true } }, { body: brokenSchema });
|
|
218
|
+
|
|
219
|
+
expect(result.success).toBe(false);
|
|
220
|
+
expect(result.errors?.[0]?.message).toBe('Validation crashed');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Static Site Generation
|
|
2
|
+
|
|
3
|
+
This directory contains the static-build execution path used when Ecopages renders pages ahead of time.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The static-site generator reuses the same app-owned config, route matching, and rendering services that development and preview flows use, but drives them in a build-oriented loop.
|
|
8
|
+
|
|
9
|
+
It is responsible for:
|
|
10
|
+
|
|
11
|
+
- enumerating renderable routes
|
|
12
|
+
- rendering static outputs through the normal rendering pipeline
|
|
13
|
+
- respecting route-level constraints such as cache policy and unsupported dynamic server-only paths
|
|
14
|
+
|
|
15
|
+
## Design Rule
|
|
16
|
+
|
|
17
|
+
Static generation should follow the same ownership model as runtime rendering.
|
|
18
|
+
|
|
19
|
+
That means it should reuse:
|
|
20
|
+
|
|
21
|
+
- built app config
|
|
22
|
+
- route matching
|
|
23
|
+
- render orchestration
|
|
24
|
+
- asset processing
|
|
25
|
+
|
|
26
|
+
It should not invent a parallel rendering stack just for build mode.
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { describe, expect, test, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { fileSystem } from '@ecopages/file-system';
|
|
3
|
+
import { StaticSiteGenerator } from './static-site-generator';
|
|
4
|
+
import type { EcoPagesAppConfig } from '../internal-types';
|
|
5
|
+
import type { FSRouter } from '../router/server/fs-router';
|
|
6
|
+
import type { RouteRendererFactory } from '../route-renderer/route-renderer';
|
|
7
|
+
import { appLogger } from '../global/app-logger.ts';
|
|
8
|
+
import { PageModuleImportService } from '../services/module-loading/page-module-import.service';
|
|
9
|
+
import { DEFAULT_ECOPAGES_WORK_DIR } from '../constants.ts';
|
|
10
|
+
|
|
11
|
+
const originalEnsureDir = fileSystem.ensureDir;
|
|
12
|
+
const originalWrite = fileSystem.write;
|
|
13
|
+
|
|
14
|
+
const createMockConfig = (overrides: Partial<EcoPagesAppConfig> = {}): EcoPagesAppConfig =>
|
|
15
|
+
({
|
|
16
|
+
rootDir: '/test/project',
|
|
17
|
+
distDir: 'dist',
|
|
18
|
+
workDir: DEFAULT_ECOPAGES_WORK_DIR,
|
|
19
|
+
srcDir: 'src',
|
|
20
|
+
robotsTxt: {
|
|
21
|
+
preferences: {
|
|
22
|
+
'*': ['/admin', '/private'],
|
|
23
|
+
Googlebot: ['/no-google'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
absolutePaths: {
|
|
27
|
+
distDir: '/test/project/dist',
|
|
28
|
+
workDir: '/test/project/.eco',
|
|
29
|
+
} as EcoPagesAppConfig['absolutePaths'],
|
|
30
|
+
integrations: [],
|
|
31
|
+
...overrides,
|
|
32
|
+
}) as EcoPagesAppConfig;
|
|
33
|
+
|
|
34
|
+
describe('StaticSiteGenerator', () => {
|
|
35
|
+
let ensureDirMock: any;
|
|
36
|
+
let writeMock: any;
|
|
37
|
+
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
ensureDirMock = vi.fn(() => {});
|
|
40
|
+
writeMock = vi.fn(() => {});
|
|
41
|
+
fileSystem.ensureDir = ensureDirMock;
|
|
42
|
+
fileSystem.write = writeMock;
|
|
43
|
+
vi.spyOn(PageModuleImportService.prototype, 'importModule').mockResolvedValue({
|
|
44
|
+
default: Object.assign(() => null, { cache: 'static' }),
|
|
45
|
+
});
|
|
46
|
+
vi.spyOn(appLogger, 'warn').mockReturnValue(appLogger);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
fileSystem.ensureDir = originalEnsureDir;
|
|
51
|
+
fileSystem.write = originalWrite;
|
|
52
|
+
vi.restoreAllMocks();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('constructor', () => {
|
|
56
|
+
test('should create instance with appConfig', () => {
|
|
57
|
+
const config = createMockConfig();
|
|
58
|
+
const ssg = new StaticSiteGenerator({ appConfig: config });
|
|
59
|
+
expect(ssg.appConfig).toBe(config);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('isRootDir', () => {
|
|
64
|
+
test('should return true for root path /', () => {
|
|
65
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
66
|
+
expect(ssg.isRootDir('/')).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('should return false for nested path /foo/bar', () => {
|
|
70
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
71
|
+
expect(ssg.isRootDir('/foo/bar')).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('should return false for deeply nested paths', () => {
|
|
75
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
76
|
+
expect(ssg.isRootDir('/a/b/c/d')).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('should return null (falsy) for paths without slashes', () => {
|
|
80
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
81
|
+
expect(ssg.isRootDir('no-slashes')).toBeFalsy();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('getDirectories', () => {
|
|
86
|
+
test('should return empty array for root-level routes', () => {
|
|
87
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
88
|
+
const dirs = ssg.getDirectories(['/about', '/contact']);
|
|
89
|
+
expect(dirs).toEqual([]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('should extract directories from nested routes', () => {
|
|
93
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
94
|
+
const dirs = ssg.getDirectories(['/blog/post-1', '/blog/post-2', '/docs/api']);
|
|
95
|
+
expect(dirs).toContain('/blog');
|
|
96
|
+
expect(dirs).toContain('/docs');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('should handle HTTP URLs and extract pathname', () => {
|
|
100
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
101
|
+
const dirs = ssg.getDirectories(['http://localhost:3000/blog/post']);
|
|
102
|
+
expect(dirs).toContain('/blog');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('should deduplicate directories', () => {
|
|
106
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
107
|
+
const dirs = ssg.getDirectories(['/blog/a', '/blog/b', '/blog/c']);
|
|
108
|
+
expect(dirs.filter((d) => d === '/blog').length).toBe(1);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should handle deeply nested paths', () => {
|
|
112
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
113
|
+
const dirs = ssg.getDirectories(['/a/b/c/page']);
|
|
114
|
+
expect(dirs).toContain('/a/b/c');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('generateRobotsTxt', () => {
|
|
119
|
+
test('should generate robots.txt with preferences from config', () => {
|
|
120
|
+
const config = createMockConfig();
|
|
121
|
+
const ssg = new StaticSiteGenerator({ appConfig: config });
|
|
122
|
+
|
|
123
|
+
ssg.generateRobotsTxt();
|
|
124
|
+
|
|
125
|
+
expect(ensureDirMock).toHaveBeenCalledWith('/test/project/dist');
|
|
126
|
+
expect(writeMock).toHaveBeenCalledWith('/test/project/dist/robots.txt', expect.any(String));
|
|
127
|
+
|
|
128
|
+
const writtenContent = writeMock.mock.calls[0][1] as string;
|
|
129
|
+
expect(writtenContent).toContain('user-agent: *');
|
|
130
|
+
expect(writtenContent).toContain('disallow: /admin');
|
|
131
|
+
expect(writtenContent).toContain('disallow: /private');
|
|
132
|
+
expect(writtenContent).toContain('user-agent: Googlebot');
|
|
133
|
+
expect(writtenContent).toContain('disallow: /no-google');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('should handle empty preferences', () => {
|
|
137
|
+
const config = createMockConfig({
|
|
138
|
+
robotsTxt: { preferences: {} },
|
|
139
|
+
});
|
|
140
|
+
const ssg = new StaticSiteGenerator({ appConfig: config });
|
|
141
|
+
|
|
142
|
+
ssg.generateRobotsTxt();
|
|
143
|
+
|
|
144
|
+
expect(writeMock).toHaveBeenCalledWith('/test/project/dist/robots.txt', '');
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('generateStaticPages', () => {
|
|
149
|
+
const createMockRouter = (routes: Record<string, { filePath: string; pathname: string }>) =>
|
|
150
|
+
({
|
|
151
|
+
routes: Object.fromEntries(
|
|
152
|
+
Object.entries(routes).map(([key, value]) => [key, { ...value, kind: 'exact' }]),
|
|
153
|
+
),
|
|
154
|
+
origin: 'http://localhost:3000',
|
|
155
|
+
}) as unknown as FSRouter;
|
|
156
|
+
|
|
157
|
+
test('should filter out dynamic routes containing [', async () => {
|
|
158
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
159
|
+
const Router = createMockRouter({
|
|
160
|
+
'/static': { filePath: '/src/pages/static.ghtml.ts', pathname: '/static' },
|
|
161
|
+
'/dynamic/[id]': { filePath: '/src/pages/dynamic/[id].ghtml.ts', pathname: '/dynamic/[id]' },
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const RendererFactory = {
|
|
165
|
+
createRenderer: vi.fn(() => ({
|
|
166
|
+
createRoute: vi.fn(async () => ({ body: '<html>Static</html>' })),
|
|
167
|
+
})),
|
|
168
|
+
} as unknown as RouteRendererFactory;
|
|
169
|
+
|
|
170
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', RendererFactory);
|
|
171
|
+
|
|
172
|
+
expect(writeMock).toHaveBeenCalledTimes(1);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('should create directories for nested routes', async () => {
|
|
176
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
177
|
+
const Router = createMockRouter({
|
|
178
|
+
'/blog/post': { filePath: '/src/pages/blog/post.ghtml.ts', pathname: '/blog/post' },
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const RendererFactory = {
|
|
182
|
+
createRenderer: vi.fn(() => ({
|
|
183
|
+
createRoute: vi.fn(async () => ({ body: '<html>Blog Post</html>' })),
|
|
184
|
+
})),
|
|
185
|
+
} as unknown as RouteRendererFactory;
|
|
186
|
+
|
|
187
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', RendererFactory);
|
|
188
|
+
|
|
189
|
+
expect(ensureDirMock).toHaveBeenCalled();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('should throw error when routeRendererFactory is missing for render strategy', async () => {
|
|
193
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
194
|
+
const Router = createMockRouter({
|
|
195
|
+
'/page': { filePath: '/src/pages/page.ghtml.ts', pathname: '/page' },
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', undefined);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('should write index.html for root path', async () => {
|
|
202
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
203
|
+
const Router = createMockRouter({
|
|
204
|
+
'/': { filePath: '/src/pages/index.ghtml.ts', pathname: '/' },
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const RendererFactory = {
|
|
208
|
+
createRenderer: vi.fn(() => ({
|
|
209
|
+
createRoute: vi.fn(async () => ({ body: '<html>Home</html>' })),
|
|
210
|
+
})),
|
|
211
|
+
} as unknown as RouteRendererFactory;
|
|
212
|
+
|
|
213
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', RendererFactory);
|
|
214
|
+
|
|
215
|
+
expect(writeMock).toHaveBeenCalledWith(expect.stringContaining('index.html'), '<html>Home</html>');
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test('should handle Buffer content from renderer', async () => {
|
|
219
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
220
|
+
const Router = createMockRouter({
|
|
221
|
+
'/': { filePath: '/src/pages/index.ghtml.ts', pathname: '/' },
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const bufferContent = Buffer.from('<html>Buffer Content</html>');
|
|
225
|
+
const RendererFactory = {
|
|
226
|
+
createRenderer: vi.fn(() => ({
|
|
227
|
+
createRoute: vi.fn(async () => ({ body: bufferContent })),
|
|
228
|
+
})),
|
|
229
|
+
} as unknown as RouteRendererFactory;
|
|
230
|
+
|
|
231
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', RendererFactory);
|
|
232
|
+
|
|
233
|
+
expect(writeMock).toHaveBeenCalledWith(expect.stringContaining('index.html'), bufferContent);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('should skip cache dynamic pages during static generation and log a warning', async () => {
|
|
237
|
+
vi.spyOn(PageModuleImportService.prototype, 'importModule').mockResolvedValue({
|
|
238
|
+
default: Object.assign(() => null, { cache: 'dynamic' }),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
242
|
+
const Router = createMockRouter({
|
|
243
|
+
'/dashboard': { filePath: '/src/pages/dashboard.tsx', pathname: '/dashboard' },
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const RendererFactory = {
|
|
247
|
+
createRenderer: vi.fn(() => ({
|
|
248
|
+
createRoute: vi.fn(async () => ({ body: '<html>Dashboard</html>' })),
|
|
249
|
+
})),
|
|
250
|
+
} as unknown as RouteRendererFactory;
|
|
251
|
+
|
|
252
|
+
await ssg.generateStaticPages(Router, 'http://localhost:3000', RendererFactory);
|
|
253
|
+
|
|
254
|
+
expect(RendererFactory.createRenderer).not.toHaveBeenCalled();
|
|
255
|
+
expect(writeMock).not.toHaveBeenCalled();
|
|
256
|
+
expect(appLogger.warn).toHaveBeenCalledWith(
|
|
257
|
+
"Pages with cache: 'dynamic' are not supported in static generation or preview, so they will be skipped\n",
|
|
258
|
+
'➤ /src/pages/dashboard.tsx',
|
|
259
|
+
);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
describe('run', () => {
|
|
264
|
+
test('should call generateRobotsTxt and generateStaticPages', async () => {
|
|
265
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
266
|
+
const Router = {
|
|
267
|
+
routes: {},
|
|
268
|
+
origin: 'http://localhost:3000',
|
|
269
|
+
} as unknown as FSRouter;
|
|
270
|
+
|
|
271
|
+
await ssg.run({
|
|
272
|
+
router: Router,
|
|
273
|
+
baseUrl: 'http://localhost:3000',
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
expect(ensureDirMock).toHaveBeenCalled();
|
|
277
|
+
expect(writeMock).toHaveBeenCalledWith('/test/project/dist/robots.txt', expect.any(String));
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
test('should skip explicit static routes backed by cache dynamic views', async () => {
|
|
281
|
+
const ssg = new StaticSiteGenerator({ appConfig: createMockConfig() });
|
|
282
|
+
const dynamicView = Object.assign(() => null, { cache: 'dynamic' }) as any;
|
|
283
|
+
|
|
284
|
+
await ssg.run({
|
|
285
|
+
router: {
|
|
286
|
+
routes: {},
|
|
287
|
+
origin: 'http://localhost:3000',
|
|
288
|
+
} as unknown as FSRouter,
|
|
289
|
+
baseUrl: 'http://localhost:3000',
|
|
290
|
+
routeRendererFactory: {
|
|
291
|
+
getRendererByIntegration: vi.fn(),
|
|
292
|
+
} as unknown as RouteRendererFactory,
|
|
293
|
+
staticRoutes: [
|
|
294
|
+
{
|
|
295
|
+
path: '/dashboard',
|
|
296
|
+
loader: async () => ({ default: dynamicView }),
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
expect(appLogger.warn).toHaveBeenCalledWith(
|
|
302
|
+
"Pages with cache: 'dynamic' are not supported in static generation or preview, so they will be skipped\n",
|
|
303
|
+
'➤ /dashboard',
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
});
|