veryfront 0.1.215 → 0.1.217

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 (305) hide show
  1. package/README.md +1 -1
  2. package/esm/cli/commands/extension/command-help.d.ts +3 -0
  3. package/esm/cli/commands/extension/command-help.d.ts.map +1 -0
  4. package/esm/cli/commands/extension/command-help.js +16 -0
  5. package/esm/cli/commands/extension/handler.d.ts +3 -0
  6. package/esm/cli/commands/extension/handler.d.ts.map +1 -0
  7. package/esm/cli/commands/extension/handler.js +36 -0
  8. package/esm/cli/commands/extension/init-command.d.ts +19 -0
  9. package/esm/cli/commands/extension/init-command.d.ts.map +1 -0
  10. package/esm/cli/commands/extension/init-command.js +122 -0
  11. package/esm/cli/commands/extension/validate-command.d.ts +13 -0
  12. package/esm/cli/commands/extension/validate-command.d.ts.map +1 -0
  13. package/esm/cli/commands/extension/validate-command.js +62 -0
  14. package/esm/cli/commands/generate/integration-generator-helpers.d.ts +35 -0
  15. package/esm/cli/commands/generate/integration-generator-helpers.d.ts.map +1 -0
  16. package/esm/cli/commands/generate/integration-generator-helpers.js +123 -0
  17. package/esm/cli/commands/generate/integration-generator.d.ts +1 -2
  18. package/esm/cli/commands/generate/integration-generator.d.ts.map +1 -1
  19. package/esm/cli/commands/generate/integration-generator.js +1 -123
  20. package/esm/cli/commands/knowledge/command-helpers.d.ts +48 -0
  21. package/esm/cli/commands/knowledge/command-helpers.d.ts.map +1 -0
  22. package/esm/cli/commands/knowledge/command-helpers.js +216 -0
  23. package/esm/cli/commands/knowledge/command.d.ts +12 -17
  24. package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
  25. package/esm/cli/commands/knowledge/command.js +26 -214
  26. package/esm/cli/help/command-definitions.d.ts.map +1 -1
  27. package/esm/cli/help/command-definitions.js +2 -0
  28. package/esm/cli/mcp/remote-file-tool-helpers.d.ts +5 -0
  29. package/esm/cli/mcp/remote-file-tool-helpers.d.ts.map +1 -0
  30. package/esm/cli/mcp/remote-file-tool-helpers.js +22 -0
  31. package/esm/cli/mcp/remote-file-tools.d.ts.map +1 -1
  32. package/esm/cli/mcp/remote-file-tools.js +1 -22
  33. package/esm/cli/router.d.ts.map +1 -1
  34. package/esm/cli/router.js +2 -0
  35. package/esm/cli/templates/integration-loader-helpers.d.ts +8 -0
  36. package/esm/cli/templates/integration-loader-helpers.d.ts.map +1 -0
  37. package/esm/cli/templates/integration-loader-helpers.js +29 -0
  38. package/esm/cli/templates/integration-loader.d.ts.map +1 -1
  39. package/esm/cli/templates/integration-loader.js +5 -21
  40. package/esm/cli/templates/manifest.d.ts +1 -0
  41. package/esm/cli/templates/manifest.js +2 -1
  42. package/esm/deno.d.ts +3 -0
  43. package/esm/deno.js +5 -2
  44. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  45. package/esm/src/agent/runtime/index.js +48 -90
  46. package/esm/src/chat/ag-ui-helpers.d.ts +17 -0
  47. package/esm/src/chat/ag-ui-helpers.d.ts.map +1 -0
  48. package/esm/src/chat/ag-ui-helpers.js +111 -0
  49. package/esm/src/chat/ag-ui.d.ts.map +1 -1
  50. package/esm/src/chat/ag-ui.js +1 -111
  51. package/esm/src/config/schemas/config.schema.d.ts +1 -0
  52. package/esm/src/config/schemas/config.schema.d.ts.map +1 -1
  53. package/esm/src/config/schemas/config.schema.js +11 -0
  54. package/esm/src/config/schemas/index.d.ts +11 -1
  55. package/esm/src/config/schemas/index.d.ts.map +1 -1
  56. package/esm/src/errors/error-registry-helpers.d.ts +6 -0
  57. package/esm/src/errors/error-registry-helpers.d.ts.map +1 -0
  58. package/esm/src/errors/error-registry-helpers.js +9 -0
  59. package/esm/src/errors/error-registry.d.ts.map +1 -1
  60. package/esm/src/errors/error-registry.js +4 -3
  61. package/esm/src/extensions/capabilities.d.ts +20 -0
  62. package/esm/src/extensions/capabilities.d.ts.map +1 -0
  63. package/esm/src/extensions/capabilities.js +77 -0
  64. package/esm/src/extensions/contracts.d.ts +10 -0
  65. package/esm/src/extensions/contracts.d.ts.map +1 -0
  66. package/esm/src/extensions/contracts.js +28 -0
  67. package/esm/src/extensions/discovery.d.ts +48 -0
  68. package/esm/src/extensions/discovery.d.ts.map +1 -0
  69. package/esm/src/extensions/discovery.js +179 -0
  70. package/esm/src/extensions/errors.d.ts +10 -0
  71. package/esm/src/extensions/errors.d.ts.map +1 -0
  72. package/esm/src/extensions/errors.js +34 -0
  73. package/esm/src/extensions/factory-loader.d.ts +29 -0
  74. package/esm/src/extensions/factory-loader.d.ts.map +1 -0
  75. package/esm/src/extensions/factory-loader.js +63 -0
  76. package/esm/src/extensions/index.d.ts +37 -0
  77. package/esm/src/extensions/index.d.ts.map +1 -0
  78. package/esm/src/extensions/index.js +41 -0
  79. package/esm/src/extensions/interfaces/ai-model-provider.d.ts +94 -0
  80. package/esm/src/extensions/interfaces/ai-model-provider.d.ts.map +1 -0
  81. package/esm/src/extensions/interfaces/ai-model-provider.js +8 -0
  82. package/esm/src/extensions/interfaces/auth-provider.d.ts +49 -0
  83. package/esm/src/extensions/interfaces/auth-provider.d.ts.map +1 -0
  84. package/esm/src/extensions/interfaces/auth-provider.js +8 -0
  85. package/esm/src/extensions/interfaces/bundler.d.ts +118 -0
  86. package/esm/src/extensions/interfaces/bundler.d.ts.map +1 -0
  87. package/esm/src/extensions/interfaces/bundler.js +8 -0
  88. package/esm/src/extensions/interfaces/cache-store.d.ts +27 -0
  89. package/esm/src/extensions/interfaces/cache-store.d.ts.map +1 -0
  90. package/esm/src/extensions/interfaces/cache-store.js +8 -0
  91. package/esm/src/extensions/interfaces/code-parser.d.ts +76 -0
  92. package/esm/src/extensions/interfaces/code-parser.d.ts.map +1 -0
  93. package/esm/src/extensions/interfaces/code-parser.js +8 -0
  94. package/esm/src/extensions/interfaces/content-transformer.d.ts +40 -0
  95. package/esm/src/extensions/interfaces/content-transformer.d.ts.map +1 -0
  96. package/esm/src/extensions/interfaces/content-transformer.js +8 -0
  97. package/esm/src/extensions/interfaces/css-processor.d.ts +38 -0
  98. package/esm/src/extensions/interfaces/css-processor.d.ts.map +1 -0
  99. package/esm/src/extensions/interfaces/css-processor.js +8 -0
  100. package/esm/src/extensions/interfaces/database-client.d.ts +31 -0
  101. package/esm/src/extensions/interfaces/database-client.d.ts.map +1 -0
  102. package/esm/src/extensions/interfaces/database-client.js +8 -0
  103. package/esm/src/extensions/interfaces/embedding-provider.d.ts +37 -0
  104. package/esm/src/extensions/interfaces/embedding-provider.d.ts.map +1 -0
  105. package/esm/src/extensions/interfaces/embedding-provider.js +8 -0
  106. package/esm/src/extensions/interfaces/index.d.ts +21 -0
  107. package/esm/src/extensions/interfaces/index.d.ts.map +1 -0
  108. package/esm/src/extensions/interfaces/index.js +9 -0
  109. package/esm/src/extensions/interfaces/node-compat.d.ts +25 -0
  110. package/esm/src/extensions/interfaces/node-compat.d.ts.map +1 -0
  111. package/esm/src/extensions/interfaces/node-compat.js +8 -0
  112. package/esm/src/extensions/interfaces/schema-validator.d.ts +46 -0
  113. package/esm/src/extensions/interfaces/schema-validator.d.ts.map +1 -0
  114. package/esm/src/extensions/interfaces/schema-validator.js +8 -0
  115. package/esm/src/extensions/interfaces/tracing-exporter.d.ts +44 -0
  116. package/esm/src/extensions/interfaces/tracing-exporter.d.ts.map +1 -0
  117. package/esm/src/extensions/interfaces/tracing-exporter.js +8 -0
  118. package/esm/src/extensions/loader.d.ts +33 -0
  119. package/esm/src/extensions/loader.d.ts.map +1 -0
  120. package/esm/src/extensions/loader.js +209 -0
  121. package/esm/src/extensions/orchestrate.d.ts +54 -0
  122. package/esm/src/extensions/orchestrate.d.ts.map +1 -0
  123. package/esm/src/extensions/orchestrate.js +116 -0
  124. package/esm/src/extensions/recommendations.d.ts +7 -0
  125. package/esm/src/extensions/recommendations.d.ts.map +1 -0
  126. package/esm/src/extensions/recommendations.js +22 -0
  127. package/esm/src/extensions/types.d.ts +47 -0
  128. package/esm/src/extensions/types.d.ts.map +1 -0
  129. package/esm/src/extensions/types.js +6 -0
  130. package/esm/src/extensions/validation.d.ts +44 -0
  131. package/esm/src/extensions/validation.d.ts.map +1 -0
  132. package/esm/src/extensions/validation.js +115 -0
  133. package/esm/src/html/styles-builder/plugin-loader.d.ts.map +1 -1
  134. package/esm/src/html/styles-builder/plugin-loader.js +23 -0
  135. package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts +29 -0
  136. package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts.map +1 -0
  137. package/esm/src/html/styles-builder/tailwind-plugin-allowlist.js +48 -0
  138. package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts +15 -0
  139. package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts.map +1 -0
  140. package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.js +22 -0
  141. package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts +0 -2
  142. package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts.map +1 -1
  143. package/esm/src/modules/react-loader/ssr-module-loader/loader.js +4 -24
  144. package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts +19 -0
  145. package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts.map +1 -0
  146. package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.js +26 -0
  147. package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
  148. package/esm/src/platform/adapters/fs/veryfront/adapter.js +4 -20
  149. package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts +1 -0
  150. package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts.map +1 -1
  151. package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.js +3 -0
  152. package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
  153. package/esm/src/platform/adapters/fs/veryfront/read-operations.js +4 -7
  154. package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts +28 -0
  155. package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts.map +1 -0
  156. package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.js +41 -0
  157. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts +1 -4
  158. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
  159. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +7 -40
  160. package/esm/src/platform/compat/process/command.d.ts +31 -0
  161. package/esm/src/platform/compat/process/command.d.ts.map +1 -0
  162. package/esm/src/platform/compat/process/command.js +193 -0
  163. package/esm/src/platform/compat/process/env.d.ts +31 -0
  164. package/esm/src/platform/compat/process/env.d.ts.map +1 -0
  165. package/esm/src/platform/compat/process/env.js +175 -0
  166. package/esm/src/platform/compat/process/lifecycle.d.ts +98 -0
  167. package/esm/src/platform/compat/process/lifecycle.d.ts.map +1 -0
  168. package/esm/src/platform/compat/process/lifecycle.js +305 -0
  169. package/esm/src/platform/compat/process/runtime-process.d.ts +10 -0
  170. package/esm/src/platform/compat/process/runtime-process.d.ts.map +1 -0
  171. package/esm/src/platform/compat/process/runtime-process.js +24 -0
  172. package/esm/src/platform/compat/process.d.ts +4 -165
  173. package/esm/src/platform/compat/process.d.ts.map +1 -1
  174. package/esm/src/platform/compat/process.js +4 -682
  175. package/esm/src/platform/index.d.ts +1 -1
  176. package/esm/src/platform/index.d.ts.map +1 -1
  177. package/esm/src/provider/runtime-loader/provider-endpoints.d.ts +8 -0
  178. package/esm/src/provider/runtime-loader/provider-endpoints.d.ts.map +1 -0
  179. package/esm/src/provider/runtime-loader/provider-endpoints.js +27 -0
  180. package/esm/src/provider/runtime-loader/provider-request-init.d.ts +32 -0
  181. package/esm/src/provider/runtime-loader/provider-request-init.d.ts.map +1 -0
  182. package/esm/src/provider/runtime-loader/provider-request-init.js +67 -0
  183. package/esm/src/provider/runtime-loader/tool-input-status.d.ts +17 -0
  184. package/esm/src/provider/runtime-loader/tool-input-status.d.ts.map +1 -0
  185. package/esm/src/provider/runtime-loader/tool-input-status.js +155 -0
  186. package/esm/src/provider/runtime-loader.d.ts +2 -3
  187. package/esm/src/provider/runtime-loader.d.ts.map +1 -1
  188. package/esm/src/provider/runtime-loader.js +92 -291
  189. package/esm/src/proxy/handler.d.ts.map +1 -1
  190. package/esm/src/proxy/handler.js +14 -0
  191. package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts +8 -0
  192. package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts.map +1 -0
  193. package/esm/src/rendering/orchestrator/pipeline-helpers.js +20 -0
  194. package/esm/src/rendering/orchestrator/pipeline.d.ts +0 -3
  195. package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
  196. package/esm/src/rendering/orchestrator/pipeline.js +4 -22
  197. package/esm/src/routing/api/module-loader/loader-helpers.d.ts +10 -0
  198. package/esm/src/routing/api/module-loader/loader-helpers.d.ts.map +1 -0
  199. package/esm/src/routing/api/module-loader/loader-helpers.js +62 -0
  200. package/esm/src/routing/api/module-loader/loader.d.ts +1 -1
  201. package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
  202. package/esm/src/routing/api/module-loader/loader.js +2 -60
  203. package/esm/src/server/bootstrap.d.ts +22 -2
  204. package/esm/src/server/bootstrap.d.ts.map +1 -1
  205. package/esm/src/server/bootstrap.js +67 -5
  206. package/esm/src/server/dev-ui/manifest.d.ts +2 -0
  207. package/esm/src/server/dev-ui/manifest.js +3 -1
  208. package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -1
  209. package/esm/src/server/handlers/request/api/project-discovery.js +14 -8
  210. package/esm/src/server/production-server.js +1 -1
  211. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.d.ts.map +1 -1
  212. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +2 -2
  213. package/esm/src/server/utils/domain-parser.d.ts.map +1 -1
  214. package/esm/src/server/utils/domain-parser.js +4 -0
  215. package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
  216. package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
  217. package/esm/src/tool/index.d.ts +1 -1
  218. package/esm/src/tool/index.d.ts.map +1 -1
  219. package/esm/src/tool/types.d.ts +20 -0
  220. package/esm/src/tool/types.d.ts.map +1 -1
  221. package/esm/src/utils/version-constant.d.ts +1 -1
  222. package/esm/src/utils/version-constant.js +1 -1
  223. package/package.json +7 -1
  224. package/src/cli/commands/extension/command-help.ts +18 -0
  225. package/src/cli/commands/extension/handler.ts +41 -0
  226. package/src/cli/commands/extension/init-command.ts +140 -0
  227. package/src/cli/commands/extension/validate-command.ts +78 -0
  228. package/src/cli/commands/generate/integration-generator-helpers.ts +185 -0
  229. package/src/cli/commands/generate/integration-generator.ts +12 -168
  230. package/src/cli/commands/knowledge/command-helpers.ts +295 -0
  231. package/src/cli/commands/knowledge/command.ts +34 -261
  232. package/src/cli/help/command-definitions.ts +2 -0
  233. package/src/cli/mcp/remote-file-tool-helpers.ts +27 -0
  234. package/src/cli/mcp/remote-file-tools.ts +6 -28
  235. package/src/cli/router.ts +2 -0
  236. package/src/cli/templates/integration-loader-helpers.ts +49 -0
  237. package/src/cli/templates/integration-loader.ts +10 -28
  238. package/src/cli/templates/manifest.js +2 -1
  239. package/src/deno.js +5 -2
  240. package/src/src/agent/runtime/index.ts +77 -94
  241. package/src/src/chat/ag-ui-helpers.ts +139 -0
  242. package/src/src/chat/ag-ui.ts +11 -139
  243. package/src/src/config/schemas/config.schema.ts +11 -0
  244. package/src/src/config/schemas/index.ts +15 -1
  245. package/src/src/errors/error-registry-helpers.ts +23 -0
  246. package/src/src/errors/error-registry.ts +8 -3
  247. package/src/src/extensions/capabilities.ts +97 -0
  248. package/src/src/extensions/contracts.ts +36 -0
  249. package/src/src/extensions/discovery.ts +221 -0
  250. package/src/src/extensions/errors.ts +39 -0
  251. package/src/src/extensions/factory-loader.ts +76 -0
  252. package/src/src/extensions/index.ts +79 -0
  253. package/src/src/extensions/interfaces/ai-model-provider.ts +100 -0
  254. package/src/src/extensions/interfaces/auth-provider.ts +52 -0
  255. package/src/src/extensions/interfaces/bundler.ts +116 -0
  256. package/src/src/extensions/interfaces/cache-store.ts +27 -0
  257. package/src/src/extensions/interfaces/code-parser.ts +84 -0
  258. package/src/src/extensions/interfaces/content-transformer.ts +38 -0
  259. package/src/src/extensions/interfaces/css-processor.ts +40 -0
  260. package/src/src/extensions/interfaces/database-client.ts +35 -0
  261. package/src/src/extensions/interfaces/embedding-provider.ts +39 -0
  262. package/src/src/extensions/interfaces/index.ts +81 -0
  263. package/src/src/extensions/interfaces/node-compat.ts +25 -0
  264. package/src/src/extensions/interfaces/schema-validator.ts +51 -0
  265. package/src/src/extensions/interfaces/tracing-exporter.ts +42 -0
  266. package/src/src/extensions/loader.ts +245 -0
  267. package/src/src/extensions/orchestrate.ts +184 -0
  268. package/src/src/extensions/recommendations.ts +24 -0
  269. package/src/src/extensions/types.ts +57 -0
  270. package/src/src/extensions/validation.ts +147 -0
  271. package/src/src/html/styles-builder/plugin-loader.ts +32 -0
  272. package/src/src/html/styles-builder/tailwind-plugin-allowlist.ts +51 -0
  273. package/src/src/modules/react-loader/ssr-module-loader/loader-helpers.ts +37 -0
  274. package/src/src/modules/react-loader/ssr-module-loader/loader.ts +8 -39
  275. package/src/src/platform/adapters/fs/veryfront/adapter-helpers.ts +43 -0
  276. package/src/src/platform/adapters/fs/veryfront/adapter.ts +8 -22
  277. package/src/src/platform/adapters/fs/veryfront/read-operations-helpers.ts +4 -0
  278. package/src/src/platform/adapters/fs/veryfront/read-operations.ts +4 -7
  279. package/src/src/platform/adapters/fs/veryfront/websocket-manager-helpers.ts +73 -0
  280. package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +29 -44
  281. package/src/src/platform/compat/process/command.ts +297 -0
  282. package/src/src/platform/compat/process/env.ts +227 -0
  283. package/src/src/platform/compat/process/lifecycle.ts +330 -0
  284. package/src/src/platform/compat/process/runtime-process.ts +27 -0
  285. package/src/src/platform/compat/process.ts +37 -870
  286. package/src/src/platform/index.ts +1 -0
  287. package/src/src/provider/runtime-loader/provider-endpoints.ts +50 -0
  288. package/src/src/provider/runtime-loader/provider-request-init.ts +101 -0
  289. package/src/src/provider/runtime-loader/tool-input-status.ts +210 -0
  290. package/src/src/provider/runtime-loader.ts +113 -368
  291. package/src/src/proxy/handler.ts +16 -0
  292. package/src/src/rendering/orchestrator/pipeline-helpers.ts +35 -0
  293. package/src/src/rendering/orchestrator/pipeline.ts +8 -35
  294. package/src/src/routing/api/module-loader/loader-helpers.ts +68 -0
  295. package/src/src/routing/api/module-loader/loader.ts +8 -65
  296. package/src/src/server/bootstrap.ts +88 -7
  297. package/src/src/server/dev-ui/manifest.js +3 -1
  298. package/src/src/server/handlers/request/api/project-discovery.ts +19 -8
  299. package/src/src/server/production-server.ts +1 -1
  300. package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +2 -2
  301. package/src/src/server/utils/domain-parser.ts +4 -0
  302. package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
  303. package/src/src/tool/index.ts +1 -0
  304. package/src/src/tool/types.ts +21 -0
  305. package/src/src/utils/version-constant.ts +1 -1
@@ -0,0 +1,35 @@
1
+ import type { LayoutItem } from "../../types/index.js";
2
+ import { extractRelativePath as extractRelativePathShared } from "../../utils/route-path-utils.js";
3
+
4
+ const RENDERED_CSS_HASH_RE = /href="\/_vf\/css\/([a-z0-9-]{1,16})\.css"/i;
5
+
6
+ export function extractRenderedCssHash(html: string): string | undefined {
7
+ return html.match(RENDERED_CSS_HASH_RE)?.[1];
8
+ }
9
+
10
+ export function serializeLayouts(
11
+ nestedLayouts: LayoutItem[],
12
+ projectDir: string,
13
+ ): Array<{ kind: LayoutItem["kind"]; path: string }> {
14
+ return nestedLayouts
15
+ .filter((layout: LayoutItem) => layout.componentPath || layout.path)
16
+ .map((layout: LayoutItem) => ({
17
+ kind: layout.kind,
18
+ path: extractRelativePathShared(
19
+ layout.componentPath || layout.path || "",
20
+ projectDir,
21
+ ),
22
+ }));
23
+ }
24
+
25
+ export function serializeLayoutProps(
26
+ layoutProps: Map<string, Record<string, unknown>>,
27
+ ): Record<string, Record<string, unknown>> {
28
+ const serialized: Record<string, Record<string, unknown>> = {};
29
+
30
+ for (const [layoutId, props] of layoutProps.entries()) {
31
+ serialized[layoutId] = props;
32
+ }
33
+
34
+ return serialized;
35
+ }
@@ -26,6 +26,11 @@ import {
26
26
  extractRelativePath as extractRelativePathShared,
27
27
  extractRouteParams as extractRouteParamsShared,
28
28
  } from "../../utils/route-path-utils.js";
29
+ import {
30
+ extractRenderedCssHash,
31
+ serializeLayoutProps,
32
+ serializeLayouts,
33
+ } from "./pipeline-helpers.js";
29
34
  import { join } from "../../platform/compat/path/index.js";
30
35
  import type { MdxBundle, PageBundle } from "../../types/index.js";
31
36
  import type { RuntimeAdapter } from "../../platform/adapters/base.js";
@@ -77,8 +82,6 @@ import {
77
82
  const renderPageLog = logger.component("render-page");
78
83
  const renderPipelineLog = logger.component("render-pipeline");
79
84
  const resolvePageDataLog = logger.component("resolve-page-data");
80
- const RENDERED_CSS_HASH_RE = /href="\/_vf\/css\/([a-z0-9-]{1,16})\.css"/i;
81
-
82
85
  // Re-export test helper for backward compatibility
83
86
  export { __injectCssCacheForTests } from "./css-cache.js";
84
87
 
@@ -159,15 +162,11 @@ export class RenderPipeline {
159
162
  return loadModule(filePath, this.moduleLoaderConfig);
160
163
  }
161
164
 
162
- private extractRenderedCssHash(html: string): string | undefined {
163
- return html.match(RENDERED_CSS_HASH_RE)?.[1];
164
- }
165
-
166
165
  private async resolveCssFromRenderedHtml(
167
166
  html: string,
168
167
  projectSlug: string | undefined,
169
168
  ): Promise<string | undefined> {
170
- const cssHash = this.extractRenderedCssHash(html);
169
+ const cssHash = extractRenderedCssHash(html);
171
170
  if (!cssHash) return undefined;
172
171
 
173
172
  const cachedCss = await getCSSByHashAsync(cssHash);
@@ -664,7 +663,7 @@ export class RenderPipeline {
664
663
 
665
664
  const pageProps: Record<string, unknown> = dataResolution.pageProps;
666
665
  const params = dataResolution.params;
667
- const layoutProps = this.serializeLayoutProps(dataResolution.layoutProps);
666
+ const layoutProps = serializeLayoutProps(dataResolution.layoutProps);
668
667
 
669
668
  const { frontmatter, headings } = await this.extractMdxMetadata(
670
669
  pageType,
@@ -674,7 +673,7 @@ export class RenderPipeline {
674
673
  params,
675
674
  );
676
675
 
677
- const layouts = this.serializeLayouts(layoutResult.nestedLayouts);
676
+ const layouts = serializeLayouts(layoutResult.nestedLayouts, this.config.projectDir);
678
677
 
679
678
  const providers: string[] = [];
680
679
 
@@ -756,32 +755,6 @@ export class RenderPipeline {
756
755
  }
757
756
  }
758
757
 
759
- private serializeLayouts(
760
- nestedLayouts: LayoutItem[],
761
- ): Array<{ kind: LayoutItem["kind"]; path: string }> {
762
- return nestedLayouts
763
- .filter((layout: LayoutItem) => layout.componentPath || layout.path)
764
- .map((layout: LayoutItem) => ({
765
- kind: layout.kind,
766
- path: extractRelativePathShared(
767
- layout.componentPath || layout.path || "",
768
- this.config.projectDir,
769
- ),
770
- }));
771
- }
772
-
773
- private serializeLayoutProps(
774
- layoutProps: Map<string, Record<string, unknown>>,
775
- ): Record<string, Record<string, unknown>> {
776
- const serialized: Record<string, Record<string, unknown>> = {};
777
-
778
- for (const [layoutId, props] of layoutProps.entries()) {
779
- serialized[layoutId] = props;
780
- }
781
-
782
- return serialized;
783
- }
784
-
785
758
  private async resolveAppPath(): Promise<string | undefined> {
786
759
  for (const ext of LAYOUT_EXTENSIONS) {
787
760
  const candidatePath = join(this.config.projectDir, `components/app.${ext}`);
@@ -0,0 +1,68 @@
1
+ import * as pathHelper from "../../../platform/compat/path/index.js";
2
+ import { createError, toError } from "../../../errors/veryfront-error.js";
3
+ import { isWithinDirectory } from "../../../security/path-validation.js";
4
+
5
+ const EXT_TO_LOADER: Record<string, "tsx" | "jsx" | "ts" | "js" | "json"> = {
6
+ tsx: "tsx",
7
+ jsx: "jsx",
8
+ ts: "ts",
9
+ json: "json",
10
+ };
11
+
12
+ export const FILE_EXTENSIONS: string[] = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs"];
13
+
14
+ /**
15
+ * Validates that a module path is contained within the project directory.
16
+ * Prevents path traversal attacks that could load arbitrary files from the host.
17
+ */
18
+ export function validateModulePath(modulePath: string, projectDir: string): void {
19
+ const resolved = pathHelper.resolve(modulePath);
20
+ const resolvedProject = pathHelper.resolve(projectDir);
21
+
22
+ if (!isWithinDirectory(resolvedProject, resolved)) {
23
+ throw toError(
24
+ createError({
25
+ type: "api",
26
+ message: `[API] module path escapes project directory: ${modulePath}`,
27
+ }),
28
+ );
29
+ }
30
+ }
31
+
32
+ export function resolveExportEntry(entry: unknown): string | undefined {
33
+ if (typeof entry === "string") return entry;
34
+ if (entry && typeof entry === "object") {
35
+ const obj = entry as Record<string, unknown>;
36
+ for (const key of ["import", "default"]) {
37
+ const value = obj[key];
38
+ if (typeof value === "string") return value;
39
+ if (value && typeof value === "object") {
40
+ const nested = value as Record<string, unknown>;
41
+ if (typeof nested.default === "string") return nested.default;
42
+ }
43
+ }
44
+ }
45
+ return undefined;
46
+ }
47
+
48
+ export function toCjsDestructureBindings(bindings: string): string {
49
+ const inner = bindings.trim().replace(/^\{\s*/, "").replace(/\s*\}$/, "");
50
+ if (!inner) return "{}";
51
+
52
+ const converted = inner
53
+ .split(",")
54
+ .map((part) => part.trim())
55
+ .filter(Boolean)
56
+ .map((part) => {
57
+ const aliasMatch = part.match(/^([A-Za-z_$][\w$]*)\s+as\s+([A-Za-z_$][\w$]*)$/);
58
+ if (aliasMatch) return `${aliasMatch[1]}: ${aliasMatch[2]}`;
59
+ return part;
60
+ });
61
+
62
+ return `{ ${converted.join(", ")} }`;
63
+ }
64
+
65
+ export function getLoaderForFile(filePath: string): "tsx" | "jsx" | "ts" | "js" | "json" {
66
+ const ext = filePath.split(".").pop() ?? "";
67
+ return EXT_TO_LOADER[ext] ?? "js";
68
+ }
@@ -12,6 +12,13 @@ import { getEsbuildLoader } from "../../../utils/path-utils.js";
12
12
  import { createFileSystem } from "../../../platform/compat/fs.js";
13
13
  import type { FileSystem } from "../../../platform/compat/fs.js";
14
14
  import * as pathHelper from "../../../platform/compat/path/index.js";
15
+ import {
16
+ FILE_EXTENSIONS,
17
+ getLoaderForFile,
18
+ resolveExportEntry,
19
+ toCjsDestructureBindings,
20
+ validateModulePath,
21
+ } from "./loader-helpers.js";
15
22
  import { isDeno, isNode } from "../../../platform/compat/runtime.js";
16
23
  import { withSpan } from "../../../observability/tracing/otlp-setup.js";
17
24
  import { isCompiledBinary } from "../../../utils/index.js";
@@ -21,23 +28,7 @@ import { rewriteNpmImports } from "../../../transforms/npm-import-rewrites.js";
21
28
 
22
29
  const logger = serverLogger.component("api");
23
30
 
24
- /**
25
- * Validates that a module path is contained within the project directory.
26
- * Prevents path traversal attacks that could load arbitrary files from the host.
27
- */
28
- function validateModulePath(modulePath: string, projectDir: string): void {
29
- const resolved = pathHelper.resolve(modulePath);
30
- const resolvedProject = pathHelper.resolve(projectDir);
31
-
32
- if (!isWithinDirectory(resolvedProject, resolved)) {
33
- throw toError(
34
- createError({
35
- type: "api",
36
- message: `[API] module path escapes project directory: ${modulePath}`,
37
- }),
38
- );
39
- }
40
- }
31
+ export { toCjsDestructureBindings } from "./loader-helpers.js";
41
32
 
42
33
  /** Node.js built-in module names — shared across the CJS shim, esbuild externals, and Deno rewrites. */
43
34
  const NODE_BUILTINS = [
@@ -165,54 +156,6 @@ require.ensure = function(mods, cb) { cb(); };
165
156
  `.trim();
166
157
  }
167
158
 
168
- function resolveExportEntry(entry: unknown): string | undefined {
169
- if (typeof entry === "string") return entry;
170
- if (entry && typeof entry === "object") {
171
- const obj = entry as Record<string, unknown>;
172
- // Prefer import > default > first string value
173
- for (const key of ["import", "default"]) {
174
- const val = obj[key];
175
- if (typeof val === "string") return val;
176
- if (val && typeof val === "object") {
177
- const nested = val as Record<string, unknown>;
178
- if (typeof nested.default === "string") return nested.default;
179
- }
180
- }
181
- }
182
- return undefined;
183
- }
184
-
185
- export function toCjsDestructureBindings(bindings: string): string {
186
- const inner = bindings.trim().replace(/^\{\s*/, "").replace(/\s*\}$/, "");
187
- if (!inner) return "{}";
188
-
189
- const converted = inner
190
- .split(",")
191
- .map((part) => part.trim())
192
- .filter(Boolean)
193
- .map((part) => {
194
- const aliasMatch = part.match(/^([A-Za-z_$][\w$]*)\s+as\s+([A-Za-z_$][\w$]*)$/);
195
- if (aliasMatch) return `${aliasMatch[1]}: ${aliasMatch[2]}`;
196
- return part;
197
- });
198
-
199
- return `{ ${converted.join(", ")} }`;
200
- }
201
-
202
- const FILE_EXTENSIONS: string[] = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs"];
203
-
204
- const EXT_TO_LOADER: Record<string, "tsx" | "jsx" | "ts" | "js" | "json"> = {
205
- tsx: "tsx",
206
- jsx: "jsx",
207
- ts: "ts",
208
- json: "json",
209
- };
210
-
211
- function getLoaderForFile(filePath: string): "tsx" | "jsx" | "ts" | "js" | "json" {
212
- const ext = filePath.split(".").pop() ?? "";
213
- return EXT_TO_LOADER[ext] ?? "js";
214
- }
215
-
216
159
  export function loadHandlerModule(options: LoadModuleOptions): Promise<APIRoute | null> {
217
160
  return withSpan(
218
161
  "api.loadHandlerModule",
@@ -2,6 +2,7 @@ import type { RuntimeAdapter } from "../platform/adapters/base.js";
2
2
  import type { VeryfrontConfig } from "../config/index.js";
3
3
  import type { InvalidationProjectContext } from "../platform/adapters/fs/veryfront/types.js";
4
4
  import { clearConfigCache, getConfig } from "../config/index.js";
5
+ import { type ExtensionLoader, orchestrateExtensions } from "../extensions/index.js";
5
6
  import {
6
7
  getEnvironmentConfig,
7
8
  refreshEnvironmentConfig,
@@ -41,8 +42,52 @@ export interface BootstrapResult {
41
42
  /** FSAdapter type (if used) */
42
43
  fsAdapterType?: string;
43
44
 
44
- /** Dispose FSAdapter resources (WebSocket connections, caches) */
45
- dispose?: () => void;
45
+ /**
46
+ * Extension loader that ran setup for all discovered extensions.
47
+ * Even when no extensions exist, a loader instance is present so callers
48
+ * can safely invoke `teardownAll()` unconditionally.
49
+ */
50
+ extensionLoader: ExtensionLoader;
51
+
52
+ /**
53
+ * Dispose bootstrap resources: tears down extensions (reverse order),
54
+ * then releases any FSAdapter resources (WebSocket connections, caches).
55
+ */
56
+ dispose?: () => void | Promise<void>;
57
+ }
58
+
59
+ function combineDispose(
60
+ extensionLoader: ExtensionLoader,
61
+ fsDispose?: () => void,
62
+ ): () => Promise<void> {
63
+ return async () => {
64
+ try {
65
+ await extensionLoader.teardownAll();
66
+ } finally {
67
+ if (fsDispose) fsDispose();
68
+ }
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Run extension orchestration, disposing the FS adapter if orchestration fails.
74
+ *
75
+ * Exported for unit testing. In the FS-adapter path the caller has already
76
+ * allocated FS resources (WebSocket connections, caches) that must be
77
+ * released before the bootstrap error propagates.
78
+ *
79
+ * @internal
80
+ */
81
+ export async function orchestrateOrDisposeFS(
82
+ orchestrate: () => Promise<ExtensionLoader>,
83
+ fsDispose: (() => void) | undefined,
84
+ ): Promise<ExtensionLoader> {
85
+ try {
86
+ return await orchestrate();
87
+ } catch (err) {
88
+ if (fsDispose) fsDispose();
89
+ throw err;
90
+ }
46
91
  }
47
92
 
48
93
  let envLogged = false;
@@ -115,7 +160,18 @@ export async function bootstrap(
115
160
 
116
161
  if (!needsFSAdapter) {
117
162
  bootstrapLog.debug("Using local filesystem (no FSAdapter needed)");
118
- return { adapter, config, usingFSAdapter: false };
163
+ const extensionLoader = await orchestrateExtensions({
164
+ projectDir,
165
+ config,
166
+ logger: bootstrapLog,
167
+ });
168
+ return {
169
+ adapter,
170
+ config,
171
+ usingFSAdapter: false,
172
+ extensionLoader,
173
+ dispose: combineDispose(extensionLoader),
174
+ };
119
175
  }
120
176
 
121
177
  bootstrapLog.debug("Initializing FSAdapter", { type: fsType });
@@ -144,7 +200,18 @@ export async function bootstrap(
144
200
  fsAdapter: "local",
145
201
  });
146
202
 
147
- return { adapter, config, usingFSAdapter: false };
203
+ const extensionLoader = await orchestrateExtensions({
204
+ projectDir,
205
+ config,
206
+ logger: bootstrapLog,
207
+ });
208
+ return {
209
+ adapter,
210
+ config,
211
+ usingFSAdapter: false,
212
+ extensionLoader,
213
+ dispose: combineDispose(extensionLoader),
214
+ };
148
215
  }
149
216
 
150
217
  const isProxyMode = config.fs?.veryfront?.proxyMode === true;
@@ -179,23 +246,37 @@ export async function bootstrap(
179
246
  fsAdapter: fsType,
180
247
  });
181
248
 
182
- let dispose: (() => void) | undefined;
249
+ let fsDispose: (() => void) | undefined;
183
250
  if (isExtendedFSAdapter(enhancedAdapter.fs)) {
184
251
  const underlying = enhancedAdapter.fs.getUnderlyingAdapter();
185
252
  if (
186
253
  "dispose" in underlying &&
187
254
  typeof (underlying as { dispose?: () => void }).dispose === "function"
188
255
  ) {
189
- dispose = () => (underlying as { dispose: () => void }).dispose();
256
+ fsDispose = () => (underlying as { dispose: () => void }).dispose();
190
257
  }
191
258
  }
192
259
 
260
+ // If extension orchestration fails after the FS adapter has been wired up,
261
+ // release the FS resources (WebSocket connections, caches) before
262
+ // propagating the error — otherwise the adapter would leak.
263
+ const extensionLoader = await orchestrateOrDisposeFS(
264
+ () =>
265
+ orchestrateExtensions({
266
+ projectDir,
267
+ config,
268
+ logger: bootstrapLog,
269
+ }),
270
+ fsDispose,
271
+ );
272
+
193
273
  return {
194
274
  adapter: enhancedAdapter,
195
275
  config,
196
276
  usingFSAdapter: true,
197
277
  fsAdapterType: fsType,
198
- dispose,
278
+ extensionLoader,
279
+ dispose: combineDispose(extensionLoader, fsDispose),
199
280
  };
200
281
  }
201
282