@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.
- package/analyzer-template/.build-info.json +7 -7
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +7 -6
- package/analyzer-template/packages/ai/index.ts +2 -0
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +24 -0
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +14 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +1402 -546
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.ts +138 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +139 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/DebugTracer.ts +224 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/PathManager.ts +203 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/README.md +294 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +161 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.ts +235 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +2 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/selectBestValue.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.ts +113 -0
- package/analyzer-template/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.ts +36 -0
- package/analyzer-template/packages/ai/src/lib/generateEntityKeyAttributes.ts +32 -8
- package/analyzer-template/packages/ai/src/lib/getConditionalUsagesFromCode.ts +27 -6
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +42 -4
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +39 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +18 -6
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/index.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +8 -10
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +8 -6
- package/analyzer-template/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.ts +5 -13
- package/analyzer-template/packages/analyze/src/lib/files/analyzeChange.ts +34 -15
- package/analyzer-template/packages/analyze/src/lib/files/analyzeEntity.ts +17 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyzeInitial.ts +35 -16
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +7 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.ts +9 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarioData.ts +6 -1
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateScenarios.ts +9 -1
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts +23 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.d.ts.map +1 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js +30 -0
- package/analyzer-template/packages/aws/dist/src/lib/s3/getPresignedUrl.js.map +1 -0
- package/analyzer-template/packages/aws/package.json +5 -4
- package/analyzer-template/packages/aws/s3/index.ts +4 -0
- package/analyzer-template/packages/aws/src/lib/s3/getPresignedUrl.ts +62 -0
- package/analyzer-template/packages/generate/src/lib/scenarioComponent.ts +6 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js +5 -3
- package/analyzer-template/packages/github/dist/generate/src/lib/scenarioComponent.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js +3 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts +2 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tableRelations.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts +37 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/analyzer-template/packages/github/dist/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/github/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/index.js +1 -0
- package/analyzer-template/packages/github/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/github/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/supabase/src/lib/kysely/db.ts +6 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tableRelations.ts +3 -0
- package/analyzer-template/packages/supabase/src/lib/kysely/tables/debugReportsTable.ts +61 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/index.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/index.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts +25 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.d.ts.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js +40 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/Semaphore.js.map +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/analyzer-template/packages/utils/dist/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/analyzer-template/packages/utils/index.ts +1 -0
- package/analyzer-template/packages/utils/src/lib/Semaphore.ts +42 -0
- package/analyzer-template/packages/utils/src/lib/frameworks/getRemixRoutePath.ts +2 -1
- package/analyzer-template/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.ts +1 -0
- package/analyzer-template/project/constructMockCode.ts +170 -6
- package/analyzer-template/project/reconcileMockDataKeys.ts +13 -0
- package/analyzer-template/project/start.ts +1 -11
- package/analyzer-template/project/writeMockDataTsx.ts +32 -1
- package/analyzer-template/project/writeScenarioComponents.ts +164 -18
- package/analyzer-template/project/writeUniversalMocks.ts +66 -8
- package/background/src/lib/virtualized/project/constructMockCode.js +158 -7
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js +12 -0
- package/background/src/lib/virtualized/project/reconcileMockDataKeys.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +1 -8
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +25 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +129 -17
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeUniversalMocks.js +56 -7
- package/background/src/lib/virtualized/project/writeUniversalMocks.js.map +1 -1
- package/codeyam-cli/src/cli.js +6 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/codeyam-cli.js +0 -0
- package/codeyam-cli/src/commands/debug.js +221 -0
- package/codeyam-cli/src/commands/debug.js.map +1 -0
- package/codeyam-cli/src/commands/report.js +102 -0
- package/codeyam-cli/src/commands/report.js.map +1 -0
- package/codeyam-cli/src/commands/setup-sandbox.js +164 -0
- package/codeyam-cli/src/commands/setup-sandbox.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js +6 -6
- package/codeyam-cli/src/utils/__tests__/cleanupAnalysisFiles.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +8 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analyzer.js +30 -0
- package/codeyam-cli/src/utils/analyzer.js.map +1 -1
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js +2 -2
- package/codeyam-cli/src/utils/cleanupAnalysisFiles.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +219 -0
- package/codeyam-cli/src/utils/generateReport.js.map +1 -0
- package/codeyam-cli/src/utils/install-skills.js +7 -0
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js +1 -0
- package/codeyam-cli/src/utils/queue/__tests__/job.pidTracking.test.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +5 -1
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +4 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +50 -2
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-D5ZHFomX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-CDnfNKKQ.js → InteractivePreview-XDSzQLOY.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-DUS-3h7I.js → LibraryFunctionPreview-BYVx9KFp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-TJzDQku1.js → LogViewer-CRcT5fOZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ReportIssueModal-BORLgi0X.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-BgdlWM6p.js → SafeScreenshot-Bual6h18.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bi-YUMa-.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-4D2vLLJz.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/_index-BC200mfN.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-CxvZPkCv.js +10 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.generate-report-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-B8fb6wnw.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chunk-WWGJGFF6-DvL0YqDJ.js → chunk-WWGJGFF6-De6i8FUT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/circle-alert-IdsgAK39.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/circle-check-BACUUf75.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/clock-vWeoCemX.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/createLucideIcon-CS7XDrKv.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-DIOEw_3i.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-3bYjyojg.js → entity._sha._-8Els_3Wb.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DtfwpN9J.js → entity._sha_.create-scenario-C3FZJx1w.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-YJz_igar.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/entityStatus-BEqj2qBy.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-DiP0q291.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/file-text-LM0mgxXE.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/files-Dxh9CcaV.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{git-WoKohOtW.js → git-BXmqrWCH.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/globals-BGS74ED-.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/html2canvas-pro.esm-XQCGvadH.js +5 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-Vvbl94Xc.js → index-D-zYbzFZ.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-BXPKbHEb.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/manifest-1af162d4.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-DB7VgjCY.js +16 -0
- package/codeyam-cli/src/webserver/build/client/assets/settings-5zF_GOcS.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{settings-LuiJ1UIm.js → settings-Dc4MlMpK.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-BQ-02-jB.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/triangle-alert-D7k-ArFa.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-CpUcCv1V.js → useLastLogLine-AlhS7g5F.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-Ddo4UQv7.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/zap-_jw-9DCp.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/{index-DzbqTxoN.js → index-D4JpXSIO.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-vwbN7n65.js +169 -0
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/codeyam-cli/templates/codeyam-setup-skill.md +65 -85
- package/codeyam-cli/templates/debug-command.md +125 -0
- package/package.json +4 -6
- package/packages/ai/index.js +1 -1
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +13 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +12 -0
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +1023 -405
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js +137 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/FunctionCallManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/ReactFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +112 -0
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js +176 -0
- package/packages/ai/src/lib/dataStructure/helpers/DebugTracer.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js +178 -0
- package/packages/ai/src/lib/dataStructure/helpers/PathManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +138 -0
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js +199 -0
- package/packages/ai/src/lib/dataStructure/helpers/VisitedTracker.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +2 -0
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js +62 -0
- package/packages/ai/src/lib/dataStructure/helpers/selectBestValue.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js +90 -0
- package/packages/ai/src/lib/dataStructure/helpers/uniqueIdUtils.js.map +1 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js +22 -0
- package/packages/ai/src/lib/gatherRelevantDependentKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/generateEntityKeyAttributes.js +32 -8
- package/packages/ai/src/lib/generateEntityKeyAttributes.js.map +1 -1
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js +13 -8
- package/packages/ai/src/lib/getConditionalUsagesFromCode.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +36 -3
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js +7 -0
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +17 -5
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/index.js +2 -1
- package/packages/analyze/src/lib/asts/nodes/index.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +6 -8
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +5 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +8 -2
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js +5 -8
- package/packages/analyze/src/lib/files/analyze/trackEntityCircularDependencies.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeChange.js +21 -9
- package/packages/analyze/src/lib/files/analyzeChange.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeEntity.js +10 -4
- package/packages/analyze/src/lib/files/analyzeEntity.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeInitial.js +21 -9
- package/packages/analyze/src/lib/files/analyzeInitial.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +6 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateKeyAttributes.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js +5 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarioData.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js +9 -1
- package/packages/analyze/src/lib/files/scenarios/generateScenarios.js.map +1 -1
- package/packages/generate/src/lib/scenarioComponent.js +5 -3
- package/packages/generate/src/lib/scenarioComponent.js.map +1 -1
- package/packages/supabase/src/lib/kysely/db.js +3 -0
- package/packages/supabase/src/lib/kysely/db.js.map +1 -1
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js +27 -0
- package/packages/supabase/src/lib/kysely/tables/debugReportsTable.js.map +1 -0
- package/packages/utils/index.js +1 -0
- package/packages/utils/index.js.map +1 -1
- package/packages/utils/src/lib/Semaphore.js +40 -0
- package/packages/utils/src/lib/Semaphore.js.map +1 -0
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js +2 -1
- package/packages/utils/src/lib/frameworks/getRemixRoutePath.js.map +1 -1
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js +1 -0
- package/packages/utils/src/lib/frameworks/remixRouteFileNameToRoute.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityTypeIcon-B9Sf8e9w.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioPreview-Bl6GY-OE.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/ScenarioViewer-BDq8RX50.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/_index-Bh3y3Wsl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/activity.(_tab)-tq7Bl6-t.js +0 -10
- package/codeyam-cli/src/webserver/build/client/assets/chart-column-q9_nHfwv.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/circle-alert-CKMpA1v_.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/clock-Wnfog8Qw.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C_ixaqqh.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/entity._sha_.edit._scenarioId-QecTs_sq.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/entry.client-hnkEgHrC.js +0 -5
- package/codeyam-cli/src/webserver/build/client/assets/file-text-CvCVdKLW.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-DgUCYhbd.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-DZfbt0u5.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/loader-circle-Bxm63UxG.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-c90b8608.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-DrVZQamX.js +0 -16
- package/codeyam-cli/src/webserver/build/client/assets/search-CJkk16Ct.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/settings-ConzHeiL.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/simulations-B9LRwAej.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/useToast-DOxmMaSg.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/zap-D5R1FAcH.js +0 -1
- 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
|
-
|
|
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(
|
|
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
|
-
//
|
|
747
|
-
//
|
|
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
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
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:
|
|
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
|
-
:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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 =
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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}`;
|