@codeyam/codeyam-cli 0.1.0-staging.09652b8 → 0.1.0-staging.28f73cf

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 (287) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +7 -6
  4. package/analyzer-template/packages/ai/index.ts +2 -0
  5. package/analyzer-template/packages/ai/package.json +2 -2
  6. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +24 -0
  7. package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +14 -0
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1402 -546
  9. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.ts +138 -0
  10. package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +1 -1
  11. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +139 -0
  12. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/DebugTracer.ts +224 -0
  13. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/PathManager.ts +203 -0
  14. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/README.md +294 -0
  15. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +161 -0
  16. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.ts +235 -0
  17. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +2 -0
  18. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/selectBestValue.ts +70 -0
  19. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.ts +113 -0
  20. package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +36 -0
  21. package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +32 -8
  22. package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +27 -6
  23. package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +42 -4
  24. package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +39 -0
  25. package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +18 -6
  26. package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +2 -1
  27. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +8 -10
  28. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +6 -1
  29. package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +8 -6
  30. package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +5 -13
  31. package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +34 -15
  32. package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +17 -3
  33. package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +35 -16
  34. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +7 -1
  35. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +9 -1
  36. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +6 -1
  37. package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +9 -1
  38. package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts +23 -0
  39. package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts.map +1 -0
  40. package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js +30 -0
  41. package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js.map +1 -0
  42. package/analyzer-template/packages/aws/package.json +5 -4
  43. package/analyzer-template/packages/aws/s3/index.ts +4 -0
  44. package/analyzer-template/packages/aws/src/lib/s3/getPresignedUrl.ts +62 -0
  45. package/analyzer-template/packages/generate/src/lib/scenarioComponent.ts +6 -3
  46. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.d.ts.map +1 -1
  47. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js +5 -3
  48. package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js.map +1 -1
  49. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts +2 -0
  50. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts.map +1 -1
  51. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js +3 -0
  52. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js.map +1 -1
  53. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts +2 -0
  54. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts.map +1 -1
  55. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts +37 -0
  56. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -0
  57. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
  58. package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
  59. package/analyzer-template/packages/github/dist/utils/index.d.ts +1 -0
  60. package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
  61. package/analyzer-template/packages/github/dist/utils/index.js +1 -0
  62. package/analyzer-template/packages/github/dist/utils/index.js.map +1 -1
  63. package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts +25 -0
  64. package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
  65. package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js +40 -0
  66. package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js.map +1 -0
  67. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
  68. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
  69. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
  70. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
  71. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
  72. package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
  73. package/analyzer-template/packages/supabase/src/lib/kysely/db.ts +6 -0
  74. package/analyzer-template/packages/supabase/src/lib/kysely/tableRelations.ts +3 -0
  75. package/analyzer-template/packages/supabase/src/lib/kysely/tables/debugReportsTable.ts +61 -0
  76. package/analyzer-template/packages/utils/dist/utils/index.d.ts +1 -0
  77. package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
  78. package/analyzer-template/packages/utils/dist/utils/index.js +1 -0
  79. package/analyzer-template/packages/utils/dist/utils/index.js.map +1 -1
  80. package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts +25 -0
  81. package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
  82. package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js +40 -0
  83. package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js.map +1 -0
  84. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
  85. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
  86. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
  87. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
  88. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
  89. package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
  90. package/analyzer-template/packages/utils/index.ts +1 -0
  91. package/analyzer-template/packages/utils/src/lib/Semaphore.ts +42 -0
  92. package/analyzer-template/packages/utils/src/lib/frameworks/getRemixRoutePath.ts +2 -1
  93. package/analyzer-template/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.ts +1 -0
  94. package/analyzer-template/project/constructMockCode.ts +170 -6
  95. package/analyzer-template/project/reconcileMockDataKeys.ts +13 -0
  96. package/analyzer-template/project/start.ts +1 -11
  97. package/analyzer-template/project/writeMockDataTsx.ts +32 -1
  98. package/analyzer-template/project/writeScenarioComponents.ts +164 -18
  99. package/analyzer-template/project/writeUniversalMocks.ts +66 -8
  100. package/background/src/lib/virtualized/project/constructMockCode.js +158 -7
  101. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  102. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +12 -0
  103. package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
  104. package/background/src/lib/virtualized/project/start.js +1 -8
  105. package/background/src/lib/virtualized/project/start.js.map +1 -1
  106. package/background/src/lib/virtualized/project/writeMockDataTsx.js +25 -1
  107. package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
  108. package/background/src/lib/virtualized/project/writeScenarioComponents.js +129 -17
  109. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  110. package/background/src/lib/virtualized/project/writeUniversalMocks.js +56 -7
  111. package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
  112. package/codeyam-cli/src/cli.js +6 -0
  113. package/codeyam-cli/src/cli.js.map +1 -1
  114. package/codeyam-cli/src/codeyam-cli.js +0 -0
  115. package/codeyam-cli/src/commands/debug.js +221 -0
  116. package/codeyam-cli/src/commands/debug.js.map +1 -0
  117. package/codeyam-cli/src/commands/report.js +102 -0
  118. package/codeyam-cli/src/commands/report.js.map +1 -0
  119. package/codeyam-cli/src/commands/setup-sandbox.js +164 -0
  120. package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -0
  121. package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js +6 -6
  122. package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js.map +1 -1
  123. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +8 -0
  124. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
  125. package/codeyam-cli/src/utils/analyzer.js +30 -0
  126. package/codeyam-cli/src/utils/analyzer.js.map +1 -1
  127. package/codeyam-cli/src/utils/cleanupAnalysisFiles.js +2 -2
  128. package/codeyam-cli/src/utils/cleanupAnalysisFiles.js.map +1 -1
  129. package/codeyam-cli/src/utils/generateReport.js +219 -0
  130. package/codeyam-cli/src/utils/generateReport.js.map +1 -0
  131. package/codeyam-cli/src/utils/install-skills.js +7 -0
  132. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  133. package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js +1 -0
  134. package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js.map +1 -1
  135. package/codeyam-cli/src/utils/queue/job.js +5 -1
  136. package/codeyam-cli/src/utils/queue/job.js.map +1 -1
  137. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +4 -0
  138. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  139. package/codeyam-cli/src/webserver/app/lib/database.js +50 -2
  140. package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
  141. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-D5ZHFomX.js +1 -0
  142. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CDnfNKKQ.js → InteractivePreview-XDSzQLOY.js} +2 -2
  143. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-DUS-3h7I.js → LibraryFunctionPreview-BYVx9KFp.js} +1 -1
  144. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-TJzDQku1.js → LogViewer-CRcT5fOZ.js} +1 -1
  145. package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-BORLgi0X.js +1 -0
  146. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-BgdlWM6p.js → SafeScreenshot-Bual6h18.js} +1 -1
  147. package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bi-YUMa-.js +6 -0
  148. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-4D2vLLJz.js +5 -0
  149. package/codeyam-cli/src/webserver/build/client/assets/_index-BC200mfN.js +1 -0
  150. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CxvZPkCv.js +10 -0
  151. package/codeyam-cli/src/webserver/build/client/assets/api.generate-report-l0sNRNKZ.js +1 -0
  152. package/codeyam-cli/src/webserver/build/client/assets/chart-column-B8fb6wnw.js +1 -0
  153. package/codeyam-cli/src/webserver/build/client/assets/{chunk-WWGJGFF6-DvL0YqDJ.js → chunk-WWGJGFF6-De6i8FUT.js} +1 -1
  154. package/codeyam-cli/src/webserver/build/client/assets/circle-alert-IdsgAK39.js +1 -0
  155. package/codeyam-cli/src/webserver/build/client/assets/circle-check-BACUUf75.js +1 -0
  156. package/codeyam-cli/src/webserver/build/client/assets/clock-vWeoCemX.js +1 -0
  157. package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CS7XDrKv.js +1 -0
  158. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DIOEw_3i.js +1 -0
  159. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-3bYjyojg.js → entity._sha._-8Els_3Wb.js} +10 -10
  160. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DtfwpN9J.js → entity._sha_.create-scenario-C3FZJx1w.js} +1 -1
  161. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-YJz_igar.js +5 -0
  162. package/codeyam-cli/src/webserver/build/client/assets/entityStatus-BEqj2qBy.js +1 -0
  163. package/codeyam-cli/src/webserver/build/client/assets/entry.client-DiP0q291.js +5 -0
  164. package/codeyam-cli/src/webserver/build/client/assets/file-text-LM0mgxXE.js +1 -0
  165. package/codeyam-cli/src/webserver/build/client/assets/files-Dxh9CcaV.js +1 -0
  166. package/codeyam-cli/src/webserver/build/client/assets/{git-WoKohOtW.js → git-BXmqrWCH.js} +10 -10
  167. package/codeyam-cli/src/webserver/build/client/assets/globals-BGS74ED-.css +1 -0
  168. package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +5 -0
  169. package/codeyam-cli/src/webserver/build/client/assets/{index-Vvbl94Xc.js → index-D-zYbzFZ.js} +2 -2
  170. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-BXPKbHEb.js +1 -0
  171. package/codeyam-cli/src/webserver/build/client/assets/manifest-1af162d4.js +1 -0
  172. package/codeyam-cli/src/webserver/build/client/assets/root-DB7VgjCY.js +16 -0
  173. package/codeyam-cli/src/webserver/build/client/assets/settings-5zF_GOcS.js +1 -0
  174. package/codeyam-cli/src/webserver/build/client/assets/{settings-LuiJ1UIm.js → settings-Dc4MlMpK.js} +1 -1
  175. package/codeyam-cli/src/webserver/build/client/assets/simulations-BQ-02-jB.js +1 -0
  176. package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-D7k-ArFa.js +1 -0
  177. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-CpUcCv1V.js → useLastLogLine-AlhS7g5F.js} +1 -1
  178. package/codeyam-cli/src/webserver/build/client/assets/useToast-Ddo4UQv7.js +1 -0
  179. package/codeyam-cli/src/webserver/build/client/assets/zap-_jw-9DCp.js +1 -0
  180. package/codeyam-cli/src/webserver/build/server/assets/{index-DzbqTxoN.js → index-D4JpXSIO.js} +1 -1
  181. package/codeyam-cli/src/webserver/build/server/assets/server-build-vwbN7n65.js +169 -0
  182. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  183. package/codeyam-cli/src/webserver/build-info.json +5 -5
  184. package/codeyam-cli/templates/codeyam-setup-skill.md +65 -85
  185. package/codeyam-cli/templates/debug-command.md +125 -0
  186. package/package.json +4 -6
  187. package/packages/ai/index.js +1 -1
  188. package/packages/ai/index.js.map +1 -1
  189. package/packages/ai/src/lib/analyzeScope.js +13 -0
  190. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  191. package/packages/ai/src/lib/astScopes/processExpression.js +12 -0
  192. package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
  193. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1023 -405
  194. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  195. package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js +137 -1
  196. package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js.map +1 -1
  197. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +1 -1
  198. package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
  199. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +112 -0
  200. package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -0
  201. package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js +176 -0
  202. package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js.map +1 -0
  203. package/packages/ai/src/lib/dataStructure/helpers/PathManager.js +178 -0
  204. package/packages/ai/src/lib/dataStructure/helpers/PathManager.js.map +1 -0
  205. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +138 -0
  206. package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -0
  207. package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js +199 -0
  208. package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js.map +1 -0
  209. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +2 -0
  210. package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
  211. package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js +62 -0
  212. package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js.map +1 -0
  213. package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js +90 -0
  214. package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js.map +1 -0
  215. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +22 -0
  216. package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
  217. package/packages/ai/src/lib/generateEntityKeyAttributes.js +32 -8
  218. package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
  219. package/packages/ai/src/lib/getConditionalUsagesFromCode.js +13 -8
  220. package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
  221. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +36 -3
  222. package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
  223. package/packages/ai/src/lib/worker/SerializableDataStructure.js +7 -0
  224. package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
  225. package/packages/analyze/src/lib/FileAnalyzer.js +17 -5
  226. package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
  227. package/packages/analyze/src/lib/asts/nodes/index.js +2 -1
  228. package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
  229. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +6 -8
  230. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  231. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +5 -1
  232. package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
  233. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +8 -2
  234. package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
  235. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +5 -8
  236. package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
  237. package/packages/analyze/src/lib/files/analyzeChange.js +21 -9
  238. package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
  239. package/packages/analyze/src/lib/files/analyzeEntity.js +10 -4
  240. package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
  241. package/packages/analyze/src/lib/files/analyzeInitial.js +21 -9
  242. package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
  243. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +6 -1
  244. package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
  245. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +9 -1
  246. package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
  247. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +5 -1
  248. package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
  249. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +9 -1
  250. package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
  251. package/packages/generate/src/lib/scenarioComponent.js +5 -3
  252. package/packages/generate/src/lib/scenarioComponent.js.map +1 -1
  253. package/packages/supabase/src/lib/kysely/db.js +3 -0
  254. package/packages/supabase/src/lib/kysely/db.js.map +1 -1
  255. package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
  256. package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
  257. package/packages/utils/index.js +1 -0
  258. package/packages/utils/index.js.map +1 -1
  259. package/packages/utils/src/lib/Semaphore.js +40 -0
  260. package/packages/utils/src/lib/Semaphore.js.map +1 -0
  261. package/packages/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
  262. package/packages/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
  263. package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
  264. package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
  265. package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-B9Sf8e9w.js +0 -1
  266. package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bl6GY-OE.js +0 -6
  267. package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-BDq8RX50.js +0 -5
  268. package/codeyam-cli/src/webserver/build/client/assets/_index-Bh3y3Wsl.js +0 -1
  269. package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-tq7Bl6-t.js +0 -10
  270. package/codeyam-cli/src/webserver/build/client/assets/chart-column-q9_nHfwv.js +0 -1
  271. package/codeyam-cli/src/webserver/build/client/assets/circle-alert-CKMpA1v_.js +0 -1
  272. package/codeyam-cli/src/webserver/build/client/assets/clock-Wnfog8Qw.js +0 -1
  273. package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C_ixaqqh.js +0 -1
  274. package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-QecTs_sq.js +0 -5
  275. package/codeyam-cli/src/webserver/build/client/assets/entry.client-hnkEgHrC.js +0 -5
  276. package/codeyam-cli/src/webserver/build/client/assets/file-text-CvCVdKLW.js +0 -1
  277. package/codeyam-cli/src/webserver/build/client/assets/files-DgUCYhbd.js +0 -1
  278. package/codeyam-cli/src/webserver/build/client/assets/globals-DZfbt0u5.css +0 -1
  279. package/codeyam-cli/src/webserver/build/client/assets/loader-circle-Bxm63UxG.js +0 -1
  280. package/codeyam-cli/src/webserver/build/client/assets/manifest-c90b8608.js +0 -1
  281. package/codeyam-cli/src/webserver/build/client/assets/root-DrVZQamX.js +0 -16
  282. package/codeyam-cli/src/webserver/build/client/assets/search-CJkk16Ct.js +0 -1
  283. package/codeyam-cli/src/webserver/build/client/assets/settings-ConzHeiL.js +0 -1
  284. package/codeyam-cli/src/webserver/build/client/assets/simulations-B9LRwAej.js +0 -1
  285. package/codeyam-cli/src/webserver/build/client/assets/useToast-DOxmMaSg.js +0 -1
  286. package/codeyam-cli/src/webserver/build/client/assets/zap-D5R1FAcH.js +0 -1
  287. package/codeyam-cli/src/webserver/build/server/assets/server-build-DGGis3OZ.js +0 -166
@@ -43,6 +43,12 @@ interface WriteScenarioComponentsArgs {
43
43
  })[];
44
44
  writtenScenarioComponents?: { [key: string]: string[] };
45
45
  fileStore?: LazyFileStore;
46
+ /**
47
+ * When a default export needs to be accessible as a named export (e.g., when
48
+ * the parent imports it as `{ Name }` via an index re-export), pass the name here.
49
+ * A re-export statement `export { default as Name };` will be added to the output.
50
+ */
51
+ exportAsNamed?: string;
46
52
  }
47
53
 
48
54
  type EnhancedImportedExport = Omit<
@@ -417,6 +423,7 @@ export default async function writeScenarioComponents({
417
423
  namespaceMocks,
418
424
  writtenScenarioComponents = {},
419
425
  fileStore,
426
+ exportAsNamed,
420
427
  }: WriteScenarioComponentsArgs): Promise<{
421
428
  scenarioComponentPaths: string[];
422
429
  writtenScenarioComponents: { [key: string]: string[] };
@@ -651,10 +658,12 @@ export default async function writeScenarioComponents({
651
658
  (importedExportEntity as Entity).localFilePath = importedExport.filePath;
652
659
 
653
660
  if (!importedExport.isMocked) {
661
+ // Use resolvedFilePath (actual entity location) for scenario component writing.
662
+ // This is critical for re-exports: when importing from index.tsx which re-exports
663
+ // from a nested file, we need to write scenario components for the actual file
664
+ // where the entity code lives, not the re-export file.
654
665
  const importedExportFilePath =
655
- importedExportEntity.localFilePath === file.path
656
- ? (importedExport.resolvedFilePath ?? importedExport.filePath)
657
- : importedExport.filePath;
666
+ importedExport.resolvedFilePath ?? importedExport.filePath;
658
667
 
659
668
  if (importedExportFilePath !== file.path) {
660
669
  if (
@@ -676,17 +685,41 @@ export default async function writeScenarioComponents({
676
685
  ? fileStore.getByPath(importedExportFilePath)
677
686
  : project.files.find((f) => f.path === importedExportFilePath);
678
687
 
688
+ // Fallback: if file at resolvedFilePath doesn't exist, try filePath
689
+ // This handles cases where the actual entity file isn't in project.files
690
+ // (e.g., type re-exports where only the index file is tracked)
691
+ if (
692
+ !fileNotMocked &&
693
+ importedExport.resolvedFilePath &&
694
+ importedExport.filePath !== importedExport.resolvedFilePath
695
+ ) {
696
+ const fallbackPath = importedExport.filePath;
697
+ fileNotMocked = fileStore
698
+ ? fileStore.getByPath(fallbackPath)
699
+ : project.files.find((f) => f.path === fallbackPath);
700
+ }
701
+
702
+ // Skip if file still not found - can't write scenario component without the file
703
+ if (!fileNotMocked) {
704
+ continue;
705
+ }
706
+
679
707
  // Ensure content is loaded for the file
680
708
  if (
681
709
  fileNotMocked &&
682
710
  fileStore &&
683
- !fileStore.isContentLoaded(importedExportFilePath)
711
+ !fileStore.isContentLoaded(fileNotMocked.path)
684
712
  ) {
685
- fileNotMocked = await fileStore.ensureContent(
686
- importedExportFilePath,
687
- );
713
+ fileNotMocked = await fileStore.ensureContent(fileNotMocked.path);
688
714
  }
689
715
 
716
+ // When a default export is imported as named (via index re-export), we need
717
+ // to add a named re-export to the scenario component so the import works.
718
+ // e.g., if file has `export default X` but parent does `import { X } from '...'`
719
+ const needsNamedReExport =
720
+ importedExport.resolvedIsDefault === true &&
721
+ importedExport.isDefault === false;
722
+
690
723
  const {
691
724
  scenarioComponentPaths: newScenarioComponentPaths,
692
725
  writtenScenarioComponents: updatedWrittenScenarioComponents,
@@ -704,6 +737,8 @@ export default async function writeScenarioComponents({
704
737
  namespaceMocks,
705
738
  writtenScenarioComponents,
706
739
  fileStore,
740
+ // Pass the import name so we can add `export { default as Name };`
741
+ exportAsNamed: needsNamedReExport ? importedExport.name : undefined,
707
742
  });
708
743
  writtenScenarioComponents = updatedWrittenScenarioComponents;
709
744
  scenarioComponentPaths.push(...newScenarioComponentPaths);
@@ -737,18 +772,38 @@ export default async function writeScenarioComponents({
737
772
  relativeMocksDir,
738
773
  scenario.name,
739
774
  );
775
+ } else if (importedExport.isMocked) {
776
+ // No mock structure available, but isMocked is true.
777
+ // Generate a simple stub mock that returns scenario data.
778
+ // This prevents ReferenceError at runtime when the stripped
779
+ // function is called (e.g., local helper functions like getInitialProps).
780
+ const functionName = importedExport.name;
781
+
782
+ // Add scenarios import if not present
783
+ if (fileContent.indexOf('import { scenarios } from') === -1) {
784
+ const mockDataPath = `${relativeMocksDir}/MockData_${safeFileName(scenario.name)}`;
785
+ const importStatement = `import { scenarios } from "${mockDataPath}";`;
786
+ fileContent = `${fileContent}\n\n\n${importStatement}`;
787
+ }
788
+
789
+ // Generate a simple stub that returns the scenario data for this function
790
+ const stubMock = `\n\n// Stub mock for local function without mock structure\nfunction ${functionName}(...args) {\n return scenarios().data()?.["${functionName}()"];\n}`;
791
+ fileContent += stubMock;
740
792
  }
741
793
  }
742
794
  }
743
795
 
744
796
  // Try to find the import mapping using different key formats
745
797
  // The import mapping may use either absolute or relative paths as keys
746
- // IMPORTANT: Use filePath (where it's imported FROM), not resolvedFilePath (where entity lives)
747
- // For re-exports like ~codeyam/types, filePath="packages/types/index.ts",
748
- // resolvedFilePath="packages/types/src/types/Commit.ts"
749
- // We need to generate files at the import location (index.ts), not the entity location
798
+ // Use filePath (import source) for looking up the import mapping
799
+ // because that's how imports are written in source code
750
800
  const mockFilePathRelative = importedExport.filePath;
751
801
 
802
+ // For scenario component paths, prefer resolvedFilePath (where entity actually lives)
803
+ // because that's where scenario component files are written
804
+ const scenarioFilePathRelative =
805
+ importedExport.resolvedFilePath ?? importedExport.filePath;
806
+
752
807
  // Try looking up with different key formats (absolute, relative, resolved absolute)
753
808
  // Filter out undefined keys to avoid misleading undefined lookups
754
809
  const lookupKeys = [
@@ -802,10 +857,28 @@ export default async function writeScenarioComponents({
802
857
  } else {
803
858
  // For non-mocked imports, rewrite the import path to point to the generated scenario file
804
859
  // Use fileStore for O(1) lookup when available
805
- const fileNotMocked = fileStore
806
- ? fileStore.getByPath(mockFilePathRelative)
807
- : project.files.find((f) => f.path === mockFilePathRelative);
808
- const fileName = mockFilePathRelative.split('/').pop();
860
+ // First try resolvedFilePath (where entity lives), fallback to filePath (import source)
861
+ let fileNotMocked = fileStore
862
+ ? fileStore.getByPath(scenarioFilePathRelative)
863
+ : project.files.find((f) => f.path === scenarioFilePathRelative);
864
+
865
+ // Track which path we're actually using for the scenario component
866
+ let actualScenarioFilePathRelative = scenarioFilePathRelative;
867
+ if (
868
+ !fileNotMocked &&
869
+ importedExport.resolvedFilePath &&
870
+ importedExport.filePath !== importedExport.resolvedFilePath
871
+ ) {
872
+ // Fallback to filePath if file at resolvedFilePath doesn't exist
873
+ actualScenarioFilePathRelative = importedExport.filePath;
874
+ fileNotMocked = fileStore
875
+ ? fileStore.getByPath(actualScenarioFilePathRelative)
876
+ : project.files.find(
877
+ (f) => f.path === actualScenarioFilePathRelative,
878
+ );
879
+ }
880
+
881
+ const fileName = actualScenarioFilePathRelative.split('/').pop();
809
882
  const fileNotMockedIsIndex = isIndexPath(fileNotMocked?.path);
810
883
  const mockFilePath = isFrameworkRoute(
811
884
  fileNotMocked,
@@ -818,7 +891,7 @@ export default async function writeScenarioComponents({
818
891
  rootFile,
819
892
  entity: importedExportEntity,
820
893
  rootAnalysis,
821
- scenarioComponentPath: mockFilePathRelative,
894
+ scenarioComponentPath: actualScenarioFilePathRelative,
822
895
  project,
823
896
  framework,
824
897
  scenario,
@@ -826,7 +899,7 @@ export default async function writeScenarioComponents({
826
899
  .split('.')
827
900
  .slice(0, -1)
828
901
  .join('.')
829
- : mockFilePathRelative.replace(
902
+ : actualScenarioFilePathRelative.replace(
830
903
  `${fileName}`,
831
904
  `${importedExportEntity.sha}_${fileNotMockedIsIndex ? 'index_' : ''}${safeFileName(importedExportEntity.name)}_${safeFileName(scenario.name)}`,
832
905
  );
@@ -841,7 +914,39 @@ export default async function writeScenarioComponents({
841
914
  'g',
842
915
  );
843
916
 
844
- fileContent = fileContent.replace(importRegExp, `${path}$1`);
917
+ // Check if the original import path still exists in the file
918
+ // If it was already rewritten by another entity from the same module,
919
+ // we need to add a separate import statement for this entity
920
+ if (fileContent.match(importRegExp)) {
921
+ fileContent = fileContent.replace(importRegExp, `${path}$1`);
922
+ } else {
923
+ // The import path was already rewritten - add a new import for this entity
924
+ // This handles cases where multiple entities are imported from the same index file
925
+ // (e.g., import { A, B, C } from '@pkg') and each has its own scenario file
926
+ const entityImportName = importedExport.name;
927
+ const newImport = `import { ${entityImportName} } from '${path}';`;
928
+
929
+ // First, try to remove this entity from the already-rewritten grouped import
930
+ // This prevents duplicate/conflicting imports
931
+ // Match patterns like "EntityName," or ", EntityName" or "EntityName" (if only one)
932
+ const removeFromGroupedImportPatterns = [
933
+ new RegExp(`\\b${entityImportName}\\s*,\\s*`, 'g'), // "EntityName, "
934
+ new RegExp(`\\s*,\\s*${entityImportName}\\b`, 'g'), // ", EntityName"
935
+ ];
936
+ for (const pattern of removeFromGroupedImportPatterns) {
937
+ fileContent = fileContent.replace(pattern, '');
938
+ }
939
+
940
+ // Add the new import at the beginning of fileContent
941
+ // Note: The header comment (// Scenario:) doesn't exist yet - it's prepended at writeFile time
942
+ // So prepending here puts the import right after the header in the final output
943
+ //
944
+ // IMPORTANT: We cannot use indexOf('// Scenario:') + '\n\n' here because:
945
+ // 1. The header doesn't exist during processing
946
+ // 2. indexOf would return -1, and indexOf('\n\n', -1) starts from 0
947
+ // 3. This could find a \n\n inside a function body, inserting the import there!
948
+ fileContent = newImport + '\n' + fileContent;
949
+ }
845
950
  }
846
951
  }
847
952
  }
@@ -860,6 +965,36 @@ export default async function writeScenarioComponents({
860
965
  );
861
966
  }
862
967
 
968
+ // Rewrite node_module imports that have universal mocks
969
+ // Universal mocks create mock files at __codeyamMocks__/{safeFileName}.tsx
970
+ // We need to rewrite imports like `import { logger } from "@formbricks/logger"`
971
+ // to `import { logger } from "../__codeyamMocks__/_formbricks_logger"`
972
+ const universalMocks = project.metadata?.universalMocks ?? [];
973
+ const nodeModuleUniversalMocks = universalMocks.filter(
974
+ (mock) => mock.nodeModule && mock.content,
975
+ );
976
+
977
+ for (const universalMock of nodeModuleUniversalMocks) {
978
+ const originalPath = universalMock.filePath;
979
+ // Create the mock file name using the same pattern as applyUniversalMocks
980
+ const safeFileName = originalPath.replace(/[^a-zA-Z0-9_\-./]/g, '_');
981
+ const mockFileRelativePath = `${relativeMocksDir}/${safeFileName}`;
982
+
983
+ // Match both single and double quotes, and handle both named and default imports
984
+ // Pattern 1: import { x, y } from "module"
985
+ // Pattern 2: import x from "module"
986
+ // Pattern 3: import * as x from "module"
987
+ const importRegex = new RegExp(
988
+ `(import\\s+(?:\\{[^}]*\\}|\\*\\s+as\\s+\\w+|\\w+)\\s+from\\s+)['"]${originalPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}['"]`,
989
+ 'g',
990
+ );
991
+
992
+ fileContent = fileContent.replace(
993
+ importRegex,
994
+ `$1'${mockFileRelativePath}'`,
995
+ );
996
+ }
997
+
863
998
  if (
864
999
  rootAnalysis.entitySha === entity.sha &&
865
1000
  entity.metadata?.notExported &&
@@ -872,6 +1007,17 @@ export default async function writeScenarioComponents({
872
1007
  }
873
1008
  }
874
1009
 
1010
+ // When a default export is imported as named via re-export (e.g., index.tsx re-exports
1011
+ // a default export as named), we need to add a named export so the parent's
1012
+ // import statement works: `import { Name } from './path'`
1013
+ // The local variable name is the same as exportAsNamed (e.g., ScenarioEditor)
1014
+ if (exportAsNamed) {
1015
+ const namedExport = `export { ${exportAsNamed} };`;
1016
+ if (!fileContent.includes(namedExport)) {
1017
+ fileContent = `${fileContent}\n\n${namedExport}`;
1018
+ }
1019
+ }
1020
+
875
1021
  const basePath = safeFolder(file.path.split('/').slice(0, -1).join('/'));
876
1022
  const extension = file.name.split('.').pop();
877
1023
  // Include scenario name in path to allow multiple scenarios to coexist
@@ -28,7 +28,26 @@ export default async function writeUniversalMocks({
28
28
  }: WriteUniversalMocksArgs) {
29
29
  const { project } = projectAnalyzer;
30
30
 
31
- for (const universalMock of project.metadata?.universalMocks ?? []) {
31
+ // Group node_module mocks by filePath to merge multiple exports into one file
32
+ // This prevents later mocks from overwriting earlier ones for the same package
33
+ const nodeModuleMocksByPath = new Map<
34
+ string,
35
+ Array<(typeof universalMocks)[number]>
36
+ >();
37
+ const universalMocks = project.metadata?.universalMocks ?? [];
38
+
39
+ for (const mock of universalMocks) {
40
+ if (mock.nodeModule) {
41
+ const existing = nodeModuleMocksByPath.get(mock.filePath) ?? [];
42
+ existing.push(mock);
43
+ nodeModuleMocksByPath.set(mock.filePath, existing);
44
+ }
45
+ }
46
+
47
+ // Track which filePaths we've already processed (for node_modules)
48
+ const processedNodeModulePaths = new Set<string>();
49
+
50
+ for (const universalMock of universalMocks) {
32
51
  console.log(
33
52
  'CodeYam: Initializing universal mock',
34
53
  universalMock.filePath,
@@ -71,6 +90,16 @@ export default async function writeUniversalMocks({
71
90
  mockContent = file.content.replace(entityCode, universalMock.content);
72
91
  }
73
92
  } else {
93
+ // For node_modules, check if we've already processed this path
94
+ // (multiple mocks for the same package should be merged)
95
+ if (universalMock.nodeModule) {
96
+ if (processedNodeModulePaths.has(universalMock.filePath)) {
97
+ // Already processed as part of a merged mock, skip
98
+ continue;
99
+ }
100
+ processedNodeModulePaths.add(universalMock.filePath);
101
+ }
102
+
74
103
  const appPath = getAppPath(
75
104
  project,
76
105
  framework,
@@ -87,14 +116,37 @@ export default async function writeUniversalMocks({
87
116
  CODEYAM_MOCKS_DIRNAME,
88
117
  safeFileName(filePathForMockFile) + '.tsx',
89
118
  );
90
- const exportName =
91
- universalMock.entityName === 'default'
92
- ? 'default'
93
- : `{ ${universalMock.entityName} }`;
94
- if (exportName === 'default') {
95
- mockContent = `export default ${universalMock.content}`;
119
+
120
+ // For node_modules, merge all mocks for this filePath
121
+ const mocksToProcess = universalMock.nodeModule
122
+ ? (nodeModuleMocksByPath.get(universalMock.filePath) ?? [
123
+ universalMock,
124
+ ])
125
+ : [universalMock];
126
+
127
+ const contentParts: string[] = [];
128
+ const namedExports: string[] = [];
129
+ let hasDefaultExport = false;
130
+
131
+ for (const mock of mocksToProcess) {
132
+ if (mock.entityName === 'default') {
133
+ hasDefaultExport = true;
134
+ contentParts.push(`export default ${mock.content}`);
135
+ } else {
136
+ contentParts.push(mock.content);
137
+ namedExports.push(mock.entityName);
138
+ }
139
+ }
140
+
141
+ // Build the final mock content
142
+ if (namedExports.length > 0) {
143
+ mockContent = contentParts.join('\n\n');
144
+ // Only add export statement for non-default exports if not already in content
145
+ if (!hasDefaultExport || namedExports.length > 0) {
146
+ mockContent += `\n\nexport { ${namedExports.join(', ')} };`;
147
+ }
96
148
  } else {
97
- mockContent = `${universalMock.content}\n\nexport { ${universalMock.entityName} };`;
149
+ mockContent = contentParts.join('\n\n');
98
150
  }
99
151
  }
100
152
 
@@ -136,6 +188,12 @@ export default async function writeUniversalMocks({
136
188
  );
137
189
  const allSourceFiles = projectAnalyzer.getAllSourceFiles();
138
190
  for (const sourceFile of allSourceFiles) {
191
+ // Skip JSON files - they should not have imports rewritten
192
+ // This can happen when resolveJsonModule is enabled in tsconfig
193
+ // and package.json is included in the TypeScript program
194
+ if (sourceFile.path.endsWith('.json')) {
195
+ continue;
196
+ }
139
197
  if (importRegEx.test(sourceFile.content)) {
140
198
  const relativeMockPath = getRelativePath(sourceFile.path, mockPath);
141
199
  const newContent = sourceFile.content.replace(
@@ -187,7 +187,13 @@ export default function constructMockCode(mockName, dependencySchemas) {
187
187
  return [];
188
188
  }
189
189
  const addReturnValueFunctionAccessor = (dataPath) => {
190
- if (returnValue.returnsFunctionArgs) {
190
+ // Add function call accessor if:
191
+ // - There are actual arguments, OR
192
+ // - This is a callable (not a method that returns an array directly)
193
+ // For methods like getAll() that return arrays, the data is at ["getAll()"] not ["getAll()"]["()"]
194
+ if (returnValue.returnsFunctionArgs &&
195
+ (returnValue.returnsFunctionArgs.length > 0 ||
196
+ !returnValue.returnsFunctionArray)) {
191
197
  if (returnValue.isArray) {
192
198
  dataPath = `${dataPath}${optionalAccess('[0]')}`;
193
199
  }
@@ -214,14 +220,57 @@ export default function constructMockCode(mockName, dependencySchemas) {
214
220
  .filter(Boolean);
215
221
  };
216
222
  const constructContent = (dataPaths) => {
217
- const { name, args, nested, isArray, isGenericArray, returnsFunctionArgs, returnsFunctionArray, isAsyncFunction, } = returnValue;
223
+ const { name, args, nested, isArray, isGenericArray, returnsFunctionArgs, returnsFunctionArray, isAsyncFunction, hasNoReturnData, } = returnValue;
218
224
  const nestedContent = (nested ?? []).map((nestedItem) => {
219
225
  const nestedContent = constructReturnValueString(nestedItem, dataPaths);
220
226
  return nestedContent;
221
227
  });
228
+ // Array prototype methods that should be ignored when building mocks
229
+ // (these work on any array - we don't need to mock them)
230
+ const ARRAY_PROTOTYPE_METHODS = new Set([
231
+ 'at',
232
+ 'concat',
233
+ 'copyWithin',
234
+ 'entries',
235
+ 'every',
236
+ 'fill',
237
+ 'filter',
238
+ 'find',
239
+ 'findIndex',
240
+ 'findLast',
241
+ 'findLastIndex',
242
+ 'flat',
243
+ 'flatMap',
244
+ 'forEach',
245
+ 'includes',
246
+ 'indexOf',
247
+ 'join',
248
+ 'keys',
249
+ 'lastIndexOf',
250
+ 'map',
251
+ 'pop',
252
+ 'push',
253
+ 'reduce',
254
+ 'reduceRight',
255
+ 'reverse',
256
+ 'shift',
257
+ 'slice',
258
+ 'some',
259
+ 'sort',
260
+ 'splice',
261
+ 'toLocaleString',
262
+ 'toReversed',
263
+ 'toSorted',
264
+ 'toSpliced',
265
+ 'toString',
266
+ 'unshift',
267
+ 'values',
268
+ 'with',
269
+ 'length',
270
+ ]);
222
271
  const levelContentItems = [];
223
272
  // Add spread for data paths when:
224
- // - Not a function returning an array
273
+ // - Not a function returning an array, OR function returns array with custom methods
225
274
  // - Has function args OR not an array
226
275
  // - Not structural, OR is a structural [0] element with nested content
227
276
  // (array elements with nested functions need their other properties spread)
@@ -229,7 +278,19 @@ export default function constructMockCode(mockName, dependencySchemas) {
229
278
  returnValue.name === '[0]' &&
230
279
  nested &&
231
280
  nested.length > 0;
232
- if (!returnsFunctionArray &&
281
+ // Check if function returns array but has custom methods (not just array prototype methods)
282
+ // Excludes array indices like [0], [1], [] which are not methods
283
+ const hasCustomMethodsOnArrayReturn = returnsFunctionArray &&
284
+ nested &&
285
+ nested.length > 0 &&
286
+ nested.some((n) => {
287
+ // Skip array indices - they're not methods
288
+ if (n.name.match(/^\[\d*\]$/))
289
+ return false;
290
+ const methodName = n.name.replace(/[<(].*$/, '');
291
+ return !ARRAY_PROTOTYPE_METHODS.has(methodName);
292
+ });
293
+ if ((!returnsFunctionArray || hasCustomMethodsOnArrayReturn) &&
233
294
  (returnsFunctionArgs || !isArray) &&
234
295
  (!returnValue.isStructural || isStructuralArrayElementWithNested)) {
235
296
  levelContentItems.push(...dataPaths.map((path) => `...${path}`));
@@ -242,7 +303,16 @@ export default function constructMockCode(mockName, dependencySchemas) {
242
303
  .join(', ');
243
304
  let funcContents = '';
244
305
  if (returnsFunctionArray) {
245
- if (levelContents.length === 0) {
306
+ if (hasNoReturnData) {
307
+ // Function has no return data (only signatures) - return empty array
308
+ funcContents = 'return []';
309
+ }
310
+ else if (levelContents.length === 0 && dataPaths.length === 1) {
311
+ // When returning an array with no nested content, return the data path directly
312
+ // (the data path points to the array in scenario data)
313
+ funcContents = `return ${dataPaths[0]}`;
314
+ }
315
+ else if (levelContents.length === 0) {
246
316
  funcContents = 'return []';
247
317
  }
248
318
  else {
@@ -250,8 +320,19 @@ export default function constructMockCode(mockName, dependencySchemas) {
250
320
  }
251
321
  }
252
322
  else {
323
+ // Check if function has no actual return data (only signatures)
324
+ const hasNestedItems = nested && nested.length > 0;
325
+ const hasActualNestedContent = nestedContent.filter(Boolean).length > 0;
253
326
  if (levelContentItems.length === 1 && dataPaths.length === 1) {
254
- funcContents = `return ${dataPaths[0]}`;
327
+ if (hasNoReturnData ||
328
+ (hasNestedItems && !hasActualNestedContent)) {
329
+ // Function has no return data (only signatures) - return empty array
330
+ funcContents = 'return []';
331
+ }
332
+ else {
333
+ // Has return data - return data path
334
+ funcContents = `return ${dataPaths[0]}`;
335
+ }
255
336
  }
256
337
  else {
257
338
  funcContents = `return {\n${indent(levelContents)}\n}`;
@@ -262,12 +343,30 @@ export default function constructMockCode(mockName, dependencySchemas) {
262
343
  return levelContents;
263
344
  }
264
345
  }
346
+ // Check if all nested items are array prototype methods
347
+ const hasOnlyArrayPrototypeMethods = returnsFunctionArray &&
348
+ nested &&
349
+ nested.length > 0 &&
350
+ nested.every((n) => {
351
+ // Extract method name before type params and args (e.g., "reduce<...>(...)" -> "reduce")
352
+ const methodName = n.name.replace(/[<(].*$/, '');
353
+ return ARRAY_PROTOTYPE_METHODS.has(methodName);
354
+ });
265
355
  let returnValueContents = '';
266
356
  if (!returnsFunctionArgs &&
267
357
  nestedContent.length === 0 &&
268
358
  dataPaths.length === 1) {
269
359
  returnValueContents = dataPaths[0];
270
360
  }
361
+ else if (returnsFunctionArray &&
362
+ dataPaths.length === 1 &&
363
+ !root &&
364
+ (!nested || nested.length === 0 || hasOnlyArrayPrototypeMethods)) {
365
+ // Nested method returns an array - return the data path directly
366
+ // Only if nested content is empty or only contains array prototype methods
367
+ // (like .reduce() which work on any array - we don't need to mock them)
368
+ returnValueContents = dataPaths[0];
369
+ }
271
370
  else {
272
371
  if (isArray) {
273
372
  // When GENERIC array (using []) has nested content (like functions that need wrapping),
@@ -523,6 +622,23 @@ export default function constructMockCode(mockName, dependencySchemas) {
523
622
  if (returnValueSection.returnsFunctionArgs && value === 'array') {
524
623
  returnValueSection.returnsFunctionArray = true;
525
624
  }
625
+ // Check if this function call has actual return data in the schema
626
+ // If the path only has .signature entries (no .functionCallReturnValue), mark as no return data
627
+ // Use parts[i] (original part) instead of modified 'part' to include array indices like [1]
628
+ const functionCallPath = joinParenthesesAndArrays([
629
+ ...parts.slice(0, i),
630
+ parts[i], // Use original part which may include [1](args) together
631
+ ]);
632
+ // Check if there's a .functionCallReturnValue AFTER this function call path
633
+ const hasFunctionCallReturnValue = Object.keys(relevantReturnValueSchema).some((k) => {
634
+ if (!k.startsWith(functionCallPath))
635
+ return false;
636
+ const afterPath = k.slice(functionCallPath.length);
637
+ return afterPath.startsWith('.functionCallReturnValue');
638
+ });
639
+ if (!hasFunctionCallReturnValue) {
640
+ returnValueSection.hasNoReturnData = true;
641
+ }
526
642
  }
527
643
  if (nextIsDifferentiatedArray || hasNestedFunction) {
528
644
  continue;
@@ -648,6 +764,25 @@ export default function constructMockCode(mockName, dependencySchemas) {
648
764
  }
649
765
  }
650
766
  if (!hasNestedFunction) {
767
+ // Before breaking, check if this function returns an array
768
+ // by looking for a functionCallReturnValue: 'array' entry in the schema
769
+ if (relevantPart && part.endsWith(')')) {
770
+ const functionReturnPath = joinParenthesesAndArrays([
771
+ ...parts.slice(0, i + 1),
772
+ RETURN_VALUE,
773
+ ]);
774
+ const returnType = relevantReturnValueSchema[functionReturnPath];
775
+ if (returnType === 'array') {
776
+ // Only set returnsFunctionArray if the array contains plain data,
777
+ // NOT if it contains functions (which need wrapping)
778
+ const arrayElementPath = `${functionReturnPath}[]`;
779
+ const arrayElementType = relevantReturnValueSchema[arrayElementPath];
780
+ // If array element is a function, we need to wrap it - don't set returnsFunctionArray
781
+ if (arrayElementType !== 'function') {
782
+ relevantPart.returnsFunctionArray = true;
783
+ }
784
+ }
785
+ }
651
786
  break;
652
787
  }
653
788
  returnValueSection = relevantPart;
@@ -680,7 +815,23 @@ export default function constructMockCode(mockName, dependencySchemas) {
680
815
  return `const ${mockNameParts[0]} = {\n${indent(returnParts.join(',\n'))}\n};`;
681
816
  }
682
817
  else if (isFunction) {
683
- return `const ${mockName}ReturnValue = ${contents};\n\n${isRootAsyncFunction ? 'async ' : ''}function ${mockName}() {\n${indent(`return ${mockName}ReturnValue;`)}\n}`;
818
+ // For headers() and cookies() from next/headers, add common iterator methods
819
+ // These are needed when the mock is passed to functions that use .entries(), .keys(), etc.
820
+ // (e.g., Object.fromEntries(headers.entries()) in buildLegacyHeaders)
821
+ const needsIteratorMethods = mockName === 'headers' || mockName === 'cookies';
822
+ let enhancedContents = contents;
823
+ if (needsIteratorMethods && contents.trim().startsWith('{')) {
824
+ // Add iterator methods that operate on the scenario data
825
+ const iteratorMethods = `,
826
+ entries: () => Object.entries(scenarios().data()?.["${mockName}()"] || {}),
827
+ keys: () => Object.keys(scenarios().data()?.["${mockName}()"] || {}),
828
+ values: () => Object.values(scenarios().data()?.["${mockName}()"] || {}),
829
+ forEach: (fn) => Object.entries(scenarios().data()?.["${mockName}()"] || {}).forEach(([k, v]) => fn(v, k)),
830
+ has: (key) => Object.prototype.hasOwnProperty.call(scenarios().data()?.["${mockName}()"] || {}, key)`;
831
+ // Insert before the closing brace (handle trailing whitespace)
832
+ enhancedContents = contents.replace(/\}\s*$/, iteratorMethods + '\n}');
833
+ }
834
+ return `const ${mockName}ReturnValue = ${enhancedContents};\n\n${isRootAsyncFunction ? 'async ' : ''}function ${mockName}() {\n${indent(`return ${mockName}ReturnValue;`)}\n}`;
684
835
  }
685
836
  else {
686
837
  return `const ${mockName} = ${contents}`;