@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.
Files changed (354) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/package.json +212 -92
  3. package/src/adapters/abstract/application-adapter.d.ts +168 -0
  4. package/src/adapters/abstract/application-adapter.js +109 -0
  5. package/src/adapters/abstract/router-adapter.d.ts +26 -0
  6. package/src/adapters/abstract/router-adapter.js +5 -0
  7. package/src/adapters/abstract/server-adapter.d.ts +69 -0
  8. package/src/adapters/abstract/server-adapter.js +15 -0
  9. package/src/adapters/bun/client-bridge.d.ts +34 -0
  10. package/src/adapters/bun/client-bridge.js +48 -0
  11. package/src/adapters/bun/create-app.d.ts +60 -0
  12. package/src/adapters/bun/create-app.js +117 -0
  13. package/src/adapters/bun/hmr-manager.d.ts +143 -0
  14. package/src/adapters/bun/hmr-manager.js +334 -0
  15. package/src/adapters/bun/index.d.ts +2 -0
  16. package/src/adapters/bun/index.js +8 -0
  17. package/src/adapters/bun/server-adapter.d.ts +155 -0
  18. package/src/adapters/bun/server-adapter.js +373 -0
  19. package/src/adapters/bun/server-lifecycle.d.ts +63 -0
  20. package/src/adapters/bun/server-lifecycle.js +92 -0
  21. package/src/adapters/index.d.ts +6 -0
  22. package/src/adapters/index.js +14 -0
  23. package/src/adapters/node/bootstrap-dependency-resolver.d.ts +44 -0
  24. package/src/adapters/node/bootstrap-dependency-resolver.js +172 -0
  25. package/src/adapters/node/create-app.d.ts +21 -0
  26. package/src/adapters/node/create-app.js +143 -0
  27. package/src/adapters/node/index.d.ts +6 -0
  28. package/src/adapters/node/index.js +11 -0
  29. package/src/adapters/node/node-client-bridge.d.ts +26 -0
  30. package/src/adapters/node/node-client-bridge.js +66 -0
  31. package/src/adapters/node/node-hmr-manager.d.ts +133 -0
  32. package/src/adapters/node/node-hmr-manager.js +312 -0
  33. package/src/adapters/node/runtime-adapter.d.ts +46 -0
  34. package/src/adapters/node/runtime-adapter.js +306 -0
  35. package/src/adapters/node/server-adapter.d.ts +161 -0
  36. package/src/adapters/node/server-adapter.js +358 -0
  37. package/src/adapters/node/static-content-server.d.ts +60 -0
  38. package/src/adapters/node/static-content-server.js +194 -0
  39. package/src/adapters/node/write-runtime-manifest.d.ts +26 -0
  40. package/src/adapters/node/write-runtime-manifest.js +12 -0
  41. package/src/adapters/shared/api-response.d.ts +52 -0
  42. package/src/adapters/shared/api-response.js +96 -0
  43. package/src/adapters/shared/application-adapter.d.ts +18 -0
  44. package/src/adapters/shared/application-adapter.js +90 -0
  45. package/src/adapters/shared/define-api-handler.d.ts +25 -0
  46. package/src/adapters/shared/define-api-handler.js +15 -0
  47. package/src/adapters/shared/explicit-static-route-matcher.d.ts +38 -0
  48. package/src/adapters/shared/explicit-static-route-matcher.js +103 -0
  49. package/src/adapters/shared/file-route-middleware-pipeline.d.ts +65 -0
  50. package/src/adapters/shared/file-route-middleware-pipeline.js +99 -0
  51. package/src/adapters/shared/fs-server-response-factory.d.ts +19 -0
  52. package/src/adapters/shared/fs-server-response-factory.js +97 -0
  53. package/src/adapters/shared/fs-server-response-matcher.d.ts +75 -0
  54. package/src/adapters/shared/fs-server-response-matcher.js +160 -0
  55. package/src/adapters/shared/hmr-entrypoint-registrar.d.ts +55 -0
  56. package/src/adapters/shared/hmr-entrypoint-registrar.js +87 -0
  57. package/src/adapters/shared/hmr-html-response.d.ts +22 -0
  58. package/src/adapters/shared/hmr-html-response.js +32 -0
  59. package/src/adapters/shared/render-context.d.ts +14 -0
  60. package/src/adapters/shared/render-context.js +70 -0
  61. package/src/adapters/shared/runtime-bootstrap.d.ts +38 -0
  62. package/src/adapters/shared/runtime-bootstrap.js +43 -0
  63. package/src/adapters/shared/server-adapter.d.ts +97 -0
  64. package/src/adapters/shared/server-adapter.js +386 -0
  65. package/src/adapters/shared/server-route-handler.d.ts +89 -0
  66. package/src/adapters/shared/server-route-handler.js +111 -0
  67. package/src/adapters/shared/server-static-builder.d.ts +70 -0
  68. package/src/adapters/shared/server-static-builder.js +99 -0
  69. package/src/build/build-adapter.d.ts +186 -0
  70. package/src/build/build-adapter.js +168 -0
  71. package/src/build/build-manifest.d.ts +27 -0
  72. package/src/build/build-manifest.js +30 -0
  73. package/src/build/build-types.d.ts +57 -0
  74. package/src/build/build-types.js +0 -0
  75. package/src/build/dev-build-coordinator.d.ts +74 -0
  76. package/src/build/dev-build-coordinator.js +161 -0
  77. package/src/build/esbuild-build-adapter.d.ts +72 -0
  78. package/src/build/esbuild-build-adapter.js +422 -0
  79. package/src/build/runtime-build-executor.d.ts +13 -0
  80. package/src/build/runtime-build-executor.js +20 -0
  81. package/src/build/runtime-specifier-alias-plugin.d.ts +15 -0
  82. package/src/build/runtime-specifier-alias-plugin.js +31 -0
  83. package/src/config/config-builder.d.ts +238 -0
  84. package/src/config/config-builder.js +565 -0
  85. package/src/constants.d.ts +45 -0
  86. package/src/constants.js +25 -0
  87. package/src/create-app.d.ts +17 -0
  88. package/src/create-app.js +66 -0
  89. package/src/dev/sc-server.d.ts +30 -0
  90. package/src/dev/sc-server.js +111 -0
  91. package/src/eco/component-render-context.d.ts +105 -0
  92. package/src/eco/component-render-context.js +87 -0
  93. package/src/eco/eco.d.ts +9 -0
  94. package/src/eco/eco.js +114 -0
  95. package/src/eco/eco.types.d.ts +178 -0
  96. package/src/eco/eco.types.js +0 -0
  97. package/src/eco/eco.utils.d.ts +40 -0
  98. package/src/eco/eco.utils.js +40 -0
  99. package/src/eco/global-injector-map.d.ts +16 -0
  100. package/src/eco/global-injector-map.js +80 -0
  101. package/src/eco/lazy-injector-map.d.ts +8 -0
  102. package/src/eco/lazy-injector-map.js +70 -0
  103. package/src/eco/module-dependencies.d.ts +18 -0
  104. package/src/eco/module-dependencies.js +49 -0
  105. package/src/errors/http-error.d.ts +31 -0
  106. package/src/errors/http-error.js +50 -0
  107. package/src/errors/index.d.ts +2 -0
  108. package/src/errors/index.js +4 -0
  109. package/src/errors/locals-access-error.d.ts +4 -0
  110. package/src/errors/locals-access-error.js +9 -0
  111. package/src/global/app-logger.d.ts +2 -0
  112. package/src/global/app-logger.js +6 -0
  113. package/src/hmr/client/hmr-runtime.d.ts +5 -0
  114. package/src/hmr/client/hmr-runtime.js +109 -0
  115. package/src/hmr/hmr-strategy.d.ts +159 -0
  116. package/src/hmr/hmr-strategy.js +29 -0
  117. package/src/hmr/hmr.postcss.test.e2e.d.ts +1 -0
  118. package/src/hmr/hmr.postcss.test.e2e.js +31 -0
  119. package/src/hmr/hmr.test.e2e.d.ts +1 -0
  120. package/src/hmr/hmr.test.e2e.js +43 -0
  121. package/src/hmr/strategies/default-hmr-strategy.d.ts +43 -0
  122. package/src/hmr/strategies/default-hmr-strategy.js +34 -0
  123. package/src/hmr/strategies/js-hmr-strategy.d.ts +139 -0
  124. package/src/hmr/strategies/js-hmr-strategy.js +178 -0
  125. package/src/index.browser.d.ts +3 -0
  126. package/src/index.browser.js +4 -0
  127. package/src/index.d.ts +5 -0
  128. package/src/index.js +10 -0
  129. package/src/integrations/ghtml/ghtml-renderer.d.ts +15 -0
  130. package/src/integrations/ghtml/ghtml-renderer.js +62 -0
  131. package/src/integrations/ghtml/ghtml.plugin.d.ts +20 -0
  132. package/src/integrations/ghtml/ghtml.plugin.js +21 -0
  133. package/src/internal-types.d.ts +221 -0
  134. package/src/internal-types.js +0 -0
  135. package/src/plugins/alias-resolver-plugin.d.ts +2 -0
  136. package/src/plugins/alias-resolver-plugin.js +53 -0
  137. package/src/plugins/eco-component-meta-plugin.d.ts +97 -0
  138. package/src/plugins/eco-component-meta-plugin.js +157 -0
  139. package/src/plugins/integration-plugin.d.ts +136 -0
  140. package/src/plugins/integration-plugin.js +133 -0
  141. package/src/plugins/processor.d.ts +95 -0
  142. package/src/plugins/processor.js +136 -0
  143. package/src/plugins/runtime-capability.d.ts +9 -0
  144. package/src/plugins/runtime-capability.js +0 -0
  145. package/src/public-types.d.ts +1149 -0
  146. package/src/public-types.js +0 -0
  147. package/src/route-renderer/component-graph/component-graph-executor.d.ts +32 -0
  148. package/src/route-renderer/component-graph/component-graph-executor.js +31 -0
  149. package/src/route-renderer/component-graph/component-graph.d.ts +42 -0
  150. package/src/route-renderer/component-graph/component-graph.js +72 -0
  151. package/src/route-renderer/component-graph/component-marker.d.ts +52 -0
  152. package/src/route-renderer/component-graph/component-marker.js +46 -0
  153. package/src/route-renderer/component-graph/component-reference.d.ts +10 -0
  154. package/src/route-renderer/component-graph/component-reference.js +19 -0
  155. package/src/route-renderer/component-graph/marker-graph-resolver.d.ts +77 -0
  156. package/src/route-renderer/component-graph/marker-graph-resolver.js +95 -0
  157. package/src/route-renderer/orchestration/integration-renderer.d.ts +372 -0
  158. package/src/route-renderer/orchestration/integration-renderer.js +589 -0
  159. package/src/route-renderer/orchestration/render-execution.service.d.ts +103 -0
  160. package/src/route-renderer/orchestration/render-execution.service.js +121 -0
  161. package/src/route-renderer/orchestration/render-preparation.service.d.ts +121 -0
  162. package/src/route-renderer/orchestration/render-preparation.service.js +332 -0
  163. package/src/route-renderer/page-loading/dependency-resolver.d.ts +35 -0
  164. package/src/route-renderer/page-loading/dependency-resolver.js +442 -0
  165. package/src/route-renderer/page-loading/page-module-loader.d.ts +87 -0
  166. package/src/route-renderer/page-loading/page-module-loader.js +124 -0
  167. package/src/route-renderer/route-renderer.d.ts +61 -0
  168. package/src/route-renderer/route-renderer.js +87 -0
  169. package/src/router/client/link-intent.js +34 -0
  170. package/src/router/client/link-intent.test.browser.d.ts +1 -0
  171. package/src/router/client/link-intent.test.browser.js +43 -0
  172. package/src/router/client/navigation-coordinator.d.ts +149 -0
  173. package/src/router/client/navigation-coordinator.js +215 -0
  174. package/src/router/server/fs-router-scanner.d.ts +41 -0
  175. package/src/router/server/fs-router-scanner.js +156 -0
  176. package/src/router/server/fs-router.d.ts +26 -0
  177. package/src/router/server/fs-router.js +100 -0
  178. package/src/services/assets/asset-processing-service/asset-processing.service.d.ts +120 -0
  179. package/src/services/assets/asset-processing-service/asset-processing.service.js +331 -0
  180. package/src/services/assets/asset-processing-service/asset.factory.d.ts +17 -0
  181. package/src/services/assets/asset-processing-service/asset.factory.js +82 -0
  182. package/src/services/assets/asset-processing-service/assets.types.d.ts +89 -0
  183. package/src/services/assets/asset-processing-service/assets.types.js +0 -0
  184. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.d.ts +55 -0
  185. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.js +48 -0
  186. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.d.ts +20 -0
  187. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.js +41 -0
  188. package/src/services/assets/asset-processing-service/index.d.ts +5 -0
  189. package/src/services/assets/asset-processing-service/index.js +5 -0
  190. package/src/services/assets/asset-processing-service/processor.interface.d.ts +22 -0
  191. package/src/services/assets/asset-processing-service/processor.interface.js +6 -0
  192. package/src/services/assets/asset-processing-service/processor.registry.d.ts +8 -0
  193. package/src/services/assets/asset-processing-service/processor.registry.js +15 -0
  194. package/src/services/assets/asset-processing-service/processors/base/base-processor.d.ts +24 -0
  195. package/src/services/assets/asset-processing-service/processors/base/base-processor.js +64 -0
  196. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.d.ts +17 -0
  197. package/src/services/assets/asset-processing-service/processors/base/base-script-processor.js +72 -0
  198. package/src/services/assets/asset-processing-service/processors/index.d.ts +5 -0
  199. package/src/services/assets/asset-processing-service/processors/index.js +5 -0
  200. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.d.ts +5 -0
  201. package/src/services/assets/asset-processing-service/processors/script/content-script.processor.js +57 -0
  202. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.d.ts +8 -0
  203. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.js +76 -0
  204. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.d.ts +7 -0
  205. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.js +75 -0
  206. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.d.ts +5 -0
  207. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.js +25 -0
  208. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.d.ts +9 -0
  209. package/src/services/assets/asset-processing-service/processors/stylesheet/file-stylesheet.processor.js +66 -0
  210. package/src/services/assets/browser-bundle.service.d.ts +32 -0
  211. package/src/services/assets/browser-bundle.service.js +33 -0
  212. package/src/services/cache/cache.types.d.ts +107 -0
  213. package/src/services/cache/cache.types.js +0 -0
  214. package/src/services/cache/index.d.ts +7 -0
  215. package/src/services/cache/index.js +7 -0
  216. package/src/services/cache/memory-cache-store.d.ts +42 -0
  217. package/src/services/cache/memory-cache-store.js +98 -0
  218. package/src/services/cache/page-cache-service.d.ts +70 -0
  219. package/src/services/cache/page-cache-service.js +152 -0
  220. package/src/services/cache/page-request-cache-coordinator.service.d.ts +75 -0
  221. package/src/services/cache/page-request-cache-coordinator.service.js +109 -0
  222. package/src/services/html/html-rewriter-provider.service.d.ts +37 -0
  223. package/src/services/html/html-rewriter-provider.service.js +65 -0
  224. package/src/services/html/html-transformer.service.d.ts +77 -0
  225. package/src/services/html/html-transformer.service.js +221 -0
  226. package/src/services/invalidation/development-invalidation.service.d.ts +74 -0
  227. package/src/services/invalidation/development-invalidation.service.js +189 -0
  228. package/src/services/module-loading/app-server-module-transpiler.service.d.ts +16 -0
  229. package/src/services/module-loading/app-server-module-transpiler.service.js +34 -0
  230. package/src/services/module-loading/page-module-import.service.d.ts +71 -0
  231. package/src/services/module-loading/page-module-import.service.js +132 -0
  232. package/src/services/module-loading/server-loader.service.d.ts +96 -0
  233. package/src/services/module-loading/server-loader.service.js +32 -0
  234. package/src/services/module-loading/server-module-transpiler.service.d.ts +69 -0
  235. package/src/services/module-loading/server-module-transpiler.service.js +61 -0
  236. package/src/services/runtime-manifest/node-runtime-manifest.service.d.ts +35 -0
  237. package/src/services/runtime-manifest/node-runtime-manifest.service.js +60 -0
  238. package/src/services/runtime-state/dev-graph.service.d.ts +118 -0
  239. package/src/services/runtime-state/dev-graph.service.js +162 -0
  240. package/src/services/runtime-state/entrypoint-dependency-graph.service.d.ts +41 -0
  241. package/src/services/runtime-state/entrypoint-dependency-graph.service.js +85 -0
  242. package/src/services/runtime-state/runtime-specifier-registry.service.d.ts +69 -0
  243. package/src/services/runtime-state/runtime-specifier-registry.service.js +37 -0
  244. package/src/services/runtime-state/server-invalidation-state.service.d.ts +26 -0
  245. package/src/services/runtime-state/server-invalidation-state.service.js +35 -0
  246. package/src/services/validation/schema-validation-service.d.ts +122 -0
  247. package/src/services/validation/schema-validation-service.js +101 -0
  248. package/src/services/validation/standard-schema.types.d.ts +65 -0
  249. package/src/services/validation/standard-schema.types.js +0 -0
  250. package/src/static-site-generator/static-site-generator.d.ts +109 -0
  251. package/src/static-site-generator/static-site-generator.js +353 -0
  252. package/src/utils/css.d.ts +1 -0
  253. package/src/utils/css.js +7 -0
  254. package/src/utils/deep-merge.d.ts +14 -0
  255. package/src/utils/deep-merge.js +32 -0
  256. package/src/utils/hash.d.ts +1 -0
  257. package/src/utils/hash.js +7 -0
  258. package/src/utils/html.d.ts +1 -0
  259. package/src/utils/html.js +4 -0
  260. package/src/utils/invariant.d.ts +5 -0
  261. package/src/utils/invariant.js +11 -0
  262. package/src/utils/locals-utils.d.ts +15 -0
  263. package/src/utils/locals-utils.js +24 -0
  264. package/src/utils/parse-cli-args.d.ts +24 -0
  265. package/src/utils/parse-cli-args.js +47 -0
  266. package/src/utils/path-utils.module.d.ts +5 -0
  267. package/src/utils/path-utils.module.js +14 -0
  268. package/src/utils/resolve-work-dir.d.ts +11 -0
  269. package/src/utils/resolve-work-dir.js +31 -0
  270. package/src/utils/runtime.d.ts +11 -0
  271. package/src/utils/runtime.js +40 -0
  272. package/src/utils/server-utils.module.d.ts +19 -0
  273. package/src/utils/server-utils.module.js +56 -0
  274. package/src/watchers/project-watcher.d.ts +136 -0
  275. package/src/watchers/project-watcher.js +281 -0
  276. package/src/watchers/project-watcher.test-helpers.d.ts +4 -0
  277. package/src/watchers/project-watcher.test-helpers.js +52 -0
  278. package/src/adapters/bun/hmr-manager.test.ts +0 -267
  279. package/src/adapters/node/bootstrap-dependency-resolver.test.ts +0 -282
  280. package/src/adapters/node/node-client-bridge.test.ts +0 -198
  281. package/src/adapters/node/node-hmr-manager.test.ts +0 -322
  282. package/src/adapters/node/runtime-adapter.test.ts +0 -868
  283. package/src/adapters/node/static-content-server.test.ts +0 -60
  284. package/src/adapters/shared/api-response.test.ts +0 -97
  285. package/src/adapters/shared/explicit-static-route-matcher.test.ts +0 -381
  286. package/src/adapters/shared/file-route-middleware-pipeline.test.ts +0 -90
  287. package/src/adapters/shared/fs-server-response-factory.test.ts +0 -187
  288. package/src/adapters/shared/fs-server-response-matcher.test.ts +0 -286
  289. package/src/adapters/shared/hmr-manager.contract.test.ts +0 -196
  290. package/src/adapters/shared/hmr-manager.dispatch.test.ts +0 -220
  291. package/src/adapters/shared/render-context.test.ts +0 -146
  292. package/src/adapters/shared/server-adapter.test.ts +0 -77
  293. package/src/adapters/shared/server-route-handler.test.ts +0 -110
  294. package/src/adapters/shared/server-static-builder.test.ts +0 -316
  295. package/src/build/build-adapter-serialization.test.ts +0 -268
  296. package/src/build/build-adapter.test.ts +0 -815
  297. package/src/build/runtime-specifier-alias-plugin.test.ts +0 -43
  298. package/src/config/config-builder.test.ts +0 -410
  299. package/src/eco/eco.test.ts +0 -678
  300. package/src/eco/eco.utils.test.ts +0 -124
  301. package/src/eco/global-injector-map.test.ts +0 -42
  302. package/src/eco/lazy-injector-map.test.ts +0 -66
  303. package/src/eco/module-dependencies.test.ts +0 -30
  304. package/src/errors/http-error.test.ts +0 -134
  305. package/src/global/utils.test.ts +0 -12
  306. 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
  307. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-HMR-Server-Integration-should-load-fixture-app-page-1.png +0 -0
  308. package/src/hmr/client/__screenshots__/hmr-runtime.test.browser.ts/HMR-Runtime-WebSocket-Connection-should-connect-to-correct-HMR-endpoint-1.png +0 -0
  309. package/src/hmr/hmr-strategy.test.ts +0 -124
  310. package/src/hmr/strategies/js-hmr-strategy.test.ts +0 -335
  311. package/src/integrations/ghtml/ghtml-renderer.test.ts +0 -63
  312. package/src/plugins/alias-resolver-plugin.test.ts +0 -41
  313. package/src/plugins/eco-component-meta-plugin.test.ts +0 -380
  314. package/src/plugins/integration-plugin.test.ts +0 -111
  315. package/src/plugins/processor.test.ts +0 -148
  316. package/src/route-renderer/component-graph/component-graph-executor.test.ts +0 -41
  317. package/src/route-renderer/component-graph/component-graph.test.ts +0 -63
  318. package/src/route-renderer/component-graph/component-marker.test.ts +0 -73
  319. package/src/route-renderer/component-graph/marker-graph-resolver.test.ts +0 -135
  320. package/src/route-renderer/orchestration/integration-renderer.test.ts +0 -936
  321. package/src/route-renderer/orchestration/render-execution.service.test.ts +0 -97
  322. package/src/route-renderer/orchestration/render-preparation.service.test.ts +0 -235
  323. package/src/route-renderer/page-loading/dependency-resolver.test.ts +0 -345
  324. package/src/route-renderer/page-loading/page-module-loader.test.ts +0 -96
  325. package/src/router/client/navigation-coordinator.test.ts +0 -237
  326. package/src/router/server/fs-router-scanner.test.ts +0 -83
  327. package/src/router/server/fs-router.test.ts +0 -214
  328. package/src/services/assets/asset-processing-service/asset-processing.service.test.ts +0 -385
  329. package/src/services/assets/asset-processing-service/asset.factory.test.ts +0 -63
  330. package/src/services/assets/asset-processing-service/browser-runtime-asset.factory.test.ts +0 -72
  331. package/src/services/assets/asset-processing-service/browser-runtime-entry.factory.test.ts +0 -67
  332. package/src/services/assets/asset-processing-service/processors/base/base-processor.test.ts +0 -59
  333. package/src/services/assets/asset-processing-service/processors/script/file-script.processor.test.ts +0 -286
  334. package/src/services/assets/asset-processing-service/processors/script/node-module-script.processor.test.ts +0 -227
  335. package/src/services/assets/asset-processing-service/processors/stylesheet/content-stylesheet.processor.test.ts +0 -199
  336. package/src/services/assets/browser-bundle.service.test.ts +0 -36
  337. package/src/services/cache/memory-cache-store.test.ts +0 -225
  338. package/src/services/cache/page-cache-service.test.ts +0 -175
  339. package/src/services/cache/page-request-cache-coordinator.service.test.ts +0 -79
  340. package/src/services/html/html-rewriter-provider.service.test.ts +0 -183
  341. package/src/services/html/html-transformer.service.test.ts +0 -378
  342. package/src/services/invalidation/development-invalidation.service.test.ts +0 -77
  343. package/src/services/module-loading/page-module-import.service.test.ts +0 -253
  344. package/src/services/module-loading/server-loader.service.test.ts +0 -161
  345. package/src/services/module-loading/server-module-transpiler.service.test.ts +0 -115
  346. package/src/services/runtime-manifest/node-runtime-manifest.service.test.ts +0 -95
  347. package/src/services/validation/schema-validation-service.test.ts +0 -223
  348. package/src/static-site-generator/static-site-generator.test.ts +0 -307
  349. package/src/utils/deep-merge.test.ts +0 -114
  350. package/src/utils/invariant.test.ts +0 -22
  351. package/src/utils/path-utils.test.ts +0 -15
  352. package/src/utils/server-utils.test.ts +0 -38
  353. package/src/watchers/project-watcher.integration.test.ts +0 -337
  354. 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
- });