veryfront 0.1.128 → 0.1.129

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 (382) hide show
  1. package/esm/cli/router.d.ts +0 -5
  2. package/esm/cli/router.d.ts.map +1 -1
  3. package/esm/cli/router.js +30 -2
  4. package/esm/cli/shared/update-check.d.ts +4 -0
  5. package/esm/cli/shared/update-check.d.ts.map +1 -0
  6. package/esm/cli/shared/update-check.js +97 -0
  7. package/esm/deno.d.ts +5 -0
  8. package/esm/deno.js +13 -8
  9. package/esm/src/channels/control-plane.d.ts.map +1 -1
  10. package/esm/src/channels/control-plane.js +5 -5
  11. package/esm/src/channels/invoke.d.ts +1 -1
  12. package/esm/src/channels/invoke.d.ts.map +1 -1
  13. package/esm/src/channels/invoke.js +6 -6
  14. package/esm/src/chat/index.d.ts +12 -24
  15. package/esm/src/chat/index.d.ts.map +1 -1
  16. package/esm/src/chat/index.js +5 -25
  17. package/esm/src/config/env.d.ts.map +1 -1
  18. package/esm/src/config/env.js +18 -10
  19. package/esm/src/data/static-data-fetcher.d.ts +3 -0
  20. package/esm/src/data/static-data-fetcher.d.ts.map +1 -1
  21. package/esm/src/data/static-data-fetcher.js +29 -25
  22. package/esm/src/data/static-paths-fetcher.d.ts.map +1 -1
  23. package/esm/src/data/static-paths-fetcher.js +3 -2
  24. package/esm/src/errors/logging.d.ts.map +1 -1
  25. package/esm/src/errors/logging.js +16 -7
  26. package/esm/src/errors/user-friendly/error-formatter.d.ts.map +1 -1
  27. package/esm/src/errors/user-friendly/error-formatter.js +9 -25
  28. package/esm/src/fs/index.d.ts +11 -12
  29. package/esm/src/fs/index.d.ts.map +1 -1
  30. package/esm/src/fs/index.js +11 -24
  31. package/esm/src/html/dev-scripts.d.ts.map +1 -1
  32. package/esm/src/html/dev-scripts.js +5 -8
  33. package/esm/src/html/html-escape.d.ts +1 -0
  34. package/esm/src/html/html-escape.d.ts.map +1 -1
  35. package/esm/src/html/html-escape.js +3 -0
  36. package/esm/src/html/html-injection.js +2 -2
  37. package/esm/src/html/html-shell-generator.d.ts +5 -2
  38. package/esm/src/html/html-shell-generator.d.ts.map +1 -1
  39. package/esm/src/html/html-shell-generator.js +41 -30
  40. package/esm/src/html/hydration-script-builder/dev-client-renderer.js +2 -2
  41. package/esm/src/html/hydration-script-builder/dev-component-manifest.js +2 -2
  42. package/esm/src/html/hydration-script-builder/dev-error-logger.d.ts.map +1 -1
  43. package/esm/src/html/hydration-script-builder/dev-error-logger.js +2 -6
  44. package/esm/src/html/hydration-script-builder/dev-scripts.js +2 -2
  45. package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts +3 -1
  46. package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts.map +1 -1
  47. package/esm/src/html/hydration-script-builder/hydration-data-generator.js +2 -2
  48. package/esm/src/html/hydration-script-builder/index.d.ts +1 -1
  49. package/esm/src/html/hydration-script-builder/index.d.ts.map +1 -1
  50. package/esm/src/html/hydration-script-builder/index.js +1 -1
  51. package/esm/src/html/hydration-script-builder/prod-hydration.js +2 -2
  52. package/esm/src/html/hydration-script-builder/prod-scripts.d.ts +2 -0
  53. package/esm/src/html/hydration-script-builder/prod-scripts.d.ts.map +1 -1
  54. package/esm/src/html/hydration-script-builder/prod-scripts.js +14 -14
  55. package/esm/src/html/schemas/html.schema.d.ts +2 -0
  56. package/esm/src/html/schemas/html.schema.d.ts.map +1 -1
  57. package/esm/src/html/schemas/html.schema.js +2 -0
  58. package/esm/src/html/styles-builder/css-pregeneration.d.ts +17 -1
  59. package/esm/src/html/styles-builder/css-pregeneration.d.ts.map +1 -1
  60. package/esm/src/html/styles-builder/css-pregeneration.js +103 -1
  61. package/esm/src/html/styles-builder/dev-styles.js +2 -2
  62. package/esm/src/html/utils.d.ts +2 -0
  63. package/esm/src/html/utils.d.ts.map +1 -1
  64. package/esm/src/html/utils.js +49 -28
  65. package/esm/src/integrations/remote-tools.d.ts.map +1 -1
  66. package/esm/src/integrations/remote-tools.js +32 -39
  67. package/esm/src/internal-agents/ag-ui-sse.d.ts +0 -1
  68. package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -1
  69. package/esm/src/internal-agents/ag-ui-sse.js +2 -16
  70. package/esm/src/internal-agents/control-plane-auth.d.ts.map +1 -1
  71. package/esm/src/internal-agents/control-plane-auth.js +5 -3
  72. package/esm/src/internal-agents/request-body.d.ts.map +1 -1
  73. package/esm/src/internal-agents/request-body.js +6 -3
  74. package/esm/src/internal-agents/session-manager.d.ts +1 -0
  75. package/esm/src/internal-agents/session-manager.d.ts.map +1 -1
  76. package/esm/src/internal-agents/session-manager.js +12 -18
  77. package/esm/src/issues/core.d.ts.map +1 -1
  78. package/esm/src/issues/core.js +24 -23
  79. package/esm/src/issues/schemas/issue.schema.d.ts.map +1 -1
  80. package/esm/src/issues/schemas/issue.schema.js +2 -1
  81. package/esm/src/jobs/runtime-env.d.ts.map +1 -1
  82. package/esm/src/jobs/runtime-env.js +21 -44
  83. package/esm/src/markdown/index.d.ts +1 -2
  84. package/esm/src/markdown/index.d.ts.map +1 -1
  85. package/esm/src/markdown/index.js +1 -6
  86. package/esm/src/mcp/server.d.ts +0 -1
  87. package/esm/src/mcp/server.d.ts.map +1 -1
  88. package/esm/src/mcp/server.js +40 -41
  89. package/esm/src/mdx/index.d.ts +3 -2
  90. package/esm/src/mdx/index.d.ts.map +1 -1
  91. package/esm/src/mdx/index.js +3 -5
  92. package/esm/src/middleware/builtin/logger.d.ts.map +1 -1
  93. package/esm/src/middleware/builtin/logger.js +31 -28
  94. package/esm/src/middleware/builtin/security/rate-limit.d.ts.map +1 -1
  95. package/esm/src/middleware/builtin/security/rate-limit.js +17 -12
  96. package/esm/src/middleware/builtin/timeout.d.ts.map +1 -1
  97. package/esm/src/middleware/builtin/timeout.js +17 -10
  98. package/esm/src/modules/import-map/default-import-map.d.ts.map +1 -1
  99. package/esm/src/modules/import-map/default-import-map.js +4 -3
  100. package/esm/src/oauth/handlers/callback-handler.d.ts +0 -5
  101. package/esm/src/oauth/handlers/callback-handler.d.ts.map +1 -1
  102. package/esm/src/oauth/handlers/callback-handler.js +9 -14
  103. package/esm/src/oauth/handlers/index.d.ts +1 -1
  104. package/esm/src/oauth/handlers/index.js +1 -1
  105. package/esm/src/oauth/handlers/init-handler.d.ts.map +1 -1
  106. package/esm/src/oauth/handlers/init-handler.js +32 -20
  107. package/esm/src/oauth/providers/index.d.ts +1 -1
  108. package/esm/src/oauth/providers/index.js +1 -1
  109. package/esm/src/oauth/schemas/index.d.ts +1 -1
  110. package/esm/src/oauth/schemas/index.js +1 -1
  111. package/esm/src/oauth/token-store/index.d.ts +1 -1
  112. package/esm/src/oauth/token-store/index.js +1 -1
  113. package/esm/src/oauth/token-store/memory.d.ts +1 -1
  114. package/esm/src/oauth/token-store/memory.d.ts.map +1 -1
  115. package/esm/src/oauth/token-store/memory.js +8 -8
  116. package/esm/src/observability/request-profiler.d.ts +31 -0
  117. package/esm/src/observability/request-profiler.d.ts.map +1 -0
  118. package/esm/src/observability/request-profiler.js +94 -0
  119. package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
  120. package/esm/src/observability/tracing/otlp-setup.js +16 -21
  121. package/esm/src/prompt/factory.d.ts.map +1 -1
  122. package/esm/src/prompt/factory.js +10 -12
  123. package/esm/src/prompt/registry.d.ts.map +1 -1
  124. package/esm/src/prompt/registry.js +12 -10
  125. package/esm/src/prompt/schemas/prompt.schema.d.ts.map +1 -1
  126. package/esm/src/prompt/schemas/prompt.schema.js +0 -2
  127. package/esm/src/prompt/types.d.ts +1 -1
  128. package/esm/src/prompt/types.d.ts.map +1 -1
  129. package/esm/src/provider/local/ai-sdk-adapter.d.ts.map +1 -1
  130. package/esm/src/provider/local/ai-sdk-adapter.js +3 -8
  131. package/esm/src/provider/local/env.d.ts +4 -6
  132. package/esm/src/provider/local/env.d.ts.map +1 -1
  133. package/esm/src/provider/local/env.js +14 -1
  134. package/esm/src/provider/local/local-engine.d.ts.map +1 -1
  135. package/esm/src/provider/local/local-engine.js +2 -7
  136. package/esm/src/provider/model-registry.d.ts.map +1 -1
  137. package/esm/src/provider/model-registry.js +2 -7
  138. package/esm/src/provider/veryfront-cloud/provider.d.ts.map +1 -1
  139. package/esm/src/provider/veryfront-cloud/provider.js +1 -7
  140. package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
  141. package/esm/src/provider/veryfront-cloud/shared.js +9 -11
  142. package/esm/src/proxy/handler.d.ts.map +1 -1
  143. package/esm/src/proxy/handler.js +56 -57
  144. package/esm/src/react/compat/hooks-adapter.d.ts +1 -7
  145. package/esm/src/react/compat/hooks-adapter.d.ts.map +1 -1
  146. package/esm/src/react/compat/hooks-adapter.js +35 -40
  147. package/esm/src/react/components/Head.d.ts +1 -26
  148. package/esm/src/react/components/Head.d.ts.map +1 -1
  149. package/esm/src/react/components/Head.js +1 -172
  150. package/esm/src/react/context/index.d.ts +2 -46
  151. package/esm/src/react/context/index.d.ts.map +1 -1
  152. package/esm/src/react/context/index.js +1 -44
  153. package/esm/src/react/head-collector.d.ts +1 -10
  154. package/esm/src/react/head-collector.d.ts.map +1 -1
  155. package/esm/src/react/head-collector.js +4 -0
  156. package/esm/src/react/router/index.d.ts +2 -45
  157. package/esm/src/react/router/index.d.ts.map +1 -1
  158. package/esm/src/react/router/index.js +1 -49
  159. package/esm/src/react/runtime/core.d.ts +49 -0
  160. package/esm/src/react/runtime/core.d.ts.map +1 -0
  161. package/esm/src/react/runtime/core.js +200 -0
  162. package/esm/src/rendering/orchestrator/html.d.ts +2 -0
  163. package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
  164. package/esm/src/rendering/orchestrator/html.js +69 -12
  165. package/esm/src/rendering/orchestrator/ssr-orchestrator.d.ts.map +1 -1
  166. package/esm/src/rendering/orchestrator/ssr-orchestrator.js +4 -0
  167. package/esm/src/rendering/orchestrator/types.d.ts +4 -0
  168. package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
  169. package/esm/src/repositories/types.d.ts.map +1 -1
  170. package/esm/src/resource/factory.d.ts.map +1 -1
  171. package/esm/src/resource/factory.js +12 -9
  172. package/esm/src/resource/registry.d.ts +3 -3
  173. package/esm/src/resource/registry.d.ts.map +1 -1
  174. package/esm/src/resource/registry.js +7 -7
  175. package/esm/src/schemas/common.d.ts.map +1 -1
  176. package/esm/src/schemas/common.js +7 -4
  177. package/esm/src/security/http/config.d.ts +0 -1
  178. package/esm/src/security/http/config.d.ts.map +1 -1
  179. package/esm/src/security/http/config.js +3 -16
  180. package/esm/src/security/http/response/security-handler.d.ts +1 -0
  181. package/esm/src/security/http/response/security-handler.d.ts.map +1 -1
  182. package/esm/src/security/http/response/security-handler.js +17 -12
  183. package/esm/src/security/index.d.ts +4 -2
  184. package/esm/src/security/index.d.ts.map +1 -1
  185. package/esm/src/security/index.js +3 -1
  186. package/esm/src/server/handlers/dev/styles-css.handler.d.ts.map +1 -1
  187. package/esm/src/server/handlers/dev/styles-css.handler.js +8 -7
  188. package/esm/src/server/handlers/monitoring/metrics.handler.d.ts.map +1 -1
  189. package/esm/src/server/handlers/monitoring/metrics.handler.js +3 -1
  190. package/esm/src/server/handlers/request/module/module-server-handler.d.ts.map +1 -1
  191. package/esm/src/server/handlers/request/module/module-server-handler.js +18 -15
  192. package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts +8 -0
  193. package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts.map +1 -0
  194. package/esm/src/server/handlers/request/prod-hydration-module.handler.js +41 -0
  195. package/esm/src/server/handlers/request/ssr/ssr.handler.d.ts.map +1 -1
  196. package/esm/src/server/handlers/request/ssr/ssr.handler.js +3 -0
  197. package/esm/src/server/production-server.d.ts.map +1 -1
  198. package/esm/src/server/production-server.js +65 -0
  199. package/esm/src/server/runtime-handler/handler-context-builder.d.ts +1 -1
  200. package/esm/src/server/runtime-handler/handler-context-builder.d.ts.map +1 -1
  201. package/esm/src/server/runtime-handler/index.d.ts +1 -1
  202. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  203. package/esm/src/server/runtime-handler/index.js +36 -11
  204. package/esm/src/server/runtime-handler/request-utils.d.ts +7 -0
  205. package/esm/src/server/runtime-handler/request-utils.d.ts.map +1 -1
  206. package/esm/src/server/runtime-handler/request-utils.js +10 -0
  207. package/esm/src/server/services/rendering/ssr.service.d.ts +1 -0
  208. package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
  209. package/esm/src/server/services/rendering/ssr.service.js +12 -5
  210. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
  211. package/esm/src/skill/allowed-tools.d.ts +3 -8
  212. package/esm/src/skill/allowed-tools.d.ts.map +1 -1
  213. package/esm/src/skill/executor.js +2 -2
  214. package/esm/src/skill/parser.d.ts.map +1 -1
  215. package/esm/src/skill/parser.js +12 -12
  216. package/esm/src/skill/path-safety.js +1 -1
  217. package/esm/src/skill/tools.d.ts.map +1 -1
  218. package/esm/src/skill/tools.js +18 -11
  219. package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
  220. package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
  221. package/esm/src/task/discovery.d.ts.map +1 -1
  222. package/esm/src/task/discovery.js +73 -95
  223. package/esm/src/tool/executor.d.ts.map +1 -1
  224. package/esm/src/tool/executor.js +8 -7
  225. package/esm/src/tool/factory.d.ts.map +1 -1
  226. package/esm/src/tool/factory.js +13 -16
  227. package/esm/src/transforms/esm/package-registry.d.ts +4 -0
  228. package/esm/src/transforms/esm/package-registry.d.ts.map +1 -1
  229. package/esm/src/transforms/esm/package-registry.js +34 -17
  230. package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.d.ts.map +1 -1
  231. package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.js +2 -1
  232. package/esm/src/transforms/mdx/esm-module-loader/cache-format.d.ts.map +1 -1
  233. package/esm/src/transforms/mdx/esm-module-loader/cache-format.js +26 -1
  234. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts +1 -1
  235. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
  236. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +1 -1
  237. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts +1 -0
  238. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts.map +1 -1
  239. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.js +3 -0
  240. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.d.ts +1 -1
  241. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.js +1 -1
  242. package/esm/src/transforms/veryfront-module-urls.d.ts.map +1 -1
  243. package/esm/src/transforms/veryfront-module-urls.js +7 -3
  244. package/esm/src/types/entities/getEntityInfo.d.ts.map +1 -1
  245. package/esm/src/types/entities/getEntityInfo.js +79 -127
  246. package/esm/src/utils/path-utils.d.ts +1 -1
  247. package/esm/src/utils/path-utils.d.ts.map +1 -1
  248. package/esm/src/utils/path-utils.js +16 -7
  249. package/esm/src/utils/version-constant.d.ts +1 -1
  250. package/esm/src/utils/version-constant.js +1 -1
  251. package/esm/src/utils/version.d.ts.map +1 -1
  252. package/esm/src/utils/version.js +0 -1
  253. package/esm/src/workflow/worker/dynamic-job-entrypoint.d.ts.map +1 -1
  254. package/esm/src/workflow/worker/dynamic-job-entrypoint.js +5 -72
  255. package/esm/src/workflow/worker/job-entrypoint.d.ts.map +1 -1
  256. package/esm/src/workflow/worker/job-entrypoint.js +5 -72
  257. package/esm/src/workflow/worker/shared.d.ts +18 -0
  258. package/esm/src/workflow/worker/shared.d.ts.map +1 -0
  259. package/esm/src/workflow/worker/shared.js +77 -0
  260. package/package.json +1 -1
  261. package/src/cli/router.ts +41 -2
  262. package/src/cli/shared/update-check.ts +110 -0
  263. package/src/deno.js +13 -8
  264. package/src/src/channels/control-plane.ts +6 -10
  265. package/src/src/channels/invoke.ts +7 -7
  266. package/src/src/chat/index.ts +96 -132
  267. package/src/src/config/env.ts +24 -11
  268. package/src/src/data/static-data-fetcher.ts +59 -34
  269. package/src/src/data/static-paths-fetcher.ts +4 -2
  270. package/src/src/errors/logging.ts +21 -7
  271. package/src/src/errors/user-friendly/error-formatter.ts +14 -29
  272. package/src/src/fs/index.ts +21 -30
  273. package/src/src/html/dev-scripts.ts +5 -9
  274. package/src/src/html/html-escape.ts +4 -0
  275. package/src/src/html/html-injection.ts +2 -2
  276. package/src/src/html/html-shell-generator.ts +60 -26
  277. package/src/src/html/hydration-script-builder/dev-client-renderer.ts +2 -2
  278. package/src/src/html/hydration-script-builder/dev-component-manifest.ts +2 -2
  279. package/src/src/html/hydration-script-builder/dev-error-logger.ts +2 -8
  280. package/src/src/html/hydration-script-builder/dev-scripts.ts +2 -2
  281. package/src/src/html/hydration-script-builder/hydration-data-generator.ts +2 -1
  282. package/src/src/html/hydration-script-builder/index.ts +5 -1
  283. package/src/src/html/hydration-script-builder/prod-hydration.ts +2 -2
  284. package/src/src/html/hydration-script-builder/prod-scripts.ts +16 -15
  285. package/src/src/html/schemas/html.schema.ts +2 -0
  286. package/src/src/html/styles-builder/css-pregeneration.ts +133 -1
  287. package/src/src/html/styles-builder/dev-styles.ts +2 -2
  288. package/src/src/html/utils.ts +62 -29
  289. package/src/src/integrations/remote-tools.ts +39 -37
  290. package/src/src/internal-agents/ag-ui-sse.ts +2 -17
  291. package/src/src/internal-agents/control-plane-auth.ts +8 -6
  292. package/src/src/internal-agents/request-body.ts +7 -5
  293. package/src/src/internal-agents/session-manager.ts +16 -20
  294. package/src/src/issues/core.ts +24 -27
  295. package/src/src/issues/schemas/issue.schema.ts +3 -1
  296. package/src/src/jobs/runtime-env.ts +24 -50
  297. package/src/src/markdown/index.ts +5 -8
  298. package/src/src/mcp/server.ts +50 -53
  299. package/src/src/mdx/index.ts +7 -8
  300. package/src/src/middleware/builtin/logger.ts +44 -29
  301. package/src/src/middleware/builtin/security/rate-limit.ts +20 -11
  302. package/src/src/middleware/builtin/timeout.ts +22 -13
  303. package/src/src/modules/import-map/default-import-map.ts +4 -3
  304. package/src/src/oauth/handlers/callback-handler.ts +9 -16
  305. package/src/src/oauth/handlers/index.ts +1 -1
  306. package/src/src/oauth/handlers/init-handler.ts +56 -27
  307. package/src/src/oauth/providers/index.ts +1 -1
  308. package/src/src/oauth/schemas/index.ts +1 -1
  309. package/src/src/oauth/token-store/index.ts +1 -1
  310. package/src/src/oauth/token-store/memory.ts +8 -8
  311. package/src/src/observability/request-profiler.ts +140 -0
  312. package/src/src/observability/tracing/otlp-setup.ts +16 -22
  313. package/src/src/prompt/factory.ts +16 -14
  314. package/src/src/prompt/registry.ts +14 -13
  315. package/src/src/prompt/schemas/prompt.schema.ts +0 -4
  316. package/src/src/prompt/types.ts +1 -2
  317. package/src/src/provider/local/ai-sdk-adapter.ts +3 -10
  318. package/src/src/provider/local/env.ts +22 -2
  319. package/src/src/provider/local/local-engine.ts +2 -9
  320. package/src/src/provider/model-registry.ts +2 -9
  321. package/src/src/provider/veryfront-cloud/provider.ts +1 -8
  322. package/src/src/provider/veryfront-cloud/shared.ts +12 -15
  323. package/src/src/proxy/handler.ts +90 -74
  324. package/src/src/react/compat/hooks-adapter.ts +43 -44
  325. package/src/src/react/components/Head.tsx +1 -181
  326. package/src/src/react/context/index.tsx +2 -83
  327. package/src/src/react/head-collector.ts +9 -0
  328. package/src/src/react/router/index.tsx +2 -100
  329. package/src/src/react/runtime/core.ts +303 -0
  330. package/src/src/rendering/orchestrator/html.ts +122 -18
  331. package/src/src/rendering/orchestrator/ssr-orchestrator.ts +8 -0
  332. package/src/src/rendering/orchestrator/types.ts +4 -0
  333. package/src/src/repositories/types.ts +0 -4
  334. package/src/src/resource/factory.ts +15 -11
  335. package/src/src/resource/registry.ts +7 -7
  336. package/src/src/schemas/common.ts +8 -5
  337. package/src/src/security/http/config.ts +3 -19
  338. package/src/src/security/http/response/security-handler.ts +22 -13
  339. package/src/src/security/index.ts +4 -7
  340. package/src/src/server/handlers/dev/styles-css.handler.ts +32 -14
  341. package/src/src/server/handlers/monitoring/metrics.handler.ts +3 -1
  342. package/src/src/server/handlers/request/module/module-server-handler.ts +24 -17
  343. package/src/src/server/handlers/request/prod-hydration-module.handler.ts +61 -0
  344. package/src/src/server/handlers/request/ssr/ssr.handler.ts +3 -0
  345. package/src/src/server/production-server.ts +84 -0
  346. package/src/src/server/runtime-handler/handler-context-builder.ts +1 -1
  347. package/src/src/server/runtime-handler/index.ts +44 -13
  348. package/src/src/server/runtime-handler/request-utils.ts +11 -0
  349. package/src/src/server/services/rendering/ssr.service.ts +31 -18
  350. package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
  351. package/src/src/skill/allowed-tools.ts +1 -8
  352. package/src/src/skill/executor.ts +2 -2
  353. package/src/src/skill/parser.ts +13 -20
  354. package/src/src/skill/path-safety.ts +1 -1
  355. package/src/src/skill/tools.ts +27 -20
  356. package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
  357. package/src/src/task/discovery.ts +97 -97
  358. package/src/src/tool/executor.ts +10 -8
  359. package/src/src/tool/factory.ts +21 -22
  360. package/src/src/tool/types.ts +0 -17
  361. package/src/src/transforms/esm/package-registry.ts +52 -20
  362. package/src/src/transforms/import-rewriter/strategies/veryfront-strategy.ts +2 -1
  363. package/src/src/transforms/mdx/esm-module-loader/cache-format.ts +34 -1
  364. package/src/src/transforms/mdx/esm-module-loader/module-fetcher/index.ts +1 -1
  365. package/src/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.ts +4 -0
  366. package/src/src/transforms/pipeline/stages/ssr-vf-modules/index.ts +1 -1
  367. package/src/src/transforms/veryfront-module-urls.ts +6 -2
  368. package/src/src/types/entities/getEntityInfo.ts +131 -152
  369. package/src/src/utils/path-utils.ts +16 -7
  370. package/src/src/utils/version-constant.ts +1 -1
  371. package/src/src/utils/version.ts +0 -1
  372. package/src/src/workflow/worker/dynamic-job-entrypoint.ts +18 -84
  373. package/src/src/workflow/worker/job-entrypoint.ts +18 -85
  374. package/src/src/workflow/worker/shared.ts +127 -0
  375. package/esm/src/prompt/schemas/index.d.ts +0 -7
  376. package/esm/src/prompt/schemas/index.d.ts.map +0 -1
  377. package/esm/src/prompt/schemas/index.js +0 -6
  378. package/esm/src/security/http/handlers-index.d.ts +0 -5
  379. package/esm/src/security/http/handlers-index.d.ts.map +0 -1
  380. package/esm/src/security/http/handlers-index.js +0 -3
  381. package/src/src/prompt/schemas/index.ts +0 -7
  382. package/src/src/security/http/handlers-index.ts +0 -4
@@ -111,20 +111,3 @@ export interface ToolDefinition {
111
111
  description: string;
112
112
  parameters: JsonSchema;
113
113
  }
114
-
115
- /**
116
- * Tool registry entry
117
- */
118
- interface ToolRegistryEntry {
119
- /** Tool ID */
120
- id: string;
121
-
122
- /** Tool instance */
123
- tool: Tool;
124
-
125
- /** File path where tool was defined */
126
- filePath?: string;
127
-
128
- /** Auto-discovered */
129
- autoDiscovered: boolean;
130
- }
@@ -18,6 +18,14 @@ import {
18
18
  // Re-export constants from unified source
19
19
  export { CSSTYPE_VERSION, DEFAULT_REACT_VERSION, TAILWIND_VERSION };
20
20
 
21
+ interface CachedDependencyVersions {
22
+ mtimeMs: number | null;
23
+ react?: string;
24
+ veryfront?: string;
25
+ }
26
+
27
+ const dependencyVersionCache = new Map<string, CachedDependencyVersions>();
28
+
21
29
  /**
22
30
  * Validate React version format (semver: X.Y.Z).
23
31
  */
@@ -88,8 +96,48 @@ export function stripSemverRange(version: string): string {
88
96
  * Compatibility no-op. Kept for tests and older call sites.
89
97
  */
90
98
  export function clearReactVersionCache(): void {
91
- // Intentionally empty: resolveProjectReactVersion reads package.json per call
92
- // to avoid stale version values in long-lived processes.
99
+ dependencyVersionCache.clear();
100
+ }
101
+
102
+ function getPackageJsonPath(projectDir: string): string {
103
+ return `${projectDir}/package.json`;
104
+ }
105
+
106
+ function getMtimeMs(mtime: Date | null | undefined): number | null {
107
+ return mtime instanceof Date ? mtime.getTime() : null;
108
+ }
109
+
110
+ export async function readProjectDependencyVersions(
111
+ projectDir: string,
112
+ ): Promise<{ react?: string; veryfront?: string }> {
113
+ const packageJsonPath = getPackageJsonPath(projectDir);
114
+
115
+ try {
116
+ const { createFileSystem } = await import("../../platform/compat/fs.js");
117
+ const fs = createFileSystem();
118
+ const stat = await fs.stat(packageJsonPath);
119
+ const mtimeMs = getMtimeMs(stat.mtime);
120
+ const cached = dependencyVersionCache.get(packageJsonPath);
121
+
122
+ if (cached && cached.mtimeMs === mtimeMs) {
123
+ return { react: cached.react, veryfront: cached.veryfront };
124
+ }
125
+
126
+ const content = await fs.readTextFile(packageJsonPath);
127
+ const pkg = JSON.parse(content) as {
128
+ dependencies?: Record<string, string>;
129
+ devDependencies?: Record<string, string>;
130
+ };
131
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
132
+ const react = deps.react ? normalizeReactVersion(stripSemverRange(deps.react)) : undefined;
133
+ const veryfront = deps.veryfront ? stripSemverRange(deps.veryfront) : undefined;
134
+
135
+ dependencyVersionCache.set(packageJsonPath, { mtimeMs, react, veryfront });
136
+
137
+ return { react, veryfront };
138
+ } catch (_) {
139
+ return {};
140
+ }
93
141
  }
94
142
 
95
143
  /**
@@ -119,24 +167,8 @@ export async function resolveProjectReactVersion(options: {
119
167
 
120
168
  // 2. Detect from package.json
121
169
  if (projectDir) {
122
- try {
123
- const { createFileSystem } = await import("../../platform/compat/fs.js");
124
- const fs = createFileSystem();
125
- const content = await fs.readTextFile(`${projectDir}/package.json`);
126
- const pkg = JSON.parse(content) as {
127
- dependencies?: Record<string, string>;
128
- devDependencies?: Record<string, string>;
129
- };
130
-
131
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
132
- const rawVersion = deps.react;
133
- if (rawVersion) {
134
- const stripped = stripSemverRange(rawVersion);
135
- return normalizeReactVersion(stripped);
136
- }
137
- } catch (_) {
138
- /* expected: package.json may not exist or be unreadable */
139
- }
170
+ const detected = await readProjectDependencyVersions(projectDir);
171
+ if (detected.react) return detected.react;
140
172
  }
141
173
 
142
174
  // 3. Fallback to default
@@ -54,7 +54,8 @@ export class VeryfrontStrategy implements ImportRewriteStrategy {
54
54
  // Handle #veryfront/* (internal framework imports)
55
55
  if (specifier.startsWith("#veryfront/")) {
56
56
  const path = specifier.slice("#veryfront/".length);
57
- // Try resolving via deno.json mappings first (veryfront/head → react/components/Head.js)
57
+ // Try resolving via deno.json mappings first (for example,
58
+ // veryfront/head → react/runtime/core.js).
58
59
  const mapped = resolveVeryfrontModuleUrl(`veryfront/${path}`);
59
60
  if (mapped) {
60
61
  if (ctx.target === "ssr") return { specifier: `${mapped}?ssr=true` };
@@ -2,12 +2,35 @@ import { hashCodeHex } from "../../../utils/hash-utils.js";
2
2
  import { createCacheNamespace } from "../../../utils/cache-namespace.js";
3
3
  import { REACT_DEFAULT_VERSION } from "../../../utils/constants/cdn.js";
4
4
  import { VERSION } from "../../../utils/version.js";
5
+ import {
6
+ resolveVeryfrontModuleTarget,
7
+ resolveVeryfrontModuleUrl,
8
+ } from "../../veryfront-module-urls.js";
5
9
  import { UNRESOLVED_VF_MODULES_PATTERN } from "./constants.js";
6
10
  import { hashString } from "./utils/hash.js";
7
11
 
8
12
  const ALL_FILE_URL_PATTERN_SOURCE = /file:\/\/([^"'\s]+)/.source;
9
13
  const MJS_FILE_URL_PATTERN_SOURCE = /file:\/\/([^"'\s]+\.mjs)/.source;
10
14
  const CACHE_NAMESPACE_SENTINEL = "__vf_cache_namespace__";
15
+ const PUBLIC_RUNTIME_SPECIFIERS = [
16
+ "veryfront/head",
17
+ "veryfront/router",
18
+ "veryfront/context",
19
+ ] as const;
20
+
21
+ function buildPublicRuntimeAliasSchema(
22
+ overrides?: Partial<Record<(typeof PUBLIC_RUNTIME_SPECIFIERS)[number], string>>,
23
+ ) {
24
+ return Object.fromEntries(
25
+ PUBLIC_RUNTIME_SPECIFIERS.map((specifier) => [
26
+ specifier,
27
+ {
28
+ target: overrides?.[specifier] ?? resolveVeryfrontModuleTarget(specifier),
29
+ url: resolveVeryfrontModuleUrl(specifier),
30
+ },
31
+ ]),
32
+ );
33
+ }
11
34
 
12
35
  function formatMdxEsmTransformCacheKey(
13
36
  namespace: string,
@@ -84,6 +107,11 @@ function buildMdxEsmCacheSchemaSample() {
84
107
  hashString("_vf_modules/pages/index.jsexport default 1;"),
85
108
  hashString("/tmp/project/Button.tsx"),
86
109
  ],
110
+ publicRuntimeAliases: buildPublicRuntimeAliasSchema({
111
+ "veryfront/head": "./src/react/runtime/core.ts",
112
+ "veryfront/router": "./src/react/runtime/core.ts",
113
+ "veryfront/context": "./src/react/runtime/core.ts",
114
+ }),
87
115
  frameworkVersion: VERSION,
88
116
  };
89
117
  }
@@ -92,10 +120,15 @@ function buildFrameworkVfModuleCacheSchemaSample() {
92
120
  return {
93
121
  moduleFile: formatFrameworkVfModuleCacheFileName(
94
122
  CACHE_NAMESPACE_SENTINEL,
95
- hashCodeHex("_vf_modules/_veryfront/react/components/Head.js"),
123
+ hashCodeHex("/_vf_modules/_veryfront/react/runtime/core.js"),
96
124
  hashCodeHex("/app/.cache/veryfront-mdx-esm").slice(0, 8),
97
125
  hashCodeHex("export default function Head() {}"),
98
126
  ),
127
+ publicRuntimeAliases: buildPublicRuntimeAliasSchema({
128
+ "veryfront/head": "./src/react/runtime/core.ts",
129
+ "veryfront/router": "./src/react/runtime/core.ts",
130
+ "veryfront/context": "./src/react/runtime/core.ts",
131
+ }),
99
132
  };
100
133
  }
101
134
 
@@ -37,7 +37,7 @@ import { cacheModule, normalizePath } from "./module-cache.js";
37
37
 
38
38
  // Re-export extracted modules for backward compatibility
39
39
  export { rewriteDntImports } from "./import-rewriter.js";
40
- export { endRenderSession, startRenderSession } from "./render-sessions.js";
40
+ export { endRenderSession, hasRenderSession, startRenderSession } from "./render-sessions.js";
41
41
 
42
42
  /**
43
43
  * Maximum time allowed for the entire transform tree (recursive module resolution).
@@ -76,6 +76,10 @@ export function endRenderSession(sessionId: string): void {
76
76
  renderSessions.delete(sessionId);
77
77
  }
78
78
 
79
+ export function hasRenderSession(sessionId: string): boolean {
80
+ return renderSessions.has(sessionId);
81
+ }
82
+
79
83
  /**
80
84
  * Get the current active render session (if any).
81
85
  * Used to record modules during fetch and for per-session in-flight deduplication.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * SSR VF Modules Stage - resolves /_vf_modules/_veryfront/ paths to framework source.
3
3
  *
4
- * The SSR import map rewrites "veryfront/head" -> "/_vf_modules/_veryfront/react/components/Head.js?ssr=true"
4
+ * The SSR import map rewrites "veryfront/head" -> "/_vf_modules/_veryfront/react/runtime/core.js?ssr=true"
5
5
  * This stage resolves those paths to actual framework source files, transforms them
6
6
  * (including React import rewriting), and rewrites imports to file:// paths.
7
7
  *
@@ -39,6 +39,7 @@ function addMapping(
39
39
  index: ModuleTargetIndex,
40
40
  specifier: string,
41
41
  target: string,
42
+ options?: { preserveExistingExact?: boolean },
42
43
  ): void {
43
44
  if (!target.startsWith(SRC_PREFIX)) return;
44
45
 
@@ -50,6 +51,7 @@ function addMapping(
50
51
  return;
51
52
  }
52
53
 
54
+ if (options?.preserveExistingExact && index.exactTargets.has(specifier)) return;
53
55
  index.exactTargets.set(specifier, target);
54
56
  }
55
57
 
@@ -91,12 +93,14 @@ for (const [key, target] of Object.entries(config.exports ?? {})) {
91
93
  if (typeof target !== "string") continue;
92
94
 
93
95
  if (key === ".") {
94
- addMapping(veryfrontTargetIndex, "veryfront", target);
96
+ addMapping(veryfrontTargetIndex, "veryfront", target, { preserveExistingExact: true });
95
97
  continue;
96
98
  }
97
99
 
98
100
  if (!key.startsWith("./")) continue;
99
- addMapping(veryfrontTargetIndex, `veryfront/${key.slice(2)}`, target);
101
+ addMapping(veryfrontTargetIndex, `veryfront/${key.slice(2)}`, target, {
102
+ preserveExistingExact: true,
103
+ });
100
104
  }
101
105
 
102
106
  finalizeIndex(veryfrontTargetIndex);
@@ -16,6 +16,12 @@ const logger = baseLogger.component("get-entity-by-slug");
16
16
 
17
17
  const entityInfoScope = createErrorScope("getEntityInfo");
18
18
  const fs = createFileSystem();
19
+ const PAGE_FILE_EXTENSIONS = ["mdx", "md", "tsx", "jsx", "ts"] as const;
20
+ const DIRECT_ROUTE_EXTENSIONS = ["mdx", "md", "tsx", "ts"] as const;
21
+ const LAYOUT_FILE_EXTENSIONS = ["mdx", "md", "tsx", "jsx", "ts", "js"] as const;
22
+ const DYNAMIC_PAGE_ENTRY_PATTERN = /\[.+\]\.(mdx|md|tsx|jsx|ts|js)$/;
23
+
24
+ type DirectoryEntry = { name: string; isFile: boolean; isDirectory: boolean };
19
25
 
20
26
  export async function getEntityInfo(
21
27
  filePath: string,
@@ -204,7 +210,7 @@ export async function getEntityBySlug(
204
210
  basePaths,
205
211
  });
206
212
 
207
- const pathResults = await parallelMap(basePaths, async (basePath) => {
213
+ const candidateResults = await parallelMap(basePaths, async (basePath) => {
208
214
  const resolvedPath = await resolveFile.call(adapter.fs, basePath);
209
215
  logger.debug("resolveFile result", {
210
216
  basePath,
@@ -214,7 +220,7 @@ export async function getEntityBySlug(
214
220
  return await getEntityInfo(resolvedPath, adapter);
215
221
  });
216
222
 
217
- for (const info of pathResults) {
223
+ for (const info of candidateResults) {
218
224
  if (info?.entity.isPage) {
219
225
  logger.debug("Found page via resolveFile", {
220
226
  slug,
@@ -225,147 +231,44 @@ export async function getEntityBySlug(
225
231
  }
226
232
  }
227
233
 
228
- const slugParts = normalizedSlug === "" ? [] : normalizedSlug.split("/");
229
- for (let depth = slugParts.length - 1; depth >= 0; depth--) {
230
- const parentPath = slugParts.slice(0, depth).join("/");
231
- const pagesDir = parentPath
232
- ? pathHelper.join(projectDir, "pages", parentPath)
233
- : pathHelper.join(projectDir, "pages");
234
-
235
- try {
236
- let dirExists = false;
237
- try {
238
- const stat = await withFallback(
239
- () => adapter.fs.stat(pagesDir),
240
- () => fs.stat(pagesDir),
241
- { operationName: "stat:getEntityBySlug", logError: false },
242
- );
243
- dirExists = stat.isDirectory;
244
- } catch (_) {
245
- /* expected: stat may fail for non-existent directories */
246
- dirExists = false;
247
- }
248
-
249
- if (!dirExists) continue;
250
-
251
- const entries: { name: string; isFile: boolean; isDirectory: boolean }[] = [];
252
- for await (const entry of adapter.fs.readDir(pagesDir)) {
253
- entries.push(entry);
254
- }
255
-
256
- const dynamicEntries = entries.filter(
257
- (entry) => entry.isFile && /\[.+\]\.(mdx|md|tsx|jsx|ts|js)$/.test(entry.name),
258
- );
259
-
260
- const dynamicResults = await parallelMap(dynamicEntries, async (entry) => {
261
- const dynamicPath = pathHelper.join(pagesDir, entry.name);
262
- return await getEntityInfo(dynamicPath, adapter);
263
- });
264
-
265
- for (const info of dynamicResults) {
266
- if (info?.entity.isPage) return info;
267
- }
268
- } catch (_) {
269
- /* expected: directory may not exist or readDir may fail */
270
- }
271
- }
234
+ const dynamicPage = await findDynamicPageEntity(projectDir, normalizedSlug, adapter);
235
+ if (dynamicPage) return dynamicPage;
272
236
 
273
237
  logger.debug("No page found via resolveFile branch", { slug, normalizedSlug });
274
238
  return null;
275
239
  }
276
240
 
277
- const possiblePaths = [
278
- pathHelper.join(projectDir, "pages", `${normalizedSlug}.mdx`),
279
- pathHelper.join(projectDir, "pages", `${normalizedSlug}.md`),
280
- pathHelper.join(projectDir, "pages", `${normalizedSlug}.tsx`),
281
- pathHelper.join(projectDir, "pages", `${normalizedSlug}.jsx`),
282
- pathHelper.join(projectDir, "pages", `${normalizedSlug}.ts`),
283
- pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.mdx`),
284
- pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.md`),
285
- pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.tsx`),
286
- pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.jsx`),
287
- pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.ts`),
241
+ const candidatePaths = [
242
+ ...buildFileCandidates(projectDir, ["pages"], normalizedSlug, PAGE_FILE_EXTENSIONS),
243
+ ...buildFileCandidates(
244
+ projectDir,
245
+ ["pages"],
246
+ `${normalizedSlug}/index`,
247
+ PAGE_FILE_EXTENSIONS,
248
+ ),
288
249
  ];
289
250
 
290
251
  if (isVeryfrontRoute) {
291
- possiblePaths.unshift(
292
- pathHelper.join(projectDir, `${normalizedSlug}.mdx`),
293
- pathHelper.join(projectDir, `${normalizedSlug}.md`),
294
- pathHelper.join(projectDir, `${normalizedSlug}.tsx`),
295
- pathHelper.join(projectDir, `${normalizedSlug}.ts`),
252
+ candidatePaths.unshift(
253
+ ...buildFileCandidates(projectDir, [], normalizedSlug, DIRECT_ROUTE_EXTENSIONS),
296
254
  );
297
255
  }
298
256
 
299
257
  if (normalizedSlug === "index" || normalizedSlug === "") {
300
- possiblePaths.unshift(
301
- pathHelper.join(projectDir, "pages", "index.mdx"),
302
- pathHelper.join(projectDir, "pages", "index.md"),
303
- pathHelper.join(projectDir, "pages", "index.tsx"),
304
- pathHelper.join(projectDir, "pages", "index.ts"),
258
+ candidatePaths.unshift(
259
+ ...buildFileCandidates(projectDir, ["pages"], "index", DIRECT_ROUTE_EXTENSIONS),
305
260
  );
306
261
  }
307
262
 
308
- const pathResults = await parallelMap(possiblePaths, async (p) => {
309
- return await getEntityInfo(p, adapter);
263
+ const candidateResults = await parallelMap(candidatePaths, async (candidatePath) => {
264
+ return await getEntityInfo(candidatePath, adapter);
310
265
  });
311
266
 
312
- for (const info of pathResults) {
267
+ for (const info of candidateResults) {
313
268
  if (info?.entity.isPage) return info;
314
269
  }
315
270
 
316
- const slugParts = normalizedSlug === "" ? [] : normalizedSlug.split("/");
317
- for (let depth = slugParts.length - 1; depth >= 0; depth--) {
318
- const parentPath = slugParts.slice(0, depth).join("/");
319
- const pagesDir = parentPath
320
- ? pathHelper.join(projectDir, "pages", parentPath)
321
- : pathHelper.join(projectDir, "pages");
322
-
323
- try {
324
- let dirExists = false;
325
- if (adapter) {
326
- try {
327
- const stat = await withFallback(
328
- () => adapter.fs.stat(pagesDir),
329
- () => fs.stat(pagesDir),
330
- { operationName: "stat:getEntityBySlug", logError: false },
331
- );
332
- dirExists = stat.isDirectory;
333
- } catch (_) {
334
- /* expected: stat may fail for non-existent directories */
335
- dirExists = false;
336
- }
337
- } else {
338
- dirExists = await fs.exists(pagesDir);
339
- }
340
-
341
- if (!dirExists) continue;
342
-
343
- const entries: { name: string; isFile: boolean; isDirectory: boolean }[] = [];
344
- const dirIterator = adapter?.fs.readDir
345
- ? adapter.fs.readDir(pagesDir)
346
- : fs.readDir(pagesDir);
347
- for await (const entry of dirIterator) {
348
- entries.push(entry);
349
- }
350
-
351
- const dynamicEntries = entries.filter(
352
- (entry) => entry.isFile && /\[.+\]\.(mdx|md|tsx|jsx|ts|js)$/.test(entry.name),
353
- );
354
-
355
- const dynamicResults = await parallelMap(dynamicEntries, async (entry) => {
356
- const dynamicPath = pathHelper.join(pagesDir, entry.name);
357
- return await getEntityInfo(dynamicPath, adapter);
358
- });
359
-
360
- for (const info of dynamicResults) {
361
- if (info?.entity.isPage) return info;
362
- }
363
- } catch (_) {
364
- /* expected: directory may not exist or readDir may fail */
365
- }
366
- }
367
-
368
- return null;
271
+ return await findDynamicPageEntity(projectDir, normalizedSlug, adapter);
369
272
  },
370
273
  {
371
274
  "entity.slug": slug,
@@ -399,43 +302,38 @@ export async function getLayoutEntity(
399
302
  }
400
303
 
401
304
  // Files in layouts/ are treated as layouts by convention (any extension)
402
- const layoutsDirPaths = [
403
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.mdx`),
404
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.md`),
405
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.tsx`),
406
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.jsx`),
407
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.ts`),
408
- pathHelper.join(projectDir, "layouts", `${resolvedLayoutName}.js`),
409
- ];
305
+ const layoutCandidatePaths = buildFileCandidates(
306
+ projectDir,
307
+ ["layouts"],
308
+ resolvedLayoutName,
309
+ LAYOUT_FILE_EXTENSIONS,
310
+ );
410
311
 
411
312
  // Files in components/ must be detected as layouts by name/frontmatter
412
- const componentsPaths = [
413
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.mdx`),
414
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.md`),
415
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.tsx`),
416
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.jsx`),
417
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.ts`),
418
- pathHelper.join(projectDir, "components", `${resolvedLayoutName}Layout.js`),
419
- pathHelper.join(projectDir, "components", "Layout.mdx"),
420
- pathHelper.join(projectDir, "components", "Layout.md"),
421
- pathHelper.join(projectDir, "components", "Layout.tsx"),
422
- pathHelper.join(projectDir, "components", "Layout.jsx"),
423
- pathHelper.join(projectDir, "components", "Layout.ts"),
424
- pathHelper.join(projectDir, "components", "Layout.js"),
313
+ const componentCandidatePaths = [
314
+ ...buildFileCandidates(
315
+ projectDir,
316
+ ["components"],
317
+ `${resolvedLayoutName}Layout`,
318
+ LAYOUT_FILE_EXTENSIONS,
319
+ ),
320
+ ...buildFileCandidates(projectDir, ["components"], "Layout", LAYOUT_FILE_EXTENSIONS),
425
321
  ];
426
322
 
427
- const allPaths = [...layoutsDirPaths, ...componentsPaths];
428
- const pathResults = await parallelMap(allPaths, async (p) => {
429
- return await getEntityInfo(p, adapter);
430
- });
323
+ const candidateResults = await parallelMap(
324
+ [...layoutCandidatePaths, ...componentCandidatePaths],
325
+ async (candidatePath) => {
326
+ return await getEntityInfo(candidatePath, adapter);
327
+ },
328
+ );
431
329
 
432
- const layoutsDirCount = layoutsDirPaths.length;
433
- for (let i = 0; i < pathResults.length; i++) {
434
- const info = pathResults[i];
330
+ const layoutCandidateCount = layoutCandidatePaths.length;
331
+ for (let i = 0; i < candidateResults.length; i++) {
332
+ const info = candidateResults[i];
435
333
  if (!info) continue;
436
334
  // layouts/ dir: any valid entity is a layout
437
335
  // components/ dir: must be detected as layout by name/frontmatter
438
- if (i < layoutsDirCount || info.entity.isLayout) {
336
+ if (i < layoutCandidateCount || info.entity.isLayout) {
439
337
  return {
440
338
  entity: {
441
339
  ...info.entity,
@@ -454,6 +352,87 @@ export async function getLayoutEntity(
454
352
  );
455
353
  }
456
354
 
355
+ function buildFileCandidates(
356
+ projectDir: string,
357
+ segments: string[],
358
+ relativeStem: string,
359
+ extensions: readonly string[],
360
+ ): string[] {
361
+ return extensions.map((extension) =>
362
+ pathHelper.join(projectDir, ...segments, `${relativeStem}.${extension}`)
363
+ );
364
+ }
365
+
366
+ async function findDynamicPageEntity(
367
+ projectDir: string,
368
+ normalizedSlug: string,
369
+ adapter?: RuntimeAdapter,
370
+ ): Promise<EntityInfo | null> {
371
+ const slugParts = normalizedSlug === "" ? [] : normalizedSlug.split("/");
372
+ for (let depth = slugParts.length - 1; depth >= 0; depth--) {
373
+ const parentPath = slugParts.slice(0, depth).join("/");
374
+ const pagesDir = parentPath
375
+ ? pathHelper.join(projectDir, "pages", parentPath)
376
+ : pathHelper.join(projectDir, "pages");
377
+
378
+ try {
379
+ const canReadDirectory = await pagesDirectoryExists(pagesDir, adapter);
380
+ if (!canReadDirectory) continue;
381
+
382
+ const entries = await readDirectoryEntries(pagesDir, adapter);
383
+ const dynamicEntries = entries.filter(
384
+ (entry) => entry.isFile && DYNAMIC_PAGE_ENTRY_PATTERN.test(entry.name),
385
+ );
386
+
387
+ const candidateResults = await parallelMap(dynamicEntries, async (entry) => {
388
+ const candidatePath = pathHelper.join(pagesDir, entry.name);
389
+ return await getEntityInfo(candidatePath, adapter);
390
+ });
391
+
392
+ for (const info of candidateResults) {
393
+ if (info?.entity.isPage) return info;
394
+ }
395
+ } catch (_) {
396
+ /* expected: directory may not exist or readDir may fail */
397
+ }
398
+ }
399
+
400
+ return null;
401
+ }
402
+
403
+ async function pagesDirectoryExists(
404
+ pagesDir: string,
405
+ adapter?: RuntimeAdapter,
406
+ ): Promise<boolean> {
407
+ if (!adapter) return await fs.exists(pagesDir);
408
+
409
+ try {
410
+ const stat = await withFallback(
411
+ () => adapter.fs.stat(pagesDir),
412
+ () => fs.stat(pagesDir),
413
+ { operationName: "stat:getEntityBySlug", logError: false },
414
+ );
415
+ return stat.isDirectory;
416
+ } catch (_) {
417
+ /* expected: stat may fail for non-existent directories */
418
+ return false;
419
+ }
420
+ }
421
+
422
+ async function readDirectoryEntries(
423
+ pagesDir: string,
424
+ adapter?: RuntimeAdapter,
425
+ ): Promise<DirectoryEntry[]> {
426
+ const entries: DirectoryEntry[] = [];
427
+ const iterator = adapter?.fs.readDir ? adapter.fs.readDir(pagesDir) : fs.readDir(pagesDir);
428
+
429
+ for await (const entry of iterator) {
430
+ entries.push(entry);
431
+ }
432
+
433
+ return entries;
434
+ }
435
+
457
436
  function getSlugFromPath(filePath: string): string {
458
437
  const parts = filePath.split(pathHelper.sep);
459
438
  const fileName = parts[parts.length - 1] ?? "";
@@ -1,4 +1,5 @@
1
1
  import { normalize } from "../platform/compat/path/index.js";
2
+ import { base64urlEncode } from "./base64url.js";
2
3
  import { logger } from "./logger/logger.js";
3
4
 
4
5
  function stripTrailingSlash(pathname: string): string {
@@ -72,21 +73,29 @@ export function getEsbuildLoader(filePath: string): "tsx" | "jsx" | "ts" | "js"
72
73
 
73
74
  export { isAbsolute as isAbsolutePath } from "../platform/compat/path/index.js";
74
75
 
75
- export function toBase64Url(s: string): string {
76
- return btoa(s).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
76
+ export function toBase64Url(input: string): string {
77
+ return base64urlEncode(input);
77
78
  }
78
79
 
79
- function getBase64Padding(length: number): string {
80
- if (length % 4 === 2) return "==";
81
- if (length % 4 === 3) return "=";
82
- return "";
80
+ function getRequiredBase64Padding(length: number): string | undefined {
81
+ const remainder = length % 4;
82
+ if (remainder === 0) return "";
83
+ if (remainder === 2) return "==";
84
+ if (remainder === 3) return "=";
85
+ return undefined;
83
86
  }
84
87
 
85
88
  export function fromBase64Url(encoded: string): string {
86
89
  const b64 = encoded.replaceAll("-", "+").replaceAll("_", "/");
90
+ const padding = getRequiredBase64Padding(b64.length);
91
+
92
+ if (padding === undefined) {
93
+ logger.debug(`Failed to decode base64url string "${encoded}": invalid length`);
94
+ return "";
95
+ }
87
96
 
88
97
  try {
89
- return atob(b64 + getBase64Padding(b64.length));
98
+ return atob(b64 + padding);
90
99
  } catch (error) {
91
100
  logger.debug(`Failed to decode base64url string "${encoded}":`, error);
92
101
  return "";
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.128";
3
+ export const VERSION = "0.1.129";
@@ -32,7 +32,6 @@ export const RUNTIME_VERSION = resolveRuntimeVersion({
32
32
  veryfrontVersion: getVersionEnv("VERYFRONT_VERSION"),
33
33
  releaseVersion: getVersionEnv("RELEASE_VERSION"),
34
34
  denoVersion: typeof denoConfig.version === "string" ? denoConfig.version : undefined,
35
- fallbackVersion: VERSION,
36
35
  });
37
36
 
38
37
  export const SERVER_START_TIME: number = Date.now();