@superblocksteam/vite-plugin-file-sync 2.0.3-next.46

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 (562) hide show
  1. package/LICENSE.txt +87 -0
  2. package/dist/ai-service/artifacts/bolt.d.ts +8 -0
  3. package/dist/ai-service/artifacts/bolt.d.ts.map +1 -0
  4. package/dist/ai-service/artifacts/bolt.js +34 -0
  5. package/dist/ai-service/artifacts/bolt.js.map +1 -0
  6. package/dist/ai-service/const.d.ts +8 -0
  7. package/dist/ai-service/const.d.ts.map +1 -0
  8. package/dist/ai-service/const.js +9 -0
  9. package/dist/ai-service/const.js.map +1 -0
  10. package/dist/ai-service/eval/template-renderer.d.ts +13 -0
  11. package/dist/ai-service/eval/template-renderer.d.ts.map +1 -0
  12. package/dist/ai-service/eval/template-renderer.js +66 -0
  13. package/dist/ai-service/eval/template-renderer.js.map +1 -0
  14. package/dist/ai-service/index.d.ts +18 -0
  15. package/dist/ai-service/index.d.ts.map +1 -0
  16. package/dist/ai-service/index.js +140 -0
  17. package/dist/ai-service/index.js.map +1 -0
  18. package/dist/ai-service/integrations/const.d.ts +41 -0
  19. package/dist/ai-service/integrations/const.d.ts.map +1 -0
  20. package/dist/ai-service/integrations/const.js +76 -0
  21. package/dist/ai-service/integrations/const.js.map +1 -0
  22. package/dist/ai-service/integrations/from-prompt-context.d.ts +4 -0
  23. package/dist/ai-service/integrations/from-prompt-context.d.ts.map +1 -0
  24. package/dist/ai-service/integrations/from-prompt-context.js +56 -0
  25. package/dist/ai-service/integrations/from-prompt-context.js.map +1 -0
  26. package/dist/ai-service/integrations/to-sdk-prompt.d.ts +3 -0
  27. package/dist/ai-service/integrations/to-sdk-prompt.d.ts.map +1 -0
  28. package/dist/ai-service/integrations/to-sdk-prompt.js +47 -0
  29. package/dist/ai-service/integrations/to-sdk-prompt.js.map +1 -0
  30. package/dist/ai-service/integrations/types.d.ts +31 -0
  31. package/dist/ai-service/integrations/types.d.ts.map +1 -0
  32. package/dist/ai-service/integrations/types.js +2 -0
  33. package/dist/ai-service/integrations/types.js.map +1 -0
  34. package/dist/ai-service/prompts/draft-subprompts/superblocks-api-draft.d.ts +2 -0
  35. package/dist/ai-service/prompts/draft-subprompts/superblocks-api-draft.d.ts.map +1 -0
  36. package/dist/ai-service/prompts/draft-subprompts/superblocks-api-draft.js +386 -0
  37. package/dist/ai-service/prompts/draft-subprompts/superblocks-api-draft.js.map +1 -0
  38. package/dist/ai-service/prompts/draft-subprompts/superblocks-layouts-with-grid-examples.d.ts +2 -0
  39. package/dist/ai-service/prompts/draft-subprompts/superblocks-layouts-with-grid-examples.d.ts.map +1 -0
  40. package/dist/ai-service/prompts/draft-subprompts/superblocks-layouts-with-grid-examples.js +219 -0
  41. package/dist/ai-service/prompts/draft-subprompts/superblocks-layouts-with-grid-examples.js.map +1 -0
  42. package/dist/ai-service/prompts/generated/index.d.ts +4 -0
  43. package/dist/ai-service/prompts/generated/index.d.ts.map +1 -0
  44. package/dist/ai-service/prompts/generated/index.js +6 -0
  45. package/dist/ai-service/prompts/generated/index.js.map +1 -0
  46. package/dist/ai-service/prompts/generated/library-components/SbButtonPropsDocs.d.ts +2 -0
  47. package/dist/ai-service/prompts/generated/library-components/SbButtonPropsDocs.d.ts.map +1 -0
  48. package/dist/ai-service/prompts/generated/library-components/SbButtonPropsDocs.js +6 -0
  49. package/dist/ai-service/prompts/generated/library-components/SbButtonPropsDocs.js.map +1 -0
  50. package/dist/ai-service/prompts/generated/library-components/SbCheckboxPropsDocs.d.ts +2 -0
  51. package/dist/ai-service/prompts/generated/library-components/SbCheckboxPropsDocs.d.ts.map +1 -0
  52. package/dist/ai-service/prompts/generated/library-components/SbCheckboxPropsDocs.js +6 -0
  53. package/dist/ai-service/prompts/generated/library-components/SbCheckboxPropsDocs.js.map +1 -0
  54. package/dist/ai-service/prompts/generated/library-components/SbColumnPropsDocs.d.ts +2 -0
  55. package/dist/ai-service/prompts/generated/library-components/SbColumnPropsDocs.d.ts.map +1 -0
  56. package/dist/ai-service/prompts/generated/library-components/SbColumnPropsDocs.js +6 -0
  57. package/dist/ai-service/prompts/generated/library-components/SbColumnPropsDocs.js.map +1 -0
  58. package/dist/ai-service/prompts/generated/library-components/SbContainerPropsDocs.d.ts +2 -0
  59. package/dist/ai-service/prompts/generated/library-components/SbContainerPropsDocs.d.ts.map +1 -0
  60. package/dist/ai-service/prompts/generated/library-components/SbContainerPropsDocs.js +6 -0
  61. package/dist/ai-service/prompts/generated/library-components/SbContainerPropsDocs.js.map +1 -0
  62. package/dist/ai-service/prompts/generated/library-components/SbDatePickerPropsDocs.d.ts +2 -0
  63. package/dist/ai-service/prompts/generated/library-components/SbDatePickerPropsDocs.d.ts.map +1 -0
  64. package/dist/ai-service/prompts/generated/library-components/SbDatePickerPropsDocs.js +6 -0
  65. package/dist/ai-service/prompts/generated/library-components/SbDatePickerPropsDocs.js.map +1 -0
  66. package/dist/ai-service/prompts/generated/library-components/SbDropdownPropsDocs.d.ts +2 -0
  67. package/dist/ai-service/prompts/generated/library-components/SbDropdownPropsDocs.d.ts.map +1 -0
  68. package/dist/ai-service/prompts/generated/library-components/SbDropdownPropsDocs.js +6 -0
  69. package/dist/ai-service/prompts/generated/library-components/SbDropdownPropsDocs.js.map +1 -0
  70. package/dist/ai-service/prompts/generated/library-components/SbIconPropsDocs.d.ts +2 -0
  71. package/dist/ai-service/prompts/generated/library-components/SbIconPropsDocs.d.ts.map +1 -0
  72. package/dist/ai-service/prompts/generated/library-components/SbIconPropsDocs.js +6 -0
  73. package/dist/ai-service/prompts/generated/library-components/SbIconPropsDocs.js.map +1 -0
  74. package/dist/ai-service/prompts/generated/library-components/SbImagePropsDocs.d.ts +2 -0
  75. package/dist/ai-service/prompts/generated/library-components/SbImagePropsDocs.d.ts.map +1 -0
  76. package/dist/ai-service/prompts/generated/library-components/SbImagePropsDocs.js +6 -0
  77. package/dist/ai-service/prompts/generated/library-components/SbImagePropsDocs.js.map +1 -0
  78. package/dist/ai-service/prompts/generated/library-components/SbInputPropsDocs.d.ts +2 -0
  79. package/dist/ai-service/prompts/generated/library-components/SbInputPropsDocs.d.ts.map +1 -0
  80. package/dist/ai-service/prompts/generated/library-components/SbInputPropsDocs.js +6 -0
  81. package/dist/ai-service/prompts/generated/library-components/SbInputPropsDocs.js.map +1 -0
  82. package/dist/ai-service/prompts/generated/library-components/SbKeyValuePropsDocs.d.ts +2 -0
  83. package/dist/ai-service/prompts/generated/library-components/SbKeyValuePropsDocs.d.ts.map +1 -0
  84. package/dist/ai-service/prompts/generated/library-components/SbKeyValuePropsDocs.js +6 -0
  85. package/dist/ai-service/prompts/generated/library-components/SbKeyValuePropsDocs.js.map +1 -0
  86. package/dist/ai-service/prompts/generated/library-components/SbModalPropsDocs.d.ts +2 -0
  87. package/dist/ai-service/prompts/generated/library-components/SbModalPropsDocs.d.ts.map +1 -0
  88. package/dist/ai-service/prompts/generated/library-components/SbModalPropsDocs.js +6 -0
  89. package/dist/ai-service/prompts/generated/library-components/SbModalPropsDocs.js.map +1 -0
  90. package/dist/ai-service/prompts/generated/library-components/SbPagePropsDocs.d.ts +2 -0
  91. package/dist/ai-service/prompts/generated/library-components/SbPagePropsDocs.d.ts.map +1 -0
  92. package/dist/ai-service/prompts/generated/library-components/SbPagePropsDocs.js +6 -0
  93. package/dist/ai-service/prompts/generated/library-components/SbPagePropsDocs.js.map +1 -0
  94. package/dist/ai-service/prompts/generated/library-components/SbSectionPropsDocs.d.ts +2 -0
  95. package/dist/ai-service/prompts/generated/library-components/SbSectionPropsDocs.d.ts.map +1 -0
  96. package/dist/ai-service/prompts/generated/library-components/SbSectionPropsDocs.js +6 -0
  97. package/dist/ai-service/prompts/generated/library-components/SbSectionPropsDocs.js.map +1 -0
  98. package/dist/ai-service/prompts/generated/library-components/SbSlideoutPropsDocs.d.ts +2 -0
  99. package/dist/ai-service/prompts/generated/library-components/SbSlideoutPropsDocs.d.ts.map +1 -0
  100. package/dist/ai-service/prompts/generated/library-components/SbSlideoutPropsDocs.js +6 -0
  101. package/dist/ai-service/prompts/generated/library-components/SbSlideoutPropsDocs.js.map +1 -0
  102. package/dist/ai-service/prompts/generated/library-components/SbSwitchPropsDocs.d.ts +2 -0
  103. package/dist/ai-service/prompts/generated/library-components/SbSwitchPropsDocs.d.ts.map +1 -0
  104. package/dist/ai-service/prompts/generated/library-components/SbSwitchPropsDocs.js +6 -0
  105. package/dist/ai-service/prompts/generated/library-components/SbSwitchPropsDocs.js.map +1 -0
  106. package/dist/ai-service/prompts/generated/library-components/SbTablePropsDocs.d.ts +2 -0
  107. package/dist/ai-service/prompts/generated/library-components/SbTablePropsDocs.d.ts.map +1 -0
  108. package/dist/ai-service/prompts/generated/library-components/SbTablePropsDocs.js +6 -0
  109. package/dist/ai-service/prompts/generated/library-components/SbTablePropsDocs.js.map +1 -0
  110. package/dist/ai-service/prompts/generated/library-components/SbTextPropsDocs.d.ts +2 -0
  111. package/dist/ai-service/prompts/generated/library-components/SbTextPropsDocs.d.ts.map +1 -0
  112. package/dist/ai-service/prompts/generated/library-components/SbTextPropsDocs.js +6 -0
  113. package/dist/ai-service/prompts/generated/library-components/SbTextPropsDocs.js.map +1 -0
  114. package/dist/ai-service/prompts/generated/library-components/index.d.ts +18 -0
  115. package/dist/ai-service/prompts/generated/library-components/index.d.ts.map +1 -0
  116. package/dist/ai-service/prompts/generated/library-components/index.js +20 -0
  117. package/dist/ai-service/prompts/generated/library-components/index.js.map +1 -0
  118. package/dist/ai-service/prompts/generated/library-typedefs/Dim.d.ts +2 -0
  119. package/dist/ai-service/prompts/generated/library-typedefs/Dim.d.ts.map +1 -0
  120. package/dist/ai-service/prompts/generated/library-typedefs/Dim.js +6 -0
  121. package/dist/ai-service/prompts/generated/library-typedefs/Dim.js.map +1 -0
  122. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.d.ts +2 -0
  123. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.d.ts.map +1 -0
  124. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js +6 -0
  125. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js.map +1 -0
  126. package/dist/ai-service/prompts/generated/library-typedefs/index.d.ts +3 -0
  127. package/dist/ai-service/prompts/generated/library-typedefs/index.d.ts.map +1 -0
  128. package/dist/ai-service/prompts/generated/library-typedefs/index.js +5 -0
  129. package/dist/ai-service/prompts/generated/library-typedefs/index.js.map +1 -0
  130. package/dist/ai-service/prompts/generated/subprompts/index.d.ts +12 -0
  131. package/dist/ai-service/prompts/generated/subprompts/index.d.ts.map +1 -0
  132. package/dist/ai-service/prompts/generated/subprompts/index.js +14 -0
  133. package/dist/ai-service/prompts/generated/subprompts/index.js.map +1 -0
  134. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.d.ts +2 -0
  135. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.d.ts.map +1 -0
  136. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.js +6 -0
  137. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.js.map +1 -0
  138. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.d.ts +2 -0
  139. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.d.ts.map +1 -0
  140. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.js +6 -0
  141. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.js.map +1 -0
  142. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.d.ts +2 -0
  143. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.d.ts.map +1 -0
  144. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.js +6 -0
  145. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.js.map +1 -0
  146. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.d.ts +2 -0
  147. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.d.ts.map +1 -0
  148. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.js +6 -0
  149. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.js.map +1 -0
  150. package/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.d.ts +2 -0
  151. package/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.d.ts.map +1 -0
  152. package/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.js +6 -0
  153. package/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.js.map +1 -0
  154. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.d.ts +2 -0
  155. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.d.ts.map +1 -0
  156. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.js +6 -0
  157. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.js.map +1 -0
  158. package/dist/ai-service/prompts/generated/subprompts/superblocks-routes.d.ts +2 -0
  159. package/dist/ai-service/prompts/generated/subprompts/superblocks-routes.d.ts.map +1 -0
  160. package/dist/ai-service/prompts/generated/subprompts/superblocks-routes.js +6 -0
  161. package/dist/ai-service/prompts/generated/subprompts/superblocks-routes.js.map +1 -0
  162. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.d.ts +2 -0
  163. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.d.ts.map +1 -0
  164. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.js +6 -0
  165. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.js.map +1 -0
  166. package/dist/ai-service/prompts/generated/subprompts/superblocks-theming.d.ts +2 -0
  167. package/dist/ai-service/prompts/generated/subprompts/superblocks-theming.d.ts.map +1 -0
  168. package/dist/ai-service/prompts/generated/subprompts/superblocks-theming.js +6 -0
  169. package/dist/ai-service/prompts/generated/subprompts/superblocks-theming.js.map +1 -0
  170. package/dist/ai-service/prompts/generated/subprompts/superblocks-timers.d.ts +2 -0
  171. package/dist/ai-service/prompts/generated/subprompts/superblocks-timers.d.ts.map +1 -0
  172. package/dist/ai-service/prompts/generated/subprompts/superblocks-timers.js +6 -0
  173. package/dist/ai-service/prompts/generated/subprompts/superblocks-timers.js.map +1 -0
  174. package/dist/ai-service/prompts/generated/subprompts/system.d.ts +2 -0
  175. package/dist/ai-service/prompts/generated/subprompts/system.d.ts.map +1 -0
  176. package/dist/ai-service/prompts/generated/subprompts/system.js +6 -0
  177. package/dist/ai-service/prompts/generated/subprompts/system.js.map +1 -0
  178. package/dist/ai-service/prompts/markdown-loader.d.ts +9 -0
  179. package/dist/ai-service/prompts/markdown-loader.d.ts.map +1 -0
  180. package/dist/ai-service/prompts/markdown-loader.js +55 -0
  181. package/dist/ai-service/prompts/markdown-loader.js.map +1 -0
  182. package/dist/ai-service/prompts/system.d.ts +2 -0
  183. package/dist/ai-service/prompts/system.d.ts.map +1 -0
  184. package/dist/ai-service/prompts/system.js +145 -0
  185. package/dist/ai-service/prompts/system.js.map +1 -0
  186. package/dist/ai-service/result-buffer/bolt.d.ts +15 -0
  187. package/dist/ai-service/result-buffer/bolt.d.ts.map +1 -0
  188. package/dist/ai-service/result-buffer/bolt.js +73 -0
  189. package/dist/ai-service/result-buffer/bolt.js.map +1 -0
  190. package/dist/ai-service/result-buffer/shared.d.ts +13 -0
  191. package/dist/ai-service/result-buffer/shared.d.ts.map +1 -0
  192. package/dist/ai-service/result-buffer/shared.js +7 -0
  193. package/dist/ai-service/result-buffer/shared.js.map +1 -0
  194. package/dist/ai-service/state-machine/clark-fsm.d.ts +158 -0
  195. package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -0
  196. package/dist/ai-service/state-machine/clark-fsm.js +62 -0
  197. package/dist/ai-service/state-machine/clark-fsm.js.map +1 -0
  198. package/dist/ai-service/state-machine/fsm.d.ts +42 -0
  199. package/dist/ai-service/state-machine/fsm.d.ts.map +1 -0
  200. package/dist/ai-service/state-machine/fsm.js +55 -0
  201. package/dist/ai-service/state-machine/fsm.js.map +1 -0
  202. package/dist/ai-service/state-machine/handlers/agent-planning.d.ts +3 -0
  203. package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -0
  204. package/dist/ai-service/state-machine/handlers/agent-planning.js +209 -0
  205. package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -0
  206. package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts +3 -0
  207. package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -0
  208. package/dist/ai-service/state-machine/handlers/awaiting-user.js +21 -0
  209. package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -0
  210. package/dist/ai-service/state-machine/handlers/idle.d.ts +3 -0
  211. package/dist/ai-service/state-machine/handlers/idle.d.ts.map +1 -0
  212. package/dist/ai-service/state-machine/handlers/idle.js +22 -0
  213. package/dist/ai-service/state-machine/handlers/idle.js.map +1 -0
  214. package/dist/ai-service/state-machine/handlers/llm-generating.d.ts +3 -0
  215. package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -0
  216. package/dist/ai-service/state-machine/handlers/llm-generating.js +123 -0
  217. package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -0
  218. package/dist/ai-service/state-machine/handlers/play-dead.d.ts +3 -0
  219. package/dist/ai-service/state-machine/handlers/play-dead.d.ts.map +1 -0
  220. package/dist/ai-service/state-machine/handlers/play-dead.js +11 -0
  221. package/dist/ai-service/state-machine/handlers/play-dead.js.map +1 -0
  222. package/dist/ai-service/state-machine/handlers/post-processing.d.ts +3 -0
  223. package/dist/ai-service/state-machine/handlers/post-processing.d.ts.map +1 -0
  224. package/dist/ai-service/state-machine/handlers/post-processing.js +50 -0
  225. package/dist/ai-service/state-machine/handlers/post-processing.js.map +1 -0
  226. package/dist/ai-service/state-machine/handlers/runtime-reviewing.d.ts +3 -0
  227. package/dist/ai-service/state-machine/handlers/runtime-reviewing.d.ts.map +1 -0
  228. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js +37 -0
  229. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js.map +1 -0
  230. package/dist/ai-service/state-machine/helpers/metadata.d.ts +6 -0
  231. package/dist/ai-service/state-machine/helpers/metadata.d.ts.map +1 -0
  232. package/dist/ai-service/state-machine/helpers/metadata.js +11 -0
  233. package/dist/ai-service/state-machine/helpers/metadata.js.map +1 -0
  234. package/dist/ai-service/state-machine/helpers/peer.d.ts +5 -0
  235. package/dist/ai-service/state-machine/helpers/peer.d.ts.map +1 -0
  236. package/dist/ai-service/state-machine/helpers/peer.js +7 -0
  237. package/dist/ai-service/state-machine/helpers/peer.js.map +1 -0
  238. package/dist/ai-service/state-machine/helpers/transition.d.ts +13 -0
  239. package/dist/ai-service/state-machine/helpers/transition.d.ts.map +1 -0
  240. package/dist/ai-service/state-machine/helpers/transition.js +6 -0
  241. package/dist/ai-service/state-machine/helpers/transition.js.map +1 -0
  242. package/dist/ai-service/state-machine/mocks.d.ts +7 -0
  243. package/dist/ai-service/state-machine/mocks.d.ts.map +1 -0
  244. package/dist/ai-service/state-machine/mocks.js +63 -0
  245. package/dist/ai-service/state-machine/mocks.js.map +1 -0
  246. package/dist/ai-service/state-machine/test-util.d.ts +5 -0
  247. package/dist/ai-service/state-machine/test-util.d.ts.map +1 -0
  248. package/dist/ai-service/state-machine/test-util.js +29 -0
  249. package/dist/ai-service/state-machine/test-util.js.map +1 -0
  250. package/dist/ai-service/transform/add-metadata-to-api-yaml/transformer.d.ts +21 -0
  251. package/dist/ai-service/transform/add-metadata-to-api-yaml/transformer.d.ts.map +1 -0
  252. package/dist/ai-service/transform/add-metadata-to-api-yaml/transformer.js +47 -0
  253. package/dist/ai-service/transform/add-metadata-to-api-yaml/transformer.js.map +1 -0
  254. package/dist/ai-service/transform/api-builder/shared.d.ts +11 -0
  255. package/dist/ai-service/transform/api-builder/shared.d.ts.map +1 -0
  256. package/dist/ai-service/transform/api-builder/shared.js +53 -0
  257. package/dist/ai-service/transform/api-builder/shared.js.map +1 -0
  258. package/dist/ai-service/transform/api-builder/to-sdk-transformer.d.ts +27 -0
  259. package/dist/ai-service/transform/api-builder/to-sdk-transformer.d.ts.map +1 -0
  260. package/dist/ai-service/transform/api-builder/to-sdk-transformer.js +66 -0
  261. package/dist/ai-service/transform/api-builder/to-sdk-transformer.js.map +1 -0
  262. package/dist/ai-service/transform/api-builder/to-yaml-transformer.d.ts +23 -0
  263. package/dist/ai-service/transform/api-builder/to-yaml-transformer.d.ts.map +1 -0
  264. package/dist/ai-service/transform/api-builder/to-yaml-transformer.js +59 -0
  265. package/dist/ai-service/transform/api-builder/to-yaml-transformer.js.map +1 -0
  266. package/dist/ai-service/transform/remove-api-builder-imports/transformer.d.ts +19 -0
  267. package/dist/ai-service/transform/remove-api-builder-imports/transformer.d.ts.map +1 -0
  268. package/dist/ai-service/transform/remove-api-builder-imports/transformer.js +45 -0
  269. package/dist/ai-service/transform/remove-api-builder-imports/transformer.js.map +1 -0
  270. package/dist/ai-service/transform/shared.d.ts +20 -0
  271. package/dist/ai-service/transform/shared.d.ts.map +1 -0
  272. package/dist/ai-service/transform/shared.js +132 -0
  273. package/dist/ai-service/transform/shared.js.map +1 -0
  274. package/dist/ai-service/transform/workaround-missing-sbapi/transformer.d.ts +17 -0
  275. package/dist/ai-service/transform/workaround-missing-sbapi/transformer.d.ts.map +1 -0
  276. package/dist/ai-service/transform/workaround-missing-sbapi/transformer.js +33 -0
  277. package/dist/ai-service/transform/workaround-missing-sbapi/transformer.js.map +1 -0
  278. package/dist/ai-service/types.d.ts +65 -0
  279. package/dist/ai-service/types.d.ts.map +1 -0
  280. package/dist/ai-service/types.js +2 -0
  281. package/dist/ai-service/types.js.map +1 -0
  282. package/dist/binding-extraction/extract-control-block-identifiers.d.ts +4 -0
  283. package/dist/binding-extraction/extract-control-block-identifiers.d.ts.map +1 -0
  284. package/dist/binding-extraction/extract-control-block-identifiers.js +86 -0
  285. package/dist/binding-extraction/extract-control-block-identifiers.js.map +1 -0
  286. package/dist/binding-extraction/extract-embedded-identifiers.d.ts +16 -0
  287. package/dist/binding-extraction/extract-embedded-identifiers.d.ts.map +1 -0
  288. package/dist/binding-extraction/extract-embedded-identifiers.js +100 -0
  289. package/dist/binding-extraction/extract-embedded-identifiers.js.map +1 -0
  290. package/dist/binding-extraction/extract-identifiers.d.ts +8 -0
  291. package/dist/binding-extraction/extract-identifiers.d.ts.map +1 -0
  292. package/dist/binding-extraction/extract-identifiers.js +150 -0
  293. package/dist/binding-extraction/extract-identifiers.js.map +1 -0
  294. package/dist/binding-extraction/extract-js-identifiers.d.ts +19 -0
  295. package/dist/binding-extraction/extract-js-identifiers.d.ts.map +1 -0
  296. package/dist/binding-extraction/extract-js-identifiers.js +161 -0
  297. package/dist/binding-extraction/extract-js-identifiers.js.map +1 -0
  298. package/dist/binding-extraction/extract-py-identifiers.d.ts +4 -0
  299. package/dist/binding-extraction/extract-py-identifiers.d.ts.map +1 -0
  300. package/dist/binding-extraction/extract-py-identifiers.js +161 -0
  301. package/dist/binding-extraction/extract-py-identifiers.js.map +1 -0
  302. package/dist/binding-extraction/shared.d.ts +225 -0
  303. package/dist/binding-extraction/shared.d.ts.map +1 -0
  304. package/dist/binding-extraction/shared.js +43 -0
  305. package/dist/binding-extraction/shared.js.map +1 -0
  306. package/dist/binding-extraction/template-strings.d.ts +9 -0
  307. package/dist/binding-extraction/template-strings.d.ts.map +1 -0
  308. package/dist/binding-extraction/template-strings.js +45 -0
  309. package/dist/binding-extraction/template-strings.js.map +1 -0
  310. package/dist/codegen.d.ts +26 -0
  311. package/dist/codegen.d.ts.map +1 -0
  312. package/dist/codegen.js +217 -0
  313. package/dist/codegen.js.map +1 -0
  314. package/dist/components-manager.d.ts +38 -0
  315. package/dist/components-manager.d.ts.map +1 -0
  316. package/dist/components-manager.js +177 -0
  317. package/dist/components-manager.js.map +1 -0
  318. package/dist/custom-components.d.ts +6 -0
  319. package/dist/custom-components.d.ts.map +1 -0
  320. package/dist/custom-components.js +51 -0
  321. package/dist/custom-components.js.map +1 -0
  322. package/dist/draft-interface.d.ts +11 -0
  323. package/dist/draft-interface.d.ts.map +1 -0
  324. package/dist/draft-interface.js +2 -0
  325. package/dist/draft-interface.js.map +1 -0
  326. package/dist/errors/error-handler.d.ts +35 -0
  327. package/dist/errors/error-handler.d.ts.map +1 -0
  328. package/dist/errors/error-handler.js +65 -0
  329. package/dist/errors/error-handler.js.map +1 -0
  330. package/dist/errors/make-server-error.d.ts +5 -0
  331. package/dist/errors/make-server-error.d.ts.map +1 -0
  332. package/dist/errors/make-server-error.js +21 -0
  333. package/dist/errors/make-server-error.js.map +1 -0
  334. package/dist/file-sync-vite-plugin.d.ts +4 -0
  335. package/dist/file-sync-vite-plugin.d.ts.map +1 -0
  336. package/dist/file-sync-vite-plugin.js +573 -0
  337. package/dist/file-sync-vite-plugin.js.map +1 -0
  338. package/dist/file-system-helpers.d.ts +7 -0
  339. package/dist/file-system-helpers.d.ts.map +1 -0
  340. package/dist/file-system-helpers.js +12 -0
  341. package/dist/file-system-helpers.js.map +1 -0
  342. package/dist/file-system-manager.d.ts +131 -0
  343. package/dist/file-system-manager.d.ts.map +1 -0
  344. package/dist/file-system-manager.js +1159 -0
  345. package/dist/file-system-manager.js.map +1 -0
  346. package/dist/generate.d.ts +8 -0
  347. package/dist/generate.d.ts.map +1 -0
  348. package/dist/generate.js +7 -0
  349. package/dist/generate.js.map +1 -0
  350. package/dist/ids.d.ts +2 -0
  351. package/dist/ids.d.ts.map +1 -0
  352. package/dist/ids.js +21 -0
  353. package/dist/ids.js.map +1 -0
  354. package/dist/index.d.ts +6 -0
  355. package/dist/index.d.ts.map +1 -0
  356. package/dist/index.js +6 -0
  357. package/dist/index.js.map +1 -0
  358. package/dist/injected-index.d.ts +12 -0
  359. package/dist/injected-index.d.ts.map +1 -0
  360. package/dist/injected-index.js +38 -0
  361. package/dist/injected-index.js.map +1 -0
  362. package/dist/lock-service/index.d.ts +93 -0
  363. package/dist/lock-service/index.d.ts.map +1 -0
  364. package/dist/lock-service/index.js +267 -0
  365. package/dist/lock-service/index.js.map +1 -0
  366. package/dist/parsing/bindings.d.ts +4 -0
  367. package/dist/parsing/bindings.d.ts.map +1 -0
  368. package/dist/parsing/bindings.js +17 -0
  369. package/dist/parsing/bindings.js.map +1 -0
  370. package/dist/parsing/computed/to-code-computed.d.ts +2 -0
  371. package/dist/parsing/computed/to-code-computed.d.ts.map +1 -0
  372. package/dist/parsing/computed/to-code-computed.js +39 -0
  373. package/dist/parsing/computed/to-code-computed.js.map +1 -0
  374. package/dist/parsing/computed/to-value-computed.d.ts +4 -0
  375. package/dist/parsing/computed/to-value-computed.d.ts.map +1 -0
  376. package/dist/parsing/computed/to-value-computed.js +13 -0
  377. package/dist/parsing/computed/to-value-computed.js.map +1 -0
  378. package/dist/parsing/dim/to-code-dimensions.d.ts +3 -0
  379. package/dist/parsing/dim/to-code-dimensions.d.ts.map +1 -0
  380. package/dist/parsing/dim/to-code-dimensions.js +22 -0
  381. package/dist/parsing/dim/to-code-dimensions.js.map +1 -0
  382. package/dist/parsing/dim/to-value-dimensions.d.ts +4 -0
  383. package/dist/parsing/dim/to-value-dimensions.d.ts.map +1 -0
  384. package/dist/parsing/dim/to-value-dimensions.js +39 -0
  385. package/dist/parsing/dim/to-value-dimensions.js.map +1 -0
  386. package/dist/parsing/entity/index.d.ts +8 -0
  387. package/dist/parsing/entity/index.d.ts.map +1 -0
  388. package/dist/parsing/entity/index.js +8 -0
  389. package/dist/parsing/entity/index.js.map +1 -0
  390. package/dist/parsing/entity/to-code-entity.d.ts +3 -0
  391. package/dist/parsing/entity/to-code-entity.d.ts.map +1 -0
  392. package/dist/parsing/entity/to-code-entity.js +38 -0
  393. package/dist/parsing/entity/to-code-entity.js.map +1 -0
  394. package/dist/parsing/entity/to-value-entity.d.ts +8 -0
  395. package/dist/parsing/entity/to-value-entity.d.ts.map +1 -0
  396. package/dist/parsing/entity/to-value-entity.js +98 -0
  397. package/dist/parsing/entity/to-value-entity.js.map +1 -0
  398. package/dist/parsing/events/to-code-events.d.ts +3 -0
  399. package/dist/parsing/events/to-code-events.d.ts.map +1 -0
  400. package/dist/parsing/events/to-code-events.js +86 -0
  401. package/dist/parsing/events/to-code-events.js.map +1 -0
  402. package/dist/parsing/events/to-value-events.d.ts +5 -0
  403. package/dist/parsing/events/to-value-events.d.ts.map +1 -0
  404. package/dist/parsing/events/to-value-events.js +155 -0
  405. package/dist/parsing/events/to-value-events.js.map +1 -0
  406. package/dist/parsing/ids.d.ts +17 -0
  407. package/dist/parsing/ids.d.ts.map +1 -0
  408. package/dist/parsing/ids.js +121 -0
  409. package/dist/parsing/ids.js.map +1 -0
  410. package/dist/parsing/imports.d.ts +6 -0
  411. package/dist/parsing/imports.d.ts.map +1 -0
  412. package/dist/parsing/imports.js +27 -0
  413. package/dist/parsing/imports.js.map +1 -0
  414. package/dist/parsing/jsx-utils.d.ts +9 -0
  415. package/dist/parsing/jsx-utils.d.ts.map +1 -0
  416. package/dist/parsing/jsx-utils.js +42 -0
  417. package/dist/parsing/jsx-utils.js.map +1 -0
  418. package/dist/parsing/jsx.d.ts +23 -0
  419. package/dist/parsing/jsx.d.ts.map +1 -0
  420. package/dist/parsing/jsx.js +327 -0
  421. package/dist/parsing/jsx.js.map +1 -0
  422. package/dist/parsing/page.d.ts +9 -0
  423. package/dist/parsing/page.d.ts.map +1 -0
  424. package/dist/parsing/page.js +156 -0
  425. package/dist/parsing/page.js.map +1 -0
  426. package/dist/parsing/properties.d.ts +5 -0
  427. package/dist/parsing/properties.d.ts.map +1 -0
  428. package/dist/parsing/properties.js +89 -0
  429. package/dist/parsing/properties.js.map +1 -0
  430. package/dist/parsing/scope.d.ts +80 -0
  431. package/dist/parsing/scope.d.ts.map +1 -0
  432. package/dist/parsing/scope.js +549 -0
  433. package/dist/parsing/scope.js.map +1 -0
  434. package/dist/parsing/template/to-code-template.d.ts +2 -0
  435. package/dist/parsing/template/to-code-template.d.ts.map +1 -0
  436. package/dist/parsing/template/to-code-template.js +5 -0
  437. package/dist/parsing/template/to-code-template.js.map +1 -0
  438. package/dist/parsing/template/to-value-template.d.ts +4 -0
  439. package/dist/parsing/template/to-value-template.d.ts.map +1 -0
  440. package/dist/parsing/template/to-value-template.js +19 -0
  441. package/dist/parsing/template/to-value-template.js.map +1 -0
  442. package/dist/parsing/theme.d.ts +3 -0
  443. package/dist/parsing/theme.d.ts.map +1 -0
  444. package/dist/parsing/theme.js +87 -0
  445. package/dist/parsing/theme.js.map +1 -0
  446. package/dist/parsing/type-parsing-registry.d.ts +18 -0
  447. package/dist/parsing/type-parsing-registry.d.ts.map +1 -0
  448. package/dist/parsing/type-parsing-registry.js +31 -0
  449. package/dist/parsing/type-parsing-registry.js.map +1 -0
  450. package/dist/parsing/util.d.ts +30 -0
  451. package/dist/parsing/util.d.ts.map +1 -0
  452. package/dist/parsing/util.js +310 -0
  453. package/dist/parsing/util.js.map +1 -0
  454. package/dist/plugin-options.d.ts +25 -0
  455. package/dist/plugin-options.d.ts.map +1 -0
  456. package/dist/plugin-options.js +14 -0
  457. package/dist/plugin-options.js.map +1 -0
  458. package/dist/refactor/blocks.d.ts +10 -0
  459. package/dist/refactor/blocks.d.ts.map +1 -0
  460. package/dist/refactor/blocks.js +214 -0
  461. package/dist/refactor/blocks.js.map +1 -0
  462. package/dist/refactor/javascript.d.ts +15 -0
  463. package/dist/refactor/javascript.d.ts.map +1 -0
  464. package/dist/refactor/javascript.js +171 -0
  465. package/dist/refactor/javascript.js.map +1 -0
  466. package/dist/refactor-jsx.d.ts +28 -0
  467. package/dist/refactor-jsx.d.ts.map +1 -0
  468. package/dist/refactor-jsx.js +77 -0
  469. package/dist/refactor-jsx.js.map +1 -0
  470. package/dist/rename-manager.d.ts +27 -0
  471. package/dist/rename-manager.d.ts.map +1 -0
  472. package/dist/rename-manager.js +148 -0
  473. package/dist/rename-manager.js.map +1 -0
  474. package/dist/routing.d.ts +6 -0
  475. package/dist/routing.d.ts.map +1 -0
  476. package/dist/routing.js +76 -0
  477. package/dist/routing.js.map +1 -0
  478. package/dist/sb-scope-manager.d.ts +96 -0
  479. package/dist/sb-scope-manager.d.ts.map +1 -0
  480. package/dist/sb-scope-manager.js +438 -0
  481. package/dist/sb-scope-manager.js.map +1 -0
  482. package/dist/socket-manager.d.ts +40 -0
  483. package/dist/socket-manager.d.ts.map +1 -0
  484. package/dist/socket-manager.js +174 -0
  485. package/dist/socket-manager.js.map +1 -0
  486. package/dist/source-tracker.d.ts +190 -0
  487. package/dist/source-tracker.d.ts.map +1 -0
  488. package/dist/source-tracker.js +955 -0
  489. package/dist/source-tracker.js.map +1 -0
  490. package/dist/sync-service/download.d.ts +15 -0
  491. package/dist/sync-service/download.d.ts.map +1 -0
  492. package/dist/sync-service/download.js +116 -0
  493. package/dist/sync-service/download.js.map +1 -0
  494. package/dist/sync-service/draft-helpers.d.ts +68 -0
  495. package/dist/sync-service/draft-helpers.d.ts.map +1 -0
  496. package/dist/sync-service/draft-helpers.js +362 -0
  497. package/dist/sync-service/draft-helpers.js.map +1 -0
  498. package/dist/sync-service/hash-cache.d.ts +15 -0
  499. package/dist/sync-service/hash-cache.d.ts.map +1 -0
  500. package/dist/sync-service/hash-cache.js +58 -0
  501. package/dist/sync-service/hash-cache.js.map +1 -0
  502. package/dist/sync-service/hash-dir-tree.d.ts +10 -0
  503. package/dist/sync-service/hash-dir-tree.d.ts.map +1 -0
  504. package/dist/sync-service/hash-dir-tree.js +53 -0
  505. package/dist/sync-service/hash-dir-tree.js.map +1 -0
  506. package/dist/sync-service/index.d.ts +134 -0
  507. package/dist/sync-service/index.d.ts.map +1 -0
  508. package/dist/sync-service/index.js +323 -0
  509. package/dist/sync-service/index.js.map +1 -0
  510. package/dist/sync-service/list-dir.d.ts +29 -0
  511. package/dist/sync-service/list-dir.d.ts.map +1 -0
  512. package/dist/sync-service/list-dir.js +66 -0
  513. package/dist/sync-service/list-dir.js.map +1 -0
  514. package/dist/sync-service/server-rpc/client.d.ts +13 -0
  515. package/dist/sync-service/server-rpc/client.d.ts.map +1 -0
  516. package/dist/sync-service/server-rpc/client.js +62 -0
  517. package/dist/sync-service/server-rpc/client.js.map +1 -0
  518. package/dist/sync-service/server-rpc/handlers.d.ts +3 -0
  519. package/dist/sync-service/server-rpc/handlers.d.ts.map +1 -0
  520. package/dist/sync-service/server-rpc/handlers.js +18 -0
  521. package/dist/sync-service/server-rpc/handlers.js.map +1 -0
  522. package/dist/sync-service/snapshot/take-snapshot.d.ts +38 -0
  523. package/dist/sync-service/snapshot/take-snapshot.d.ts.map +1 -0
  524. package/dist/sync-service/snapshot/take-snapshot.js +232 -0
  525. package/dist/sync-service/snapshot/take-snapshot.js.map +1 -0
  526. package/dist/sync-service/snapshot/types.d.ts +24 -0
  527. package/dist/sync-service/snapshot/types.d.ts.map +1 -0
  528. package/dist/sync-service/snapshot/types.js +3 -0
  529. package/dist/sync-service/snapshot/types.js.map +1 -0
  530. package/dist/sync-service/snapshot/upload-snapshot.d.ts +5 -0
  531. package/dist/sync-service/snapshot/upload-snapshot.d.ts.map +1 -0
  532. package/dist/sync-service/snapshot/upload-snapshot.js +50 -0
  533. package/dist/sync-service/snapshot/upload-snapshot.js.map +1 -0
  534. package/dist/traverse.d.ts +6 -0
  535. package/dist/traverse.d.ts.map +1 -0
  536. package/dist/traverse.js +7 -0
  537. package/dist/traverse.js.map +1 -0
  538. package/dist/util/generation-number-sequence.d.ts +7 -0
  539. package/dist/util/generation-number-sequence.d.ts.map +1 -0
  540. package/dist/util/generation-number-sequence.js +13 -0
  541. package/dist/util/generation-number-sequence.js.map +1 -0
  542. package/dist/util/logger.d.ts +22 -0
  543. package/dist/util/logger.d.ts.map +1 -0
  544. package/dist/util/logger.js +64 -0
  545. package/dist/util/logger.js.map +1 -0
  546. package/dist/util/operation-queue.d.ts +17 -0
  547. package/dist/util/operation-queue.d.ts.map +1 -0
  548. package/dist/util/operation-queue.js +27 -0
  549. package/dist/util/operation-queue.js.map +1 -0
  550. package/dist/util/tracing.d.ts +4 -0
  551. package/dist/util/tracing.d.ts.map +1 -0
  552. package/dist/util/tracing.js +19 -0
  553. package/dist/util/tracing.js.map +1 -0
  554. package/dist/util/with-resolvers.d.ts +10 -0
  555. package/dist/util/with-resolvers.d.ts.map +1 -0
  556. package/dist/util/with-resolvers.js +14 -0
  557. package/dist/util/with-resolvers.js.map +1 -0
  558. package/dist/util.d.ts +26 -0
  559. package/dist/util.d.ts.map +1 -0
  560. package/dist/util.js +82 -0
  561. package/dist/util.js.map +1 -0
  562. package/package.json +123 -0
@@ -0,0 +1,1159 @@
1
+ import fs from "fs/promises";
2
+ import EventEmitter from "node:events";
3
+ import path from "node:path";
4
+ import { transformFromAstAsync } from "@babel/core";
5
+ import t from "@babel/types";
6
+ import { getClientApiId, PROCESSED_TRANSACTIONS_ATTRIBUTE, ROOT_WIDGET_ATTRIBUTE, WIDGET_SOURCE_ID_ATTRIBUTE, } from "@superblocksteam/library-shared";
7
+ import { readAppApiYamlFile, writeApiFiles, } from "@superblocksteam/util";
8
+ import { glob } from "glob";
9
+ import { isEqual } from "lodash-es";
10
+ import yaml from "yaml";
11
+ import { generateJSXAttribute } from "./codegen.js";
12
+ import { addLegacyCustomComponentVariables, modifyLegacyCustomComponentElements, modifyLegacyCustomComponentImports, } from "./custom-components.js";
13
+ import { applyErrorHandling, } from "./errors/error-handler.js";
14
+ import { getPageFolder, PAGES_DIRECTORY, ROUTES_FILE, SCOPE_FILE, } from "./file-system-helpers.js";
15
+ import { generate } from "./generate.js";
16
+ import { doesElementHaveBinding } from "./parsing/bindings.js";
17
+ import { getSbElementId } from "./parsing/ids.js";
18
+ import { makeJSXAttribute } from "./parsing/jsx.js";
19
+ import { getPageRoots } from "./parsing/page.js";
20
+ import { getScope } from "./parsing/scope.js";
21
+ import { getLegacyComponentsFolder, isCustomBuildEnabled, } from "./plugin-options.js";
22
+ import { RenameManager } from "./rename-manager.js";
23
+ import { SourceTracker } from "./source-tracker.js";
24
+ import { traverse } from "./traverse.js";
25
+ import { getErrorMeta, getLogger } from "./util/logger.js";
26
+ const SUPPORTED_FILETYPES = [
27
+ {
28
+ type: "tsx",
29
+ extension: ".tsx",
30
+ },
31
+ {
32
+ type: "scope",
33
+ extension: SCOPE_FILE,
34
+ },
35
+ {
36
+ type: "api",
37
+ extension: ".yaml",
38
+ },
39
+ {
40
+ type: "python-api-step",
41
+ extension: ".py",
42
+ },
43
+ {
44
+ type: "js-api-step",
45
+ extension: ".js",
46
+ },
47
+ ];
48
+ const APP_THEME_FILE_NAME = "appTheme.ts";
49
+ export class FileSyncManager extends EventEmitter {
50
+ rootDir;
51
+ tsFiles = {};
52
+ apiFiles = {};
53
+ sourceTracker;
54
+ fsOperationQueue;
55
+ generationNumberSequence;
56
+ routes = {};
57
+ watcher;
58
+ registeredComponentPaths = {};
59
+ renameManager = new RenameManager();
60
+ constructor(fsOperationQueue, generationNumberSequence) {
61
+ super({ captureRejections: true });
62
+ this.rootDir = "/";
63
+ this.fsOperationQueue = fsOperationQueue;
64
+ this.generationNumberSequence = generationNumberSequence;
65
+ applyErrorHandling(this, {
66
+ watch: { operation: "editing from code" },
67
+ handleCreatePage: { operation: "creating a page" },
68
+ handleReparent: { operation: "moving a component" },
69
+ handleCreateComponent: { operation: "creating a component" },
70
+ handleDeleteComponents: { operation: "deleting components" },
71
+ handleSetProperty: { operation: "setting a property" },
72
+ handleSetProperties: { operation: "setting properties" },
73
+ handleDeleteProperties: { operation: "deleting properties" },
74
+ handleBatchUpdate: { operation: "updating multiple things" },
75
+ handleUpdateApi: { operation: "updating an API" },
76
+ handleDeleteApi: { operation: "deleting an API" },
77
+ handleRenameApi: { operation: "renaming an API" },
78
+ handleAddEntity: { operation: "adding an entity" },
79
+ handleUpdateEntity: { operation: "updating an entity" },
80
+ handleDeleteEntity: { operation: "deleting an entity" },
81
+ handleUpdateTheme: { operation: "updating the theme" },
82
+ handleRenameElement: { operation: "renaming an element" },
83
+ });
84
+ }
85
+ get appFilePath() {
86
+ if (!this.rootDir) {
87
+ throw new Error("Root directory not set");
88
+ }
89
+ return path.join(this.rootDir, "App.tsx");
90
+ }
91
+ updateApi = (content, path) => {
92
+ if (!this.rootDir) {
93
+ throw new Error("Root directory not set");
94
+ }
95
+ const { api: apiContents, stepPathMap } = content;
96
+ const pageName = getPageName(path);
97
+ let scopeId = this.sourceTracker?.getScopeDefinitionForPage(pageName)?.id;
98
+ if (!scopeId) {
99
+ console.warn("Scope ID not found for API", apiContents.metadata.name);
100
+ scopeId = "";
101
+ }
102
+ const updatedApi = {
103
+ apiPb: yaml.parse(JSON.stringify(apiContents)),
104
+ pageName,
105
+ stepPathMap,
106
+ scopeId,
107
+ };
108
+ this.apiFiles[path] = updatedApi;
109
+ return { updatedApi, pageName };
110
+ };
111
+ async watch(watcher, rootPath) {
112
+ const logger = getLogger();
113
+ this.rootDir = rootPath;
114
+ this.watcher = watcher;
115
+ // APIs and pages are in the pages subfolder
116
+ const fileNames = await readFiles(path.join(rootPath));
117
+ // this reads all files excluding ignore list in the root path. Should we read all files in pages and add root.tsx and App.tsx instead?
118
+ const tsxFiles = fileNames.filter((f) => f.endsWith(".tsx") && !f.includes(`${getLegacyComponentsFolder()}/`));
119
+ const yamlFiles = fileNames.filter((f) => f.endsWith(".yaml"));
120
+ const scopeFiles = fileNames.filter((f) => f.endsWith(SCOPE_FILE));
121
+ // For the moment, the theme file is `appTheme.ts`. This may change in the future.
122
+ const appThemeFile = path.join(rootPath, APP_THEME_FILE_NAME);
123
+ logger.info(`files to be scanned ${JSON.stringify(tsxFiles)}`);
124
+ logger.info(`api files to be scanned ${JSON.stringify(yamlFiles)}`);
125
+ logger.info(`app theme file to be scanned ${JSON.stringify(appThemeFile)}`);
126
+ logger.info(`scope files to be scanned ${JSON.stringify(scopeFiles)}`);
127
+ const allFiles = [
128
+ ...tsxFiles.map((f) => {
129
+ return {
130
+ type: "tsx",
131
+ path: f,
132
+ content: readFile(f),
133
+ };
134
+ }),
135
+ ...scopeFiles.map((f) => {
136
+ return {
137
+ type: "ts",
138
+ path: f,
139
+ content: readFile(f),
140
+ };
141
+ }),
142
+ ...yamlFiles.map((f) => {
143
+ return {
144
+ type: "api",
145
+ path: f,
146
+ content: getMergedApiContent(f),
147
+ };
148
+ }),
149
+ ].flat();
150
+ if (appThemeFile) {
151
+ allFiles.push({
152
+ type: "ts",
153
+ path: appThemeFile,
154
+ content: readFile(appThemeFile),
155
+ });
156
+ }
157
+ const contents = await Promise.all(allFiles.map((f) => f.content));
158
+ contents.forEach((content, i) => {
159
+ if (!content)
160
+ return;
161
+ const file = allFiles[i];
162
+ if (!file)
163
+ return;
164
+ const { type, path } = file;
165
+ // We only want to load the typescript files here, before the source tracker is initialized
166
+ // API setup needs to be deferred until we've parsed the scope files (which is done in the source tracker)
167
+ if (type === "tsx" || type === "ts") {
168
+ this.tsFiles[path] = content;
169
+ }
170
+ });
171
+ // And routes are in the root
172
+ const routePath = path.join(rootPath, ROUTES_FILE);
173
+ const routeFile = await readFile(routePath);
174
+ if (routeFile) {
175
+ try {
176
+ this.routes = JSON.parse(routeFile);
177
+ }
178
+ catch (e) {
179
+ logger.error("Error parsing routes file", getErrorMeta(e));
180
+ }
181
+ }
182
+ try {
183
+ this.initializeSourceTracker();
184
+ }
185
+ catch (e) {
186
+ logger.error("Error initializing source tracker", getErrorMeta(e));
187
+ }
188
+ contents.forEach((content, i) => {
189
+ if (!content)
190
+ return;
191
+ const file = allFiles[i];
192
+ if (!file)
193
+ return;
194
+ const { type, path } = file;
195
+ if (type === "api") {
196
+ this.updateApi(content, path);
197
+ }
198
+ });
199
+ watcher.on("all", async (event, filePath) => {
200
+ switch (event) {
201
+ case "add": {
202
+ const fileType = SUPPORTED_FILETYPES.find((f) => filePath.endsWith(f.extension));
203
+ if (!fileType || !filePath.startsWith(rootPath)) {
204
+ return;
205
+ }
206
+ const data = await readFile(filePath);
207
+ if (typeof data !== "string")
208
+ return;
209
+ // if we match pages/*/index.tsx, we want to emit an addPage event
210
+ if (/pages\/.*\/index\.tsx/.test(filePath)) {
211
+ const file = await readFile(filePath);
212
+ if (!file) {
213
+ logger.error(`Failed to read file: ${filePath}`);
214
+ return;
215
+ }
216
+ if (!(filePath in this.tsFiles)) {
217
+ this.tsFiles[filePath] = file;
218
+ this.handleNonVisualChangeByDeletingIds(filePath, file);
219
+ this.emit("addPage", filePath);
220
+ }
221
+ }
222
+ switch (fileType.type) {
223
+ case "api":
224
+ case "python-api-step":
225
+ case "js-api-step": {
226
+ await processApiUpdates(filePath, fileType, logger, this.apiFiles, this.updateApi.bind(this), this.emit.bind(this), this.createClientApi.bind(this));
227
+ break;
228
+ }
229
+ }
230
+ break;
231
+ }
232
+ case "change": {
233
+ // Special routes file handling
234
+ if (filePath === routePath) {
235
+ const data = await readFile(filePath);
236
+ try {
237
+ this.routes = JSON.parse(data);
238
+ this.emit("routesChanged", this.routes);
239
+ }
240
+ catch (e) {
241
+ logger.error("Error parsing routes file", getErrorMeta(e));
242
+ }
243
+ return;
244
+ }
245
+ const fileType = SUPPORTED_FILETYPES.find((f) => filePath.endsWith(f.extension));
246
+ if (!fileType || !filePath.startsWith(rootPath)) {
247
+ return;
248
+ }
249
+ const data = await readFile(filePath);
250
+ if (typeof data !== "string")
251
+ return;
252
+ switch (fileType.type) {
253
+ case "tsx":
254
+ case "scope":
255
+ {
256
+ if (!(filePath in this.tsFiles && this.tsFiles[filePath] === data)) {
257
+ logger.info(`File changed: ${filePath} updating AST tracker`);
258
+ this.tsFiles[filePath] = data;
259
+ // only update the source tracker if the file is different
260
+ this.handleNonVisualChangeByDeletingIds(filePath, data);
261
+ this.emit("fileChanged", filePath, data, true);
262
+ }
263
+ else {
264
+ logger.info(`File unchanged from last tracked state: ${filePath}`);
265
+ this.emit("fileChanged", filePath, data, false);
266
+ }
267
+ }
268
+ break;
269
+ case "api":
270
+ case "python-api-step":
271
+ case "js-api-step":
272
+ {
273
+ await processApiUpdates(filePath, fileType, logger, this.apiFiles, this.updateApi.bind(this), this.emit.bind(this), this.createClientApi.bind(this));
274
+ }
275
+ break;
276
+ }
277
+ break;
278
+ }
279
+ case "unlink": {
280
+ if (filePath in this.apiFiles) {
281
+ const api = this.apiFiles[filePath];
282
+ delete this.apiFiles[filePath];
283
+ if (!api || !this.sourceTracker)
284
+ break;
285
+ const scopeId = await this.sourceTracker.deleteApi({
286
+ pageName: api.pageName,
287
+ apiName: api.apiPb.metadata.name,
288
+ });
289
+ this.emit("apiManualDelete", {
290
+ api: {
291
+ id: getClientApiId(api.apiPb.metadata.name, api.pageName),
292
+ apiName: api.apiPb.metadata.name,
293
+ // TODO(saksham): get pagename more defensively
294
+ pageName: filePath.split("/").slice(1, -1).join("/"),
295
+ scopeId,
296
+ },
297
+ });
298
+ }
299
+ if (filePath in this.tsFiles) {
300
+ delete this.tsFiles[filePath];
301
+ this.sourceTracker?.removeFile(filePath);
302
+ this.emit("deletePage", filePath);
303
+ }
304
+ break;
305
+ }
306
+ }
307
+ });
308
+ }
309
+ getApiFiles() {
310
+ return this.formatApisToClientApis(this.apiFiles);
311
+ }
312
+ getTsFilePaths() {
313
+ return Object.keys(this.tsFiles);
314
+ }
315
+ async writeFile(path, content, kind) {
316
+ if (kind === "ts") {
317
+ // happens eagerly regardless of error - possible desync
318
+ this.tsFiles[path] = content;
319
+ // TODO(george): as an optimization, we could update the memory snapshot of the file that SyncService is holding
320
+ await this.fsOperationQueue.enqueue(async () => {
321
+ await fs.writeFile(path, content);
322
+ });
323
+ }
324
+ else if (kind === "api") {
325
+ const currentApiFile = this.apiFiles[path];
326
+ const apiPb = yaml.parse(content);
327
+ // Client APIs have id, but server APIs don't
328
+ if (apiPb.metadata.id) {
329
+ delete apiPb.metadata.id;
330
+ }
331
+ const stepPathMap = currentApiFile?.stepPathMap ?? {};
332
+ this.updateApi({ api: apiPb, stepPathMap }, path);
333
+ // TODO(george): as an optimization, we could update the memory snapshot of the file that SyncService is holding
334
+ await this.fsOperationQueue.enqueue(async () => {
335
+ await writeApiFiles({ apiPb }, "api", path.split("/").slice(0, -1).join("/"), false, [], [], { extractLargeSourceFiles: true, minLinesForExtraction: 1 }, new Set(Object.keys(this.apiFiles)), stepPathMap);
336
+ // stepPathMap will be generated after the write when the file doesn't exist
337
+ if (this.apiFiles[path]) {
338
+ this.apiFiles[path].stepPathMap = stepPathMap;
339
+ }
340
+ });
341
+ }
342
+ }
343
+ readFile(path) {
344
+ return this.tsFiles[path];
345
+ }
346
+ initializeSourceTracker() {
347
+ this.sourceTracker = new SourceTracker();
348
+ this.sourceTracker.initializeSourceTracker({
349
+ files: this.tsFiles,
350
+ });
351
+ }
352
+ handleNonVisualChangeByDeletingIds(path, content) {
353
+ if (!this.sourceTracker) {
354
+ throw new Error("Source tracker not initialized");
355
+ }
356
+ return this.sourceTracker.handleNonVisualChangeByDeletingIds(path, content);
357
+ }
358
+ async getFileWithIds(path) {
359
+ const logger = getLogger();
360
+ if (!this.sourceTracker) {
361
+ throw new Error("Source tracker not initialized");
362
+ }
363
+ const files = this.sourceTracker.getCurrentFiles();
364
+ if (!files[path]) {
365
+ throw new Error("File not found in source tracker " + path);
366
+ }
367
+ const ast = files[path].ast;
368
+ if (!ast) {
369
+ throw new Error("No AST found for file in source tracker " + path);
370
+ }
371
+ const clonedAst = await transformFromAstAsync(ast, undefined, {
372
+ ast: true,
373
+ });
374
+ if (!clonedAst?.ast) {
375
+ throw new Error("Failed to clone AST for file " + path);
376
+ }
377
+ const processedTransactions = this.getProcessedTransactionsWithNonce();
378
+ const customImports = new Set();
379
+ let customBuildTraversal = {};
380
+ if (isCustomBuildEnabled()) {
381
+ customBuildTraversal = {
382
+ ImportDeclaration(path) {
383
+ // when we see a custom component, we want to track the import and modify it to point
384
+ // to the built source
385
+ modifyLegacyCustomComponentImports(path, customImports);
386
+ },
387
+ JSXElement(path) {
388
+ // based on the imports we see, we want to modify the JSXElement that uses the custom component
389
+ modifyLegacyCustomComponentElements(path, customImports);
390
+ },
391
+ Program: {
392
+ // we want to write the wrapped custom elements as local variables to the file
393
+ exit(path) {
394
+ addLegacyCustomComponentVariables(path, customImports);
395
+ },
396
+ },
397
+ };
398
+ }
399
+ traverse(clonedAst.ast, {
400
+ ...customBuildTraversal,
401
+ ReturnStatement(path) {
402
+ const argument = path.get("argument");
403
+ if (!argument.isJSXElement()) {
404
+ return;
405
+ }
406
+ const openingElement = argument.get("openingElement");
407
+ if (!openingElement.isJSXOpeningElement()) {
408
+ return;
409
+ }
410
+ openingElement.pushContainer("attributes", makeJSXAttribute(ROOT_WIDGET_ATTRIBUTE, "true"));
411
+ openingElement.pushContainer("attributes", generateJSXAttribute(PROCESSED_TRANSACTIONS_ATTRIBUTE, {
412
+ value: processedTransactions,
413
+ type: "EXPRESSION",
414
+ __info: true,
415
+ }));
416
+ },
417
+ JSXOpeningElement(path) {
418
+ const elementId = getSbElementId(path.node);
419
+ if (elementId) {
420
+ path.pushContainer("attributes", makeJSXAttribute(WIDGET_SOURCE_ID_ATTRIBUTE, elementId));
421
+ }
422
+ },
423
+ ObjectProperty(path) {
424
+ const elementId = getSbElementId(path.node);
425
+ if (!elementId) {
426
+ path.skip();
427
+ return;
428
+ }
429
+ path.traverse({
430
+ ObjectExpression(path) {
431
+ path.pushContainer("properties", t.objectProperty(t.identifier("id"), t.stringLiteral(elementId)));
432
+ path.skip();
433
+ },
434
+ });
435
+ },
436
+ });
437
+ try {
438
+ const result = generate(clonedAst.ast);
439
+ return result.code;
440
+ }
441
+ catch (e) {
442
+ logger.error("Error generating file with ids", getErrorMeta(e));
443
+ return null;
444
+ }
445
+ }
446
+ getLocalBindingEntities(path) {
447
+ const logger = getLogger();
448
+ const files = this.sourceTracker?.getCurrentFiles();
449
+ if (!files || !files[path]) {
450
+ logger.warn(`File not found in source tracker for local binding entities: ${path}`);
451
+ return [];
452
+ }
453
+ const ast = files[path].ast;
454
+ if (!ast) {
455
+ logger.warn(`No AST found for file in source tracker for local binding entities: ${path}`);
456
+ return [];
457
+ }
458
+ const localBindingEntities = new Set();
459
+ traverse(ast, {
460
+ JSXOpeningElement(path) {
461
+ const elementId = getSbElementId(path.node);
462
+ if (!elementId) {
463
+ return;
464
+ }
465
+ const hasLocalBinding = doesElementHaveBinding(path);
466
+ if (hasLocalBinding) {
467
+ localBindingEntities.add(elementId);
468
+ }
469
+ },
470
+ });
471
+ return Array.from(localBindingEntities);
472
+ }
473
+ pendingTransactions = new Set();
474
+ processedTransactions = [];
475
+ flushTransactions = () => {
476
+ // TODO do something more sophisticated than this.
477
+ this.processedTransactions = this.processedTransactions.slice(-20);
478
+ this.processedTransactions.push(...Array.from(this.pendingTransactions));
479
+ this.pendingTransactions.clear();
480
+ };
481
+ trackTransaction = (transactionId) => {
482
+ this.pendingTransactions.add(transactionId);
483
+ };
484
+ transactionNonce = Date.now();
485
+ // Until we have a sophisticated way to track ALL operations, including non-UI initiated ops, we will use a nonce
486
+ // TODO https://github.com/superblocksteam/superblocks/pull/11788
487
+ getProcessedTransactionsWithNonce() {
488
+ const nonce = `t-${this.transactionNonce++}`;
489
+ return this.processedTransactions.concat(nonce);
490
+ }
491
+ handleCreatePage = async (payload) => {
492
+ const { name } = payload;
493
+ if (!this.rootDir) {
494
+ throw new Error("Root directory not set");
495
+ }
496
+ const pagePath = getPageFolder(this.rootDir, name);
497
+ const pageIndexPath = path.join(pagePath, "index.tsx");
498
+ const pageContent = /*js*/ `import { SbPage, SbContainer, registerPage } from "@superblocksteam/library";
499
+ function Page() {
500
+ return <SbPage name="${name}">
501
+ <SbContainer width={Dim.fill()} />
502
+ </SbPage>;
503
+ }
504
+
505
+ export default registerPage(Page, { name: "${name}" });
506
+ `;
507
+ await fs.mkdir(pagePath, { recursive: true });
508
+ await this.writeFile(pageIndexPath, pageContent, "ts");
509
+ await this.handleNonVisualChangeByDeletingIds(pageIndexPath, pageContent);
510
+ this.emit("addPage", pageIndexPath);
511
+ };
512
+ handleReparent = async (payload, writeFile = true) => {
513
+ const { from, to, changedProps, transaction } = payload;
514
+ this.trackTransaction(transaction?.id);
515
+ await this.sourceTracker?.setProperties({
516
+ source: from.source,
517
+ changes: changedProps ?? {},
518
+ });
519
+ await this.sourceTracker?.moveElement({
520
+ from,
521
+ to,
522
+ });
523
+ if (writeFile) {
524
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
525
+ await this.writeChanges(changes ?? [], (fileName) => {
526
+ this.emit("reparent", fileName);
527
+ });
528
+ this.flushTransactions();
529
+ }
530
+ };
531
+ handleCreateComponent = async (payload, writeFile = true) => {
532
+ const sourceId = await this.sourceTracker?.addElement(payload);
533
+ if (writeFile) {
534
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
535
+ await this.writeChanges(changes ?? [], (fileName) => {
536
+ this.emit("createComponent", fileName);
537
+ });
538
+ }
539
+ return sourceId;
540
+ };
541
+ handleDeleteComponents = async (payload, writeFile = true) => {
542
+ const { elements } = payload;
543
+ for (const element of elements) {
544
+ await this.sourceTracker?.deleteElement({
545
+ source: element.source,
546
+ scopeName: element.scopeName,
547
+ });
548
+ }
549
+ if (writeFile) {
550
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
551
+ await this.writeChanges(changes ?? [], (fileName) => {
552
+ this.emit("deleteComponents", fileName);
553
+ });
554
+ }
555
+ };
556
+ handleSetProperty = async (payload, writeFile = true) => {
557
+ const { element: { source }, property, value: { value, type }, transaction, } = payload;
558
+ this.trackTransaction(transaction?.id);
559
+ await this.sourceTracker?.setProperty({
560
+ source,
561
+ property,
562
+ value: value,
563
+ type,
564
+ });
565
+ if (writeFile) {
566
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
567
+ await this.writeChanges(changes ?? []);
568
+ this.flushTransactions();
569
+ }
570
+ this.emit("setProperty", payload);
571
+ };
572
+ handleSetProperties = async (payload, writeFile = true) => {
573
+ const { element: { source }, properties, transaction, } = payload;
574
+ this.trackTransaction(transaction?.id);
575
+ await this.sourceTracker?.setProperties({
576
+ source,
577
+ changes: properties,
578
+ });
579
+ if (writeFile) {
580
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
581
+ await this.writeChanges(changes ?? []);
582
+ this.flushTransactions();
583
+ }
584
+ this.emit("setProperties", payload);
585
+ };
586
+ handleDeleteProperties = async (payload, writeFile = true) => {
587
+ await this.sourceTracker?.deleteProperties({
588
+ source: payload.element.source,
589
+ properties: payload.properties,
590
+ });
591
+ if (writeFile) {
592
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
593
+ await this.writeChanges(changes ?? []);
594
+ }
595
+ this.emit("deleteProperties", payload);
596
+ };
597
+ handleBatchUpdate = async (payload) => {
598
+ const { updates } = payload;
599
+ const returnValues = [];
600
+ for (const update of updates) {
601
+ switch (update.type) {
602
+ case "editor:setProperty":
603
+ returnValues.push(await this.handleSetProperty(update.payload, false));
604
+ break;
605
+ case "editor:setProperties":
606
+ returnValues.push(await this.handleSetProperties(update.payload, false));
607
+ break;
608
+ case "editor:moveComponent":
609
+ returnValues.push(await this.handleReparent(update.payload, false));
610
+ break;
611
+ case "editor:createComponent":
612
+ returnValues.push(await this.handleCreateComponent(update.payload, false));
613
+ break;
614
+ case "editor:deleteProperties":
615
+ returnValues.push(await this.handleDeleteProperties(update.payload, false));
616
+ break;
617
+ }
618
+ }
619
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
620
+ await this.writeChanges(changes ?? []);
621
+ this.emit("batchUpdate", payload);
622
+ return returnValues;
623
+ };
624
+ handleUpdateApi = async (payload) => {
625
+ const { api } = payload;
626
+ if (!this.sourceTracker) {
627
+ throw new Error("Source tracker not initialized");
628
+ }
629
+ if (!this.rootDir) {
630
+ throw new Error("Root directory not set");
631
+ }
632
+ if (!api.pageName) {
633
+ throw new Error("API page name is not set");
634
+ }
635
+ const apiName = api.apiPb.metadata.name;
636
+ if (!apiName) {
637
+ throw new Error("API name is not set");
638
+ }
639
+ const apiDir = path.join(this.rootDir, "pages", api.pageName, "apis", apiName);
640
+ const apiPath = path.join(apiDir, "api.yaml");
641
+ const isNewApi = !this.getApiFiles()[apiPath];
642
+ try {
643
+ const stats = await fs.stat(apiDir);
644
+ if (!stats.isDirectory()) {
645
+ await fs.mkdir(apiDir, { recursive: true });
646
+ }
647
+ }
648
+ catch {
649
+ await fs.mkdir(apiDir, { recursive: true });
650
+ }
651
+ await this.writeFile(apiPath, yaml.stringify(api.apiPb), "api");
652
+ const generationNumber = this.generationNumberSequence.next();
653
+ const apiDef = this.createClientApi(api);
654
+ let scopeId = "";
655
+ if (isNewApi) {
656
+ // We want to add the API entity to our scope, but we do not want to emit entity events, because
657
+ // the API update event handles this particular side effect.
658
+ scopeId = await this.sourceTracker.addApi({
659
+ pageName: api.pageName,
660
+ apiName: api.apiPb.metadata.name,
661
+ });
662
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
663
+ await this.writeChanges(changes);
664
+ }
665
+ else {
666
+ const scopeDef = this.sourceTracker.getScopeDefinitionForPage(api.pageName);
667
+ scopeId = scopeDef?.id ?? "";
668
+ }
669
+ this.emit("apiUpdate", { api: apiDef, scopeId });
670
+ return { api: apiDef, scopeId, generationNumber };
671
+ };
672
+ handleDeleteApi = async (payload) => {
673
+ const logger = getLogger();
674
+ const { apis } = payload;
675
+ if (!this.rootDir) {
676
+ throw new Error("Root directory not set");
677
+ }
678
+ const rootDir = this.rootDir;
679
+ const executeDeleteApis = Promise.all(apis.map(({ apiName, pageName }) => {
680
+ return new Promise(
681
+ // eslint-disable-next-line no-async-promise-executor
682
+ async (resolve) => {
683
+ const apiFilePath = path.join(rootDir, "pages", pageName, "apis", apiName, "api.yaml");
684
+ const api = this.apiFiles[apiFilePath];
685
+ if (!api || !this.sourceTracker) {
686
+ return resolve(undefined);
687
+ }
688
+ const apiDir = path.join(rootDir, "pages", pageName, "apis", apiName);
689
+ try {
690
+ const stats = await fs.stat(apiDir);
691
+ if (stats.isDirectory()) {
692
+ await fs.rmdir(apiDir, { recursive: true });
693
+ }
694
+ delete this.apiFiles[apiFilePath];
695
+ const scopeId = await this.sourceTracker.deleteApi({
696
+ pageName,
697
+ apiName,
698
+ });
699
+ resolve({
700
+ apiName,
701
+ pageName,
702
+ scopeId,
703
+ });
704
+ }
705
+ catch (e) {
706
+ logger.warn(`Could not delete api ${apiFilePath} ${JSON.stringify(e)}`);
707
+ resolve(undefined);
708
+ }
709
+ resolve(undefined);
710
+ });
711
+ }));
712
+ const deletedApis = (await executeDeleteApis).filter((api) => api !== undefined);
713
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
714
+ await this.writeChanges(changes);
715
+ this.emit("apiDelete", {
716
+ apis: deletedApis.filter((api) => api !== undefined),
717
+ });
718
+ return { deletedApis };
719
+ };
720
+ handleRenameApi = async (payload) => {
721
+ const { oldName, newName, pageName } = payload;
722
+ if (!this.rootDir) {
723
+ throw new Error("Root directory not set");
724
+ }
725
+ const pagePath = getPageFolder(this.rootDir, pageName);
726
+ const existingApiFolder = path.join(this.rootDir, "pages", pageName, "apis", oldName);
727
+ const newApiFolder = path.join(this.rootDir, "pages", pageName, "apis", newName);
728
+ const files = this.sourceTracker?.getCurrentFiles();
729
+ const file = files?.[path.join(pagePath, "index.tsx")];
730
+ if (!file || !file.ast) {
731
+ throw new Error(`Page ${pageName} not found`);
732
+ }
733
+ const apiFilePath = path.join(existingApiFolder, "api.yaml");
734
+ const apiDef = this.apiFiles[apiFilePath];
735
+ if (!apiDef) {
736
+ throw new Error(`API ${oldName} not found`);
737
+ }
738
+ const newApiFolderExists = await fs.stat(newApiFolder).catch(() => false);
739
+ if (newApiFolderExists) {
740
+ throw new Error(`API ${newName} already exists`);
741
+ }
742
+ apiDef.apiPb.metadata.name = newName;
743
+ await fs.rename(existingApiFolder, newApiFolder);
744
+ this.sourceTracker?.renameIdentifier({
745
+ oldName,
746
+ newName,
747
+ filePath: path.join(pagePath, "index.tsx"),
748
+ });
749
+ delete this.apiFiles[apiFilePath];
750
+ this.writeFile(path.join(newApiFolder, "api.yaml"), yaml.stringify(apiDef.apiPb), "api");
751
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
752
+ await this.writeChanges(changes);
753
+ const scopeDef = this.sourceTracker?.getScopeDefinitionForPage(pageName);
754
+ this.emit("apiManualUpdate", {
755
+ api: this.createClientApi(apiDef),
756
+ oldName,
757
+ pageName,
758
+ scopeId: scopeDef?.id ?? "",
759
+ }, true);
760
+ const otherPageAPIs = structuredClone(Object.keys(this.apiFiles)
761
+ .filter((path) => path.startsWith(pagePath) && path !== apiFilePath)
762
+ .map((path) => ({
763
+ api: { apiPb: this.apiFiles[path]?.apiPb },
764
+ filePath: path,
765
+ }))
766
+ .filter((api) => !!api.api));
767
+ await this.renameManager.renameEntityInApis({
768
+ oldName,
769
+ newName,
770
+ apis: otherPageAPIs,
771
+ });
772
+ // only save the APIs that have changed
773
+ await Promise.all(otherPageAPIs.map(async ({ api, filePath }) => {
774
+ if (isEqual(api?.apiPb, this.apiFiles[filePath]?.apiPb)) {
775
+ return Promise.resolve();
776
+ }
777
+ await this.writeFile(filePath, yaml.stringify(api?.apiPb), "api");
778
+ this.emit("apiManualUpdate", {
779
+ api: this.createClientApi(api),
780
+ pageName,
781
+ scopeId: scopeDef?.id ?? "",
782
+ }, true);
783
+ // TODO: Should I delete here?
784
+ }));
785
+ };
786
+ handleAddEntity = async (payload) => {
787
+ await this.sourceTracker?.addEntity({
788
+ scopeId: payload.scopeId,
789
+ entity: {
790
+ type: payload.type,
791
+ name: payload.name,
792
+ attributes: payload.attributes,
793
+ },
794
+ });
795
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
796
+ await this.writeChanges(changes, (fileName) => {
797
+ this.emit("addEntity", fileName, payload);
798
+ });
799
+ };
800
+ handleUpdateEntity = async (payload) => {
801
+ await this.sourceTracker?.updateEntity({
802
+ entityId: payload.entityId,
803
+ updates: payload.updates,
804
+ });
805
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
806
+ await this.writeChanges(changes, (fileName) => {
807
+ this.emit("updateEntity", fileName, payload);
808
+ });
809
+ };
810
+ handleDeleteEntity = async (payload) => {
811
+ await this.sourceTracker?.deleteEntity({
812
+ entityId: payload.entityId,
813
+ });
814
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
815
+ await this.writeChanges(changes, (fileName) => {
816
+ this.emit("deleteEntity", fileName, payload);
817
+ });
818
+ };
819
+ handleUpdateTheme = async (payload) => {
820
+ const { theme } = payload;
821
+ if (!this.rootDir) {
822
+ throw new Error("Root directory not set");
823
+ }
824
+ const filePath = path.join(this.rootDir, APP_THEME_FILE_NAME);
825
+ await this.sourceTracker?.updateTheme({
826
+ themeFilePath: filePath,
827
+ theme,
828
+ });
829
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
830
+ await this.writeChanges(changes);
831
+ };
832
+ handleRenameElement = async (payload) => {
833
+ if (payload.kind === "component") {
834
+ return this.handleRenameComponent(payload);
835
+ }
836
+ else if (payload.kind === "entity") {
837
+ return this.handleRenameEntity(payload);
838
+ }
839
+ else if (payload.kind === "page") {
840
+ return this.handleRenamePage(payload);
841
+ }
842
+ };
843
+ handleRenameComponent = async (payload) => {
844
+ const { elementId, newName, oldName, scopeName } = payload;
845
+ await this.sourceTracker?.renameComponent({
846
+ widgetSourceId: elementId,
847
+ oldName,
848
+ newName,
849
+ scopeName,
850
+ });
851
+ await this.renameIdentifierInApis({
852
+ elementId,
853
+ oldName,
854
+ newName,
855
+ });
856
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
857
+ await this.writeChanges(changes, (fileName) => {
858
+ this.emit("renameComponent", fileName);
859
+ });
860
+ };
861
+ handleRenameEntity = async (payload) => {
862
+ const { elementId, newName, oldName, scopeName } = payload;
863
+ await this.sourceTracker?.renameEntity({
864
+ entityId: elementId,
865
+ oldName,
866
+ newName,
867
+ scopeName,
868
+ });
869
+ await this.renameIdentifierInApis(payload);
870
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
871
+ await this.writeChanges(changes, (fileName) => {
872
+ this.emit("renameEntity", fileName);
873
+ });
874
+ };
875
+ handleRenamePage = async (payload) => {
876
+ const { newName, oldName } = payload;
877
+ if (!this.rootDir) {
878
+ throw new Error("Root directory not set");
879
+ }
880
+ const newPageFolder = getPageFolder(this.rootDir, newName);
881
+ const newIndexFilePath = path.join(newPageFolder, "index.tsx");
882
+ const oldIndexFilePath = path.join(this.rootDir, "pages", oldName, "index.tsx");
883
+ const oldPageFolder = getPageFolder(this.rootDir, oldName);
884
+ this.watcher?.unwatch(newPageFolder);
885
+ this.watcher?.unwatch(oldPageFolder);
886
+ const existingRoute = Object.keys(this.routes).find((route) => this.routes[route]?.file ===
887
+ this.getRelativeRoutePath(oldIndexFilePath));
888
+ if (!existingRoute) {
889
+ throw new Error(`Route for ${oldName} not found`);
890
+ }
891
+ // Write the name attribute to the page file
892
+ await this.sourceTracker?.renamePage({
893
+ newName,
894
+ filePath: oldIndexFilePath,
895
+ });
896
+ const changes = (await this.sourceTracker?.getAndFlushChanges()) ?? [];
897
+ await this.writeChanges(changes);
898
+ // A rename of a folder is an unlink followed by an add, so the file watcher will take over initializing this
899
+ // "new" page
900
+ await fs.rename(oldPageFolder, newPageFolder);
901
+ // Now we just clean up the routes
902
+ await this.removeRoute(oldIndexFilePath);
903
+ await this.addRoute(existingRoute, newIndexFilePath);
904
+ const newIndexFile = await readFile(newIndexFilePath);
905
+ if (!newIndexFile) {
906
+ throw new Error(`New index file ${newIndexFilePath} not found`);
907
+ }
908
+ this.tsFiles[newIndexFilePath] = newIndexFile;
909
+ await this.handleNonVisualChangeByDeletingIds(newIndexFilePath, newIndexFile);
910
+ this.emit("renamePage", newIndexFilePath);
911
+ // Re-add the watcher
912
+ this.watcher?.add(newPageFolder);
913
+ this.watcher?.add(oldPageFolder);
914
+ };
915
+ getPageRoots(filePath) {
916
+ const scopeFilePath = path.join(path.dirname(filePath), "index.tsx");
917
+ const currentFile = this.sourceTracker?.getCurrentFiles()[scopeFilePath];
918
+ if (!currentFile) {
919
+ return null;
920
+ }
921
+ return getPageRoots(filePath, currentFile);
922
+ }
923
+ getScope(filePath) {
924
+ // get the scope.ts file in the same directory as path
925
+ const scopeFilePath = path.join(path.dirname(filePath), SCOPE_FILE);
926
+ const currentFile = this.sourceTracker?.getCurrentFiles()[scopeFilePath];
927
+ if (!currentFile) {
928
+ console.log("File not found", scopeFilePath);
929
+ return null;
930
+ }
931
+ const scope = getScope(scopeFilePath, currentFile);
932
+ return scope;
933
+ }
934
+ getRoutes() {
935
+ const routes = [];
936
+ for (const [path, { file }] of Object.entries(this.routes)) {
937
+ routes.push({
938
+ path,
939
+ component: file,
940
+ });
941
+ }
942
+ return routes;
943
+ }
944
+ async addRoute(route, filePath) {
945
+ if (!this.rootDir) {
946
+ throw new Error("Root directory not set");
947
+ }
948
+ this.routes[route] = { file: this.getRelativeRoutePath(filePath) };
949
+ await this.writeFile(path.join(this.rootDir, ROUTES_FILE), JSON.stringify(this.routes, null, 2));
950
+ }
951
+ async removeRoute(filePath) {
952
+ if (!this.rootDir) {
953
+ throw new Error("Root directory not set");
954
+ }
955
+ const relativeFilePath = this.getRelativeRoutePath(filePath);
956
+ this.routes = Object.fromEntries(Object.entries(this.routes).filter(([_, value]) => value.file !== relativeFilePath));
957
+ await this.writeFile(path.join(this.rootDir, ROUTES_FILE), JSON.stringify(this.routes, null, 2));
958
+ }
959
+ async writeChanges(changes, callback) {
960
+ return Promise.all(changes.map(async ({ fileName, source, kind }) => {
961
+ await this.writeFile(fileName, source, kind);
962
+ return callback?.(fileName, source);
963
+ }));
964
+ }
965
+ getNodeForWidgetSourceId(id) {
966
+ return this.sourceTracker?.getElementToLocation(id);
967
+ }
968
+ getAstForWidgetSourceId(id) {
969
+ const filePath = this.sourceTracker?.getElementToFilePath(id);
970
+ if (!filePath) {
971
+ return null;
972
+ }
973
+ return this.sourceTracker?.getCurrentFiles()[filePath]?.ast;
974
+ }
975
+ renameIdentifierInApis = async ({ elementId, oldName, newName, parentBinding, }) => {
976
+ const apisInScope = structuredClone(this.getApisInScope(elementId));
977
+ await this.renameManager.renameEntityInApis({
978
+ oldName,
979
+ newName,
980
+ parentBinding,
981
+ apis: apisInScope,
982
+ });
983
+ // only save the APIs that have changed
984
+ await Promise.all(apisInScope.map(({ api, filePath }) => {
985
+ if (isEqual(api?.apiPb, this.apiFiles[filePath]?.apiPb)) {
986
+ return Promise.resolve();
987
+ }
988
+ return this.writeFile(filePath, yaml.stringify(api?.apiPb), "api");
989
+ }));
990
+ };
991
+ getApisInScope = (elementId) => {
992
+ const filePath = this.sourceTracker?.getElementToFilePath(elementId);
993
+ if (!filePath) {
994
+ return [];
995
+ }
996
+ const pagePath = path.dirname(filePath);
997
+ return Object.entries(this.apiFiles)
998
+ .filter(([filePath]) => filePath.includes(pagePath))
999
+ .map(([filePath, api]) => ({ api, filePath }));
1000
+ };
1001
+ getRelativeRoutePath(filePath) {
1002
+ if (!this.rootDir) {
1003
+ throw new Error("Root directory not set");
1004
+ }
1005
+ // no leading slash
1006
+ return path.relative(path.join(this.rootDir, PAGES_DIRECTORY), filePath);
1007
+ }
1008
+ // Utilities for converting server API format to Client API format
1009
+ // We internally save the API as the server does, but we return should always return it
1010
+ // to the client with an id generated as PageName_ApiName
1011
+ createClientApi(api) {
1012
+ return {
1013
+ pageName: api.pageName,
1014
+ apiPb: {
1015
+ ...api.apiPb,
1016
+ metadata: {
1017
+ ...api.apiPb.metadata,
1018
+ id: getClientApiId(api.apiPb.metadata.name, api.pageName),
1019
+ },
1020
+ },
1021
+ };
1022
+ }
1023
+ formatApisToClientApis(serverApis) {
1024
+ return Object.keys(serverApis).reduce((acc, key) => {
1025
+ if (!serverApis[key]) {
1026
+ return acc;
1027
+ }
1028
+ acc[key] = {
1029
+ api: this.createClientApi(serverApis[key]),
1030
+ scopeId: serverApis[key].scopeId,
1031
+ };
1032
+ return acc;
1033
+ }, {});
1034
+ }
1035
+ }
1036
+ // Add new mock implementation
1037
+ export class MockFileSyncManager extends FileSyncManager {
1038
+ tsFiles = {};
1039
+ apiFiles = {};
1040
+ async watch(_watcher, _path) {
1041
+ // Mock implementation doesn't actually watch files
1042
+ }
1043
+ async writeFile(path, content, kind) {
1044
+ await this.fsOperationQueue.enqueue(async () => {
1045
+ if (kind === "ts") {
1046
+ this.tsFiles[path] = content;
1047
+ }
1048
+ else {
1049
+ this.apiFiles[path] = {
1050
+ apiPb: yaml.parse(content),
1051
+ pageName: getPageName(path),
1052
+ stepPathMap: {},
1053
+ // TODO: generate a scope ID for tests
1054
+ scopeId: "",
1055
+ };
1056
+ }
1057
+ // Notify subscribers
1058
+ this.emit("fileChanged", path, content, true);
1059
+ });
1060
+ }
1061
+ // Helper methods for testing
1062
+ mockFileChange(path, content) {
1063
+ this.tsFiles[path] = content;
1064
+ this.emit("fileChanged", path, content, true);
1065
+ }
1066
+ handleUpdateApi = async (payload) => {
1067
+ const apiName = payload.api.apiPb.metadata.name;
1068
+ this.apiFiles[apiName] = {
1069
+ ...payload.api,
1070
+ stepPathMap: {},
1071
+ scopeId: payload.scopeId,
1072
+ };
1073
+ const scopeDef = this.sourceTracker?.getScopeDefinitionForPage(payload.api.pageName);
1074
+ const generationNumber = this.generationNumberSequence.next();
1075
+ this.emit("apiUpdate", {
1076
+ api: payload.api,
1077
+ scopeId: scopeDef?.id ?? "",
1078
+ });
1079
+ return {
1080
+ api: payload.api,
1081
+ generationNumber,
1082
+ scopeId: scopeDef?.id ?? "",
1083
+ };
1084
+ };
1085
+ getSourceTracker() {
1086
+ return this.sourceTracker;
1087
+ }
1088
+ }
1089
+ async function readFile(path) {
1090
+ try {
1091
+ // in order for try-catch to work, we need to intentionally await the readFile call,
1092
+ // otherwise the error won't be be caught
1093
+ // see: https://github.com/nodejs/node/issues/51894#issuecomment-1974017737
1094
+ const content = await fs.readFile(path, "utf-8");
1095
+ return content;
1096
+ }
1097
+ catch (e) {
1098
+ getLogger().error(`error reading file: ${path}`, getErrorMeta(e));
1099
+ return null;
1100
+ }
1101
+ }
1102
+ async function readFiles(dir) {
1103
+ return await glob(path.join(dir, "**/*.{tsx,yaml,ts}"), {
1104
+ ignore: [
1105
+ "node_modules/**",
1106
+ "dist/**",
1107
+ "build/**",
1108
+ ".superblocks/**",
1109
+ `./${getLegacyComponentsFolder()}/**`,
1110
+ ],
1111
+ });
1112
+ }
1113
+ const getMergedApiContent = async (path) => {
1114
+ return readAppApiYamlFile(path.split("/").slice(0, -1).join("/"));
1115
+ };
1116
+ const getPageName = (path) => {
1117
+ const parts = path.split("/");
1118
+ const pagesIndex = parts.findIndex((part) => part === "pages");
1119
+ if (pagesIndex !== -1 && parts[pagesIndex + 1]) {
1120
+ return parts[pagesIndex + 1] ?? "";
1121
+ }
1122
+ return "";
1123
+ };
1124
+ async function processApiUpdates(filePath, fileType, logger, apiFiles, updateApi, emit, createClientApi) {
1125
+ {
1126
+ let yamlPath = filePath;
1127
+ if (fileType.type === "python-api-step" ||
1128
+ fileType.type === "js-api-step") {
1129
+ const apiFolderPath = filePath.split("/").slice(0, -1).join("/");
1130
+ yamlPath = path.join(apiFolderPath, "api.yaml");
1131
+ }
1132
+ try {
1133
+ const apiContent = await getMergedApiContent(yamlPath);
1134
+ if (!apiContent) {
1135
+ return;
1136
+ }
1137
+ const parsedData = { apiPb: apiContent?.api };
1138
+ if (!(yamlPath in apiFiles &&
1139
+ isEqual(apiFiles[yamlPath]?.apiPb, parsedData.apiPb))) {
1140
+ logger.info(`API changed: ${yamlPath}`);
1141
+ const { updatedApi, pageName } = updateApi({
1142
+ api: parsedData.apiPb,
1143
+ stepPathMap: apiContent.stepPathMap,
1144
+ }, yamlPath);
1145
+ emit("apiManualUpdate", {
1146
+ api: createClientApi(updatedApi),
1147
+ pageName,
1148
+ });
1149
+ }
1150
+ else {
1151
+ logger.info(`File unchanged from last tracked state: ${filePath}`);
1152
+ }
1153
+ }
1154
+ catch {
1155
+ logger.info(`API file incomplete: ${yamlPath}`);
1156
+ }
1157
+ }
1158
+ }
1159
+ //# sourceMappingURL=file-system-manager.js.map