@ecopages/core 0.2.0-alpha.7 → 0.2.0-alpha.8
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/CHANGELOG.md +31 -0
- package/package.json +212 -92
- package/src/adapters/abstract/application-adapter.d.ts +168 -0
- package/src/adapters/abstract/application-adapter.js +109 -0
- package/src/adapters/abstract/router-adapter.d.ts +26 -0
- package/src/adapters/abstract/router-adapter.js +5 -0
- package/src/adapters/abstract/server-adapter.d.ts +69 -0
- package/src/adapters/abstract/server-adapter.js +15 -0
- package/src/adapters/bun/client-bridge.d.ts +34 -0
- package/src/adapters/bun/client-bridge.js +48 -0
- package/src/adapters/bun/create-app.d.ts +60 -0
- package/src/adapters/bun/create-app.js +117 -0
- package/src/adapters/bun/hmr-manager.d.ts +143 -0
- package/src/adapters/bun/hmr-manager.js +334 -0
- package/src/adapters/bun/index.d.ts +2 -0
- package/src/adapters/bun/index.js +8 -0
- package/src/adapters/bun/server-adapter.d.ts +155 -0
- package/src/adapters/bun/server-adapter.js +373 -0
- package/src/adapters/bun/server-lifecycle.d.ts +63 -0
- package/src/adapters/bun/server-lifecycle.js +92 -0
- package/src/adapters/index.d.ts +6 -0
- package/src/adapters/index.js +14 -0
- package/src/adapters/node/bootstrap-dependency-resolver.d.ts +44 -0
- package/src/adapters/node/bootstrap-dependency-resolver.js +172 -0
- package/src/adapters/node/create-app.d.ts +21 -0
- package/src/adapters/node/create-app.js +143 -0
- package/src/adapters/node/index.d.ts +6 -0
- package/src/adapters/node/index.js +11 -0
- package/src/adapters/node/node-client-bridge.d.ts +26 -0
- package/src/adapters/node/node-client-bridge.js +66 -0
- package/src/adapters/node/node-hmr-manager.d.ts +133 -0
- package/src/adapters/node/node-hmr-manager.js +312 -0
- package/src/adapters/node/runtime-adapter.d.ts +46 -0
- package/src/adapters/node/runtime-adapter.js +306 -0
- package/src/adapters/node/server-adapter.d.ts +161 -0
- package/src/adapters/node/server-adapter.js +358 -0
- package/src/adapters/node/static-content-server.d.ts +60 -0
- package/src/adapters/node/static-content-server.js +194 -0
- package/src/adapters/node/write-runtime-manifest.d.ts +26 -0
- package/src/adapters/node/write-runtime-manifest.js +12 -0
- package/src/adapters/shared/api-response.d.ts +52 -0
- package/src/adapters/shared/api-response.js +96 -0
- package/src/adapters/shared/application-adapter.d.ts +18 -0
- package/src/adapters/shared/application-adapter.js +90 -0
- package/src/adapters/shared/define-api-handler.d.ts +25 -0
- package/src/adapters/shared/define-api-handler.js +15 -0
- package/src/adapters/shared/explicit-static-route-matcher.d.ts +38 -0
- package/src/adapters/shared/explicit-static-route-matcher.js +103 -0
- package/src/adapters/shared/file-route-middleware-pipeline.d.ts +65 -0
- package/src/adapters/shared/file-route-middleware-pipeline.js +99 -0
- package/src/adapters/shared/fs-server-response-factory.d.ts +19 -0
- package/src/adapters/shared/fs-server-response-factory.js +97 -0
- package/src/adapters/shared/fs-server-response-matcher.d.ts +75 -0
- package/src/adapters/shared/fs-server-response-matcher.js +160 -0
- package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +55 -0
- package/src/adapters/shared/hmr-entrypoint-registrar.js +87 -0
- package/src/adapters/shared/hmr-html-response.d.ts +22 -0
- package/src/adapters/shared/hmr-html-response.js +32 -0
- package/src/adapters/shared/render-context.d.ts +14 -0
- package/src/adapters/shared/render-context.js +70 -0
- package/src/adapters/shared/runtime-bootstrap.d.ts +38 -0
- package/src/adapters/shared/runtime-bootstrap.js +43 -0
- package/src/adapters/shared/server-adapter.d.ts +97 -0
- package/src/adapters/shared/server-adapter.js +386 -0
- package/src/adapters/shared/server-route-handler.d.ts +89 -0
- package/src/adapters/shared/server-route-handler.js +111 -0
- package/src/adapters/shared/server-static-builder.d.ts +70 -0
- package/src/adapters/shared/server-static-builder.js +99 -0
- package/src/build/build-adapter.d.ts +186 -0
- package/src/build/build-adapter.js +168 -0
- package/src/build/build-manifest.d.ts +27 -0
- package/src/build/build-manifest.js +30 -0
- package/src/build/build-types.d.ts +57 -0
- package/src/build/build-types.js +0 -0
- package/src/build/dev-build-coordinator.d.ts +74 -0
- package/src/build/dev-build-coordinator.js +161 -0
- package/src/build/esbuild-build-adapter.d.ts +72 -0
- package/src/build/esbuild-build-adapter.js +422 -0
- package/src/build/runtime-build-executor.d.ts +13 -0
- package/src/build/runtime-build-executor.js +20 -0
- package/src/build/runtime-specifier-alias-plugin.d.ts +15 -0
- package/src/build/runtime-specifier-alias-plugin.js +31 -0
- package/src/config/config-builder.d.ts +238 -0
- package/src/config/config-builder.js +565 -0
- package/src/constants.d.ts +45 -0
- package/src/constants.js +25 -0
- package/src/create-app.d.ts +17 -0
- package/src/create-app.js +66 -0
- package/src/dev/sc-server.d.ts +30 -0
- package/src/dev/sc-server.js +111 -0
- package/src/eco/component-render-context.d.ts +105 -0
- package/src/eco/component-render-context.js +87 -0
- package/src/eco/eco.d.ts +9 -0
- package/src/eco/eco.js +114 -0
- package/src/eco/eco.types.d.ts +178 -0
- package/src/eco/eco.types.js +0 -0
- package/src/eco/eco.utils.d.ts +40 -0
- package/src/eco/eco.utils.js +40 -0
- package/src/eco/global-injector-map.d.ts +16 -0
- package/src/eco/global-injector-map.js +80 -0
- package/src/eco/lazy-injector-map.d.ts +8 -0
- package/src/eco/lazy-injector-map.js +70 -0
- package/src/eco/module-dependencies.d.ts +18 -0
- package/src/eco/module-dependencies.js +49 -0
- package/src/errors/http-error.d.ts +31 -0
- package/src/errors/http-error.js +50 -0
- package/src/errors/index.d.ts +2 -0
- package/src/errors/index.js +4 -0
- package/src/errors/locals-access-error.d.ts +4 -0
- package/src/errors/locals-access-error.js +9 -0
- package/src/global/app-logger.d.ts +2 -0
- package/src/global/app-logger.js +6 -0
- package/src/hmr/client/hmr-runtime.d.ts +5 -0
- package/src/hmr/client/hmr-runtime.js +109 -0
- package/src/hmr/hmr-strategy.d.ts +159 -0
- package/src/hmr/hmr-strategy.js +29 -0
- package/src/hmr/hmr.postcss.test.e2e.d.ts +1 -0
- package/src/hmr/hmr.postcss.test.e2e.js +31 -0
- package/src/hmr/hmr.test.e2e.d.ts +1 -0
- package/src/hmr/hmr.test.e2e.js +43 -0
- package/src/hmr/strategies/default-hmr-strategy.d.ts +43 -0
- package/src/hmr/strategies/default-hmr-strategy.js +34 -0
- package/src/hmr/strategies/js-hmr-strategy.d.ts +139 -0
- package/src/hmr/strategies/js-hmr-strategy.js +178 -0
- package/src/index.browser.d.ts +3 -0
- package/src/index.browser.js +4 -0
- package/src/index.d.ts +5 -0
- package/src/index.js +10 -0
- package/src/integrations/ghtml/ghtml-renderer.d.ts +15 -0
- package/src/integrations/ghtml/ghtml-renderer.js +62 -0
- package/src/integrations/ghtml/ghtml.plugin.d.ts +20 -0
- package/src/integrations/ghtml/ghtml.plugin.js +21 -0
- package/src/internal-types.d.ts +221 -0
- package/src/internal-types.js +0 -0
- package/src/plugins/alias-resolver-plugin.d.ts +2 -0
- package/src/plugins/alias-resolver-plugin.js +53 -0
- package/src/plugins/eco-component-meta-plugin.d.ts +97 -0
- package/src/plugins/eco-component-meta-plugin.js +157 -0
- package/src/plugins/integration-plugin.d.ts +136 -0
- package/src/plugins/integration-plugin.js +133 -0
- package/src/plugins/processor.d.ts +95 -0
- package/src/plugins/processor.js +136 -0
- package/src/plugins/runtime-capability.d.ts +9 -0
- package/src/plugins/runtime-capability.js +0 -0
- package/src/public-types.d.ts +1149 -0
- package/src/public-types.js +0 -0
- package/src/route-renderer/component-graph/component-graph-executor.d.ts +32 -0
- package/src/route-renderer/component-graph/component-graph-executor.js +31 -0
- package/src/route-renderer/component-graph/component-graph.d.ts +42 -0
- package/src/route-renderer/component-graph/component-graph.js +72 -0
- package/src/route-renderer/component-graph/component-marker.d.ts +52 -0
- package/src/route-renderer/component-graph/component-marker.js +46 -0
- package/src/route-renderer/component-graph/component-reference.d.ts +10 -0
- package/src/route-renderer/component-graph/component-reference.js +19 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +77 -0
- package/src/route-renderer/component-graph/marker-graph-resolver.js +95 -0
- package/src/route-renderer/orchestration/integration-renderer.d.ts +372 -0
- package/src/route-renderer/orchestration/integration-renderer.js +589 -0
- package/src/route-renderer/orchestration/render-execution.service.d.ts +103 -0
- package/src/route-renderer/orchestration/render-execution.service.js +121 -0
- package/src/route-renderer/orchestration/render-preparation.service.d.ts +121 -0
- package/src/route-renderer/orchestration/render-preparation.service.js +332 -0
- package/src/route-renderer/page-loading/dependency-resolver.d.ts +35 -0
- package/src/route-renderer/page-loading/dependency-resolver.js +442 -0
- package/src/route-renderer/page-loading/page-module-loader.d.ts +87 -0
- package/src/route-renderer/page-loading/page-module-loader.js +124 -0
- package/src/route-renderer/route-renderer.d.ts +61 -0
- package/src/route-renderer/route-renderer.js +87 -0
- package/src/router/client/link-intent.js +34 -0
- package/src/router/client/link-intent.test.browser.d.ts +1 -0
- package/src/router/client/link-intent.test.browser.js +43 -0
- package/src/router/client/navigation-coordinator.d.ts +149 -0
- package/src/router/client/navigation-coordinator.js +215 -0
- package/src/router/server/fs-router-scanner.d.ts +41 -0
- package/src/router/server/fs-router-scanner.js +156 -0
- package/src/router/server/fs-router.d.ts +26 -0
- package/src/router/server/fs-router.js +100 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +120 -0
- package/src/services/assets/asset-processing-service/asset-processing.service.js +331 -0
- package/src/services/assets/asset-processing-service/asset.factory.d.ts +17 -0
- package/src/services/assets/asset-processing-service/asset.factory.js +82 -0
- package/src/services/assets/asset-processing-service/assets.types.d.ts +89 -0
- package/src/services/assets/asset-processing-service/assets.types.js +0 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +55 -0
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +48 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +20 -0
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +41 -0
- package/src/services/assets/asset-processing-service/index.d.ts +5 -0
- package/src/services/assets/asset-processing-service/index.js +5 -0
- package/src/services/assets/asset-processing-service/processor.interface.d.ts +22 -0
- package/src/services/assets/asset-processing-service/processor.interface.js +6 -0
- package/src/services/assets/asset-processing-service/processor.registry.d.ts +8 -0
- package/src/services/assets/asset-processing-service/processor.registry.js +15 -0
- package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +24 -0
- package/src/services/assets/asset-processing-service/processors/base/base-processor.js +64 -0
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +17 -0
- package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +72 -0
- package/src/services/assets/asset-processing-service/processors/index.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/index.js +5 -0
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +57 -0
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +8 -0
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +76 -0
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +7 -0
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +75 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +5 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +25 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +9 -0
- package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +66 -0
- package/src/services/assets/browser-bundle.service.d.ts +32 -0
- package/src/services/assets/browser-bundle.service.js +33 -0
- package/src/services/cache/cache.types.d.ts +107 -0
- package/src/services/cache/cache.types.js +0 -0
- package/src/services/cache/index.d.ts +7 -0
- package/src/services/cache/index.js +7 -0
- package/src/services/cache/memory-cache-store.d.ts +42 -0
- package/src/services/cache/memory-cache-store.js +98 -0
- package/src/services/cache/page-cache-service.d.ts +70 -0
- package/src/services/cache/page-cache-service.js +152 -0
- package/src/services/cache/page-request-cache-coordinator.service.d.ts +75 -0
- package/src/services/cache/page-request-cache-coordinator.service.js +109 -0
- package/src/services/html/html-rewriter-provider.service.d.ts +37 -0
- package/src/services/html/html-rewriter-provider.service.js +65 -0
- package/src/services/html/html-transformer.service.d.ts +77 -0
- package/src/services/html/html-transformer.service.js +221 -0
- package/src/services/invalidation/development-invalidation.service.d.ts +74 -0
- package/src/services/invalidation/development-invalidation.service.js +189 -0
- package/src/services/module-loading/app-server-module-transpiler.service.d.ts +16 -0
- package/src/services/module-loading/app-server-module-transpiler.service.js +34 -0
- package/src/services/module-loading/page-module-import.service.d.ts +71 -0
- package/src/services/module-loading/page-module-import.service.js +132 -0
- package/src/services/module-loading/server-loader.service.d.ts +96 -0
- package/src/services/module-loading/server-loader.service.js +32 -0
- package/src/services/module-loading/server-module-transpiler.service.d.ts +69 -0
- package/src/services/module-loading/server-module-transpiler.service.js +61 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.d.ts +35 -0
- package/src/services/runtime-manifest/node-runtime-manifest.service.js +60 -0
- package/src/services/runtime-state/dev-graph.service.d.ts +118 -0
- package/src/services/runtime-state/dev-graph.service.js +162 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +41 -0
- package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +69 -0
- package/src/services/runtime-state/runtime-specifier-registry.service.js +37 -0
- package/src/services/runtime-state/server-invalidation-state.service.d.ts +26 -0
- package/src/services/runtime-state/server-invalidation-state.service.js +35 -0
- package/src/services/validation/schema-validation-service.d.ts +122 -0
- package/src/services/validation/schema-validation-service.js +101 -0
- package/src/services/validation/standard-schema.types.d.ts +65 -0
- package/src/services/validation/standard-schema.types.js +0 -0
- package/src/static-site-generator/static-site-generator.d.ts +109 -0
- package/src/static-site-generator/static-site-generator.js +353 -0
- package/src/utils/css.d.ts +1 -0
- package/src/utils/css.js +7 -0
- package/src/utils/deep-merge.d.ts +14 -0
- package/src/utils/deep-merge.js +32 -0
- package/src/utils/hash.d.ts +1 -0
- package/src/utils/hash.js +7 -0
- package/src/utils/html.d.ts +1 -0
- package/src/utils/html.js +4 -0
- package/src/utils/invariant.d.ts +5 -0
- package/src/utils/invariant.js +11 -0
- package/src/utils/locals-utils.d.ts +15 -0
- package/src/utils/locals-utils.js +24 -0
- package/src/utils/parse-cli-args.d.ts +24 -0
- package/src/utils/parse-cli-args.js +47 -0
- package/src/utils/path-utils.module.d.ts +5 -0
- package/src/utils/path-utils.module.js +14 -0
- package/src/utils/resolve-work-dir.d.ts +11 -0
- package/src/utils/resolve-work-dir.js +31 -0
- package/src/utils/runtime.d.ts +11 -0
- package/src/utils/runtime.js +40 -0
- package/src/utils/server-utils.module.d.ts +19 -0
- package/src/utils/server-utils.module.js +56 -0
- package/src/watchers/project-watcher.d.ts +136 -0
- package/src/watchers/project-watcher.js +281 -0
- package/src/watchers/project-watcher.test-helpers.d.ts +4 -0
- package/src/watchers/project-watcher.test-helpers.js +52 -0
- package/src/adapters/bun/hmr-manager.test.ts +0 -267
- package/src/adapters/node/bootstrap-dependency-resolver.test.ts +0 -282
- package/src/adapters/node/node-client-bridge.test.ts +0 -198
- package/src/adapters/node/node-hmr-manager.test.ts +0 -322
- package/src/adapters/node/runtime-adapter.test.ts +0 -868
- package/src/adapters/node/static-content-server.test.ts +0 -60
- package/src/adapters/shared/api-response.test.ts +0 -97
- package/src/adapters/shared/explicit-static-route-matcher.test.ts +0 -381
- package/src/adapters/shared/file-route-middleware-pipeline.test.ts +0 -90
- package/src/adapters/shared/fs-server-response-factory.test.ts +0 -187
- package/src/adapters/shared/fs-server-response-matcher.test.ts +0 -286
- package/src/adapters/shared/hmr-manager.contract.test.ts +0 -196
- package/src/adapters/shared/hmr-manager.dispatch.test.ts +0 -220
- package/src/adapters/shared/render-context.test.ts +0 -146
- package/src/adapters/shared/server-adapter.test.ts +0 -77
- package/src/adapters/shared/server-route-handler.test.ts +0 -110
- package/src/adapters/shared/server-static-builder.test.ts +0 -316
- package/src/build/build-adapter-serialization.test.ts +0 -268
- package/src/build/build-adapter.test.ts +0 -815
- package/src/build/runtime-specifier-alias-plugin.test.ts +0 -43
- package/src/config/config-builder.test.ts +0 -410
- package/src/eco/eco.test.ts +0 -678
- package/src/eco/eco.utils.test.ts +0 -124
- package/src/eco/global-injector-map.test.ts +0 -42
- package/src/eco/lazy-injector-map.test.ts +0 -66
- package/src/eco/module-dependencies.test.ts +0 -30
- package/src/errors/http-error.test.ts +0 -134
- package/src/global/utils.test.ts +0 -12
- 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/hmr-strategy.test.ts +0 -124
- package/src/hmr/strategies/js-hmr-strategy.test.ts +0 -335
- package/src/integrations/ghtml/ghtml-renderer.test.ts +0 -63
- package/src/plugins/alias-resolver-plugin.test.ts +0 -41
- package/src/plugins/eco-component-meta-plugin.test.ts +0 -380
- package/src/plugins/integration-plugin.test.ts +0 -111
- package/src/plugins/processor.test.ts +0 -148
- package/src/route-renderer/component-graph/component-graph-executor.test.ts +0 -41
- package/src/route-renderer/component-graph/component-graph.test.ts +0 -63
- package/src/route-renderer/component-graph/component-marker.test.ts +0 -73
- package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +0 -135
- package/src/route-renderer/orchestration/integration-renderer.test.ts +0 -936
- package/src/route-renderer/orchestration/render-execution.service.test.ts +0 -97
- package/src/route-renderer/orchestration/render-preparation.service.test.ts +0 -235
- package/src/route-renderer/page-loading/dependency-resolver.test.ts +0 -345
- package/src/route-renderer/page-loading/page-module-loader.test.ts +0 -96
- package/src/router/client/navigation-coordinator.test.ts +0 -237
- package/src/router/server/fs-router-scanner.test.ts +0 -83
- package/src/router/server/fs-router.test.ts +0 -214
- package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +0 -385
- package/src/services/assets/asset-processing-service/asset.factory.test.ts +0 -63
- package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +0 -72
- package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +0 -67
- package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +0 -59
- package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +0 -286
- package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +0 -227
- package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +0 -199
- package/src/services/assets/browser-bundle.service.test.ts +0 -36
- package/src/services/cache/memory-cache-store.test.ts +0 -225
- package/src/services/cache/page-cache-service.test.ts +0 -175
- package/src/services/cache/page-request-cache-coordinator.service.test.ts +0 -79
- package/src/services/html/html-rewriter-provider.service.test.ts +0 -183
- package/src/services/html/html-transformer.service.test.ts +0 -378
- package/src/services/invalidation/development-invalidation.service.test.ts +0 -77
- package/src/services/module-loading/page-module-import.service.test.ts +0 -253
- package/src/services/module-loading/server-loader.service.test.ts +0 -161
- package/src/services/module-loading/server-module-transpiler.service.test.ts +0 -115
- package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +0 -95
- package/src/services/validation/schema-validation-service.test.ts +0 -223
- package/src/static-site-generator/static-site-generator.test.ts +0 -307
- package/src/utils/deep-merge.test.ts +0 -114
- package/src/utils/invariant.test.ts +0 -22
- package/src/utils/path-utils.test.ts +0 -15
- package/src/utils/server-utils.test.ts +0 -38
- package/src/watchers/project-watcher.integration.test.ts +0 -337
- package/src/watchers/project-watcher.test.ts +0 -678
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import type { AddressInfo } from 'node:net';
|
|
6
|
-
import { NodeStaticContentServer } from './static-content-server.ts';
|
|
7
|
-
import type { EcoPagesAppConfig } from '../../internal-types.ts';
|
|
8
|
-
|
|
9
|
-
const TMP_DIR = path.join(os.tmpdir(), 'node-static-content-server-test');
|
|
10
|
-
|
|
11
|
-
const createAppConfig = (): EcoPagesAppConfig =>
|
|
12
|
-
({
|
|
13
|
-
rootDir: TMP_DIR,
|
|
14
|
-
distDir: 'dist',
|
|
15
|
-
absolutePaths: {
|
|
16
|
-
distDir: path.join(TMP_DIR, 'dist'),
|
|
17
|
-
workDir: path.join(TMP_DIR, '.eco'),
|
|
18
|
-
} as EcoPagesAppConfig['absolutePaths'],
|
|
19
|
-
}) as EcoPagesAppConfig;
|
|
20
|
-
|
|
21
|
-
describe('NodeStaticContentServer', () => {
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
fs.rmSync(TMP_DIR, { recursive: true, force: true });
|
|
24
|
-
fs.mkdirSync(path.join(TMP_DIR, 'dist', 'assets', 'pages'), { recursive: true });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
fs.rmSync(TMP_DIR, { recursive: true, force: true });
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should serve built CSS assets with the correct content type in preview mode', async () => {
|
|
32
|
-
const distDir = path.join(TMP_DIR, 'dist');
|
|
33
|
-
fs.writeFileSync(
|
|
34
|
-
path.join(distDir, 'api-lab.html'),
|
|
35
|
-
'<html><head><link rel="stylesheet" href="/assets/pages/api-lab.css"></head><body>API Lab</body></html>',
|
|
36
|
-
);
|
|
37
|
-
fs.writeFileSync(path.join(distDir, 'assets', 'pages', 'api-lab.css'), '.api-lab { color: tomato; }');
|
|
38
|
-
|
|
39
|
-
const server = new NodeStaticContentServer({
|
|
40
|
-
appConfig: createAppConfig(),
|
|
41
|
-
options: { hostname: '127.0.0.1', port: 0 },
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const httpServer = await server.start();
|
|
45
|
-
const address = httpServer.address() as AddressInfo;
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
const htmlResponse = await fetch(`http://127.0.0.1:${address.port}/api-lab`);
|
|
49
|
-
const cssResponse = await fetch(`http://127.0.0.1:${address.port}/assets/pages/api-lab.css`);
|
|
50
|
-
|
|
51
|
-
expect(htmlResponse.status).toBe(200);
|
|
52
|
-
expect(await htmlResponse.text()).toContain('/assets/pages/api-lab.css');
|
|
53
|
-
expect(cssResponse.status).toBe(200);
|
|
54
|
-
expect(cssResponse.headers.get('content-type')).toContain('text/css');
|
|
55
|
-
expect(await cssResponse.text()).toContain('.api-lab { color: tomato; }');
|
|
56
|
-
} finally {
|
|
57
|
-
await server.stop();
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { ApiResponseBuilder } from './api-response';
|
|
3
|
-
|
|
4
|
-
describe('ApiResponseBuilder', () => {
|
|
5
|
-
let builder: ApiResponseBuilder;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
builder = new ApiResponseBuilder();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
describe('json()', () => {
|
|
12
|
-
it('should create JSON response with correct content type and data', async () => {
|
|
13
|
-
const data = { foo: 'bar' };
|
|
14
|
-
const response = builder.json(data);
|
|
15
|
-
|
|
16
|
-
expect(response.headers.get('Content-Type')).toBe('application/json; charset=utf-8');
|
|
17
|
-
expect(await response.json()).toEqual(data);
|
|
18
|
-
expect(response.status).toBe(200);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
describe('text()', () => {
|
|
23
|
-
it('should create text response with correct content type and data', async () => {
|
|
24
|
-
const text = 'Hello World';
|
|
25
|
-
const response = builder.text(text);
|
|
26
|
-
|
|
27
|
-
expect(response.headers.get('Content-Type')).toBe('text/plain; charset=utf-8');
|
|
28
|
-
expect(await response.text()).toBe(text);
|
|
29
|
-
expect(response.status).toBe(200);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('html()', () => {
|
|
34
|
-
it('should create HTML response with correct content type and data', async () => {
|
|
35
|
-
const html = '<h1>Hello</h1>';
|
|
36
|
-
const response = builder.html(html);
|
|
37
|
-
|
|
38
|
-
expect(response.headers.get('Content-Type')).toBe('text/html; charset=utf-8');
|
|
39
|
-
expect(await response.text()).toBe(html);
|
|
40
|
-
expect(response.status).toBe(200);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('status()', () => {
|
|
45
|
-
it('should set custom status code', () => {
|
|
46
|
-
const response = builder.status(404).json({ message: 'Not Found' });
|
|
47
|
-
expect(response.status).toBe(404);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('headers()', () => {
|
|
52
|
-
it('should set custom headers', () => {
|
|
53
|
-
const response = builder.headers({ 'X-Custom': 'Value' }).json({});
|
|
54
|
-
expect(response.headers.get('X-Custom')).toBe('Value');
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('redirect()', () => {
|
|
59
|
-
it('should create redirect response with location header', () => {
|
|
60
|
-
const url = 'https://example.com';
|
|
61
|
-
const response = builder.redirect(url);
|
|
62
|
-
|
|
63
|
-
expect(response.headers.get('Location')).toBe(url);
|
|
64
|
-
expect(response.status).toBe(302);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should use explicit status for redirect', () => {
|
|
68
|
-
const response = builder.redirect('https://example.com', 301);
|
|
69
|
-
expect(response.status).toBe(301);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe('error()', () => {
|
|
74
|
-
it('should create JSON error response for object data', async () => {
|
|
75
|
-
const error = { code: 'ERR_1', message: 'Error occurred' };
|
|
76
|
-
const response = builder.error(error);
|
|
77
|
-
|
|
78
|
-
expect(response.headers.get('Content-Type')).toBe('application/json; charset=utf-8');
|
|
79
|
-
expect(await response.json()).toEqual({ error });
|
|
80
|
-
expect(response.status).toBe(500);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should create text error response for string data', async () => {
|
|
84
|
-
const error = 'Error occurred';
|
|
85
|
-
const response = builder.error(error);
|
|
86
|
-
|
|
87
|
-
expect(response.headers.get('Content-Type')).toBe('text/plain; charset=utf-8');
|
|
88
|
-
expect(await response.text()).toBe(error);
|
|
89
|
-
expect(response.status).toBe(500);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should use explicit status for error', () => {
|
|
93
|
-
const response = builder.error('Not Found', 404);
|
|
94
|
-
expect(response.status).toBe(404);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import type { EcoPageComponent, StaticRoute, ViewLoader } from '../../public-types.ts';
|
|
3
|
-
import { ExplicitStaticRouteMatcher } from './explicit-static-route-matcher.ts';
|
|
4
|
-
|
|
5
|
-
function createMockView(integration = 'ghtml'): EcoPageComponent<any> {
|
|
6
|
-
const view = (() => '<div>Test</div>') as EcoPageComponent<any>;
|
|
7
|
-
view.config = {
|
|
8
|
-
integration,
|
|
9
|
-
__eco: { id: 'test', file: '/test/-view.ts', integration },
|
|
10
|
-
};
|
|
11
|
-
return view;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function createMockLoader(view?: EcoPageComponent<any>): ViewLoader<any> {
|
|
15
|
-
const actualView = view ?? createMockView();
|
|
16
|
-
return () => Promise.resolve({ default: actualView });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function createMockRoute(path: string, view?: EcoPageComponent<any>): StaticRoute {
|
|
20
|
-
return {
|
|
21
|
-
path,
|
|
22
|
-
loader: createMockLoader(view),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function createMatcher(staticRoutes: StaticRoute[]) {
|
|
27
|
-
return new ExplicitStaticRouteMatcher({
|
|
28
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
29
|
-
routeRendererFactory: {} as any,
|
|
30
|
-
staticRoutes,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
describe('ExplicitStaticRouteMatcher', () => {
|
|
35
|
-
describe('match', () => {
|
|
36
|
-
test('should match exact static path', () => {
|
|
37
|
-
const matcher = createMatcher([createMockRoute('/about')]);
|
|
38
|
-
|
|
39
|
-
const result = matcher.match('http://localhost:3000/about');
|
|
40
|
-
|
|
41
|
-
expect(result).not.toBeNull();
|
|
42
|
-
expect(result?.route.path).toBe('/about');
|
|
43
|
-
expect(result?.params).toEqual({});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('should match root path', () => {
|
|
47
|
-
const matcher = createMatcher([createMockRoute('/')]);
|
|
48
|
-
|
|
49
|
-
const result = matcher.match('http://localhost:3000/');
|
|
50
|
-
|
|
51
|
-
expect(result).not.toBeNull();
|
|
52
|
-
expect(result?.route.path).toBe('/');
|
|
53
|
-
expect(result?.params).toEqual({});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('should match nested static path', () => {
|
|
57
|
-
const matcher = createMatcher([createMockRoute('/docs/getting-started')]);
|
|
58
|
-
|
|
59
|
-
const result = matcher.match('http://localhost:3000/docs/getting-started');
|
|
60
|
-
|
|
61
|
-
expect(result).not.toBeNull();
|
|
62
|
-
expect(result?.route.path).toBe('/docs/getting-started');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test('should return null for non-matching path', () => {
|
|
66
|
-
const matcher = createMatcher([createMockRoute('/about')]);
|
|
67
|
-
|
|
68
|
-
const result = matcher.match('http://localhost:3000/contact');
|
|
69
|
-
|
|
70
|
-
expect(result).toBeNull();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test('should return null for partial match', () => {
|
|
74
|
-
const matcher = createMatcher([createMockRoute('/about')]);
|
|
75
|
-
|
|
76
|
-
const result = matcher.match('http://localhost:3000/about/team');
|
|
77
|
-
|
|
78
|
-
expect(result).toBeNull();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('match with :param syntax', () => {
|
|
83
|
-
test('should match dynamic segment with colon syntax', () => {
|
|
84
|
-
const matcher = createMatcher([createMockRoute('/blog/:slug')]);
|
|
85
|
-
|
|
86
|
-
const result = matcher.match('http://localhost:3000/blog/hello-world');
|
|
87
|
-
|
|
88
|
-
expect(result).not.toBeNull();
|
|
89
|
-
expect(result?.params).toEqual({ slug: 'hello-world' });
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('should match multiple dynamic segments', () => {
|
|
93
|
-
const matcher = createMatcher([createMockRoute('/blog/:year/:month/:slug')]);
|
|
94
|
-
|
|
95
|
-
const result = matcher.match('http://localhost:3000/blog/2024/01/hello-world');
|
|
96
|
-
|
|
97
|
-
expect(result).not.toBeNull();
|
|
98
|
-
expect(result?.params).toEqual({
|
|
99
|
-
year: '2024',
|
|
100
|
-
month: '01',
|
|
101
|
-
slug: 'hello-world',
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test('should match mixed static and dynamic segments', () => {
|
|
106
|
-
const matcher = createMatcher([createMockRoute('/users/:id/posts')]);
|
|
107
|
-
|
|
108
|
-
const result = matcher.match('http://localhost:3000/users/123/posts');
|
|
109
|
-
|
|
110
|
-
expect(result).not.toBeNull();
|
|
111
|
-
expect(result?.params).toEqual({ id: '123' });
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe('match with [param] syntax', () => {
|
|
116
|
-
test('should match dynamic segment with bracket syntax', () => {
|
|
117
|
-
const matcher = createMatcher([createMockRoute('/blog/[slug]')]);
|
|
118
|
-
|
|
119
|
-
const result = matcher.match('http://localhost:3000/blog/hello-world');
|
|
120
|
-
|
|
121
|
-
expect(result).not.toBeNull();
|
|
122
|
-
expect(result?.params).toEqual({ slug: 'hello-world' });
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test('should match multiple bracket parameters', () => {
|
|
126
|
-
const matcher = createMatcher([createMockRoute('/products/[category]/[id]')]);
|
|
127
|
-
|
|
128
|
-
const result = matcher.match('http://localhost:3000/products/electronics/12345');
|
|
129
|
-
|
|
130
|
-
expect(result).not.toBeNull();
|
|
131
|
-
expect(result?.params).toEqual({
|
|
132
|
-
category: 'electronics',
|
|
133
|
-
id: '12345',
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('match with catch-all routes', () => {
|
|
139
|
-
test('should match catch-all with bracket syntax', () => {
|
|
140
|
-
const matcher = createMatcher([createMockRoute('/docs/[...path]')]);
|
|
141
|
-
|
|
142
|
-
const result = matcher.match('http://localhost:3000/docs/api/reference/components');
|
|
143
|
-
|
|
144
|
-
expect(result).not.toBeNull();
|
|
145
|
-
expect(result?.params).toEqual({ path: 'api/reference/components' });
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('should match catch-all with colon syntax', () => {
|
|
149
|
-
const matcher = createMatcher([createMockRoute('/files/:...path')]);
|
|
150
|
-
|
|
151
|
-
const result = matcher.match('http://localhost:3000/files/images/2024/photo.jpg');
|
|
152
|
-
|
|
153
|
-
expect(result).not.toBeNull();
|
|
154
|
-
expect(result?.params).toEqual({ path: 'images/2024/photo.jpg' });
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test('should match catch-all with single segment', () => {
|
|
158
|
-
const matcher = createMatcher([createMockRoute('/docs/[...path]')]);
|
|
159
|
-
|
|
160
|
-
const result = matcher.match('http://localhost:3000/docs/intro');
|
|
161
|
-
|
|
162
|
-
expect(result).not.toBeNull();
|
|
163
|
-
expect(result?.params).toEqual({ path: 'intro' });
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe('route priority', () => {
|
|
168
|
-
test('should match first route when multiple routes match', () => {
|
|
169
|
-
const aboutView = createMockView();
|
|
170
|
-
const catchAllView = createMockView();
|
|
171
|
-
|
|
172
|
-
const matcher = createMatcher([
|
|
173
|
-
createMockRoute('/about', aboutView),
|
|
174
|
-
createMockRoute('/[...path]', catchAllView),
|
|
175
|
-
]);
|
|
176
|
-
|
|
177
|
-
const result = matcher.match('http://localhost:3000/about');
|
|
178
|
-
|
|
179
|
-
expect(result).not.toBeNull();
|
|
180
|
-
expect(result?.route.path).toBe('/about');
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
test('should match exact route before dynamic route', () => {
|
|
184
|
-
const exactView = createMockView();
|
|
185
|
-
const dynamicView = createMockView();
|
|
186
|
-
|
|
187
|
-
const matcher = createMatcher([
|
|
188
|
-
createMockRoute('/blog/featured', exactView),
|
|
189
|
-
createMockRoute('/blog/:slug', dynamicView),
|
|
190
|
-
]);
|
|
191
|
-
|
|
192
|
-
const result = matcher.match('http://localhost:3000/blog/featured');
|
|
193
|
-
|
|
194
|
-
expect(result).not.toBeNull();
|
|
195
|
-
expect(result?.route.path).toBe('/blog/featured');
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
describe('edge cases', () => {
|
|
200
|
-
test('should handle URL with query parameters', () => {
|
|
201
|
-
const matcher = createMatcher([createMockRoute('/search')]);
|
|
202
|
-
|
|
203
|
-
const result = matcher.match('http://localhost:3000/search?q=test&page=1');
|
|
204
|
-
|
|
205
|
-
expect(result).not.toBeNull();
|
|
206
|
-
expect(result?.route.path).toBe('/search');
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
test('should handle URL with hash', () => {
|
|
210
|
-
const matcher = createMatcher([createMockRoute('/docs/intro')]);
|
|
211
|
-
|
|
212
|
-
const result = matcher.match('http://localhost:3000/docs/intro#section-1');
|
|
213
|
-
|
|
214
|
-
expect(result).not.toBeNull();
|
|
215
|
-
expect(result?.route.path).toBe('/docs/intro');
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
test('should handle trailing slash', () => {
|
|
219
|
-
const matcher = createMatcher([createMockRoute('/about')]);
|
|
220
|
-
|
|
221
|
-
const result = matcher.match('http://localhost:3000/about/');
|
|
222
|
-
|
|
223
|
-
expect(result).not.toBeNull();
|
|
224
|
-
expect(result?.route.path).toBe('/about');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
test('should return null for empty routes array', () => {
|
|
228
|
-
const matcher = createMatcher([]);
|
|
229
|
-
|
|
230
|
-
const result = matcher.match('http://localhost:3000/anything');
|
|
231
|
-
|
|
232
|
-
expect(result).toBeNull();
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
describe('handleMatch', () => {
|
|
237
|
-
test('should accept integration metadata from view.config.integration', async () => {
|
|
238
|
-
const view = (() => '<div>Test</div>') as EcoPageComponent<any>;
|
|
239
|
-
view.config = {
|
|
240
|
-
integration: 'ghtml',
|
|
241
|
-
__eco: { id: 'test', file: '/test/-view.ts', integration: 'ghtml' },
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
const mockResponse = new Response('<html>Test</html>');
|
|
245
|
-
const renderToResponse = vi.fn(() => mockResponse);
|
|
246
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
247
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
248
|
-
routeRendererFactory: {
|
|
249
|
-
getRendererByIntegration: vi.fn(() => ({
|
|
250
|
-
renderToResponse,
|
|
251
|
-
})),
|
|
252
|
-
} as any,
|
|
253
|
-
staticRoutes: [createMockRoute('/about', view)],
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
const match = matcher.match('http://localhost:3000/about');
|
|
257
|
-
const response = await matcher.handleMatch(match!);
|
|
258
|
-
|
|
259
|
-
expect(response).toBe(mockResponse);
|
|
260
|
-
expect(renderToResponse).toHaveBeenCalledWith(view, {}, {});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
test('should throw error when view is missing __eco.integration', async () => {
|
|
264
|
-
const viewWithoutIntegration = (() => '<div>Test</div>') as EcoPageComponent<any>;
|
|
265
|
-
viewWithoutIntegration.config = {
|
|
266
|
-
__eco: undefined,
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
270
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
271
|
-
routeRendererFactory: {
|
|
272
|
-
getRendererByIntegration: vi.fn(() => null),
|
|
273
|
-
} as any,
|
|
274
|
-
staticRoutes: [createMockRoute('/about', viewWithoutIntegration)],
|
|
275
|
-
});
|
|
276
|
-
const match = matcher.match('http://localhost:3000/about');
|
|
277
|
-
|
|
278
|
-
expect(match).not.toBeNull();
|
|
279
|
-
await expect(matcher.handleMatch(match!)).rejects.toThrow('missing __eco.integration');
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
test('should throw error when renderer is not found', async () => {
|
|
283
|
-
const view = createMockView('nonexistent-integration');
|
|
284
|
-
const RendererFactory = {
|
|
285
|
-
getRendererByIntegration: vi.fn(() => null),
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
289
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
290
|
-
routeRendererFactory: RendererFactory as any,
|
|
291
|
-
staticRoutes: [createMockRoute('/about', view)],
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
const match = matcher.match('http://localhost:3000/about');
|
|
295
|
-
|
|
296
|
-
await expect(matcher.handleMatch(match!)).rejects.toThrow(
|
|
297
|
-
'No renderer found for integration: nonexistent-integration',
|
|
298
|
-
);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
test('should call renderer.renderToResponse with correct arguments', async () => {
|
|
302
|
-
const view = createMockView('ghtml');
|
|
303
|
-
const mockResponse = new Response('<html>Test</html>');
|
|
304
|
-
const RenderToResponse = vi.fn(() => mockResponse);
|
|
305
|
-
const RendererFactory = {
|
|
306
|
-
getRendererByIntegration: vi.fn(() => ({
|
|
307
|
-
renderToResponse: RenderToResponse,
|
|
308
|
-
})),
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
312
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
313
|
-
routeRendererFactory: RendererFactory as any,
|
|
314
|
-
staticRoutes: [createMockRoute('/about', view)],
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
const match = matcher.match('http://localhost:3000/about');
|
|
318
|
-
const response = await matcher.handleMatch(match!);
|
|
319
|
-
|
|
320
|
-
expect(response).toBe(mockResponse);
|
|
321
|
-
expect(RenderToResponse).toHaveBeenCalledTimes(1);
|
|
322
|
-
expect(RenderToResponse).toHaveBeenCalledWith(view, {}, {});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
test('should resolve staticProps and pass to renderer', async () => {
|
|
326
|
-
const view = createMockView('ghtml');
|
|
327
|
-
view.staticProps = vi.fn(async () => ({
|
|
328
|
-
props: { title: 'About Page', content: 'Hello' },
|
|
329
|
-
}));
|
|
330
|
-
|
|
331
|
-
const mockResponse = new Response('<html>Test</html>');
|
|
332
|
-
const RenderToResponse = vi.fn(() => mockResponse);
|
|
333
|
-
const RendererFactory = {
|
|
334
|
-
getRendererByIntegration: vi.fn(() => ({
|
|
335
|
-
renderToResponse: RenderToResponse,
|
|
336
|
-
})),
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
340
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
341
|
-
routeRendererFactory: RendererFactory as any,
|
|
342
|
-
staticRoutes: [createMockRoute('/about', view)],
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
const match = matcher.match('http://localhost:3000/about');
|
|
346
|
-
await matcher.handleMatch(match!);
|
|
347
|
-
|
|
348
|
-
expect(view.staticProps).toHaveBeenCalledTimes(1);
|
|
349
|
-
expect(RenderToResponse).toHaveBeenCalledWith(view, { title: 'About Page', content: 'Hello' }, {});
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
test('should pass params to staticProps', async () => {
|
|
353
|
-
const view = createMockView('ghtml');
|
|
354
|
-
view.staticProps = vi.fn(async ({ pathname }) => ({
|
|
355
|
-
props: { slug: pathname.params.slug },
|
|
356
|
-
}));
|
|
357
|
-
|
|
358
|
-
const mockResponse = new Response('<html>Test</html>');
|
|
359
|
-
const RendererFactory = {
|
|
360
|
-
getRendererByIntegration: vi.fn(() => ({
|
|
361
|
-
renderToResponse: vi.fn(() => mockResponse),
|
|
362
|
-
})),
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
const matcher = new ExplicitStaticRouteMatcher({
|
|
366
|
-
appConfig: { baseUrl: 'http://localhost:3000' } as any,
|
|
367
|
-
routeRendererFactory: RendererFactory as any,
|
|
368
|
-
staticRoutes: [createMockRoute('/blog/:slug', view)],
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
const match = matcher.match('http://localhost:3000/blog/hello-world');
|
|
372
|
-
await matcher.handleMatch(match!);
|
|
373
|
-
|
|
374
|
-
expect(view.staticProps).toHaveBeenCalledWith(
|
|
375
|
-
expect.objectContaining({
|
|
376
|
-
pathname: { params: { slug: 'hello-world' } },
|
|
377
|
-
}),
|
|
378
|
-
);
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
});
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import type { Middleware } from '../../public-types.ts';
|
|
3
|
-
import { LocalsAccessError } from '../../errors/locals-access-error.ts';
|
|
4
|
-
import {
|
|
5
|
-
FILE_ROUTE_MIDDLEWARE_PIPELINE_ERRORS,
|
|
6
|
-
FileRouteMiddlewarePipeline,
|
|
7
|
-
} from './file-route-middleware-pipeline.ts';
|
|
8
|
-
|
|
9
|
-
declare module '../../public-types.ts' {
|
|
10
|
-
interface RequestLocals {
|
|
11
|
-
user?: string;
|
|
12
|
-
first?: boolean;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
describe('FileRouteMiddlewarePipeline', () => {
|
|
17
|
-
it('should reject middleware on non-dynamic pages', () => {
|
|
18
|
-
const service = new FileRouteMiddlewarePipeline(null);
|
|
19
|
-
|
|
20
|
-
expect(() =>
|
|
21
|
-
service.assertValidConfiguration({
|
|
22
|
-
middleware: [async (_ctx, next) => next()],
|
|
23
|
-
pageCacheStrategy: 'static',
|
|
24
|
-
filePath: '/app/pages/index.tsx',
|
|
25
|
-
}),
|
|
26
|
-
).toThrowError(
|
|
27
|
-
new LocalsAccessError(
|
|
28
|
-
FILE_ROUTE_MIDDLEWARE_PIPELINE_ERRORS.middlewareRequiresDynamic('/app/pages/index.tsx'),
|
|
29
|
-
),
|
|
30
|
-
);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should create middleware context with render methods disabled', async () => {
|
|
34
|
-
const service = new FileRouteMiddlewarePipeline(null);
|
|
35
|
-
const DummyView = (() => '<div>dummy</div>') as never;
|
|
36
|
-
const context = service.createContext({
|
|
37
|
-
request: new Request('http://localhost:3000/hello'),
|
|
38
|
-
params: { slug: 'hello' },
|
|
39
|
-
locals: { user: 'andee' },
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
await expect(context.render(DummyView, {})).rejects.toThrow(
|
|
43
|
-
FILE_ROUTE_MIDDLEWARE_PIPELINE_ERRORS.CTX_RENDER_UNAVAILABLE,
|
|
44
|
-
);
|
|
45
|
-
await expect(context.renderPartial(DummyView, {})).rejects.toThrow(
|
|
46
|
-
FILE_ROUTE_MIDDLEWARE_PIPELINE_ERRORS.CTX_RENDER_PARTIAL_UNAVAILABLE,
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
expect(context.require('user', () => new Response('missing', { status: 500 }))).toBe('andee');
|
|
50
|
-
expect(await context.html('<p>ok</p>').text()).toContain('<p>ok</p>');
|
|
51
|
-
expect(await context.json({ ok: true }).text()).toContain('{"ok":true}');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should execute middleware in order and eventually render the response', async () => {
|
|
55
|
-
const service = new FileRouteMiddlewarePipeline(null);
|
|
56
|
-
const context = service.createContext({
|
|
57
|
-
request: new Request('http://localhost:3000/hello'),
|
|
58
|
-
params: {},
|
|
59
|
-
locals: {},
|
|
60
|
-
});
|
|
61
|
-
const events: string[] = [];
|
|
62
|
-
|
|
63
|
-
const middleware: Middleware[] = [
|
|
64
|
-
async (ctx, next) => {
|
|
65
|
-
events.push('first:before');
|
|
66
|
-
ctx.locals.first = true;
|
|
67
|
-
const response = await next();
|
|
68
|
-
events.push('first:after');
|
|
69
|
-
return response;
|
|
70
|
-
},
|
|
71
|
-
async (ctx, next) => {
|
|
72
|
-
events.push('second');
|
|
73
|
-
expect(ctx.locals.first).toBe(true);
|
|
74
|
-
return next();
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
const response = await service.run({
|
|
79
|
-
middleware,
|
|
80
|
-
context,
|
|
81
|
-
renderResponse: async () => {
|
|
82
|
-
events.push('render');
|
|
83
|
-
return new Response('done');
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
expect(await response.text()).toBe('done');
|
|
88
|
-
expect(events).toEqual(['first:before', 'second', 'render', 'first:after']);
|
|
89
|
-
});
|
|
90
|
-
});
|